212 lines
5.6 KiB
Vue
212 lines
5.6 KiB
Vue
<template>
|
|
<el-dialog
|
|
:model-value="modelValue"
|
|
:title="isEdit ? '编辑定价方案' : '新建定价方案'"
|
|
width="500px"
|
|
@update:model-value="$emit('update:modelValue', $event)"
|
|
@close="handleClose"
|
|
>
|
|
<el-form
|
|
ref="formRef"
|
|
:model="formData"
|
|
:rules="rules"
|
|
label-width="100px"
|
|
>
|
|
<el-form-item label="项目" prop="project_id">
|
|
<el-select
|
|
v-model="formData.project_id"
|
|
placeholder="请选择项目"
|
|
filterable
|
|
style="width: 100%"
|
|
:disabled="isEdit"
|
|
>
|
|
<el-option
|
|
v-for="item in projectList"
|
|
:key="item.id"
|
|
:label="item.project_name"
|
|
:value="item.id"
|
|
/>
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item label="方案名称" prop="plan_name">
|
|
<el-input v-model="formData.plan_name" placeholder="请输入方案名称" />
|
|
</el-form-item>
|
|
<el-form-item label="策略类型" prop="strategy_type">
|
|
<el-radio-group v-model="formData.strategy_type">
|
|
<el-radio-button
|
|
v-for="item in strategyTypeOptions"
|
|
:key="item.value"
|
|
:value="item.value"
|
|
>
|
|
{{ item.label }}
|
|
</el-radio-button>
|
|
</el-radio-group>
|
|
</el-form-item>
|
|
<el-form-item label="目标毛利率" prop="target_margin">
|
|
<el-input-number
|
|
v-model="formData.target_margin"
|
|
:min="0"
|
|
:max="100"
|
|
:precision="1"
|
|
controls-position="right"
|
|
style="width: 100%"
|
|
/>
|
|
<span class="ml-2">%</span>
|
|
</el-form-item>
|
|
<el-form-item v-if="isEdit" label="最终定价" prop="final_price">
|
|
<el-input-number
|
|
v-model="formData.final_price"
|
|
:min="0"
|
|
:precision="2"
|
|
controls-position="right"
|
|
style="width: 100%"
|
|
/>
|
|
<span class="ml-2">元</span>
|
|
</el-form-item>
|
|
<el-form-item v-if="isEdit" label="状态" prop="is_active">
|
|
<el-switch v-model="formData.is_active" />
|
|
</el-form-item>
|
|
</el-form>
|
|
|
|
<template #footer>
|
|
<el-button @click="handleClose">取消</el-button>
|
|
<el-button type="primary" :loading="loading" @click="handleSubmit">
|
|
{{ isEdit ? '保存' : '创建' }}
|
|
</el-button>
|
|
</template>
|
|
</el-dialog>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, computed, watch } from 'vue'
|
|
import { ElMessage, type FormInstance, type FormRules } from 'element-plus'
|
|
import {
|
|
pricingApi,
|
|
strategyTypeOptions,
|
|
type PricingPlan,
|
|
type PricingPlanCreate,
|
|
type PricingPlanUpdate,
|
|
type StrategyType,
|
|
} from '@/api/pricing'
|
|
import type { Project } from '@/api/projects'
|
|
|
|
const props = defineProps<{
|
|
modelValue: boolean
|
|
editData: PricingPlan | null
|
|
projectList: Project[]
|
|
}>()
|
|
|
|
const emit = defineEmits<{
|
|
(e: 'update:modelValue', value: boolean): void
|
|
(e: 'success'): void
|
|
}>()
|
|
|
|
const formRef = ref<FormInstance>()
|
|
const loading = ref(false)
|
|
|
|
const isEdit = computed(() => !!props.editData?.id)
|
|
|
|
// 表单数据
|
|
const formData = ref<{
|
|
project_id: number | null
|
|
plan_name: string
|
|
strategy_type: StrategyType
|
|
target_margin: number
|
|
final_price: number | null
|
|
is_active: boolean
|
|
}>({
|
|
project_id: null,
|
|
plan_name: '',
|
|
strategy_type: 'profit',
|
|
target_margin: 50,
|
|
final_price: null,
|
|
is_active: true,
|
|
})
|
|
|
|
// 表单验证规则
|
|
const rules: FormRules = {
|
|
project_id: [{ required: true, message: '请选择项目', trigger: 'change' }],
|
|
plan_name: [
|
|
{ required: true, message: '请输入方案名称', trigger: 'blur' },
|
|
{ min: 1, max: 100, message: '长度在 1 到 100 个字符', trigger: 'blur' },
|
|
],
|
|
strategy_type: [{ required: true, message: '请选择策略类型', trigger: 'change' }],
|
|
target_margin: [{ required: true, message: '请输入目标毛利率', trigger: 'blur' }],
|
|
}
|
|
|
|
// 监听编辑数据
|
|
watch(
|
|
() => props.editData,
|
|
(val) => {
|
|
if (val) {
|
|
formData.value = {
|
|
project_id: val.project_id,
|
|
plan_name: val.plan_name,
|
|
strategy_type: val.strategy_type as StrategyType,
|
|
target_margin: val.target_margin,
|
|
final_price: val.final_price,
|
|
is_active: val.is_active,
|
|
}
|
|
} else {
|
|
resetForm()
|
|
}
|
|
},
|
|
{ immediate: true }
|
|
)
|
|
|
|
// 重置表单
|
|
const resetForm = () => {
|
|
formData.value = {
|
|
project_id: null,
|
|
plan_name: '',
|
|
strategy_type: 'profit',
|
|
target_margin: 50,
|
|
final_price: null,
|
|
is_active: true,
|
|
}
|
|
formRef.value?.clearValidate()
|
|
}
|
|
|
|
// 关闭对话框
|
|
const handleClose = () => {
|
|
emit('update:modelValue', false)
|
|
resetForm()
|
|
}
|
|
|
|
// 提交
|
|
const handleSubmit = async () => {
|
|
const valid = await formRef.value?.validate()
|
|
if (!valid) return
|
|
|
|
loading.value = true
|
|
try {
|
|
if (isEdit.value) {
|
|
const updateData: PricingPlanUpdate = {
|
|
plan_name: formData.value.plan_name,
|
|
strategy_type: formData.value.strategy_type,
|
|
target_margin: formData.value.target_margin,
|
|
final_price: formData.value.final_price || undefined,
|
|
is_active: formData.value.is_active,
|
|
}
|
|
await pricingApi.update(props.editData!.id, updateData)
|
|
ElMessage.success('更新成功')
|
|
} else {
|
|
const createData: PricingPlanCreate = {
|
|
project_id: formData.value.project_id!,
|
|
plan_name: formData.value.plan_name,
|
|
strategy_type: formData.value.strategy_type,
|
|
target_margin: formData.value.target_margin,
|
|
}
|
|
await pricingApi.create(createData)
|
|
ElMessage.success('创建成功')
|
|
}
|
|
emit('success')
|
|
handleClose()
|
|
} catch (error) {
|
|
console.error('操作失败:', error)
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
</script>
|