CRM:合同的 code review

This commit is contained in:
YunaiV 2024-02-01 13:38:14 +08:00
parent a5f8c3d79c
commit 956f19d9d0
16 changed files with 77 additions and 28 deletions

View File

@ -32,9 +32,11 @@ export const getModelPage = async (params) => {
export const getModel = async (id: number) => { export const getModel = async (id: number) => {
return await request.get({ url: '/bpm/model/get?id=' + id }) return await request.get({ url: '/bpm/model/get?id=' + id })
} }
export const getModelByKey = async (key: string) => { export const getModelByKey = async (key: string) => {
return await request.get({ url: '/bpm/model/get-by-key?key=' + key }) return await request.get({ url: '/bpm/model/get-by-key?key=' + key })
} }
export const updateModel = async (data: ModelVO) => { export const updateModel = async (data: ModelVO) => {
return await request.put({ url: '/bpm/model/update', data: data }) return await request.put({ url: '/bpm/model/update', data: data })
} }

View File

@ -5,11 +5,13 @@ export interface BiContractRanKingRespVO {
nickname: string nickname: string
deptName: string deptName: string
} }
export interface BiReceivablesRanKingRespVO { export interface BiReceivablesRanKingRespVO {
price: number price: number
nickname: string nickname: string
deptName: string deptName: string
} }
export interface BiRankReqVO { export interface BiRankReqVO {
deptId: number deptId: number
type: string type: string

View File

@ -73,6 +73,7 @@ export const getBusinessListByIds = async (val: number[]) => {
} }
// 商机转移 // 商机转移
// TODO @puhui999transferBusiness
export const transfer = async (data: TransferReqVO) => { export const transfer = async (data: TransferReqVO) => {
return await request.put({ url: '/crm/business/transfer', data }) return await request.put({ url: '/crm/business/transfer', data })
} }

View File

@ -71,6 +71,7 @@ export const handleApprove = async (id: number) => {
} }
// 合同转移 // 合同转移
// TODO @puhui999transfer 相关方法,这块要补充下;
export const transfer = async (data: TransferReqVO) => { export const transfer = async (data: TransferReqVO) => {
return await request.put({ url: '/crm/contract/transfer', data }) return await request.put({ url: '/crm/contract/transfer', data })
} }

View File

@ -1,3 +1,4 @@
<!-- TODO @puhui999这个最好加个注释哈 -->
<template> <template>
<Dialog v-model="dialogVisible" :appendToBody="true" :scroll="true" :title="title" width="60%"> <Dialog v-model="dialogVisible" :appendToBody="true" :scroll="true" :title="title" width="60%">
<el-table <el-table

View File

