|
|
@@ -0,0 +1,244 @@
|
|
|
+<template>
|
|
|
+ <div class="customer-query-tab">
|
|
|
+ <!-- 查询表单 -->
|
|
|
+ <div class="query-form">
|
|
|
+ <el-form :model="queryParams" inline>
|
|
|
+ <el-form-item label="微信昵称">
|
|
|
+ <el-input v-model="queryParams.name" placeholder="请输入微信昵称" clearable />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="微信备注">
|
|
|
+ <el-input v-model="queryParams.remark" placeholder="请输入微信备注" clearable />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <el-button type="primary" @click="handleQuery">查询</el-button>
|
|
|
+ <el-button @click="resetQuery">重置</el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 客户列表(后端分页) -->
|
|
|
+ <el-table
|
|
|
+ v-loading="tableLoading"
|
|
|
+ :data="customerList"
|
|
|
+ border
|
|
|
+ stripe
|
|
|
+ style="width: 100%"
|
|
|
+ >
|
|
|
+ <el-table-column prop="externalUserId" label="客户ID" min-width="200" type="hidden" />
|
|
|
+ <el-table-column prop="name" label="微信昵称" min-width="120" />
|
|
|
+ <el-table-column prop="remark" label="备注" min-width="120" show-overflow-tooltip />
|
|
|
+ <el-table-column prop="staffCount" label="关联客服数" width="100" />
|
|
|
+ <el-table-column label="操作" width="100">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-button type="text" @click="openDrawer(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="getCustomerList"
|
|
|
+ ></pagination>
|
|
|
+
|
|
|
+ <!-- 抽屉:客服列表 + 会话详情 -->
|
|
|
+ <el-drawer
|
|
|
+ :visible.sync="drawerVisible"
|
|
|
+ :title="(currentCustomer && currentCustomer.name ? currentCustomer.name : '') + ' 的会话'"
|
|
|
+ direction="rtl"
|
|
|
+ size="80%"
|
|
|
+ destroy-on-close
|
|
|
+ >
|
|
|
+ <div class="drawer-container">
|
|
|
+ <div class="staff-list">
|
|
|
+ <el-table
|
|
|
+ :data="staffList"
|
|
|
+ v-loading="staffLoading"
|
|
|
+ height="100%"
|
|
|
+ highlight-current-row
|
|
|
+ @row-click="handleStaffClick"
|
|
|
+ >
|
|
|
+ <el-table-column prop="qwUserName" label="客服" />
|
|
|
+ <el-table-column prop="remark" label="备注" show-overflow-tooltip />
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+ <div class="conversation-panel">
|
|
|
+ <ConversationPanelPure
|
|
|
+ :corpId="corpId"
|
|
|
+ :customerId="currentCustomer && currentCustomer.externalUserId"
|
|
|
+ :staffUserId="selectedStaffUserId"
|
|
|
+ @logout="handleLogout"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-drawer>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { qwCustomerList, qwCustomerStaffList } from "@/api/qw/companySession";
|
|
|
+import ConversationPanelPure from "./ConversationPanelPure.vue";
|
|
|
+import Pagination from "@/components/Pagination";
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: "CustomerQueryTab",
|
|
|
+ components: { ConversationPanelPure, Pagination },
|
|
|
+ props: {
|
|
|
+ corpId: { type: String, required: true }
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ corpId() {
|
|
|
+ this.queryParams.pageNum = 1;
|
|
|
+ this.getCustomerList();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ queryParams: {
|
|
|
+ externalUserId: "",
|
|
|
+ name: "",
|
|
|
+ remark: "",
|
|
|
+ pageNum: 1,
|
|
|
+ pageSize: 10
|
|
|
+ },
|
|
|
+ customerList: [],
|
|
|
+ total: 0,
|
|
|
+ tableLoading: false,
|
|
|
+
|
|
|
+ // 抽屉相关
|
|
|
+ drawerVisible: false,
|
|
|
+ currentCustomer: null,
|
|
|
+ staffList: [],
|
|
|
+ staffLoading: false,
|
|
|
+ selectedStaffUserId: ''
|
|
|
+ };
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.getCustomerList();
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ // 获取客户列表(后端分页)
|
|
|
+ async getCustomerList() {
|
|
|
+ this.tableLoading = true;
|
|
|
+ try {
|
|
|
+ const params = {
|
|
|
+ corpId: this.corpId,
|
|
|
+ externalUserId: this.queryParams.externalUserId || undefined,
|
|
|
+ name: this.queryParams.name || undefined,
|
|
|
+ remark: this.queryParams.remark || undefined,
|
|
|
+ pageNum: this.queryParams.pageNum,
|
|
|
+ pageSize: this.queryParams.pageSize
|
|
|
+ };
|
|
|
+ const res = await qwCustomerList(params);
|
|
|
+ if (res.rows) {
|
|
|
+ this.customerList = res.rows;
|
|
|
+ this.total = res.total || 0;
|
|
|
+ } else {
|
|
|
+ this.customerList = [];
|
|
|
+ this.total = 0;
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ console.error("获取客户列表失败", e);
|
|
|
+ this.customerList = [];
|
|
|
+ this.total = 0;
|
|
|
+ } finally {
|
|
|
+ this.tableLoading = false;
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 查询按钮
|
|
|
+ handleQuery() {
|
|
|
+ this.queryParams.pageNum = 1;
|
|
|
+ this.getCustomerList();
|
|
|
+ },
|
|
|
+
|
|
|
+ // 重置查询条件
|
|
|
+ resetQuery() {
|
|
|
+ this.queryParams = {
|
|
|
+ externalUserId: "",
|
|
|
+ name: "",
|
|
|
+ remark: "",
|
|
|
+ pageNum: 1,
|
|
|
+ pageSize: 10
|
|
|
+ };
|
|
|
+ this.getCustomerList();
|
|
|
+ },
|
|
|
+
|
|
|
+ // 打开抽屉,加载该客户的客服列表
|
|
|
+ openDrawer(row) {
|
|
|
+ this.currentCustomer = row;
|
|
|
+ this.drawerVisible = true;
|
|
|
+ this.selectedStaffUserId = '';
|
|
|
+ this.staffList = [];
|
|
|
+ this.loadStaffList();
|
|
|
+ },
|
|
|
+
|
|
|
+ // 加载该客户关联的客服列表
|
|
|
+ async loadStaffList() {
|
|
|
+ if (!this.currentCustomer) return;
|
|
|
+ this.staffLoading = true;
|
|
|
+ try {
|
|
|
+ const res = await qwCustomerStaffList({
|
|
|
+ corpId: this.corpId,
|
|
|
+ externalUserId: this.currentCustomer.externalUserId
|
|
|
+ });
|
|
|
+ this.staffList = res.data || [];
|
|
|
+ } catch (e) {
|
|
|
+ console.error("获取客服列表失败", e);
|
|
|
+ this.staffList = [];
|
|
|
+ } finally {
|
|
|
+ this.staffLoading = false;
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 选中客服
|
|
|
+ handleStaffClick(row) {
|
|
|
+ this.selectedStaffUserId = row.userId;
|
|
|
+ },
|
|
|
+
|
|
|
+ // 会话登录失效处理
|
|
|
+ handleLogout() {
|
|
|
+ this.$message.warning("会话登录已失效,请刷新页面重试");
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.customer-query-tab {
|
|
|
+ height: 100%;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+}
|
|
|
+
|
|
|
+.query-form {
|
|
|
+ background: #fff;
|
|
|
+ padding: 16px;
|
|
|
+ margin-bottom: 16px;
|
|
|
+ border-radius: 4px;
|
|
|
+}
|
|
|
+
|
|
|
+.drawer-container {
|
|
|
+ display: flex;
|
|
|
+ height: 100%;
|
|
|
+ gap: 16px;
|
|
|
+}
|
|
|
+
|
|
|
+.staff-list {
|
|
|
+ width: 320px;
|
|
|
+ flex-shrink: 0;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ overflow: hidden;
|
|
|
+}
|
|
|
+
|
|
|
+.conversation-panel {
|
|
|
+ flex: 1;
|
|
|
+ background: #f5f6f7;
|
|
|
+ border-radius: 8px;
|
|
|
+ overflow: hidden;
|
|
|
+}
|
|
|
+</style>
|