| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335 |
- <template>
- <div class="employee-query-tab">
- <!-- 查询表单 -->
- <div class="query-form">
- <el-form :model="queryParams" inline>
- <el-form-item label="员工">
- <el-select
- v-model="queryParams.userId"
- filterable
- clearable
- placeholder="请选择员工"
- :loading="staffOptionsLoading"
- >
- <el-option
- v-for="item in staffOptions"
- :key="item.userId"
- :label="item.nickName || item.qwUserName"
- :value="item.userId"
- />
- </el-select>
- </el-form-item>
- <el-form-item label="企微昵称">
- <el-input v-model="queryParams.qwUserName" 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="staffList"
- border
- stripe
- style="width: 100%"
- >
- <el-table-column prop="nickName" label="员工" />
- <el-table-column prop="qwUserName" label="企微昵称" />
- <el-table-column prop="departmentName" label="部门" />
- <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="getStaffList"
- ></pagination>
- <!-- 抽屉:客户列表 + 会话详情 -->
- <el-drawer
- :visible.sync="drawerVisible"
- :title="(currentStaff && (currentStaff.nickName || currentStaff.qwUserName) ? (currentStaff.nickName || currentStaff.qwUserName) : '') + ' 的客户会话'"
- direction="rtl"
- size="80%"
- destroy-on-close
- >
- <div class="drawer-container">
- <div class="customer-list">
- <el-table
- :data="filteredCustomerList"
- v-loading="customerLoading"
- height="100%"
- highlight-current-row
- @row-click="handleCustomerClick"
- >
- <el-table-column label="头像" width="60">
- <template slot-scope="scope">
- <img :src="scope.row.avatar" style="width:40px;height:40px;border-radius:50%;" />
- </template>
- </el-table-column>
- <el-table-column prop="name" label="客户名称" />
- <el-table-column prop="qwUserName" label="销售昵称" />
- </el-table>
- <pagination
- v-show="customerTotal > 0"
- :total="customerTotal"
- :page.sync="customerPageNum"
- :limit.sync="customerPageSize"
- @pagination="loadCustomerList"
- layout="prev, pager, next"
- ></pagination>
- </div>
- <div class="conversation-panel">
- <ConversationPanelPure
- :corpId="currentStaff && currentStaff.corpId"
- :customerId="selectedCustomerId"
- :customerAvatar="selectedCustomerAvatar"
- :staffUserId="currentStaff && currentStaff.qwUserId"
- @logout="handleLogout"
- />
- </div>
- </div>
- </el-drawer>
- </div>
- </template>
- <script>
- import { getAllCompanyUserListNoParams } from "@/api/company/companyUser";
- import { selectQwUserListByCondition } from "@/api/qw/qwUser";
- import { listExternalContact } from "@/api/qw/externalContact";
- import ConversationPanelPure from "./ConversationPanelPure.vue";
- import Pagination from "@/components/Pagination";
- export default {
- name: "EmployeeQueryTab",
- components: { ConversationPanelPure, Pagination },
- props: {
- corp: {
- type: Object,
- default: null
- }
- },
- watch: {
- corp(newVal) {
- if (newVal && newVal.corpId) {
- this.queryParams.userId = null; // 清空已选员工
- this.queryParams.pageNum = 1;
- this.getStaffList();
- }
- }
- },
- data() {
- return {
- // 员工下拉选项(全量,用于查询条件)
- staffOptions: [],
- staffOptionsLoading: false,
- // 员工查询参数(后端分页)
- queryParams: {
- userId: null,
- qwUserName: "",
- pageNum: 1,
- pageSize: 10
- },
- staffList: [], // 当前页数据
- total: 0, // 总记录数
- tableLoading: false,
- // 抽屉相关
- drawerVisible: false,
- currentStaff: null,
- customerList: [],
- customerTotal: 0,
- customerPageNum: 1,
- customerPageSize: 10,
- customerLoading: false,
- customerKeyword: "",
- selectedCustomerId: null,
- selectedCustomerAvatar: ""
- };
- },
- computed: {
- filteredCustomerList() {
- if (!this.customerKeyword) return this.customerList;
- return this.customerList.filter(c => c.name && c.name.includes(this.customerKeyword));
- }
- },
- mounted() {
- this.loadStaffOptions();
- this.getStaffList();
- },
- methods: {
- // 加载所有员工用于下拉选项(无公司限制)
- async loadStaffOptions() {
- this.staffOptionsLoading = true;
- try {
- const res = await getAllCompanyUserListNoParams();
- let data = [];
- if (res.code === 200) {
- data = res.data || [];
- } else if (Array.isArray(res)) {
- data = res;
- } else if (res.data && Array.isArray(res.data)) {
- data = res.data;
- }
- this.staffOptions = data.map(item => ({
- userId: item.userId,
- nickName: item.nickName,
- qwUserName: item.qwUserName,
- qwUserId: item.id,
- departmentName: item.departmentName,
- corpId: item.corpId
- }));
- } catch (e) {
- console.error("加载员工下拉选项失败", e);
- this.staffOptions = [];
- } finally {
- this.staffOptionsLoading = false;
- }
- },
- // 获取员工列表(后端分页)
- async getStaffList() {
- this.tableLoading = true;
- try {
- // 构建请求参数,不传 companyId 让后端返回所有公司的员工(需后端支持)
- const params = {
- userId: this.queryParams.userId,
- qwUserName: this.queryParams.qwUserName,
- corpId: this.corp ? this.corp.corpId : null,
- pageNum: this.queryParams.pageNum,
- pageSize: this.queryParams.pageSize
- };
- const res = await selectQwUserListByCondition(params);
- if (res.code === 200 && res.data) {
- this.staffList = res.data.list || [];
- this.total = res.data.total || 0;
- } else {
- this.staffList = [];
- this.total = 0;
- }
- } catch (e) {
- console.error("获取员工列表失败", e);
- this.staffList = [];
- this.total = 0;
- } finally {
- this.tableLoading = false;
- }
- },
- // 查询按钮
- handleQuery() {
- this.queryParams.pageNum = 1;
- this.getStaffList();
- },
- // 重置查询条件
- resetQuery() {
- this.queryParams = {
- userId: null,
- qwUserName: "",
- pageNum: 1,
- pageSize: 10
- };
- this.getStaffList();
- },
- // 打开抽屉,加载客户列表
- openDrawer(row) {
- this.currentStaff = { ...row, corpId: this.corp?.corpId };
- this.drawerVisible = true;
- this.selectedCustomerId = null;
- this.selectedCustomerAvatar = "";
- this.customerPageNum = 1;
- this.loadCustomerList();
- },
- // 加载客户列表(使用员工自身的corpId)
- async loadCustomerList() {
- if (!this.currentStaff) return;
- this.customerLoading = true;
- try {
- const params = {
- pageNum: this.customerPageNum,
- pageSize: this.customerPageSize,
- qwUserId: this.currentStaff.id,
- corpId: this.corp?.corpId
- };
- const res = await listExternalContact(params);
- if (res.rows) {
- this.customerList = res.rows;
- this.customerTotal = res.total || 0;
- } else {
- this.customerList = [];
- this.customerTotal = 0;
- }
- } catch (e) {
- console.error("获取客户列表失败", e);
- this.customerList = [];
- this.customerTotal = 0;
- } finally {
- this.customerLoading = false;
- }
- },
- // 选中客户
- handleCustomerClick(row) {
- this.selectedCustomerId = row.externalUserId;
- this.selectedCustomerAvatar = row.avatar;
- },
- // 会话登录失效处理
- handleLogout() {
- this.$message.warning("会话登录已失效,请刷新页面重试");
- }
- }
- };
- </script>
- <style scoped>
- .employee-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;
- }
- .customer-list {
- width: 360px;
- flex-shrink: 0;
- display: flex;
- flex-direction: column;
- overflow: hidden;
- }
- .conversation-panel {
- flex: 1;
- background: #f5f6f7;
- border-radius: 8px;
- overflow: hidden;
- }
- </style>
|