@ -96,8 +96,8 @@ const leftSides = ref([
const sideClick = (item) => { const sideClick = (item) => {
leftType.value = item.infoType leftType.value = item.infoType
} }
// TODO @dhb52:
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.side-item-list { .side-item-list {
top: 0; top: 0;

View File

@ -36,12 +36,12 @@
</ContentWrap> </ContentWrap>
<el-col> <el-col>
<el-tabs v-model="activeTab"> <el-tabs v-model="activeTab">
<el-tab-pane label="合同金额排行" name="contractAmountRanking">
<!-- 合同金额排行 --> <!-- 合同金额排行 -->
<el-tab-pane label="合同金额排行" name="contractAmountRanking">
<RankingContractStatistics :queryParams="queryParams" ref="rankingContractStatisticsRef" /> <RankingContractStatistics :queryParams="queryParams" ref="rankingContractStatisticsRef" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="回款金额排行" name="receivablesRanKing" lazy>
<!-- 回款金额排行 --> <!-- 回款金额排行 -->
<el-tab-pane label="回款金额排行" name="receivablesRanKing" lazy>
<RankingReceivablesStatistics <RankingReceivablesStatistics
:queryParams="queryParams" :queryParams="queryParams"
ref="rankingReceivablesStatisticsRef" ref="rankingReceivablesStatisticsRef"
@ -83,6 +83,7 @@ const resetQuery = () => {
queryFormRef.value.resetFields() queryFormRef.value.resetFields()
handleQuery() handleQuery()
} }
// //
onMounted(async () => { onMounted(async () => {
deptList.value = handleTree(await DeptApi.getSimpleDeptList()) deptList.value = handleTree(await DeptApi.getSimpleDeptList())

View File

@ -57,6 +57,7 @@ const message = useMessage()
const id = Number(route.params.id) // const id = Number(route.params.id) //
const loading = ref(true) // const loading = ref(true) //
const contact = ref<ContactApi.ContactVO>({} as ContactApi.ContactVO) // const contact = ref<ContactApi.ContactVO>({} as ContactApi.ContactVO) //
const permissionListRef = ref<InstanceType<typeof PermissionList>>() // Ref
/** 获取详情 */ /** 获取详情 */
const getContactData = async (id: number) => { const getContactData = async (id: number) => {
@ -68,22 +69,20 @@ const getContactData = async (id: number) => {
loading.value = false loading.value = false
} }
} }
/** 编辑 */ /** 编辑 */
const formRef = ref() const formRef = ref()
const openForm = (type: string, id?: number) => { const openForm = (type: string, id?: number) => {
formRef.value.open(type, id) formRef.value.open(type, id)
} }
/** 联系人转移 */ /** 联系人转移 */
const crmTransferFormRef = ref<InstanceType<typeof CrmTransferForm>>() // ref const crmTransferFormRef = ref<InstanceType<typeof CrmTransferForm>>() // ref
const transfer = () => { const transfer = () => {
crmTransferFormRef.value?.open('联系人转移', contact.value.id, ContactApi.transfer) crmTransferFormRef.value?.open('联系人转移', contact.value.id, ContactApi.transfer)
} }
const permissionListRef = ref<InstanceType<typeof PermissionList>>() // Ref /** 获取操作日志 */
/**
* 获取操作日志
*/
const logList = ref<OperateLogV2VO[]>([]) // const logList = ref<OperateLogV2VO[]>([]) //
const getOperateLog = async (contactId: number) => { const getOperateLog = async (contactId: number) => {
if (!contactId) { if (!contactId) {
@ -95,9 +94,12 @@ const getOperateLog = async (contactId: number) => {
}) })
logList.value = data.list logList.value = data.list
} }
/** 关闭窗口 */
const close = () => { const close = () => {
delView(unref(currentRoute)) delView(unref(currentRoute))
} }
/** 初始化 */ /** 初始化 */
const { delView } = useTagsViewStore() // const { delView } = useTagsViewStore() //
const { currentRoute } = useRouter() // const { currentRoute } = useRouter() //

View File

@ -144,6 +144,7 @@
<el-col :span="24"> <el-col :span="24">
<CardTitle class="mb-10px" title="审批信息" /> <CardTitle class="mb-10px" title="审批信息" />
</el-col> </el-col>
<!-- TODO 芋艿需要后面在 review 目前看不到信息 -->
<el-col :span="12"> <el-col :span="12">
<el-button <el-button
class="m-20px" class="m-20px"
@ -188,7 +189,9 @@ const formRules = reactive({
no: [{ required: true, message: '合同编号不能为空', trigger: 'blur' }] no: [{ required: true, message: '合同编号不能为空', trigger: 'blur' }]
}) })
const formRef = ref() // Ref const formRef = ref() // Ref
const BPMLModelRef = ref<InstanceType<typeof BPMLModel>>() const BPMLModelRef = ref<InstanceType<typeof BPMLModel>>() // TODO @puhui999 bpm model
// TODO @puhui999
watch( watch(
() => formData.value.productItems, () => formData.value.productItems,
(val) => { (val) => {
@ -205,13 +208,13 @@ watch(
}, },
{ deep: true } { deep: true }
) )
/** 打开弹窗 */ /** 打开弹窗 */
const open = async (type: string, id?: number) => { const open = async (type: string, id?: number) => {
dialogVisible.value = true dialogVisible.value = true
dialogTitle.value = t('action.' + type) dialogTitle.value = t('action.' + type)
formType.value = type formType.value = type
resetForm() resetForm()
await getAllApi()
// //
if (id) { if (id) {
formLoading.value = true formLoading.value = true
@ -221,10 +224,9 @@ const open = async (type: string, id?: number) => {
formLoading.value = false formLoading.value = false
} }
} }
await getAllApi()
} }
const getAllApi = async () => {
await Promise.all([getCustomerList(), getUserList(), getContactListList(), getBusinessList()])
}
defineExpose({ open }) // open defineExpose({ open }) // open
/** 提交表单 */ /** 提交表单 */
@ -252,32 +254,42 @@ const submitForm = async () => {
formLoading.value = false formLoading.value = false
} }
} }
const customerList = ref<CustomerApi.CustomerVO[]>([])
/** 重置表单 */
const resetForm = () => {
formData.value = {} as ContractApi.ContractVO
formRef.value?.resetFields()
}
/** 获取其它相关数据 */
const getAllApi = async () => {
await Promise.all([getCustomerList(), getUserList(), getContactListList(), getBusinessList()])
}
/** 获取客户 */ /** 获取客户 */
const customerList = ref<CustomerApi.CustomerVO[]>([])
const getCustomerList = async () => { const getCustomerList = async () => {
customerList.value = await CustomerApi.getSimpleCustomerList() customerList.value = await CustomerApi.getSimpleCustomerList()
} }
const contactList = ref<ContactApi.ContactVO[]>([])
/** 动态获取客户联系人 */ /** 动态获取客户联系人 */
const contactList = ref<ContactApi.ContactVO[]>([])
const getContactOptions = computed(() => const getContactOptions = computed(() =>
contactList.value.filter((item) => item.customerId === formData.value.customerId) contactList.value.filter((item) => item.customerId === formData.value.customerId)
) )
const getContactListList = async () => { const getContactListList = async () => {
contactList.value = await ContactApi.getSimpleContactList() contactList.value = await ContactApi.getSimpleContactList()
} }
const userList = ref<UserApi.UserVO[]>([])
/** 获取用户列表 */ /** 获取用户列表 */
const userList = ref<UserApi.UserVO[]>([])
const getUserList = async () => { const getUserList = async () => {
userList.value = await UserApi.getSimpleUserList() userList.value = await UserApi.getSimpleUserList()
} }
const businessList = ref<BusinessApi.BusinessVO[]>([])
/** 获取商机 */ /** 获取商机 */
const businessList = ref<BusinessApi.BusinessVO[]>([])
const getBusinessList = async () => { const getBusinessList = async () => {
businessList.value = await BusinessApi.getSimpleBusinessList() businessList.value = await BusinessApi.getSimpleBusinessList()
} }
/** 重置表单 */
const resetForm = () => {
formData.value = {} as ContractApi.ContractVO
formRef.value?.resetFields()
}
</script> </script>

