admin-vue3/src/views/crm/project/ProjectForm.vue

469 lines
16 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="100px"
v-loading="formLoading"
>
<el-row>
<el-col :span="12">
<el-form-item label="项目名称" prop="deptId">
<el-select
filterable
clearable
v-model="formData.deptId"
class="w-1/1"
>
<el-option
v-for="item in deptList"
:key="item.id"
:label="item.name"
:value="item.id ?? ''"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="场地ID" prop="siteId">
<el-select
filterable
clearable
v-model="formData.siteId"
class="w-1/1"
>
<el-option
v-for="item in siteOptions"
:key="item.id"
:label="item.name"
:value="item.id ?? ''"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="类型" prop="type">
<el-select v-model="formData.type" placeholder="请选择类型">
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_PROJECT_TYPE)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="状态" prop="projectStatus">
<el-radio-group
v-model="formData.projectStatus"
>
<el-radio :value=0>开启</el-radio>
<el-radio :value=1>关闭</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="项目投资额" prop="totalInvestment">
<el-input-number v-model="formData.totalInvestment" :min="0" :step="1" placeholder="请输入项目投资额" class="w-1/1" />
<span class="ml-2">万元</span>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="场地枪数" prop="estimatedPiles">
<el-input v-model="estimatedPiles" readonly placeholder="自动带出" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item :label-width="120" label="单把充电枪成本" prop="gunCost">
<el-input :value="gunCost" readonly placeholder="自动计算" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="场地合同" prop="cooperationAgreement">
<el-select
filterable
clearable
v-model="formData.cooperationAgreement"
class="w-1/1"
>
<el-option
v-for="item in contractOptions"
:key="item.id"
:label="item.name"
:value="item.id ?? ''"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="EPC合同" prop="epcContractId">
<el-select
filterable
clearable
v-model="formData.epcContractId"
class="w-1/1"
>
<el-option
v-for="item in contractOptions"
:key="item.id"
:label="item.name"
:value="item.id ?? ''"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="设备合同" prop="purchaseContractId">
<el-select
filterable
clearable
v-model="formData.purchaseContractId"
class="w-1/1"
>
<el-option
v-for="item in contractOptions"
:key="item.id"
:label="item.name"
:value="item.id ?? ''"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="供电类型" prop="powerSupplyType">
<el-select v-model="formData.powerSupplyType" placeholder="请选择类型">
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_PROJECT_POWER_SUPPLY_TYPE)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item v-if="formData.type === 2 || formData.type === 3"
label="合作投资协议日期"
prop="investmentAgreementDate"
label-width="150px"
>
<el-date-picker
v-model="formData.investmentAgreementDate"
type="date"
placeholder="选择合作投资协议日期"
style="width: 100%"
format="YYYY-MM-DD"
popper-class="full-width-datepicker"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col>
<el-tabs v-if="formData.type === 2" v-model="subTabsName" class="-mt-15px mb-10px">
<el-tab-pane label="合伙人明细" name="partner">
<ProjectPartnerForm
ref="partnerFormRef"
v-model:partners="formData.partners"
:disabled="formLoading"
:price="formData.totalInvestment"
:id="formData.id"
/>
</el-tab-pane>
</el-tabs>
<el-tabs v-if="formData.type === 3" v-model="subTabsName" class="-mt-15px mb-10px">
<el-tab-pane label="分成方明细" name="partner">
<ProjectRevenueSharePartnerForm
ref="revenueSharePartnerFromRef"
:partners="formData.revenueSharePartners"
:disabled="formLoading"
/>
</el-tab-pane>
</el-tabs>
</el-col>
</el-row>
<el-divider>附件</el-divider>
<el-row>
<el-col :span="12">
<el-form-item label="同意建桩证明" prop="buildPermit" label-width="120px">
<UploadFile
v-model="formData.buildPermit"
:isShowTip="false"
:limit="1"
:file-size="20"
:file-type="['pdf']"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="场地权属证明" prop="ownershipProof" label-width="120px">
<UploadFile
v-model="formData.ownershipProof"
:isShowTip="false"
:limit="1"
:file-size="20"
:file-type="['pdf']"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="项目备案" prop="projectRecord" label-width="120px">
<UploadFile
v-model="formData.projectRecord"
:isShowTip="false"
:limit="1"
:file-size="20"
:file-type="['pdf']"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="其他补充材料" prop="supplementaryMaterials" label-width="120px">
<UploadFile
v-model="formData.supplementaryMaterials"
:isShowTip="false"
:limit="5"
:file-size="20"
:file-type="['pdf']"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col v-if="formData.type === 2" :span="12">
<el-form-item label="合作投资协议" prop="investmentAgreement" label-width="120px">
<UploadFile
v-model="formData.investmentAgreement"
:isShowTip="false"
:limit="1"
:file-size="20"
:file-type="['pdf']"
/>
</el-form-item>
</el-col>
<el-col v-if="formData.type === 3" :span="12">
<el-form-item label="合作分成协议" prop="investmentShareAgreement" label-width="120px">
<UploadFile
v-model="formData.investmentShareAgreement"
:isShowTip="false"
:limit="1"
:file-size="20"
:file-type="['pdf']"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item v-if="formData.powerSupplyType === 2" label="供电答复单" prop="powerSupplyReply" label-width="120px">
<UploadFile
v-model="formData.powerSupplyReply"
:isShowTip="false"
:limit="1"
:file-size="20"
:file-type="['pdf']"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import * as ProjectApi from '@/api/crm/project'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import * as DeptApi from '@/api/system/dept'
import * as ContractApi from '@/api/crm/contract'
import * as StationSiteApi from '@/api/crm/stationsite'
import ProjectPartnerForm from './component/ProjectPartnerForm.vue'
import ProjectRevenueSharePartnerForm from './component/ProjectRevenueSharePartnerForm.vue'
import UploadFile from '@/components/UploadFile/src/UploadFile.vue'
/** CRM 项目信息 表单 */
defineOptions({ name: 'ProjectForm' })
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('') // 弹窗的标题
const formLoading = ref(false) // 表单的加载中1修改时的数据加载2提交的按钮禁用
const formType = ref('') // 表单的类型create - 新增update - 修改
const formData = ref({
id: undefined,
deptId: undefined,
siteId: undefined,
totalInvestment: 0,
purchaseContractId: undefined,
cooperationAgreement:undefined,
epcContractId: undefined,
buildPermit: '',
ownershipProof: '',
projectRecord: '',
powerSupplyReply: '',
investmentAgreement: '',
investmentAgreementDate: undefined,
investmentShareAgreement: '',
supplementaryMaterials: [],
partners:[],
revenueSharePartners:[],
type: undefined,
projectStatus: undefined,
powerSupplyType: undefined
})
const formRules = computed(() => ({
deptId: [{ required: true, message: '部门ID不能为空', trigger: 'blur' }],
siteId: [{ required: true, message: '场地ID不能为空', trigger: 'blur' }],
totalInvestment: [{ required: true, message: '项目总投资额不能为空', trigger: 'blur' }],
type: [{ required: true, message: '类型不能为空', trigger: 'change' }],
projectStatus: [{ required: true, message: '状态不能为空', trigger: 'blur' }],
powerSupplyType: [{ required: true, message: '供电类型不能为空', trigger: 'blur' }],
cooperationAgreement: [{ required: true, message: '场地合同不能为空', trigger: 'blur' }],
epcContractId: [{ required: true, message: 'EPC合同不能为空', trigger: 'blur' }],
purchaseContractId: [{ required: true, message: '设备合同不能为空', trigger: 'blur' }],
investmentAgreementDate: [{ required: true, message: '合作投资协议日期不能为空', trigger: 'blur' }],
}))
const formRef = ref() // 表单 Ref
const deptList = ref<DeptApi.DeptVO[]>([])
const contractOptions = ref<ContractApi.ContractVO[]>([]) // 合同列表
const siteOptions = ref<StationSiteApi.StationSiteVO[]>([]) // 场地列表
const partnerFormRef = ref()
const revenueSharePartnerFromRef = ref()
const estimatedPiles = ref<number | undefined>(undefined)
/** 子表的表单 */
const subTabsName = ref('partner')
const gunCost = computed(() => {
if (!estimatedPiles.value || !formData.value.totalInvestment) return ''
if (Number(estimatedPiles.value) === 0) return ''
return (Number(formData.value.totalInvestment) / Number(estimatedPiles.value)).toFixed(2)
})
watch(
() => formData.value.siteId,
async (siteId) => {
if (siteId) {
const site = await StationSiteApi.getStationSite(siteId)
estimatedPiles.value = site.estimatedPiles
} else {
estimatedPiles.value = undefined
}
}
)
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
// 修改时,设置数据
if (id) {
formLoading.value = true
try {
const projectData = await ProjectApi.getProject(id)
// 处理日期格式转换
if (projectData.investmentAgreementDate && Array.isArray(projectData.investmentAgreementDate)) {
const [year, month, day] = projectData.investmentAgreementDate
projectData.investmentAgreementDate = new Date(year, month - 1, day) // month需要减1因为Date的月份是从0开始的
}
formData.value = projectData
} finally {
formLoading.value = false
}
}
// 加载部门列表
deptList.value = await DeptApi.querySimpleDeptList(3)
// 获得合同列表
contractOptions.value = await ContractApi.getContractSimpleAllList()
// 获得场地列表
siteOptions.value = await StationSiteApi.getStationSiteSimpleList()
}
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
/** 提交表单 */
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
const submitForm = async () => {
// 校验表单
await formRef.value.validate()
// 校验子表
if (partnerFormRef.value && !(await partnerFormRef.value.validate())) {
message.error('请完善合伙人明细')
return
}
if (revenueSharePartnerFromRef.value && !(await revenueSharePartnerFromRef.value.validate())) {
message.error('请完善分成方明细')
return
}
// 提交请求
formLoading.value = true
try {
const data = { ...formData.value } as unknown as ProjectApi.ProjectVO
// 处理日期格式转换 - 将Date对象转换为后端期望的数组格式
if (data.investmentAgreementDate && data.investmentAgreementDate instanceof Date) {
const date = data.investmentAgreementDate
data.investmentAgreementDate = [
date.getFullYear(),
date.getMonth() + 1, // month需要加1因为Date的月份是从0开始的
date.getDate()
] as any
}
if (formType.value === 'create') {
await ProjectApi.createProject(data)
message.success(t('common.createSuccess'))
} else {
await ProjectApi.updateProject(data)
message.success(t('common.updateSuccess'))
}
dialogVisible.value = false
// 发送操作成功的事件
emit('success')
} finally {
formLoading.value = false
}
}
/** 重置表单 */
const resetForm = () => {
formData.value = {
id: undefined,
deptId: undefined,
siteId: undefined,
totalInvestment: 0,
purchaseContractId: undefined,
cooperationAgreement:undefined,
epcContractId: undefined,
buildPermit: '',
ownershipProof: '',
projectRecord: '',
powerSupplyReply: '',
investmentAgreement: '',
investmentAgreementDate: undefined,
investmentShareAgreement: '',
supplementaryMaterials: [],
partners:[],
revenueSharePartners:[],
type: undefined,
projectStatus: undefined,
powerSupplyType: undefined
}
formRef.value?.resetFields()
}
</script>