收款计划

pull/853/head
wersd 2025-07-05 00:17:33 +08:00
parent 9f891fc362
commit b4cf7a6e15
9 changed files with 85 additions and 68 deletions

View File

@ -4,6 +4,7 @@ import request from '@/config/axios'
export interface ProjectVO { export interface ProjectVO {
id: number // 主键ID id: number // 主键ID
deptId: number // 部门ID deptId: number // 部门ID
name?: string
siteId: number // 场地ID siteId: number // 场地ID
totalInvestment: number // 项目总投资额 totalInvestment: number // 项目总投资额
ownerUserId: string // 项目合伙人 ownerUserId: string // 项目合伙人
@ -51,3 +52,8 @@ export const deleteProject = async (id: number) => {
export const exportProject = async (params: any) => { 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 })
} }
// 获取项目列表
export const getProjectSimpleList = async () => {
return await request.get({ url: `/crm/project/simple-list` })
}

View File

@ -8,6 +8,8 @@ export interface ReceivableVO {
customerId?: number customerId?: number
customerName?: string customerName?: string
contractId?: number contractId?: number
type: number
deptId: number
contract?: { contract?: {
id?: number id?: number
name?: string name?: string

View File

@ -3,7 +3,7 @@ import request from '@/config/axios'
export interface ReceivablePlanVO { export interface ReceivablePlanVO {
id: number id: number
period: number period: number
receivableId: number receivableId: number[]
price: number price: number
returnTime: Date returnTime: Date
remindDays: number remindDays: number
@ -25,10 +25,10 @@ export interface ReceivablePlanVO {
creatorName?: string // 创建人名称 creatorName?: string // 创建人名称
createTime: Date // 创建时间 createTime: Date // 创建时间
updateTime: Date // 更新时间 updateTime: Date // 更新时间
receivable?: { receivable?: [{
price: number price: number
returnTime: Date returnTime: Date
} }]
} }
// 查询收款计划列表 // 查询收款计划列表

View File

@ -204,7 +204,8 @@ export enum DICT_TYPE {
CRM_AUDIT_STATUS = 'crm_audit_status', // CRM 审批状态 CRM_AUDIT_STATUS = 'crm_audit_status', // CRM 审批状态
CRM_BIZ_TYPE = 'crm_biz_type', // CRM 业务类型 CRM_BIZ_TYPE = 'crm_biz_type', // CRM 业务类型
CRM_BUSINESS_END_STATUS_TYPE = 'crm_business_end_status_type', // CRM 商机结束状态类型 CRM_BUSINESS_END_STATUS_TYPE = 'crm_business_end_status_type', // CRM 商机结束状态类型
CRM_RECEIVABLE_RETURN_TYPE = 'crm_receivable_return_type', // CRM 回款的还款方式 CRM_RECEIVABLE_RETURN_TYPE = 'crm_receivable_return_type', // CRM 付款的付款方式
CRM_RECEIVABLE_TYPE = 'crm_receivable_type', // CRM 付款类型
CRM_CUSTOMER_INDUSTRY = 'crm_customer_industry', // CRM 客户所属行业 CRM_CUSTOMER_INDUSTRY = 'crm_customer_industry', // CRM 客户所属行业
CRM_CUSTOMER_DEAL_STATUS = 'crm_customer_deal_status', // CRM 客户成交状态 CRM_CUSTOMER_DEAL_STATUS = 'crm_customer_deal_status', // CRM 客户成交状态
CRM_CUSTOMER_LEVEL = 'crm_customer_level', // CRM 客户级别 CRM_CUSTOMER_LEVEL = 'crm_customer_level', // CRM 客户级别

View File

@ -199,7 +199,7 @@
</Dialog> </Dialog>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ProjectApi, ProjectVO } from '@/api/crm/project' import * as ProjectApi from '@/api/crm/project'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import * as DeptApi from '@/api/system/dept' import * as DeptApi from '@/api/system/dept'
import * as ContractApi from '@/api/crm/contract' import * as ContractApi from '@/api/crm/contract'
@ -224,7 +224,7 @@ const formData = ref({
id: undefined, id: undefined,
deptId: undefined, deptId: undefined,
siteId: undefined, siteId: undefined,
totalInvestment: undefined, totalInvestment: 0,
partner: undefined, partner: undefined,
ratio: undefined, ratio: undefined,
investment: 0, investment: 0,
@ -308,7 +308,7 @@ const submitForm = async () => {
// //
formLoading.value = true formLoading.value = true
try { try {
const data = formData.value as unknown as ProjectVO const data = formData.value as unknown as ProjectApi.ProjectVO
if (formType.value === 'create') { if (formType.value === 'create') {
await ProjectApi.createProject(data) await ProjectApi.createProject(data)
message.success(t('common.createSuccess')) message.success(t('common.createSuccess'))
@ -330,7 +330,7 @@ const resetForm = () => {
id: undefined, id: undefined,
deptId: undefined, deptId: undefined,
siteId: undefined, siteId: undefined,
totalInvestment: undefined, totalInvestment: 0,
partner: undefined, partner: undefined,
ratio: undefined, ratio: undefined,
investment: 0, investment: 0,

View File

@ -144,7 +144,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { dateFormatter } from '@/utils/formatTime' import { dateFormatter } from '@/utils/formatTime'
import download from '@/utils/download' import download from '@/utils/download'
import { ProjectApi, ProjectVO } from '@/api/crm/project' import * as ProjectApi from '@/api/crm/project'
import ProjectForm from './ProjectForm.vue' import ProjectForm from './ProjectForm.vue'
/** CRM 项目信息 列表 */ /** CRM 项目信息 列表 */
@ -154,7 +154,7 @@ const message = useMessage() // 消息弹窗
const { t } = useI18n() // const { t } = useI18n() //
const loading = ref(true) // const loading = ref(true) //
const list = ref<ProjectVO[]>([]) // const list = ref<ProjectApi.ProjectVO[]>([]) //
const total = ref(0) // const total = ref(0) //
const queryParams = reactive({ const queryParams = reactive({
pageNo: 1, pageNo: 1,

View File

@ -9,22 +9,38 @@
> >
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="付款编号" prop="no"> <el-form-item label="付款期数" prop="planId">
<el-input v-model="formData.no" disabled placeholder="保存时自动生成" /> <el-select
v-model="formData.planId"
:disabled="formType !== 'create' || !formData.contractId"
class="!w-1/1"
placeholder="请选择付款期数"
@change="handleReceivablePlanChange"
>
<el-option
v-for="data in receivablePlanList"
:key="data.id"
disabled
:label="'第 ' + data.period + ' 期'"
:value="data.id!"
/>
</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="ownerUserId"> <el-form-item label="付款单位" prop="contractId">
<el-select <el-select
v-model="formData.ownerUserId" v-model="formData.deptId"
:disabled="formType !== 'create'" disabled
class="w-1/1" class="w-1/1"
filterable
placeholder="请选择付款单位"
> >
<el-option <el-option
v-for="item in userOptions" v-for="data in deptList"
:key="item.id" :key="data.id"
:label="item.nickname" :label="data.name"
:value="item.id" :value="data.id!"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -32,13 +48,13 @@
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="客户名称" prop="customerId"> <el-form-item label="收款单位" prop="customerId">
<el-select <el-select
v-model="formData.customerId" v-model="formData.customerId"
:disabled="formType !== 'create'" :disabled="formType !== 'create'"
class="w-1/1" class="w-1/1"
filterable filterable
placeholder="请选择客户" placeholder="请选择收款单位"
@change="handleCustomerChange" @change="handleCustomerChange"
> >
<el-option <el-option
@ -71,39 +87,6 @@
</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="planId">
<el-select
v-model="formData.planId"
:disabled="formType !== 'create' || !formData.contractId"
class="!w-1/1"
placeholder="请选择付款期数"
@change="handleReceivablePlanChange"
>
<el-option
v-for="data in receivablePlanList"
:key="data.id"
:disabled="data.receivableId"
:label="'第 ' + data.period + ' 期'"
:value="data.id!"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="付款方式" prop="returnType">
<el-select v-model="formData.returnType" class="w-1/1" placeholder="请选择付款方式">
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_RECEIVABLE_RETURN_TYPE)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="付款金额" prop="price"> <el-form-item label="付款金额" prop="price">
@ -129,12 +112,30 @@
</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="returnType">
<el-select v-model="formData.returnType" class="w-1/1" placeholder="请选择付款方式">
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_RECEIVABLE_RETURN_TYPE)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="收支类型" prop="incomeType"> <el-form-item label="收支类型" prop="incomeType">
<el-select v-model="formData.incomeType" placeholder="请选择收支类型" class="w-1/1"> <el-select v-model="formData.incomeType" placeholder="请选择收支类型" class="w-1/1">
<el-option label="收入" value="income" /> <el-option
<el-option label="支出" value="expense" /> v-for="dict in getIntDictOptions(DICT_TYPE.CRM_RECEIVABLE_TYPE)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -152,7 +153,7 @@
<el-option <el-option
v-for="item in projectList" v-for="item in projectList"
:key="item.id" :key="item.id"
:label="item.id + ' - ' + item.deptId" :label="item.name"
:value="item.id" :value="item.id"
/> />
</el-select> </el-select>
@ -166,8 +167,8 @@
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="24"> <el-col :span="24">
<el-form-item label="收入/开支内容" prop="content"> <el-form-item label="备注" prop="content">
<el-input v-model="formData.content" 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>
@ -186,6 +187,7 @@ 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 * as ProjectApi from '@/api/crm/project'
import * as DeptApi from '@/api/system/dept'
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'
@ -209,12 +211,13 @@ const formRules = reactive({
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' }], date: [{ required: true, message: '日期不能为空', trigger: 'blur' }],
content: [{ required: true, message: '收入/开支内容不能为空', trigger: 'blur' }], content: [{ required: true, message: '备注不能为空', trigger: 'blur' }],
incomeType: [{ required: true, message: '收支类型不能为空', trigger: 'change' }], incomeType: [{ required: true, message: '收支类型不能为空', trigger: 'change' }],
projectId: [{ required: true, message: '项目名称不能为空', trigger: 'change' }], projectId: [{ required: true, message: '项目名称不能为空', trigger: 'change' }],
isDeposit: [{ required: true, message: '请选择是否押金', trigger: 'change' }], isDeposit: [{ required: true, message: '请选择是否押金', trigger: 'change' }],
}) })
const formRef = ref() // Ref const formRef = ref() // Ref
const deptList = ref<DeptApi.DeptVO[]>([])
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[]>([]) //
@ -242,18 +245,21 @@ const open = async (
formLoading.value = false formLoading.value = false
} }
} }
//
deptList.value = await DeptApi.querySimpleDeptList(2)
// //
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 || []) projectList.value = await ProjectApi.getProjectSimpleList()
// //
if (formType.value === 'create') { if (formType.value === 'create') {
formData.value.ownerUserId = useUserStore().getUser.id formData.value.ownerUserId = useUserStore().getUser.id
} }
// //
if (receivablePlan) { if (receivablePlan) {
// receivablePlan.contractId undefined // receivablePlan.contractId undefined
if (receivablePlan) { if (receivablePlan) {
formData.value.customerId = receivablePlan.customerId formData.value.customerId = receivablePlan.customerId
@ -302,6 +308,7 @@ const submitForm = async () => {
const resetForm = () => { const resetForm = () => {
formData.value = {} as ReceivableApi.ReceivableVO formData.value = {} as ReceivableApi.ReceivableVO
formRef.value?.resetFields() formRef.value?.resetFields()
formData.value.isDeposit = false //
} }
/** 处理切换客户 */ /** 处理切换客户 */
@ -330,6 +337,8 @@ const handleContractChange = async (contractId: number) => {
const contract = contractList.value.find((item) => item.id === contractId) const contract = contractList.value.find((item) => item.id === contractId)
if (contract) { if (contract) {
formData.value.price = contract.totalPrice - contract.totalReceivablePrice formData.value.price = contract.totalPrice - contract.totalReceivablePrice
//
formData.value.deptId = contract.deptId
} }
} }
} }

View File

@ -204,6 +204,7 @@ const submitForm = async () => {
// //
formLoading.value = true formLoading.value = true
try { try {
formData.value.type = 0
const data = formData.value as unknown as ReceivablePlanApi.ReceivablePlanVO const data = formData.value as unknown as ReceivablePlanApi.ReceivablePlanVO
if (formType.value === 'create') { if (formType.value === 'create') {
await ReceivablePlanApi.createReceivablePlan(data) await ReceivablePlanApi.createReceivablePlan(data)

View File

@ -70,6 +70,7 @@
<!-- 列表 --> <!-- 列表 -->
<ContentWrap> <ContentWrap>
<el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true"> <el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true">
<el-table-column <el-table-column
:formatter="dateFormatter2" :formatter="dateFormatter2"
align="center" align="center"
@ -132,10 +133,9 @@
width="160" width="160"
> >
<template #default="scope"> <template #default="scope">
<el-text v-if="scope.row.receivable"> <el-text>
{{ erpPriceInputFormatter(scope.row.receivable.price) }} {{ erpPriceInputFormatter((scope.row.receivable && Array.isArray(scope.row.receivable) && scope.row.receivable.length > 0) ? scope.row.receivable.reduce((sum, r) => sum + (r.price || 0), 0) : 0) }}
</el-text> </el-text>
<el-text v-else>{{ erpPriceInputFormatter(0) }}</el-text>
</template> </template>
</el-table-column> </el-table-column>
<!-- <el-table-column <!-- <el-table-column
@ -152,10 +152,9 @@
width="160" width="160"
> >
<template #default="scope"> <template #default="scope">
<el-text v-if="scope.row.receivable"> <el-text>
{{ erpPriceInputFormatter(scope.row.price - scope.row.receivable.price) }} {{ erpPriceInputFormatter(scope.row.price - ((scope.row.receivable && Array.isArray(scope.row.receivable) && scope.row.receivable.length > 0) ? scope.row.receivable.reduce((sum, r) => sum + (r.price || 0), 0) : 0)) }}
</el-text> </el-text>
<el-text v-else>{{ erpPriceInputFormatter(scope.row.price) }}</el-text>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="审核状态" align="center" width="90" prop="auditStatus"> <el-table-column label="审核状态" align="center" width="90" prop="auditStatus">
@ -171,7 +170,6 @@
link link
type="success" type="success"
@click="openReceivableForm(scope.row)" @click="openReceivableForm(scope.row)"
:disabled="scope.row.receivableId"
> >
创建付款 创建付款
</el-button> </el-button>