diff --git a/src/api/crm/backlog/index.ts b/src/api/crm/backlog/index.ts index 614b0ef2..7ea01990 100644 --- a/src/api/crm/backlog/index.ts +++ b/src/api/crm/backlog/index.ts @@ -1,11 +1,6 @@ import request from '@/config/axios' // TODO 芋艿:融合下 -// 3. 获得分配给我的客户数量 -export const getFollowCustomerCount = async () => { - return await request.get({ url: '/crm/customer/follow-customer-count' }) -} - // 5. 获得待审核合同数量 export const getCheckContractCount = async () => { return await request.get({ url: '/crm/contract/check-contract-count' }) diff --git a/src/api/crm/contact/index.ts b/src/api/crm/contact/index.ts index e16646cc..67036194 100644 --- a/src/api/crm/contact/index.ts +++ b/src/api/crm/contact/index.ts @@ -37,6 +37,11 @@ export interface ContactBusinessReqVO { businessIds: number[] } +export interface ContactBusiness2ReqVO { + businessId: number + contactIds: number[] +} + // 查询 CRM 联系人列表 export const getContactPage = async (params) => { return await request.get({ url: `/crm/contact/page`, params }) @@ -87,11 +92,21 @@ export const createContactBusinessList = async (data: ContactBusinessReqVO) => { return await request.post({ url: `/crm/contact/create-business-list`, data }) } +// 批量新增联系人商机关联 +export const createContactBusinessList2 = async (data: ContactBusiness2ReqVO) => { + return await request.post({ url: `/crm/contact/create-business-list2`, data }) +} + // 解除联系人商机关联 export const deleteContactBusinessList = async (data: ContactBusinessReqVO) => { return await request.delete({ url: `/crm/contact/delete-business-list`, data }) } +// 解除联系人商机关联 +export const deleteContactBusinessList2 = async (data: ContactBusiness2ReqVO) => { + return await request.delete({ url: `/crm/contact/delete-business-list2`, data }) +} + // 联系人转移 export const transferContact = 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 494c60c7..bd9e93e0 100644 --- a/src/api/crm/contract/index.ts +++ b/src/api/crm/contract/index.ts @@ -101,3 +101,13 @@ export const submitContract = async (id: number) => { export const transferContract = async (data: TransferReqVO) => { return await request.put({ url: '/crm/contract/transfer', data }) } + +// 获得待审核合同数量 +export const getAuditContractCount = async () => { + return await request.get({ url: '/crm/contract/audit-count' }) +} + +// 获得即将到期(提醒)的合同数量 +export const getRemindContractCount = async () => { + return await request.get({ url: '/crm/contract/remind-count' }) +} diff --git a/src/api/crm/bi/rank.ts b/src/api/crm/statistics/rank.ts similarity index 65% rename from src/api/crm/bi/rank.ts rename to src/api/crm/statistics/rank.ts index 13ceb7ef..a9b355e0 100644 --- a/src/api/crm/bi/rank.ts +++ b/src/api/crm/statistics/rank.ts @@ -1,66 +1,66 @@ import request from '@/config/axios' -export interface BiRankRespVO { +export interface StatisticsRankRespVO { count: number nickname: string deptName: string } // 排行 API -export const RankApi = { +export const StatisticsRankApi = { // 获得合同排行榜 getContractPriceRank: (params: any) => { return request.get({ - url: '/crm/bi-rank/get-contract-price-rank', + url: '/crm/statistics-rank/get-contract-price-rank', params }) }, // 获得回款排行榜 getReceivablePriceRank: (params: any) => { return request.get({ - url: '/crm/bi-rank/get-receivable-price-rank', + url: '/crm/statistics-rank/get-receivable-price-rank', params }) }, // 签约合同排行 getContractCountRank: (params: any) => { return request.get({ - url: '/crm/bi-rank/get-contract-count-rank', + url: '/crm/statistics-rank/get-contract-count-rank', params }) }, // 产品销量排行 getProductSalesRank: (params: any) => { return request.get({ - url: '/crm/bi-rank/get-product-sales-rank', + url: '/crm/statistics-rank/get-product-sales-rank', params }) }, // 新增客户数排行 getCustomerCountRank: (params: any) => { return request.get({ - url: '/crm/bi-rank/get-customer-count-rank', + url: '/crm/statistics-rank/get-customer-count-rank', params }) }, // 新增联系人数排行 getContactsCountRank: (params: any) => { return request.get({ - url: '/crm/bi-rank/get-contacts-count-rank', + url: '/crm/statistics-rank/get-contacts-count-rank', params }) }, // 跟进次数排行 getFollowCountRank: (params: any) => { return request.get({ - url: '/crm/bi-rank/get-follow-count-rank', + url: '/crm/statistics-rank/get-follow-count-rank', params }) }, // 跟进客户数排行 getFollowCustomerCountRank: (params: any) => { return request.get({ - url: '/crm/bi-rank/get-follow-customer-count-rank', + url: '/crm/statistics-rank/get-follow-customer-count-rank', params }) } diff --git a/src/views/crm/backlog/tables/CheckContract.vue b/src/views/crm/backlog/components/ContractAuditList.vue similarity index 67% rename from src/views/crm/backlog/tables/CheckContract.vue rename to src/views/crm/backlog/components/ContractAuditList.vue index ad4782e0..62a80b4d 100644 --- a/src/views/crm/backlog/tables/CheckContract.vue +++ b/src/views/crm/backlog/components/ContractAuditList.vue @@ -30,8 +30,14 @@ <ContentWrap> <el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true"> - <el-table-column align="center" fixed="left" label="合同编号" prop="no" width="130" /> - <el-table-column align="center" label="合同名称" prop="name" width="130" /> + <el-table-column align="center" fixed="left" label="合同编号" prop="no" width="180" /> + <el-table-column align="center" fixed="left" label="合同名称" prop="name" width="160"> + <template #default="scope"> + <el-link :underline="false" type="primary" @click="openDetail(scope.row.id)"> + {{ scope.row.name }} + </el-link> + </template> + </el-table-column> <el-table-column align="center" label="客户名称" prop="customerName" width="120"> <template #default="scope"> <el-link @@ -43,8 +49,24 @@ </el-link> </template> </el-table-column> - <!-- TODO @puhui999:做了商机详情后,可以把这个超链接加上 --> - <el-table-column align="center" label="商机名称" prop="businessName" width="130" /> + <el-table-column align="center" label="商机名称" prop="businessName" width="130"> + <template #default="scope"> + <el-link + :underline="false" + type="primary" + @click="openBusinessDetail(scope.row.businessId)" + > + {{ scope.row.businessName }} + </el-link> + </template> + </el-table-column> + <el-table-column + align="center" + label="合同金额(元)" + prop="totalPrice" + width="140" + :formatter="erpPriceTableColumnFormatter" + /> <el-table-column align="center" label="下单时间" @@ -52,13 +74,6 @@ width="120" :formatter="dateFormatter2" /> - <el-table-column - align="center" - label="合同金额" - prop="price" - width="130" - :formatter="fenToYuanFormat" - /> <el-table-column align="center" label="合同开始时间" @@ -78,17 +93,24 @@ <el-link :underline="false" type="primary" - @click="openContactDetail(scope.row.contactId)" + @click="openContactDetail(scope.row.signContactId)" > - {{ scope.row.contactName }} + {{ scope.row.signContactName }} </el-link> </template> </el-table-column> <el-table-column align="center" label="公司签约人" prop="signUserName" width="130" /> - <el-table-column align="center" label="备注" prop="remark" width="130" /> + <el-table-column align="center" label="备注" prop="remark" width="200" /> <!-- TODO @puhui999:后续可加 【已收款金额】、【未收款金额】 --> + <el-table-column + :formatter="dateFormatter" + align="center" + label="最后跟进时间" + prop="contactLastTime" + width="180px" + /> <el-table-column align="center" label="负责人" prop="ownerUserName" width="120" /> - <el-table-column align="center" label="创建人" prop="creatorName" width="120" /> + <el-table-column align="center" label="所属部门" prop="ownerUserDeptName" width="100px" /> <el-table-column :formatter="dateFormatter" align="center" @@ -103,11 +125,24 @@ prop="createTime" width="180px" /> + <el-table-column align="center" label="创建人" prop="creatorName" width="120" /> <el-table-column align="center" fixed="right" label="合同状态" prop="auditStatus" width="120"> <template #default="scope"> <dict-tag :type="DICT_TYPE.CRM_AUDIT_STATUS" :value="scope.row.auditStatus" /> </template> </el-table-column> + <el-table-column fixed="right" label="操作" width="90"> + <template #default="scope"> + <el-button + link + v-hasPermi="['crm:contract:update']" + type="primary" + @click="handleProcessDetail(scope.row)" + > + 查看审批 + </el-button> + </template> + </el-table-column> </el-table> <!-- 分页 --> <Pagination @@ -122,9 +157,9 @@ <script setup lang="ts" name="CheckContract"> import { dateFormatter, dateFormatter2 } from '@/utils/formatTime' import * as ContractApi from '@/api/crm/contract' -import { fenToYuanFormat } from '@/utils/formatter' import { DICT_TYPE } from '@/utils/dict' import { AUDIT_STATUS } from './common' +import { erpPriceTableColumnFormatter } from '@/utils' const loading = ref(true) // 列表的加载中 const total = ref(0) // 列表的总页数 @@ -132,7 +167,8 @@ const list = ref([]) // 列表的数据 const queryParams = reactive({ pageNo: 1, pageSize: 10, - auditStatus: 20 + sceneType: 1, // 我负责的 + auditStatus: 10 }) const queryFormRef = ref() // 搜索的表单 @@ -154,8 +190,18 @@ const handleQuery = () => { getList() } +/** 查看审批 */ +const handleProcessDetail = (row: ContractApi.ContractVO) => { + push({ name: 'BpmProcessInstanceDetail', query: { id: row.processInstanceId } }) +} + +/** 打开合同详情 */ +const { push } = useRouter() +const openDetail = (id: number) => { + push({ name: 'CrmContractDetail', params: { id } }) +} + /** 打开客户详情 */ -const { push } = useRouter() // 路由 const openCustomerDetail = (id: number) => { push({ name: 'CrmCustomerDetail', params: { id } }) } @@ -165,6 +211,16 @@ const openContactDetail = (id: number) => { push({ name: 'CrmContactDetail', params: { id } }) } +/** 打开商机详情 */ +const openBusinessDetail = (id: number) => { + push({ name: 'CrmBusinessDetail', params: { id } }) +} + +/** 激活时 */ +onActivated(async () => { + await getList() +}) + /** 初始化 **/ onMounted(() => { getList() diff --git a/src/views/crm/backlog/tables/EndContract.vue b/src/views/crm/backlog/components/ContractRemindList.vue similarity index 68% rename from src/views/crm/backlog/tables/EndContract.vue rename to src/views/crm/backlog/components/ContractRemindList.vue index f31bb524..2f87f44c 100644 --- a/src/views/crm/backlog/tables/EndContract.vue +++ b/src/views/crm/backlog/components/ContractRemindList.vue @@ -30,8 +30,14 @@ <ContentWrap> <el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true"> - <el-table-column align="center" fixed="left" label="合同编号" prop="no" width="130" /> - <el-table-column align="center" label="合同名称" prop="name" width="130" /> + <el-table-column align="center" fixed="left" label="合同编号" prop="no" width="180" /> + <el-table-column align="center" fixed="left" label="合同名称" prop="name" width="160"> + <template #default="scope"> + <el-link :underline="false" type="primary" @click="openDetail(scope.row.id)"> + {{ scope.row.name }} + </el-link> + </template> + </el-table-column> <el-table-column align="center" label="客户名称" prop="customerName" width="120"> <template #default="scope"> <el-link @@ -43,8 +49,24 @@ </el-link> </template> </el-table-column> - <!-- TODO @puhui999:做了商机详情后,可以把这个超链接加上 --> - <el-table-column align="center" label="商机名称" prop="businessName" width="130" /> + <el-table-column align="center" label="商机名称" prop="businessName" width="130"> + <template #default="scope"> + <el-link + :underline="false" + type="primary" + @click="openBusinessDetail(scope.row.businessId)" + > + {{ scope.row.businessName }} + </el-link> + </template> + </el-table-column> + <el-table-column + align="center" + label="合同金额(元)" + prop="totalPrice" + width="140" + :formatter="erpPriceTableColumnFormatter" + /> <el-table-column align="center" label="下单时间" @@ -52,13 +74,6 @@ width="120" :formatter="dateFormatter2" /> - <el-table-column - align="center" - label="合同金额" - prop="price" - width="130" - :formatter="fenToYuanFormat" - /> <el-table-column align="center" label="合同开始时间" @@ -78,17 +93,24 @@ <el-link :underline="false" type="primary" - @click="openContactDetail(scope.row.contactId)" + @click="openContactDetail(scope.row.signContactId)" > - {{ scope.row.contactName }} + {{ scope.row.signContactName }} </el-link> </template> </el-table-column> <el-table-column align="center" label="公司签约人" prop="signUserName" width="130" /> - <el-table-column align="center" label="备注" prop="remark" width="130" /> + <el-table-column align="center" label="备注" prop="remark" width="200" /> <!-- TODO @puhui999:后续可加 【已收款金额】、【未收款金额】 --> + <el-table-column + :formatter="dateFormatter" + align="center" + label="最后跟进时间" + prop="contactLastTime" + width="180px" + /> <el-table-column align="center" label="负责人" prop="ownerUserName" width="120" /> - <el-table-column align="center" label="创建人" prop="creatorName" width="120" /> + <el-table-column align="center" label="所属部门" prop="ownerUserDeptName" width="100px" /> <el-table-column :formatter="dateFormatter" align="center" @@ -103,11 +125,24 @@ prop="createTime" width="180px" /> + <el-table-column align="center" label="创建人" prop="creatorName" width="120" /> <el-table-column align="center" fixed="right" label="合同状态" prop="auditStatus" width="120"> <template #default="scope"> <dict-tag :type="DICT_TYPE.CRM_AUDIT_STATUS" :value="scope.row.auditStatus" /> </template> </el-table-column> + <el-table-column fixed="right" label="操作" width="90"> + <template #default="scope"> + <el-button + link + v-hasPermi="['crm:contract:update']" + type="primary" + @click="handleProcessDetail(scope.row)" + > + 查看审批 + </el-button> + </template> + </el-table-column> </el-table> <!-- 分页 --> <Pagination @@ -125,8 +160,7 @@ import * as ContractApi from '@/api/crm/contract' import { fenToYuanFormat } from '@/utils/formatter' import { DICT_TYPE } from '@/utils/dict' import { CONTRACT_EXPIRY_TYPE } from './common' - -const { push } = useRouter() // 路由 +import { erpPriceTableColumnFormatter } from '@/utils' const loading = ref(true) // 列表的加载中 const total = ref(0) // 列表的总页数 @@ -134,6 +168,7 @@ const list = ref([]) // 列表的数据 const queryParams = reactive({ pageNo: 1, pageSize: 10, + sceneType: '1', // 自己负责的 expiryType: 1 }) const queryFormRef = ref() // 搜索的表单 @@ -156,6 +191,17 @@ const handleQuery = () => { getList() } +/** 查看审批 */ +const handleProcessDetail = (row: ContractApi.ContractVO) => { + push({ name: 'BpmProcessInstanceDetail', query: { id: row.processInstanceId } }) +} + +/** 打开合同详情 */ +const { push } = useRouter() +const openDetail = (id: number) => { + push({ name: 'CrmContractDetail', params: { id } }) +} + /** 打开客户详情 */ const openCustomerDetail = (id: number) => { push({ name: 'CrmCustomerDetail', params: { id } }) @@ -166,10 +212,18 @@ const openContactDetail = (id: number) => { push({ name: 'CrmContactDetail', params: { id } }) } +/** 打开商机详情 */ +const openBusinessDetail = (id: number) => { + push({ name: 'CrmBusinessDetail', params: { id } }) +} + +/** 激活时 */ +onActivated(async () => { + await getList() +}) + /** 初始化 **/ onMounted(() => { getList() }) </script> - -<style scoped></style> diff --git a/src/views/crm/backlog/components/CustomerFollowList.vue b/src/views/crm/backlog/components/CustomerFollowList.vue index 8e1017a3..0f367a3f 100644 --- a/src/views/crm/backlog/components/CustomerFollowList.vue +++ b/src/views/crm/backlog/components/CustomerFollowList.vue @@ -130,8 +130,8 @@ const list = ref([]) // 列表的数据 const queryParams = ref({ pageNo: 1, pageSize: 10, - followUpStatus: false, - sceneType: 1 + sceneType: 1, + followUpStatus: false }) const queryFormRef = ref() // 搜索的表单 @@ -158,10 +158,13 @@ const openDetail = (id: number) => { push({ name: 'CrmCustomerDetail', params: { id } }) } +/** 激活时 */ +onActivated(async () => { + await getList() +}) + /** 初始化 **/ onMounted(() => { getList() }) </script> - -<style scoped></style> diff --git a/src/views/crm/backlog/components/common.ts b/src/views/crm/backlog/components/common.ts index d18763aa..9ff6bfc3 100644 --- a/src/views/crm/backlog/components/common.ts +++ b/src/views/crm/backlog/components/common.ts @@ -20,8 +20,9 @@ export const CONTACT_STATUS = [ /** 审批状态 */ export const AUDIT_STATUS = [ - { label: '已审批', value: 20 }, - { label: '待审批', value: 10 } + { label: '待审批', value: 10 }, + { label: '审核通过', value: 20 }, + { label: '审核不通过', value: 30 } ] /** 回款提醒类型 */ diff --git a/src/views/crm/backlog/index.vue b/src/views/crm/backlog/index.vue index b1351a2d..b5c3a9a4 100644 --- a/src/views/crm/backlog/index.vue +++ b/src/views/crm/backlog/index.vue @@ -17,9 +17,9 @@ <el-col :span="20" :xs="24"> <CustomerTodayContactList v-if="leftMenu === 'customerTodayContact'" /> <ClueFollowList v-if="leftMenu === 'clueFollow'" /> - <CheckContract v-if="leftMenu === 'checkContract'" /> + <ContractAuditList v-if="leftMenu === 'contractAudit'" /> <CheckReceivables v-if="leftMenu === 'checkReceivables'" /> - <EndContract v-if="leftMenu === 'endContract'" /> + <ContractRemindList v-if="leftMenu === 'contractRemind'" /> <CustomerFollowList v-if="leftMenu === 'customerFollow'" /> <CustomerPutPoolRemindList v-if="leftMenu === 'customerPutPoolRemind'" /> <RemindReceivables v-if="leftMenu === 'remindReceivables'" /> @@ -33,25 +33,26 @@ import CustomerFollowList from './components/CustomerFollowList.vue' import CustomerTodayContactList from './components/CustomerTodayContactList.vue' import CustomerPutPoolRemindList from './components/CustomerPutPoolRemindList.vue' import ClueFollowList from './components/ClueFollowList.vue' -import CheckContract from './tables/CheckContract.vue' -import CheckReceivables from './tables/CheckReceivables.vue' -import EndContract from './tables/EndContract.vue' +import ContractAuditList from './components/ContractAuditList.vue' +import ContractRemindList from './components/ContractRemindList.vue' import RemindReceivables from './tables/RemindReceivables.vue' +import CheckReceivables from './tables/CheckReceivables.vue' import * as CustomerApi from '@/api/crm/customer' import * as ClueApi from '@/api/crm/clue' +import * as ContractApi from '@/api/crm/contract' defineOptions({ name: 'CrmBacklog' }) const leftMenu = ref('customerTodayContact') -const customerTodayContactCount = ref(0) const clueFollowCount = ref(0) const customerFollowCount = ref(0) const customerPutPoolRemindCount = ref(0) -const checkContractCount = ref(0) +const customerTodayContactCount = ref(0) +const contractAuditCount = ref(0) +const contractRemindCount = ref(0) const checkReceivablesCount = ref(0) const remindReceivablesCount = ref(0) -const endContractCount = ref(0) const leftSides = ref([ { @@ -76,8 +77,8 @@ const leftSides = ref([ }, { name: '待审核合同', - menu: 'checkContract', - count: checkContractCount + menu: 'contractAudit', + count: contractAuditCount }, { name: '待审核回款', @@ -91,8 +92,8 @@ const leftSides = ref([ }, { name: '即将到期的合同', - menu: 'endContract', - count: endContractCount + menu: 'contractRemind', + count: contractRemindCount } ]) @@ -110,10 +111,10 @@ const getCount = () => { ) CustomerApi.getFollowCustomerCount().then((count) => (customerFollowCount.value = count)) ClueApi.getFollowClueCount().then((count) => (clueFollowCount.value = count)) - BacklogApi.getCheckContractCount().then((count) => (checkContractCount.value = count)) + ContractApi.getAuditContractCount().then((count) => (contractAuditCount.value = count)) + ContractApi.getRemindContractCount().then((count) => (contractRemindCount.value = count)) BacklogApi.getCheckReceivablesCount().then((count) => (checkReceivablesCount.value = count)) BacklogApi.getRemindReceivablePlanCount().then((count) => (remindReceivablesCount.value = count)) - BacklogApi.getEndContractCount().then((count) => (endContractCount.value = count)) } /** 激活时 */ diff --git a/src/views/crm/contact/components/ContactList.vue b/src/views/crm/contact/components/ContactList.vue index 7de9a3cd..83af1e52 100644 --- a/src/views/crm/contact/components/ContactList.vue +++ b/src/views/crm/contact/components/ContactList.vue @@ -5,11 +5,32 @@ <Icon class="mr-5px" icon="system-uicons:contacts" /> 创建联系人 </el-button> + <el-button + @click="openBusinessModal" + v-hasPermi="['crm:contact:create-business']" + v-if="queryParams.businessId" + > + <Icon class="mr-5px" icon="ep:circle-plus" />关联 + </el-button> + <el-button + @click="deleteContactBusinessList" + v-hasPermi="['crm:contact:delete-business']" + v-if="queryParams.businessId" + > + <Icon class="mr-5px" icon="ep:remove" />解除关联 + </el-button> </el-row> <!-- 列表 --> <ContentWrap class="mt-10px"> - <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true"> + <el-table + ref="contactRef" + v-loading="loading" + :data="list" + :stripe="true" + :show-overflow-tooltip="true" + > + <el-table-column type="selection" width="55" v-if="queryParams.businessId" /> <el-table-column label="姓名" fixed="left" align="center" prop="name"> <template #default="scope"> <el-link type="primary" :underline="false" @click="openDetail(scope.row.id)"> @@ -37,12 +58,19 @@ <!-- 表单弹窗:添加 --> <ContactForm ref="formRef" @success="getList" /> + <!-- 关联商机选择弹框 --> + <ContactListModal + ref="contactModalRef" + :customer-id="props.customerId" + @success="createContactBusinessList" + /> </template> <script setup lang="ts"> import * as ContactApi from '@/api/crm/contact' import ContactForm from './../ContactForm.vue' import { DICT_TYPE } from '@/utils/dict' import { BizTypeEnum } from '@/api/crm/permission' +import ContactListModal from './ContactListModal.vue' defineOptions({ name: 'CrmContactList' }) const props = defineProps<{ @@ -58,8 +86,10 @@ const list = ref([]) // 列表的数据 const queryParams = reactive({ pageNo: 1, pageSize: 10, - customerId: undefined as unknown // 允许 undefined + number + customerId: undefined as unknown, // 允许 undefined + number + businessId: undefined as unknown // 允许 undefined + number }) +const message = useMessage() /** 查询列表 */ const getList = async () => { @@ -106,6 +136,41 @@ const openDetail = (id: number) => { push({ name: 'CrmContactDetail', params: { id } }) } +/** 打开联系人与商机的关联弹窗 */ +const contactModalRef = ref() +const openBusinessModal = () => { + contactModalRef.value.open() +} +const createContactBusinessList = async (contactIds: number[]) => { + const data = { + businessId: props.bizId, + contactIds: contactIds + } as ContactApi.ContactBusiness2ReqVO + contactRef.value.getSelectionRows().forEach((row: ContactApi.ContactVO) => { + data.businessIds.push(row.id) + }) + await ContactApi.createContactBusinessList2(data) + // 刷新列表 + message.success('关联联系人成功') + handleQuery() +} + +/** 解除联系人与商机的关联 */ +const contactRef = ref() +const deleteContactBusinessList = async () => { + const data = { + businessId: props.bizId, + contactIds: contactRef.value.getSelectionRows().map((row: ContactApi.ContactVO) => row.id) + } as ContactApi.ContactBusiness2ReqVO + if (data.contactIds.length === 0) { + return message.error('未选择联系人') + } + await ContactApi.deleteContactBusinessList2(data) + // 刷新列表 + message.success('取关联系人成功') + handleQuery() +} + /** 监听打开的 bizId + bizType,从而加载最新的列表 */ watch( () => [props.bizId, props.bizType], diff --git a/src/views/crm/contract/index.vue b/src/views/crm/contract/index.vue index 9064e161..ed266057 100644 --- a/src/views/crm/contract/index.vue +++ b/src/views/crm/contract/index.vue @@ -79,7 +79,7 @@ <el-tab-pane label="下属负责的" name="3" /> </el-tabs> <el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true"> - <el-table-column align="center" fixed="left" label="合同编号" prop="no" width="160" /> + <el-table-column align="center" fixed="left" label="合同编号" prop="no" width="180" /> <el-table-column align="center" fixed="left" label="合同名称" prop="name" width="160"> <template #default="scope"> <el-link :underline="false" type="primary" @click="openDetail(scope.row.id)"> diff --git a/src/views/crm/bi/rank/ContactsCountRank.vue b/src/views/crm/statistics/rank/ContactsCountRank.vue similarity index 91% rename from src/views/crm/bi/rank/ContactsCountRank.vue rename to src/views/crm/statistics/rank/ContactsCountRank.vue index 61ef91a6..199d94bd 100644 --- a/src/views/crm/bi/rank/ContactsCountRank.vue +++ b/src/views/crm/statistics/rank/ContactsCountRank.vue @@ -18,7 +18,7 @@ </el-card> </template> <script setup lang="ts"> -import { RankApi, BiRankRespVO } from '@/api/crm/bi/rank' +import { StatisticsRankApi, StatisticsRankRespVO } from '@/api/crm/statistics/rank' import { EChartsOption } from 'echarts' import { clone } from 'lodash-es' @@ -26,7 +26,7 @@ defineOptions({ name: 'ContactsCountRank' }) const props = defineProps<{ queryParams: any }>() // 搜索参数 const loading = ref(false) // 加载中 -const list = ref<BiRankRespVO[]>([]) // 列表的数据 +const list = ref<StatisticsRankRespVO[]>([]) // 列表的数据 /** 柱状图配置:横向 */ const echartsOption = reactive<EChartsOption>({ @@ -80,7 +80,7 @@ const echartsOption = reactive<EChartsOption>({ const loadData = async () => { // 1. 加载排行数据 loading.value = true - const rankingList = await RankApi.getContactsCountRank(props.queryParams) + const rankingList = await StatisticsRankApi.getContactsCountRank(props.queryParams) // 2.1 更新 Echarts 数据 if (echartsOption.dataset && echartsOption.dataset['source']) { echartsOption.dataset['source'] = clone(rankingList).reverse() diff --git a/src/views/crm/bi/rank/ContractCountRank.vue b/src/views/crm/statistics/rank/ContractCountRank.vue similarity index 90% rename from src/views/crm/bi/rank/ContractCountRank.vue rename to src/views/crm/statistics/rank/ContractCountRank.vue index 28332653..fc50a6db 100644 --- a/src/views/crm/bi/rank/ContractCountRank.vue +++ b/src/views/crm/statistics/rank/ContractCountRank.vue @@ -18,7 +18,7 @@ </el-card> </template> <script setup lang="ts"> -import { RankApi, BiRankRespVO } from '@/api/crm/bi/rank' +import { StatisticsRankApi, StatisticsRankRespVO } from '@/api/crm/statistics/rank' import { EChartsOption } from 'echarts' import { clone } from 'lodash-es' @@ -26,7 +26,7 @@ defineOptions({ name: 'ContractCountRank' }) const props = defineProps<{ queryParams: any }>() // 搜索参数 const loading = ref(false) // 加载中 -const list = ref<BiRankRespVO[]>([]) // 列表的数据 +const list = ref<StatisticsRankRespVO[]>([]) // 列表的数据 /** 柱状图配置:横向 */ const echartsOption = reactive<EChartsOption>({ @@ -80,7 +80,7 @@ const echartsOption = reactive<EChartsOption>({ const loadData = async () => { // 1. 加载排行数据 loading.value = true - const rankingList = await RankApi.getContractCountRank(props.queryParams) + const rankingList = await StatisticsRankApi.getContractCountRank(props.queryParams) // 2.1 更新 Echarts 数据 if (echartsOption.dataset && echartsOption.dataset['source']) { echartsOption.dataset['source'] = clone(rankingList).reverse() diff --git a/src/views/crm/bi/rank/ContractPriceRank.vue b/src/views/crm/statistics/rank/ContractPriceRank.vue similarity index 90% rename from src/views/crm/bi/rank/ContractPriceRank.vue rename to src/views/crm/statistics/rank/ContractPriceRank.vue index 067fa36c..79794c4e 100644 --- a/src/views/crm/bi/rank/ContractPriceRank.vue +++ b/src/views/crm/statistics/rank/ContractPriceRank.vue @@ -18,7 +18,7 @@ </el-card> </template> <script setup lang="ts"> -import { RankApi, BiRankRespVO } from '@/api/crm/bi/rank' +import { StatisticsRankApi, StatisticsRankRespVO } from '@/api/crm/statistics/rank' import { EChartsOption } from 'echarts' import { clone } from 'lodash-es' @@ -26,7 +26,7 @@ defineOptions({ name: 'ContractPriceRank' }) const props = defineProps<{ queryParams: any }>() // 搜索参数 const loading = ref(false) // 加载中 -const list = ref<BiRankRespVO[]>([]) // 列表的数据 +const list = ref<StatisticsRankRespVO[]>([]) // 列表的数据 /** 柱状图配置:横向 */ const echartsOption = reactive<EChartsOption>({ @@ -80,7 +80,7 @@ const echartsOption = reactive<EChartsOption>({ const loadData = async () => { // 1. 加载排行数据 loading.value = true - const rankingList = await RankApi.getContractPriceRank(props.queryParams) + const rankingList = await StatisticsRankApi.getContractPriceRank(props.queryParams) // 2.1 更新 Echarts 数据 if (echartsOption.dataset && echartsOption.dataset['source']) { echartsOption.dataset['source'] = clone(rankingList).reverse() diff --git a/src/views/crm/bi/rank/CustomerCountRank.vue b/src/views/crm/statistics/rank/CustomerCountRank.vue similarity index 90% rename from src/views/crm/bi/rank/CustomerCountRank.vue rename to src/views/crm/statistics/rank/CustomerCountRank.vue index aeafd039..b66a6816 100644 --- a/src/views/crm/bi/rank/CustomerCountRank.vue +++ b/src/views/crm/statistics/rank/CustomerCountRank.vue @@ -18,7 +18,7 @@ </el-card> </template> <script setup lang="ts"> -import { RankApi, BiRankRespVO } from '@/api/crm/bi/rank' +import { StatisticsRankApi, StatisticsRankRespVO } from '@/api/crm/statistics/rank' import { EChartsOption } from 'echarts' import { clone } from 'lodash-es' @@ -26,7 +26,7 @@ defineOptions({ name: 'CustomerCountRank' }) const props = defineProps<{ queryParams: any }>() // 搜索参数 const loading = ref(false) // 加载中 -const list = ref<BiRankRespVO[]>([]) // 列表的数据 +const list = ref<StatisticsRankRespVO[]>([]) // 列表的数据 /** 柱状图配置:横向 */ const echartsOption = reactive<EChartsOption>({ @@ -80,7 +80,7 @@ const echartsOption = reactive<EChartsOption>({ const loadData = async () => { // 1. 加载排行数据 loading.value = true - const rankingList = await RankApi.getCustomerCountRank(props.queryParams) + const rankingList = await StatisticsRankApi.getCustomerCountRank(props.queryParams) // 2.1 更新 Echarts 数据 if (echartsOption.dataset && echartsOption.dataset['source']) { echartsOption.dataset['source'] = clone(rankingList).reverse() diff --git a/src/views/crm/bi/rank/FollowCountRank.vue b/src/views/crm/statistics/rank/FollowCountRank.vue similarity index 90% rename from src/views/crm/bi/rank/FollowCountRank.vue rename to src/views/crm/statistics/rank/FollowCountRank.vue index e86cd7fa..43352ab0 100644 --- a/src/views/crm/bi/rank/FollowCountRank.vue +++ b/src/views/crm/statistics/rank/FollowCountRank.vue @@ -18,7 +18,7 @@ </el-card> </template> <script setup lang="ts"> -import { RankApi, BiRankRespVO } from '@/api/crm/bi/rank' +import { StatisticsRankApi, StatisticsRankRespVO } from '@/api/crm/statistics/rank' import { EChartsOption } from 'echarts' import { clone } from 'lodash-es' @@ -26,7 +26,7 @@ defineOptions({ name: 'FollowCountRank' }) const props = defineProps<{ queryParams: any }>() // 搜索参数 const loading = ref(false) // 加载中 -const list = ref<BiRankRespVO[]>([]) // 列表的数据 +const list = ref<StatisticsRankRespVO[]>([]) // 列表的数据 /** 柱状图配置:横向 */ const echartsOption = reactive<EChartsOption>({ @@ -80,7 +80,7 @@ const echartsOption = reactive<EChartsOption>({ const loadData = async () => { // 1. 加载排行数据 loading.value = true - const rankingList = await RankApi.getFollowCountRank(props.queryParams) + const rankingList = await StatisticsRankApi.getFollowCountRank(props.queryParams) // 2.1 更新 Echarts 数据 if (echartsOption.dataset && echartsOption.dataset['source']) { echartsOption.dataset['source'] = clone(rankingList).reverse() diff --git a/src/views/crm/bi/rank/FollowCustomerCountRank.vue b/src/views/crm/statistics/rank/FollowCustomerCountRank.vue similarity index 90% rename from src/views/crm/bi/rank/FollowCustomerCountRank.vue rename to src/views/crm/statistics/rank/FollowCustomerCountRank.vue index 81d3b99d..92a22058 100644 --- a/src/views/crm/bi/rank/FollowCustomerCountRank.vue +++ b/src/views/crm/statistics/rank/FollowCustomerCountRank.vue @@ -18,7 +18,7 @@ </el-card> </template> <script setup lang="ts"> -import { RankApi, BiRankRespVO } from '@/api/crm/bi/rank' +import { StatisticsRankApi, StatisticsRankRespVO } from '@/api/crm/statistics/rank' import { EChartsOption } from 'echarts' import { clone } from 'lodash-es' @@ -26,7 +26,7 @@ defineOptions({ name: 'FollowCustomerCountRank' }) const props = defineProps<{ queryParams: any }>() // 搜索参数 const loading = ref(false) // 加载中 -const list = ref<BiRankRespVO[]>([]) // 列表的数据 +const list = ref<StatisticsRankRespVO[]>([]) // 列表的数据 /** 柱状图配置:横向 */ const echartsOption = reactive<EChartsOption>({ @@ -80,7 +80,7 @@ const echartsOption = reactive<EChartsOption>({ const loadData = async () => { // 1. 加载排行数据 loading.value = true - const rankingList = await RankApi.getFollowCustomerCountRank(props.queryParams) + const rankingList = await StatisticsRankApi.getFollowCustomerCountRank(props.queryParams) // 2.1 更新 Echarts 数据 if (echartsOption.dataset && echartsOption.dataset['source']) { echartsOption.dataset['source'] = clone(rankingList).reverse() diff --git a/src/views/crm/bi/rank/ProductSalesRank.vue b/src/views/crm/statistics/rank/ProductSalesRank.vue similarity index 90% rename from src/views/crm/bi/rank/ProductSalesRank.vue rename to src/views/crm/statistics/rank/ProductSalesRank.vue index 3401dd91..e2a02b70 100644 --- a/src/views/crm/bi/rank/ProductSalesRank.vue +++ b/src/views/crm/statistics/rank/ProductSalesRank.vue @@ -18,7 +18,7 @@ </el-card> </template> <script setup lang="ts"> -import { RankApi, BiRankRespVO } from '@/api/crm/bi/rank' +import { StatisticsRankApi, StatisticsRankRespVO } from '@/api/crm/statistics/rank' import { EChartsOption } from 'echarts' import { clone } from 'lodash-es' @@ -26,7 +26,7 @@ defineOptions({ name: 'ProductSalesRank' }) const props = defineProps<{ queryParams: any }>() // 搜索参数 const loading = ref(false) // 加载中 -const list = ref<BiRankRespVO[]>([]) // 列表的数据 +const list = ref<StatisticsRankRespVO[]>([]) // 列表的数据 /** 柱状图配置:横向 */ const echartsOption = reactive<EChartsOption>({ @@ -80,7 +80,7 @@ const echartsOption = reactive<EChartsOption>({ const loadData = async () => { // 1. 加载排行数据 loading.value = true - const rankingList = await RankApi.getProductSalesRank(props.queryParams) + const rankingList = await StatisticsRankApi.getProductSalesRank(props.queryParams) // 2.1 更新 Echarts 数据 if (echartsOption.dataset && echartsOption.dataset['source']) { echartsOption.dataset['source'] = clone(rankingList).reverse() diff --git a/src/views/crm/bi/rank/ReceivablePriceRank.vue b/src/views/crm/statistics/rank/ReceivablePriceRank.vue similarity index 90% rename from src/views/crm/bi/rank/ReceivablePriceRank.vue rename to src/views/crm/statistics/rank/ReceivablePriceRank.vue index b073dcda..a2f38422 100644 --- a/src/views/crm/bi/rank/ReceivablePriceRank.vue +++ b/src/views/crm/statistics/rank/ReceivablePriceRank.vue @@ -18,7 +18,7 @@ </el-card> </template> <script setup lang="ts"> -import { RankApi, BiRankRespVO } from '@/api/crm/bi/rank' +import { StatisticsRankApi, StatisticsRankRespVO } from '@/api/crm/statistics/rank' import { EChartsOption } from 'echarts' import { clone } from 'lodash-es' @@ -26,7 +26,7 @@ defineOptions({ name: 'ReceivablePriceRank' }) const props = defineProps<{ queryParams: any }>() // 搜索参数 const loading = ref(false) // 加载中 -const list = ref<BiRankRespVO[]>([]) // 列表的数据 +const list = ref<StatisticsRankRespVO[]>([]) // 列表的数据 /** 柱状图配置:横向 */ const echartsOption = reactive<EChartsOption>({ @@ -81,7 +81,7 @@ const echartsOption = reactive<EChartsOption>({ const loadData = async () => { // 1. 加载排行数据 loading.value = true - const rankingList = await RankApi.getReceivablePriceRank(props.queryParams) + const rankingList = await StatisticsRankApi.getReceivablePriceRank(props.queryParams) // 2.1 更新 Echarts 数据 if (echartsOption.dataset && echartsOption.dataset['source']) { echartsOption.dataset['source'] = clone(rankingList).reverse() diff --git a/src/views/crm/bi/rank/index.vue b/src/views/crm/statistics/rank/index.vue similarity index 99% rename from src/views/crm/bi/rank/index.vue rename to src/views/crm/statistics/rank/index.vue index b82ff9a1..50f2f43f 100644 --- a/src/views/crm/bi/rank/index.vue +++ b/src/views/crm/statistics/rank/index.vue @@ -90,7 +90,7 @@ import * as DeptApi from '@/api/system/dept' import { beginOfDay, defaultShortcuts, endOfDay, formatDate } from '@/utils/formatTime' import { useUserStore } from '@/store/modules/user' -defineOptions({ name: 'CrmBiRank' }) +defineOptions({ name: 'CrmStatisticsRank' }) const queryParams = reactive({ deptId: useUserStore().getUser.deptId,