From a27f80b043bb9651fd0032dcd28b2fee6cf820b9 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期一, 03 八月 2026 13:42:34 +0800
Subject: [PATCH] feat(ai): 集成AI智能分析功能到MPS表单和仪表板
---
src/views/mes/pro/workorder/modules/ai/predict-delivery.vue | 87 +++++++++++++++++++++++++++++++++++++++----
1 files changed, 79 insertions(+), 8 deletions(-)
diff --git a/src/views/mes/pro/workorder/modules/ai/predict-delivery.vue b/src/views/mes/pro/workorder/modules/ai/predict-delivery.vue
index 09e4da0..339aea9 100644
--- a/src/views/mes/pro/workorder/modules/ai/predict-delivery.vue
+++ b/src/views/mes/pro/workorder/modules/ai/predict-delivery.vue
@@ -1,36 +1,78 @@
<script lang="ts" setup>
import type { MesProAiApi } from '#/api/mes/pro/ai';
-import { ref } from 'vue';
+import { onUnmounted, ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { IconifyIcon } from '@vben/icons';
-import { Alert, Button, message, Progress, Tag } from 'ant-design-vue';
+import { Alert, Button, Progress, Tag } from 'ant-design-vue';
import { predictDelivery } from '#/api/mes/pro/ai';
defineOptions({ name: 'MesProAiPredictDelivery' });
-const props = defineProps<{ workOrderId: number }>();
+const props = defineProps<{ workOrderId?: number; mpsId?: number }>();
const loading = ref(false);
+const progress = ref(0);
const result = ref<MesProAiApi.PredictDeliveryRespVO>();
+const errorMsg = ref('');
+
+let progressTimer: ReturnType<typeof setInterval> | null = null;
+
+function startProgress() {
+ progress.value = 0;
+ progressTimer = setInterval(() => {
+ if (progress.value < 30) {
+ progress.value += 3;
+ } else if (progress.value < 70) {
+ progress.value += 2;
+ } else if (progress.value < 88) {
+ progress.value += 0.5;
+ }
+ }, 100);
+}
+
+function stopProgress() {
+ if (progressTimer) {
+ clearInterval(progressTimer);
+ progressTimer = null;
+ }
+}
+
+function finishProgress() {
+ stopProgress();
+ progress.value = 100;
+}
+
+onUnmounted(() => stopProgress());
async function handlePredict() {
loading.value = true;
result.value = undefined;
+ errorMsg.value = '';
+ modalApi.open();
+ startProgress();
try {
- result.value = await predictDelivery(props.workOrderId);
- modalApi.open();
+ result.value = await predictDelivery(props.workOrderId, props.mpsId);
+ finishProgress();
} catch {
- message.error('AI 鍒嗘瀽鏆傛椂涓嶅彲鐢紝璇风◢鍚庨噸璇�');
+ errorMsg.value = 'AI 鍒嗘瀽鏆傛椂涓嶅彲鐢紝璇风◢鍚庨噸璇�';
+ stopProgress();
} finally {
loading.value = false;
}
}
-const [ResultModal, modalApi] = useVbenModal({ footer: false });
+const [ResultModal, modalApi] = useVbenModal({
+ footer: false,
+ onOpenChange(isOpen: boolean) {
+ if (!isOpen) {
+ stopProgress();
+ }
+ },
+});
</script>
<template>
@@ -40,7 +82,36 @@
</Button>
<ResultModal title="AI 鎸夋椂浜や粯棰勬祴" class="w-1/2">
- <template v-if="result">
+ <!-- 鍔犺浇涓� -->
+ <div v-if="loading" class="flex flex-col items-center py-10">
+ <div class="relative mb-6">
+ <div class="absolute inset-0 animate-ping rounded-full bg-green-400 opacity-20" style="width: 80px; height: 80px" />
+ <div class="relative flex h-20 w-20 items-center justify-center rounded-full bg-green-50">
+ <IconifyIcon icon="ant-design:check-circle-outlined" class="text-3xl text-green-500" />
+ </div>
+ </div>
+ <div class="mb-3 text-base font-medium text-gray-700">
+ AI 姝e湪璇勪及浜や粯鑳藉姏...
+ </div>
+ <div class="w-2/3">
+ <Progress
+ :percent="Math.round(progress)"
+ :stroke-color="{ '0%': '#52c41a', '100%': '#b7eb8f' }"
+ :show-info="true"
+ status="active"
+ />
+ </div>
+ <div class="mt-2 text-sm text-gray-400">姝e湪鍒嗘瀽鐢熶骇杩涘害銆佸墿浣欏伐鏃朵笌浜や粯椋庨櫓</div>
+ </div>
+
+ <!-- 閿欒 -->
+ <div v-else-if="errorMsg" class="flex flex-col items-center py-10">
+ <IconifyIcon icon="ant-design:close-circle-filled" class="mb-4 text-5xl text-red-400" />
+ <span class="text-base text-gray-500">{{ errorMsg }}</span>
+ </div>
+
+ <!-- 缁撴灉 -->
+ <template v-else-if="result">
<div class="mb-4 flex items-center gap-4">
<div class="flex items-center gap-2">
<span class="text-base font-medium">鑳藉惁鎸夋椂浜や粯锛�</span>
--
Gitblit v1.9.3