From 27c8277d717b34b55f3ea967027b53b067f77df3 Mon Sep 17 00:00:00 2001
From: xiaoyi <908147524@qq.com>
Date: 星期四, 20 八月 2026 16:58:49 +0800
Subject: [PATCH] feat 功能变更

---
 src/views/bi/decision/forecast-analysis/index.vue |  159 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 154 insertions(+), 5 deletions(-)

diff --git a/src/views/bi/decision/forecast-analysis/index.vue b/src/views/bi/decision/forecast-analysis/index.vue
index 413733b..404c042 100644
--- a/src/views/bi/decision/forecast-analysis/index.vue
+++ b/src/views/bi/decision/forecast-analysis/index.vue
@@ -1,12 +1,16 @@
 <script lang="ts" setup>
 import { onMounted, ref } from 'vue';
 
-import { Page } from '@vben/common-ui';
+import { Page, useVbenModal } from '@vben/common-ui';
 
-import { DatePicker, Select, Spin } from 'ant-design-vue';
+import { DatePicker, message, Select, Spin } from 'ant-design-vue';
 import dayjs from 'dayjs';
 
-import { getForecastList } from '#/api/bi/decision/forecast';
+import { useVbenForm } from '#/adapter/form';
+import {
+  generateForecastWorkOrder,
+  getForecastList,
+} from '#/api/bi/decision/forecast';
 
 defineOptions({ name: 'DecisionForecastAnalysis' });
 
@@ -18,6 +22,12 @@
   { label: '鏃ヨ礋鑽烽娴�', value: 'load_forecast_daily' },
   { label: '鍛ㄨ礋鑽烽娴�', value: 'load_forecast_weekly' },
   { label: '鏈堣礋鑽烽娴�', value: 'load_forecast_monthly' },
+];
+
+const WORK_ORDER_TYPE_OPTIONS = [
+  { label: '鐢靛姏杩愮淮', value: 4 },
+  { label: '鍙戠數', value: 5 },
+  { label: '妫�淇�', value: 6 },
 ];
 
 async function loadData() {
@@ -32,10 +42,135 @@
 }
 
 onMounted(loadData);
+
+/** ========== 鐢熸垚宸ュ崟 ========== */
+const [Form, formApi] = useVbenForm({
+  commonConfig: {
+    componentProps: {
+      class: 'w-full',
+    },
+    labelWidth: 100,
+  },
+  wrapperClass: 'grid-cols-1',
+  layout: 'vertical',
+  schema: [
+    {
+      fieldName: 'forecastId',
+      component: 'Input',
+      dependencies: {
+        triggerFields: [''],
+        show: () => false,
+      },
+    },
+    {
+      fieldName: 'workOrderName',
+      label: '宸ュ崟鍚嶇О',
+      component: 'Input',
+      componentProps: {
+        placeholder: '璇疯緭鍏ュ伐鍗曞悕绉�',
+      },
+    },
+    {
+      fieldName: 'workOrderType',
+      label: '宸ュ崟绫诲瀷',
+      component: 'Select',
+      componentProps: {
+        options: WORK_ORDER_TYPE_OPTIONS,
+        placeholder: '璇烽�夋嫨宸ュ崟绫诲瀷',
+      },
+      rules: 'selectRequired',
+    },
+    {
+      fieldName: 'requestDate',
+      label: '闇�姹傛棩鏈�',
+      component: 'DatePicker',
+      componentProps: {
+        placeholder: '璇烽�夋嫨闇�姹傛棩鏈�',
+        valueFormat: 'YYYY-MM-DD HH:mm:ss',
+      },
+    },
+    {
+      fieldName: 'quantity',
+      label: '鐢熶骇鏁伴噺',
+      component: 'InputNumber',
+      componentProps: {
+        class: '!w-full',
+        min: 0,
+        precision: 2,
+        placeholder: '璇疯緭鍏ョ敓浜ф暟閲�',
+      },
+      rules: 'required',
+    },
+    {
+      fieldName: 'remark',
+      label: '澶囨敞',
+      component: 'Textarea',
+      componentProps: {
+        placeholder: '璇疯緭鍏ュ娉�',
+        rows: 3,
+      },
+    },
+  ],
+  showDefaultActions: false,
+});
+
+const [Modal, modalApi] = useVbenModal({
+  async onConfirm() {
+    const { valid } = await formApi.validate();
+    if (!valid) {
+      return;
+    }
+    modalApi.lock();
+    try {
+      const values = await formApi.getValues<{
+        forecastId: number;
+        workOrderName?: string;
+        workOrderType: number;
+        requestDate?: string;
+        quantity: number;
+        remark?: string;
+      }>();
+      await generateForecastWorkOrder({
+        forecastId: Number(values.forecastId),
+        workOrderName: values.workOrderName,
+        workOrderType: Number(values.workOrderType),
+        requestDate: values.requestDate,
+        quantity: Number(values.quantity ?? 1),
+        remark: values.remark,
+      });
+      await modalApi.close();
+      message.success('宸ュ崟鐢熸垚鎴愬姛');
+    } finally {
+      modalApi.unlock();
+    }
+  },
+  async onOpenChange(isOpen: boolean) {
+    if (!isOpen) {
+      return;
+    }
+    const data = modalApi.getData<{ item: any }>();
+    const item = data?.item;
+    await formApi.resetForm();
+    await formApi.setValues({
+      forecastId: item?.id,
+      workOrderType: 4,
+      requestDate: item?.pointTime ?? dayjs().format('YYYY-MM-DD HH:mm:ss'),
+      quantity: item?.forecastValue ?? 1,
+      remark: `鐢辫礋鑽烽娴嬶紙${item?.forecastName ?? forecastCode.value}锛夎嚜鍔ㄧ敓鎴恅,
+    });
+  },
+});
+
+function handleGenerate(item: any) {
+  modalApi.setData({ item }).open();
+}
 </script>
 
 <template>
   <Page :auto-content-height="true">
+    <Modal title="璐熻嵎棰勬祴鐢熸垚鐢熶骇宸ュ崟" class="w-1/2">
+      <Form class="mx-3" />
+    </Modal>
     <div class="p-4">
       <div class="mb-4 flex items-center gap-4">
         <h2 class="text-lg font-bold">璐熻嵎棰勬祴</h2>
@@ -52,7 +187,11 @@
           鏆傛棤棰勬祴鏁版嵁锛岃鍏堥厤缃� KPI 鎸囨爣鍜岄璀﹁鍒欏悗鏌ョ湅
         </div>
         <div v-else class="grid grid-cols-1 gap-4 lg:grid-cols-2">
-          <div v-for="item in forecastData" :key="item.id" class="rounded-lg border p-4">
+          <div
+            v-for="item in forecastData"
+            :key="item.id"
+            class="rounded-lg border p-4"
+          >
             <div class="mb-2 flex items-center justify-between">
               <span class="font-medium">{{ item.forecastName }}</span>
               <span class="text-xs text-gray-400">{{ item.pointTime }}</span>
@@ -70,9 +209,19 @@
             <div v-if="item.dimension" class="mt-1 text-xs text-gray-400">
               {{ item.dimension }}: {{ item.dimensionValue }}
             </div>
+            <div class="mt-3">
+              <a-button
+                type="primary"
+                ghost
+                size="small"
+                @click="handleGenerate(item)"
+              >
+                鐢熸垚宸ュ崟
+              </a-button>
+            </div>
           </div>
         </div>
       </Spin>
     </div>
   </Page>
-</template>
\ No newline at end of file
+</template>

--
Gitblit v1.9.3