Prechádzať zdrojové kódy

新增获客链接管理功能

cgp 1 mesiac pred
rodič
commit
03ccb4951d

+ 126 - 0
src/api/qw/acquisitionAssistant.js

@@ -0,0 +1,126 @@
+import request from '@/utils/request'
+
+// 查询获客链接列表
+export function listAssistant(query) {
+  return request({
+    url: '/qw/acquisitionAssistant/list',
+    method: 'get',
+    params: query
+  })
+}
+
+/**
+ * 获取企微用户列表(POST请求)
+ * @param {Object} params 查询参数
+ * @param {string} params.qwUserName 搜索关键词
+ * @param {number} params.pageNum 页码
+ * @param {number} params.pageSize 每页条数
+ * @param {string} params.corpId 企业ID
+ */
+export function getQwUserList(params) {
+  return request({
+    url: '/qw/acquisitionAssistant/qwUserList',
+    method: 'post',
+    data: params
+  })
+}
+
+/**
+ * 获取企微用户主体列表
+ * @param {Object} data 查询参数
+ * @param {number} data.status 状态
+ */
+export function qwUserCompanyList(data) {
+  return request({
+    url: '/qw/acquisitionAssistant/qwUserCompanyList',
+    method: 'post',
+    data: data
+  })
+}
+
+/**
+ * 批量获取企微用户详情
+ * @param {Array} qwUserIds 企微用户ID列表
+ */
+export function getQwUserListByIds(qwUserIds) {
+  return request({
+    url: '/qw/acquisitionAssistant/qwUserListByIds',
+    method: 'post',
+    data: qwUserIds
+  })
+}
+
+// 从企微同步获客链接列表(全量)- 需要corpId
+export function syncList(corpId) {
+  return request({
+    url: '/qw/acquisitionAssistant/syncList',
+    method: 'post',
+    params: { corpId }
+  })
+}
+
+// 分页获取企微列表(直接调用企微接口)- 需要corpId
+export function getQwList(limit, cursor, corpId) {
+  return request({
+    url: '/qw/acquisitionAssistant/qwList',
+    method: 'get',
+    params: {
+      limit: limit,
+      cursor: cursor,
+      corpId: corpId
+    }
+  })
+}
+
+// 根据linkId直接获取详情
+export function getDetailByLinkId(linkId) {
+  return request({
+    url: `/qw/acquisitionAssistant/getDetailByLinkId/${linkId}`,
+    method: 'get'
+  })
+}
+
+// 新增获客链接
+export function addAssistant(data) {
+  return request({
+    url: '/qw/acquisitionAssistant/add',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改获客链接
+export function updateAssistant(data) {
+  return request({
+    url: '/qw/acquisitionAssistant/edit',
+    method: 'post',
+    data: data
+  })
+}
+
+// 删除获客链接
+export function deleteAssistant(id) {
+  return request({
+    url: `/qw/acquisitionAssistant/delete/${id}`,
+    method: 'get'
+  })
+}
+
+// 批量删除获客链接
+export function batchDeleteAssistant(ids) {
+  return request({
+    url: '/qw/acquisitionAssistant/batchDelete',
+    method: 'delete',
+    data: ids
+  })
+}
+
+// 导出获客链接
+export function exportAssistant(query) {
+  return request({
+    url: '/qw/acquisitionAssistant/export',
+    method: 'get',
+    params: query,
+    responseType: 'blob'
+  })
+}

+ 1000 - 0
src/views/qw/acquisitionAssistant/index.vue

@@ -0,0 +1,1000 @@
+<template>
+  <div class="app-container">
+    <!-- 搜索栏 - 主体选择放在最前面 -->
+    <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="100px">
+      <!-- 主体选择 - 全局筛选条件 -->
+      <el-form-item label="选择主体" prop="corpId" required>
+        <el-select
+          v-model="queryParams.corpId"
+          placeholder="请选择主体"
+          clearable
+          size="small"
+          style="width: 200px"
+          @change="handleCorpChange"
+        >
+          <el-option
+            v-for="item in corpOptions"
+            :key="item.corpId"
+            :label="item.corpName"
+            :value="item.corpId"
+          />
+        </el-select>
+      </el-form-item>
+
+      <el-form-item label="链接名称" prop="linkName">
+        <el-input
+          v-model="queryParams.linkName"
+          placeholder="请输入链接名称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="链接ID" prop="linkId">
+        <el-input
+          v-model="queryParams.linkId"
+          placeholder="请输入链接ID"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="状态" prop="status">
+        <el-select v-model="queryParams.status" placeholder="请选择状态" clearable size="small">
+          <el-option label="正常" :value="1" />
+          <el-option label="已失效" :value="2" />
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <!-- 操作按钮 -->
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+        >新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          icon="el-icon-edit"
+          size="mini"
+          :disabled="single"
+          @click="handleUpdate"
+        >修改</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+        >删除</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          icon="el-icon-refresh"
+          size="mini"
+          @click="handleSync"
+        >同步企微</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="info"
+          icon="el-icon-view"
+          size="mini"
+          @click="handleViewQwList"
+        >查看企微原始数据</el-button>
+      </el-col>
+    </el-row>
+
+    <!-- 数据表格 -->
+    <el-table
+      v-loading="loading"
+      :data="assistantList"
+      @selection-change="handleSelectionChange"
+    >
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="ID" prop="id" width="80" align="center" />
+      <el-table-column label="主体" width="150" align="center">
+        <template slot-scope="scope">
+          {{ getCorpName(scope.row.corpId) }}
+        </template>
+      </el-table-column>
+      <el-table-column label="链接ID" prop="linkId" width="200" :show-overflow-tooltip="true" />
+      <el-table-column label="链接名称" prop="linkName" width="150" :show-overflow-tooltip="true" />
+      <el-table-column label="链接URL" prop="url" width="200" :show-overflow-tooltip="true" />
+      <el-table-column label="使用范围" prop="rangeDesc" width="200" :show-overflow-tooltip="true" />
+      <el-table-column label="状态" width="80" align="center">
+        <template slot-scope="scope">
+          <el-tag :type="scope.row.status === 1 ? 'success' : 'danger'">
+            {{ scope.row.status === 1 ? '正常' : '已失效' }}
+          </el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="企微创建时间" width="160" align="center">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.qwCreateTime) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="最后同步时间" width="160" align="center">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.syncTime) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" width="220" fixed="right">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-view"
+            @click="handleDetail(scope.row)"
+          >详情</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+          >修改</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+          >删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <!-- 分页 -->
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 新增/修改对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="700px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="140px">
+        <el-form-item label="链接名称" prop="linkName">
+          <el-input v-model="form.linkName" placeholder="请输入链接名称" maxlength="50" />
+        </el-form-item>
+
+        <el-form-item label="是否无需验证" prop="skipVerify">
+          <el-radio-group v-model="form.skipVerify">
+            <el-radio :label="0">需要验证</el-radio>
+            <el-radio :label="1">无需验证</el-radio>
+          </el-radio-group>
+        </el-form-item>
+
+        <el-form-item label="是否标记来源" prop="markSource">
+          <el-radio-group v-model="form.markSource">
+            <el-radio :label="0">不标记</el-radio>
+            <el-radio :label="1">标记</el-radio>
+          </el-radio-group>
+        </el-form-item>
+
+        <el-form-item label="优先分配类型" prop="priorityType">
+          <el-radio-group v-model="form.priorityType">
+            <el-radio :label="0">不启用</el-radio>
+            <el-radio :label="1">全企业范围内优先分配给有好友关系的</el-radio>
+            <el-radio :label="2">指定范围内优先分配有好友关系的</el-radio>
+          </el-radio-group>
+        </el-form-item>
+
+        <!-- 关联成员选择器(企微用户) -->
+        <el-form-item label="关联成员" prop="userListParam">
+          <el-select
+            v-model="form.userListParam"
+            multiple
+            filterable
+            remote
+            reserve-keyword
+            :remote-method="searchQwUsers"
+            :loading="userLoading"
+            :multiple-limit="500"
+            :disabled="!queryParams.corpId"
+            :placeholder="getUserSelectPlaceholder"
+            style="width: 100%"
+            @visible-change="handleSelectVisible"
+            @focus="loadUsersByCorp"
+          >
+            <el-option
+              v-for="item in qwUserOptions"
+              :key="`${item.qwUserId}_${item.corpId}`"
+              :label="`${item.qwUserName} (${item.qwUserId})`"
+              :value="item.qwUserId"
+            >
+              <span style="float: left">{{ item.qwUserName }}</span>
+              <span style="float: right; color: #8492a6; font-size: 13px">{{ item.qwUserId }}</span>
+              <div style="clear: both;"></div>
+              <div style="font-size: 12px; color: #999;" v-if="item.department">
+                部门ID:{{ item.department }}
+              </div>
+            </el-option>
+
+            <!-- 加载更多 -->
+            <div style="text-align: center; padding: 10px;" v-if="hasMoreUsers">
+              <el-button type="text" @click="loadMoreUsers" :loading="loadingMore">加载更多</el-button>
+            </div>
+
+            <!-- 空状态 -->
+            <div slot="empty" style="text-align: center; padding: 20px;">
+              <span v-if="!queryParams.corpId">请先在搜索栏选择主体</span>
+              <span v-else-if="searchKeyword">未找到相关成员</span>
+              <span v-else>暂无成员数据</span>
+            </div>
+          </el-select>
+
+          <!-- 显示当前选择的主体信息 -->
+          <div v-if="queryParams.corpId" class="el-form-item__tips" style="color: #67C23A; font-size: 12px; margin-top: 5px;">
+            当前主体:{{ getCorpName(queryParams.corpId) }}
+          </div>
+
+          <!-- 已选数量提示 -->
+          <div v-if="form.userListParam && form.userListParam.length" class="el-form-item__tips" style="color: #909399; font-size: 12px; margin-top: 5px;">
+            已选择 {{ form.userListParam.length }} 名成员(最多可选500人)
+            <el-button type="text" @click="clearSelectedUsers" size="mini">清空</el-button>
+          </div>
+        </el-form-item>
+
+        <el-form-item label="备注" prop="remark">
+          <el-input v-model="form.remark" type="textarea" placeholder="请输入备注" maxlength="200" />
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+
+    <!-- 详情对话框 -->
+    <el-dialog title="获客链接详情" :visible.sync="detailOpen" width="700px" append-to-body>
+      <el-form ref="detailForm" :model="detailData" label-width="140px">
+        <el-form-item label="链接ID">{{ detailData.linkId }}</el-form-item>
+        <el-form-item label="链接名称">{{ detailData.linkName }}</el-form-item>
+        <el-form-item label="链接URL">
+          <el-link :href="detailData.url" target="_blank" type="primary">{{ detailData.url }}</el-link>
+        </el-form-item>
+        <el-form-item label="链接Scheme">{{ detailData.scheme }}</el-form-item>
+        <el-form-item label="是否无需验证">
+          <el-tag :type="detailData.skipVerify === 1 ? 'success' : 'info'">
+            {{ detailData.skipVerify === 1 ? '无需验证' : '需要验证' }}
+          </el-tag>
+        </el-form-item>
+        <el-form-item label="是否标记来源">
+          <el-tag :type="detailData.markSource === 1 ? 'success' : 'info'">
+            {{ detailData.markSource === 1 ? '标记' : '不标记' }}
+          </el-tag>
+        </el-form-item>
+        <el-form-item label="优先分配类型">
+          <span v-if="detailData.priorityType === 0">不启用</span>
+          <span v-else-if="detailData.priorityType === 1">全企业范围内优先分配给有好友关系的</span>
+          <span v-else-if="detailData.priorityType === 2">指定范围内优先分配有好友关系的</span>
+        </el-form-item>
+        <el-form-item label="关联成员">
+          <span v-if="detailData.userListParam && detailData.userListParam.length">
+            {{ formatSelectedUsers(detailData.userListParam) }}
+          </span>
+          <span v-else>-</span>
+        </el-form-item>
+        <el-form-item label="优先分配成员" v-if="detailData.priorityType === 2">
+          {{ detailData.priorityUserListParam ? detailData.priorityUserListParam.join(', ') : '-' }}
+        </el-form-item>
+        <el-form-item label="使用范围描述">{{ detailData.rangeDesc || '-' }}</el-form-item>
+        <el-form-item label="状态">
+          <el-tag :type="detailData.status === 1 ? 'success' : 'danger'">
+            {{ detailData.status === 1 ? '正常' : '已失效' }}
+          </el-tag>
+        </el-form-item>
+        <el-form-item label="企微创建时间">{{ parseTime(detailData.qwCreateTime) }}</el-form-item>
+        <el-form-item label="最后同步时间">{{ parseTime(detailData.syncTime) }}</el-form-item>
+        <el-form-item label="备注">{{ detailData.remark || '-' }}</el-form-item>
+      </el-form>
+    </el-dialog>
+
+    <!-- 企微原始数据对话框 -->
+    <el-dialog
+      title="企微获客链接原始数据"
+      :visible.sync="qwListOpen"
+      width="900px"
+      append-to-body
+      @close="handleQwListClose"
+    >
+      <div class="mb8">
+        <el-button
+          type="primary"
+          icon="el-icon-plus"
+          size="mini"
+          :disabled="!selectedQwLinks || selectedQwLinks.length === 0"
+          @click="handleImportQw"
+        >导入选中到本地</el-button>
+      </div>
+      <el-table
+        :data="qwDataList"
+        v-loading="qwLoading"
+        height="400"
+        @selection-change="handleQwSelectionChange"
+      >
+        <el-table-column type="selection" width="55" align="center" />
+        <el-table-column label="链接ID" prop="link_id" width="200" :show-overflow-tooltip="true" />
+        <el-table-column label="链接名称" prop="link_name" width="150" :show-overflow-tooltip="true" />
+        <el-table-column label="链接URL" prop="url" width="200" :show-overflow-tooltip="true" />
+        <el-table-column label="创建时间" prop="create_time" width="160" align="center" />
+        <el-table-column label="操作" width="150" align="center" fixed="right">
+          <template slot-scope="scope">
+            <el-button size="mini" type="text" @click="handleViewDetail(scope.row.link_id)">查看详情</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="pagination-container" style="margin-top: 15px; text-align: right;">
+        <el-pagination
+          background
+          @current-change="handleQwPageChange"
+          :current-page="qwPage"
+          :page-size="qwLimit"
+          layout="prev, pager, next"
+          :total="qwTotal"
+        />
+      </div>
+    </el-dialog>
+
+    <!-- 企微详情对话框 -->
+    <el-dialog
+      title="企微获客链接详情"
+      :visible.sync="qwDetailOpen"
+      width="700px"
+      append-to-body
+    >
+      <el-form :model="qwDetailData" label-width="120px">
+        <el-form-item label="链接ID">{{ qwDetailData.link_id }}</el-form-item>
+        <el-form-item label="链接名称">{{ qwDetailData.link_name }}</el-form-item>
+        <el-form-item label="链接URL">
+          <el-link :href="qwDetailData.url" target="_blank" type="primary">{{ qwDetailData.url }}</el-link>
+        </el-form-item>
+        <el-form-item label="创建时间">{{ qwDetailData.create_time }}</el-form-item>
+        <el-form-item label="使用范围">{{ qwDetailData.range_desc || '-' }}</el-form-item>
+        <el-form-item label="配置信息">
+          <pre>{{ JSON.stringify(qwDetailData.config, null, 2) }}</pre>
+        </el-form-item>
+      </el-form>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  listAssistant,
+  syncList,
+  getQwList,
+  getDetailByLinkId,
+  addAssistant,
+  updateAssistant,
+  deleteAssistant,
+  getQwUserList,
+  getQwUserListByIds,
+  qwUserCompanyList
+} from '@/api/qw/acquisitionAssistant'
+
+export default {
+  name: 'AcquisitionAssistant',
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      qwLoading: false,
+      userLoading: false,
+      loadingMore: false,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 总条数
+      total: 0,
+      // 表格数据
+      assistantList: [],
+      // 企微列表数据
+      qwDataList: [],
+      qwTotal: 0,
+      qwPage: 1,
+      qwLimit: 100,
+      qwCursor: '',
+      selectedQwLinks: [],
+      // 详情数据
+      detailData: {},
+      qwDetailData: {},
+      // 弹出层标题
+      title: '',
+      // 是否显示弹出层
+      open: false,
+      detailOpen: false,
+      qwListOpen: false,
+      qwDetailOpen: false,
+      // 查询参数 - corpId作为全局筛选条件
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        linkName: '',
+        linkId: '',
+        status: '',
+        corpId: '' // 全局主体ID,所有需要corpId的接口都会用到
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        linkName: [
+          { required: true, message: '链接名称不能为空', trigger: 'blur' }
+        ]
+      },
+      // 企业主体相关
+      corpOptions: [],
+      corpMap: new Map(),
+      // 企微用户相关
+      qwUserOptions: [],
+      searchKeyword: '',
+      userPage: 1,
+      userPageSize: 20,
+      userTotal: 0,
+      hasMoreUsers: true,
+      initialLoaded: false
+    }
+  },
+  computed: {
+    getUserSelectPlaceholder() {
+      if (!this.queryParams.corpId) {
+        return '请先在搜索栏选择主体'
+      }
+      return '请输入成员姓名进行搜索,或直接下拉选择'
+    }
+  },
+  created() {
+    this.getCorpList().then(() => {
+      // 默认选中第一个主体
+      if (this.corpOptions && this.corpOptions.length > 0) {
+        this.queryParams.corpId = this.corpOptions[0].corpId
+        console.log('默认选中主体:', this.queryParams.corpId)
+        this.getList() // 获取列表数据
+      } else {
+        this.msgWarning('请先配置企业主体')
+      }
+    })
+  },
+  methods: {
+    /** 检查是否已选择主体 */
+    checkCorpId() {
+      if (!this.queryParams.corpId) {
+        this.msgError('请先在搜索栏选择主体')
+        return false
+      }
+      return true
+    },
+
+    /** 查询列表 */
+    getList() {
+      if (!this.checkCorpId()) {
+        this.loading = false
+        return
+      }
+
+      this.loading = true
+      const params = { ...this.queryParams }
+      listAssistant(params).then(response => {
+        this.assistantList = response.rows
+        this.total = response.total
+        this.loading = false
+      }).catch(() => {
+        this.loading = false
+      })
+    },
+
+    /** 获取企业主体列表 */
+    getCorpList() {
+      return qwUserCompanyList({ status: 1 }).then(response => {
+        this.corpOptions = response.data || []
+        // 创建Map方便根据corpId获取corpName
+        this.corpMap.clear()
+        this.corpOptions.forEach(item => {
+          this.corpMap.set(item.corpId, item.corpName)
+        })
+        console.log('获取到的主体列表:', this.corpOptions)
+      })
+    },
+
+    /** 根据corpId获取企业名称 */
+    getCorpName(corpId) {
+      return this.corpMap.get(corpId) || corpId
+    },
+
+    /** 切换主体时的处理 */
+    handleCorpChange(corpId) {
+      console.log('切换主体:', corpId)
+
+      // 重置用户相关数据
+      this.qwUserOptions = []
+      this.initialLoaded = false
+      this.userPage = 1
+      this.hasMoreUsers = true
+      this.searchKeyword = ''
+
+      // 如果有关联成员选择框打开,清空已选成员
+      if (this.form.userListParam) {
+        this.form.userListParam = []
+      }
+
+      if (corpId) {
+        // 重新查询列表
+        this.queryParams.pageNum = 1
+        this.getList()
+        // 预加载用户数据
+        this.loadUsersByCorp()
+      } else {
+        // 如果没有选择主体,清空列表
+        this.assistantList = []
+        this.total = 0
+      }
+    },
+
+    /** 根据当前选择的主体加载用户 */
+    loadUsersByCorp() {
+      if (!this.checkCorpId()) return
+
+      const corpId = this.queryParams.corpId
+      console.log('loadUsersByCorp: 开始加载主体用户', corpId)
+
+      // 重置分页和数据
+      this.userPage = 1
+      this.qwUserOptions = []
+      this.initialLoaded = false
+      this.searchKeyword = ''
+
+      // 调用搜索方法,传入空字符串加载所有用户
+      this.searchQwUsers('')
+    },
+
+    /** 搜索企微用户 - POST请求 */
+    searchQwUsers(query) {
+      if (!this.checkCorpId()) {
+        this.userLoading = false
+        return
+      }
+
+      if (query !== undefined) {
+        this.searchKeyword = query
+        this.userPage = 1
+      }
+
+      if (!this.searchKeyword && this.initialLoaded) {
+        return
+      }
+
+      this.userLoading = true
+
+      const params = {
+        qwUserName: this.searchKeyword || '',
+        pageNum: this.userPage,
+        pageSize: this.userPageSize,
+        corpId: this.queryParams.corpId
+      }
+
+      console.log('搜索用户参数:', params)
+
+      getQwUserList(params).then(response => {
+        console.log('API返回原始数据:', response)
+
+        let newUsers = []
+        if (response.data && Array.isArray(response.data)) {
+          newUsers = response.data
+        } else if (response.rows && Array.isArray(response.rows)) {
+          newUsers = response.rows
+        } else if (Array.isArray(response)) {
+          newUsers = response
+        }
+
+        if (this.userPage === 1) {
+          this.qwUserOptions = newUsers
+        } else {
+          const existingKeys = new Set(
+            this.qwUserOptions.map(u => `${u.qwUserId}_${u.corpId}`)
+          )
+          const uniqueNewUsers = newUsers.filter(u =>
+            !existingKeys.has(`${u.qwUserId}_${u.corpId}`)
+          )
+          this.qwUserOptions = [...this.qwUserOptions, ...uniqueNewUsers]
+        }
+
+        if (response.total !== undefined) {
+          this.userTotal = response.total
+        } else if (response.data && response.data.total) {
+          this.userTotal = response.data.total
+        } else {
+          this.userTotal = this.qwUserOptions.length
+        }
+
+        this.hasMoreUsers = this.qwUserOptions.length < this.userTotal
+
+        if (this.userPage === 1) {
+          this.initialLoaded = true
+        }
+
+        console.log('更新后的qwUserOptions长度:', this.qwUserOptions.length)
+
+        this.userLoading = false
+        this.loadingMore = false
+      }).catch(error => {
+        console.error('搜索用户失败:', error)
+        this.userLoading = false
+        this.loadingMore = false
+      })
+    },
+
+    /** 加载初始用户列表 */
+    loadInitialUsers() {
+      if (!this.initialLoaded && this.qwUserOptions.length === 0) {
+        this.searchQwUsers('')
+      }
+    },
+
+    /** 处理选择器显隐变化 */
+    handleSelectVisible(visible) {
+      if (visible && this.queryParams.corpId) {
+        if (!this.initialLoaded || this.qwUserOptions.length === 0) {
+          this.loadUsersByCorp()
+        }
+      }
+    },
+
+    /** 加载更多用户 */
+    loadMoreUsers() {
+      if (this.loadingMore || !this.hasMoreUsers) return
+
+      this.loadingMore = true
+      this.userPage++
+      this.searchQwUsers(this.searchKeyword)
+    },
+
+    /** 清空已选用户 */
+    clearSelectedUsers() {
+      this.form.userListParam = []
+    },
+
+    /** 加载已选中用户的详细信息 */
+    loadSelectedUsers(userIds) {
+      if (!userIds || userIds.length === 0) return
+
+      getQwUserListByIds(userIds).then(response => {
+        const selectedUsers = response.data || []
+
+        selectedUsers.forEach(user => {
+          const exists = this.qwUserOptions.some(opt =>
+            opt.qwUserId === user.qwUserId && opt.corpId === user.corpId
+          )
+          if (!exists) {
+            this.qwUserOptions.push(user)
+          }
+        })
+      })
+    },
+
+    /** 格式化已选中的用户显示 */
+    formatSelectedUsers(userIds) {
+      if (!userIds || !userIds.length) return '-'
+
+      const selectedNames = []
+      userIds.forEach(id => {
+        const users = this.qwUserOptions.filter(opt => opt.qwUserId === id)
+        if (users.length > 0) {
+          users.forEach(u => {
+            const deptInfo = u.department ? `(部门:${u.department})` : ''
+            const corpInfo = this.getCorpName(u.corpId)
+            selectedNames.push(`${u.qwUserName}${deptInfo} - ${corpInfo}`)
+          })
+        } else {
+          selectedNames.push(id)
+        }
+      })
+      return selectedNames.join(', ')
+    },
+
+    /** 搜索按钮操作 */
+    handleQuery() {
+      if (!this.checkCorpId()) return
+      this.queryParams.pageNum = 1
+      this.getList()
+    },
+
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm('queryForm')
+      // 重置时保留主体选择
+      const currentCorpId = this.queryParams.corpId
+      this.queryParams = {
+        pageNum: 1,
+        pageSize: 10,
+        linkName: '',
+        linkId: '',
+        status: '',
+        corpId: currentCorpId
+      }
+      this.handleQuery()
+    },
+
+    /** 多选框选中数据 */
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length !== 1
+      this.multiple = !selection.length
+    },
+
+    /** 新增按钮操作 */
+    handleAdd() {
+      if (!this.checkCorpId()) return
+
+      this.reset()
+      this.open = true
+      this.title = '添加获客链接'
+
+      // 预加载用户数据
+      this.loadUsersByCorp()
+    },
+
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      if (!this.checkCorpId()) return
+
+      this.reset()
+
+      // 先查询详情
+      getDetailByLinkId(row.linkId).then(response => {
+        this.form = response.data
+        // 解析JSON字段
+        if (this.form.userList) {
+          this.form.userListParam = JSON.parse(this.form.userList)
+        }
+        if (this.form.priorityUserList) {
+          this.form.priorityUserListParam = JSON.parse(this.form.priorityUserList)
+        }
+
+        // 加载该主体的用户
+        this.loadUsersByCorp()
+
+        // 如果有已选用户,加载他们的详细信息
+        if (this.form.userListParam && this.form.userListParam.length > 0) {
+          this.loadSelectedUsers(this.form.userListParam)
+        }
+
+        this.open = true
+        this.title = '修改获客链接'
+      })
+    },
+
+    /** 详情按钮操作 */
+    handleDetail(row) {
+      getDetailByLinkId(row.linkId).then(response => {
+        this.detailData = response.data
+        // 解析JSON字段
+        if (this.detailData.userList) {
+          this.detailData.userListParam = JSON.parse(this.detailData.userList)
+        }
+        if (this.detailData.priorityUserList) {
+          this.detailData.priorityUserListParam = JSON.parse(this.detailData.priorityUserList)
+        }
+        this.detailOpen = true
+      })
+    },
+
+    /** 提交按钮 */
+    submitForm() {
+      if (!this.checkCorpId()) return
+
+      this.$refs['form'].validate(valid => {
+        if (valid) {
+          // 验证关联成员是否超过500
+          if (this.form.userListParam && this.form.userListParam.length > 500) {
+            this.msgError('关联成员最多只能选择500人')
+            return
+          }
+
+          // 设置当前选中的主体ID
+          this.form.corpId = this.queryParams.corpId
+
+          if (this.form.id) {
+            updateAssistant(this.form).then(response => {
+              this.msgSuccess('修改成功')
+              this.open = false
+              this.getList()
+            })
+          } else {
+            addAssistant(this.form).then(response => {
+              this.msgSuccess('新增成功')
+              this.open = false
+              this.getList()
+            })
+          }
+        }
+      })
+    },
+
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      if (!this.checkCorpId()) return
+
+      const ids = row.id || this.ids.join(',')
+      this.$confirm('是否确认删除获客链接编号为"' + ids + '"的数据项?', '警告', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        return deleteAssistant(ids)
+      }).then(() => {
+        this.getList()
+        this.msgSuccess('删除成功')
+      })
+    },
+
+    /** 同步企微 - 需要传入当前选中的corpId */
+    handleSync() {
+      if (!this.checkCorpId()) return
+
+      this.$confirm('确认同步企微获客链接列表?此操作将全量更新本地数据', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        return syncList(this.queryParams.corpId)
+      }).then(response => {
+        this.msgSuccess(response.msg || '同步成功')
+        this.getList()
+      }).catch(() => {})
+    },
+
+    /** 查看企微原始数据 - 需要传入当前选中的corpId */
+    handleViewQwList() {
+      if (!this.checkCorpId()) return
+
+      this.qwListOpen = true
+      this.qwPage = 1
+      this.qwCursor = ''
+      this.getQwList()
+    },
+
+    /** 获取企微列表 - 使用当前选中的corpId */
+    getQwList() {
+      if (!this.checkCorpId()) {
+        this.qwLoading = false
+        return
+      }
+
+      this.qwLoading = true
+      getQwList(this.qwLimit, this.qwCursor, this.queryParams.corpId).then(response => {
+        console.log('企微原始数据响应:', response)
+
+        if (response.code === 200) {
+          const data = response.data || {}
+          this.qwDataList = data.link_list || []
+          this.qwTotal = data.total_count || 0
+          this.qwCursor = data.next_cursor || ''
+        } else {
+          this.qwDataList = []
+          this.qwTotal = 0
+          this.msgError(response.msg || '获取数据失败')
+        }
+
+        this.qwLoading = false
+      }).catch(error => {
+        console.error('获取企微原始数据失败:', error)
+        this.qwLoading = false
+        this.msgError('获取企微原始数据失败')
+      })
+    },
+
+    /** 企微分页切换 */
+    handleQwPageChange(page) {
+      this.qwPage = page
+      this.getQwList()
+    },
+
+    /** 企微列表选中 */
+    handleQwSelectionChange(selection) {
+      this.selectedQwLinks = selection
+    },
+
+    /** 导入选中 */
+    handleImportQw() {
+      if (!this.selectedQwLinks || this.selectedQwLinks.length === 0) {
+        this.msgError('请至少选择一条数据')
+        return
+      }
+
+      if (!this.checkCorpId()) return
+
+      // 跳转到新增页面并填充数据
+      const link = this.selectedQwLinks[0]
+      this.qwListOpen = false
+      this.$nextTick(() => {
+        this.handleAdd()
+        this.form.linkId = link.link_id
+        this.form.linkName = link.link_name
+        this.form.url = link.url
+      })
+    },
+
+    /** 查看企微详情 */
+    handleViewDetail(linkId) {
+      this.qwLoading = true
+      getDetailByLinkId(linkId).then(response => {
+        this.qwDetailData = response.data
+        this.qwDetailOpen = true
+        this.qwLoading = false
+      }).catch(() => {
+        this.qwLoading = false
+      })
+    },
+
+    /** 关闭企微列表弹窗 */
+    handleQwListClose() {
+      this.selectedQwLinks = []
+      this.qwCursor = ''
+    },
+
+    /** 取消按钮 */
+    cancel() {
+      this.open = false
+      this.reset()
+    },
+
+    /** 表单重置 */
+    reset() {
+      this.form = {
+        linkName: '',
+        skipVerify: 0,
+        markSource: 0,
+        priorityType: 0,
+        userListParam: [],
+        priorityUserListParam: [],
+        remark: '',
+        corpId: this.queryParams.corpId
+      }
+      this.searchKeyword = ''
+      this.userPage = 1
+      this.hasMoreUsers = true
+      this.resetForm('form')
+    }
+  }
+}
+</script>
+
+<style scoped>
+.mb8 {
+  margin-bottom: 8px;
+}
+
+.el-form-item__tips {
+  font-size: 12px;
+  color: #909399;
+  margin-top: 5px;
+}
+
+/* 优化下拉选项的显示 */
+.el-select-dropdown__item {
+  height: auto;
+  padding: 8px 20px;
+}
+
+.el-select-dropdown__item span {
+  line-height: 1.5;
+}
+</style>