feat: 新增PDMS模型轻量化处理功能及相关分析工具页面和配置。

This commit is contained in:
sladro 2026-02-23 17:22:41 +08:00
parent 29904d4479
commit d70a881bd3
7 changed files with 925 additions and 6 deletions

View File

@ -12,7 +12,11 @@
:model-data="modelData"
@page-change="(page) => $emit('page-change', page)"
/>
<div v-else-if="currentConnectedSoftware === 'pdms'" class="no-connection">PDMS分析功能开发中</div>
<PdmsAnalysisDashboard
v-else-if="currentConnectedSoftware === 'pdms'"
:model-data="modelData"
@page-change="(page) => $emit('page-change', page)"
/>
<div v-else class="no-connection">请先连接CAD软件</div>
</div>
</template>
@ -20,6 +24,7 @@
<script setup>
import CreoModelAnalysis from '@/components/pages/CreoModelAnalysis.vue'
import RevitAnalysisDashboard from '@/components/pages/RevitAnalysisDashboard.vue'
import PdmsAnalysisDashboard from '@/components/pages/PdmsAnalysisDashboard.vue'
defineProps({
currentConnectedSoftware: {

View File

@ -0,0 +1,327 @@
<template>
<div class="pdms-analysis-dashboard pdms-theme">
<!-- 如果没有模型显示欢迎界面 -->
<div v-if="!hasModel" class="pdms-analysis-welcome pdms-theme">
<div class="welcome-icon">
<i class="fas fa-industry"></i>
</div>
<h2>PDMS 模型分析中心</h2>
<p>专业的工厂设计模型处理工具提供智能化轻量化和优化选项请先打开或连接一个PDMS项目以开始分析</p>
<div class="welcome-actions">
<button class="welcome-btn" @click="openProject">
<i class="fas fa-folder-open"></i>
打开项目
</button>
<button class="welcome-btn" @click="refreshConnection">
<i class="fas fa-sync-alt"></i>
刷新连接
</button>
</div>
</div>
<!-- 如果有模型显示分析仪表板 -->
<div v-else>
<div class="pdms-analysis-header">
<h3>
<i class="fas fa-industry"></i>
PDMS 模型处理
</h3>
<p class="subtitle">{{ modelData?.ProjectInfo?.ProjectName || '当前连接的PDMS模型' }}</p>
</div>
<div class="pdms-strategy-selector">
<h4>
<i class="fas fa-cogs"></i>
模型处理工具选择
</h4>
<div class="pdms-strategy-grid">
<div
class="pdms-strategy-card"
data-strategy="shrinkwrap"
@click="openShrinkwrapPage"
>
<div class="strategy-icon">
<i class="fas fa-compress-arrows-alt"></i>
</div>
<h5>模型轻量化处理 (Shrinkwrap)</h5>
<p>
对PDMS模型进行轮廓化处理保留外部边缘删除内部不需要的构件从而大幅缩减模型体积
</p>
<div class="features">
<span>轮廓化</span>
<span>缩小体积</span>
<span>定制类型保留</span>
</div>
<div class="status-badge" style="background: var(--color-success)">新功能</div>
</div>
<!-- 可以预留其他PDMS处理工具位置 -->
<div class="pdms-strategy-card disabled" data-strategy="piping-analysis">
<div class="strategy-icon" style="background: var(--color-border-primary);">
<i class="fas fa-drafting-compass"></i>
</div>
<h5 style="color: var(--color-text-secondary);">管道专项分析 (开发中)</h5>
<p style="color: var(--color-text-disabled);">
针对管道模型进行碰撞检测及流体路径复杂性评估
</p>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { computed } from 'vue'
import { ElNotification } from 'element-plus'
const props = defineProps({
modelData: {
type: Object,
default: null
}
})
const emit = defineEmits(['page-change'])
//
const hasModel = computed(() => {
return props.modelData && Object.keys(props.modelData).length > 0
})
//
const openProject = () => {
emit('page-change', 'connection')
}
const openShrinkwrapPage = () => {
emit('page-change', 'pdms-shrinkwrap')
}
const refreshConnection = () => {
ElNotification({
title: '刷新连接',
message: '连接状态已刷新',
type: 'info',
position: 'top-right',
duration: 2000
})
}
</script>
<style scoped>
/* 仿照Revit的样式颜色可以适当调整体现PDMS的工业感 */
.pdms-analysis-welcome {
background: linear-gradient(135deg, var(--color-bg-secondary) 0%, var(--color-bg-primary) 100%);
border: 1px solid var(--color-border-primary);
border-radius: 16px;
padding: 32px;
text-align: center;
backdrop-filter: blur(20px);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
animation: slideInUp 0.4s ease-out;
}
.welcome-icon {
width: 80px;
height: 80px;
border-radius: 50%;
background: linear-gradient(135deg, #10b981 0%, #059669 100%);
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 24px auto;
box-shadow: 0 8px 32px rgba(16, 185, 129, 0.3);
}
.welcome-icon i {
font-size: 32px;
color: white;
}
.pdms-analysis-welcome h2 {
color: #10b981;
font-size: 1.6em;
font-weight: 600;
margin: 0 0 16px 0;
}
.pdms-analysis-welcome p {
color: var(--color-text-secondary);
font-size: 0.9em;
margin: 0 0 32px 0;
line-height: 1.6;
}
.welcome-actions {
display: flex;
justify-content: center;
gap: 16px;
flex-wrap: wrap;
}
.welcome-btn {
display: flex;
align-items: center;
gap: 8px;
padding: 12px 24px;
background: linear-gradient(135deg, #10b981 0%, #059669 100%);
color: white;
border: none;
border-radius: 8px;
font-size: 0.9em;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(16, 185, 129, 0.4);
}
.welcome-btn:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(16, 185, 129, 0.6);
}
.pdms-analysis-dashboard {
background: linear-gradient(135deg, var(--color-bg-secondary) 0%, var(--color-bg-primary) 100%);
border: 1px solid var(--color-border-primary);
border-radius: 16px;
padding: 24px;
backdrop-filter: blur(20px);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
animation: slideInUp 0.4s ease-out;
}
.pdms-analysis-header {
text-align: center;
margin-bottom: 32px;
}
.pdms-analysis-header h3 {
color: #10b981;
font-size: 1.6em;
font-weight: 600;
margin: 0 0 8px 0;
display: flex;
align-items: center;
justify-content: center;
gap: 12px;
}
.pdms-analysis-header .subtitle {
color: var(--color-text-secondary);
font-size: 0.9em;
margin: 0;
}
.pdms-strategy-selector {
margin-bottom: 32px;
}
.pdms-strategy-selector h4 {
color: var(--color-text-primary);
font-size: 1.3em;
font-weight: 600;
margin: 0 0 20px 0;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
}
.pdms-strategy-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 20px;
margin-bottom: 24px;
}
.pdms-strategy-card {
background: linear-gradient(135deg, var(--color-bg-secondary) 0%, var(--color-white-rgb-05) 100%);
border: 2px solid transparent;
border-radius: 12px;
padding: 24px;
cursor: pointer;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
position: relative;
backdrop-filter: blur(10px);
text-align: center;
}
.pdms-strategy-card:hover {
transform: translateY(-4px);
border-color: #10b981;
box-shadow: 0 8px 25px rgba(16, 185, 129, 0.3);
}
.pdms-strategy-card.disabled {
opacity: 0.6;
cursor: not-allowed;
border-color: var(--color-text-disabled);
}
.pdms-strategy-card.disabled:hover {
transform: none;
border-color: var(--color-text-disabled);
box-shadow: none;
}
.strategy-icon {
width: 60px;
height: 60px;
border-radius: 12px;
background: linear-gradient(135deg, #10b981 0%, #059669 100%);
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 16px auto;
box-shadow: 0 4px 15px rgba(16, 185, 129, 0.4);
}
.strategy-icon i {
font-size: 24px;
color: white;
}
.pdms-strategy-card h5 {
color: var(--color-text-primary);
font-size: 1.2em;
font-weight: 600;
margin: 0 0 8px 0;
}
.pdms-strategy-card p {
color: var(--color-text-secondary);
font-size: 0.9em;
margin: 0 0 16px 0;
line-height: 1.5;
}
.status-badge {
position: absolute;
top: 12px;
right: 12px;
background: var(--color-warning);
color: white;
padding: 4px 8px;
border-radius: 6px;
font-size: 0.7em;
font-weight: 600;
}
.features {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 8px;
}
.features span {
background: rgba(16, 185, 129, 0.1);
color: #10b981;
padding: 4px 8px;
border-radius: 6px;
font-size: 0.75em;
font-weight: 500;
}
</style>

View File

@ -0,0 +1,565 @@
<template>
<div class="pdms-shrinkwrap pdms-theme">
<div class="header-actions">
<button class="icon-btn" @click="goBack" title="返回">
<i class="fas fa-arrow-left"></i> 返回分析中心
</button>
</div>
<div class="optimization-header">
<h2>
<i class="fas fa-compress-arrows-alt"></i>
PDMS模型轻量化处理
</h2>
<p class="subtitle">保留工厂建筑模型外部轮廓删除多余内部细节大幅缩减模型体积</p>
</div>
<!-- 任务参数设置区 -->
<div class="settings-panel" v-if="taskStatus === 'idle' || taskStatus === 'failed'">
<div class="setting-group checkbox-group">
<label>保留类别 (Keep Types)</label>
<div class="checkbox-options">
<el-checkbox-group v-model="formData.keepTypes">
<el-checkbox label="SITE">SITE (场地)</el-checkbox>
<el-checkbox label="ZONE">ZONE (区域)</el-checkbox>
<el-checkbox label="STRU">STRU (结构)</el-checkbox>
<el-checkbox label="FRAME">FRAME (框架)</el-checkbox>
<el-checkbox label="SHELL">SHELL (壳体)</el-checkbox>
<el-checkbox label="PLAT">PLAT (平台)</el-checkbox>
<el-checkbox label="WALL">WALL (墙体)</el-checkbox>
</el-checkbox-group>
</div>
</div>
<div class="setting-group parameters-group">
<div class="param-item">
<label>外壳内缩距离 (Padding)</label>
<el-input-number v-model="formData.padding" :min="0" :step="100" />
<p class="help-text">向内偏移判定距离默认 500.0</p>
</div>
<div class="param-item">
<label>内外判断容差 (Tolerance)</label>
<el-input-number v-model="formData.touchTolerance" :min="0" :step="0.5" />
<p class="help-text">判断模型是否相交的容差值默认 1.0</p>
</div>
</div>
<div class="setting-group">
<label>区域过滤 (Zone Filters, 可选)</label>
<el-input
v-model="zoneFiltersInput"
placeholder="输入要处理的ZONE路径逗号分隔为空则全量处理"
></el-input>
</div>
<div class="setting-group toggle-group">
<label>安全设置</label>
<div class="toggle-control">
<span>开启模拟模式 (Dry Run)仅模拟不真删</span>
<el-switch v-model="formData.dryRun" active-color="#13ce66" inactive-color="#ff4949"></el-switch>
</div>
</div>
<div class="action-bar">
<button class="primary-btn" @click="startTask" :disabled="isStarting">
<i class="fas" :class="isStarting ? 'fa-spinner fa-spin' : 'fa-play'"></i>
{{ isStarting ? '正在处理...' : '执行轻量化' }}
</button>
</div>
<div v-if="errorMessage" class="error-message">
<i class="fas fa-exclamation-triangle"></i> {{ errorMessage }}
</div>
</div>
<!-- 任务执行中进度区 -->
<div class="execution-panel" v-else-if="taskStatus === 'Processing'">
<h3>
<i class="fas fa-cog fa-spin"></i>
正在处理PDMS模型请耐心等待 (可能需要几分钟)...
</h3>
<div class="progress-container">
<div class="progress-bar">
<div class="progress-fill active"></div>
</div>
</div>
</div>
<!-- 任务结果区 -->
<div class="result-panel" v-else-if="taskStatus === 'Completed' && taskResult">
<div class="success-header">
<i class="fas fa-check-circle success-icon"></i>
<h3>模型轻量化完成</h3>
<p v-if="taskResult.dryRun" style="color:var(--color-warning);">本次为模拟运行模式未真实删除模型</p>
</div>
<div class="metrics-grid">
<div class="metric-card">
<div class="metric-icon"><i class="fas fa-trash-alt"></i></div>
<div class="metric-info">
<div class="metric-value highlight">{{ taskResult.removedCount || 0 }}</div>
<div class="metric-label">移除内部构件数</div>
</div>
</div>
<div class="metric-card">
<div class="metric-icon"><i class="fas fa-check"></i></div>
<div class="metric-info">
<div class="metric-value">{{ taskResult.keptCount || 0 }}</div>
<div class="metric-label">保留构件总数</div>
</div>
</div>
<div class="metric-card">
<div class="metric-icon"><i class="fas fa-search-plus"></i></div>
<div class="metric-info">
<div class="metric-value">{{ taskResult.totalVisited || 0 }}</div>
<div class="metric-label">扫描构件总数</div>
</div>
</div>
<div class="metric-card" v-if="taskResult.shellKeptCount !== undefined">
<div class="metric-icon"><i class="fas fa-cube"></i></div>
<div class="metric-info">
<div class="metric-value">{{ taskResult.shellKeptCount }}</div>
<div class="metric-label">壳体保留数</div>
</div>
</div>
</div>
<div class="details-box">
<h4>处理信息</h4>
<p v-if="taskResult.message">{{ taskResult.message }}</p>
<p v-if="taskResult.startedAt && taskResult.completedAt">
执行时间: {{ formatTime(taskResult.startedAt) }} - {{ formatTime(taskResult.completedAt) }}
</p>
<!-- Zone summaries -->
<div v-if="taskResult.zoneSummaries && Object.keys(taskResult.zoneSummaries).length > 0">
<h5 style="margin-top:20px; color: var(--color-text-primary);">Zone 处理汇总</h5>
<ul>
<li v-for="(count, zone) in taskResult.zoneSummaries" :key="zone">
<span style="color:var(--color-primary)">{{ zone }}</span> : {{ count }} 个移除
</li>
</ul>
</div>
<!-- Errors -->
<div v-if="taskResult.errors && taskResult.errors.length > 0" class="error-message" style="margin-top:20px;">
<p><i class="fas fa-exclamation-triangle"></i> 部分处理出错</p>
<ul>
<li v-for="(err, idx) in taskResult.errors.slice(0, 5)" :key="idx">{{ err }}</li>
<li v-if="taskResult.errors.length > 5">...以及其他 {{ taskResult.errors.length - 5 }} 个错误</li>
</ul>
</div>
</div>
<div class="result-actions">
<button class="primary-btn" @click="resetTask">
<i class="fas fa-redo"></i> 再次处理
</button>
<button class="secondary-btn" @click="goBack">
<i class="fas fa-home"></i> 返回分析中心
</button>
</div>
</div>
</div>
</template>
<script setup>
import { ref, reactive } from 'vue'
import { ElNotification } from 'element-plus'
import pdmsApi from '@/services/pdmsApi'
const emit = defineEmits(['page-change'])
//
// idle | Processing | Completed | failed
const taskStatus = ref('idle')
const isStarting = ref(false)
const errorMessage = ref('')
const taskResult = ref(null)
const zoneFiltersInput = ref("")
//
const formData = reactive({
dryRun: true,
padding: 500.0,
touchTolerance: 1.0,
keepTypes: ["SITE", "ZONE", "STRU", "FRAME", "SHELL", "PLAT", "WALL"]
})
//
const goBack = () => {
emit('page-change', 'analysis-tools')
}
//
const resetTask = () => {
taskStatus.value = 'idle'
taskResult.value = null
errorMessage.value = ''
}
//
const formatTime = (timeStr) => {
if (!timeStr) return ""
return new Date(timeStr).toLocaleString()
}
//
const startTask = async () => {
isStarting.value = true
errorMessage.value = ''
taskStatus.value = 'Processing'
try {
const payload = {
dryRun: formData.dryRun,
padding: formData.padding,
touchTolerance: formData.touchTolerance,
zoneFilters: zoneFiltersInput.value ? zoneFiltersInput.value.split(',').map(s => s.trim()).filter(s => s) : [],
keepTypes: formData.keepTypes
}
const res = await pdmsApi.executeShrinkwrap(payload)
if (res.success && res.data && res.data.code === 0) {
taskStatus.value = 'Completed'
taskResult.value = res.data.data
ElNotification({
title: '处理完成',
message: 'PDMS模型轻量化处理执行完毕。',
type: 'success'
})
} else {
taskStatus.value = 'failed'
errorMessage.value = (res.data && res.data.message) || res.error || '执行轻量化失败,返回数据异常。'
ElNotification({
title: '处理失败',
message: errorMessage.value,
type: 'error'
})
}
} catch (err) {
taskStatus.value = 'failed'
errorMessage.value = err.message || '网络请求错误'
ElNotification({
title: '处理失败',
message: errorMessage.value,
type: 'error'
})
} finally {
isStarting.value = false
}
}
</script>
<style scoped>
.pdms-shrinkwrap {
background: linear-gradient(135deg, var(--color-bg-secondary) 0%, var(--color-bg-primary) 100%);
border: 1px solid var(--color-border-primary);
border-radius: 16px;
padding: 24px;
backdrop-filter: blur(20px);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
animation: slideInUp 0.4s ease-out;
color: var(--color-text-primary);
min-height: 100%;
}
.header-actions {
margin-bottom: 20px;
}
.icon-btn {
background: transparent;
border: none;
color: #10b981;
font-size: 1.1em;
font-weight: 600;
cursor: pointer;
display: flex;
align-items: center;
gap: 8px;
transition: all 0.3s;
}
.icon-btn:hover {
transform: translateX(-4px);
color: #059669;
}
.optimization-header {
text-align: center;
margin-bottom: 32px;
}
.optimization-header h2 {
color: #10b981;
font-size: 1.8em;
font-weight: 600;
margin: 0 0 12px 0;
display: flex;
align-items: center;
justify-content: center;
gap: 12px;
}
.optimization-header .subtitle {
color: var(--color-text-secondary);
font-size: 1em;
max-width: 600px;
margin: 0 auto;
line-height: 1.6;
}
/* 设定区 */
.settings-panel {
background: var(--color-bg-card);
border-radius: 12px;
padding: 32px;
max-width: 800px;
margin: 0 auto;
border: 1px solid var(--color-border-primary);
}
.setting-group {
margin-bottom: 32px;
}
.setting-group > label {
display: block;
font-size: 1.1em;
font-weight: 600;
margin-bottom: 16px;
color: var(--color-text-primary);
}
.parameters-group {
display: flex;
gap: 32px;
flex-wrap: wrap;
}
.param-item {
display: flex;
flex-direction: column;
gap: 8px;
}
.param-item label {
font-weight: 500;
color: var(--color-text-primary);
}
.param-item .help-text {
font-size: 0.8em;
color: var(--color-text-secondary);
margin: 0;
}
.toggle-group {
background: var(--color-bg-secondary);
padding: 16px;
border-radius: 12px;
}
.toggle-control {
display: flex;
justify-content: space-between;
align-items: center;
}
.action-bar {
text-align: center;
margin-top: 32px;
}
::v-deep(.el-checkbox-group) {
display: flex;
flex-wrap: wrap;
gap: 16px;
}
::v-deep(.el-checkbox) {
margin-right: 0;
color: var(--color-text-primary);
}
.primary-btn {
background: linear-gradient(135deg, #10b981 0%, #059669 100%);
color: white;
border: none;
border-radius: 8px;
padding: 14px 40px;
font-size: 1.1em;
font-weight: 600;
cursor: pointer;
box-shadow: 0 4px 15px rgba(16, 185, 129, 0.4);
transition: all 0.3s;
display: flex;
align-items: center;
gap: 10px;
margin: 0 auto;
}
.primary-btn:hover:not(:disabled) {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(16, 185, 129, 0.6);
}
.primary-btn:disabled {
opacity: 0.7;
cursor: not-allowed;
}
.secondary-btn {
background: var(--color-bg-secondary);
color: var(--color-text-primary);
border: 1px solid var(--color-border-primary);
border-radius: 8px;
padding: 14px 40px;
font-size: 1.1em;
font-weight: 600;
cursor: pointer;
transition: all 0.3s;
display: flex;
align-items: center;
gap: 10px;
}
.secondary-btn:hover {
background: var(--color-white-rgb-1);
}
.error-message {
margin-top: 20px;
padding: 12px;
background: rgba(255, 73, 73, 0.1);
color: #ff4949;
border-left: 4px solid #ff4949;
border-radius: 4px;
}
/* 执行进度区 */
.execution-panel {
text-align: center;
padding: 60px 20px;
}
.execution-panel h3 {
color: #10b981;
font-size: 1.6em;
margin-bottom: 40px;
}
.progress-container {
max-width: 500px;
margin: 0 auto;
}
.progress-bar {
height: 8px;
background: var(--color-border-primary);
border-radius: 4px;
overflow: hidden;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, #10b981, #34d399);
width: 50%;
border-radius: 4px;
}
.progress-fill.active {
animation: progressIndeterminate 2s infinite ease-in-out;
transform-origin: 0% 50%;
}
@keyframes progressIndeterminate {
0% { transform: translateX(-100%) scaleX(0.2); }
50% { transform: translateX(0) scaleX(1); }
100% { transform: translateX(200%) scaleX(0.2); }
}
/* 结果区 */
.result-panel {
max-width: 900px;
margin: 0 auto;
}
.success-header {
text-align: center;
margin-bottom: 40px;
}
.success-icon {
font-size: 64px;
color: #10b981;
margin-bottom: 16px;
text-shadow: 0 4px 15px rgba(16, 185, 129, 0.3);
}
.success-header h3 {
font-size: 1.8em;
color: var(--color-text-primary);
margin: 0;
}
.metrics-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 24px;
margin-bottom: 32px;
}
.metric-card {
background: var(--color-bg-card);
border: 1px solid var(--color-border-primary);
border-radius: 12px;
padding: 24px;
display: flex;
align-items: center;
gap: 20px;
}
.metric-icon {
font-size: 32px;
color: #10b981;
width: 60px;
height: 60px;
background: rgba(16, 185, 129, 0.1);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.metric-info {
flex: 1;
}
.metric-value {
font-size: 1.8em;
font-weight: 700;
color: var(--color-text-primary);
}
.metric-value.highlight {
color: #10b981;
}
.metric-label {
color: var(--color-text-secondary);
font-size: 0.9em;
margin-top: 4px;
}
.details-box {
background: var(--color-bg-card);
border: 1px solid var(--color-border-primary);
border-radius: 12px;
padding: 24px;
margin-bottom: 40px;
}
.details-box h4 {
margin: 0 0 20px 0;
color: var(--color-text-primary);
font-size: 1.2em;
}
.result-actions {
display: flex;
justify-content: center;
gap: 20px;
}
</style>

View File

@ -127,11 +127,12 @@ const CAD_SOFTWARE_DEFINITIONS = {
apiVersion: 'v1',
priority: 3,
description: '工厂设计管理',
features: ['status', 'piping'],
features: ['status', 'piping', 'shrinkwrap'],
endpoints: {
connect: '/test',
status: '/api/status/model',
piping: '/api/v1/piping'
piping: '/api/v1/piping',
shrinkwrap: '/api/model/shrinkwrap'
}
},
AUTOCAD: {

View File

@ -13,7 +13,8 @@ export const PAGE_TYPES = {
GEOMETRY_OPTIMIZATION_PARAMS: 'geometry-optimization-params',
GEOMETRY_OPTIMIZATION_RESULT: 'geometry-optimization-result',
FILE_MANAGEMENT: 'file-management',
REVIT_ENVELOPE_OPTIMIZATION: 'revit-envelope-optimization'
REVIT_ENVELOPE_OPTIMIZATION: 'revit-envelope-optimization',
PDMS_SHRINKWRAP: 'pdms-shrinkwrap'
}
// 需要CAD连接的页面
@ -21,5 +22,6 @@ export const CAD_REQUIRED_PAGES = [
PAGE_TYPES.MODEL_VIEWER,
PAGE_TYPES.ANALYSIS_TOOLS,
PAGE_TYPES.EXPORT_TOOLS,
PAGE_TYPES.REVIT_ENVELOPE_OPTIMIZATION
PAGE_TYPES.REVIT_ENVELOPE_OPTIMIZATION,
PAGE_TYPES.PDMS_SHRINKWRAP
]

View File

@ -35,6 +35,23 @@ class PdmsApiService {
}
})
}
/**
* 执行PDMS模型轻量化处理
* @param {Object} params 轻量化参数
* @returns {Promise<{success: boolean, data?: any, error?: string}>}
*/
async executeShrinkwrap(params) {
const url = buildApiUrl(this.softwareName, 'shrinkwrap')
return await apiClient.post(url, params, {
timeout: 600000, // 超时600s
operationContext: {
software: 'PDMS',
operation: '模型轻量化处理'
}
})
}
}
export const pdmsApi = new PdmsApiService()

View File

@ -66,6 +66,7 @@ import GeometryComplexityResult from '@/components/pages/GeometryComplexityResul
import GeometryOptimizationParams from '@/components/pages/GeometryOptimizationParams.vue'
import GeometryOptimizationResult from '@/components/pages/GeometryOptimizationResult.vue'
import RevitEnvelopeOptimization from '@/components/pages/RevitEnvelopeOptimization.vue'
import PdmsShrinkwrapPage from '@/components/pages/PdmsShrinkwrapPage.vue'
import FileManagementPage from '@/components/pages/FileManagementPage.vue'
import InfoManagementPanel from '@/components/layout/InfoManagementPanel.vue'
import { PAGE_TYPES } from '@/config/pages'
@ -112,7 +113,8 @@ const pageComponentMap = {
[PAGE_TYPES.GEOMETRY_OPTIMIZATION_PARAMS]: GeometryOptimizationParams,
[PAGE_TYPES.GEOMETRY_OPTIMIZATION_RESULT]: GeometryOptimizationResult,
[PAGE_TYPES.FILE_MANAGEMENT]: FileManagementPage,
[PAGE_TYPES.REVIT_ENVELOPE_OPTIMIZATION]: RevitEnvelopeOptimization
[PAGE_TYPES.REVIT_ENVELOPE_OPTIMIZATION]: RevitEnvelopeOptimization,
[PAGE_TYPES.PDMS_SHRINKWRAP]: PdmsShrinkwrapPage
}
// computed