项目立项
parent
e6520ccdd4
commit
9f891fc362
|
|
@ -16,40 +16,38 @@ export interface ProjectVO {
|
||||||
ownershipProof: string // 场地权属证明
|
ownershipProof: string // 场地权属证明
|
||||||
projectRecord: string // 项目备案
|
projectRecord: string // 项目备案
|
||||||
powerSupplyReply: string // 供电答复单
|
powerSupplyReply: string // 供电答复单
|
||||||
|
investmentAgreement: string // 合作投资协议
|
||||||
supplementaryMaterials: string // 其他补充材料文件路径
|
supplementaryMaterials: string // 其他补充材料文件路径
|
||||||
type: number // 类型
|
type: number // 类型
|
||||||
projectStatus: number // 状态
|
projectStatus: number // 状态
|
||||||
}
|
}
|
||||||
|
|
||||||
// CRM 项目信息 API
|
// 查询CRM 项目信息分页
|
||||||
export const ProjectApi = {
|
export const getProjectPage = async (params: any) => {
|
||||||
// 查询CRM 项目信息分页
|
|
||||||
getProjectPage: async (params: any) => {
|
|
||||||
return await request.get({ url: `/crm/project/page`, params })
|
return await request.get({ url: `/crm/project/page`, params })
|
||||||
},
|
}
|
||||||
|
|
||||||
// 查询CRM 项目信息详情
|
// 查询CRM 项目信息详情
|
||||||
getProject: async (id: number) => {
|
export const getProject = async (id: number) => {
|
||||||
return await request.get({ url: `/crm/project/get?id=` + id })
|
return await request.get({ url: `/crm/project/get?id=` + id })
|
||||||
},
|
}
|
||||||
|
|
||||||
// 新增CRM 项目信息
|
// 新增CRM 项目信息
|
||||||
createProject: async (data: ProjectVO) => {
|
export const createProject = async (data: ProjectVO) => {
|
||||||
return await request.post({ url: `/crm/project/create`, data })
|
return await request.post({ url: `/crm/project/create`, data })
|
||||||
},
|
}
|
||||||
|
|
||||||
// 修改CRM 项目信息
|
// 修改CRM 项目信息
|
||||||
updateProject: async (data: ProjectVO) => {
|
export const updateProject = async (data: ProjectVO) => {
|
||||||
return await request.put({ url: `/crm/project/update`, data })
|
return await request.put({ url: `/crm/project/update`, data })
|
||||||
},
|
}
|
||||||
|
|
||||||
// 删除CRM 项目信息
|
// 删除CRM 项目信息
|
||||||
deleteProject: async (id: number) => {
|
export const deleteProject = async (id: number) => {
|
||||||
return await request.delete({ url: `/crm/project/delete?id=` + id })
|
return await request.delete({ url: `/crm/project/delete?id=` + id })
|
||||||
},
|
}
|
||||||
|
|
||||||
// 导出CRM 项目信息 Excel
|
// 导出CRM 项目信息 Excel
|
||||||
exportProject: async (params) => {
|
export const exportProject = async (params: any) => {
|
||||||
return await request.download({ url: `/crm/project/export-excel`, params })
|
return await request.download({ url: `/crm/project/export-excel`, params })
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
@ -19,8 +19,8 @@ export const getSimpleDeptList = async (): Promise<DeptVO[]> => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询部门(精简)列表
|
// 查询部门(精简)列表
|
||||||
export const querySimpleDeptList = async () => {
|
export const querySimpleDeptList = async (type: number) => {
|
||||||
return await request.get({ url: '/system/dept/query-list?type=2'})
|
return await request.get({ url: `/system/dept/query-list?type=${type}` })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询部门列表
|
// 查询部门列表
|
||||||
|
|
|
||||||
|
|
@ -218,6 +218,7 @@ export enum DICT_TYPE {
|
||||||
CRM_CONTRACT_TYPE = 'crm_contract_type', // CRM 合同类型
|
CRM_CONTRACT_TYPE = 'crm_contract_type', // CRM 合同类型
|
||||||
CRM_CONTRACT_STATUS = 'crm_contract_status', // CRM 合同状态
|
CRM_CONTRACT_STATUS = 'crm_contract_status', // CRM 合同状态
|
||||||
CRM_CONTRACT_ATTRIBUTE = 'crm_contract_attribute', // CRM 合同属性
|
CRM_CONTRACT_ATTRIBUTE = 'crm_contract_attribute', // CRM 合同属性
|
||||||
|
CRM_PROJECT_TYPE = 'crm_project_type', // CRM 项目类型
|
||||||
|
|
||||||
|
|
||||||
// ========== ERP - 企业资源计划模块 ==========
|
// ========== ERP - 企业资源计划模块 ==========
|
||||||
|
|
|
||||||
|
|
@ -340,7 +340,7 @@ const open = async (type: string, id?: number) => {
|
||||||
// 获取联系人
|
// 获取联系人
|
||||||
contactList.value = await ContactApi.getSimpleContactList()
|
contactList.value = await ContactApi.getSimpleContactList()
|
||||||
// 加载部门列表
|
// 加载部门列表
|
||||||
deptList.value = await DeptApi.querySimpleDeptList()
|
deptList.value = await DeptApi.querySimpleDeptList(2)
|
||||||
}
|
}
|
||||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,18 +47,42 @@
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="类型" prop="type">
|
<el-form-item label="类型" prop="type">
|
||||||
<el-select v-model="formData.type" placeholder="请选择类型">
|
<el-select v-model="formData.type" placeholder="请选择类型">
|
||||||
<el-option label="请选择字典生成" value="" />
|
<el-option
|
||||||
|
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_PROJECT_TYPE)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="状态" prop="projectStatus">
|
<el-form-item label="状态" prop="projectStatus">
|
||||||
<el-radio-group v-model="formData.projectStatus">
|
<el-radio-group v-model="formData.projectStatus">
|
||||||
<el-radio value="1">请选择字典生成</el-radio>
|
<el-radio value="0">关闭</el-radio>
|
||||||
|
<el-radio value="1">开启</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</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-row>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
|
|
@ -115,17 +139,17 @@
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="项目总投资额" prop="totalInvestment">
|
|
||||||
<el-input v-model="formData.totalInvestment" placeholder="请输入项目总投资额" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col>
|
<el-col>
|
||||||
<el-form-item label="合伙人明细">
|
<el-form-item v-if="formData.type === 2" label="合伙人明细">
|
||||||
<ProjectPartnetForm v-model:partners="formData.partners" :disabled="formLoading" ref="partnerFormRef" />
|
<ProjectPartnetForm
|
||||||
|
v-model:partners="partners"
|
||||||
|
:disabled="formLoading"
|
||||||
|
:price="formData.totalInvestment"
|
||||||
|
ref="partnerFormRef"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
@ -133,33 +157,36 @@
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="同意建桩证明" prop="buildPermit">
|
<el-form-item label="同意建桩证明" prop="buildPermit">
|
||||||
<el-input v-model="formData.buildPermit" placeholder="请输入同意建桩证明" />
|
<UploadFile v-model="formData.buildPermit" :isShowTip="false" :limit="1" :file-type="['pdf']" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="场地权属证明" prop="ownershipProof">
|
<el-form-item label="场地权属证明" prop="ownershipProof">
|
||||||
<el-input v-model="formData.ownershipProof" placeholder="请输入场地权属证明" />
|
<UploadFile v-model="formData.ownershipProof" :isShowTip="false" :limit="1" :file-type="['pdf']" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="项目备案" prop="projectRecord">
|
<el-form-item label="项目备案" prop="projectRecord">
|
||||||
<el-input v-model="formData.projectRecord" placeholder="请输入项目备案" />
|
<UploadFile v-model="formData.projectRecord" :isShowTip="false" :limit="1" :file-type="['pdf']" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="供电答复单" prop="powerSupplyReply">
|
<el-form-item label="供电答复单" prop="powerSupplyReply">
|
||||||
<el-input v-model="formData.powerSupplyReply" placeholder="请输入供电答复单" />
|
<UploadFile v-model="formData.powerSupplyReply" :isShowTip="false" :limit="1" :file-type="['pdf']" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-row>
|
<el-row>
|
||||||
|
<el-col v-if="formData.type === 2" :span="12">
|
||||||
|
<el-form-item label="合作投资协议" prop="investmentAgreement">
|
||||||
|
<UploadFile v-model="formData.investmentAgreement" :isShowTip="false" :limit="1" :file-type="['pdf']" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="其他补充材料文件路径" prop="supplementaryMaterials">
|
<el-form-item label="其他补充材料" prop="supplementaryMaterials">
|
||||||
<el-input v-model="formData.supplementaryMaterials" placeholder="请输入其他补充材料文件路径" />
|
<UploadFile v-model="formData.supplementaryMaterials" :isShowTip="false" :limit="5" :file-type="['pdf']" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
@ -178,6 +205,8 @@ import * as DeptApi from '@/api/system/dept'
|
||||||
import * as ContractApi from '@/api/crm/contract'
|
import * as ContractApi from '@/api/crm/contract'
|
||||||
import * as StationSiteApi from '@/api/crm/stationsite'
|
import * as StationSiteApi from '@/api/crm/stationsite'
|
||||||
import ProjectPartnetForm from './component/ProjectPartnetForm.vue'
|
import ProjectPartnetForm from './component/ProjectPartnetForm.vue'
|
||||||
|
import { totalCountFormat } from '@/views/mall/promotion/coupon/formatter'
|
||||||
|
import UploadFile from '@/components/UploadFile/src/UploadFile.vue'
|
||||||
|
|
||||||
/** CRM 项目信息 表单 */
|
/** CRM 项目信息 表单 */
|
||||||
defineOptions({ name: 'ProjectForm' })
|
defineOptions({ name: 'ProjectForm' })
|
||||||
|
|
@ -189,6 +218,8 @@ const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
const dialogTitle = ref('') // 弹窗的标题
|
const dialogTitle = ref('') // 弹窗的标题
|
||||||
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||||
|
const partners = ref([]) // 合伙人列表
|
||||||
|
|
||||||
const formData = ref({
|
const formData = ref({
|
||||||
id: undefined,
|
id: undefined,
|
||||||
deptId: undefined,
|
deptId: undefined,
|
||||||
|
|
@ -196,18 +227,18 @@ const formData = ref({
|
||||||
totalInvestment: undefined,
|
totalInvestment: undefined,
|
||||||
partner: undefined,
|
partner: undefined,
|
||||||
ratio: undefined,
|
ratio: undefined,
|
||||||
investment: undefined,
|
investment: 0,
|
||||||
cooperationAgreement: undefined,
|
cooperationAgreement: undefined,
|
||||||
purchaseContractId: undefined,
|
purchaseContractId: undefined,
|
||||||
epcContractId: undefined,
|
epcContractId: undefined,
|
||||||
buildPermit: undefined,
|
buildPermit: '',
|
||||||
ownershipProof: undefined,
|
ownershipProof: '',
|
||||||
projectRecord: undefined,
|
projectRecord: '',
|
||||||
powerSupplyReply: undefined,
|
powerSupplyReply: '',
|
||||||
supplementaryMaterials: undefined,
|
investmentAgreement: '',
|
||||||
|
supplementaryMaterials: [],
|
||||||
type: undefined,
|
type: undefined,
|
||||||
projectStatus: undefined,
|
projectStatus: undefined
|
||||||
partners: [],
|
|
||||||
})
|
})
|
||||||
const formRules = reactive({
|
const formRules = reactive({
|
||||||
deptId: [{ required: true, message: '部门ID不能为空', trigger: 'blur' }],
|
deptId: [{ required: true, message: '部门ID不能为空', trigger: 'blur' }],
|
||||||
|
|
@ -221,6 +252,24 @@ const deptList = ref<DeptApi.DeptVO[]>([])
|
||||||
const contractOptions = ref<ContractApi.ContractVO[]>([]) // 合同列表
|
const contractOptions = ref<ContractApi.ContractVO[]>([]) // 合同列表
|
||||||
const siteOptions = ref<StationSiteApi.StationSiteVO[]>([]) // 场地列表
|
const siteOptions = ref<StationSiteApi.StationSiteVO[]>([]) // 场地列表
|
||||||
const partnerFormRef = ref()
|
const partnerFormRef = ref()
|
||||||
|
const estimatedPiles = ref<number | undefined>(undefined)
|
||||||
|
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) => {
|
const open = async (type: string, id?: number) => {
|
||||||
|
|
@ -238,7 +287,7 @@ const open = async (type: string, id?: number) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 加载部门列表
|
// 加载部门列表
|
||||||
deptList.value = await DeptApi.querySimpleDeptList()
|
deptList.value = await DeptApi.getSimpleDeptList()
|
||||||
// 获得合同列表
|
// 获得合同列表
|
||||||
contractOptions.value = await ContractApi.getContractSimpleAllList()
|
contractOptions.value = await ContractApi.getContractSimpleAllList()
|
||||||
// 获得场地列表
|
// 获得场地列表
|
||||||
|
|
@ -284,18 +333,18 @@ const resetForm = () => {
|
||||||
totalInvestment: undefined,
|
totalInvestment: undefined,
|
||||||
partner: undefined,
|
partner: undefined,
|
||||||
ratio: undefined,
|
ratio: undefined,
|
||||||
investment: undefined,
|
investment: 0,
|
||||||
cooperationAgreement: undefined,
|
cooperationAgreement: undefined,
|
||||||
purchaseContractId: undefined,
|
purchaseContractId: undefined,
|
||||||
epcContractId: undefined,
|
epcContractId: undefined,
|
||||||
buildPermit: undefined,
|
buildPermit: '',
|
||||||
ownershipProof: undefined,
|
ownershipProof: '',
|
||||||
projectRecord: undefined,
|
projectRecord: '',
|
||||||
powerSupplyReply: undefined,
|
powerSupplyReply: '',
|
||||||
supplementaryMaterials: undefined,
|
investmentAgreement: '',
|
||||||
|
supplementaryMaterials: [],
|
||||||
type: undefined,
|
type: undefined,
|
||||||
projectStatus: undefined,
|
projectStatus: undefined
|
||||||
partners: [],
|
|
||||||
}
|
}
|
||||||
formRef.value?.resetFields()
|
formRef.value?.resetFields()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,12 +9,13 @@
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
>
|
>
|
||||||
<el-table :data="formData" style="width: 100%">
|
<el-table :data="formData" style="width: 100%">
|
||||||
|
|
||||||
<el-table-column label="序号" type="index" align="center" width="60" />
|
<el-table-column label="序号" type="index" align="center" width="60" />
|
||||||
<el-table-column label="项目合伙人" min-width="180">
|
<el-table-column label="项目合伙人" min-width="180">
|
||||||
<template #default="{ $index }">
|
<template #default="{ row, $index }">
|
||||||
<el-form-item :prop="`${$index}.partner`" :rules="formRules.partner" class="mb-0px!">
|
<el-form-item :prop="`${$index}.partner`" :rules="formRules.partner" class="mb-0px!">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="formRules.partner"
|
v-model="row.partner"
|
||||||
filterable
|
filterable
|
||||||
clearable
|
clearable
|
||||||
placeholder="请选择"
|
placeholder="请选择"
|
||||||
|
|
@ -30,17 +31,24 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="比例" min-width="120">
|
<el-table-column label="比例(%)" min-width="200">
|
||||||
<template #default="{ row, $index }">
|
<template #default="{ row, $index }">
|
||||||
<el-form-item :prop="`${$index}.ratio`" :rules="formRules.ratio" class="mb-0px!">
|
<el-form-item :prop="`${$index}.ratio`" :rules="formRules.ratio" class="mb-0px!">
|
||||||
<el-input v-model="row.ratio" placeholder="请输入比例" />
|
<el-input-number
|
||||||
|
v-model="row.ratio"
|
||||||
|
:min="0"
|
||||||
|
:step="1"
|
||||||
|
:max="getMaxRatio($index)"
|
||||||
|
placeholder="请输入比例"
|
||||||
|
class="w-1/1"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="投资额" min-width="150">
|
<el-table-column label="投资额(万元)" min-width="150">
|
||||||
<template #default="{ row, $index }">
|
<template #default="{ row, $index }">
|
||||||
<el-form-item :prop="`${$index}.investment`" :rules="formRules.investment" class="mb-0px!">
|
<el-form-item :prop="`${$index}.investment`" class="mb-0px!">
|
||||||
<el-input v-model="row.investment" placeholder="请输入投资额" />
|
<el-input v-model="row.investment" placeholder="自动计算" :value="calcInvestment(row)" readonly />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
@ -57,11 +65,14 @@
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import * as UserApi from '@/api/system/user'
|
import * as UserApi from '@/api/system/user'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
partners: any[]
|
partners: any[]
|
||||||
disabled: boolean
|
disabled: boolean
|
||||||
|
price: number
|
||||||
}>()
|
}>()
|
||||||
|
const emit = defineEmits(['update:partners'])
|
||||||
const formLoading = ref(false)
|
const formLoading = ref(false)
|
||||||
const userOptions = ref<any[]>([])
|
const userOptions = ref<any[]>([])
|
||||||
|
|
||||||
|
|
@ -74,9 +85,22 @@ interface PartnerRow {
|
||||||
const formData = ref<PartnerRow[]>([])
|
const formData = ref<PartnerRow[]>([])
|
||||||
|
|
||||||
const formRules = reactive({
|
const formRules = reactive({
|
||||||
partner: [{ required: true, message: '项目合伙人不能为空', trigger: 'blur' }],
|
partner: [
|
||||||
|
{ required: true, message: '项目合伙人不能为空', trigger: 'blur' },
|
||||||
|
{
|
||||||
|
validator: (_rule: any, value: string, callback: any) => {
|
||||||
|
// 检查合伙人是否重复
|
||||||
|
const count = formData.value.filter(item => item.partner === value).length
|
||||||
|
if (value && count > 1) {
|
||||||
|
callback(new Error('项目合伙人不能重复'))
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
trigger: 'change',
|
||||||
|
},
|
||||||
|
],
|
||||||
ratio: [{ required: true, message: '比例不能为空', trigger: 'blur' }],
|
ratio: [{ required: true, message: '比例不能为空', trigger: 'blur' }],
|
||||||
investment: [{ required: true, message: '投资额不能为空', trigger: 'blur' }]
|
|
||||||
})
|
})
|
||||||
const formRef = ref<any>(null)
|
const formRef = ref<any>(null)
|
||||||
|
|
||||||
|
|
@ -88,7 +112,10 @@ onMounted(async () => {
|
||||||
watch(
|
watch(
|
||||||
() => props.partners,
|
() => props.partners,
|
||||||
(val) => {
|
(val) => {
|
||||||
formData.value = val || []
|
formData.value = (val || []).map(item => ({
|
||||||
|
...item,
|
||||||
|
partner: item.partner ? String(item.partner) : ''
|
||||||
|
}))
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
)
|
)
|
||||||
|
|
@ -101,8 +128,44 @@ const handleDelete = (index: number) => {
|
||||||
formData.value.splice(index, 1)
|
formData.value.splice(index, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
const validate = () => {
|
const validate = async () => {
|
||||||
return formRef.value?.validate?.()
|
const valid = await formRef.value?.validate?.()
|
||||||
|
if (!valid) return false
|
||||||
|
// 校验所有合伙人比例之和不能超过100
|
||||||
|
const totalRatio = formData.value.reduce((sum, item) => sum + (Number(item.ratio) || 0), 0)
|
||||||
|
if (totalRatio > 100) {
|
||||||
|
ElMessage.error('所有合伙人比例之和不能超过100%')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
const calcInvestment = (row: PartnerRow) => {
|
||||||
|
const ratio = Number(row.ratio) || 0
|
||||||
|
const price = Number(props.price) || 0
|
||||||
|
return ratio && price ? ((ratio * price) / 100).toFixed(2) : ''
|
||||||
|
}
|
||||||
|
const getMaxRatio = (index: number) => {
|
||||||
|
// 计算除当前行外,其他合伙人已占用的比例
|
||||||
|
const used = formData.value.reduce((sum, item, idx) => idx !== index ? sum + (Number(item.ratio) || 0) : sum, 0)
|
||||||
|
return Math.max(0, 100 - used)
|
||||||
|
}
|
||||||
|
watch(
|
||||||
|
() => formData.value.map(item => item.ratio),
|
||||||
|
() => {
|
||||||
|
formData.value.forEach(row => {
|
||||||
|
row.investment = calcInvestment(row)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{ deep: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => formData.value,
|
||||||
|
(val) => {
|
||||||
|
emit('update:partners', val)
|
||||||
|
},
|
||||||
|
{ deep: true }
|
||||||
|
)
|
||||||
|
|
||||||
defineExpose({ validate })
|
defineExpose({ validate })
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -129,10 +129,45 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="收支类型" prop="incomeType">
|
||||||
|
<el-select v-model="formData.incomeType" placeholder="请选择收支类型" class="w-1/1">
|
||||||
|
<el-option label="收入" value="income" />
|
||||||
|
<el-option label="支出" value="expense" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="项目名称" prop="projectId">
|
||||||
|
<el-select
|
||||||
|
v-model="formData.projectId"
|
||||||
|
filterable
|
||||||
|
clearable
|
||||||
|
placeholder="请选择项目"
|
||||||
|
class="w-1/1"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in projectList"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.id + ' - ' + item.deptId"
|
||||||
|
:value="item.id"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="是否押金" prop="isDeposit">
|
||||||
|
<el-switch v-model="formData.isDeposit" active-text="是" inactive-text="否" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<el-form-item label="备注" prop="remark">
|
<el-form-item label="收入/开支内容" prop="content">
|
||||||
<el-input v-model="formData.remark" placeholder="请输入备注" type="textarea" />
|
<el-input v-model="formData.content" placeholder="请输入收入/开支内容" type="textarea" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
@ -150,6 +185,7 @@ import { ReceivableVO } from '@/api/crm/receivable'
|
||||||
import * as UserApi from '@/api/system/user'
|
import * as UserApi from '@/api/system/user'
|
||||||
import * as CustomerApi from '@/api/crm/customer'
|
import * as CustomerApi from '@/api/crm/customer'
|
||||||
import * as ContractApi from '@/api/crm/contract'
|
import * as ContractApi from '@/api/crm/contract'
|
||||||
|
import * as ProjectApi from '@/api/crm/project'
|
||||||
import { useUserStore } from '@/store/modules/user'
|
import { useUserStore } from '@/store/modules/user'
|
||||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||||
|
|
||||||
|
|
@ -160,17 +196,29 @@ const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
const dialogTitle = ref('') // 弹窗的标题
|
const dialogTitle = ref('') // 弹窗的标题
|
||||||
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||||
const formData = ref<ReceivableApi.ReceivableVO>({} as ReceivableApi.ReceivableVO)
|
const formData = ref<ReceivableApi.ReceivableVO & {
|
||||||
|
date?: number | string
|
||||||
|
content?: string
|
||||||
|
incomeType?: string
|
||||||
|
projectId?: number
|
||||||
|
isDeposit?: boolean
|
||||||
|
}>({} as ReceivableApi.ReceivableVO)
|
||||||
const formRules = reactive({
|
const formRules = reactive({
|
||||||
customerId: [{ required: true, message: '客户不能为空', trigger: 'blur' }],
|
customerId: [{ required: true, message: '客户不能为空', trigger: 'blur' }],
|
||||||
contractId: [{ required: true, message: '合同不能为空', trigger: 'blur' }],
|
contractId: [{ required: true, message: '合同不能为空', trigger: 'blur' }],
|
||||||
returnTime: [{ required: true, message: '付款日期不能为空', trigger: 'blur' }],
|
returnTime: [{ required: true, message: '付款日期不能为空', trigger: 'blur' }],
|
||||||
price: [{ required: true, message: '付款金额不能为空', trigger: 'blur' }]
|
price: [{ required: true, message: '付款金额不能为空', trigger: 'blur' }],
|
||||||
|
date: [{ required: true, message: '日期不能为空', trigger: 'blur' }],
|
||||||
|
content: [{ required: true, message: '收入/开支内容不能为空', trigger: 'blur' }],
|
||||||
|
incomeType: [{ required: true, message: '收支类型不能为空', trigger: 'change' }],
|
||||||
|
projectId: [{ required: true, message: '项目名称不能为空', trigger: 'change' }],
|
||||||
|
isDeposit: [{ required: true, message: '请选择是否押金', trigger: 'change' }],
|
||||||
})
|
})
|
||||||
const formRef = ref() // 表单 Ref
|
const formRef = ref() // 表单 Ref
|
||||||
const customerList = ref<CustomerApi.CustomerVO[]>([]) // 客户列表
|
const customerList = ref<CustomerApi.CustomerVO[]>([]) // 客户列表
|
||||||
const contractList = ref<ContractApi.ContractVO[]>([]) // 合同列表
|
const contractList = ref<ContractApi.ContractVO[]>([]) // 合同列表
|
||||||
const receivablePlanList = ref<ReceivablePlanApi.ReceivablePlanVO[]>([]) // 付款计划列表
|
const receivablePlanList = ref<ReceivablePlanApi.ReceivablePlanVO[]>([]) // 付款计划列表
|
||||||
|
const projectList = ref<ProjectApi.ProjectVO[]>([]) // 项目列表
|
||||||
|
|
||||||
/** 打开弹窗 */
|
/** 打开弹窗 */
|
||||||
const open = async (
|
const open = async (
|
||||||
|
|
@ -198,22 +246,29 @@ const open = async (
|
||||||
userOptions.value = await UserApi.getSimpleUserList()
|
userOptions.value = await UserApi.getSimpleUserList()
|
||||||
// 获得客户列表
|
// 获得客户列表
|
||||||
customerList.value = await CustomerApi.getCustomerSimpleList()
|
customerList.value = await CustomerApi.getCustomerSimpleList()
|
||||||
|
// 获得项目列表
|
||||||
|
projectList.value = await ProjectApi.getProjectPage({ pageSize: 1000, pageNo: 1 }).then(res => res.list || [])
|
||||||
// 默认新建时选中自己
|
// 默认新建时选中自己
|
||||||
if (formType.value === 'create') {
|
if (formType.value === 'create') {
|
||||||
formData.value.ownerUserId = useUserStore().getUser.id
|
formData.value.ownerUserId = useUserStore().getUser.id
|
||||||
}
|
}
|
||||||
// 从付款计划创建付款
|
// 从付款计划创建付款
|
||||||
|
if (receivablePlan) {
|
||||||
|
// 修复 receivablePlan.contractId 可能为 undefined 的类型问题
|
||||||
if (receivablePlan) {
|
if (receivablePlan) {
|
||||||
formData.value.customerId = receivablePlan.customerId
|
formData.value.customerId = receivablePlan.customerId
|
||||||
await handleCustomerChange(receivablePlan.customerId)
|
await handleCustomerChange(receivablePlan.customerId)
|
||||||
|
if (receivablePlan.contractId) {
|
||||||
formData.value.contractId = receivablePlan.contractId
|
formData.value.contractId = receivablePlan.contractId
|
||||||
await handleContractChange(receivablePlan.contractId)
|
await handleContractChange(receivablePlan.contractId)
|
||||||
|
}
|
||||||
if (receivablePlan.id) {
|
if (receivablePlan.id) {
|
||||||
formData.value.planId = receivablePlan.id
|
formData.value.planId = receivablePlan.id
|
||||||
formData.value.price = receivablePlan.price
|
formData.value.price = receivablePlan.price
|
||||||
formData.value.returnType = receivablePlan.returnType
|
formData.value.returnType = receivablePlan.returnType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,7 @@ const open = async (type: string, id?: number, customerId?: number, contractId?:
|
||||||
// 获得用户列表
|
// 获得用户列表
|
||||||
userOptions.value = await UserApi.getSimpleUserList()
|
userOptions.value = await UserApi.getSimpleUserList()
|
||||||
// 加载部门列表
|
// 加载部门列表
|
||||||
deptList.value = await DeptApi.querySimpleDeptList()
|
deptList.value = await DeptApi.querySimpleDeptList(3)
|
||||||
// 获得客户列表
|
// 获得客户列表
|
||||||
customerList.value = await CustomerApi.getCustomerSimpleAllList()
|
customerList.value = await CustomerApi.getCustomerSimpleAllList()
|
||||||
// 默认新建时选中自己
|
// 默认新建时选中自己
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue