|
@@ -1,664 +0,0 @@
|
|
|
-<template>
|
|
|
- <!-- 销售预测表单容器 -->
|
|
|
- <div class="forecast-form-container basic-container">
|
|
|
-
|
|
|
-
|
|
|
- <!-- 表单内容区域 -->
|
|
|
- <div class="forecast-form-content">
|
|
|
- <el-form
|
|
|
- ref="forecastForm"
|
|
|
- :model="formData"
|
|
|
- :rules="dynamicFormRules"
|
|
|
- label-width="120px"
|
|
|
- class="forecast-form"
|
|
|
- >
|
|
|
- <div class="form-section">
|
|
|
- <h3 class="section-title">基本信息</h3>
|
|
|
- <el-row :gutter="20">
|
|
|
- <el-col :span="12" v-if="isEdit">
|
|
|
- <el-form-item label="预测编码" prop="forecastCode">
|
|
|
- <el-input
|
|
|
- v-model="formData.forecastCode"
|
|
|
- placeholder="请输入预测编码"
|
|
|
- disabled
|
|
|
- >
|
|
|
- </el-input>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- <el-col :span="12">
|
|
|
- <el-form-item label="年份" prop="year">
|
|
|
- <el-date-picker
|
|
|
- v-model="formData.year"
|
|
|
- type="year"
|
|
|
- placeholder="请选择年份"
|
|
|
- value-format="yyyy"
|
|
|
- :disabled="isEdit"
|
|
|
- style="width: 100%"
|
|
|
- ></el-date-picker>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
- <el-row :gutter="20">
|
|
|
- <el-col :span="12">
|
|
|
- <el-form-item label="月份" prop="month">
|
|
|
- <el-select
|
|
|
- v-model="formData.month"
|
|
|
- placeholder="请选择月份"
|
|
|
- :disabled="isEdit"
|
|
|
- style="width: 100%"
|
|
|
- >
|
|
|
- <el-option
|
|
|
- v-for="item in monthOptions"
|
|
|
- :key="item.value"
|
|
|
- :label="item.label"
|
|
|
- :value="item.value"
|
|
|
- ></el-option>
|
|
|
- </el-select>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- <el-col :span="12">
|
|
|
- <el-form-item label="客户" prop="customerId">
|
|
|
- <customer-select
|
|
|
- v-model="formData.customerId"
|
|
|
- placeholder="请选择客户"
|
|
|
- @customer-selected="handleCustomerSelected"
|
|
|
- />
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div class="form-section">
|
|
|
- <h3 class="section-title">产品信息</h3>
|
|
|
- <el-row :gutter="20">
|
|
|
- <el-col :span="12">
|
|
|
- <el-form-item label="品牌ID" prop="brandId">
|
|
|
- <el-input
|
|
|
- v-model="formData.brandId"
|
|
|
- placeholder="请输入品牌ID"
|
|
|
- style="width: 100%"
|
|
|
- ></el-input>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- <el-col :span="12">
|
|
|
- <el-form-item label="品牌编码" prop="brandCode">
|
|
|
- <el-input
|
|
|
- v-model="formData.brandCode"
|
|
|
- placeholder="请输入品牌编码"
|
|
|
- style="width: 100%"
|
|
|
- ></el-input>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
- <el-row :gutter="20">
|
|
|
- <el-col :span="12">
|
|
|
- <el-form-item label="品牌名称" prop="brandName">
|
|
|
- <el-input
|
|
|
- v-model="formData.brandName"
|
|
|
- placeholder="请输入品牌名称"
|
|
|
- style="width: 100%"
|
|
|
- ></el-input>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- <el-col :span="12">
|
|
|
- <el-form-item label="物料" prop="itemId">
|
|
|
- <el-select
|
|
|
- v-model="formData.itemId"
|
|
|
- placeholder="请选择物料"
|
|
|
- filterable
|
|
|
- remote
|
|
|
- :remote-method="remoteItemSearch"
|
|
|
- :loading="itemLoading"
|
|
|
- @change="handleItemChange"
|
|
|
- style="width: 100%"
|
|
|
- >
|
|
|
- <el-option
|
|
|
- v-for="item in itemOptions"
|
|
|
- :key="item.id"
|
|
|
- :label="item.name"
|
|
|
- :value="item.id"
|
|
|
- >
|
|
|
- <div style="display: flex; justify-content: space-between">
|
|
|
- <span>{{ item.code }} - {{ item.name }}</span>
|
|
|
- <span style="color: #8492a6; font-size: 13px">
|
|
|
- {{ item.specs || '无规格' }}
|
|
|
- </span>
|
|
|
- </div>
|
|
|
- </el-option>
|
|
|
- </el-select>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
- <el-row :gutter="20">
|
|
|
- <el-col :span="12">
|
|
|
- <el-form-item label="物料编码">
|
|
|
- <el-input
|
|
|
- v-model="formData.itemCode"
|
|
|
- placeholder="选择物料后自动填充"
|
|
|
- disabled
|
|
|
- style="width: 100%"
|
|
|
- ></el-input>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- <el-col :span="12">
|
|
|
- <el-form-item label="物料名称">
|
|
|
- <el-input
|
|
|
- v-model="formData.itemName"
|
|
|
- placeholder="选择物料后自动填充"
|
|
|
- disabled
|
|
|
- style="width: 100%"
|
|
|
- ></el-input>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
- <el-row :gutter="20">
|
|
|
- <el-col :span="12">
|
|
|
- <el-form-item label="物料规格">
|
|
|
- <el-input
|
|
|
- v-model="formData.itemSpecs"
|
|
|
- placeholder="选择物料后自动填充"
|
|
|
- disabled
|
|
|
- style="width: 100%"
|
|
|
- ></el-input>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
- <el-row :gutter="20">
|
|
|
- <el-col :span="12">
|
|
|
- <el-form-item label="预测数量" prop="forecastQuantity">
|
|
|
- <div class="forecast-quantity-section">
|
|
|
- <el-input-number
|
|
|
- v-model="formData.forecastQuantity"
|
|
|
- :min="1"
|
|
|
- :precision="0"
|
|
|
- :step="1"
|
|
|
- controls-position="right"
|
|
|
- style="width: 100%"
|
|
|
- class="quantity-input"
|
|
|
- ></el-input-number>
|
|
|
- <div class="inventory-display" v-if="currentInventory !== null">
|
|
|
- 当前库存: {{ currentInventory }}
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- 审批信息区域 - 仅在编辑模式下显示 -->
|
|
|
- <div class="form-section" v-if="isEdit && formData.approvalStatus !== undefined">
|
|
|
- <h3 class="section-title">审批信息</h3>
|
|
|
- <div class="approval-info">
|
|
|
- <div class="info-item">
|
|
|
- <span class="label">审批状态:</span>
|
|
|
- <span class="value">
|
|
|
- <el-tag :type="getApprovalStatusType(formData.approvalStatus)">
|
|
|
- {{ getApprovalStatusLabel(formData.approvalStatus) }}
|
|
|
- </el-tag>
|
|
|
- </span>
|
|
|
- </div>
|
|
|
- <div class="info-item" v-if="formData.approver">
|
|
|
- <span class="label">审批人:</span>
|
|
|
- <span class="value">{{ formData.approver }}</span>
|
|
|
- </div>
|
|
|
- <div class="info-item" v-if="formData.approvalTime">
|
|
|
- <span class="label">审批时间:</span>
|
|
|
- <span class="value">{{ formData.approvalTime }}</span>
|
|
|
- </div>
|
|
|
- <div class="info-item" v-if="formData.approvalRemark">
|
|
|
- <span class="label">审批备注:</span>
|
|
|
- <span class="value">{{ formData.approvalRemark }}</span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </el-form>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-</template>
|
|
|
-
|
|
|
-<script>
|
|
|
-import forecastFormMixin from './index.js'
|
|
|
-import CustomerSelect from '@/components/common/customer-select.vue'
|
|
|
-import { getApprovalStatusLabel, getApprovalStatusType } from '@/constants/forecast'
|
|
|
-import { addForecast, updateForecast } from '@/api/forecast'
|
|
|
-
|
|
|
-/**
|
|
|
- * 销售预测表单组件
|
|
|
- * @description 基于Element UI的销售预测表单组件,支持新增和编辑销售预测功能
|
|
|
- */
|
|
|
-export default {
|
|
|
- name: 'ForecastForm',
|
|
|
- mixins: [forecastFormMixin],
|
|
|
-
|
|
|
- /**
|
|
|
- * 组件注册
|
|
|
- */
|
|
|
- components: {
|
|
|
- CustomerSelect
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 组件数据
|
|
|
- */
|
|
|
- data() {
|
|
|
- return {
|
|
|
- /**
|
|
|
- * 月份选项
|
|
|
- * @type {Array<{label: string, value: string}>}
|
|
|
- */
|
|
|
- monthOptions: [
|
|
|
- { label: '1月', value: '01' },
|
|
|
- { label: '2月', value: '02' },
|
|
|
- { label: '3月', value: '03' },
|
|
|
- { label: '4月', value: '04' },
|
|
|
- { label: '5月', value: '05' },
|
|
|
- { label: '6月', value: '06' },
|
|
|
- { label: '7月', value: '07' },
|
|
|
- { label: '8月', value: '08' },
|
|
|
- { label: '9月', value: '09' },
|
|
|
- { label: '10月', value: '10' },
|
|
|
- { label: '11月', value: '11' },
|
|
|
- { label: '12月', value: '12' }
|
|
|
- ],
|
|
|
-
|
|
|
- /**
|
|
|
- * 品牌选项
|
|
|
- * @type {Array<{id: string, code: string, name: string}>}
|
|
|
- */
|
|
|
- brandOptions: [],
|
|
|
-
|
|
|
- /**
|
|
|
- * 物料选项
|
|
|
- * @type {Array<{id: string, code: string, name: string, specs: string}>}
|
|
|
- */
|
|
|
- itemOptions: [],
|
|
|
-
|
|
|
- /**
|
|
|
- * 品牌加载状态
|
|
|
- * @type {boolean}
|
|
|
- */
|
|
|
- brandLoading: false,
|
|
|
-
|
|
|
- /**
|
|
|
- * 物料加载状态
|
|
|
- * @type {boolean}
|
|
|
- */
|
|
|
- itemLoading: false,
|
|
|
-
|
|
|
- /**
|
|
|
- * 当前库存
|
|
|
- * @type {number|null}
|
|
|
- */
|
|
|
- currentInventory: null,
|
|
|
-
|
|
|
- /**
|
|
|
- * 保存加载状态
|
|
|
- * @type {boolean}
|
|
|
- */
|
|
|
- saveLoading: false,
|
|
|
-
|
|
|
- /**
|
|
|
- * 表单数据
|
|
|
- * @type {Object}
|
|
|
- */
|
|
|
- formData: (() => {
|
|
|
- const now = new Date()
|
|
|
- const currentYear = now.getFullYear()
|
|
|
- const currentMonth = now.getMonth() + 1
|
|
|
-
|
|
|
- let nextYear, nextMonth
|
|
|
- if (currentMonth === 12) {
|
|
|
- // 当前是12月,下个月是明年1月
|
|
|
- nextYear = currentYear + 1
|
|
|
- nextMonth = 1
|
|
|
- } else {
|
|
|
- // 其他月份,直接 +1
|
|
|
- nextYear = currentYear
|
|
|
- nextMonth = currentMonth + 1
|
|
|
- }
|
|
|
-
|
|
|
- return {
|
|
|
- forecastCode: '', // 预测编码
|
|
|
- year: nextYear.toString(), // 年份
|
|
|
- month: nextMonth.toString().padStart(2, '0'), // 月份
|
|
|
- customerId: '', // 客户ID
|
|
|
- customerCode: '', // 客户编码
|
|
|
- customerName: '', // 客户名称
|
|
|
- brandId: '', // 品牌ID
|
|
|
- brandCode: '', // 品牌编码
|
|
|
- brandName: '', // 品牌名称
|
|
|
- itemId: '', // 物料ID
|
|
|
- itemCode: '', // 物料编码
|
|
|
- itemName: '', // 物料名称
|
|
|
- itemSpecs: '', // 物料规格
|
|
|
- forecastQuantity: '', // 预测数量
|
|
|
- currentInventory: '', // 当前库存
|
|
|
- approvalStatus: 0, // 审批状态
|
|
|
- approvalRemark: '' // 审批备注
|
|
|
- }
|
|
|
- })(),
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 计算属性
|
|
|
- * @description 组件的响应式计算属性
|
|
|
- */
|
|
|
- computed: {
|
|
|
- /**
|
|
|
- * 表单标题
|
|
|
- * @description 根据编辑模式动态显示表单标题
|
|
|
- * @returns {string} 表单标题文本
|
|
|
- */
|
|
|
- formTitle() {
|
|
|
- return this.isEdit ? '编辑销售预测' : '新增销售预测'
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 动态表单验证规则
|
|
|
- * @description 根据编辑模式动态生成验证规则
|
|
|
- * @returns {Object} 表单验证规则对象
|
|
|
- */
|
|
|
- dynamicFormRules() {
|
|
|
- const rules = { ...this.formRules }
|
|
|
-
|
|
|
- // 新增模式时,移除预测编码的验证规则
|
|
|
- if (!this.isEdit) {
|
|
|
- delete rules.forecastCode
|
|
|
- }
|
|
|
-
|
|
|
- return rules
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 组件属性定义
|
|
|
- * @description 定义组件接收的外部属性及其类型约束
|
|
|
- */
|
|
|
- props: {
|
|
|
- /**
|
|
|
- * 表单可见性控制
|
|
|
- * @description 控制销售预测表单的显示和隐藏状态
|
|
|
- * @type {boolean}
|
|
|
- * @default false
|
|
|
- */
|
|
|
- visible: {
|
|
|
- type: Boolean,
|
|
|
- default: false,
|
|
|
- validator: (value) => typeof value === 'boolean'
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 编辑模式标识
|
|
|
- * @description 标识当前表单是新增模式还是编辑模式
|
|
|
- * @type {boolean}
|
|
|
- * @default false
|
|
|
- */
|
|
|
- isEdit: {
|
|
|
- type: Boolean,
|
|
|
- default: false,
|
|
|
- validator: (value) => typeof value === 'boolean'
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 预测记录唯一标识
|
|
|
- * @description 编辑模式下用于标识要编辑的预测记录
|
|
|
- * @type {string|number|null}
|
|
|
- * @default null
|
|
|
- */
|
|
|
- forecastId: {
|
|
|
- type: [String, Number],
|
|
|
- default: null,
|
|
|
- validator: (value) => {
|
|
|
- return value === null ||
|
|
|
- typeof value === 'string' ||
|
|
|
- typeof value === 'number'
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 方法定义
|
|
|
- * @description 组件的方法和事件处理函数
|
|
|
- */
|
|
|
- methods: {
|
|
|
- /**
|
|
|
- * 获取审批状态标签
|
|
|
- * @param {string|number} status - 审批状态值
|
|
|
- * @returns {string} 审批状态标签文本
|
|
|
- */
|
|
|
- getApprovalStatusLabel,
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取审批状态类型
|
|
|
- * @param {string|number} status - 审批状态值
|
|
|
- * @returns {string} 审批状态类型(用于标签样式)
|
|
|
- */
|
|
|
- getApprovalStatusType,
|
|
|
-
|
|
|
- /**
|
|
|
- * 返回列表
|
|
|
- * @description 处理返回列表按钮点击事件
|
|
|
- */
|
|
|
- handleBack() {
|
|
|
- this.$emit('close')
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 保存表单
|
|
|
- * @description 处理保存按钮点击事件
|
|
|
- */
|
|
|
- handleSave() {
|
|
|
- this.submitForm()
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 处理客户选择事件
|
|
|
- * @description 当用户选择客户时更新表单数据中的客户相关字段
|
|
|
- * @param {Object} customerInfo - 客户信息对象
|
|
|
- * @param {string|number} customerInfo.customerId - 客户ID
|
|
|
- * @param {string} customerInfo.customerCode - 客户编码
|
|
|
- * @param {string} customerInfo.customerName - 客户名称
|
|
|
- * @param {Object} customerInfo.customerData - 完整的客户数据对象
|
|
|
- */
|
|
|
- handleCustomerSelected(customerInfo) {
|
|
|
- if (customerInfo) {
|
|
|
- this.formData.customerId = customerInfo.customerId
|
|
|
- this.formData.customerCode = customerInfo.customerCode
|
|
|
- this.formData.customerName = customerInfo.customerName
|
|
|
- } else {
|
|
|
- this.formData.customerId = ''
|
|
|
- this.formData.customerCode = ''
|
|
|
- this.formData.customerName = ''
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 远程搜索品牌
|
|
|
- * @description 根据输入关键词远程搜索品牌数据
|
|
|
- * @param {string} query - 搜索关键词
|
|
|
- */
|
|
|
- remoteBrandSearch(query) {
|
|
|
- // 简化实现,实际应该调用API
|
|
|
- this.brandLoading = true
|
|
|
- setTimeout(() => {
|
|
|
- this.brandOptions = [
|
|
|
- { id: '1', code: 'B001', name: '品牌A' },
|
|
|
- { id: '2', code: 'B002', name: '品牌B' },
|
|
|
- { id: '3', code: 'B003', name: '品牌C' }
|
|
|
- ].filter(item =>
|
|
|
- item.name.toLowerCase().includes(query.toLowerCase()) ||
|
|
|
- item.code.toLowerCase().includes(query.toLowerCase())
|
|
|
- )
|
|
|
- this.brandLoading = false
|
|
|
- }, 500)
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 处理品牌选择变更
|
|
|
- * @description 当用户选择品牌时更新表单数据
|
|
|
- * @param {string|number} brandId - 选中的品牌ID
|
|
|
- */
|
|
|
- handleBrandChange(brandId) {
|
|
|
- const selectedBrand = this.brandOptions.find(item => item.id === brandId)
|
|
|
- if (selectedBrand) {
|
|
|
- this.formData.brandId = selectedBrand.id
|
|
|
- this.formData.brandCode = selectedBrand.code
|
|
|
- this.formData.brandName = selectedBrand.name
|
|
|
- } else {
|
|
|
- this.formData.brandId = ''
|
|
|
- this.formData.brandCode = ''
|
|
|
- this.formData.brandName = ''
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 远程搜索物料
|
|
|
- * @description 根据输入关键词远程搜索物料数据
|
|
|
- * @param {string} query - 搜索关键词
|
|
|
- */
|
|
|
- remoteItemSearch(query) {
|
|
|
- // 简化实现,实际应该调用API
|
|
|
- this.itemLoading = true
|
|
|
- setTimeout(() => {
|
|
|
- this.itemOptions = [
|
|
|
- { id: '1', code: 'M001', name: '物料A', specs: '规格A' },
|
|
|
- { id: '2', code: 'M002', name: '物料B', specs: '规格B' },
|
|
|
- { id: '3', code: 'M003', name: '物料C', specs: '规格C' }
|
|
|
- ].filter(item =>
|
|
|
- item.name.toLowerCase().includes(query.toLowerCase()) ||
|
|
|
- item.code.toLowerCase().includes(query.toLowerCase())
|
|
|
- )
|
|
|
- this.itemLoading = false
|
|
|
- }, 500)
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 处理物料选择变更
|
|
|
- * @description 当用户选择物料时更新表单数据
|
|
|
- * @param {string|number} itemId - 选中的物料ID
|
|
|
- */
|
|
|
- handleItemChange(itemId) {
|
|
|
- const selectedItem = this.itemOptions.find(item => item.id === itemId)
|
|
|
- if (selectedItem) {
|
|
|
- this.formData.itemId = selectedItem.id
|
|
|
- this.formData.itemCode = selectedItem.code
|
|
|
- this.formData.itemName = selectedItem.name
|
|
|
- this.formData.itemSpecs = selectedItem.specs
|
|
|
-
|
|
|
- // 获取当前库存信息
|
|
|
- this.getCurrentInventory(selectedItem.id)
|
|
|
- } else {
|
|
|
- this.formData.itemId = ''
|
|
|
- this.formData.itemCode = ''
|
|
|
- this.formData.itemName = ''
|
|
|
- this.formData.itemSpecs = ''
|
|
|
- this.currentInventory = null
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取当前库存
|
|
|
- * @description 根据物料ID获取当前库存信息
|
|
|
- * @param {string|number} itemId - 物料ID
|
|
|
- */
|
|
|
- getCurrentInventory(itemId) {
|
|
|
- // 简化实现,实际应该调用API
|
|
|
- setTimeout(() => {
|
|
|
- // 模拟随机库存数量
|
|
|
- this.currentInventory = Math.floor(Math.random() * 1000)
|
|
|
- }, 300)
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 生成预测编码
|
|
|
- * @description 自动生成预测编码
|
|
|
- */
|
|
|
- generateForecastCode() {
|
|
|
- // 生成格式为 FC-YYYYMM-XXXX 的编码
|
|
|
- // FC: 固定前缀
|
|
|
- // YYYYMM: 年月
|
|
|
- // XXXX: 4位随机数
|
|
|
- const now = new Date()
|
|
|
- const year = this.formData.year || now.getFullYear().toString()
|
|
|
- const month = this.formData.month || (now.getMonth() + 1).toString().padStart(2, '0')
|
|
|
- const random = Math.floor(1000 + Math.random() * 9000) // 生成1000-9999之间的随机数
|
|
|
-
|
|
|
- this.formData.forecastCode = `FC-${year}${month}-${random}`
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 准备提交数据
|
|
|
- * @description 复制表单数据并进行清理和格式化处理
|
|
|
- * @returns {Object} 准备好的提交数据
|
|
|
- * @private
|
|
|
- */
|
|
|
- prepareSubmitData() {
|
|
|
- const submitData = { ...this.formData }
|
|
|
-
|
|
|
- // 转换年份为数字
|
|
|
- if (submitData.year && typeof submitData.year === 'string') {
|
|
|
- submitData.year = parseInt(submitData.year, 10)
|
|
|
- }
|
|
|
-
|
|
|
- // 确保数值字段为数字类型
|
|
|
- if (submitData.forecastQuantity) {
|
|
|
- submitData.forecastQuantity = Number(submitData.forecastQuantity)
|
|
|
- }
|
|
|
-
|
|
|
- if (submitData.currentInventory) {
|
|
|
- submitData.currentInventory = Number(submitData.currentInventory)
|
|
|
- }
|
|
|
-
|
|
|
- return submitData
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 表单提交
|
|
|
- * @description 提交表单数据,根据编辑模式调用不同的API
|
|
|
- * @returns {Promise<void>}
|
|
|
- */
|
|
|
- async submitForm() {
|
|
|
- try {
|
|
|
- // 表单验证
|
|
|
- await this.$refs.forecastForm.validate()
|
|
|
-
|
|
|
- this.saveLoading = true
|
|
|
-
|
|
|
- // 准备提交数据
|
|
|
- const submitData = this.prepareSubmitData()
|
|
|
-
|
|
|
- let res
|
|
|
- if (this.isEdit) {
|
|
|
- res = await updateForecast(submitData)
|
|
|
- } else {
|
|
|
- res = await addForecast(submitData)
|
|
|
- }
|
|
|
-
|
|
|
- if (res.data && res.data.success) {
|
|
|
- // 触发提交成功事件,传递API响应数据
|
|
|
- this.$emit('submit', res.data)
|
|
|
-
|
|
|
- // 关闭表单
|
|
|
- this.$emit('close')
|
|
|
- } else {
|
|
|
- this.$message.error(res.data?.msg || (this.isEdit ? '修改失败' : '添加失败'))
|
|
|
- }
|
|
|
- } catch (error) {
|
|
|
- if (error.fields) {
|
|
|
- // 表单验证失败
|
|
|
- return
|
|
|
- }
|
|
|
- console.error('保存失败:', error)
|
|
|
- this.$message.error('保存失败,请稍后重试')
|
|
|
- } finally {
|
|
|
- this.saveLoading = false
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-</script>
|
|
|
-
|
|
|
-<style lang="scss">
|
|
|
-@import './index.scss';
|
|
|
-</style>
|