parent
6c1472dbb4
commit
d436704756
|
|
@ -10,15 +10,29 @@ export interface ProjectVO {
|
||||||
ownerUserId: string // 项目合伙人
|
ownerUserId: string // 项目合伙人
|
||||||
ratio: string // 比例
|
ratio: string // 比例
|
||||||
investment: string // 投资额
|
investment: string // 投资额
|
||||||
cooperationAgreement: number // 场地租赁合同或合作协议
|
cooperationAgreement: number // 场地租赁合同
|
||||||
purchaseContractId: number // 设备采购合同ID
|
purchaseContractId: number // 设备采购合同ID
|
||||||
epcContractId: number // EPC施工合同ID
|
epcContractId: number // EPC施工合同ID
|
||||||
|
cooperationAgreementName?: String // 场地租赁合同名称
|
||||||
|
purchaseContractName?: String // 设备采购合同名称
|
||||||
|
epcContractName?: String // EPC施工合同名称
|
||||||
buildPermit: string // 同意建桩证明
|
buildPermit: string // 同意建桩证明
|
||||||
ownershipProof: string // 场地权属证明
|
ownershipProof: string // 场地权属证明
|
||||||
projectRecord: string // 项目备案
|
projectRecord: string // 项目备案
|
||||||
powerSupplyReply: string // 供电答复单
|
powerSupplyReply: string // 供电答复单
|
||||||
investmentAgreement: string // 合作投资协议
|
investmentAgreement: string // 合作投资协议
|
||||||
|
investmentShareAgreement: string // 合作投资分成协议
|
||||||
supplementaryMaterials: string // 其他补充材料文件路径
|
supplementaryMaterials: string // 其他补充材料文件路径
|
||||||
|
cooperationAgreementConfig?: number // 场地租赁合同配置
|
||||||
|
purchaseContractConfig?: number // 设备采购合同配置
|
||||||
|
epcContractConfig?: number // EPC施工合同配置
|
||||||
|
buildPermitConfig?: number // 同意建桩证明配置
|
||||||
|
ownershipProofConfig?: number // 场地权属证明配置
|
||||||
|
projectRecordConfig?: number // 项目备案配置
|
||||||
|
powerSupplyReplyConfig?: number // 供电答复单配置
|
||||||
|
investmentAgreementConfig?: number // 合作投资协议配置
|
||||||
|
investmentShareAgreementConfig?: number // 合作投资分成协议配置
|
||||||
|
supplementaryMaterialsConfig?: number // 其他补充材料配置
|
||||||
type: number // 类型
|
type: number // 类型
|
||||||
partners: []
|
partners: []
|
||||||
RevenueSharePartners: []
|
RevenueSharePartners: []
|
||||||
|
|
|
||||||
|
|
@ -84,3 +84,8 @@ export const submitReceivablePlan = async (id: number) => {
|
||||||
return await request.put({ url: `/crm/receivable-plan/submit?id=${id}`})
|
return await request.put({ url: `/crm/receivable-plan/submit?id=${id}`})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取汇总数据
|
||||||
|
export const getWaitPayData = async () => {
|
||||||
|
return await request.get({ url: `/crm/receivable-plan/getWaitPayData`})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -224,6 +224,7 @@ export enum DICT_TYPE {
|
||||||
CRM_CONTRACT_ATTRIBUTE = 'crm_contract_attribute', // CRM 合同属性
|
CRM_CONTRACT_ATTRIBUTE = 'crm_contract_attribute', // CRM 合同属性
|
||||||
CRM_PROJECT_TYPE = 'crm_project_type', // CRM 项目类型
|
CRM_PROJECT_TYPE = 'crm_project_type', // CRM 项目类型
|
||||||
CRM_PROJECT_POWER_SUPPLY_TYPE = 'crm_project_power_supply_type', // CRM 项目供电模式
|
CRM_PROJECT_POWER_SUPPLY_TYPE = 'crm_project_power_supply_type', // CRM 项目供电模式
|
||||||
|
CRM_PROJECT_DOCUMENT_CONFIG = 'crm_project_document_config', // CRM 项目文档配置
|
||||||
|
|
||||||
// ========== ERP - 企业资源计划模块 ==========
|
// ========== ERP - 企业资源计划模块 ==========
|
||||||
ERP_AUDIT_STATUS = 'erp_audit_status', // ERP 审批状态
|
ERP_AUDIT_STATUS = 'erp_audit_status', // ERP 审批状态
|
||||||
|
|
|
||||||
|
|
@ -416,7 +416,6 @@ const resetForm = () => {
|
||||||
const handleCustomerChange = () => {
|
const handleCustomerChange = () => {
|
||||||
formData.value.businessId = undefined
|
formData.value.businessId = undefined
|
||||||
formData.value.signContactId = undefined
|
formData.value.signContactId = undefined
|
||||||
formData.value.products = []
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -123,6 +123,7 @@
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
|
{{ formData }}
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="设备合同" prop="purchaseContractId">
|
<el-form-item label="设备合同" prop="purchaseContractId">
|
||||||
|
|
@ -238,6 +239,17 @@
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</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-col :span="12">
|
||||||
<el-form-item v-if="formData.powerSupplyType === 2" label="供电答复单" prop="powerSupplyReply" label-width="120px">
|
<el-form-item v-if="formData.powerSupplyType === 2" label="供电答复单" prop="powerSupplyReply" label-width="120px">
|
||||||
<UploadFile
|
<UploadFile
|
||||||
|
|
@ -292,6 +304,7 @@ const formData = ref({
|
||||||
projectRecord: undefined,
|
projectRecord: undefined,
|
||||||
powerSupplyReply: undefined,
|
powerSupplyReply: undefined,
|
||||||
investmentAgreement: undefined,
|
investmentAgreement: undefined,
|
||||||
|
investmentShareAgreement: undefined,
|
||||||
supplementaryMaterials: [],
|
supplementaryMaterials: [],
|
||||||
partners:[],
|
partners:[],
|
||||||
revenueSharePartners:[],
|
revenueSharePartners:[],
|
||||||
|
|
@ -306,8 +319,6 @@ const formRules = computed(() => ({
|
||||||
type: [{ required: true, message: '类型不能为空', trigger: 'change' }],
|
type: [{ required: true, message: '类型不能为空', trigger: 'change' }],
|
||||||
projectStatus: [{ required: true, message: '状态不能为空', trigger: 'blur' }],
|
projectStatus: [{ required: true, message: '状态不能为空', trigger: 'blur' }],
|
||||||
powerSupplyType: [{ required: true, message: '供电类型不能为空', trigger: 'blur' }],
|
powerSupplyType: [{ required: true, message: '供电类型不能为空', trigger: 'blur' }],
|
||||||
powerSupplyReply : formData.value.powerSupplyType === 2 ? [{ required: true, message: '供电答复单不能为空', trigger: 'blur' }] : [],
|
|
||||||
investmentAgreement: formData.value.type === 2 ?[{ required: true, message: '合作投资协议不能为空', trigger: 'blur' }] : [],
|
|
||||||
cooperationAgreement: [{ required: true, message: '场地合同不能为空', trigger: 'blur' }],
|
cooperationAgreement: [{ required: true, message: '场地合同不能为空', trigger: 'blur' }],
|
||||||
epcContractId: [{ required: true, message: 'EPC合同不能为空', trigger: 'blur' }],
|
epcContractId: [{ required: true, message: 'EPC合同不能为空', trigger: 'blur' }],
|
||||||
purchaseContractId: [{ required: true, message: '设备合同不能为空', trigger: 'blur' }],
|
purchaseContractId: [{ required: true, message: '设备合同不能为空', trigger: 'blur' }],
|
||||||
|
|
@ -411,6 +422,7 @@ const resetForm = () => {
|
||||||
projectRecord: undefined,
|
projectRecord: undefined,
|
||||||
powerSupplyReply: undefined,
|
powerSupplyReply: undefined,
|
||||||
investmentAgreement: undefined,
|
investmentAgreement: undefined,
|
||||||
|
investmentShareAgreement: undefined,
|
||||||
supplementaryMaterials: [],
|
supplementaryMaterials: [],
|
||||||
partners:[],
|
partners:[],
|
||||||
revenueSharePartners:[],
|
revenueSharePartners:[],
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
filterable
|
filterable
|
||||||
clearable
|
clearable
|
||||||
placeholder="请选择"
|
placeholder="请选择"
|
||||||
style="width: 150px"
|
style="min-width: 150px"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="user in userOptions"
|
v-for="user in userOptions"
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
filterable
|
filterable
|
||||||
clearable
|
clearable
|
||||||
placeholder="请选择"
|
placeholder="请选择"
|
||||||
style="width: 150px"
|
style="min-width: 150px"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="user in customerOptions"
|
v-for="user in customerOptions"
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,12 @@
|
||||||
<Icon class="mr-5px" icon="ep:download" />
|
<Icon class="mr-5px" icon="ep:download" />
|
||||||
导出
|
导出
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
||||||
|
<el-button plain type="warning" @click="openSummaryDialog">
|
||||||
|
<Icon class="mr-5px" icon="ep:view" />
|
||||||
|
查看汇总
|
||||||
|
|
||||||
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
|
|
@ -207,14 +213,14 @@
|
||||||
>
|
>
|
||||||
创建付款
|
创建付款
|
||||||
</el-button>
|
</el-button>
|
||||||
<!-- <el-button
|
<el-button
|
||||||
v-hasPermi="['crm:receivable-plan:update']"
|
v-hasPermi="['crm:receivable-plan:update']"
|
||||||
link
|
link
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="openForm('update', scope.row.id)"
|
@click="openForm('update', scope.row.id)"
|
||||||
>
|
>
|
||||||
编辑
|
编辑
|
||||||
</el-button> -->
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
v-hasPermi="['crm:receivable-plan:delete']"
|
v-hasPermi="['crm:receivable-plan:delete']"
|
||||||
link
|
link
|
||||||
|
|
@ -238,6 +244,13 @@
|
||||||
<!-- 表单弹窗:添加/修改 -->
|
<!-- 表单弹窗:添加/修改 -->
|
||||||
<ReceivablePlanForm ref="formRef" @success="getList" />
|
<ReceivablePlanForm ref="formRef" @success="getList" />
|
||||||
<ReceivableForm ref="receivableFormRef" @success="getList" />
|
<ReceivableForm ref="receivableFormRef" @success="getList" />
|
||||||
|
<!-- 汇总弹窗 -->
|
||||||
|
<Dialog v-model="summaryDialogVisible" title="收款计划汇总" @open="fetchSummaryData">
|
||||||
|
<div v-loading="summaryLoading" style="height:400px;">
|
||||||
|
<div v-if="!summaryLoading && summaryChartData.length === 0" style="text-align:center;padding:100px 0;">暂无数据</div>
|
||||||
|
<div v-else ref="summaryChartRef" style="width:100%;height:100%;"></div>
|
||||||
|
</div>
|
||||||
|
</Dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
|
@ -252,7 +265,104 @@ import ReceivableForm from '@/views/crm/receivable/ReceivableForm.vue'
|
||||||
import ReceivablePlanForm from './ReceivablePlanForm.vue'
|
import ReceivablePlanForm from './ReceivablePlanForm.vue'
|
||||||
import ContractList from '../../contract/components/ContractList.vue'
|
import ContractList from '../../contract/components/ContractList.vue'
|
||||||
|
|
||||||
|
import * as echarts from 'echarts'
|
||||||
|
|
||||||
defineOptions({ name: 'ReceivablePlan' })
|
defineOptions({ name: 'ReceivablePlan' })
|
||||||
|
// 汇总弹窗相关
|
||||||
|
const summaryDialogVisible = ref(false)
|
||||||
|
const summaryLoading = ref(false)
|
||||||
|
const summaryChartRef = ref()
|
||||||
|
const summaryChartData = ref<any[]>([])
|
||||||
|
|
||||||
|
const openSummaryDialog = () => {
|
||||||
|
summaryDialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchSummaryData = async () => {
|
||||||
|
summaryLoading.value = true
|
||||||
|
try {
|
||||||
|
const res = await ReceivablePlanApi.getWaitPayData()
|
||||||
|
summaryChartData.value = Array.isArray(res) ? res : (res.data || [])
|
||||||
|
// Dialog弹窗动画结束后再渲染ECharts,避免宽高为0
|
||||||
|
setTimeout(() => {
|
||||||
|
nextTick(() => renderSummaryChart())
|
||||||
|
}, 200)
|
||||||
|
} finally {
|
||||||
|
summaryLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const renderSummaryChart = () => {
|
||||||
|
if (!summaryChartRef.value) return
|
||||||
|
// 销毁旧实例,防止多次渲染
|
||||||
|
let chart = echarts.getInstanceByDom(summaryChartRef.value)
|
||||||
|
if (chart) chart.dispose()
|
||||||
|
chart = echarts.init(summaryChartRef.value)
|
||||||
|
const xAxis = [
|
||||||
|
'未付款',
|
||||||
|
'1个月内',
|
||||||
|
'2个月内',
|
||||||
|
'3个月内',
|
||||||
|
'4个月内',
|
||||||
|
'5个月内',
|
||||||
|
'6个月内',
|
||||||
|
'7个月内',
|
||||||
|
'8个月内',
|
||||||
|
'9个月内',
|
||||||
|
'10个月内',
|
||||||
|
'11个月内',
|
||||||
|
'12个月内'
|
||||||
|
]
|
||||||
|
const series = summaryChartData.value.map(item => ({
|
||||||
|
name: item.deptName || `部门${item.deptId}`,
|
||||||
|
type: 'bar',
|
||||||
|
stack: '金额',
|
||||||
|
emphasis: { focus: 'series' },
|
||||||
|
barWidth: 32,
|
||||||
|
itemStyle: {
|
||||||
|
borderRadius: [0, 0, 0, 0]
|
||||||
|
},
|
||||||
|
data: [
|
||||||
|
item.passPrice || 0,
|
||||||
|
item.month1Price || 0,
|
||||||
|
item.month2Price || 0,
|
||||||
|
item.month3Price || 0,
|
||||||
|
item.month4Price || 0,
|
||||||
|
item.month5Price || 0,
|
||||||
|
item.month6Price || 0,
|
||||||
|
item.month7Price || 0,
|
||||||
|
item.month8Price || 0,
|
||||||
|
item.month9Price || 0,
|
||||||
|
item.month10Price || 0,
|
||||||
|
item.month11Price || 0,
|
||||||
|
item.month12Price || 0
|
||||||
|
]
|
||||||
|
}))
|
||||||
|
chart.setOption({
|
||||||
|
tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
|
||||||
|
legend: { data: summaryChartData.value.map(item => item.deptName || `部门${item.deptId}`) },
|
||||||
|
grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: xAxis,
|
||||||
|
axisTick: { alignWithLabel: true },
|
||||||
|
axisLabel: { fontWeight: 'bold' }
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'value',
|
||||||
|
name: '金额(万元)',
|
||||||
|
axisLabel: { fontWeight: 'bold' }
|
||||||
|
},
|
||||||
|
series
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(summaryDialogVisible, (val) => {
|
||||||
|
if (!val && summaryChartRef.value) {
|
||||||
|
const chart = echarts.getInstanceByDom(summaryChartRef.value)
|
||||||
|
if (chart) chart.dispose()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
const { t } = useI18n() // 国际化
|
const { t } = useI18n() // 国际化
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue