diff --git a/src/api/bpm/model/index.ts b/src/api/bpm/model/index.ts index 2e1d4e64..fea5ecf0 100644 --- a/src/api/bpm/model/index.ts +++ b/src/api/bpm/model/index.ts @@ -32,7 +32,9 @@ export const getModelPage = async (params) => { export const getModel = async (id: number) => { return await request.get({ url: '/bpm/model/get?id=' + id }) } - +export const getModelByKey = async (key: string) => { + return await request.get({ url: '/bpm/model/get-by-key?key=' + key }) +} export const updateModel = async (data: ModelVO) => { return await request.put({ url: '/bpm/model/update', data: data }) } diff --git a/src/api/crm/bi/ranking.ts b/src/api/crm/bi/ranking.ts new file mode 100644 index 00000000..53c09e63 --- /dev/null +++ b/src/api/crm/bi/ranking.ts @@ -0,0 +1,34 @@ +import request from '@/config/axios' + +export interface BiContractRanKingRespVO { + price: number + nickname: string + deptName: string +} +export interface BiReceivablesRanKingRespVO { + price: number + nickname: string + deptName: string +} +export interface BiRankReqVO { + deptId: number + type: string +} + +// 排行 API +export const RankingStatisticsApi = { + // 获得合同排行榜 + contractAmountRanking: (params: any) => { + return request.get({ + url: '/bi/ranking/contract-ranking', + params + }) + }, + // 获得回款排行榜 + receivablesAmountRanking: (params: any) => { + return request.get({ + url: '/bi/ranking/receivables-ranking', + params + }) + } +} diff --git a/src/api/crm/business/index.ts b/src/api/crm/business/index.ts index 810ec6e9..314eb389 100644 --- a/src/api/crm/business/index.ts +++ b/src/api/crm/business/index.ts @@ -1,4 +1,5 @@ import request from '@/config/axios' +import { TransferReqVO } from '@/api/crm/customer' export interface BusinessVO { id: number @@ -70,3 +71,8 @@ export const getBusinessPageByContact = async (params) => { export const getBusinessListByIds = async (val: number[]) => { return await request.get({ url: '/crm/business/list-by-ids', params: { ids: val.join(',') } }) } + +// 商机转移 +export const transfer = async (data: TransferReqVO) => { + return await request.put({ url: '/crm/business/transfer', data }) +} diff --git a/src/api/crm/contact/index.ts b/src/api/crm/contact/index.ts index 4144c931..6edb90a1 100644 --- a/src/api/crm/contact/index.ts +++ b/src/api/crm/contact/index.ts @@ -1,4 +1,5 @@ import request from '@/config/axios' +import { TransferReqVO } from '@/api/crm/customer' export interface ContactVO { name: string @@ -86,7 +87,7 @@ export const deleteContactBusinessList = async (data: ContactBusinessReqVO) => { return await request.delete({ url: `/crm/contact/delete-business-list`, data }) } -// 查询联系人操作日志 -export const getOperateLogPage = async (params: any) => { - return await request.get({ url: '/crm/contact/operate-log-page', params }) +// 联系人转移 +export const transfer = async (data: TransferReqVO) => { + return await request.put({ url: '/crm/contact/transfer', data }) } diff --git a/src/api/crm/contract/index.ts b/src/api/crm/contract/index.ts index 3498e843..731750c1 100644 --- a/src/api/crm/contract/index.ts +++ b/src/api/crm/contract/index.ts @@ -1,4 +1,6 @@ import request from '@/config/axios' +import { ProductExpandVO } from '@/api/crm/product' +import { TransferReqVO } from '@/api/crm/customer' export interface ContractVO { id: number @@ -14,12 +16,18 @@ export interface ContractVO { price: number discountPercent: number productPrice: number - roUserIds: string - rwUserIds: string contactId: number signUserId: number contactLastTime: Date + status: number remark: string + productItems: ProductExpandVO[] + creatorName: string + updateTime?: Date + createTime?: Date + customerName: string + contactName: string + ownerUserName: string } // 查询 CRM 合同列表 @@ -56,3 +64,13 @@ export const deleteContract = async (id: number) => { export const exportContract = async (params) => { return await request.download({ url: `/crm/contract/export-excel`, params }) } + +// 提交审核 +export const handleApprove = async (id: number) => { + return await request.put({ url: `/crm/contract/approve?id=${id}` }) +} + +// 合同转移 +export const transfer = async (data: TransferReqVO) => { + return await request.put({ url: '/crm/contract/transfer', data }) +} diff --git a/src/api/crm/customer/index.ts b/src/api/crm/customer/index.ts index eb3445cf..a6fb489b 100644 --- a/src/api/crm/customer/index.ts +++ b/src/api/crm/customer/index.ts @@ -63,16 +63,16 @@ export const exportCustomer = async (params: any) => { return await request.download({ url: `/crm/customer/export-excel`, params }) } +// 下载客户导入模板 +export const importCustomerTemplate = () => { + return request.download({ url: '/crm/customer/get-import-template' }) +} + // 客户列表 export const getSimpleCustomerList = async () => { return await request.get({ url: `/crm/customer/list-all-simple` }) } -// 查询客户操作日志 -export const getOperateLogPage = async (id: number) => { - return await request.get({ url: '/crm/customer/operate-log-page?id=' + id }) -} - // ======================= 业务操作 ======================= export interface TransferReqVO { diff --git a/src/api/crm/operateLog/index.ts b/src/api/crm/operateLog/index.ts new file mode 100644 index 00000000..d0f25b6b --- /dev/null +++ b/src/api/crm/operateLog/index.ts @@ -0,0 +1,11 @@ +import request from '@/config/axios' + +export interface OperateLogVO extends PageParam { + bizType: number + bizId: number +} + +// 获得操作日志 +export const getOperateLogPage = async (params: OperateLogVO) => { + return await request.get({ url: `/crm/operate-log/page`, params }) +} diff --git a/src/api/crm/permission/index.ts b/src/api/crm/permission/index.ts index e616a404..5c829b6a 100644 --- a/src/api/crm/permission/index.ts +++ b/src/api/crm/permission/index.ts @@ -22,8 +22,11 @@ export enum BizTypeEnum { CRM_LEADS = 1, // 线索 CRM_CUSTOMER = 2, // 客户 CRM_CONTACT = 3, // 联系人 - CRM_BUSINESS = 5, // 商机 - CRM_CONTRACT = 6 // 合同 + CRM_BUSINESS = 4, // 商机 + CRM_CONTRACT = 5, // 合同 + CRM_PRODUCT = 6, // 产品 + CRM_RECEIVABLE = 7, // 回款 + CRM_RECEIVABLE_PLAN = 8 // 回款计划 } /** diff --git a/src/api/crm/product/index.ts b/src/api/crm/product/index.ts index 2d88cb09..e6508fb4 100644 --- a/src/api/crm/product/index.ts +++ b/src/api/crm/product/index.ts @@ -12,6 +12,12 @@ export interface ProductVO { ownerUserId: number } +export interface ProductExpandVO extends ProductVO { + count: number + discountPercent: number + totalPrice: number +} + // 查询产品列表 export const getProductPage = async (params) => { return await request.get({ url: `/crm/product/page`, params }) @@ -41,8 +47,3 @@ export const deleteProduct = async (id: number) => { export const exportProduct = async (params) => { return await request.download({ url: `/crm/product/export-excel`, params }) } - -// 查询产品操作日志 -export const getOperateLogPage = async (params: any) => { - return await request.get({ url: '/crm/product/operate-log-page', params }) -} diff --git a/src/components/Table/index.ts b/src/components/Table/index.ts index 689f64a8..9f893171 100644 --- a/src/components/Table/index.ts +++ b/src/components/Table/index.ts @@ -1,6 +1,7 @@ import Table from './src/Table.vue' import { ElTable } from 'element-plus' import { TableSetPropsType } from '@/types/table' +import TableSelectForm from './src/TableSelectForm.vue' export interface TableExpose { setProps: (props: Recordable) => void @@ -9,4 +10,4 @@ export interface TableExpose { elTableRef: ComponentRef } -export { Table } +export { Table, TableSelectForm } diff --git a/src/components/Table/src/TableSelectForm.vue b/src/components/Table/src/TableSelectForm.vue new file mode 100644 index 00000000..55b2855e --- /dev/null +++ b/src/components/Table/src/TableSelectForm.vue @@ -0,0 +1,90 @@ + + + diff --git a/src/router/modules/remaining.ts b/src/router/modules/remaining.ts index 7bcd81d2..edda3820 100644 --- a/src/router/modules/remaining.ts +++ b/src/router/modules/remaining.ts @@ -507,6 +507,17 @@ const remainingRouter: AppRouteRecordRaw[] = [ }, component: () => import('@/views/crm/customer/detail/index.vue') }, + { + path: 'contract/detail/:id', + name: 'CrmContractDetail', + meta: { + title: '合同详情', + noCache: true, + hidden: true, + activeMenu: '/crm/contract' + }, + component: () => import('@/views/crm/contract/detail/index.vue') + }, { path: 'contact/detail/:id', name: 'CrmContactDetail', diff --git a/src/utils/dict.ts b/src/utils/dict.ts index 2c8e47ff..4c490f59 100644 --- a/src/utils/dict.ts +++ b/src/utils/dict.ts @@ -203,5 +203,8 @@ export enum DICT_TYPE { CRM_PRODUCT_STATUS = 'crm_product_status', CRM_PERMISSION_LEVEL = 'crm_permission_level', // CRM 数据权限的级别 CRM_PRODUCT_UNIT = 'crm_product_unit', // 产品单位 - CRM_FOLLOW_UP_TYPE = 'crm_follow_up_type' // 跟进方式 + CRM_FOLLOW_UP_TYPE = 'crm_follow_up_type', // 跟进方式 + + // ========== BI - 商业智能模块 ========== + BI_ANALYZE_TYPE = 'bi_analyze_type' // 分析类型 } diff --git a/src/views/crm/bi/ranking/components/RankingContractStatistics.vue b/src/views/crm/bi/ranking/components/RankingContractStatistics.vue new file mode 100644 index 00000000..b560131c --- /dev/null +++ b/src/views/crm/bi/ranking/components/RankingContractStatistics.vue @@ -0,0 +1,133 @@ + + + diff --git a/src/views/crm/bi/ranking/components/RankingReceivablesStatistics.vue b/src/views/crm/bi/ranking/components/RankingReceivablesStatistics.vue new file mode 100644 index 00000000..80186535 --- /dev/null +++ b/src/views/crm/bi/ranking/components/RankingReceivablesStatistics.vue @@ -0,0 +1,133 @@ + + + diff --git a/src/views/crm/bi/ranking/index.vue b/src/views/crm/bi/ranking/index.vue new file mode 100644 index 00000000..fac2b8ba --- /dev/null +++ b/src/views/crm/bi/ranking/index.vue @@ -0,0 +1,91 @@ + + + diff --git a/src/views/crm/contact/detail/ContactDetailsHeader.vue b/src/views/crm/contact/detail/ContactDetailsHeader.vue index 31daa499..86fb42a5 100644 --- a/src/views/crm/contact/detail/ContactDetailsHeader.vue +++ b/src/views/crm/contact/detail/ContactDetailsHeader.vue @@ -10,9 +10,7 @@
- - 编辑 - +
@@ -32,18 +30,10 @@ - - - diff --git a/src/views/crm/contact/detail/index.vue b/src/views/crm/contact/detail/index.vue index cb8eea16..65678a3d 100644 --- a/src/views/crm/contact/detail/index.vue +++ b/src/views/crm/contact/detail/index.vue @@ -1,5 +1,12 @@ - diff --git a/src/views/crm/contract/components/BPMLModel.vue b/src/views/crm/contract/components/BPMLModel.vue new file mode 100644 index 00000000..5a8e7ecc --- /dev/null +++ b/src/views/crm/contract/components/BPMLModel.vue @@ -0,0 +1,31 @@ + + + diff --git a/src/views/crm/contract/components/ProductList.vue b/src/views/crm/contract/components/ProductList.vue new file mode 100644 index 00000000..6c4ca350 --- /dev/null +++ b/src/views/crm/contract/components/ProductList.vue @@ -0,0 +1,112 @@ + + + diff --git a/src/views/crm/contract/detail/ContractDetailsHeader.vue b/src/views/crm/contract/detail/ContractDetailsHeader.vue new file mode 100644 index 00000000..b3552735 --- /dev/null +++ b/src/views/crm/contract/detail/ContractDetailsHeader.vue @@ -0,0 +1,40 @@ + + diff --git a/src/views/crm/contract/detail/ContractDetailsInfo.vue b/src/views/crm/contract/detail/ContractDetailsInfo.vue new file mode 100644 index 00000000..f18f7c08 --- /dev/null +++ b/src/views/crm/contract/detail/ContractDetailsInfo.vue @@ -0,0 +1,51 @@ + + diff --git a/src/views/crm/contract/detail/index.vue b/src/views/crm/contract/detail/index.vue new file mode 100644 index 00000000..fde35ba2 --- /dev/null +++ b/src/views/crm/contract/detail/index.vue @@ -0,0 +1,111 @@ + + diff --git a/src/views/crm/contract/index.vue b/src/views/crm/contract/index.vue index 26ff403a..da3aeaad 100644 --- a/src/views/crm/contract/index.vue +++ b/src/views/crm/contract/index.vue @@ -2,44 +2,52 @@ - 搜索 - 重置 - - 新增 + + + 搜索 + + + + 重置 + + + + 新增 - 导出 + + 导出 @@ -48,70 +56,86 @@ - - - - - - + + + + + + - - + + - - - - - + + + + + - - + + - diff --git a/src/views/crm/customer/CustomerImportForm.vue b/src/views/crm/customer/CustomerImportForm.vue new file mode 100644 index 00000000..7a74acf9 --- /dev/null +++ b/src/views/crm/customer/CustomerImportForm.vue @@ -0,0 +1,134 @@ + + diff --git a/src/views/crm/customer/detail/index.vue b/src/views/crm/customer/detail/index.vue index 23c169f6..44e62314 100644 --- a/src/views/crm/customer/detail/index.vue +++ b/src/views/crm/customer/detail/index.vue @@ -91,6 +91,7 @@ import CrmTransferForm from '@/views/crm/permission/components/TransferForm.vue' import FollowUpList from '@/views/crm/followup/index.vue' import { BizTypeEnum } from '@/api/crm/permission' import type { OperateLogV2VO } from '@/api/system/operatelog' +import { getOperateLogPage } from '@/api/crm/operateLog' defineOptions({ name: 'CrmCustomerDetail' }) @@ -164,7 +165,10 @@ const getOperateLog = async () => { if (!customerId.value) { return } - const data = await CustomerApi.getOperateLogPage(customerId.value) + const data = await getOperateLogPage({ + bizType: BizTypeEnum.CRM_CUSTOMER, + bizId: customerId.value + }) logList.value = data.list } diff --git a/src/views/crm/customer/index.vue b/src/views/crm/customer/index.vue index b2cee2f7..2c441d99 100644 --- a/src/views/crm/customer/index.vue +++ b/src/views/crm/customer/index.vue @@ -84,6 +84,10 @@ 新增 + + + 导入 + +