ContactList.vue 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. <template>
  2. <!-- 操作栏 -->
  3. <el-row justify="end">
  4. <el-button @click="openForm">
  5. <Icon class="mr-5px" icon="system-uicons:contacts" />
  6. 创建联系人
  7. </el-button>
  8. <el-button
  9. v-if="queryParams.businessId"
  10. v-hasPermi="['crm:contact:create-business']"
  11. @click="openBusinessModal"
  12. >
  13. <Icon class="mr-5px" icon="ep:circle-plus" />
  14. 关联
  15. </el-button>
  16. <el-button
  17. v-if="queryParams.businessId"
  18. v-hasPermi="['crm:contact:delete-business']"
  19. @click="deleteContactBusinessList"
  20. >
  21. <Icon class="mr-5px" icon="ep:remove" />
  22. 解除关联
  23. </el-button>
  24. </el-row>
  25. <!-- 列表 -->
  26. <ContentWrap class="mt-10px">
  27. <el-table
  28. ref="contactRef"
  29. v-loading="loading"
  30. :data="list"
  31. :show-overflow-tooltip="true"
  32. :stripe="true"
  33. >
  34. <el-table-column v-if="queryParams.businessId" type="selection" width="55" />
  35. <el-table-column align="center" fixed="left" label="姓名" prop="name">
  36. <template #default="scope">
  37. <el-link :underline="false" type="primary" @click="openDetail(scope.row.id)">
  38. {{ scope.row.name }}
  39. </el-link>
  40. </template>
  41. </el-table-column>
  42. <el-table-column align="center" label="手机号" prop="mobile" />
  43. <el-table-column align="center" label="职位" prop="post" />
  44. <el-table-column align="center" label="直属上级" prop="parentName" />
  45. <el-table-column align="center" label="是否关键决策人" min-width="100" prop="master">
  46. <template #default="scope">
  47. <dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.master" />
  48. </template>
  49. </el-table-column>
  50. </el-table>
  51. <!-- 分页 -->
  52. <Pagination
  53. v-model:limit="queryParams.pageSize"
  54. v-model:page="queryParams.pageNo"
  55. :total="total"
  56. @pagination="getList"
  57. />
  58. </ContentWrap>
  59. <!-- 表单弹窗:添加 -->
  60. <ContactForm ref="formRef" @success="getList" />
  61. <!-- 关联商机选择弹框 -->
  62. <ContactListModal
  63. v-if="customerId"
  64. ref="contactModalRef"
  65. :customer-id="customerId"
  66. @success="createContactBusinessList"
  67. />
  68. </template>
  69. <script lang="ts" setup>
  70. import * as ContactApi from '@/api/crm/contact'
  71. import ContactForm from './../ContactForm.vue'
  72. import { DICT_TYPE } from '@/utils/dict'
  73. import { BizTypeEnum } from '@/api/crm/permission'
  74. import ContactListModal from './ContactListModal.vue'
  75. defineOptions({ name: 'CrmContactList' })
  76. const props = defineProps<{
  77. bizType: number // 业务类型
  78. bizId: number // 业务编号
  79. customerId?: number // 特殊:客户编号;在【商机】详情中,可以传递客户编号,默认新建的联系人关联到该客户
  80. businessId?: 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. businessId: undefined as unknown // 允许 undefined + number
  90. })
  91. const message = useMessage()
  92. /** 查询列表 */
  93. const getList = async () => {
  94. loading.value = true
  95. try {
  96. // 置空参数
  97. queryParams.customerId = 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 ContactApi.getContactPageByCustomer(queryParams)
  104. break
  105. case BizTypeEnum.CRM_BUSINESS:
  106. queryParams.businessId = props.bizId
  107. data = await ContactApi.getContactPageByBusiness(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', undefined, props.customerId, props.businessId)
  127. }
  128. /** 打开联系人详情 */
  129. const { push } = useRouter()
  130. const openDetail = (id: number) => {
  131. push({ name: 'CrmContactDetail', params: { id } })
  132. }
  133. /** 打开联系人与商机的关联弹窗 */
  134. const contactModalRef = ref()
  135. const openBusinessModal = () => {
  136. contactModalRef.value.open()
  137. }
  138. const createContactBusinessList = async (contactIds: number[]) => {
  139. const data = {
  140. businessId: props.bizId,
  141. contactIds: contactIds
  142. } as ContactApi.ContactBusiness2ReqVO
  143. contactRef.value.getSelectionRows().forEach((row: ContactApi.ContactVO) => {
  144. data.contactIds.push(row.id)
  145. })
  146. await ContactApi.createContactBusinessList2(data)
  147. // 刷新列表
  148. message.success('关联联系人成功')
  149. handleQuery()
  150. }
  151. /** 解除联系人与商机的关联 */
  152. const contactRef = ref()
  153. const deleteContactBusinessList = async () => {
  154. const data = {
  155. businessId: props.bizId,
  156. contactIds: contactRef.value.getSelectionRows().map((row: ContactApi.ContactVO) => row.id)
  157. } as ContactApi.ContactBusiness2ReqVO
  158. if (data.contactIds.length === 0) {
  159. return message.error('未选择联系人')
  160. }
  161. await ContactApi.deleteContactBusinessList2(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>