BusinessList.vue 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. <template>
  2. <!-- 操作栏 -->
  3. <el-row justify="end">
  4. <el-button @click="openForm">
  5. <Icon class="mr-5px" icon="ep:opportunity" />
  6. 创建商机
  7. </el-button>
  8. <el-button
  9. @click="openBusinessModal"
  10. v-hasPermi="['crm:contact:create-business']"
  11. v-if="queryParams.contactId"
  12. >
  13. <Icon class="mr-5px" icon="ep:circle-plus" />关联
  14. </el-button>
  15. <el-button
  16. @click="deleteContactBusinessList"
  17. v-hasPermi="['crm:contact:delete-business']"
  18. v-if="queryParams.contactId"
  19. >
  20. <Icon class="mr-5px" icon="ep:remove" />解除关联
  21. </el-button>
  22. </el-row>
  23. <!-- 列表 -->
  24. <ContentWrap class="mt-10px">
  25. <el-table
  26. ref="businessRef"
  27. v-loading="loading"
  28. :data="list"
  29. :stripe="true"
  30. :show-overflow-tooltip="true"
  31. >
  32. <el-table-column type="selection" width="55" v-if="queryParams.contactId" />
  33. <el-table-column label="商机名称" fixed="left" align="center" prop="name">
  34. <template #default="scope">
  35. <el-link type="primary" :underline="false" @click="openDetail(scope.row.id)">
  36. {{ scope.row.name }}
  37. </el-link>
  38. </template>
  39. </el-table-column>
  40. <el-table-column
  41. label="商机金额"
  42. align="center"
  43. prop="price"
  44. :formatter="erpPriceTableColumnFormatter"
  45. />
  46. <el-table-column label="客户名称" align="center" prop="customerName" />
  47. <el-table-column label="商机组" align="center" prop="statusTypeName" />
  48. <el-table-column label="商机阶段" align="center" prop="statusName" />
  49. </el-table>
  50. <!-- 分页 -->
  51. <Pagination
  52. :total="total"
  53. v-model:page="queryParams.pageNo"
  54. v-model:limit="queryParams.pageSize"
  55. @pagination="getList"
  56. />
  57. </ContentWrap>
  58. <!-- 表单弹窗:添加 -->
  59. <BusinessForm ref="formRef" @success="getList" />
  60. <!-- 关联商机选择弹框 -->
  61. <BusinessListModal
  62. ref="businessModalRef"
  63. :customer-id="props.customerId"
  64. @success="createContactBusinessList"
  65. />
  66. </template>
  67. <script setup lang="ts">
  68. import * as BusinessApi from '@/api/crm/business'
  69. import * as ContactApi from '@/api/crm/contact'
  70. import BusinessForm from './../BusinessForm.vue'
  71. import { BizTypeEnum } from '@/api/crm/permission'
  72. import BusinessListModal from './BusinessListModal.vue'
  73. import { erpPriceTableColumnFormatter } from '@/utils'
  74. const message = useMessage() // 消息
  75. defineOptions({ name: 'CrmBusinessList' })
  76. const props = defineProps<{
  77. bizType: number // 业务类型
  78. bizId: number // 业务编号
  79. customerId?: number // 关联联系人与商机时,需要传入 customerId 进行筛选
  80. contactId?: number // 特殊:联系人编号;在【联系人】详情中,可以传递联系人编号,默认新建的商机关联到该联系人
  81. }>()
  82. const loading = ref(true) // 列表的加载中
  83. const total = ref(0) // 列表的总页数
  84. const list = ref([]) // 列表的数据
  85. const queryParams = reactive({
  86. pageNo: 1,
  87. pageSize: 10,
  88. customerId: undefined as unknown, // 允许 undefined + number
  89. contactId: undefined as unknown // 允许 undefined + number
  90. })
  91. /** 查询列表 */
  92. const getList = async () => {
  93. loading.value = true
  94. try {
  95. // 置空参数
  96. queryParams.customerId = undefined
  97. queryParams.contactId = undefined
  98. // 执行查询
  99. let data = { list: [], total: 0 }
  100. switch (props.bizType) {
  101. case BizTypeEnum.CRM_CUSTOMER:
  102. queryParams.customerId = props.bizId
  103. data = await BusinessApi.getBusinessPageByCustomer(queryParams)
  104. break
  105. case BizTypeEnum.CRM_CONTACT:
  106. queryParams.contactId = props.bizId
  107. data = await BusinessApi.getBusinessPageByContact(queryParams)
  108. break
  109. default:
  110. return
  111. }
  112. list.value = data.list
  113. total.value = data.total
  114. } finally {
  115. loading.value = false
  116. }
  117. }
  118. /** 搜索按钮操作 */
  119. const handleQuery = () => {
  120. queryParams.pageNo = 1
  121. getList()
  122. }
  123. /** 添加操作 */
  124. const formRef = ref()
  125. const openForm = () => {
  126. formRef.value.open('create', null, props.customerId, props.contactId)
  127. }
  128. /** 打开联系人详情 */
  129. const { push } = useRouter()
  130. const openDetail = (id: number) => {
  131. push({ name: 'CrmBusinessDetail', params: { id } })
  132. }
  133. /** 打开联系人与商机的关联弹窗 */
  134. const businessModalRef = ref()
  135. const openBusinessModal = () => {
  136. businessModalRef.value.open()
  137. }
  138. const createContactBusinessList = async (businessIds: number[]) => {
  139. const data = {
  140. contactId: props.bizId,
  141. businessIds: businessIds
  142. } as ContactApi.ContactBusinessReqVO
  143. businessRef.value.getSelectionRows().forEach((row: BusinessApi.BusinessVO) => {
  144. data.businessIds.push(row.id)
  145. })
  146. await ContactApi.createContactBusinessList(data)
  147. // 刷新列表
  148. message.success('关联商机成功')
  149. handleQuery()
  150. }
  151. /** 解除联系人与商机的关联 */
  152. const businessRef = ref()
  153. const deleteContactBusinessList = async () => {
  154. const data = {
  155. contactId: props.bizId,
  156. businessIds: businessRef.value.getSelectionRows().map((row: BusinessApi.BusinessVO) => row.id)
  157. } as ContactApi.ContactBusinessReqVO
  158. if (data.businessIds.length === 0) {
  159. return message.error('未选择商机')
  160. }
  161. await ContactApi.deleteContactBusinessList(data)
  162. // 刷新列表
  163. message.success('取关商机成功')
  164. handleQuery()
  165. }
  166. /** 监听打开的 bizId + bizType,从而加载最新的列表 */
  167. watch(
  168. () => [props.bizId, props.bizType],
  169. () => {
  170. handleQuery()
  171. },
  172. { immediate: true, deep: true }
  173. )
  174. </script>