View File

@ -1,3 +1,4 @@
<!-- 合同 Form 表单下的 Product 列表 -->
<template> <template>
<el-row justify="end"> <el-row justify="end">
<el-button plain type="primary" @click="openForm">添加产品</el-button> <el-button plain type="primary" @click="openForm">添加产品</el-button>
@ -71,23 +72,32 @@ withDefaults(defineProps<{ modelValue: any[] }>(), { modelValue: () => [] })
const emits = defineEmits<{ const emits = defineEmits<{
(e: 'update:modelValue', v: any[]): void (e: 'update:modelValue', v: any[]): void
}>() }>()
const list = ref<ProductApi.ProductExpandVO[]>([])
const list = ref<ProductApi.ProductExpandVO[]>([]) // TODO @puhui999
const multipleSelection = ref<ProductApi.ProductExpandVO[]>([]) //
/** 处理删除 */
const handleDelete = (id: number) => { const handleDelete = (id: number) => {
const index = list.value.findIndex((item) => item.id === id) const index = list.value.findIndex((item) => item.id === id)
if (index !== -1) { if (index !== -1) {
list.value.splice(index, 1) list.value.splice(index, 1)
} }
} }
/** 打开 Product 弹窗 */
const tableSelectFormRef = ref<InstanceType<typeof TableSelectForm>>() const tableSelectFormRef = ref<InstanceType<typeof TableSelectForm>>()
const multipleSelection = ref<ProductApi.ProductExpandVO[]>([])
const openForm = () => { const openForm = () => {
tableSelectFormRef.value?.open(ProductApi.getProductPage) tableSelectFormRef.value?.open(ProductApi.getProductPage)
} }
/** 计算 totalPrice */
const getTotalPrice = computed(() => (row: ProductApi.ProductExpandVO) => { const getTotalPrice = computed(() => (row: ProductApi.ProductExpandVO) => {
const totalPrice = (row.price * row.count * row.discountPercent) / 100 const totalPrice = (row.price * row.count * row.discountPercent) / 100
row.totalPrice = isNaN(totalPrice) ? 0 : totalPrice row.totalPrice = isNaN(totalPrice) ? 0 : totalPrice
return isNaN(totalPrice) ? 0 : totalPrice return isNaN(totalPrice) ? 0 : totalPrice
}) })
// TODO @puhui999
watch( watch(
list, list,
(val) => { (val) => {
@ -98,6 +108,8 @@ watch(
}, },
{ deep: true } { deep: true }
) )
// TODO @puhui999
watch( watch(
multipleSelection, multipleSelection,
(val) => { (val) => {

View File

@ -1,3 +1,4 @@
<!-- TODO @puhui999这个组件的注释加下方便大家打开就知道哈 -->
<template> <template>
<div> <div>
<div class="flex items-start justify-between"> <div class="flex items-start justify-between">

View File

@ -1,3 +1,4 @@
<!-- TODO @puhui999这个组件的注释加下方便大家打开就知道哈 -->
<template> <template>
<ContentWrap> <ContentWrap>
<el-collapse v-model="activeNames"> <el-collapse v-model="activeNames">

View File

@ -1,3 +1,4 @@
<!-- TODO @puhui999这个组件的注释加下方便大家打开就知道哈 -->
<template> <template>
<ContractDetailsHeader v-loading="loading" :contract="contract"> <ContractDetailsHeader v-loading="loading" :contract="contract">
<el-button v-if="permissionListRef?.validateWrite" @click="openForm('update', contract.id)"> <el-button v-if="permissionListRef?.validateWrite" @click="openForm('update', contract.id)">
@ -57,11 +58,14 @@ const message = useMessage()
const contractId = ref(0) // const contractId = ref(0) //
const loading = ref(true) // const loading = ref(true) //
const contract = ref<ContractApi.ContractVO>({} as ContractApi.ContractVO) // const contract = ref<ContractApi.ContractVO>({} as ContractApi.ContractVO) //
const permissionListRef = ref<InstanceType<typeof PermissionList>>() // Ref
/** 编辑 */ /** 编辑 */
const formRef = ref() const formRef = ref()
const openForm = (type: string, id?: number) => { const openForm = (type: string, id?: number) => {
formRef.value.open(type, id) formRef.value.open(type, id)
} }
/** 获取详情 */ /** 获取详情 */
const getContractData = async () => { const getContractData = async () => {
loading.value = true loading.value = true
@ -86,18 +90,21 @@ const getOperateLog = async (contractId: number) => {
logList.value = data.list logList.value = data.list
} }
/** 转移 */
// TODO @puhui999transferFormRef
const crmTransferFormRef = ref<InstanceType<typeof CrmTransferForm>>() // ref const crmTransferFormRef = ref<InstanceType<typeof CrmTransferForm>>() // ref
const transfer = () => { const transfer = () => {
crmTransferFormRef.value?.open('合同转移', contract.value.id, ContractApi.transfer) crmTransferFormRef.value?.open('合同转移', contract.value.id, ContractApi.transfer)
} }
const permissionListRef = ref<InstanceType<typeof PermissionList>>() // Ref /** 关闭 */
/** 初始化 */
const { delView } = useTagsViewStore() // const { delView } = useTagsViewStore() //
const { currentRoute } = useRouter() // const { currentRoute } = useRouter() //
const close = () => { const close = () => {
delView(unref(currentRoute)) delView(unref(currentRoute))
} }
/** 初始化 */
onMounted(async () => { onMounted(async () => {
const id = route.params.id const id = route.params.id
if (!id) { if (!id) {

View File

@ -1,3 +1,4 @@
<!-- TODO @puhui999这个好像和 detail 重复了 -->
<template> <template>
<el-form ref="formRef" v-loading="formLoading" :model="formData" label-width="110px"> <el-form ref="formRef" v-loading="formLoading" :model="formData" label-width="110px">
<el-row> <el-row>

View File

@ -1,3 +1,4 @@
<!-- 客户导入窗口 -->
<template> <template>
<Dialog v-model="dialogVisible" title="客户导入" width="400"> <Dialog v-model="dialogVisible" title="客户导入" width="400">
<el-upload <el-upload
@ -20,7 +21,7 @@
<div class="el-upload__tip text-center"> <div class="el-upload__tip text-center">
<div class="el-upload__tip"> <div class="el-upload__tip">
<el-checkbox v-model="updateSupport" /> <el-checkbox v-model="updateSupport" />
是否更新已经存在的客户数据 是否更新已经存在的客户数据客户名称重复
</div> </div>
<span>仅允许导入 xlsxlsx 格式文件</span> <span>仅允许导入 xlsxlsx 格式文件</span>
<el-link <el-link

View File

@ -339,10 +339,14 @@ const handleDelete = async (id: number) => {
await getList() await getList()
} catch {} } catch {}
} }
/** 导入按钮操作 */
// TODO @puhui999importFormRef
const customerImportFormRef = ref<InstanceType<typeof CustomerImportForm>>() const customerImportFormRef = ref<InstanceType<typeof CustomerImportForm>>()
const handleImport = () => { const handleImport = () => {
customerImportFormRef.value?.open() customerImportFormRef.value?.open()
} }
/** 导出按钮操作 */ /** 导出按钮操作 */
const handleExport = async () => { const handleExport = async () => {
try { try {