✨ CRM:完善合同的跟进记录实现
This commit is contained in:
parent
3bfdb2df33
commit
9acd01e768
@ -26,7 +26,7 @@
|
|||||||
:formatter="erpPriceTableColumnFormatter"
|
:formatter="erpPriceTableColumnFormatter"
|
||||||
/>
|
/>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="合同价格(元)"
|
label="商机价格(元)"
|
||||||
align="center"
|
align="center"
|
||||||
prop="businessPrice"
|
prop="businessPrice"
|
||||||
min-width="140"
|
min-width="140"
|
||||||
|
@ -21,14 +21,13 @@
|
|||||||
{{ contract.customerName }}
|
{{ contract.customerName }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="合同金额(元)">
|
<el-descriptions-item label="合同金额(元)">
|
||||||
{{ floatToFixed2(contract.price) }}
|
{{ erpPriceInputFormatter(contract.totalPrice) }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="下单时间">
|
<el-descriptions-item label="下单时间">
|
||||||
{{ contract.orderDate ? formatDate(contract.orderDate) : '空' }}
|
{{ contract.orderDate ? formatDate(contract.orderDate) : '空' }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="回款金额(元)">
|
<!-- TODO 芋艿:回款金额 -->
|
||||||
{{ floatToFixed2(contract.price) }}
|
<el-descriptions-item label="回款金额(元)"> 待实现 </el-descriptions-item>
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="负责人">
|
<el-descriptions-item label="负责人">
|
||||||
{{ contract.ownerUserName }}
|
{{ contract.ownerUserName }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
@ -38,7 +37,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import * as ContractApi from '@/api/crm/contract'
|
import * as ContractApi from '@/api/crm/contract'
|
||||||
import { formatDate } from '@/utils/formatTime'
|
import { formatDate } from '@/utils/formatTime'
|
||||||
import { floatToFixed2 } from '@/utils'
|
import { erpPriceInputFormatter, floatToFixed2 } from '@/utils'
|
||||||
|
|
||||||
defineOptions({ name: 'ContractDetailsHeader' })
|
defineOptions({ name: 'ContractDetailsHeader' })
|
||||||
defineProps<{ contract: ContractApi.ContractVO }>()
|
defineProps<{ contract: ContractApi.ContractVO }>()
|
||||||
|
@ -6,33 +6,25 @@
|
|||||||
<template #title>
|
<template #title>
|
||||||
<span class="text-base font-bold">基本信息</span>
|
<span class="text-base font-bold">基本信息</span>
|
||||||
</template>
|
</template>
|
||||||
<el-descriptions :column="3">
|
<el-descriptions :column="4">
|
||||||
<el-descriptions-item label="合同编号">
|
<el-descriptions-item label="合同编号">{{ contract.no }}</el-descriptions-item>
|
||||||
{{ contract.no }}
|
<el-descriptions-item label="合同名称">{{ contract.name }}</el-descriptions-item>
|
||||||
</el-descriptions-item>
|
<el-descriptions-item label="客户名称">{{ contract.customerName }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="合同名称">
|
<el-descriptions-item label="商机名称">{{ contract.businessName }}</el-descriptions-item>
|
||||||
{{ contract.name }}
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="客户名称">
|
|
||||||
{{ contract.customerName }}
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="商机名称">
|
|
||||||
{{ contract.businessName }}
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="合同金额(元)">
|
<el-descriptions-item label="合同金额(元)">
|
||||||
{{ contract.price }}
|
{{ erpPriceInputFormatter(contract.totalPrice) }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="下单时间">
|
<el-descriptions-item label="下单时间">
|
||||||
{{ formatDate(contract.orderDate) }}
|
{{ formatDate(contract.orderDate) }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="开始时间">
|
<el-descriptions-item label="合同开始时间">
|
||||||
{{ formatDate(contract.startTime) }}
|
{{ formatDate(contract.startTime) }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="结束时间">
|
<el-descriptions-item label="合同结束时间">
|
||||||
{{ formatDate(contract.endTime) }}
|
{{ formatDate(contract.endTime) }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="客户签约人">
|
<el-descriptions-item label="客户签约人">
|
||||||
{{ contract.contactName }}
|
{{ contract.signContactName }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="公司签约人">
|
<el-descriptions-item label="公司签约人">
|
||||||
{{ contract.signUserName }}
|
{{ contract.signUserName }}
|
||||||
@ -41,7 +33,7 @@
|
|||||||
{{ contract.remark }}
|
{{ contract.remark }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="合同状态">
|
<el-descriptions-item label="合同状态">
|
||||||
{{ contract.auditStatus }}
|
<dict-tag :type="DICT_TYPE.CRM_AUDIT_STATUS" :value="contract.auditStatus" />
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
</el-collapse-item>
|
</el-collapse-item>
|
||||||
@ -49,18 +41,19 @@
|
|||||||
<template #title>
|
<template #title>
|
||||||
<span class="text-base font-bold">系统信息</span>
|
<span class="text-base font-bold">系统信息</span>
|
||||||
</template>
|
</template>
|
||||||
<el-descriptions :column="2">
|
<el-descriptions :column="4">
|
||||||
<el-descriptions-item label="负责人">
|
<el-descriptions-item label="负责人">{{ contract.ownerUserName }}</el-descriptions-item>
|
||||||
{{ contract.ownerUserName }}
|
<el-descriptions-item label="最后跟进时间">
|
||||||
</el-descriptions-item>
|
{{ formatDate(contract.contactLastTime) }}
|
||||||
<el-descriptions-item label="创建人">
|
|
||||||
{{ contract.creatorName }}
|
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label=""> </el-descriptions-item>
|
||||||
|
<el-descriptions-item label=""> </el-descriptions-item>
|
||||||
|
<el-descriptions-item label="创建人">{{ contract.creatorName }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="创建时间">
|
<el-descriptions-item label="创建时间">
|
||||||
{{ contract.createTime ? formatDate(contract.createTime) : '空' }}
|
{{ formatDate(contract.createTime) }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="更新时间">
|
<el-descriptions-item label="更新时间">
|
||||||
{{ contract.updateTime ? formatDate(contract.updateTime) : '空' }}
|
{{ formatDate(contract.updateTime) }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
</el-collapse-item>
|
</el-collapse-item>
|
||||||
@ -70,6 +63,8 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import * as ContractApi from '@/api/crm/contract'
|
import * as ContractApi from '@/api/crm/contract'
|
||||||
import { formatDate } from '@/utils/formatTime'
|
import { formatDate } from '@/utils/formatTime'
|
||||||
|
import { DICT_TYPE } from '@/utils/dict'
|
||||||
|
import { erpPriceInputFormatter } from '@/utils'
|
||||||
|
|
||||||
defineOptions({ name: 'ContractDetailsInfo' })
|
defineOptions({ name: 'ContractDetailsInfo' })
|
||||||
defineProps<{
|
defineProps<{
|
||||||
|
@ -1,67 +1,66 @@
|
|||||||
<!-- 合同详情:产品列表 -->
|
|
||||||
<template>
|
<template>
|
||||||
<el-table :data="list" :show-overflow-tooltip="true" :stripe="true">
|
<ContentWrap>
|
||||||
<el-table-column align="center" label="产品名称" prop="name" width="160" />
|
<el-table :data="contract.products" :stripe="true" :show-overflow-tooltip="true">
|
||||||
<el-table-column align="center" label="产品类型" prop="categoryName" width="160" />
|
|
||||||
<el-table-column align="center" label="产品单位" prop="unit">
|
|
||||||
<template #default="scope">
|
|
||||||
<dict-tag :type="DICT_TYPE.CRM_PRODUCT_UNIT" :value="scope.row.unit" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column align="center" label="产品编码" prop="no" />
|
|
||||||
<el-table-column
|
<el-table-column
|
||||||
:formatter="fenToYuanFormat"
|
|
||||||
align="center"
|
align="center"
|
||||||
label="价格(元)"
|
label="产品名称"
|
||||||
prop="price"
|
fixed="left"
|
||||||
width="100"
|
prop="productName"
|
||||||
/>
|
min-width="160"
|
||||||
<el-table-column align="center" label="数量" prop="count" width="200" />
|
>
|
||||||
<el-table-column align="center" label="折扣(%)" prop="discountPercent" width="200" />
|
<template #default="scope">
|
||||||
<el-table-column align="center" label="合计" prop="totalPrice" width="100">
|
{{ scope.row.productName }}
|
||||||
<template #default="{ row }: { row: ProductApi.ProductExpandVO }">
|
|
||||||
{{ getTotalPrice(row) }}
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column label="产品条码" align="center" prop="productNo" min-width="120" />
|
||||||
|
<el-table-column align="center" label="产品单位" prop="productUnit" min-width="160">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<dict-tag :type="DICT_TYPE.CRM_PRODUCT_UNIT" :value="row.productUnit" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
label="产品价格(元)"
|
||||||
|
align="center"
|
||||||
|
prop="productPrice"
|
||||||
|
min-width="140"
|
||||||
|
:formatter="erpPriceTableColumnFormatter"
|
||||||
|
/>
|
||||||
|
<el-table-column
|
||||||
|
label="合同价格(元)"
|
||||||
|
align="center"
|
||||||
|
prop="contractPrice"
|
||||||
|
min-width="140"
|
||||||
|
:formatter="erpPriceTableColumnFormatter"
|
||||||
|
/>
|
||||||
|
<el-table-column
|
||||||
|
align="center"
|
||||||
|
label="数量"
|
||||||
|
prop="count"
|
||||||
|
min-width="100px"
|
||||||
|
:formatter="erpPriceTableColumnFormatter"
|
||||||
|
/>
|
||||||
|
<el-table-column
|
||||||
|
label="合计金额(元)"
|
||||||
|
align="center"
|
||||||
|
prop="totalPrice"
|
||||||
|
min-width="140"
|
||||||
|
:formatter="erpPriceTableColumnFormatter"
|
||||||
|
/>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
<el-row class="mt-10px" justify="end">
|
||||||
|
<el-col :span="3"> 整单折扣:{{ erpPriceInputFormatter(contract.discountPercent) }}% </el-col>
|
||||||
|
<el-col :span="4">
|
||||||
|
产品总金额:{{ erpPriceInputFormatter(contract.totalProductPrice) }} 元
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</ContentWrap>
|
||||||
</template>
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
<script lang="ts" setup>
|
import * as ContractApi from '@/api/crm/contract'
|
||||||
|
import { erpPriceInputFormatter, erpPriceTableColumnFormatter } from '@/utils'
|
||||||
import { DICT_TYPE } from '@/utils/dict'
|
import { DICT_TYPE } from '@/utils/dict'
|
||||||
import { fenToYuanFormat } from '@/utils/formatter'
|
|
||||||
import * as ProductApi from '@/api/crm/product'
|
|
||||||
import { floatToFixed2, yuanToFen } from '@/utils'
|
|
||||||
|
|
||||||
defineOptions({ name: 'ContractProductList' })
|
const { contract } = defineProps<{
|
||||||
const props = withDefaults(defineProps<{ modelValue: ProductApi.ProductExpandVO[] }>(), {
|
contract: ContractApi.ContractVO
|
||||||
modelValue: () => []
|
}>()
|
||||||
})
|
|
||||||
const list = ref<ProductApi.ProductExpandVO[]>([]) // 产品列表
|
|
||||||
|
|
||||||
/** 计算 totalPrice */
|
|
||||||
const getTotalPrice = computed(() => (row: ProductApi.ProductExpandVO) => {
|
|
||||||
const totalPrice =
|
|
||||||
(Number(row.price) / 100) * Number(row.count) * (1 - Number(row.discountPercent) / 100)
|
|
||||||
row.totalPrice = isNaN(totalPrice) ? 0 : yuanToFen(totalPrice)
|
|
||||||
return isNaN(totalPrice) ? 0 : totalPrice.toFixed(2)
|
|
||||||
})
|
|
||||||
|
|
||||||
/** 编辑时合同产品回显 */
|
|
||||||
const isSetListValue = ref(false) // 判断是否已经给 list 赋值过,用于编辑表单产品回显
|
|
||||||
watch(
|
|
||||||
() => props.modelValue,
|
|
||||||
(val) => {
|
|
||||||
if (!val || val.length === 0 || isSetListValue.value) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
list.value = [
|
|
||||||
...props.modelValue.map((item) => {
|
|
||||||
item.totalPrice = floatToFixed2(item.totalPrice) as unknown as number
|
|
||||||
return item
|
|
||||||
})
|
|
||||||
]
|
|
||||||
isSetListValue.value = true
|
|
||||||
},
|
|
||||||
{ immediate: true, deep: true }
|
|
||||||
)
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -10,22 +10,22 @@
|
|||||||
</ContractDetailsHeader>
|
</ContractDetailsHeader>
|
||||||
<el-col>
|
<el-col>
|
||||||
<el-tabs>
|
<el-tabs>
|
||||||
<!-- TODO @puhui999:跟进记录 -->
|
<el-tab-pane label="跟进记录">
|
||||||
|
<FollowUpList :biz-id="contract.id" :biz-type="BizTypeEnum.CRM_CONTRACT" />
|
||||||
|
</el-tab-pane>
|
||||||
<el-tab-pane label="基本信息">
|
<el-tab-pane label="基本信息">
|
||||||
<ContractDetailsInfo :contract="contract" />
|
<ContractDetailsInfo :contract="contract" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<!-- TODO @puhui999:products 更合适哈 -->
|
|
||||||
<el-tab-pane label="产品">
|
<el-tab-pane label="产品">
|
||||||
<ContractProductList v-model="contract.productItems" />
|
<ContractProductList :contract="contract" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<!-- TODO @puhui999:回款信息 -->
|
<!-- TODO @puhui999:回款信息 -->
|
||||||
<!-- TODO @puhui999:这里是不是不用 isPool 哈 -->
|
|
||||||
<el-tab-pane label="团队成员">
|
<el-tab-pane label="团队成员">
|
||||||
<PermissionList
|
<PermissionList
|
||||||
ref="permissionListRef"
|
ref="permissionListRef"
|
||||||
:biz-id="contract.id!"
|
:biz-id="contract.id!"
|
||||||
:biz-type="BizTypeEnum.CRM_CONTRACT"
|
:biz-type="BizTypeEnum.CRM_CONTRACT"
|
||||||
:show-action="!permissionListRef?.isPool || false"
|
:show-action="false"
|
||||||
@quit-team="close"
|
@quit-team="close"
|
||||||
/>
|
/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
@ -51,6 +51,7 @@ import { getOperateLogPage } from '@/api/crm/operateLog'
|
|||||||
import ContractForm from '@/views/crm/contract/ContractForm.vue'
|
import ContractForm from '@/views/crm/contract/ContractForm.vue'
|
||||||
import CrmTransferForm from '@/views/crm/permission/components/TransferForm.vue'
|
import CrmTransferForm from '@/views/crm/permission/components/TransferForm.vue'
|
||||||
import PermissionList from '@/views/crm/permission/components/PermissionList.vue'
|
import PermissionList from '@/views/crm/permission/components/PermissionList.vue'
|
||||||
|
import FollowUpList from '@/views/crm/followup/index.vue'
|
||||||
|
|
||||||
defineOptions({ name: 'CrmContractDetail' })
|
defineOptions({ name: 'CrmContractDetail' })
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user