Ver Fonte

个微属性

吴树波 há 4 semanas atrás
pai
commit
a296bd037f

+ 10 - 0
src/api/wx/wxContact.js

@@ -0,0 +1,10 @@
+import request from '@/utils/request'
+
+// 查询个微联系人列表
+export function listWxContact(query) {
+  return request({
+    url: '/company/wxContact/list',
+    method: 'get',
+    params: query
+  })
+}

+ 10 - 0
src/api/wx/wxMsgLog.js

@@ -0,0 +1,10 @@
+import request from '@/utils/request'
+
+// 查询聊天记录列表
+export function listWxMsgLog(query) {
+  return request({
+    url: '/company/wxMsgLog/list',
+    method: 'get',
+    params: query
+  })
+}

+ 0 - 1
src/views/company/companyClient/index.vue

@@ -309,7 +309,6 @@ export default {
       })
       })
     },
     },
     getQueryData() {
     getQueryData() {
-      let form = JSON.parse(JSON.stringify(this.queryParams));
       if (form.time && form.time.length === 2) {
       if (form.time && form.time.length === 2) {
         form.beginTime = form.time[0];
         form.beginTime = form.time[0];
         form.endTime = form.time[1];
         form.endTime = form.time[1];

+ 592 - 288
src/views/company/wxAccount/index.vue

@@ -1,308 +1,612 @@
 <template>
 <template>
-  <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
-      <el-form-item label="微信昵称" prop="wxNickName">
-        <el-input
-          v-model="queryParams.wxNickName"
-          placeholder="请输入微信昵称"
-          clearable
-          size="small"
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="微信号" prop="wxNo">
-        <el-input
-          v-model="queryParams.wxNo"
-          placeholder="请输入微信号"
-          clearable
-          size="small"
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="手机号" prop="wxNo">
-        <el-input
-          :maxlength="11"
-          v-model="queryParams.phone"
-          placeholder="请输入手机号"
-          clearable
-          size="small"
-          @keyup.enter.native="handleQuery"
+    <div class="app-container">
+        <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+            <el-form-item label="微信昵称" prop="wxNickName">
+                <el-input
+                    v-model="queryParams.wxNickName"
+                    placeholder="请输入微信昵称"
+                    clearable
+                    size="small"
+                    @keyup.enter.native="handleQuery"
+                />
+            </el-form-item>
+            <el-form-item label="微信号" prop="wxNo">
+                <el-input
+                    v-model="queryParams.wxNo"
+                    placeholder="请输入微信号"
+                    clearable
+                    size="small"
+                    @keyup.enter.native="handleQuery"
+                />
+            </el-form-item>
+            <el-form-item label="手机号" prop="wxNo">
+                <el-input
+                    :maxlength="11"
+                    v-model="queryParams.phone"
+                    placeholder="请输入手机号"
+                    clearable
+                    size="small"
+                    @keyup.enter.native="handleQuery"
+                />
+            </el-form-item>
+            <el-form-item label="员工" prop="companyUserId">
+                <el-select v-model="queryParams.companyUserId" clearable>
+                    <el-option v-for="item in qwUserList" :label="item.nickName" :value="item.userId" />
+                </el-select>
+            </el-form-item>
+            <el-form-item>
+                <el-button type="cyan" 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"
+                    v-hasPermi="['company:companyWx:add']"
+                >新增</el-button>
+            </el-col>
+            <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+        </el-row>
+
+        <el-table v-loading="loading" :data="companyAccountList" @selection-change="handleSelectionChange">
+            <el-table-column label="微信昵称" align="center" prop="wxNickName" />
+            <el-table-column label="头像" width="150" align="center">
+                <template slot-scope="scope">
+                    <img :src="scope.row.headImgUrl" style="height: 80px">
+                </template>
+            </el-table-column>
+            <el-table-column label="微信号" align="center" prop="wxNo" />
+            <el-table-column label="手机号" align="center" prop="phone" />
+            <el-table-column label="员工" align="center">
+                <template slot-scope="scope">
+                    <el-tag>{{scope.row.companyUserName}}</el-tag>
+                </template>
+            </el-table-column>
+            <el-table-column label="登录状态" align="center">
+                <template slot-scope="scope">
+                    <el-tag v-if="scope.row.loginStatus == 1" type="success">在线</el-tag>
+                    <el-tag v-else type="danger">离线</el-tag>
+                </template>
+            </el-table-column>
+            <el-table-column label="在线/离线时间" align="center">
+                <template slot-scope="scope">
+                    <el-tag type="danger" v-if="scope.row.loginStatus == 0">{{scope.row.outTime}}</el-tag>
+                    <el-tag type="success" v-if="scope.row.loginStatus == 1">{{scope.row.loginTime}}</el-tag>
+                </template>
+            </el-table-column>
+            <el-table-column label="离线备注" align="center" prop="outRemark">
+                <template slot-scope="scope">
+                    <p v-if="scope.row.loginStatus == 0">{{scope.row.outRemark}}</p>
+                </template>
+            </el-table-column>
+            <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+                <template slot-scope="scope">
+                    <el-button
+                        size="mini"
+                        type="text"
+                        icon="el-icon-edit"
+                        @click="handleUpdate(scope.row)"
+                        v-hasPermi="['company:companyWx:edit']"
+                    >修改</el-button>
+                    <el-button
+                        v-if="scope.row.serverStatus == 0"
+                        size="mini"
+                        type="text"
+                        @click="bind(scope.row)"
+                    >获取PAD</el-button>
+                    <el-button
+                    <!--            v-if="scope.row.serverStatus == 1 && scope.row.loginStatus == 0"-->
+                    <!--            size="mini"-->
+                    <!--            type="text"-->
+                    <!--            @click="login(scope.row, 'ipad')"-->
+                    <!--          >登录IPAD</el-button>-->
+                    <!--          <el-button-->
+                    <!--            v-if="scope.row.serverStatus == 1 && scope.row.loginStatus == 0"-->
+                    <!--            size="mini"-->
+                    <!--            type="text"-->
+                    <!--            @click="login(scope.row, 'mac')"-->
+                    <!--          >登录Mac</el-button>-->
+                    <!--          <el-button-->
+                    <!--            v-if="scope.row.serverStatus == 1 && scope.row.loginStatus == 0"-->
+                    <!--            size="mini"-->
+                    <!--            type="text"-->
+                    <!--            @click="wkUp(scope.row)"-->
+                    <!--          >唤醒登录</el-button>-->
+                    <el-button
+                        v-if="scope.row.serverStatus == 1 && scope.row.loginStatus == 1"
+                        size="mini"
+                        type="text"
+                        @click="updateWxInfoFun(scope.row.id)"
+                    >更新微信信息</el-button>
+                    <el-button
+                        v-if="scope.row.serverStatus == 1 && scope.row.loginStatus == 1"
+                        size="mini"
+                        type="text"
+                        @click="wxLoginOutFun(scope.row.id)"
+                    >退出微信</el-button>
+                    <el-button
+                        v-if="scope.row.serverStatus == 1 && scope.row.loginStatus == 1"
+                        size="mini"
+                        type="text"
+                        @click="syncWxFun(scope.row.id)"
+                    >同步通讯录</el-button>
+                    <el-button
+                        size="mini"
+                        type="text"
+                        icon="el-icon-delete"
+                        @click="handleDelete(scope.row)"
+                        v-hasPermi="['company:companyWx:remove']"
+                    >删除</el-button>
+                    <el-button size="mini" type="text" @click="handleContactList(scope.row)">联系人</el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+
+        <pagination
+            v-show="total>0"
+            :total="total"
+            :page.sync="queryParams.pageNum"
+            :limit.sync="queryParams.pageSize"
+            @pagination="getList"
         />
         />
-      </el-form-item>
-      <el-form-item label="员工" prop="companyUserId">
-        <el-select v-model="queryParams.companyUserId" clearable>
-          <el-option v-for="item in qwUserList" :label="item.qwUserName" :value="item.id" />
-        </el-select>
-      </el-form-item>
-      <el-form-item>
-        <el-button type="cyan" 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"
-          v-hasPermi="['company:companyWx:add']"
-        >新增</el-button>
-      </el-col>
-      <el-col :span="1.5">
-        <el-button
-          type="success"
-          icon="el-icon-edit"
-          size="mini"
-          :disabled="single"
-          @click="handleUpdate"
-          v-hasPermi="['company:companyWx:edit']"
-        >修改</el-button>
-      </el-col>
-      <el-col :span="1.5">
-        <el-button
-          type="danger"
-          icon="el-icon-delete"
-          size="mini"
-          :disabled="multiple"
-          @click="handleDelete"
-          v-hasPermi="['company:companyWx:remove']"
-        >删除</el-button>
-      </el-col>
-      <el-col :span="1.5">
-        <el-button
-          type="warning"
-          icon="el-icon-download"
-          size="mini"
-          @click="handleExport"
-          v-hasPermi="['company:companyWx:export']"
-        >导出</el-button>
-      </el-col>
-	  <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
-    </el-row>
+        <!-- 添加或修改个微账号对话框 -->
+        <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+            <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+                <el-form-item label="微信昵称" prop="wxNickName">
+                    <el-input v-model="form.wxNickName" placeholder="请输入微信昵称" />
+                </el-form-item>
+                <el-form-item label="微信号" prop="wxNo">
+                    <el-input v-model="form.wxNo" placeholder="请输入微信号" />
+                </el-form-item>
+                <el-form-item label="手机号" prop="phone">
+                    <el-input v-model="form.phone" :maxlength="11" placeholder="请输入手机号" />
+                </el-form-item>
+                <el-form-item label="员工" prop="companyUserId">
+                    <el-select v-model="form.companyUserId" filterable placeholder="请选择员工">
+                        <el-option v-for="item in qwUserList" :label="item.nickName" :value="item.userId" />
+                    </el-select>
+                </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-table v-loading="loading" :data="companyAccountList" @selection-change="handleSelectionChange">
-      <el-table-column type="selection" width="55" align="center" />
-      <el-table-column label="id" align="center" prop="id" />
-      <el-table-column label="微信昵称" align="center" prop="wxNickName" />
-      <el-table-column label="微信号" align="center" prop="wxNo" />
-      <el-table-column label="手机号" align="center" prop="phone" />
-      <el-table-column label="员工" align="center" prop="companyUserName" />
-      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
-        <template slot-scope="scope">
-          <el-button
-            size="mini"
-            type="text"
-            icon="el-icon-edit"
-            @click="handleUpdate(scope.row)"
-            v-hasPermi="['company:companyWx:edit']"
-          >修改</el-button>
-          <el-button
-            size="mini"
-            type="text"
-            icon="el-icon-delete"
-            @click="handleDelete(scope.row)"
-            v-hasPermi="['company:companyWx:remove']"
-          >删除</el-button>
-        </template>
-      </el-table-column>
-    </el-table>
+        <!-- 添加或修改个微账号对话框 -->
+        <el-dialog title="扫码登录" :visible.sync="loginData.open" width="500px" append-to-body>
+        </el-dialog>
+        <el-dialog
+            title="扫码登录"
+            :visible.sync="loginData.open"
+            width="600px"
+            append-to-body
+            custom-class="qr-login-dialog"
+        >
+            <div class="qr-login-container" style="text-align: center;">
+                <el-image
+                    :src="loginData.url"
+                    style="display: block; margin: 0 auto; width: 300px; height: 300px;"
+                />
+                <p class="qr-login-instructions">使用微信扫码授权登录</p>
+            </div>
+        </el-dialog>
 
 
-    <pagination
-      v-show="total>0"
-      :total="total"
-      :page.sync="queryParams.pageNum"
-      :limit.sync="queryParams.pageSize"
-      @pagination="getList"
-    />
+        <!-- 联系人列表弹窗 -->
+        <el-drawer title="联系人列表" :visible.sync="contactOpen" size="70%" append-to-body>
+            <el-table :data="contactList">
+                <el-table-column label="头像" align="center" width="70">
+                    <template slot-scope="scope">
+                        <img v-if="scope.row.headImgUrl" :src="scope.row.headImgUrl" style="width:40px;height:40px;border-radius:50%;object-fit:cover;" />
+                        <el-avatar v-else :size="40" icon="el-icon-user-solid" />
+                    </template>
+                </el-table-column>
+                <el-table-column label="微信昵称" align="center" prop="nickName" />
+                <el-table-column label="微信号" align="center" prop="alias" />
+                <el-table-column label="备注" align="center" prop="remark" show-overflow-tooltip />
+                <el-table-column label="是否好友" align="center" width="90">
+                    <template slot-scope="scope">
+                        <el-tag v-if="scope.row.friends == 1" type="success" size="small">是</el-tag>
+                        <el-tag v-else type="danger" size="small">否</el-tag>
+                    </template>
+                </el-table-column>
+                <el-table-column label="创建时间" align="center" prop="createTime" width="160">
+                    <template slot-scope="scope">
+                        <span>{{ parseTime(scope.row.createTime) }}</span>
+                    </template>
+                </el-table-column>
+                <el-table-column label="操作" align="center" width="100">
+                    <template slot-scope="scope">
+                        <el-button size="mini" type="text" @click="handleChatHistory(scope.row)">聊天记录</el-button>
+                    </template>
+                </el-table-column>
+            </el-table>
+            <pagination
+                v-show="contactTotal > 0"
+                :total="contactTotal"
+                :page.sync="contactQueryParams.pageNum"
+                :limit.sync="contactQueryParams.pageSize"
+                @pagination="getContactList"
+            />
+        </el-drawer>
 
 
-    <!-- 添加或修改个微账号对话框 -->
-    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
-      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
-        <el-form-item label="微信昵称" prop="wxNickName">
-          <el-input v-model="form.wxNickName" placeholder="请输入微信昵称" />
-        </el-form-item>
-        <el-form-item label="微信号" prop="wxNo">
-          <el-input v-model="form.wxNo" placeholder="请输入微信号" />
-        </el-form-item>
-        <el-form-item label="手机号" prop="phone">
-          <el-input v-model="form.phone" :maxlength="11" placeholder="请输入手机号" />
-        </el-form-item>
-        <el-form-item label="员工" prop="companyUserId">
-          <el-select v-model="form.companyUserId" filterable placeholder="请选择员工">
-            <el-option v-for="item in qwUserList" :label="item.nickName" :value="item.userId" />
-          </el-select>
-        </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>
-  </div>
+        <!-- 聊天记录弹窗 -->
+        <el-dialog :title="'聊天记录 - ' + (currentContact.nickName || '')" :visible.sync="chatOpen" width="60%" append-to-body>
+            <div class="chat-container">
+                <div v-for="(msg, index) in chatList" :key="index">
+                    <div class="chat-time">{{ parseTime(msg.createTime) }}</div>
+                    <!-- 收到的消息 - 左侧 -->
+                    <div v-if="msg.receiveType == 0" class="chat-item">
+                        <el-avatar :size="36" icon="el-icon-user-solid" />
+                        <div class="chat-bubble left">{{ msg.content }}</div>
+                    </div>
+                    <!-- 发出的消息 - 右侧 -->
+                    <div v-else class="chat-item self">
+                        <div class="chat-bubble right">{{ msg.content }}</div>
+                        <el-avatar :size="36" icon="el-icon-user-solid" style="background: #95ec69;" />
+                    </div>
+                </div>
+                <div v-if="chatList.length === 0" style="text-align:center; color:#999; padding: 40px 0;">暂无聊天记录</div>
+            </div>
+            <pagination
+                v-show="chatTotal > 0"
+                :total="chatTotal"
+                :page.sync="chatQueryParams.pageNum"
+                :limit.sync="chatQueryParams.pageSize"
+                @pagination="getChatList"
+            />
+        </el-dialog>
+    </div>
 </template>
 </template>
 
 
 <script>
 <script>
-import { listCompanyAccount, getCompanyAccount, delCompanyAccount, addCompanyAccount, updateCompanyAccount, exportCompanyAccount, companyListAll } from "@/api/company/companyAccount";
-import {getAllUserlist} from "@/api/company/companyUser";
+import {
+    listCompanyAccount,
+    getCompanyAccount,
+    delCompanyAccount,
+    addCompanyAccount,
+    updateCompanyAccount,
+    exportCompanyAccount,
+    companyListAll,
+    getWxQrCode,
+    getLoginStatus,
+    wakeUpLogin,
+    syncWx,
+    updateWxInfo,
+    wxLoginOut,
+    bindService
+} from '@/api/company/companyAccount'
+import { qrCodeStatus } from '@/api/qw/user'
+import { listWxContact } from "@/api/wx/wxContact"
+import { listWxMsgLog } from "@/api/wx/wxMsgLog"
 
 
 
 
 export default {
 export default {
-  name: "CompanyAccount",
-  data() {
-    return {
-      // 遮罩层
-      loading: true,
-      // 选中数组
-      ids: [],
-      // 非单个禁用
-      single: true,
-      // 非多个禁用
-      multiple: true,
-      // 显示搜索条件
-      showSearch: true,
-      // 总条数
-      total: 0,
-      // 个微账号表格数据
-      companyAccountList: [],
-      qwUserList: [],
-      // 弹出层标题
-      title: "",
-      // 是否显示弹出层
-      open: false,
-      // 查询参数
-      queryParams: {
-        pageNum: 1,
-        pageSize: 10,
-        wxNickName: null,
-        wxNo: null,
-        companyUserId: null,
-        createUser: null
-      },
-      // 表单参数
-      form: {},
-      // 表单校验
-      rules: {
-      }
-    };
-  },
-  created() {
-    this.getList();
-    companyListAll().then(e => {
-      this.qwUserList = e.data;
-    })
-  },
-  methods: {
-    /** 查询个微账号列表 */
-    getList() {
-      this.loading = true;
-      listCompanyAccount(this.queryParams).then(response => {
-        this.companyAccountList = response.rows;
-        this.total = response.total;
-        this.loading = false;
-      });
-    },
-    // 取消按钮
-    cancel() {
-      this.open = false;
-      this.reset();
+    name: "CompanyAccount",
+    data() {
+        return {
+            // 遮罩层
+            loading: true,
+            // 选中数组
+            ids: [],
+            // 非单个禁用
+            single: true,
+            // 非多个禁用
+            multiple: true,
+            // 显示搜索条件
+            showSearch: true,
+            // 总条数
+            total: 0,
+            loginData:{
+                open: false,
+                url: null
+            },
+            // 个微账号表格数据
+            companyAccountList: [],
+            loginQwInterval: null,
+            qwUserList: [],
+            // 弹出层标题
+            title: "",
+            // 是否显示弹出层
+            open: false,
+            // 查询参数
+            queryParams: {
+                pageNum: 1,
+                pageSize: 10,
+                wxNickName: null,
+                wxNo: null,
+                companyUserId: null,
+                createUser: null
+            },
+            // 表单参数
+            form: {},
+            // 表单校验
+            rules: {
+            },
+            // 联系人弹窗
+            contactOpen: false,
+            contactList: [],
+            contactTotal: 0,
+            contactQueryParams: {
+                pageNum: 1,
+                pageSize: 10,
+                accountId: null
+            },
+            // 聊天记录弹窗
+            chatOpen: false,
+            chatList: [],
+            chatTotal: 0,
+            chatQueryParams: {
+                pageNum: 1,
+                pageSize: 20,
+                accountId: null,
+                fromUserName: null,
+                toUserName: null
+            },
+            currentContact: {}
+        };
     },
     },
-    // 表单重置
-    reset() {
-      this.form = {
-        id: null,
-        wxNickName: null,
-        wxNo: null,
-        companyUserId: null,
-        createTime: null,
-        createUser: null
-      };
-      this.resetForm("form");
+    created() {
+        this.getList();
+        companyListAll().then(e => {
+            this.qwUserList = e.data;
+        })
     },
     },
-    /** 搜索按钮操作 */
-    handleQuery() {
-      this.queryParams.pageNum = 1;
-      this.getList();
-    },
-    /** 重置按钮操作 */
-    resetQuery() {
-      this.resetForm("queryForm");
-      this.handleQuery();
-    },
-    // 多选框选中数据
-    handleSelectionChange(selection) {
-      this.ids = selection.map(item => item.id)
-      this.single = selection.length!==1
-      this.multiple = !selection.length
-    },
-    /** 新增按钮操作 */
-    handleAdd() {
-      this.reset();
-      this.open = true;
-      this.title = "添加个微账号";
-    },
-    /** 修改按钮操作 */
-    handleUpdate(row) {
-      this.reset();
-      const id = row.id || this.ids
-      getCompanyAccount(id).then(response => {
-        this.form = response.data;
-        this.open = true;
-        this.title = "修改个微账号";
-      });
-    },
-    /** 提交按钮 */
-    submitForm() {
-      this.$refs["form"].validate(valid => {
-        if (valid) {
-          if (this.form.id != null) {
-            updateCompanyAccount(this.form).then(response => {
-              if (response.code === 200) {
-                this.msgSuccess("修改成功");
-                this.open = false;
+    methods: {
+        /** 查询个微账号列表 */
+        getList() {
+            this.loading = true;
+            listCompanyAccount(this.queryParams).then(response => {
+                this.companyAccountList = response.rows;
+                this.total = response.total;
+                this.loading = false;
+            });
+        },
+        // 取消按钮
+        cancel() {
+            this.open = false;
+            this.reset();
+        },
+        // 表单重置
+        reset() {
+            this.form = {
+                id: null,
+                wxNickName: null,
+                wxNo: null,
+                companyUserId: null,
+                createTime: null,
+                createUser: null
+            };
+            this.resetForm("form");
+        },
+        /** 搜索按钮操作 */
+        handleQuery() {
+            this.queryParams.pageNum = 1;
+            this.getList();
+        },
+        /** 重置按钮操作 */
+        resetQuery() {
+            this.resetForm("queryForm");
+            this.handleQuery();
+        },
+        // 多选框选中数据
+        handleSelectionChange(selection) {
+            this.ids = selection.map(item => item.id)
+            this.single = selection.length!==1
+            this.multiple = !selection.length
+        },
+        /** 新增按钮操作 */
+        handleAdd() {
+            this.reset();
+            this.open = true;
+            this.title = "添加个微账号";
+        },
+        login(row, ipadOrMac){
+            getWxQrCode({accountId: row.id, ipadOrMac}).then(e => {
+                this.loginData.open = true;
+                this.loginData.url = e.data;
+                this.loginStatus(row.id);
+            });
+        },
+        wkUp(row){
+            wakeUpLogin({accountId: row.id}).then(e => {
+                this.loginStatus(row.id);
+            });
+        },
+        loginStatus(id){
+            this.loginQwInterval = setInterval(() => {
+                this.getLoginStatusFun(id);
+            }, 3000);
+        },
+        getLoginStatusFun(id){
+            getLoginStatus({accountId: id}).then(res => {
+                if(res.data){
+                    this.loginData.open = false;
+                    this.getList();
+                    clearInterval(this.loginQwInterval);
+                }
+            });
+        },
+        updateWxInfoFun(id){
+            updateWxInfo({accountId: id}).then(res => {
+                if(res.data){
+                    this.loginData.open = false;
+                    this.getList();
+                    clearInterval(this.loginQwInterval);
+                }
+            });
+        },
+        wxLoginOutFun(id){
+            wxLoginOut({accountId: id}).then(res => {
+                if(res.data){
+                    this.getList();
+                }
+            });
+        },
+        syncWxFun(id){
+            syncWx({accountId: id}).then(res => {
+                this.msgSuccess("正在同步......");
+            });
+        },
+        bind(row){
+            bindService({accountId: row.id}).then(e => {
                 this.getList();
                 this.getList();
-              }
+            })
+        },
+        /** 修改按钮操作 */
+        handleUpdate(row) {
+            this.reset();
+            const id = row.id || this.ids
+            getCompanyAccount(id).then(response => {
+                this.form = response.data;
+                this.open = true;
+                this.title = "修改个微账号";
             });
             });
-          } else {
-            addCompanyAccount(this.form).then(response => {
-              if (response.code === 200) {
-                this.msgSuccess("新增成功");
-                this.open = false;
+        },
+        /** 提交按钮 */
+        submitForm() {
+            this.$refs["form"].validate(valid => {
+                if (valid) {
+                    if (this.form.id != null) {
+                        updateCompanyAccount(this.form).then(response => {
+                            if (response.code === 200) {
+                                this.msgSuccess("修改成功");
+                                this.open = false;
+                                this.getList();
+                            }
+                        });
+                    } else {
+                        addCompanyAccount(this.form).then(response => {
+                            if (response.code === 200) {
+                                this.msgSuccess("新增成功");
+                                this.open = false;
+                                this.getList();
+                            }
+                        });
+                    }
+                }
+            });
+        },
+        /** 删除按钮操作 */
+        handleDelete(row) {
+            const ids = row.id || this.ids;
+            this.$confirm('是否确认删除个微账号编号为"' + ids + '"的数据项?', "警告", {
+                confirmButtonText: "确定",
+                cancelButtonText: "取消",
+                type: "warning"
+            }).then(function() {
+                return delCompanyAccount(ids);
+            }).then(() => {
                 this.getList();
                 this.getList();
-              }
+                this.msgSuccess("删除成功");
+            }).catch(function() {});
+        },
+        /** 导出按钮操作 */
+        handleExport() {
+            const queryParams = this.queryParams;
+            this.$confirm('是否确认导出所有个微账号数据项?', "警告", {
+                confirmButtonText: "确定",
+                cancelButtonText: "取消",
+                type: "warning"
+            }).then(function() {
+                return exportCompanyAccount(queryParams);
+            }).then(response => {
+                this.download(response.msg);
+            }).catch(function() {});
+        },
+        /** 打开联系人弹窗 */
+        handleContactList(row) {
+            this.contactQueryParams.pageNum = 1;
+            this.contactQueryParams.accountId = row.id;
+            this.contactOpen = true;
+            this.getContactList();
+        },
+        /** 查询联系人列表 */
+        getContactList() {
+            listWxContact(this.contactQueryParams).then(response => {
+                this.contactList = response.rows;
+                this.contactTotal = response.total;
             });
             });
-          }
-        }
-      });
-    },
-    /** 删除按钮操作 */
-    handleDelete(row) {
-      const ids = row.id || this.ids;
-      this.$confirm('是否确认删除个微账号编号为"' + ids + '"的数据项?', "警告", {
-          confirmButtonText: "确定",
-          cancelButtonText: "取消",
-          type: "warning"
-        }).then(function() {
-          return delCompanyAccount(ids);
-        }).then(() => {
-          this.getList();
-          this.msgSuccess("删除成功");
-        }).catch(function() {});
-    },
-    /** 导出按钮操作 */
-    handleExport() {
-      const queryParams = this.queryParams;
-      this.$confirm('是否确认导出所有个微账号数据项?', "警告", {
-          confirmButtonText: "确定",
-          cancelButtonText: "取消",
-          type: "warning"
-        }).then(function() {
-          return exportCompanyAccount(queryParams);
-        }).then(response => {
-          this.download(response.msg);
-        }).catch(function() {});
-    },
-  }
+        },
+        /** 打开聊天记录弹窗 */
+        handleChatHistory(contactRow) {
+            this.currentContact = contactRow;
+            this.chatQueryParams.pageNum = 1;
+            this.chatQueryParams.accountId = this.contactQueryParams.accountId;
+            this.chatOpen = true;
+            this.getChatList();
+        },
+        /** 查询聊天记录列表 */
+        getChatList() {
+            listWxMsgLog(this.chatQueryParams).then(response => {
+                this.chatList = response.rows;
+                this.chatTotal = response.total;
+            });
+        },
+    }
 };
 };
 </script>
 </script>
+
+<style scoped>
+.chat-container {
+    background: #f5f5f5;
+    padding: 16px;
+    max-height: 500px;
+    overflow-y: auto;
+}
+.chat-item {
+    display: flex;
+    margin-bottom: 16px;
+    align-items: flex-start;
+}
+.chat-item.self {
+    justify-content: flex-end;
+}
+.chat-bubble {
+    max-width: 60%;
+    padding: 10px 14px;
+    border-radius: 8px;
+    font-size: 14px;
+    line-height: 1.5;
+    word-break: break-all;
+    position: relative;
+}
+.chat-bubble.left {
+    background: #fff;
+    margin-left: 10px;
+}
+.chat-bubble.left::before {
+    content: '';
+    position: absolute;
+    left: -8px;
+    top: 10px;
+    border-width: 6px 8px 6px 0;
+    border-style: solid;
+    border-color: transparent #fff transparent transparent;
+}
+.chat-bubble.right {
+    background: #95ec69;
+    margin-right: 10px;
+}
+.chat-bubble.right::after {
+    content: '';
+    position: absolute;
+    right: -8px;
+    top: 10px;
+    border-width: 6px 0 6px 8px;
+    border-style: solid;
+    border-color: transparent transparent transparent #95ec69;
+}
+.chat-time {
+    text-align: center;
+    color: #999;
+    font-size: 12px;
+    margin-bottom: 10px;
+}
+</style>

+ 1 - 1
src/views/crm/components/addOrEditCustomer.vue

@@ -1,4 +1,4 @@
-<template>
+ <template>
     <div class="customer-dialog-content">
     <div class="customer-dialog-content">
         <div class="dialog-header">
         <div class="dialog-header">
             <i class="el-icon-user header-icon"></i>
             <i class="el-icon-user header-icon"></i>

+ 194 - 18
src/views/gw/gwAccount/index.vue

@@ -100,23 +100,23 @@
             @click="bind(scope.row)"
             @click="bind(scope.row)"
           >获取PAD</el-button>
           >获取PAD</el-button>
           <el-button
           <el-button
-            v-if="scope.row.serverStatus == 1 && scope.row.loginStatus == 0"
-            size="mini"
-            type="text"
-            @click="login(scope.row, 'ipad')"
-          >登录IPAD</el-button>
-          <el-button
-            v-if="scope.row.serverStatus == 1 && scope.row.loginStatus == 0"
-            size="mini"
-            type="text"
-            @click="login(scope.row, 'mac')"
-          >登录Mac</el-button>
-          <el-button
-            v-if="scope.row.serverStatus == 1 && scope.row.loginStatus == 0"
-            size="mini"
-            type="text"
-            @click="wkUp(scope.row)"
-          >唤醒登录</el-button>
+<!--            v-if="scope.row.serverStatus == 1 && scope.row.loginStatus == 0"-->
+<!--            size="mini"-->
+<!--            type="text"-->
+<!--            @click="login(scope.row, 'ipad')"-->
+<!--          >登录IPAD</el-button>-->
+<!--          <el-button-->
+<!--            v-if="scope.row.serverStatus == 1 && scope.row.loginStatus == 0"-->
+<!--            size="mini"-->
+<!--            type="text"-->
+<!--            @click="login(scope.row, 'mac')"-->
+<!--          >登录Mac</el-button>-->
+<!--          <el-button-->
+<!--            v-if="scope.row.serverStatus == 1 && scope.row.loginStatus == 0"-->
+<!--            size="mini"-->
+<!--            type="text"-->
+<!--            @click="wkUp(scope.row)"-->
+<!--          >唤醒登录</el-button>-->
           <el-button
           <el-button
             v-if="scope.row.serverStatus == 1 && scope.row.loginStatus == 1"
             v-if="scope.row.serverStatus == 1 && scope.row.loginStatus == 1"
             size="mini"
             size="mini"
@@ -142,6 +142,7 @@
             @click="handleDelete(scope.row)"
             @click="handleDelete(scope.row)"
             v-hasPermi="['company:companyWx:remove']"
             v-hasPermi="['company:companyWx:remove']"
           >删除</el-button>
           >删除</el-button>
+          <el-button size="mini" type="text" @click="handleContactList(scope.row)">联系人</el-button>
         </template>
         </template>
       </el-table-column>
       </el-table-column>
     </el-table>
     </el-table>
@@ -196,6 +197,71 @@
         <p class="qr-login-instructions">使用微信扫码授权登录</p>
         <p class="qr-login-instructions">使用微信扫码授权登录</p>
       </div>
       </div>
     </el-dialog>
     </el-dialog>
+
+    <!-- 联系人列表弹窗 -->
+    <el-drawer title="联系人列表" :visible.sync="contactOpen" width="800px" append-to-body >
+      <el-table :data="contactList">
+        <el-table-column label="头像" align="center" width="70">
+          <template slot-scope="scope">
+            <img v-if="scope.row.headImgUrl" :src="scope.row.headImgUrl" style="width:40px;height:40px;border-radius:50%;object-fit:cover;" />
+            <el-avatar v-else :size="40" icon="el-icon-user-solid" />
+          </template>
+        </el-table-column>
+        <el-table-column label="微信昵称" align="center" prop="nickName" />
+        <el-table-column label="微信号" align="center" prop="alias" />
+        <el-table-column label="备注" align="center" prop="remark" show-overflow-tooltip />
+        <el-table-column label="是否好友" align="center" width="90">
+          <template slot-scope="scope">
+            <el-tag v-if="scope.row.friends == 1" type="success" size="small">是</el-tag>
+            <el-tag v-else type="danger" size="small">否</el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="创建时间" align="center" prop="createTime" width="160">
+          <template slot-scope="scope">
+            <span>{{ parseTime(scope.row.createTime) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" align="center" width="100">
+          <template slot-scope="scope">
+            <el-button size="mini" type="text" @click="handleChatHistory(scope.row)">聊天记录</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination
+        v-show="contactTotal > 0"
+        :total="contactTotal"
+        :page.sync="contactQueryParams.pageNum"
+        :limit.sync="contactQueryParams.pageSize"
+        @pagination="getContactList"
+      />
+    </el-drawer>
+
+    <!-- 聊天记录弹窗 -->
+    <el-dialog :title="'聊天记录 - ' + (currentContact.nickName || '')" :visible.sync="chatOpen" width="700px" append-to-body>
+      <div class="chat-container">
+        <div v-for="(msg, index) in chatList" :key="index">
+          <div class="chat-time">{{ parseTime(msg.createTime) }}</div>
+          <!-- 收到的消息 - 左侧 -->
+          <div v-if="msg.receiveType == 0" class="chat-item">
+            <el-avatar :size="36" icon="el-icon-user-solid" />
+            <div class="chat-bubble left">{{ msg.content }}</div>
+          </div>
+          <!-- 发出的消息 - 右侧 -->
+          <div v-else class="chat-item self">
+            <div class="chat-bubble right">{{ msg.content }}</div>
+            <el-avatar :size="36" icon="el-icon-user-solid" style="background: #95ec69;" />
+          </div>
+        </div>
+        <div v-if="chatList.length === 0" style="text-align:center; color:#999; padding: 40px 0;">暂无聊天记录</div>
+      </div>
+      <pagination
+        v-show="chatTotal > 0"
+        :total="chatTotal"
+        :page.sync="chatQueryParams.pageNum"
+        :limit.sync="chatQueryParams.pageSize"
+        @pagination="getChatList"
+      />
+    </el-dialog>
   </div>
   </div>
 </template>
 </template>
 
 
@@ -217,6 +283,8 @@ import {
   bindService
   bindService
 } from '@/api/company/companyAccount'
 } from '@/api/company/companyAccount'
 import { qrCodeStatus } from '@/api/qw/user'
 import { qrCodeStatus } from '@/api/qw/user'
+import { listWxContact } from "@/api/wx/wxContact"
+import { listWxMsgLog } from "@/api/wx/wxMsgLog"
 
 
 
 
 export default {
 export default {
@@ -260,7 +328,28 @@ export default {
       form: {},
       form: {},
       // 表单校验
       // 表单校验
       rules: {
       rules: {
-      }
+      },
+      // 联系人弹窗
+      contactOpen: false,
+      contactList: [],
+      contactTotal: 0,
+      contactQueryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        accountId: null
+      },
+      // 聊天记录弹窗
+      chatOpen: false,
+      chatList: [],
+      chatTotal: 0,
+      chatQueryParams: {
+        pageNum: 1,
+        pageSize: 20,
+        accountId: null,
+        fromUserName: null,
+        toUserName: null
+      },
+      currentContact: {}
     };
     };
   },
   },
   created() {
   created() {
@@ -431,6 +520,93 @@ export default {
           this.download(response.msg);
           this.download(response.msg);
         }).catch(function() {});
         }).catch(function() {});
     },
     },
