xiaoyi
4 天以前 27c8277d717b34b55f3ea967027b53b067f77df3
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>
</template>