gaoluyang
6 天以前 71a9eef518f2f2f1a1eb2fb90f2eb8ab7b155bc8
src/views/procurementManagement/procurementPlan/index.vue
@@ -1,137 +1,179 @@
<template>
  <div class="app-container">
    <!-- 搜索区域 -->
    <el-card class="search-card" shadow="never">
      <el-form :model="searchForm" :inline="true" class="search-form">
    <el-card class="search-card"
             shadow="never">
      <el-form :model="searchForm"
               :inline="true"
               class="search-form">
        <el-form-item label="计划名称">
          <el-input v-model="searchForm.planName" placeholder="请输入计划名称" clearable />
          <el-input v-model="searchForm.planName"
                    placeholder="请输入计划名称"
                    clearable />
        </el-form-item>
        <el-form-item label="状态">
          <el-select v-model="searchForm.status" placeholder="请选择状态" clearable style="width: 150px">
            <el-option label="启用" value="active" />
            <el-option label="禁用" value="disabled" />
          <el-select v-model="searchForm.status"
                     placeholder="请选择状态"
                     clearable
                     style="width: 150px">
            <el-option label="启用"
                       value="active" />
            <el-option label="禁用"
                       value="disabled" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleSearch">
            <el-icon><Search /></el-icon>
          <el-button type="primary"
                     @click="handleSearch">
            <el-icon>
              <Search />
            </el-icon>
            搜索
          </el-button>
          <el-button @click="handleReset">
            <el-icon><Refresh /></el-icon>
            <el-icon>
              <Refresh />
            </el-icon>
            重置
          </el-button>
        </el-form-item>
      </el-form>
    </el-card>
    <!-- 操作按钮 -->
    <el-card class="table-card" shadow="never">
    <el-card class="table-card"
             shadow="never">
      <div class="table-header">
        <div class="table-title">采购计划列表</div>
        <div class="table-actions">
          <el-button type="primary" @click="handleAdd">
            <el-icon><Plus /></el-icon>
          <el-button type="primary"
                     @click="handleAdd">
            <el-icon>
              <Plus />
            </el-icon>
            新增计划
          </el-button>
          <el-button type="info" @click="handleExport">
            <el-icon><Download /></el-icon>
          <el-button type="info"
                     @click="handleExport">
            <el-icon>
              <Download />
            </el-icon>
            导出
          </el-button>
        </div>
      </div>
      <!-- 数据表格 -->
      <el-table
        v-loading="loading"
        :data="tableData"
        stripe
        border
        style="width: 100%"
      >
        <el-table-column prop="planName" label="计划名称" min-width="150" />
        <el-table-column prop="description" label="描述" min-width="200" show-overflow-tooltip />
        <el-table-column prop="formula" label="计算公式" min-width="200" show-overflow-tooltip>
      <el-table v-loading="loading"
                :data="tableData"
                stripe
                border
                style="width: 100%">
        <el-table-column prop="planName"
                         label="计划名称"
                         min-width="150" />
        <el-table-column prop="description"
                         label="描述"
                         min-width="200"
                         show-overflow-tooltip />
        <el-table-column prop="formula"
                         label="计算公式"
                         min-width="200"
                         show-overflow-tooltip>
          <template #default="{ row }">
            <el-tag type="info" size="small">{{ row.formula }}</el-tag>
            <el-tag type="info"
                    size="small">{{ row.formula }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="status" label="状态" width="80" align="center">
        <el-table-column prop="status"
                         label="状态"
                         width="80"
                         align="center">
          <template #default="{ row }">
            <el-tag :type="row.status === 'active' ? 'success' : 'info'" size="small">
            <el-tag :type="row.status === 'active' ? 'success' : 'info'"
                    size="small">
              {{ row.status === 'active' ? '启用' : '禁用' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="updateTime" label="最后计算时间" width="160" />
        <el-table-column label="操作" width="200" fixed="right" align="center">
        <el-table-column prop="updateTime"
                         label="最后计算时间"
                         width="160" />
        <el-table-column label="操作"
                         width="200"
                         fixed="right"
                         align="center">
          <template #default="{ row }">
            <el-button type="primary" link @click="handleEdit(row)">编辑</el-button>
            <el-button type="success" link @click="handleCalculate(row)">计算</el-button>
            <el-button type="danger" link @click="handleDelete(row)">删除</el-button>
            <el-button type="primary"
                       link
                       @click="handleEdit(row)">编辑</el-button>
            <el-button type="success"
                       link
                       @click="handleCalculate(row)">计算</el-button>
            <el-button type="danger"
                       link
                       @click="handleDelete(row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <!-- 分页 -->
      <div class="pagination-container">
        <el-pagination
          v-model:current-page="pagination.current"
          v-model:page-size="pagination.size"
          :page-sizes="[10, 20, 50, 100]"
          :total="total"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
        <el-pagination v-model:current-page="pagination.current"
                       v-model:page-size="pagination.size"
                       :page-sizes="[10, 20, 50, 100]"
                       :total="total"
                       layout="total, sizes, prev, pager, next, jumper"
                       @size-change="handleSizeChange"
                       @current-change="handleCurrentChange" />
      </div>
    </el-card>
    <!-- 新增/编辑对话框 -->
    <el-dialog
      v-model="dialogVisible"
      :title="dialogType === 'add' ? '新增采购计划' : '编辑采购计划'"
      width="1000px"
      :close-on-click-modal="false"
    >
    <el-dialog v-model="dialogVisible"
               :title="dialogType === 'add' ? '新增采购计划' : '编辑采购计划'"
               width="1000px"
               :close-on-click-modal="false">
      <div class="form-container">
        <!-- 基本信息 -->
        <div class="form-section">
          <div class="section-title">基本信息</div>
          <el-form
            ref="formRef"
            :model="formData"
            :rules="formRules"
            label-width="120px"
          >
          <el-form ref="formRef"
                   :model="formData"
                   :rules="formRules"
                   label-width="120px">
            <el-row :gutter="20">
              <el-col :span="12">
                <el-form-item label="编码" prop="code">
                  <el-input v-model="formData.code" placeholder="系统自动生成" disabled />
                <el-form-item label="编码"
                              prop="code">
                  <el-input v-model="formData.code"
                            placeholder="系统自动生成"
                            disabled />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="名称" prop="planName" required>
                  <el-input v-model="formData.planName" placeholder="请输入计划名称" />
                <el-form-item label="名称"
                              prop="planName"
                              required>
                  <el-input v-model="formData.planName"
                            placeholder="请输入计划名称" />
                </el-form-item>
              </el-col>
            </el-row>
            <el-form-item label="描述" prop="description">
              <el-input
                v-model="formData.description"
                type="textarea"
                :rows="3"
                placeholder="请输入计划描述"
              />
            <el-form-item label="描述"
                          prop="description">
              <el-input v-model="formData.description"
                        type="textarea"
                        :rows="3"
                        placeholder="请输入计划描述" />
            </el-form-item>
            <el-row :gutter="20">
              <el-col :span="12">
                <el-form-item label="状态" prop="status">
                  <el-select v-model="formData.status" placeholder="请选择状态" style="width: 100%">
                    <el-option label="启用" value="active" />
                    <el-option label="禁用" value="disabled" />
                <el-form-item label="状态"
                              prop="status">
                  <el-select v-model="formData.status"
                             placeholder="请选择状态"
                             style="width: 100%">
                    <el-option label="启用"
                               value="active" />
                    <el-option label="禁用"
                               value="disabled" />
                  </el-select>
                </el-form-item>
              </el-col>
@@ -143,12 +185,13 @@
            </el-row>
          </el-form>
        </div>
        <!-- 计算参数 -->
        <div class="form-section">
          <div class="section-title">计算参数</div>
          <el-tabs v-model="activeTab" class="param-tabs">
            <el-tab-pane label="需求参数" name="demand">
          <el-tabs v-model="activeTab"
                   class="param-tabs">
            <el-tab-pane label="需求参数"
                         name="demand">
              <div class="checkbox-group">
                <el-checkbox v-model="formData.considerExistingStock">考虑现有库存</el-checkbox>
                <el-checkbox v-model="formData.warehouseControl">仓库运行MRP的控制</el-checkbox>
@@ -159,7 +202,8 @@
                <el-checkbox v-model="formData.negativeStockAsDemand">负库存作为需求</el-checkbox>
              </div>
            </el-tab-pane>
            <el-tab-pane label="计算参数" name="calculation">
            <el-tab-pane label="计算参数"
                         name="calculation">
              <div class="checkbox-group">
                <el-checkbox v-model="formData.considerExistingStock">考虑现有库存</el-checkbox>
                <el-checkbox v-model="formData.warehouseControl">仓库运行MRP的控制</el-checkbox>
@@ -172,7 +216,6 @@
            </el-tab-pane>
          </el-tabs>
        </div>
        <!-- 汇总合并选项 -->
        <div class="form-section">
          <div class="section-title">汇总合并选项</div>
@@ -182,129 +225,161 @@
            <el-checkbox v-model="formData.summaryDemandDate">需求日期</el-checkbox>
          </div>
        </div>
        <!-- 计算公式 -->
        <div class="form-section">
          <div class="section-title">计算公式</div>
          <div class="formula-input-section">
            <el-form-item label="计算公式" prop="formula" required>
              <el-input
                v-model="formData.formula"
                placeholder="例如: 预计出库数量 - 现有库存 + 安全库存 - 预计入库数量"
                @input="validateFormula"
              />
            <el-form-item label="计算公式"
                          prop="formula"
                          required>
              <el-input v-model="formData.formula"
                        placeholder="例如: 预计出库数量 - 现有库存 + 安全库存 - 预计入库数量"
                        @input="validateFormula" />
            </el-form-item>
            <div class="formula-help">
              <el-text type="info" size="small">
              <el-text type="info"
                       size="small">
                支持变量:预计出库数量、现有库存、安全库存、预计入库数量
              </el-text>
            </div>
          </div>
        </div>
      </div>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary"
                     @click="handleSubmit"
                     :loading="submitLoading">确定</el-button>
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
        </div>
      </template>
    </el-dialog>
    <!-- 产品选择对话框 -->
    <el-dialog
      v-model="productSelectDialogVisible"
      title="选择产品"
      width="800px"
      :close-on-click-modal="false"
    >
    <el-dialog v-model="productSelectDialogVisible"
               title="选择产品"
               width="800px"
               :close-on-click-modal="false">
      <div class="product-select">
        <el-alert
          title="请选择要计算的产品"
          type="info"
          :closable="false"
          show-icon
        >
        <el-alert title="请选择要计算的产品"
                  type="info"
                  :closable="false"
                  show-icon>
          <template #default>
            <p>选择产品后,系统将根据当前计算公式和产品库存情况进行计算。</p>
          </template>
        </el-alert>
        <el-table
          v-loading="productLoading"
          :data="productList"
          @selection-change="handleProductSelectionChange"
          stripe
          border
          style="width: 100%; margin-top: 20px;"
        >
          <el-table-column type="selection" width="55" />
          <el-table-column prop="productCategory" label="产品大类" min-width="150" />
          <el-table-column prop="specificationModel" label="产品规格" width="120" />
          <el-table-column prop="inboundNum0" label="现有库存" width="100" align="right" />
          <el-table-column prop="inboundNum" label="安全库存" width="100" align="right" />
          <el-table-column prop="inboundNum" label="预计出库" width="100" align="right" />
          <el-table-column prop="inboundNum0" label="预计入库" width="100" align="right" />
        <el-table v-loading="productLoading"
                  :data="productList"
                  @selection-change="handleProductSelectionChange"
                  stripe
                  border
                  style="width: 100%; margin-top: 20px;">
          <el-table-column type="selection"
                           width="55" />
          <el-table-column prop="productCategory"
                           label="产品大类"
                           min-width="150" />
          <el-table-column prop="specificationModel"
                           label="产品规格"
                           width="120" />
          <el-table-column prop="inboundNum0"
                           label="现有库存"
                           width="100"
                           align="right" />
          <el-table-column prop="inboundNum"
                           label="安全库存"
                           width="100"
                           align="right" />
          <el-table-column prop="inboundNum"
                           label="预计出库"
                           width="100"
                           align="right" />
          <el-table-column prop="inboundNum0"
                           label="预计入库"
                           width="100"
                           align="right" />
        </el-table>
      </div>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="productSelectDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="handleConfirmProductSelection" :disabled="selectedProducts.length === 0">
          <el-button type="primary"
                     @click="handleConfirmProductSelection"
                     :disabled="selectedProducts.length === 0">
            确认计算
          </el-button>
          <el-button @click="productSelectDialogVisible = false">取消</el-button>
        </div>
      </template>
    </el-dialog>
    <!-- 计算结果对话框 -->
    <el-dialog
      v-model="calculateDialogVisible"
      title="采购计算结果"
      width="1000px"
      :close-on-click-modal="false"
    >
    <el-dialog v-model="calculateDialogVisible"
               title="采购计算结果"
               width="1000px"
               :close-on-click-modal="false">
      <div class="calculate-result">
        <el-alert
          title="计算结果"
          type="success"
          :closable="false"
          show-icon
        >
        <el-alert title="计算结果"
                  type="success"
                  :closable="false"
                  show-icon>
          <template #default>
            <p>基于当前配置的计算公式和库存情况,系统已计算出各产品的采购需求。</p>
          </template>
        </el-alert>
        <el-table :data="calculateResult" stripe border style="width: 100%; margin-top: 20px;">
          <el-table-column prop="productCategory" label="产品大类" min-width="150" />
          <el-table-column prop="specificationModel" label="产品规格" width="120" />
          <el-table-column prop="inboundNum0" label="现有库存" width="100" align="right" />
          <el-table-column prop="inboundNum" label="安全库存" width="100" align="right" />
          <el-table-column prop="inboundNum" label="预计出库数量" width="120" align="right" />
          <el-table-column prop="inboundNum0" label="预计入库数量" width="120" align="right" />
          <el-table-column prop="weeklyNetDemand" label="按周净需求" width="120" align="right">
        <el-table :data="calculateResult"
                  stripe
                  border
                  style="width: 100%; margin-top: 20px;">
          <el-table-column prop="productCategory"
                           label="产品大类"
                           min-width="150" />
          <el-table-column prop="specificationModel"
                           label="产品规格"
                           width="120" />
          <el-table-column prop="inboundNum0"
                           label="现有库存"
                           width="100"
                           align="right" />
          <el-table-column prop="inboundNum"
                           label="安全库存"
                           width="100"
                           align="right" />
          <el-table-column prop="inboundNum"
                           label="预计出库数量"
                           width="120"
                           align="right" />
          <el-table-column prop="inboundNum0"
                           label="预计入库数量"
                           width="120"
                           align="right" />
          <el-table-column prop="weeklyNetDemand"
                           label="按周净需求"
                           width="120"
                           align="right">
            <template #default="{ row }">
              <el-tag :type="row.weeklyNetDemand > 0 ? 'warning' : 'success'" size="small">
              <el-tag :type="row.weeklyNetDemand > 0 ? 'warning' : 'success'"
                      size="small">
                {{ row.weeklyNetDemand }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="suggestedPurchase" label="建议采购" width="100" align="right">
          <el-table-column prop="suggestedPurchase"
                           label="建议采购"
                           width="100"
                           align="right">
            <template #default="{ row }">
              <el-tag :type="row.suggestedPurchase > 0 ? 'danger' : 'success'" size="small">
              <el-tag :type="row.suggestedPurchase > 0 ? 'danger' : 'success'"
                      size="small">
                {{ row.suggestedPurchase }}
              </el-tag>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary"
                     @click="handleCreatePurchaseOrder">确认</el-button>
          <el-button @click="calculateDialogVisible = false">关闭</el-button>
          <el-button type="primary" @click="handleCreatePurchaseOrder">确认</el-button>
        </div>
      </template>
    </el-dialog>
@@ -312,213 +387,48 @@
</template>
<script setup>
import {ref, reactive, onMounted, getCurrentInstance} from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Search, Refresh, Plus, Download } from '@element-plus/icons-vue'
import {listPage,add,update,del,listPageCopy} from "@/api/procurementManagement/procurementPlan.js"
  import { ref, reactive, onMounted, getCurrentInstance } from "vue";
  import { ElMessage, ElMessageBox } from "element-plus";
  import { Search, Refresh, Plus, Download } from "@element-plus/icons-vue";
  import {
    listPage,
    add,
    update,
    del,
    listPageCopy,
  } from "@/api/procurementManagement/procurementPlan.js";
// 响应式数据
const loading = ref(false)
const submitLoading = ref(false)
const dialogVisible = ref(false)
const productSelectDialogVisible = ref(false)
const calculateDialogVisible = ref(false)
const dialogType = ref('add')
const productLoading = ref(false)
const selectedProducts = ref([])
const currentPlan = ref(null)
  // 响应式数据
  const loading = ref(false);
  const submitLoading = ref(false);
  const dialogVisible = ref(false);
  const productSelectDialogVisible = ref(false);
  const calculateDialogVisible = ref(false);
  const dialogType = ref("add");
  const productLoading = ref(false);
  const selectedProducts = ref([]);
  const currentPlan = ref(null);
// 搜索表单
const searchForm = reactive({
  planName: '',
  status: ''
})
  // 搜索表单
  const searchForm = reactive({
    planName: "",
    status: "",
  });
// 分页数据
const pagination = reactive({
  current: 1,
  size: 20
})
  // 分页数据
  const pagination = reactive({
    current: 1,
    size: 20,
  });
// 表单数据
const formData = reactive({
  code: '',
  planName: '',
  description: '',
  status: '',
  isSystemPreset: false,
  formula: '',
  // 计算参数
  considerExistingStock: false,
  warehouseControl: false,
  calculateTotalDemand: false,
  considerSafetyStock: false,
  considerLockedStock: false,
  notConsiderMaterialAux: false,
  negativeStockAsDemand: false,
  // 汇总合并选项
  summaryMaterial: false,
  summaryAuxAttributes: false,
  summaryDemandDate: false
})
// 当前激活的标签页
const activeTab = ref('demand')
// 表单验证规则
const formRules = {
  planName: [
    { required: true, message: '请输入计划名称', trigger: 'blur' }
  ],
  status: [
    { required: true, message: '请选择状态', trigger: 'change' }
  ],
  formula: [
    { required: true, message: '请输入计算公式', trigger: 'blur' }
  ]
}
// 表格数据
const tableData = ref([])
// 产品列表数据
const productList = ref([
  {
    id: 4,
    productName: '产品D',
    productCode: 'PD004',
    existingStock: 90,
    safetyStock: 40,
    expectedOutbound: 160,
    expectedInbound: 35
  }
])
// 计算结果数据
const calculateResult = ref([
  {
    productName: '产品A',
    existingStock: 100,
    safetyStock: 50,
    expectedOutbound: 200,
    expectedInbound: 30,
    weeklyNetDemand: 120,
    suggestedPurchase: 150
  },
  {
    productName: '产品B',
    existingStock: 80,
    safetyStock: 30,
    expectedOutbound: 150,
    expectedInbound: 20,
    weeklyNetDemand: 100,
    suggestedPurchase: 120
  }
])
const total = ref(0)
// 方法
const handleSearch = () => {
  pagination.current = 1
  loadData()
}
const handleReset = () => {
  Object.assign(searchForm, {
    planName: '',
    status: ''
  })
  handleSearch()
}
const loadData = () => {
  loading.value = true
  listPage({...searchForm,...pagination}).then(res => {
    if(res.code === 200){
      tableData.value = res.data.records
      total.value = res.data.total
      loading.value = false
    }
  })
}
const handleAdd = () => {
  dialogType.value = 'add'
  resetForm()
  // 自动生成编码
  formData.code = 'CGJH' + String(Date.now()).slice(-4)
  dialogVisible.value = true
}
const handleEdit = (row) => {
  dialogType.value = 'edit'
  Object.assign(formData, row)
  dialogVisible.value = true
}
const handleDelete = async (row) => {
  try {
    await ElMessageBox.confirm('确定要删除这个采购计划吗?', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
    let ids = [row.id]
    del(ids).then(res =>{
     if(res.code === 200){
      ElMessage.success('删除成功')
      loadData()
    }
   })
  } catch {
    // 用户取消删除
  }
}
const handleSubmit = async () => {
  try {
    // 表单验证
    if (!formData.planName || !formData.formula) {
      ElMessage.error('请填写必填项')
      return
    }
    submitLoading.value = true
    if (dialogType.value === 'add') {
      add(formData).then(res => {
        if(res.code === 200){
          ElMessage.success('新增成功')
          dialogVisible.value = false
          loadData()
        }
      })
    } else {
      // 编辑
      update(formData).then(res => {
        if(res.code === 200){
          ElMessage.success('编辑成功')
          dialogVisible.value = false
          loadData()
        }
      })
    }
  } catch (error) {
    ElMessage.error('操作失败')
  } finally {
    submitLoading.value = false
  }
}
const resetForm = () => {
  Object.assign(formData, {
    code: '',
    planName: '',
    description: '',
    status: '',
  // 表单数据
  const formData = reactive({
    code: "",
    planName: "",
    description: "",
    status: "",
    isSystemPreset: false,
    formula: '预计出库数量 - 现有库存 + 安全库存 - 预计入库数量',
    formula: "",
    // 计算参数
    considerExistingStock: false,
    warehouseControl: false,
@@ -530,255 +440,420 @@
    // 汇总合并选项
    summaryMaterial: false,
    summaryAuxAttributes: false,
    summaryDemandDate: false
  })
  activeTab.value = 'demand'
}
    summaryDemandDate: false,
  });
const validateFormula = () => {
  // 简单的公式验证
  const formula = formData.formula
  if (formula && !/^[a-zA-Z\u4e00-\u9fa5\s\*\+\-\/\(\)\d\.]+$/.test(formula)) {
    ElMessage.warning('公式格式可能不正确,请检查')
  }
}
  // 当前激活的标签页
  const activeTab = ref("demand");
const handleCalculate = (row) => {
  currentPlan.value = row
  productSelectDialogVisible.value = true
  loadProductList()
}
  // 表单验证规则
  const formRules = {
    planName: [{ required: true, message: "请输入计划名称", trigger: "blur" }],
    status: [{ required: true, message: "请选择状态", trigger: "change" }],
    formula: [{ required: true, message: "请输入计算公式", trigger: "blur" }],
  };
const loadProductList = () => {
  productLoading.value = true
  // 模拟加载产品数据
  listPageCopy({size:-1}).then(res => {
    if(res.code === 200){
      productList.value = res.data.records
      productLoading.value = false
  // 表格数据
  const tableData = ref([]);
  // 产品列表数据
  const productList = ref([
    {
      id: 4,
      productName: "产品D",
      productCode: "PD004",
      existingStock: 90,
      safetyStock: 40,
      expectedOutbound: 160,
      expectedInbound: 35,
    },
  ]);
  // 计算结果数据
  const calculateResult = ref([
    {
      productName: "产品A",
      existingStock: 100,
      safetyStock: 50,
      expectedOutbound: 200,
      expectedInbound: 30,
      weeklyNetDemand: 120,
      suggestedPurchase: 150,
    },
    {
      productName: "产品B",
      existingStock: 80,
      safetyStock: 30,
      expectedOutbound: 150,
      expectedInbound: 20,
      weeklyNetDemand: 100,
      suggestedPurchase: 120,
    },
  ]);
  const total = ref(0);
  // 方法
  const handleSearch = () => {
    pagination.current = 1;
    loadData();
  };
  const handleReset = () => {
    Object.assign(searchForm, {
      planName: "",
      status: "",
    });
    handleSearch();
  };
  const loadData = () => {
    loading.value = true;
    listPage({ ...searchForm, ...pagination }).then(res => {
      if (res.code === 200) {
        tableData.value = res.data.records;
        total.value = res.data.total;
        loading.value = false;
      }
    });
  };
  const handleAdd = () => {
    dialogType.value = "add";
    resetForm();
    // 自动生成编码
    formData.code = "CGJH" + String(Date.now()).slice(-4);
    dialogVisible.value = true;
  };
  const handleEdit = row => {
    dialogType.value = "edit";
    Object.assign(formData, row);
    dialogVisible.value = true;
  };
  const handleDelete = async row => {
    try {
      await ElMessageBox.confirm("确定要删除这个采购计划吗?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      });
      let ids = [row.id];
      del(ids).then(res => {
        if (res.code === 200) {
          ElMessage.success("删除成功");
          loadData();
        }
      });
    } catch {
      // 用户取消删除
    }
  })
}
  };
const handleProductSelectionChange = (selection) => {
  selectedProducts.value = selection
}
  const handleSubmit = async () => {
    try {
      // 表单验证
      if (!formData.planName || !formData.formula) {
        ElMessage.error("请填写必填项");
        return;
      }
const handleConfirmProductSelection = () => {
  if (selectedProducts.value.length === 0) {
    ElMessage.warning('请选择要计算的产品')
    return
  }
  ElMessage.success(`正在计算 ${currentPlan.value.planName} 的采购需求...`)
  productSelectDialogVisible.value = false
  // 根据选择的产品和计算公式进行计算
  calculateWithSelectedProducts()
}
      submitLoading.value = true;
const calculateWithSelectedProducts = () => {
  // 模拟计算过程
  // 根据选择的产品更新计算结果
  const result = selectedProducts.value.map(product => {
    // 这里应该根据实际的计算公式进行计算
    // 示例:预计出库数量 - 现有库存 + 安全库存 - 预计入库数量
    const weeklyNetDemand = product.inboundNum - product.inboundNum0 + product.inboundNum - product.inboundNum0
    const suggestedPurchase = Math.max(0, weeklyNetDemand)
    return {
      productCategory: product.productCategory,
      specificationModel: product.specificationModel,
      inboundNum0: product.inboundNum0,
      inboundNum: product.inboundNum,
      weeklyNetDemand: weeklyNetDemand,
      suggestedPurchase: suggestedPurchase
      if (dialogType.value === "add") {
        add(formData).then(res => {
          if (res.code === 200) {
            ElMessage.success("新增成功");
            dialogVisible.value = false;
            loadData();
          }
        });
      } else {
        // 编辑
        update(formData).then(res => {
          if (res.code === 200) {
            ElMessage.success("编辑成功");
            dialogVisible.value = false;
            loadData();
          }
        });
      }
    } catch (error) {
      ElMessage.error("操作失败");
    } finally {
      submitLoading.value = false;
    }
  })
  };
  calculateResult.value = result
  calculateDialogVisible.value = true
}
  const resetForm = () => {
    Object.assign(formData, {
      code: "",
      planName: "",
      description: "",
      status: "",
      isSystemPreset: false,
      formula: "预计出库数量 - 现有库存 + 安全库存 - 预计入库数量",
      // 计算参数
      considerExistingStock: false,
      warehouseControl: false,
      calculateTotalDemand: false,
      considerSafetyStock: false,
      considerLockedStock: false,
      notConsiderMaterialAux: false,
      negativeStockAsDemand: false,
      // 汇总合并选项
      summaryMaterial: false,
      summaryAuxAttributes: false,
      summaryDemandDate: false,
    });
    activeTab.value = "demand";
  };
  const validateFormula = () => {
    // 简单的公式验证
    const formula = formData.formula;
    if (formula && !/^[a-zA-Z\u4e00-\u9fa5\s\*\+\-\/\(\)\d\.]+$/.test(formula)) {
      ElMessage.warning("公式格式可能不正确,请检查");
    }
  };
const handleCreatePurchaseOrder = () => {
  calculateDialogVisible.value = false
}
const { proxy } = getCurrentInstance();
const handleExport = () => {
  ElMessageBox.confirm("内容将被导出,是否确认导出?", "导出", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning",
  })
  const handleCalculate = row => {
    currentPlan.value = row;
    productSelectDialogVisible.value = true;
    loadProductList();
  };
  const loadProductList = () => {
    productLoading.value = true;
    // 模拟加载产品数据
    listPageCopy({ size: -1 }).then(res => {
      if (res.code === 200) {
        productList.value = res.data.records;
        productLoading.value = false;
      }
    });
  };
  const handleProductSelectionChange = selection => {
    selectedProducts.value = selection;
  };
  const handleConfirmProductSelection = () => {
    if (selectedProducts.value.length === 0) {
      ElMessage.warning("请选择要计算的产品");
      return;
    }
    ElMessage.success(`正在计算 ${currentPlan.value.planName} 的采购需求...`);
    productSelectDialogVisible.value = false;
    // 根据选择的产品和计算公式进行计算
    calculateWithSelectedProducts();
  };
  const calculateWithSelectedProducts = () => {
    // 模拟计算过程
    // 根据选择的产品更新计算结果
    const result = selectedProducts.value.map(product => {
      // 这里应该根据实际的计算公式进行计算
      // 示例:预计出库数量 - 现有库存 + 安全库存 - 预计入库数量
      const weeklyNetDemand =
        product.inboundNum -
        product.inboundNum0 +
        product.inboundNum -
        product.inboundNum0;
      const suggestedPurchase = Math.max(0, weeklyNetDemand);
      return {
        productCategory: product.productCategory,
        specificationModel: product.specificationModel,
        inboundNum0: product.inboundNum0,
        inboundNum: product.inboundNum,
        weeklyNetDemand: weeklyNetDemand,
        suggestedPurchase: suggestedPurchase,
      };
    });
    calculateResult.value = result;
    calculateDialogVisible.value = true;
  };
  const handleCreatePurchaseOrder = () => {
    calculateDialogVisible.value = false;
  };
  const { proxy } = getCurrentInstance();
  const handleExport = () => {
    ElMessageBox.confirm("内容将被导出,是否确认导出?", "导出", {
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning",
    })
      .then(() => {
        proxy.download("/procurementPlan/export", {}, "采购计划.xlsx");
      })
      .catch(() => {
        proxy.$modal.msg("已取消");
      });
}
  };
  const handleSizeChange = size => {
    pagination.size = size;
    loadData();
  };
const handleSizeChange = (size) => {
  pagination.size = size
  loadData()
}
  const handleCurrentChange = current => {
    pagination.current = current;
    loadData();
  };
const handleCurrentChange = (current) => {
  pagination.current = current
  loadData()
}
// 生命周期
onMounted(() => {
  loadData()
})
  // 生命周期
  onMounted(() => {
    loadData();
  });
</script>
<style scoped>
.app-container {
  padding: 20px;
}
  .app-container {
    padding: 20px;
  }
.page-header {
  margin-bottom: 20px;
}
  .page-header {
    margin-bottom: 20px;
  }
.page-header h2 {
  margin: 0 0 8px 0;
  color: #303133;
  font-size: 24px;
  font-weight: 600;
}
  .page-header h2 {
    margin: 0 0 8px 0;
    color: #303133;
    font-size: 24px;
    font-weight: 600;
  }
.page-header p {
  margin: 0;
  color: #909399;
  font-size: 14px;
}
  .page-header p {
    margin: 0;
    color: #909399;
    font-size: 14px;
  }
.search-card {
  margin-bottom: 20px;
}
  .search-card {
    margin-bottom: 20px;
  }
.search-form {
  margin-bottom: 0;
}
  .search-form {
    margin-bottom: 0;
  }
.table-card {
  margin-bottom: 20px;
}
  .table-card {
    margin-bottom: 20px;
  }
.table-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}
  .table-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;
  }
.table-title {
  font-size: 16px;
  font-weight: 600;
  color: #303133;
}
  .table-title {
    font-size: 16px;
    font-weight: 600;
    color: #303133;
  }
.table-actions {
  display: flex;
  gap: 10px;
}
  .table-actions {
    display: flex;
    gap: 10px;
  }
.pagination-container {
  margin-top: 20px;
  display: flex;
  justify-content: end;
}
  .pagination-container {
    margin-top: 20px;
    display: flex;
    justify-content: end;
  }
.form-container {
  padding: 0 20px;
}
  .form-container {
    padding: 0 20px;
  }
.formula-help {
  margin-top: 5px;
}
  .formula-help {
    margin-top: 5px;
  }
.calculate-result {
  padding: 20px 0;
}
  .calculate-result {
    padding: 20px 0;
  }
.dialog-footer {
  text-align: right;
}
  .dialog-footer {
    text-align: right;
  }
:deep(.el-card__body) {
  padding: 20px;
}
  :deep(.el-card__body) {
    padding: 20px;
  }
:deep(.el-table) {
  font-size: 14px;
}
  :deep(.el-table) {
    font-size: 14px;
  }
:deep(.el-form-item__label) {
  font-weight: 500;
}
  :deep(.el-form-item__label) {
    font-weight: 500;
  }
.form-container {
  padding: 0;
}
  .form-container {
    padding: 0;
  }
.form-section {
  margin-bottom: 24px;
  border: 1px solid #e4e7ed;
  border-radius: 6px;
  overflow: hidden;
}
  .form-section {
    margin-bottom: 24px;
    border: 1px solid #e4e7ed;
    border-radius: 6px;
    overflow: hidden;
  }
.section-title {
  background-color: #f5f7fa;
  padding: 12px 16px;
  font-weight: 600;
  color: #303133;
  border-bottom: 1px solid #e4e7ed;
}
  .section-title {
    background-color: #f5f7fa;
    padding: 12px 16px;
    font-weight: 600;
    color: #303133;
    border-bottom: 1px solid #e4e7ed;
  }
.form-section .el-form {
  padding: 20px;
}
  .form-section .el-form {
    padding: 20px;
  }
.param-tabs {
  padding: 20px;
}
  .param-tabs {
    padding: 20px;
  }
.param-tabs :deep(.el-tabs__header) {
  margin-bottom: 20px;
}
  .param-tabs :deep(.el-tabs__header) {
    margin-bottom: 20px;
  }
.param-tabs :deep(.el-tabs__item.is-active) {
  color: #f56c6c;
  border-bottom-color: #f56c6c;
}
  .param-tabs :deep(.el-tabs__item.is-active) {
    color: #f56c6c;
    border-bottom-color: #f56c6c;
  }
.checkbox-group {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
}
  .checkbox-group {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
  }
.checkbox-group .el-checkbox {
  margin-right: 0;
  margin-bottom: 8px;
}
  .checkbox-group .el-checkbox {
    margin-right: 0;
    margin-bottom: 8px;
  }
.formula-input-section {
  padding: 20px;
}
  .formula-input-section {
    padding: 20px;
  }
.formula-input-section .el-form-item {
  margin-bottom: 12px;
}
  .formula-input-section .el-form-item {
    margin-bottom: 12px;
  }
.formula-help {
  text-align: center;
  margin-top: 8px;
}
  .formula-help {
    text-align: center;
    margin-top: 8px;
  }
</style>