+    /** 打开联系人弹窗 */
+    handleContactList(row) {
+      this.contactQueryParams.pageNum = 1;
+      this.contactQueryParams.accountId = row.id;
+      this.contactOpen = true;
+      this.getContactList();
+    },
+    /** 查询联系人列表 */
+    getContactList() {
+      listWxContact(this.contactQueryParams).then(response => {
+        this.contactList = response.rows;
+        this.contactTotal = response.total;
+      });
+    },
+    /** 打开聊天记录弹窗 */
+    handleChatHistory(contactRow) {
+      this.currentContact = contactRow;
+      this.chatQueryParams.pageNum = 1;
+      this.chatQueryParams.accountId = this.contactQueryParams.accountId;
+      this.chatOpen = true;
+      this.getChatList();
+    },
+    /** 查询聊天记录列表 */
+    getChatList() {
+      listWxMsgLog(this.chatQueryParams).then(response => {
+        this.chatList = response.rows;
+        this.chatTotal = response.total;
+      });
+    },
   }
   }
 };
 };
 </script>
 </script>
+
+<style scoped>
+.chat-container {
+  background: #f5f5f5;
+  padding: 16px;
+  max-height: 500px;
+  overflow-y: auto;
+}
+.chat-item {
+  display: flex;
+  margin-bottom: 16px;
+  align-items: flex-start;
+}
+.chat-item.self {
+  justify-content: flex-end;
+}
+.chat-bubble {
+  max-width: 60%;
+  padding: 10px 14px;
+  border-radius: 8px;
+  font-size: 14px;
+  line-height: 1.5;
+  word-break: break-all;
+  position: relative;
+}
+.chat-bubble.left {
+  background: #fff;
+  margin-left: 10px;
+}
+.chat-bubble.left::before {
+  content: '';
+  position: absolute;
+  left: -8px;
+  top: 10px;
+  border-width: 6px 8px 6px 0;
+  border-style: solid;
+  border-color: transparent #fff transparent transparent;
+}
+.chat-bubble.right {
+  background: #95ec69;
+  margin-right: 10px;
+}
+.chat-bubble.right::after {
+  content: '';
+  position: absolute;
+  right: -8px;
+  top: 10px;
+  border-width: 6px 0 6px 8px;
+  border-style: solid;
+  border-color: transparent transparent transparent #95ec69;
+}
+.chat-time {
+  text-align: center;
+  color: #999;
+  font-size: 12px;
+  margin-bottom: 10px;
+}
+</style>