|
|
@@ -1,1323 +1,1355 @@
|
|
|
<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"
|
|
|
+ <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-row>
|
|
|
+
|
|
|
+ <!-- 数据表格 -->
|
|
|
+ <el-table
|
|
|
+ v-loading="loading"
|
|
|
+ :data="assistantList"
|
|
|
+ @selection-change="handleSelectionChange"
|
|
|
>
|
|
|
- <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-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="操作" align="center" width="300" 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>
|
|
|
+ <!-- 新增:一键提取链接按钮 -->
|
|
|
+ <el-button
|
|
|
+ size="mini"
|
|
|
+ type="text"
|
|
|
+ icon="el-icon-link"
|
|
|
+ @click="handleCopyLink(scope.row)"
|
|
|
+ >提取链接
|
|
|
+ </el-button>
|
|
|
+ <!-- 新增:生成二维码按钮 -->
|
|
|
+ <el-button
|
|
|
+ size="mini"
|
|
|
+ type="text"
|
|
|
+ icon="el-icon-s-promotion"
|
|
|
+ @click="handleGenerateQRCode(scope.row)"
|
|
|
+ style="color: #67C23A;"
|
|
|
+ >生成二维码
|
|
|
+ </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-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-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="操作" align="center" width="300" 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>
|
|
|
- <!-- 新增:一键提取链接按钮 -->
|
|
|
- <el-button
|
|
|
- size="mini"
|
|
|
- type="text"
|
|
|
- icon="el-icon-link"
|
|
|
- @click="handleCopyLink(scope.row)"
|
|
|
- >提取链接</el-button>
|
|
|
- <!-- 新增:生成二维码按钮 -->
|
|
|
- <el-button
|
|
|
- size="mini"
|
|
|
- type="text"
|
|
|
- icon="el-icon-s-promotion"
|
|
|
- @click="handleGenerateQRCode(scope.row)"
|
|
|
- style="color: #67C23A;"
|
|
|
- >生成二维码</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="true">无需验证</el-radio> <!-- true 表示无需验证 -->
|
|
|
- <el-radio :label="false">需要验证</el-radio> <!-- false 表示需要验证 -->
|
|
|
- </el-radio-group>
|
|
|
- <div class="el-form-item__tips" style="color: #909399; font-size: 12px; margin-top: 5px;">
|
|
|
- 选择"无需验证"时,客户添加好友无需员工确认
|
|
|
- </div>
|
|
|
- </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="selectedUserIds">
|
|
|
- <el-select
|
|
|
- v-model="form.selectedUserIds"
|
|
|
- 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"
|
|
|
- @change="handleUserSelectionChange"
|
|
|
- >
|
|
|
- <el-option
|
|
|
- v-for="item in qwUserOptions"
|
|
|
- :key="item.id"
|
|
|
- :label="`${item.qwUserName} (${item.qwUserId})`"
|
|
|
- :value="item.id"
|
|
|
- >
|
|
|
- <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">
|
|
|
- 部门:{{ item.departmentName || item.department }} | 本地ID:{{ item.id }}
|
|
|
- </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>
|
|
|
+ <!-- 新增/修改对话框 -->
|
|
|
+ <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="true">无需验证</el-radio> <!-- true 表示无需验证 -->
|
|
|
+ <el-radio :label="false">需要验证</el-radio> <!-- false 表示需要验证 -->
|
|
|
+ </el-radio-group>
|
|
|
+ <div class="el-form-item__tips" style="color: #909399; font-size: 12px; margin-top: 5px;">
|
|
|
+ 选择"无需验证"时,客户添加好友无需员工确认
|
|
|
+ </div>
|
|
|
+ </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="selectedUserIds">
|
|
|
+ <el-select
|
|
|
+ v-model="form.selectedUserIds"
|
|
|
+ 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"
|
|
|
+ @change="handleUserSelectionChange"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in qwUserOptions"
|
|
|
+ :key="item.id"
|
|
|
+ :label="`${item.qwUserName} (${item.qwUserId})`"
|
|
|
+ :value="item.id"
|
|
|
+ >
|
|
|
+ <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">
|
|
|
+ 部门:{{ item.departmentName || item.department }} | 本地ID:{{ item.id }}
|
|
|
+ </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.selectedUserIds && form.selectedUserIds.length" class="el-form-item__tips"
|
|
|
+ style="color: #909399; font-size: 12px; margin-top: 5px;">
|
|
|
+ <div>已选择 {{ form.selectedUserIds.length }} 名成员</div>
|
|
|
+ <el-button type="text" @click="clearSelectedUsers" size="mini">清空</el-button>
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 部门选择(如果有部门选择组件) -->
|
|
|
+ <el-form-item label="关联部门" prop="departmentListParam" v-if="showDepartment">
|
|
|
+ <el-select
|
|
|
+ v-model="form.departmentListParam"
|
|
|
+ multiple
|
|
|
+ filterable
|
|
|
+ placeholder="请选择部门"
|
|
|
+ style="width: 100%"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in departmentOptions"
|
|
|
+ :key="item.id"
|
|
|
+ :label="item.departmentName"
|
|
|
+ :value="item.id"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </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-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.selectedUserIds && form.selectedUserIds.length" class="el-form-item__tips" style="color: #909399; font-size: 12px; margin-top: 5px;">
|
|
|
- <div>已选择 {{ form.selectedUserIds.length }} 名成员</div>
|
|
|
- <el-button type="text" @click="clearSelectedUsers" size="mini">清空</el-button>
|
|
|
- </div>
|
|
|
- </el-form-item>
|
|
|
-
|
|
|
- <!-- 部门选择(如果有部门选择组件) -->
|
|
|
- <el-form-item label="关联部门" prop="departmentListParam" v-if="showDepartment">
|
|
|
- <el-select
|
|
|
- v-model="form.departmentListParam"
|
|
|
- multiple
|
|
|
- filterable
|
|
|
- placeholder="请选择部门"
|
|
|
- style="width: 100%"
|
|
|
- >
|
|
|
- <el-option
|
|
|
- v-for="item in departmentOptions"
|
|
|
- :key="item.id"
|
|
|
- :label="item.departmentName"
|
|
|
- :value="item.id"
|
|
|
- />
|
|
|
- </el-select>
|
|
|
- </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 === true ? 'success' : 'info'">
|
|
|
- {{ detailData.skipVerify === true ? '无需验证' : '需要验证' }}
|
|
|
- </el-tag>
|
|
|
- <span style="margin-left: 8px; color: #909399; font-size: 12px;">
|
|
|
+ </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 === true ? 'success' : 'info'">
|
|
|
+ {{ detailData.skipVerify === true ? '无需验证' : '需要验证' }}
|
|
|
+ </el-tag>
|
|
|
+ <span style="margin-left: 8px; color: #909399; font-size: 12px;">
|
|
|
(skipVerify = {{ detailData.skipVerify }})
|
|
|
</span>
|
|
|
- </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>{{ formatDetailMembers(detailData.qwUserTableIdList) }}</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="qrCodeDialog.visible"
|
|
|
- width="500px"
|
|
|
- append-to-body
|
|
|
- @closed="handleQrCodeDialogClosed"
|
|
|
- >
|
|
|
- <div class="qr-code-container" v-loading="qrCodeDialog.generating">
|
|
|
- <div class="qr-code-wrapper" v-if="qrCodeDialog.dataUrl">
|
|
|
- <img :src="qrCodeDialog.dataUrl" alt="二维码" class="qr-code-image" />
|
|
|
- <div class="qr-code-info">
|
|
|
- <p><strong>链接名称:</strong>{{ qrCodeDialog.linkName }}</p>
|
|
|
- <p><strong>链接ID:</strong>{{ qrCodeDialog.linkId }}</p>
|
|
|
- <p><strong>完整链接:</strong>
|
|
|
- <el-link :href="qrCodeDialog.fullUrl" target="_blank" type="primary" :underline="false">
|
|
|
- {{ qrCodeDialog.fullUrl }}
|
|
|
- </el-link>
|
|
|
- </p>
|
|
|
- <p><strong>pageParam:</strong>{{ qrCodeDialog.pageParam }}</p>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div v-else-if="!qrCodeDialog.generating" class="qr-code-empty">
|
|
|
- <el-empty description="暂无二维码" />
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div slot="footer" class="dialog-footer">
|
|
|
- <el-button type="primary" @click="downloadQRCode" :disabled="!qrCodeDialog.dataUrl">
|
|
|
- <i class="el-icon-download"></i> 保存二维码
|
|
|
- </el-button>
|
|
|
- <el-button @click="qrCodeDialog.visible = false">关 闭</el-button>
|
|
|
- </div>
|
|
|
- </el-dialog>
|
|
|
- </div>
|
|
|
+ </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>{{ formatDetailMembers(detailData.qwUserTableIdList) }}</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="qrCodeDialog.visible"
|
|
|
+ width="500px"
|
|
|
+ append-to-body
|
|
|
+ @closed="handleQrCodeDialogClosed"
|
|
|
+ >
|
|
|
+ <div class="qr-code-container" v-loading="qrCodeDialog.generating">
|
|
|
+ <div class="qr-code-wrapper" v-if="qrCodeDialog.dataUrl">
|
|
|
+ <img :src="qrCodeDialog.dataUrl" alt="二维码" class="qr-code-image"/>
|
|
|
+ <div class="qr-code-info">
|
|
|
+ <p><strong>链接名称:</strong>{{ qrCodeDialog.linkName }}</p>
|
|
|
+ <p><strong>链接ID:</strong>{{ qrCodeDialog.linkId }}</p>
|
|
|
+ <p><strong>完整链接:</strong>
|
|
|
+ <el-link :href="qrCodeDialog.fullUrl" target="_blank" type="primary" :underline="false">
|
|
|
+ {{ qrCodeDialog.fullUrl }}
|
|
|
+ </el-link>
|
|
|
+ </p>
|
|
|
+ <p><strong>pageParam:</strong>{{ qrCodeDialog.pageParam }}</p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div v-else-if="!qrCodeDialog.generating" class="qr-code-empty">
|
|
|
+ <el-empty description="暂无二维码"/>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div slot="footer" class="dialog-footer">
|
|
|
+ <el-button type="primary" @click="downloadQRCode" :disabled="!qrCodeDialog.dataUrl">
|
|
|
+ <i class="el-icon-download"></i> 保存二维码
|
|
|
+ </el-button>
|
|
|
+ <el-button @click="qrCodeDialog.visible = false">关 闭</el-button>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
import {
|
|
|
- listAssistant,
|
|
|
- getDetailByLinkId,
|
|
|
- addAssistant,
|
|
|
- updateAssistant,
|
|
|
- deleteAssistant,
|
|
|
- getQwUserList,
|
|
|
- getQwUserListByIds,
|
|
|
- qwUserCompanyList
|
|
|
+ listAssistant,
|
|
|
+ getDetailByLinkId,
|
|
|
+ addAssistant,
|
|
|
+ updateAssistant,
|
|
|
+ deleteAssistant,
|
|
|
+ getQwUserList,
|
|
|
+ getQwUserListByIds,
|
|
|
+ qwUserCompanyList
|
|
|
} from '@/api/qw/acquisitionAssistant'
|
|
|
|
|
|
import QRCode from 'qrcodejs2'
|
|
|
|
|
|
export default {
|
|
|
- name: 'AcquisitionAssistant',
|
|
|
- data() {
|
|
|
- return {
|
|
|
- // 遮罩层
|
|
|
- loading: true,
|
|
|
- userLoading: false,
|
|
|
- loadingMore: false,
|
|
|
- // 添加部门选择器显示控制
|
|
|
- showDepartment: false,
|
|
|
- // 选中数组
|
|
|
- ids: [],
|
|
|
- // 非单个禁用
|
|
|
- single: true,
|
|
|
- // 非多个禁用
|
|
|
- multiple: true,
|
|
|
- // 总条数
|
|
|
- total: 0,
|
|
|
- // 表格数据
|
|
|
- assistantList: [],
|
|
|
- // 详情数据
|
|
|
- detailData: {},
|
|
|
- // 弹出层标题
|
|
|
- title: '',
|
|
|
- // 是否显示弹出层
|
|
|
- open: false,
|
|
|
- detailOpen: false,
|
|
|
- // 二维码弹窗数据
|
|
|
- qrCodeDialog: {
|
|
|
- visible: false,
|
|
|
- generating: false,
|
|
|
- dataUrl: null,
|
|
|
- fullUrl: '',
|
|
|
- linkName: '',
|
|
|
- linkId: '',
|
|
|
- pageParam: '',
|
|
|
- rowData: null
|
|
|
- },
|
|
|
- // 查询参数 - corpId作为全局筛选条件
|
|
|
- queryParams: {
|
|
|
- pageNum: 1,
|
|
|
- pageSize: 10,
|
|
|
- linkName: '',
|
|
|
- linkId: '',
|
|
|
- status: '',
|
|
|
- corpId: '' // 全局主体ID,所有需要corpId的接口都会用到
|
|
|
- },
|
|
|
- // 表单参数
|
|
|
- form: {
|
|
|
- // 基础信息
|
|
|
- linkName: '',
|
|
|
- skipVerify: true,
|
|
|
- priorityType: 0,
|
|
|
- remark: '',
|
|
|
- corpId: '',
|
|
|
- id: null,
|
|
|
-
|
|
|
- // 关联成员相关(三套数据,各有用处)
|
|
|
- userListParam: [], // 企微用户ID数组 (用于前端显示和回显)
|
|
|
- departmentListParam: [], // 部门ID数组
|
|
|
- qwUserTableIdList: [], // 本地数据库ID数组 (需要传给后端保存)
|
|
|
- userList: '', // 完整的JSON字符串 (包含userList)
|
|
|
-
|
|
|
- // 优先分配相关
|
|
|
- priorityUserListParam: [], // 优先分配的企微用户ID数组
|
|
|
- priorityDepartmentListParam: [], // 优先分配的部门ID数组
|
|
|
- priorityUserList: '', // 优先分配的JSON字符串
|
|
|
-
|
|
|
- // 选中的ID(用于el-select绑定)
|
|
|
- selectedUserIds: [] // 与qwUserTableIdList同步,用于前端选择框显示
|
|
|
- },
|
|
|
- // 表单校验
|
|
|
- rules: {
|
|
|
- linkName: [
|
|
|
- { required: true, message: '链接名称不能为空', trigger: 'blur' }
|
|
|
- ]
|
|
|
- },
|
|
|
- // 企业主体相关
|
|
|
- corpOptions: [],
|
|
|
- corpMap: new Map(),
|
|
|
- // 企微用户相关
|
|
|
- qwUserOptions: [],
|
|
|
- searchKeyword: '',
|
|
|
- userPage: 1,
|
|
|
- userPageSize: 20,
|
|
|
- userTotal: 0,
|
|
|
- hasMoreUsers: true,
|
|
|
- initialLoaded: false,
|
|
|
- // 基础域名
|
|
|
- baseDomain: 'https://c.ysyd.top'
|
|
|
- }
|
|
|
- },
|
|
|
- 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: {
|
|
|
- /** 获取完整链接 */
|
|
|
- getFullUrl(row) {
|
|
|
- if (!row || !row.pageParam) return `${this.baseDomain}`
|
|
|
- return `${this.baseDomain}/${row.pageParam}`
|
|
|
- },
|
|
|
-
|
|
|
- /** 复制完整链接 */
|
|
|
- handleCopyFullUrl(row) {
|
|
|
- const fullUrl = this.getFullUrl(row)
|
|
|
- this.copyToClipboard(fullUrl, '完整链接已复制')
|
|
|
- },
|
|
|
-
|
|
|
- /** 一键提取链接 */
|
|
|
- handleCopyLink(row) {
|
|
|
- const fullUrl = this.getFullUrl(row)
|
|
|
- this.copyToClipboard(fullUrl, '链接已提取并复制到剪贴板')
|
|
|
- },
|
|
|
-
|
|
|
- /** 复制到剪贴板的通用方法 */
|
|
|
- copyToClipboard(text, successMessage) {
|
|
|
- // 创建临时输入框
|
|
|
- const textarea = document.createElement('textarea')
|
|
|
- textarea.value = text
|
|
|
- textarea.style.position = 'fixed'
|
|
|
- textarea.style.opacity = '0'
|
|
|
- document.body.appendChild(textarea)
|
|
|
- textarea.select()
|
|
|
-
|
|
|
- try {
|
|
|
- const successful = document.execCommand('copy')
|
|
|
- if (successful) {
|
|
|
- this.$message({
|
|
|
- message: successMessage || '复制成功',
|
|
|
- type: 'success',
|
|
|
- duration: 2000
|
|
|
- })
|
|
|
- } else {
|
|
|
- this.$message.error('复制失败,请手动复制')
|
|
|
- }
|
|
|
- } catch (err) {
|
|
|
- console.error('复制失败:', err)
|
|
|
- this.$message.error('复制失败,请手动复制')
|
|
|
- } finally {
|
|
|
- document.body.removeChild(textarea)
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- /** 生成二维码 - 使用项目自带的QRCode库 */
|
|
|
- handleGenerateQRCode(row) {
|
|
|
- if (!row || !row.pageParam) {
|
|
|
- this.$message.warning('该链接没有pageParam参数,无法生成二维码')
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- const fullUrl = this.getFullUrl(row)
|
|
|
-
|
|
|
- // 显示二维码弹窗,并显示加载中
|
|
|
- this.qrCodeDialog.visible = true
|
|
|
- this.qrCodeDialog.generating = true
|
|
|
- this.qrCodeDialog.dataUrl = null
|
|
|
- this.qrCodeDialog.fullUrl = fullUrl
|
|
|
- this.qrCodeDialog.linkName = row.linkName || '-'
|
|
|
- this.qrCodeDialog.linkId = row.linkId || '-'
|
|
|
- this.qrCodeDialog.pageParam = row.pageParam || '-'
|
|
|
- this.qrCodeDialog.rowData = row
|
|
|
-
|
|
|
- try {
|
|
|
- // 使用 setTimeout 让UI能够更新加载状态
|
|
|
- setTimeout(() => {
|
|
|
- // 创建一个临时容器来生成二维码
|
|
|
- const tempDiv = document.createElement('div')
|
|
|
- tempDiv.style.position = 'absolute'
|
|
|
- tempDiv.style.left = '-9999px'
|
|
|
- tempDiv.style.top = '-9999px'
|
|
|
- document.body.appendChild(tempDiv)
|
|
|
-
|
|
|
- try {
|
|
|
- // 使用项目自带的 QRCode 库生成二维码
|
|
|
- const qrcode = new QRCode(tempDiv, {
|
|
|
- text: fullUrl,
|
|
|
- width: 300,
|
|
|
- height: 300,
|
|
|
- colorDark: '#000000',
|
|
|
- colorLight: '#ffffff',
|
|
|
- correctLevel: QRCode.CorrectLevel.H // 使用高容错率
|
|
|
- })
|
|
|
-
|
|
|
- // 等待二维码生成
|
|
|
- setTimeout(() => {
|
|
|
- try {
|
|
|
- // 从临时容器中获取生成的 canvas 或 img 元素
|
|
|
- const canvas = tempDiv.querySelector('canvas')
|
|
|
- if (canvas) {
|
|
|
- // 转换为 data URL
|
|
|
- this.qrCodeDialog.dataUrl = canvas.toDataURL('image/png')
|
|
|
- } else {
|
|
|
- // 如果使用 table 方式生成,尝试其他方法
|
|
|
- console.warn('未找到canvas元素,尝试其他方法')
|
|
|
- this.$message.warning('二维码生成方式不支持保存为图片,请更新浏览器')
|
|
|
- }
|
|
|
- } catch (err) {
|
|
|
- console.error('获取二维码图片失败:', err)
|
|
|
- this.$message.error('生成二维码失败')
|
|
|
- } finally {
|
|
|
- // 清理临时容器
|
|
|
- document.body.removeChild(tempDiv)
|
|
|
- this.qrCodeDialog.generating = false
|
|
|
- }
|
|
|
- }, 100)
|
|
|
- } catch (err) {
|
|
|
- console.error('生成二维码失败:', err)
|
|
|
- this.$message.error('生成二维码失败')
|
|
|
- document.body.removeChild(tempDiv)
|
|
|
- this.qrCodeDialog.generating = false
|
|
|
- }
|
|
|
- }, 50)
|
|
|
- } catch (error) {
|
|
|
- console.error('生成二维码失败:', error)
|
|
|
- this.$message.error('生成二维码失败')
|
|
|
- this.qrCodeDialog.generating = false
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- /** 下载二维码 */
|
|
|
- downloadQRCode() {
|
|
|
- if (!this.qrCodeDialog.dataUrl) return
|
|
|
-
|
|
|
- // 创建下载链接
|
|
|
- const link = document.createElement('a')
|
|
|
- link.href = this.qrCodeDialog.dataUrl
|
|
|
- link.download = `qrcode_${this.qrCodeDialog.linkId || 'link'}_${Date.now()}.png`
|
|
|
- document.body.appendChild(link)
|
|
|
- link.click()
|
|
|
- document.body.removeChild(link)
|
|
|
-
|
|
|
- this.$message.success('二维码已开始下载')
|
|
|
- },
|
|
|
-
|
|
|
- /** 二维码弹窗关闭后的处理 */
|
|
|
- handleQrCodeDialogClosed() {
|
|
|
- // 可以在这里做一些清理工作,如果需要的话
|
|
|
- // 目前不需要特殊处理
|
|
|
- },
|
|
|
-
|
|
|
- /** 格式化时间 */
|
|
|
- parseTime(time, pattern) {
|
|
|
- if (arguments.length === 0 || !time) {
|
|
|
- return '-'
|
|
|
- }
|
|
|
- const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
|
|
|
- let date
|
|
|
- if (typeof time === 'object') {
|
|
|
- date = time
|
|
|
- } else {
|
|
|
- if ((typeof time === 'string')) {
|
|
|
- if ((/^[0-9]+$/.test(time))) {
|
|
|
- // 如果是纯数字字符串,转为数字
|
|
|
- time = parseInt(time)
|
|
|
- } else {
|
|
|
- // 处理 "2026-03-19T14:05:41.000+0800" 格式
|
|
|
- time = time.replace(/-/g, '/') // 将 ISO 格式转换为兼容格式
|
|
|
- }
|
|
|
- }
|
|
|
- if ((typeof time === 'number') && (time.toString().length === 10)) {
|
|
|
- time = time * 1000
|
|
|
- }
|
|
|
- date = new Date(time)
|
|
|
- }
|
|
|
-
|
|
|
- // 如果日期无效
|
|
|
- if (isNaN(date.getTime())) {
|
|
|
- return '-'
|
|
|
- }
|
|
|
-
|
|
|
- const formatObj = {
|
|
|
- y: date.getFullYear(),
|
|
|
- m: date.getMonth() + 1,
|
|
|
- d: date.getDate(),
|
|
|
- h: date.getHours(),
|
|
|
- i: date.getMinutes(),
|
|
|
- s: date.getSeconds(),
|
|
|
- a: date.getDay()
|
|
|
- }
|
|
|
- const timeStr = format.replace(/{([ymdhisa])+}/g, (result, key) => {
|
|
|
- const value = formatObj[key]
|
|
|
- // 补零
|
|
|
- if (key === 'y') {
|
|
|
- return value.toString()
|
|
|
+ name: 'AcquisitionAssistant',
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ // 遮罩层
|
|
|
+ loading: true,
|
|
|
+ userLoading: false,
|
|
|
+ loadingMore: false,
|
|
|
+ // 添加部门选择器显示控制
|
|
|
+ showDepartment: false,
|
|
|
+ // 选中数组
|
|
|
+ ids: [],
|
|
|
+ // 非单个禁用
|
|
|
+ single: true,
|
|
|
+ // 非多个禁用
|
|
|
+ multiple: true,
|
|
|
+ // 总条数
|
|
|
+ total: 0,
|
|
|
+ // 表格数据
|
|
|
+ assistantList: [],
|
|
|
+ // 详情数据
|
|
|
+ detailData: {},
|
|
|
+ // 弹出层标题
|
|
|
+ title: '',
|
|
|
+ // 是否显示弹出层
|
|
|
+ open: false,
|
|
|
+ detailOpen: false,
|
|
|
+ // 二维码弹窗数据
|
|
|
+ qrCodeDialog: {
|
|
|
+ visible: false,
|
|
|
+ generating: false,
|
|
|
+ dataUrl: null,
|
|
|
+ fullUrl: '',
|
|
|
+ linkName: '',
|
|
|
+ linkId: '',
|
|
|
+ pageParam: '',
|
|
|
+ rowData: null
|
|
|
+ },
|
|
|
+ // 查询参数 - corpId作为全局筛选条件
|
|
|
+ queryParams: {
|
|
|
+ pageNum: 1,
|
|
|
+ pageSize: 10,
|
|
|
+ linkName: '',
|
|
|
+ linkId: '',
|
|
|
+ status: '',
|
|
|
+ corpId: '' // 全局主体ID,所有需要corpId的接口都会用到
|
|
|
+ },
|
|
|
+ // 表单参数
|
|
|
+ form: {
|
|
|
+ // 基础信息
|
|
|
+ linkName: '',
|
|
|
+ skipVerify: true,
|
|
|
+ priorityType: 0,
|
|
|
+ remark: '',
|
|
|
+ corpId: '',
|
|
|
+ id: null,
|
|
|
+
|
|
|
+ // 关联成员相关(三套数据,各有用处)
|
|
|
+ userListParam: [], // 企微用户ID数组 (用于前端显示和回显)
|
|
|
+ departmentListParam: [], // 部门ID数组
|
|
|
+ qwUserTableIdList: [], // 本地数据库ID数组 (需要传给后端保存)
|
|
|
+ userList: '', // 完整的JSON字符串 (包含userList)
|
|
|
+
|
|
|
+ // 优先分配相关
|
|
|
+ priorityUserListParam: [], // 优先分配的企微用户ID数组
|
|
|
+ priorityDepartmentListParam: [], // 优先分配的部门ID数组
|
|
|
+ priorityUserList: '', // 优先分配的JSON字符串
|
|
|
+
|
|
|
+ // 选中的ID(用于el-select绑定)
|
|
|
+ selectedUserIds: [] // 与qwUserTableIdList同步,用于前端选择框显示
|
|
|
+ },
|
|
|
+ // 表单校验
|
|
|
+ rules: {
|
|
|
+ linkName: [
|
|
|
+ {required: true, message: '链接名称不能为空', trigger: 'blur'}
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ // 企业主体相关
|
|
|
+ corpOptions: [],
|
|
|
+ corpMap: new Map(),
|
|
|
+ // 企微用户相关
|
|
|
+ qwUserOptions: [],
|
|
|
+ searchKeyword: '',
|
|
|
+ userPage: 1,
|
|
|
+ userPageSize: 20,
|
|
|
+ userTotal: 0,
|
|
|
+ hasMoreUsers: true,
|
|
|
+ initialLoaded: false,
|
|
|
+ // 基础域名
|
|
|
+ baseDomain: 'https://c.ysyd.top'
|
|
|
}
|
|
|
- return ('00' + value).substr(-2)
|
|
|
- })
|
|
|
- return timeStr
|
|
|
},
|
|
|
- /** 处理用户选择变化 - 同步更新所有相关字段 */
|
|
|
- handleUserSelectionChange(selectedIds) {
|
|
|
-
|
|
|
- // 1. 更新 qwUserTableIdList(需要传给后端的本地ID)
|
|
|
- this.form.qwUserTableIdList = [...selectedIds]
|
|
|
-
|
|
|
- // 2. 根据选中的本地ID,找到对应的企微用户ID,更新 userListParam
|
|
|
- const qwUserIds = []
|
|
|
- selectedIds.forEach(id => {
|
|
|
- const user = this.qwUserOptions.find(u => u.id === id)
|
|
|
- if (user) {
|
|
|
- qwUserIds.push(user.qwUserId)
|
|
|
+ computed: {
|
|
|
+ getUserSelectPlaceholder() {
|
|
|
+ if (!this.queryParams.corpId) {
|
|
|
+ return '请先在搜索栏选择主体'
|
|
|
+ }
|
|
|
+ return '请输入成员姓名进行搜索,或直接下拉选择'
|
|
|
}
|
|
|
- })
|
|
|
- this.form.userListParam = qwUserIds
|
|
|
-
|
|
|
- // 3. 构建完整的 userList JSON(包含用户ID和部门ID)
|
|
|
- const userListData = {
|
|
|
- userList: qwUserIds, // 企微用户ID列表
|
|
|
- departmentList: this.form.departmentListParam || [], // 部门ID列表
|
|
|
- userIds: selectedIds, // 本地数据库ID列表
|
|
|
- updateTime: new Date().getTime()
|
|
|
- }
|
|
|
- this.form.userList = JSON.stringify(userListData)
|
|
|
-
|
|
|
- console.log('更新后的数据:', {
|
|
|
- qwUserTableIdList: this.form.qwUserTableIdList,
|
|
|
- userListParam: this.form.userListParam,
|
|
|
- departmentListParam: this.form.departmentListParam,
|
|
|
- userList: this.form.userList
|
|
|
- })
|
|
|
- },
|
|
|
- /** 检查是否已选择主体 */
|
|
|
- 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)
|
|
|
+ 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: {
|
|
|
+ /** 获取完整链接 */
|
|
|
+ getFullUrl(row) {
|
|
|
+ if (!row || !row.pageParam) return `${this.baseDomain}`
|
|
|
+ return `${this.baseDomain}/${row.pageParam}`
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 复制完整链接 */
|
|
|
+ handleCopyFullUrl(row) {
|
|
|
+ const fullUrl = this.getFullUrl(row)
|
|
|
+ this.copyToClipboard(fullUrl, '完整链接已复制')
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 一键提取链接 */
|
|
|
+ handleCopyLink(row) {
|
|
|
+ const fullUrl = this.getFullUrl(row)
|
|
|
+ this.copyToClipboard(fullUrl, '链接已提取并复制到剪贴板')
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 复制到剪贴板的通用方法 */
|
|
|
+ copyToClipboard(text, successMessage) {
|
|
|
+ // 创建临时输入框
|
|
|
+ const textarea = document.createElement('textarea')
|
|
|
+ textarea.value = text
|
|
|
+ textarea.style.position = 'fixed'
|
|
|
+ textarea.style.opacity = '0'
|
|
|
+ document.body.appendChild(textarea)
|
|
|
+ textarea.select()
|
|
|
|
|
|
- /** 根据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
|
|
|
-
|
|
|
- // 重置分页和数据
|
|
|
- this.userPage = 1
|
|
|
- this.qwUserOptions = []
|
|
|
- this.initialLoaded = false
|
|
|
- this.searchKeyword = ''
|
|
|
-
|
|
|
- // 调用搜索方法,传入空字符串加载所有用户
|
|
|
- this.searchQwUsers('')
|
|
|
- },
|
|
|
+ try {
|
|
|
+ const successful = document.execCommand('copy')
|
|
|
+ if (successful) {
|
|
|
+ this.$message({
|
|
|
+ message: successMessage || '复制成功',
|
|
|
+ type: 'success',
|
|
|
+ duration: 2000
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ this.$message.error('复制失败,请手动复制')
|
|
|
+ }
|
|
|
+ } catch (err) {
|
|
|
+ console.error('复制失败:', err)
|
|
|
+ this.$message.error('复制失败,请手动复制')
|
|
|
+ } finally {
|
|
|
+ document.body.removeChild(textarea)
|
|
|
+ }
|
|
|
+ },
|
|
|
|
|
|
- /** 搜索企微用户 - 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
|
|
|
- }
|
|
|
-
|
|
|
- getQwUserList(params).then(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
|
|
|
- }
|
|
|
+ /** 生成二维码 - 使用项目自带的QRCode库 */
|
|
|
+ handleGenerateQRCode(row) {
|
|
|
+ if (!row || !row.pageParam) {
|
|
|
+ this.$message.warning('该链接没有pageParam参数,无法生成二维码')
|
|
|
+ return
|
|
|
+ }
|
|
|
|
|
|
- // 处理返回的用户数据,确保包含id字段
|
|
|
- newUsers = newUsers.map(user => ({
|
|
|
- ...user,
|
|
|
- // 确保有唯一标识
|
|
|
- uniqueKey: `${user.qwUserId}_${user.corpId}`,
|
|
|
- // 确保有id字段(本地数据库ID)
|
|
|
- id: user.id || user.userId || null
|
|
|
- }))
|
|
|
-
|
|
|
- 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]
|
|
|
- }
|
|
|
+ const fullUrl = this.getFullUrl(row)
|
|
|
|
|
|
- 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.qrCodeDialog.visible = true
|
|
|
+ this.qrCodeDialog.generating = true
|
|
|
+ this.qrCodeDialog.dataUrl = null
|
|
|
+ this.qrCodeDialog.fullUrl = fullUrl
|
|
|
+ this.qrCodeDialog.linkName = row.linkName || '-'
|
|
|
+ this.qrCodeDialog.linkId = row.linkId || '-'
|
|
|
+ this.qrCodeDialog.pageParam = row.pageParam || '-'
|
|
|
+ this.qrCodeDialog.rowData = row
|
|
|
|
|
|
- this.hasMoreUsers = this.qwUserOptions.length < this.userTotal
|
|
|
+ try {
|
|
|
+ // 使用 setTimeout 让UI能够更新加载状态
|
|
|
+ setTimeout(() => {
|
|
|
+ // 创建一个临时容器来生成二维码
|
|
|
+ const tempDiv = document.createElement('div')
|
|
|
+ tempDiv.style.position = 'absolute'
|
|
|
+ tempDiv.style.left = '-9999px'
|
|
|
+ tempDiv.style.top = '-9999px'
|
|
|
+ document.body.appendChild(tempDiv)
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 使用项目自带的 QRCode 库生成二维码
|
|
|
+ const qrcode = new QRCode(tempDiv, {
|
|
|
+ text: fullUrl,
|
|
|
+ width: 300,
|
|
|
+ height: 300,
|
|
|
+ colorDark: '#000000',
|
|
|
+ colorLight: '#ffffff',
|
|
|
+ correctLevel: QRCode.CorrectLevel.H // 使用高容错率
|
|
|
+ })
|
|
|
+
|
|
|
+ // 等待二维码生成
|
|
|
+ setTimeout(() => {
|
|
|
+ try {
|
|
|
+ // 从临时容器中获取生成的 canvas 或 img 元素
|
|
|
+ const canvas = tempDiv.querySelector('canvas')
|
|
|
+ if (canvas) {
|
|
|
+ // 转换为 data URL
|
|
|
+ this.qrCodeDialog.dataUrl = canvas.toDataURL('image/png')
|
|
|
+ } else {
|
|
|
+ // 如果使用 table 方式生成,尝试其他方法
|
|
|
+ console.warn('未找到canvas元素,尝试其他方法')
|
|
|
+ this.$message.warning('二维码生成方式不支持保存为图片,请更新浏览器')
|
|
|
+ }
|
|
|
+ } catch (err) {
|
|
|
+ console.error('获取二维码图片失败:', err)
|
|
|
+ this.$message.error('生成二维码失败')
|
|
|
+ } finally {
|
|
|
+ // 清理临时容器
|
|
|
+ document.body.removeChild(tempDiv)
|
|
|
+ this.qrCodeDialog.generating = false
|
|
|
+ }
|
|
|
+ }, 100)
|
|
|
+ } catch (err) {
|
|
|
+ console.error('生成二维码失败:', err)
|
|
|
+ this.$message.error('生成二维码失败')
|
|
|
+ document.body.removeChild(tempDiv)
|
|
|
+ this.qrCodeDialog.generating = false
|
|
|
+ }
|
|
|
+ }, 50)
|
|
|
+ } catch (error) {
|
|
|
+ console.error('生成二维码失败:', error)
|
|
|
+ this.$message.error('生成二维码失败')
|
|
|
+ this.qrCodeDialog.generating = false
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 下载二维码 */
|
|
|
+ downloadQRCode() {
|
|
|
+ if (!this.qrCodeDialog.dataUrl) return
|
|
|
+
|
|
|
+ // 创建下载链接
|
|
|
+ const link = document.createElement('a')
|
|
|
+ link.href = this.qrCodeDialog.dataUrl
|
|
|
+ link.download = `qrcode_${this.qrCodeDialog.linkId || 'link'}_${Date.now()}.png`
|
|
|
+ document.body.appendChild(link)
|
|
|
+ link.click()
|
|
|
+ document.body.removeChild(link)
|
|
|
+
|
|
|
+ this.$message.success('二维码已开始下载')
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 二维码弹窗关闭后的处理 */
|
|
|
+ handleQrCodeDialogClosed() {
|
|
|
+ // 可以在这里做一些清理工作,如果需要的话
|
|
|
+ // 目前不需要特殊处理
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 格式化时间 */
|
|
|
+ parseTime(time, pattern) {
|
|
|
+ if (arguments.length === 0 || !time) {
|
|
|
+ return '-'
|
|
|
+ }
|
|
|
+ const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
|
|
|
+ let date
|
|
|
+ if (typeof time === 'object') {
|
|
|
+ date = time
|
|
|
+ } else {
|
|
|
+ if ((typeof time === 'string')) {
|
|
|
+ if ((/^[0-9]+$/.test(time))) {
|
|
|
+ // 如果是纯数字字符串,转为数字
|
|
|
+ time = parseInt(time)
|
|
|
+ } else {
|
|
|
+ // 处理 "2026-03-19T14:05:41.000+0800" 格式
|
|
|
+ time = time.replace(/-/g, '/') // 将 ISO 格式转换为兼容格式
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if ((typeof time === 'number') && (time.toString().length === 10)) {
|
|
|
+ time = time * 1000
|
|
|
+ }
|
|
|
+ date = new Date(time)
|
|
|
+ }
|
|
|
|
|
|
- if (this.userPage === 1) {
|
|
|
- this.initialLoaded = true
|
|
|
- }
|
|
|
+ // 如果日期无效
|
|
|
+ if (isNaN(date.getTime())) {
|
|
|
+ return '-'
|
|
|
+ }
|
|
|
|
|
|
- this.userLoading = false
|
|
|
- this.loadingMore = false
|
|
|
- }).catch(error => {
|
|
|
- console.error('搜索用户失败:', error)
|
|
|
- this.userLoading = false
|
|
|
- this.loadingMore = false
|
|
|
- })
|
|
|
- },
|
|
|
+ const formatObj = {
|
|
|
+ y: date.getFullYear(),
|
|
|
+ m: date.getMonth() + 1,
|
|
|
+ d: date.getDate(),
|
|
|
+ h: date.getHours(),
|
|
|
+ i: date.getMinutes(),
|
|
|
+ s: date.getSeconds(),
|
|
|
+ a: date.getDay()
|
|
|
+ }
|
|
|
+ const timeStr = format.replace(/{([ymdhisa])+}/g, (result, key) => {
|
|
|
+ const value = formatObj[key]
|
|
|
+ // 补零
|
|
|
+ if (key === 'y') {
|
|
|
+ return value.toString()
|
|
|
+ }
|
|
|
+ return ('00' + value).substr(-2)
|
|
|
+ })
|
|
|
+ return timeStr
|
|
|
+ },
|
|
|
+ /** 处理用户选择变化 - 同步更新所有相关字段 */
|
|
|
+ handleUserSelectionChange(selectedIds) {
|
|
|
+
|
|
|
+ // 1. 更新 qwUserTableIdList(需要传给后端的本地ID)
|
|
|
+ this.form.qwUserTableIdList = [...selectedIds]
|
|
|
+
|
|
|
+ // 2. 根据选中的本地ID,找到对应的企微用户ID,更新 userListParam
|
|
|
+ const qwUserIds = []
|
|
|
+ selectedIds.forEach(id => {
|
|
|
+ const user = this.qwUserOptions.find(u => u.id === id)
|
|
|
+ if (user) {
|
|
|
+ qwUserIds.push(user.qwUserId)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ this.form.userListParam = qwUserIds
|
|
|
+
|
|
|
+ // 3. 构建完整的 userList JSON(包含用户ID和部门ID)
|
|
|
+ const userListData = {
|
|
|
+ userList: qwUserIds, // 企微用户ID列表
|
|
|
+ departmentList: this.form.departmentListParam || [], // 部门ID列表
|
|
|
+ userIds: selectedIds, // 本地数据库ID列表
|
|
|
+ updateTime: new Date().getTime()
|
|
|
+ }
|
|
|
+ this.form.userList = JSON.stringify(userListData)
|
|
|
|
|
|
- /** 处理选择器显隐变化 */
|
|
|
- handleSelectVisible(visible) {
|
|
|
- if (visible && this.queryParams.corpId) {
|
|
|
- if (!this.initialLoaded || this.qwUserOptions.length === 0) {
|
|
|
- this.loadUsersByCorp()
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
+ console.log('更新后的数据:', {
|
|
|
+ qwUserTableIdList: this.form.qwUserTableIdList,
|
|
|
+ userListParam: this.form.userListParam,
|
|
|
+ departmentListParam: this.form.departmentListParam,
|
|
|
+ userList: this.form.userList
|
|
|
+ })
|
|
|
+ },
|
|
|
+ /** 检查是否已选择主体 */
|
|
|
+ checkCorpId() {
|
|
|
+ if (!this.queryParams.corpId) {
|
|
|
+ this.msgError('请先在搜索栏选择主体')
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ return true
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 查询列表 */
|
|
|
+ getList() {
|
|
|
+ if (!this.checkCorpId()) {
|
|
|
+ this.loading = false
|
|
|
+ return
|
|
|
+ }
|
|
|
|
|
|
- /** 加载更多用户 */
|
|
|
- loadMoreUsers() {
|
|
|
- if (this.loadingMore || !this.hasMoreUsers) 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)
|
|
|
+ })
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 根据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 = []
|
|
|
+ }
|
|
|
|
|
|
- this.loadingMore = true
|
|
|
- this.userPage++
|
|
|
- this.searchQwUsers(this.searchKeyword)
|
|
|
- },
|
|
|
+ if (corpId) {
|
|
|
+ // 重新查询列表
|
|
|
+ this.queryParams.pageNum = 1
|
|
|
+ this.getList()
|
|
|
+ // 预加载用户数据
|
|
|
+ this.loadUsersByCorp()
|
|
|
+ } else {
|
|
|
+ // 如果没有选择主体,清空列表
|
|
|
+ this.assistantList = []
|
|
|
+ this.total = 0
|
|
|
+ }
|
|
|
+ },
|
|
|
|
|
|
- /** 清空已选用户 */
|
|
|
- clearSelectedUsers() {
|
|
|
- this.form.selectedUserIds = []
|
|
|
- this.form.qwUserTableIdList = []
|
|
|
- this.form.userListParam = []
|
|
|
- //部门列表可能不需要清空,根据业务需求决定
|
|
|
- // this.form.departmentListParam = []
|
|
|
- this.form.userList = JSON.stringify({
|
|
|
- userList: [],
|
|
|
- departmentList: this.form.departmentListParam || [],
|
|
|
- userIds: [],
|
|
|
- updateTime: new Date().getTime()
|
|
|
- })
|
|
|
- },
|
|
|
+ /** 根据当前选择的主体加载用户 */
|
|
|
+ loadUsersByCorp() {
|
|
|
+ if (!this.checkCorpId()) return
|
|
|
|
|
|
- /** 加载已选中用户的详细信息 */
|
|
|
- loadSelectedUsers(userIds) {
|
|
|
- if (!userIds || userIds.length === 0) return
|
|
|
+ const corpId = this.queryParams.corpId
|
|
|
|
|
|
- getQwUserListByIds(userIds).then(response => {
|
|
|
- const selectedUsers = response.data || []
|
|
|
+ // 重置分页和数据
|
|
|
+ this.userPage = 1
|
|
|
+ this.qwUserOptions = []
|
|
|
+ this.initialLoaded = false
|
|
|
+ this.searchKeyword = ''
|
|
|
|
|
|
- selectedUsers.forEach(user => {
|
|
|
- const exists = this.qwUserOptions.some(opt =>
|
|
|
- opt.qwUserId === user.qwUserId && opt.corpId === user.corpId
|
|
|
- )
|
|
|
- if (!exists) {
|
|
|
- this.qwUserOptions.push(user)
|
|
|
- }
|
|
|
- })
|
|
|
- })
|
|
|
- },
|
|
|
- /** 格式化详情页面的成员显示(不显示部门) */
|
|
|
- formatDetailMembers(localIds) {
|
|
|
- if (!localIds || !localIds.length) return '-'
|
|
|
-
|
|
|
- const memberNames = []
|
|
|
- localIds.forEach(id => {
|
|
|
- // 通过本地数据库ID查找用户
|
|
|
- const user = this.qwUserOptions.find(u => u.id === id)
|
|
|
- if (user) {
|
|
|
- // 显示用户名和企微ID,不显示部门
|
|
|
- memberNames.push(`${user.qwUserName}[${user.qwUserId}]`)
|
|
|
- } else {
|
|
|
- // 如果找不到,显示原始ID
|
|
|
- memberNames.push(`ID:${id}`)
|
|
|
- }
|
|
|
- })
|
|
|
+ // 调用搜索方法,传入空字符串加载所有用户
|
|
|
+ this.searchQwUsers('')
|
|
|
+ },
|
|
|
|
|
|
- return memberNames.join(', ')
|
|
|
- },
|
|
|
- /** 搜索按钮操作 */
|
|
|
- handleQuery() {
|
|
|
- if (!this.checkCorpId()) return
|
|
|
- this.queryParams.pageNum = 1
|
|
|
- this.getList()
|
|
|
- },
|
|
|
+ /** 搜索企微用户 - POST请求 */
|
|
|
+ searchQwUsers(query) {
|
|
|
+ if (!this.checkCorpId()) {
|
|
|
+ this.userLoading = false
|
|
|
+ return
|
|
|
+ }
|
|
|
|
|
|
- /** 重置按钮操作 */
|
|
|
- resetQuery() {
|
|
|
- this.resetForm('queryForm')
|
|
|
- // 重置时保留主体选择
|
|
|
- const currentCorpId = this.queryParams.corpId
|
|
|
- this.queryParams = {
|
|
|
- pageNum: 1,
|
|
|
- pageSize: 10,
|
|
|
- linkName: '',
|
|
|
- linkId: '',
|
|
|
- status: '',
|
|
|
- corpId: currentCorpId
|
|
|
- }
|
|
|
- this.handleQuery()
|
|
|
- },
|
|
|
+ if (query !== undefined) {
|
|
|
+ this.searchKeyword = query
|
|
|
+ this.userPage = 1
|
|
|
+ }
|
|
|
|
|
|
- /** 多选框选中数据 */
|
|
|
- handleSelectionChange(selection) {
|
|
|
- this.ids = selection.map(item => item.id)
|
|
|
- this.single = selection.length !== 1
|
|
|
- this.multiple = !selection.length
|
|
|
- },
|
|
|
+ if (!this.searchKeyword && this.initialLoaded) {
|
|
|
+ return
|
|
|
+ }
|
|
|
|
|
|
- /** 新增按钮操作 */
|
|
|
- handleAdd() {
|
|
|
- if (!this.checkCorpId()) return
|
|
|
+ this.userLoading = true
|
|
|
|
|
|
- this.reset()
|
|
|
- this.open = true
|
|
|
- this.title = '添加获客链接'
|
|
|
+ const params = {
|
|
|
+ qwUserName: this.searchKeyword || '',
|
|
|
+ pageNum: this.userPage,
|
|
|
+ pageSize: this.userPageSize,
|
|
|
+ corpId: this.queryParams.corpId
|
|
|
+ }
|
|
|
|
|
|
- // 预加载用户数据
|
|
|
- this.loadUsersByCorp()
|
|
|
- },
|
|
|
+ getQwUserList(params).then(response => {
|
|
|
|
|
|
- /** 修改按钮操作 */
|
|
|
- handleUpdate(row) {
|
|
|
- if (!this.checkCorpId()) return
|
|
|
+ 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
|
|
|
+ }
|
|
|
|
|
|
- this.reset()
|
|
|
+ // 处理返回的用户数据,确保包含id字段
|
|
|
+ newUsers = newUsers.map(user => ({
|
|
|
+ ...user,
|
|
|
+ // 确保有唯一标识
|
|
|
+ uniqueKey: `${user.qwUserId}_${user.corpId}`,
|
|
|
+ // 确保有id字段(本地数据库ID)
|
|
|
+ id: user.id || user.userId || null
|
|
|
+ }))
|
|
|
+
|
|
|
+ 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]
|
|
|
+ }
|
|
|
|
|
|
- // 先查询详情
|
|
|
- getDetailByLinkId(row.linkId).then(response => {
|
|
|
- const data = response.data
|
|
|
+ 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.form.id = data.id
|
|
|
- this.form.linkId = data.linkId
|
|
|
- this.form.linkName = data.linkName
|
|
|
- //将字符串的"true"/"false"转换为布尔值
|
|
|
- this.form.skipVerify = data.skipVerify === true || data.skipVerify === 'true'
|
|
|
- this.form.priorityType = data.priorityType
|
|
|
- this.form.remark = data.remark
|
|
|
- this.form.corpId = data.corpId
|
|
|
+ this.hasMoreUsers = this.qwUserOptions.length < this.userTotal
|
|
|
|
|
|
- // ========== 关联成员相关字段回显 ==========
|
|
|
+ if (this.userPage === 1) {
|
|
|
+ this.initialLoaded = true
|
|
|
+ }
|
|
|
|
|
|
- // 1. 处理 qwUserTableIdList(本地数据库ID)
|
|
|
- if (data.qwUserTableIdList) {
|
|
|
- if (typeof data.qwUserTableIdList === 'string') {
|
|
|
- try {
|
|
|
- // 处理类似 "[28462]" 的字符串
|
|
|
- const parsed = JSON.parse(data.qwUserTableIdList)
|
|
|
- this.form.qwUserTableIdList = Array.isArray(parsed) ? parsed : [parsed]
|
|
|
- } catch (e) {
|
|
|
- // 如果不是标准JSON格式,尝试按逗号分割
|
|
|
- this.form.qwUserTableIdList = data.qwUserTableIdList
|
|
|
- .replace(/[\[\]"]/g, '') // 去除方括号和引号
|
|
|
- .split(',')
|
|
|
- .filter(id => id.trim())
|
|
|
- .map(id => parseInt(id.trim()))
|
|
|
- }
|
|
|
- } else if (Array.isArray(data.qwUserTableIdList)) {
|
|
|
- this.form.qwUserTableIdList = data.qwUserTableIdList
|
|
|
- }
|
|
|
- }
|
|
|
+ this.userLoading = false
|
|
|
+ this.loadingMore = false
|
|
|
+ }).catch(error => {
|
|
|
+ console.error('搜索用户失败:', error)
|
|
|
+ this.userLoading = false
|
|
|
+ this.loadingMore = false
|
|
|
+ })
|
|
|
+ },
|
|
|
|
|
|
- // 2. 处理 userListParam(企微用户ID)- 从 userList 字段获取
|
|
|
- if (data.userList) {
|
|
|
- if (typeof data.userList === 'string') {
|
|
|
- try {
|
|
|
- // 处理类似 "[\"TongKe\"]" 的字符串
|
|
|
- const parsed = JSON.parse(data.userList)
|
|
|
- this.form.userListParam = Array.isArray(parsed) ? parsed : [parsed]
|
|
|
- } catch (e) {
|
|
|
- // 如果不是标准JSON格式,尝试按逗号分割
|
|
|
- this.form.userListParam = data.userList
|
|
|
- .replace(/[\[\]"]/g, '') // 去除方括号和引号
|
|
|
- .split(',')
|
|
|
- .filter(id => id.trim())
|
|
|
+ /** 处理选择器显隐变化 */
|
|
|
+ handleSelectVisible(visible) {
|
|
|
+ if (visible && this.queryParams.corpId) {
|
|
|
+ if (!this.initialLoaded || this.qwUserOptions.length === 0) {
|
|
|
+ this.loadUsersByCorp()
|
|
|
+ }
|
|
|
}
|
|
|
- } else if (Array.isArray(data.userList)) {
|
|
|
- this.form.userListParam = data.userList
|
|
|
- }
|
|
|
- }
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 加载更多用户 */
|
|
|
+ loadMoreUsers() {
|
|
|
+ if (this.loadingMore || !this.hasMoreUsers) return
|
|
|
+
|
|
|
+ this.loadingMore = true
|
|
|
+ this.userPage++
|
|
|
+ this.searchQwUsers(this.searchKeyword)
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 清空已选用户 */
|
|
|
+ clearSelectedUsers() {
|
|
|
+ this.form.selectedUserIds = []
|
|
|
+ this.form.qwUserTableIdList = []
|
|
|
+ this.form.userListParam = []
|
|
|
+ //部门列表可能不需要清空,根据业务需求决定
|
|
|
+ // this.form.departmentListParam = []
|
|
|
+ this.form.userList = JSON.stringify({
|
|
|
+ userList: [],
|
|
|
+ departmentList: this.form.departmentListParam || [],
|
|
|
+ userIds: [],
|
|
|
+ updateTime: new Date().getTime()
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 加载已选中用户的详细信息 */
|
|
|
+ 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)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ })
|
|
|
+ },
|
|
|
+ /** 格式化详情页面的成员显示(不显示部门) */
|
|
|
+ formatDetailMembers(localIds) {
|
|
|
+ if (!localIds || !localIds.length) return '-'
|
|
|
+
|
|
|
+ const memberNames = []
|
|
|
+ localIds.forEach(id => {
|
|
|
+ // 通过本地数据库ID查找用户
|
|
|
+ const user = this.qwUserOptions.find(u => u.id === id)
|
|
|
+ if (user) {
|
|
|
+ // 显示用户名和企微ID,不显示部门
|
|
|
+ memberNames.push(`${user.qwUserName}[${user.qwUserId}]`)
|
|
|
+ } else {
|
|
|
+ // 如果找不到,显示原始ID
|
|
|
+ memberNames.push(`ID:${id}`)
|
|
|
+ }
|
|
|
+ })
|
|
|
|
|
|
- // 3. 处理 departmentListParam(部门ID)
|
|
|
- if (data.departmentList) {
|
|
|
- if (typeof data.departmentList === 'string') {
|
|
|
- try {
|
|
|
- const parsed = JSON.parse(data.departmentList)
|
|
|
- this.form.departmentListParam = Array.isArray(parsed) ? parsed : []
|
|
|
- } catch (e) {
|
|
|
- this.form.departmentListParam = []
|
|
|
+ return memberNames.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
|
|
|
}
|
|
|
- } else if (Array.isArray(data.departmentList)) {
|
|
|
- this.form.departmentListParam = data.departmentList
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // ========== 优先分配相关字段回显 ==========
|
|
|
+ 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.rules.selectedUserIds = [
|
|
|
+ {required: true, message: '请选择关联成员', trigger: 'change'}
|
|
|
+ ]
|
|
|
+
|
|
|
+ // 如果表单已渲染,需要重新设置校验规则
|
|
|
+ this.$nextTick(() => {
|
|
|
+ if (this.$refs.form) {
|
|
|
+ this.$refs.form.clearValidate()
|
|
|
+ }
|
|
|
+ })
|
|
|
|
|
|
- // 4. 处理 priorityUserListParam(优先分配的企微用户ID)
|
|
|
- if (data.priorityUserList) {
|
|
|
- if (typeof data.priorityUserList === 'string') {
|
|
|
- try {
|
|
|
- const parsed = JSON.parse(data.priorityUserList)
|
|
|
- this.form.priorityUserListParam = Array.isArray(parsed) ? parsed : []
|
|
|
- } catch (e) {
|
|
|
- this.form.priorityUserListParam = []
|
|
|
- }
|
|
|
- } else if (Array.isArray(data.priorityUserList)) {
|
|
|
- this.form.priorityUserListParam = data.priorityUserList
|
|
|
- }
|
|
|
- }
|
|
|
+ // 预加载用户数据
|
|
|
+ this.loadUsersByCorp()
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 修改按钮操作 */
|
|
|
+ handleUpdate(row) {
|
|
|
+ if (!this.checkCorpId()) return
|
|
|
+
|
|
|
+ this.reset()
|
|
|
+
|
|
|
+ // 先查询详情
|
|
|
+ getDetailByLinkId(row.linkId).then(response => {
|
|
|
+ const data = response.data
|
|
|
+
|
|
|
+ // 基础信息赋值
|
|
|
+ this.form.id = data.id
|
|
|
+ this.form.linkId = data.linkId
|
|
|
+ this.form.linkName = data.linkName
|
|
|
+ //将字符串的"true"/"false"转换为布尔值
|
|
|
+ this.form.skipVerify = data.skipVerify === true || data.skipVerify === 'true'
|
|
|
+ this.form.priorityType = data.priorityType
|
|
|
+ this.form.remark = data.remark
|
|
|
+ this.form.corpId = data.corpId
|
|
|
+
|
|
|
+ // ========== 关联成员相关字段回显 ==========
|
|
|
+
|
|
|
+ // 1. 处理 qwUserTableIdList(本地数据库ID)
|
|
|
+ if (data.qwUserTableIdList) {
|
|
|
+ if (typeof data.qwUserTableIdList === 'string') {
|
|
|
+ try {
|
|
|
+ // 处理类似 "[28462]" 的字符串
|
|
|
+ const parsed = JSON.parse(data.qwUserTableIdList)
|
|
|
+ this.form.qwUserTableIdList = Array.isArray(parsed) ? parsed : [parsed]
|
|
|
+ } catch (e) {
|
|
|
+ // 如果不是标准JSON格式,尝试按逗号分割
|
|
|
+ this.form.qwUserTableIdList = data.qwUserTableIdList
|
|
|
+ .replace(/[\[\]"]/g, '') // 去除方括号和引号
|
|
|
+ .split(',')
|
|
|
+ .filter(id => id.trim())
|
|
|
+ .map(id => parseInt(id.trim()))
|
|
|
+ }
|
|
|
+ } else if (Array.isArray(data.qwUserTableIdList)) {
|
|
|
+ this.form.qwUserTableIdList = data.qwUserTableIdList
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- // 5. 设置 selectedUserIds 用于前端显示(与 qwUserTableIdList 同步)
|
|
|
- this.form.selectedUserIds = [...(this.form.qwUserTableIdList || [])]
|
|
|
+ // 2. 处理 userListParam(企微用户ID)- 从 userList 字段获取
|
|
|
+ if (data.userList) {
|
|
|
+ if (typeof data.userList === 'string') {
|
|
|
+ try {
|
|
|
+ const parsed = JSON.parse(data.userList)
|
|
|
+ // 检查 parsed 是否包含 userList 字段
|
|
|
+ if (parsed && parsed.userList && Array.isArray(parsed.userList)) {
|
|
|
+ this.form.userListParam = parsed.userList
|
|
|
+ } else if (Array.isArray(parsed)) {
|
|
|
+ this.form.userListParam = parsed
|
|
|
+ } else {
|
|
|
+ this.form.userListParam = []
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ console.error('解析 userList 失败:', e)
|
|
|
+ this.form.userListParam = []
|
|
|
+ }
|
|
|
+ } else if (Array.isArray(data.userList)) {
|
|
|
+ this.form.userListParam = data.userList
|
|
|
+ } else if (data.userList && data.userList.userList) {
|
|
|
+ // 处理已经是对象的情况
|
|
|
+ this.form.userListParam = data.userList.userList
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- console.log('回显完成:', {
|
|
|
- selectedUserIds: this.form.selectedUserIds,
|
|
|
- qwUserTableIdList: this.form.qwUserTableIdList,
|
|
|
- userListParam: this.form.userListParam,
|
|
|
- departmentListParam: this.form.departmentListParam,
|
|
|
- priorityUserListParam: this.form.priorityUserListParam
|
|
|
- })
|
|
|
+ // 3. 处理 departmentListParam(部门ID)
|
|
|
+ if (data.departmentList) {
|
|
|
+ if (typeof data.departmentList === 'string') {
|
|
|
+ try {
|
|
|
+ const parsed = JSON.parse(data.departmentList)
|
|
|
+ this.form.departmentListParam = Array.isArray(parsed) ? parsed : []
|
|
|
+ } catch (e) {
|
|
|
+ this.form.departmentListParam = []
|
|
|
+ }
|
|
|
+ } else if (Array.isArray(data.departmentList)) {
|
|
|
+ this.form.departmentListParam = data.departmentList
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- // 加载该主体的用户
|
|
|
- this.loadUsersByCorp()
|
|
|
+ // ========== 优先分配相关字段回显 ==========
|
|
|
+
|
|
|
+ // 4. 处理 priorityUserListParam(优先分配的企微用户ID)
|
|
|
+ if (data.priorityUserList) {
|
|
|
+ if (typeof data.priorityUserList === 'string') {
|
|
|
+ try {
|
|
|
+ const parsed = JSON.parse(data.priorityUserList)
|
|
|
+ this.form.priorityUserListParam = Array.isArray(parsed) ? parsed : []
|
|
|
+ } catch (e) {
|
|
|
+ this.form.priorityUserListParam = []
|
|
|
+ }
|
|
|
+ } else if (Array.isArray(data.priorityUserList)) {
|
|
|
+ this.form.priorityUserListParam = data.priorityUserList
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- // 如果有已选用户,加载他们的详细信息用于显示
|
|
|
- if (this.form.selectedUserIds && this.form.selectedUserIds.length > 0) {
|
|
|
- this.loadSelectedUsers(this.form.selectedUserIds)
|
|
|
- }
|
|
|
+ // 5. 设置 selectedUserIds 用于前端显示(与 qwUserTableIdList 同步)
|
|
|
+ this.form.selectedUserIds = [...(this.form.qwUserTableIdList || [])]
|
|
|
|
|
|
- this.open = true
|
|
|
- this.title = '修改获客链接'
|
|
|
- }).catch(error => {
|
|
|
- console.error('获取详情失败:', error)
|
|
|
- this.msgError('获取详情失败')
|
|
|
- })
|
|
|
- },
|
|
|
+ console.log('回显完成:', {
|
|
|
+ selectedUserIds: this.form.selectedUserIds,
|
|
|
+ qwUserTableIdList: this.form.qwUserTableIdList,
|
|
|
+ userListParam: this.form.userListParam,
|
|
|
+ departmentListParam: this.form.departmentListParam,
|
|
|
+ priorityUserListParam: this.form.priorityUserListParam
|
|
|
+ })
|
|
|
|
|
|
- /** 详情按钮操作 */
|
|
|
- handleDetail(row) {
|
|
|
- getDetailByLinkId(row.linkId).then(response => {
|
|
|
- const data = response.data
|
|
|
- this.detailData = { ...data }
|
|
|
+ // 加载该主体的用户
|
|
|
+ this.loadUsersByCorp()
|
|
|
|
|
|
- // 解析qwUserTableIdList
|
|
|
- if (data.qwUserTableIdList) {
|
|
|
- if (typeof data.qwUserTableIdList === 'string') {
|
|
|
- try {
|
|
|
- this.detailData.qwUserTableIdList = JSON.parse(data.qwUserTableIdList)
|
|
|
- } catch (e) {
|
|
|
- this.detailData.qwUserTableIdList = []
|
|
|
- }
|
|
|
- } else {
|
|
|
- this.detailData.qwUserTableIdList = data.qwUserTableIdList || []
|
|
|
- }
|
|
|
- }
|
|
|
+ // 如果有已选用户,加载他们的详细信息用于显示
|
|
|
+ if (this.form.selectedUserIds && this.form.selectedUserIds.length > 0) {
|
|
|
+ this.loadSelectedUsers(this.form.selectedUserIds)
|
|
|
+ }
|
|
|
|
|
|
- // 解析userList
|
|
|
- if (data.userList) {
|
|
|
- try {
|
|
|
- this.detailData.userListObj = JSON.parse(data.userList)
|
|
|
- } catch (e) {
|
|
|
- this.detailData.userListObj = {}
|
|
|
- }
|
|
|
- }
|
|
|
+ this.open = true
|
|
|
+ this.title = '修改获客链接'
|
|
|
+ }).catch(error => {
|
|
|
+ console.error('获取详情失败:', error)
|
|
|
+ this.msgError('获取详情失败')
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 详情按钮操作 */
|
|
|
+ handleDetail(row) {
|
|
|
+ getDetailByLinkId(row.linkId).then(response => {
|
|
|
+ const data = response.data
|
|
|
+ this.detailData = {...data}
|
|
|
+
|
|
|
+ // 解析qwUserTableIdList
|
|
|
+ if (data.qwUserTableIdList) {
|
|
|
+ if (typeof data.qwUserTableIdList === 'string') {
|
|
|
+ try {
|
|
|
+ this.detailData.qwUserTableIdList = JSON.parse(data.qwUserTableIdList)
|
|
|
+ } catch (e) {
|
|
|
+ this.detailData.qwUserTableIdList = []
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ this.detailData.qwUserTableIdList = data.qwUserTableIdList || []
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- // 解析priorityUserList
|
|
|
- if (data.priorityUserList) {
|
|
|
- try {
|
|
|
- this.detailData.priorityUserListParam = JSON.parse(data.priorityUserList)
|
|
|
- } catch (e) {
|
|
|
- this.detailData.priorityUserListParam = []
|
|
|
- }
|
|
|
- }
|
|
|
+ // 解析userList
|
|
|
+ if (data.userList) {
|
|
|
+ try {
|
|
|
+ this.detailData.userListObj = JSON.parse(data.userList)
|
|
|
+ } catch (e) {
|
|
|
+ this.detailData.userListObj = {}
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- this.detailOpen = true
|
|
|
- })
|
|
|
- },
|
|
|
+ // 解析priorityUserList
|
|
|
+ if (data.priorityUserList) {
|
|
|
+ try {
|
|
|
+ this.detailData.priorityUserListParam = JSON.parse(data.priorityUserList)
|
|
|
+ } catch (e) {
|
|
|
+ this.detailData.priorityUserListParam = []
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- /** 提交按钮 */
|
|
|
- submitForm() {
|
|
|
- if (!this.checkCorpId()) return
|
|
|
-
|
|
|
- this.$refs['form'].validate(valid => {
|
|
|
- if (valid) {
|
|
|
- // 验证关联成员是否超过500
|
|
|
- if (this.form.selectedUserIds && this.form.selectedUserIds.length > 500) {
|
|
|
- this.msgError('关联成员最多只能选择500人')
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- // 构建提交的数据
|
|
|
- const submitData = {
|
|
|
- // 基础信息
|
|
|
- id: this.form.id,
|
|
|
- linkId: this.form.linkId,
|
|
|
- linkName: this.form.linkName,
|
|
|
- skipVerify: this.form.skipVerify, // 布尔值,提交时保持布尔类型
|
|
|
- priorityType: this.form.priorityType,
|
|
|
- remark: this.form.remark,
|
|
|
- corpId: this.queryParams.corpId,
|
|
|
-
|
|
|
- // ========== 关联成员相关 ==========
|
|
|
- // 本地数据库ID列表 - 转换为JSON字符串
|
|
|
- qwUserTableIdList: JSON.stringify(this.form.selectedUserIds || []),
|
|
|
-
|
|
|
- // 企微用户ID列表 - 转换为JSON字符串,与后端期望的格式一致
|
|
|
- userList: JSON.stringify(this.form.userListParam || []),
|
|
|
-
|
|
|
- // 部门ID列表
|
|
|
- departmentList: JSON.stringify(this.form.departmentListParam || []),
|
|
|
-
|
|
|
- // ========== 优先分配相关 ==========
|
|
|
- priorityUserList: JSON.stringify(this.form.priorityUserListParam || []),
|
|
|
- }
|
|
|
-
|
|
|
- console.log('提交的数据:', submitData)
|
|
|
-
|
|
|
- if (this.form.id) {
|
|
|
- updateAssistant(submitData).then(response => {
|
|
|
- this.msgSuccess('修改成功')
|
|
|
- this.open = false
|
|
|
- this.getList()
|
|
|
- }).catch(error => {
|
|
|
- console.error('修改失败:', error)
|
|
|
+ this.detailOpen = true
|
|
|
})
|
|
|
- } else {
|
|
|
- addAssistant(submitData).then(response => {
|
|
|
- this.msgSuccess('新增成功')
|
|
|
- this.open = false
|
|
|
- this.getList()
|
|
|
- }).catch(error => {
|
|
|
- console.error('新增失败:', error)
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 提交按钮 */
|
|
|
+ submitForm() {
|
|
|
+ if (!this.checkCorpId()) return
|
|
|
+
|
|
|
+ this.$refs['form'].validate(valid => {
|
|
|
+ if (valid) {
|
|
|
+ // 验证关联成员是否超过500
|
|
|
+ if (this.form.selectedUserIds && this.form.selectedUserIds.length > 500) {
|
|
|
+ this.msgError('关联成员最多只能选择500人')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 构建提交的数据
|
|
|
+ const submitData = {
|
|
|
+ // 基础信息
|
|
|
+ id: this.form.id,
|
|
|
+ linkId: this.form.linkId,
|
|
|
+ linkName: this.form.linkName,
|
|
|
+ skipVerify: this.form.skipVerify, // 布尔值,提交时保持布尔类型
|
|
|
+ priorityType: this.form.priorityType,
|
|
|
+ remark: this.form.remark,
|
|
|
+ corpId: this.queryParams.corpId,
|
|
|
+
|
|
|
+ // ========== 关联成员相关 ==========
|
|
|
+ // 本地数据库ID列表 - 转换为JSON字符串
|
|
|
+ qwUserTableIdList: JSON.stringify(this.form.selectedUserIds || []),
|
|
|
+
|
|
|
+ // 企微用户ID列表 - 转换为JSON字符串,与后端期望的格式一致
|
|
|
+ userList: JSON.stringify(this.form.userListParam || []),
|
|
|
+
|
|
|
+ // 部门ID列表
|
|
|
+ departmentList: JSON.stringify(this.form.departmentListParam || []),
|
|
|
+
|
|
|
+ // ========== 优先分配相关 ==========
|
|
|
+ priorityUserList: JSON.stringify(this.form.priorityUserListParam || []),
|
|
|
+
|
|
|
+ userListParam: this.form.userListParam || [],
|
|
|
+ departmentListParam: this.form.departmentListParam || [],
|
|
|
+ priorityUserListParam: this.form.priorityUserListParam || []
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log('提交的数据:', submitData)
|
|
|
+
|
|
|
+ if (this.form.id) {
|
|
|
+ updateAssistant(submitData).then(response => {
|
|
|
+ this.msgSuccess('修改成功')
|
|
|
+ this.open = false
|
|
|
+ this.getList()
|
|
|
+ }).catch(error => {
|
|
|
+ console.error('修改失败:', error)
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ addAssistant(submitData).then(response => {
|
|
|
+ this.msgSuccess('新增成功')
|
|
|
+ this.open = false
|
|
|
+ this.getList()
|
|
|
+ }).catch(error => {
|
|
|
+ console.error('新增失败:', error)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
})
|
|
|
- }
|
|
|
- }
|
|
|
- })
|
|
|
- },
|
|
|
-
|
|
|
- /** 删除按钮操作 */
|
|
|
- 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('删除成功')
|
|
|
- })
|
|
|
- },
|
|
|
-
|
|
|
- /** 取消按钮 */
|
|
|
- cancel() {
|
|
|
- this.open = false
|
|
|
- this.reset()
|
|
|
- },
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 删除按钮操作 */
|
|
|
+ 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('删除成功')
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 取消按钮 */
|
|
|
+ cancel() {
|
|
|
+ this.open = false
|
|
|
+ this.reset()
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 表单重置 */
|
|
|
+ reset() {
|
|
|
+ this.form = {
|
|
|
+ // 基础信息
|
|
|
+ linkId: '',
|
|
|
+ linkName: '',
|
|
|
+ skipVerify: true,
|
|
|
+ priorityType: 0,
|
|
|
+ remark: '',
|
|
|
+ corpId: this.queryParams.corpId,
|
|
|
+ id: null,
|
|
|
+
|
|
|
+ // 关联成员相关
|
|
|
+ userListParam: [], // 企微用户ID
|
|
|
+ departmentListParam: [], // 部门ID
|
|
|
+ qwUserTableIdList: [], // 本地数据库ID
|
|
|
+ userList: '{"userList":[],"departmentList":[],"userIds":[]}', // 完整JSON
|
|
|
+
|
|
|
+ // 优先分配相关
|
|
|
+ priorityUserListParam: [], // 优先分配的企微用户ID
|
|
|
+ priorityDepartmentListParam: [], // 优先分配的部门ID
|
|
|
+ priorityUserList: '[]', // 优先分配JSON
|
|
|
+
|
|
|
+ // 选中的ID(用于el-select绑定)
|
|
|
+ selectedUserIds: []
|
|
|
+ }
|
|
|
|
|
|
- /** 表单重置 */
|
|
|
- reset() {
|
|
|
- this.form = {
|
|
|
- // 基础信息
|
|
|
- linkId: '',
|
|
|
- linkName: '',
|
|
|
- skipVerify: true,
|
|
|
- priorityType: 0,
|
|
|
- remark: '',
|
|
|
- corpId: this.queryParams.corpId,
|
|
|
- id: null,
|
|
|
-
|
|
|
- // 关联成员相关
|
|
|
- userListParam: [], // 企微用户ID
|
|
|
- departmentListParam: [], // 部门ID
|
|
|
- qwUserTableIdList: [], // 本地数据库ID
|
|
|
- userList: '{"userList":[],"departmentList":[],"userIds":[]}', // 完整JSON
|
|
|
-
|
|
|
- // 优先分配相关
|
|
|
- priorityUserListParam: [], // 优先分配的企微用户ID
|
|
|
- priorityDepartmentListParam: [], // 优先分配的部门ID
|
|
|
- priorityUserList: '[]', // 优先分配JSON
|
|
|
-
|
|
|
- // 选中的ID(用于el-select绑定)
|
|
|
- selectedUserIds: []
|
|
|
- }
|
|
|
-
|
|
|
- this.searchKeyword = ''
|
|
|
- this.userPage = 1
|
|
|
- this.hasMoreUsers = true
|
|
|
- this.resetForm('form')
|
|
|
+ this.searchKeyword = ''
|
|
|
+ this.userPage = 1
|
|
|
+ this.hasMoreUsers = true
|
|
|
+ this.resetForm('form')
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
<style scoped>
|
|
|
.mb8 {
|
|
|
- margin-bottom: 8px;
|
|
|
+ margin-bottom: 8px;
|
|
|
}
|
|
|
|
|
|
.el-form-item__tips {
|
|
|
- font-size: 12px;
|
|
|
- color: #909399;
|
|
|
- margin-top: 5px;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #909399;
|
|
|
+ margin-top: 5px;
|
|
|
}
|
|
|
|
|
|
/* 优化下拉选项的显示 */
|
|
|
.el-select-dropdown__item {
|
|
|
- height: auto;
|
|
|
- padding: 8px 20px;
|
|
|
+ height: auto;
|
|
|
+ padding: 8px 20px;
|
|
|
}
|
|
|
|
|
|
.el-select-dropdown__item span {
|
|
|
- line-height: 1.5;
|
|
|
+ line-height: 1.5;
|
|
|
}
|
|
|
|
|
|
/* 二维码弹窗样式 */
|
|
|
.qr-code-container {
|
|
|
- display: flex;
|
|
|
- justify-content: center;
|
|
|
- align-items: center;
|
|
|
- min-height: 350px;
|
|
|
- padding: 20px 0;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ min-height: 350px;
|
|
|
+ padding: 20px 0;
|
|
|
}
|
|
|
|
|
|
.qr-code-wrapper {
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- align-items: center;
|
|
|
- width: 100%;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ width: 100%;
|
|
|
}
|
|
|
|
|
|
.qr-code-image {
|
|
|
- width: 250px;
|
|
|
- height: 250px;
|
|
|
- border: 1px solid #eee;
|
|
|
- padding: 10px;
|
|
|
- background: white;
|
|
|
- box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
|
|
- margin-bottom: 20px;
|
|
|
+ width: 250px;
|
|
|
+ height: 250px;
|
|
|
+ border: 1px solid #eee;
|
|
|
+ padding: 10px;
|
|
|
+ background: white;
|
|
|
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
|
|
+ margin-bottom: 20px;
|
|
|
}
|
|
|
|
|
|
.qr-code-info {
|
|
|
- width: 100%;
|
|
|
- padding: 15px;
|
|
|
- background-color: #f9f9f9;
|
|
|
- border-radius: 4px;
|
|
|
- font-size: 14px;
|
|
|
+ width: 100%;
|
|
|
+ padding: 15px;
|
|
|
+ background-color: #f9f9f9;
|
|
|
+ border-radius: 4px;
|
|
|
+ font-size: 14px;
|
|
|
}
|
|
|
|
|
|
.qr-code-info p {
|
|
|
- margin: 8px 0;
|
|
|
- word-break: break-all;
|
|
|
+ margin: 8px 0;
|
|
|
+ word-break: break-all;
|
|
|
}
|
|
|
|
|
|
.qr-code-empty {
|
|
|
- width: 100%;
|
|
|
- display: flex;
|
|
|
- justify-content: center;
|
|
|
+ width: 100%;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
}
|
|
|
</style>
|