Ver código fonte

蒙牛-绑定成员

三七 1 mês atrás
pai
commit
a033b6c358

+ 28 - 0
src/api/company/companyUser.js

@@ -182,6 +182,34 @@ export function getUserProfile() {
   })
 }
 
+//获取销售绑定的用户列表
+export function getSaleBindUserList(query) {
+  return request({
+    url: '/company/user/getFsUserBySaleId',
+    method: 'get',
+    params: query
+  })
+}
+
+//绑定销售会员关系
+export function bindSaleAndFsUser(data) {
+  return request({
+    url: '/company/user/bindSaleAndFsUser',
+    method: 'post',
+    data: data
+  })
+}
+
+//解绑销售会员关系
+export function unbindSaleAndFsUser(data) {
+  return request({
+    url: '/company/user/unbindSaleAndFsUser',
+    method: 'post',
+    data
+  });
+}
+
+
 // 修改用户个人信息
 export function updateUserProfile(data) {
   return request({

+ 237 - 3
src/views/company/companyUser/index.vue

@@ -248,6 +248,14 @@
                 v-hasPermi="['qw:user:bind']"
               >查或换绑企微</el-button>
 
+              <el-button
+                size="mini"
+                type="text"
+                icon="el-icon-user"
+                @click="handleBindMember(scope.row)"
+                v-hasPermi="['company:user:bindUser']"
+              >绑定员工用户</el-button>
+
               <el-button
                 size="mini"
                 type="text"
@@ -274,7 +282,7 @@
                 :loading="bindCidServerLoading"
                 @click="handleBindCidServer(scope.row)"
               >绑定cid服务</el-button>
-              
+
 
               <el-button v-if="scope.row.userType !== '00'" size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['company:user:edit']">修改</el-button>
               <el-button v-if="scope.row.userType !== '00'" size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['company:user:remove']">删除</el-button>
@@ -704,6 +712,98 @@
       </div>
     </el-dialog>
 
+    <!-- 绑定会员对话框 -->
+    <el-dialog
+      :title="member.title"
+      :visible.sync="member.open"
+      width="800px"
+      append-to-body
+      class="bind-member-dialog"
+    >
+      <!-- 筛选表单 - 优化布局,修复按钮换行问题 -->
+      <el-form
+        :model="memberQueryParams"
+        :inline="true"
+        @submit.native.prevent
+        class="filter-form"
+      >
+        <div style="display: flex; flex-wrap: wrap; gap: 12px; align-items: center;">
+          <el-form-item label="昵称" style="margin-bottom: 0; flex: 1 1 auto; min-width: 160px;">
+            <el-input
+              v-model="memberQueryParams.nickName"
+              placeholder="请输入昵称"
+              clearable
+              @keyup.enter.native="handleMemberQuery"
+              prefix-icon="el-icon-user"
+              style="width: 100%;"
+            />
+          </el-form-item>
+
+          <el-form-item label="手机号" style="margin-bottom: 0; flex: 1 1 auto; min-width: 160px;">
+            <el-input
+              v-model="memberQueryParams.phone"
+              placeholder="请输入手机号"
+              clearable
+              @keyup.enter.native="handleMemberQuery"
+              prefix-icon="el-icon-phone"
+              style="width: 100%;"
+            />
+          </el-form-item>
+
+          <el-form-item style="margin-bottom: 0; flex: 0 0 auto;">
+            <el-button type="primary" icon="el-icon-search" @click="handleMemberQuery" size="mini">搜索</el-button>
+            <el-button icon="el-icon-refresh" @click="resetMemberQuery" size="mini">重置</el-button>
+          </el-form-item>
+        </div>
+      </el-form>
+
+      <!-- 表格区域 -->
+      <div class="table-container" style="margin-top: 16px;">
+        <el-table
+          :data="memberList"
+          height="260"
+          highlight-current-row
+          @current-change="selectMember"
+          v-loading="loading"
+          border
+          stripe
+          size="small"
+        >
+          <el-table-column property="userId" label="ID" width="70" align="center"></el-table-column>
+          <el-table-column property="nickName" label="昵称" min-width="130" show-overflow-tooltip></el-table-column>
+          <el-table-column property="phone" label="手机号" width="130" align="center"></el-table-column>
+          <el-table-column property="status" label="绑定状态" width="100" align="center">
+            <template slot-scope="scope">
+              <el-tag
+                :type="scope.row.status === 1 ? 'success' : 'info'"
+                size="small"
+                effect="light"
+              >
+                {{ scope.row.status === 1 ? '已绑定' : '未绑定' }}
+              </el-tag>
+            </template>
+          </el-table-column>
+        </el-table>
+
+        <!-- 分页组件 -->
+        <!-- 修改分页组件,添加判断条件 -->
+        <pagination
+          v-show="memberTotal > 0"
+          :total="memberTotal"
+          :page.sync="memberQueryParams.pageNum"
+          :limit.sync="memberQueryParams.pageSize"
+          @pagination="handlePagination"
+          style="margin-top: 10px; text-align: center;"
+        />
+      </div>
+
+      <!-- 底部按钮 -->
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="cancelBindMember" size="small">取 消</el-button>
+        <el-button type="primary" @click="confirmBindMember" size="small">确 定</el-button>
+      </div>
+    </el-dialog>
+
   </div>
 </template>
 
@@ -737,7 +837,7 @@ import { getMyQwUserList,getMyQwCompanyList } from "@/api/qw/user";
 import  selectUser  from "@/views/company/components/selectQwUser.vue";
 import { getConfigByKey } from "@/api/company/companyConfig";
 import axios from "axios";
-import {addCodeUrl} from "../../../api/company/companyUser";
+import {addCodeUrl, getSaleBindUserList} from "../../../api/company/companyUser";
 import selectDoctor from "@/views/qw/user/selectDoctor.vue";
 import {bindCidServer,unbindCidServer} from "@/api/company/companyAiWorkflowServer"
 export default {
@@ -745,7 +845,23 @@ export default {
   components: {selectDoctor, Treeselect ,selectUser},
   data() {
     return {
+      selectedMember: null,
+      currentCompanyId: null,
       bindCidServerLoading:false,
+      memberList: [],
+      member: {
+        open: false,
+        title: "绑定会员"
+      },
+      memberTotal: 0,
+      // 添加筛选参数
+      memberQueryParams: {
+        nickName: null,
+        phone: null,
+        pageNum: 1,
+        pageSize: 10
+      },
+
       doctor: {
         open: false,
         title: '绑定医生'
@@ -953,6 +1069,7 @@ export default {
       boundUsersList: [],
       bindUserLoading: false,
     };
+
   },
   watch: {
     // 根据名称筛选部门树
@@ -1008,6 +1125,123 @@ export default {
       }
     },
 
+
+    /**
+     * 绑定会员按钮操作
+     */
+    handleBindMember(row) {
+      this.currentCompanyId = row.userId;
+      // 重置筛选参数
+      this.memberQueryParams = {
+        nickName: null,
+        phone: null,
+        pageNum: 1,    // 重置为第一页
+        pageSize: 10   // 保持每页数量
+      };
+      this.selectedMember = null;
+      this.member.open = true;
+      this.getMemberList();
+    },
+
+
+    /**
+     * 获取会员列表
+     */
+    /**
+     * 获取会员列表
+     */
+    getMemberList() {
+      // 调用指定的接口获取会员列表
+      getSaleBindUserList({
+        pageNum: this.memberQueryParams.pageNum,
+        pageSize: this.memberQueryParams.pageSize,
+        nickName: this.memberQueryParams.nickName,
+        phone: this.memberQueryParams.phone
+      })
+        .then(response => {
+          this.memberList = response.rows || [];
+          this.memberTotal = response.total || 0;
+        })
+        .catch(error => {
+          console.error('获取会员列表失败:', error);
+          this.$message.error('获取会员列表失败');
+        });
+    },
+    /**
+     * 会员搜索按钮操作
+     */
+    handleMemberQuery() {
+      this.memberQueryParams.pageNum = 1;
+      this.getMemberList();
+    },
+
+    /**
+     * 会员重置按钮操作
+     */
+    resetMemberQuery() {
+      this.memberQueryParams = {
+        nickName: null,
+        phone: null,
+        pageNum: 1,
+        pageSize: 10
+      };
+      this.getMemberList();
+    },
+
+
+    /**
+     * 选择会员
+     */
+    selectMember(member) {
+      if (member) {
+        this.selectedMember = member;
+      }
+    },
+
+
+    /**
+     * 确认绑定会员
+     */
+    confirmBindMember() {
+      if (!this.selectedMember) {
+        this.$message.warning('请选择要绑定的会员');
+        return;
+      }
+      // 这里需要根据实际接口调整参数
+      const bindData = {
+        companyUserId: this.currentCompanyId,
+        userId: this.selectedMember.userId // 使用实际的用户ID字段
+      };
+
+      // 发起绑定请求
+      bindSaleAndFsUser(bindData).then(response => {
+        if (response.code === 200) {
+          this.$message.success('绑定会员成功');
+          this.cancelBindMember();
+          this.getList(); // 刷新当前页面列表
+        } else {
+          this.$message.error(response.msg || '绑定失败');
+        }
+      })
+        .catch(error => {
+          console.error('绑定会员失败:', error);
+          this.$message.error('绑定会员失败');
+        });
+    },
+    /**
+     * 取消绑定会员
+     */
+    cancelBindMember() {
+      this.member.open = false;
+      this.memberList = [];
+      this.selectedMember = null;
+      this.currentCompanyId = null;
+      this.memberQueryParams = {
+        nickName: null,
+        phone: null
+      };
+    },
+
     // 添加处理 selectUser 关闭的方法
     handleSelectUserClose() {
       this.user.open = false
@@ -1759,7 +1993,7 @@ export default {
         this.$message.success('解绑成功');
         this.getList();
       }).catch(res=>{
-        this.bindCidServerLoading = false; 
+        this.bindCidServerLoading = false;
         console.log(res)
       });
     },

+ 519 - 1
src/views/company/companyUser/profile/index.vue

@@ -36,6 +36,62 @@
                 <div class="pull-right">{{ user.createTime }}</div>
               </li>
             </ul>
+            <!-- 操作区域 - 优化布局 -->
+            <div class="action-section">
+              <!-- 绑定会员按钮 -->
+              <el-button
+                v-if="!user.fsUserId"
+                type="primary"
+                icon="el-icon-user"
+                @click="handleBindMember"
+                class="action-btn"
+                :loading="bindLoading"
+              >绑定会员</el-button>
+
+              <!-- 已绑定会员列表 -->
+              <div v-if="user.fsUserIdArray && user.fsUserIdArray.length > 0" class="bound-members">
+                <div class="bound-header">
+                  <el-tag type="success" effect="dark" size="small">已绑定会员</el-tag>
+                  <span class="bound-count">{{ user.fsUserIdArray.length }}个</span>
+                </div>
+                <div class="member-list">
+                  <div
+                    v-for="(fsUserId, index) in user.fsUserIdArray"
+                    :key="index"
+                    class="member-item"
+                  >
+                  <span class="member-id">
+                    <i class="el-icon-user-solid"></i>
+                    {{ fsUserId }}
+                  </span>
+                    <el-button
+                      size="mini"
+                      type="danger"
+                      icon="el-icon-delete"
+                      @click="handleUnbindSpecificMember(fsUserId)"
+                      circle
+                      title="解绑"
+                    ></el-button>
+                  </div>
+                </div>
+              </div>
+
+              <!-- 微信服务号绑定 -->
+              <div v-if="needWxTemplateMsg" class="wechat-section">
+                <div v-if="user.wechatBindStatus" class="wechat-bound">
+                  <el-tag type="success" effect="dark" size="small">
+                    <i class="el-icon-wechat"></i> 已绑定服务号通知
+                  </el-tag>
+                </div>
+                <el-button
+                  v-else
+                  type="primary"
+                  @click="openWechatBindDialog"
+                  icon="el-icon-wechat"
+                  class="wechat-btn"
+                >订阅服务号通知</el-button>
+              </div>
+            </div>
             <div class="text-center" style="margin-top: 20px;" v-if="needWxTemplateMsg">
               <div v-if="user.wechatBindStatus">
                 <el-tag type="success">已绑定服务号通知</el-tag>
@@ -86,7 +142,7 @@
 import userAvatar from "./userAvatar";
 import userInfo from "./userInfo";
 import resetPwd from "./resetPwd";
-import { getUserProfile } from "@/api/company/companyUser";
+import { getUserProfile,getSaleBindUserList, bindSaleAndFsUser, unbindSaleAndFsUser } from "@/api/company/companyUser";
 import { getWechatBindQrcode, checkWechatBindStatus } from "@/api/wechat";
 export default {
   name: "Profile",
@@ -101,6 +157,27 @@ export default {
       wechatQrcode: "",
       wechatBindTimer: null,
       needWxTemplateMsg: false,
+
+      bindLoading: false,
+      confirmLoading: false,
+      // 绑定会员相关数据
+      member: {
+        open: false,
+        title: "绑定会员"
+      },
+      memberList: [],
+      selectedMember: null,
+      currentCompanyId: null,
+      memberTotal: 0,
+      loading: false,
+      // 添加筛选参数
+      memberQueryParams: {
+        nickName: null,
+        phone: null,
+        userId: null,
+        pageNum: 1,
+        pageSize: 10
+      },
     };
   },
   created() {
@@ -110,6 +187,80 @@ export default {
     this.getUser();
   },
   methods: {
+
+    handleBindMember() {
+      this.currentCompanyId = this.user.userId;
+      this.resetMemberQuery();
+      this.selectedMember = null;
+      this.member.open = true;
+    },
+
+    resetMemberQuery() {
+      this.memberQueryParams = {
+        nickName: null,
+        phone: null,
+        userId: null,
+        pageNum: 1,
+        pageSize: 10
+      };
+      this.getMemberList();
+    },
+
+
+    getMemberList() {
+      this.loading = true;
+      getSaleBindUserList({
+        pageNum: this.memberQueryParams.pageNum,
+        pageSize: this.memberQueryParams.pageSize,
+        nickName: this.memberQueryParams.nickName,
+        phone: this.memberQueryParams.phone,
+        userId: this.memberQueryParams.userId
+      })
+        .then(response => {
+          this.memberList = response.rows || [];
+          this.memberTotal = response.total || 0;
+        })
+        .catch(error => {
+          console.error('获取会员列表失败:', error);
+          this.$message.error('获取会员列表失败');
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+
+    handleUnbindSpecificMember(fsUserId) {
+      this.$confirm(`确定要解除与会员 ${fsUserId} 的绑定吗?`, "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      })
+        .then(() => {
+          const unbindData = {
+            companyUserId: this.user.userId,
+            userId: fsUserId
+          };
+
+          unbindSaleAndFsUser(unbindData)
+            .then(response => {
+              if (response.code === 200) {
+                this.$message.success("解绑成功");
+                this.getUser();
+              } else {
+                this.$message.error(response.msg || "解绑失败");
+              }
+            })
+            .catch(error => {
+              console.error("解绑失败:", error);
+              this.$message.error("解绑失败");
+            });
+        })
+        .catch(() => {
+          this.$message.info("已取消解绑");
+        });
+    },
+
+
     getUser() {
       getUserProfile().then(response => {
         this.user = response.data;
@@ -146,3 +297,370 @@ export default {
   }
 };
 </script>
+<style scoped>
+/* 个人信息卡片样式 */
+.profile-card {
+  border-radius: 8px;
+  overflow: hidden;
+}
+
+.profile-card :deep(.el-card__header) {
+  padding: 15px 20px;
+  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+  border-bottom: none;
+}
+
+.card-header {
+  color: white;
+  font-weight: 500;
+  display: flex;
+  align-items: center;
+}
+
+.card-header i {
+  margin-right: 8px;
+  font-size: 16px;
+}
+
+/* 头像区域 */
+.avatar-section {
+  text-align: center;
+  padding: 24px 20px 16px;
+  background: linear-gradient(135deg, #667eea10 0%, #764ba210 100%);
+}
+
+.user-name {
+  margin: 12px 0 0;
+  font-size: 18px;
+  font-weight: 600;
+  color: #303133;
+}
+
+/* 信息列表 */
+.info-list {
+  list-style: none;
+  padding: 0;
+  margin: 0;
+}
+
+.info-item {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 12px 20px;
+  border-bottom: 1px solid #f0f0f0;
+  transition: background-color 0.3s;
+}
+
+.info-item:hover {
+  background-color: #f5f7fa;
+}
+
+.info-item:last-child {
+  border-bottom: none;
+}
+
+.info-label {
+  color: #606266;
+  font-size: 14px;
+  display: flex;
+  align-items: center;
+}
+
+.info-label svg {
+  margin-right: 8px;
+  width: 16px;
+  height: 16px;
+  color: #909399;
+}
+
+.info-value {
+  color: #303133;
+  font-weight: 500;
+  font-size: 14px;
+}
+
+/* 操作区域 */
+.action-section {
+  padding: 20px;
+  background-color: #fafbfc;
+  border-top: 1px solid #e4e7ed;
+}
+
+.action-btn {
+  width: 100%;
+  margin-bottom: 16px;
+}
+
+/* 已绑定会员列表 */
+.bound-members {
+  margin-top: 16px;
+}
+
+.bound-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 12px;
+}
+
+.bound-count {
+  font-size: 12px;
+  color: #909399;
+  background-color: #f0f2f5;
+  padding: 2px 8px;
+  border-radius: 10px;
+}
+
+.member-list {
+  max-height: 200px;
+  overflow-y: auto;
+  border: 1px solid #e4e7ed;
+  border-radius: 4px;
+  background-color: white;
+}
+
+.member-item {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 8px 12px;
+  border-bottom: 1px solid #f0f0f0;
+  transition: background-color 0.3s;
+}
+
+.member-item:hover {
+  background-color: #f5f7fa;
+}
+
+.member-item:last-child {
+  border-bottom: none;
+}
+
+.member-id {
+  font-size: 13px;
+  color: #606266;
+  display: flex;
+  align-items: center;
+}
+
+.member-id i {
+  margin-right: 6px;
+  color: #409EFF;
+}
+
+/* 微信服务号区域 */
+.wechat-section {
+  margin-top: 16px;
+}
+
+.wechat-bound {
+  text-align: center;
+}
+
+.wechat-btn {
+  width: 100%;
+}
+
+/* 右侧卡片样式 */
+.content-card {
+  border-radius: 8px;
+}
+
+.content-card :deep(.el-card__header) {
+  padding: 15px 20px;
+  background-color: #fafbfc;
+  border-bottom: 1px solid #e4e7ed;
+}
+
+/* 绑定会员对话框样式 - 无背景色 */
+.bind-member-dialog :deep(.el-dialog__body) {
+  padding: 20px 24px;
+}
+
+/* 筛选表单 - 无背景色,优化排版 */
+.filter-container {
+  margin-bottom: 16px;
+  padding: 0 4px;
+}
+
+.filter-row {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+}
+
+.filter-buttons {
+  text-align: right;
+  white-space: nowrap;
+}
+
+.filter-buttons .el-button {
+  margin-left: 8px;
+}
+
+.filter-buttons .el-button:first-child {
+  margin-left: 0;
+}
+
+/* 表格区域 */
+.table-section {
+  border: 1px solid #e4e7ed;
+  border-radius: 6px;
+  overflow: hidden;
+}
+
+.member-table :deep(th) {
+  background-color: #f2f6fc;
+  color: #303133;
+  font-weight: 600;
+  font-size: 13px;
+}
+
+.status-tag {
+  min-width: 70px;
+}
+
+.status-tag i {
+  margin-right: 4px;
+}
+
+.nickname-cell, .phone-cell {
+  display: flex;
+  align-items: center;
+  gap: 4px;
+}
+
+.nickname-cell i, .phone-cell i {
+  color: #909399;
+  font-size: 12px;
+}
+
+.no-data {
+  color: #c0c4cc;
+}
+
+/* 分页样式 - 支持每页条数选择 */
+.pagination-wrapper {
+  padding: 16px;
+  background-color: #ffffff;
+  border-top: 1px solid #e4e7ed;
+  display: flex;
+  justify-content: flex-end;
+}
+
+.custom-pagination :deep(.el-pagination) {
+  padding: 0;
+}
+
+.custom-pagination :deep(.el-pagination__sizes) {
+  margin-right: 16px;
+}
+
+.empty-data {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  padding: 40px 0;
+  color: #909399;
+  background-color: #ffffff;
+}
+
+.empty-data i {
+  font-size: 40px;
+  margin-bottom: 8px;
+  color: #dcdfe6;
+}
+
+.dialog-footer {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding-top: 10px;
+}
+
+.selected-info {
+  font-size: 13px;
+  color: #606266;
+  background-color: #f0f9eb;
+  padding: 6px 12px;
+  border-radius: 4px;
+  border: 1px solid #e1f3d8;
+}
+
+/* 微信对话框样式 */
+.wechat-dialog :deep(.el-dialog__body) {
+  padding: 30px 20px;
+}
+
+.qrcode-container {
+  text-align: center;
+}
+
+.qrcode-img {
+  width: 260px;
+  height: 260px;
+  border: 1px solid #e4e7ed;
+  padding: 10px;
+  border-radius: 8px;
+  background-color: white;
+}
+
+.qrcode-loading {
+  width: 260px;
+  height: 260px;
+  margin: 0 auto;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  background-color: #f5f7fa;
+  border-radius: 8px;
+  color: #909399;
+}
+
+.qrcode-loading i {
+  font-size: 32px;
+  margin-bottom: 10px;
+}
+
+.qrcode-tip {
+  margin-top: 16px;
+  color: #606266;
+  font-size: 14px;
+}
+
+.qrcode-tip i {
+  color: #07C160;
+  margin-right: 6px;
+}
+
+/* 响应式调整 */
+@media (max-width: 768px) {
+  .filter-container .el-col {
+    width: 100%;
+    margin-bottom: 8px;
+  }
+
+  .filter-buttons {
+    text-align: left;
+    margin-top: 8px;
+  }
+
+  .filter-buttons .el-button {
+    margin-left: 0;
+    margin-right: 8px;
+  }
+
+  .dialog-footer {
+    flex-direction: column;
+    gap: 12px;
+  }
+
+  .selected-info {
+    width: 100%;
+    text-align: center;
+  }
+}
+</style>

+ 1 - 1
src/views/qw/contactWay/index.vue

@@ -194,7 +194,7 @@
         </el-form-item>
         <el-form-item label="客服类型" prop="userType" >
           <el-radio-group v-model="form.userType">
-             <el-radio :key="1":label="1" >全天在线</el-radio>
+<!--             <el-radio :key="1":label="1" >全天在线</el-radio>-->
              <el-radio :key="2":label="2" >自动上下线</el-radio>
              </el-radio-group>
         </el-form-item>