|
|
@@ -0,0 +1,214 @@
|
|
|
+<!-- 学校关系管理 -->
|
|
|
+<!-- art-full-height 自动计算出页面剩余高度 -->
|
|
|
+<!-- art-table-card 一个符合系统样式的 class,同时自动撑满剩余高度 -->
|
|
|
+<!-- 更多 useTable 使用示例请移步至 功能示例 下面的 高级表格示例 -->
|
|
|
+<template>
|
|
|
+ <div class="user-page art-full-height">
|
|
|
+ <!-- 搜索栏 -->
|
|
|
+ <UserSearch
|
|
|
+ v-model="searchForm"
|
|
|
+ @search="handleSearch"
|
|
|
+ @reset="resetSearchParams"
|
|
|
+ :selectList="selectList"
|
|
|
+ ></UserSearch>
|
|
|
+
|
|
|
+ <ElCard class="art-table-card" shadow="never">
|
|
|
+ <!-- 表格头部 -->
|
|
|
+ <ArtTableHeader v-model:columns="columnChecks" @refresh="refreshData">
|
|
|
+ <template #left>
|
|
|
+ <ElButton type="primary" @click="follow()" v-ripple v-auth="120301">新增跟进记录</ElButton>
|
|
|
+ </template>
|
|
|
+ </ArtTableHeader>
|
|
|
+
|
|
|
+ <!-- 表格 -->
|
|
|
+ <ArtTable
|
|
|
+ :loading="loading"
|
|
|
+ :data="data"
|
|
|
+ :columns="columns"
|
|
|
+ :pagination="pagination"
|
|
|
+ @pagination:size-change="handleSizeChange"
|
|
|
+ @pagination:current-change="handleCurrentChange"
|
|
|
+ >
|
|
|
+ </ArtTable>
|
|
|
+
|
|
|
+ <!-- 跟进弹窗 -->
|
|
|
+ <FollowDialog
|
|
|
+ v-model:visible="followDialogVisible"
|
|
|
+ :user-data="currentUserData"
|
|
|
+ :type="'school'"
|
|
|
+ :first_id="0"
|
|
|
+ :second_id="0"
|
|
|
+ :selectList="selectList"
|
|
|
+ @submit="handleDialogSubmit"
|
|
|
+ />
|
|
|
+ </ElCard>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup lang="ts">
|
|
|
+ import ArtButtonTable from '@/components/core/forms/art-button-table/index.vue'
|
|
|
+ import {ElMessageBox, ElMessage, ElTag, ElImage, ElButton} from 'element-plus'
|
|
|
+ import { useTable } from '@/composables/useTable'
|
|
|
+ import UserSearch from './modules/user-search.vue'
|
|
|
+ import { followApi } from '@/api/followApi'
|
|
|
+ import {RoutesAlias} from "@/router/routesAlias";
|
|
|
+ import {router} from "@/router";
|
|
|
+ import {schoolRelationApi} from "@/api/schoolRelationApi";
|
|
|
+
|
|
|
+ defineOptions({ name: 'SchoolFollow' })
|
|
|
+
|
|
|
+ type SchoolContactItem = Api.School.SchoolContactItem
|
|
|
+
|
|
|
+ // 弹窗相关
|
|
|
+ const dialogVisible = ref(false)
|
|
|
+ const followDialogVisible = ref(false)
|
|
|
+ const currentUserData = ref<Partial<SchoolContactItem>>({})
|
|
|
+
|
|
|
+ // 选中行
|
|
|
+ const selectedRows = ref<SchoolContactItem[]>([])
|
|
|
+
|
|
|
+
|
|
|
+ // 搜索表单
|
|
|
+ const searchForm = ref({
|
|
|
+ name: '',
|
|
|
+ phone: '',
|
|
|
+ school_id: parseInt(<string>useRoute().query.school_id) || '',
|
|
|
+ })
|
|
|
+
|
|
|
+ const selectList = ref<Api.Common.SelectRelationInfo[]>([])
|
|
|
+ const getSelectList = async () => {
|
|
|
+ const data = await schoolRelationApi.selectList()
|
|
|
+ selectList.value = data
|
|
|
+ }
|
|
|
+ getSelectList()
|
|
|
+
|
|
|
+ const {
|
|
|
+ columns,
|
|
|
+ columnChecks,
|
|
|
+ data,
|
|
|
+ loading,
|
|
|
+ pagination,
|
|
|
+ getData,
|
|
|
+ searchParams,
|
|
|
+ resetSearchParams,
|
|
|
+ handleSizeChange,
|
|
|
+ handleCurrentChange,
|
|
|
+ refreshData
|
|
|
+ } = useTable<Api.Follow.FollowInfo>({
|
|
|
+ // 核心配置
|
|
|
+ core: {
|
|
|
+ apiFn: followApi.schoolList,
|
|
|
+ apiParams: {
|
|
|
+ current: 1,
|
|
|
+ size: 20,
|
|
|
+ ...searchForm.value
|
|
|
+ },
|
|
|
+ // 排除 apiParams 中的属性
|
|
|
+ excludeParams: ['daterange'],
|
|
|
+ columnsFactory: () => [
|
|
|
+ { prop:'first_name', label:'校园(园区)' },
|
|
|
+ { prop:'second_name', label:'关系人' },
|
|
|
+ { prop:'position', label:'职位' },
|
|
|
+ { prop:'phone', label:'手机号' },
|
|
|
+ { prop:'weixin', label:'微信号' },
|
|
|
+ { prop:'chat_imgs', label:'微信聊天记录', formatter: (row) => {
|
|
|
+ return h(ElImage, {
|
|
|
+ src: row.chat_imgs[0],
|
|
|
+ previewSrcList: row.chat_imgs,
|
|
|
+ showProgress: true,
|
|
|
+ fit: "cover",
|
|
|
+ title: '点击预览全部图片',
|
|
|
+ style: {"max-width": "50px", "max-height": "50px"},
|
|
|
+ // 图片预览是否插入至 body 元素上,用于解决表格内部图片预览样式异常
|
|
|
+ previewTeleported: true
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ { prop:'user_name', label:'跟进人员' },
|
|
|
+ { prop:'create_date', label:'跟进时间' },
|
|
|
+ {
|
|
|
+ prop: 'operation',
|
|
|
+ label: '操作',
|
|
|
+ width: 120,
|
|
|
+ fixed: 'right', // 固定列
|
|
|
+ formatter: (row) =>
|
|
|
+ h('div', [
|
|
|
+ h(ArtButtonTable, {
|
|
|
+ type: 'view',
|
|
|
+ onClick: () => view(row.id)
|
|
|
+ }),
|
|
|
+ ])
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查看
|
|
|
+ */
|
|
|
+ const view = (id: number): void => {
|
|
|
+ router.push({
|
|
|
+ path: RoutesAlias.SchoolFollowInfo,
|
|
|
+ query: {
|
|
|
+ id: id
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 搜索处理
|
|
|
+ * @param params 参数
|
|
|
+ */
|
|
|
+ const handleSearch = (params: Record<string, any>) => {
|
|
|
+ Object.assign(searchParams, { ...params })
|
|
|
+ getData()
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 显示跟进弹窗
|
|
|
+ */
|
|
|
+ const follow = (): void => {
|
|
|
+ nextTick(() => {
|
|
|
+ followDialogVisible.value = true
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理弹窗提交事件
|
|
|
+ */
|
|
|
+ const handleDialogSubmit = async () => {
|
|
|
+ try {
|
|
|
+ dialogVisible.value = false
|
|
|
+ followDialogVisible.value = false
|
|
|
+ currentUserData.value = {}
|
|
|
+ // 延迟更新 不然数据可能没更新
|
|
|
+ setTimeout(() => {
|
|
|
+ refreshData()
|
|
|
+ }, 1000)
|
|
|
+ } catch (error) {
|
|
|
+ console.error('提交失败:', error)
|
|
|
+ }
|
|
|
+ }
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+ .user-page {
|
|
|
+ :deep(.user) {
|
|
|
+ .avatar {
|
|
|
+ width: 40px;
|
|
|
+ height: 40px;
|
|
|
+ margin-left: 0;
|
|
|
+ border-radius: 6px;
|
|
|
+ }
|
|
|
+
|
|
|
+ > div {
|
|
|
+ margin-left: 10px;
|
|
|
+
|
|
|
+ .user-name {
|
|
|
+ font-weight: 500;
|
|
|
+ color: var(--art-text-gray-800);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+</style>
|