Bladeren bron

Merge remote-tracking branch 'origin/金牛明医' into 金牛明医

yh 3 weken geleden
bovenliggende
commit
4360587702

+ 24 - 0
src/api/qw/externalContact.js

@@ -9,6 +9,30 @@ export function listExternalContact(query) {
   })
 }
 
+// 查询重粉用户看课记录
+export function getWatchLogList(query) {
+  return request({
+    url: '/qw/externalContact/getWatchLogList',
+    method: 'get',
+    params: query
+  })
+}
+// 查询企业微信客户列表(重粉)
+export function listRepeatExternalContact(query) {
+  return request({
+    url: '/qw/externalContact/listRepeat',
+    method: 'get',
+    params: query
+  })
+}
+// 导出企业微信客户列表(重粉)
+export function exportRepeatExternalContact(data) {
+  return request({
+    url: '/qw/externalContact/exportRepeatExternalContact',
+    method: 'post',
+    data: data
+  })
+}
 // 查询企业微信客户列表
 export function getRepeat(query) {
   return request({

+ 13 - 0
src/api/qw/qwUser.js

@@ -16,3 +16,16 @@ export function  getQwUserInfo(query) {
     params: query
   })
 }
+
+/**
+ * 模糊查询企微用户列表
+ * @param params 参数
+ * @returns {*}
+ */
+export function getQwUserListLikeName(params) {
+  return request({
+    url: '/qw/user/getQwUserListLikeName',
+    method: 'get',
+    params: params
+  })
+}

+ 1 - 1
src/views/components/his/storePayDetails.vue

@@ -8,7 +8,7 @@
         支付信息
       </div>
 
-        <div class="" v-if="item.status==0" style="float: right;margin: 5px;">
+        <div class=""  style="float: right;margin: 5px;">
            <el-button size="mini" @click="getPayStatus()" >同步支付状态</el-button>
         </div>
         <div class="" v-if="item.status>=0" style="float: right; margin: 5px;" v-hasPermi="['his:storePayment:refund']" >

+ 3 - 3
src/views/his/adv/index.vue

@@ -301,9 +301,9 @@ export default {
         showType: [
           { required: true, message: "显示类别不能为空", trigger: "blur" }
         ],
-        activeId: [
-          { required: true, message: "活动不能为空", trigger: "blur" }
-        ],
+        // activeId: [
+        //   { required: true, message: "活动不能为空", trigger: "blur" }
+        // ],
       }
     };
   },

+ 40 - 1
src/views/his/appVersion/index.vue

@@ -118,7 +118,7 @@
         <el-form-item label="更新描述" prop="note">
           <el-input v-model="form.note" type="textarea" placeholder="请输入内容" />
         </el-form-item>
-        <el-form-item label="安装包上传" prop="url" v-if="form.appType!==4">
+        <el-form-item label="安装包上传(apk)" prop="url" v-if="form.appType!==4">
           <el-upload
             accept=".apk"
             class="upload-demo"
@@ -135,6 +135,23 @@
             <div slot="tip" class="el-upload__tip">只能上传APK文件</div>
           </el-upload>
         </el-form-item>
+        <el-form-item label="安装包上传(wgt)" prop="wgtUrl" v-if="form.appType!==4">
+          <el-upload
+            accept=".wgt"
+            class="upload-demo"
+            :action="uploadUrl"
+            :before-upload="beforeUpload"
+            :on-success="handleWgtSuccess"
+            :on-preview="handlePreview"
+            :on-remove="handleWgtRemove"
+            :before-remove="beforeRemove"
+            :limit="1"
+            :on-exceed="handleWgtExceed"
+            :file-list="fileWgtList">
+            <el-button size="small" type="primary">点击上传</el-button>
+            <div slot="tip" class="el-upload__tip">只能上传WGT文件</div>
+          </el-upload>
+        </el-form-item>
         <el-form-item label="压缩包上传" prop="url" v-if="form.appType===4">
           <el-upload
             accept=".zip"
@@ -155,6 +172,9 @@
         <el-form-item label="下载地址" prop="url" v-if="form.url!==null">
           <el-input v-model="form.url" readonly />
         </el-form-item>
+        <el-form-item label="wgt下载地址" prop="url" v-if="form.wgtUrl!==null">
+          <el-input v-model="form.wgtUrl" readonly />
+        </el-form-item>
 
         <el-form-item label="baidu安装包上传" prop="baiduUrl" v-if="form.appType===3">
           <el-upload
@@ -250,6 +270,7 @@ export default {
       // APP 类型 1医生端 2药师端字典
       appTypeOptions: [],
        fileList:[],
+       fileWgtList:[],
       fileList1:[],
       // 查询参数
       queryParams: {
@@ -313,6 +334,16 @@ export default {
           background: 'rgba(0, 0, 0, 0.7)'
         });
     },
+    handleWgtSuccess(res, file) {
+      this.myloading.close();
+      if(res.code==200){
+        this.form.wgtUrl=res.url;
+      }
+      else{
+        this.msgError(res.msg);
+      }
+
+    },
     handleSuccess(res, file) {
         this.myloading.close();
         if(res.code==200){
@@ -322,6 +353,11 @@ export default {
           this.msgError(res.msg);
         }
 
+    },
+    handleWgtRemove(file, fileList) {
+      console.log(this.fileWgtList);
+      this.form.wgtUrl=null;
+
     },
     handleRemove(file, fileList) {
       console.log(this.fileList);
@@ -335,6 +371,9 @@ export default {
     handleExceed(files, fileList) {
       this.$message.warning(`当前限制选择 1 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
     },
+    handleWgtExceed(files, fileWgtList) {
+      this.$message.warning(`当前限制选择 1 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileWgtList.length} 个文件`);
+    },
     beforeRemove(file, fileList) {
 
       return this.$confirm(`确定移除 ${ file.name }?`);

+ 860 - 0
src/views/his/user/qwUser.vue

@@ -0,0 +1,860 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="企微公司" prop="corpId">
+        <el-select v-model="queryParams.corpId" placeholder="企微公司"  size="small" @change="updateCorpId()" filterable clearable>
+          <el-option
+            v-for="dict in qwCompanyList"
+            :key="dict.corpId"
+            :label="dict.corpName"
+            :value="dict.corpId"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="销售公司" prop="companyId">
+        <el-select v-model="queryParams.companyId" placeholder="销售公司"  size="small"  filterable clearable>
+          <el-option
+            v-for="dict in salesCompanyList"
+            :key="dict.companyId"
+            :label="dict.companyName"
+            :value="dict.companyId"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="销售昵称" prop="qwUserName">
+        <el-input
+          v-model="queryParams.qwUserName"
+          placeholder="请输入销售企微昵称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+          @input="searchQwUser"
+          @focus="showQwUserDropdown = true"
+          @blur="hideDropdownWithDelay"
+          @clear="onQwUserNameClear"
+        />
+        <!-- 下拉建议 -->
+        <div v-if="showQwUserDropdown && qwUserSuggestions.length > 0" class="suggestion-box"  @scroll="handleScroll">
+          <div
+            v-for="item in qwUserSuggestions"
+            :key="item.dictValue"
+            class="suggestion-item"
+            @click="selectQwUser(item.dictValue,item.dictLabel)"
+          >
+            {{ item.dictLabel }}
+          </div>
+        </div>
+      </el-form-item>
+      <el-form-item label="所属销售" prop="companyUser">
+        <el-input
+          v-model="queryParams.companyUser"
+          placeholder="请输入昵称或者手机号"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="客户名称" prop="name">
+        <el-input
+          v-model="queryParams.name"
+          placeholder="请输入客户名称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+
+
+
+      <el-form-item label="性别" prop="gender">
+        <el-select v-model="queryParams.gender" placeholder="性别" clearable size="small">
+          <el-option
+            v-for="dict in genderOptions"
+            :key="dict.dictValue"
+            :label="dict.dictLabel"
+            :value="dict.dictValue"
+          />
+        </el-select>
+      </el-form-item>
+
+
+
+
+
+      <el-form-item label="电话号码" prop="remarkMobiles">
+        <el-input
+          v-model="queryParams.remarkMobiles"
+          placeholder="请输入备注电话号码"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+
+      <el-form-item label="来源" prop="addWay">
+
+        <el-select v-model="queryParams.addWay" placeholder="来源" clearable size="small">
+          <el-option
+            v-for="dict in addWayOptions"
+            :key="dict.dictValue"
+            :label="dict.dictLabel"
+            :value="dict.dictValue"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="状态" prop="status">
+
+        <el-select v-model="queryParams.status" placeholder="状态" clearable size="small">
+          <el-option
+            v-for="dict in statusOptions"
+            :key="dict.dictValue"
+            :label="dict.dictLabel"
+            :value="dict.dictValue"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="转接状态" prop="addWay">
+
+        <el-select v-model="queryParams.transferStatus" placeholder="转接状态" clearable size="small">
+          <el-option
+            v-for="dict in transferStatusOptions"
+            :key="dict.dictValue"
+            :label="dict.dictLabel"
+            :value="dict.dictValue"
+          />
+        </el-select>
+      </el-form-item>
+
+
+      <el-form-item label="备注" prop="remark">
+        <el-input
+          v-model="queryParams.remark"
+          placeholder="请输入备注"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+
+      <el-form-item label="添加时间" prop="createTime">
+        <el-date-picker
+          v-model="createTime"
+          size="small"
+          style="width: 215px"
+          value-format="yyyy-MM-dd HH:mm:ss"
+          type="datetimerange"
+          range-separator="-"
+          start-placeholder="开始"
+          end-placeholder="结束"
+          @change="change"
+
+        ></el-date-picker>
+      </el-form-item>
+      <el-form-item label="流失时间" prop="lossTime">
+        <el-date-picker clearable size="small"
+          v-model="queryParams.lossTime"
+          type="date"
+          value-format="yyyy-MM-dd"
+          placeholder="选择流失时间">
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item label="删除时间" prop="delTime">
+        <el-date-picker clearable size="small"
+          v-model="queryParams.delTime"
+          type="date"
+          value-format="yyyy-MM-dd"
+          placeholder="选择删除时间">
+        </el-date-picker>
+      </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="warning"
+          plain
+          icon="el-icon-download"
+          size="mini"
+          :loading="exportLoading"
+          @click="handleExport"
+          v-hasPermi="['his:user:exportRepeat']"
+        >导出重粉记录</el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="externalContactList" @selection-change="handleSelectionChange" border>
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="企微客户ID" align="center" prop="id" width="100px"/>
+      <el-table-column label="企微客户头像" align="center" prop="avatar" width="100px">
+        <template slot-scope="scope">
+          <el-popover
+            placement="right"
+            title=""
+            trigger="hover">
+            <img slot="reference" :src="scope.row.avatar" width="60px">
+            <img :src="scope.row.avatar" style="max-width: 200px;">
+          </el-popover>
+        </template>
+      </el-table-column>
+      <el-table-column label="企微客户名称"  prop="name" width="110px"/>
+      <el-table-column label="销售企微昵称" align="center" prop="qwUserName" width="120px"/>
+      <el-table-column label="企微部门" align="center" prop="departmentName" width="120px"/>
+      <el-table-column label="性别" align="center" prop="gender">
+        <template slot-scope="scope">
+          <dict-tag :options="genderOptions" :value="scope.row.gender"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="备注" align="center" prop="remark" />
+      <el-table-column label="状态" align="center" prop="status" width="120px" >
+        <template slot-scope="scope">
+          <dict-tag :options="statusOptions" :value="scope.row.status"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="添加时间" align="center" prop="createTime" width="100px" />
+      <el-table-column label="流失时间" align="center" prop="lossTime" width="100px" />
+      <el-table-column label="删除时间" align="center" prop="delTime" width="100px" />
+      <el-table-column label="注册时间" align="center" prop="registerTime" width="100px" />
+      <el-table-column label="备注电话号码" align="center" prop="remarkMobiles" width="150px">
+        <template slot-scope="scope">
+          <div v-for="i in JSON.parse(scope.row.remarkMobiles)" :key="i">{{i}}</div>
+        </template>
+      </el-table-column>
+
+      <el-table-column label="转接状态" align="center" prop="transferStatus" width="100px" >
+        <template slot-scope="scope">
+          <dict-tag :options="transferStatusOptions" :value="scope.row.transferStatus"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="重粉看课历史" width="100px" align="center" fixed="right">
+        <template slot-scope="scope">
+          <div v-if="scope.row.fsUserId">
+            <el-tag type="success" v-if="scope.row.userRepeat == 0">正常</el-tag>
+            <el-tag type="danger" v-if="scope.row.userRepeat == 1">重粉</el-tag>
+            <el-button
+              size="mini"
+              type="text"
+              @click="showLog(scope.row)"
+            >重粉看课历史
+            </el-button>
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column label="是否绑定会员" width="100px" align="center" fixed="right">
+        <template slot-scope="scope">
+          <el-tag v-if="scope.row.fsUserId" >已绑定</el-tag>
+          <el-tag v-else type="info"> 未绑定</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="120px" fixed="right">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            @click="handledetails(scope.row)"
+            v-if="scope.row.fsUserId"
+          >
+            <span>会员详情</span>
+          </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-drawer title="重粉看课历史" :visible.sync="log.open" size="75%" append-to-body>
+      <div style="padding: 10px">
+        <el-form :model="log.queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px">
+          <el-form-item label="所属项目" prop="project">
+            <el-select v-model="log.queryParams.project" placeholder="请选择项目" filterable clearable size="small">
+              <el-option
+                v-for="dict in projectOptions"
+                :key="dict.dictValue"
+                :label="dict.dictLabel"
+                :value="dict.dictValue"
+              />
+            </el-select>
+          </el-form-item>
+
+          <el-form-item label="课程" prop="courseId">
+            <el-select filterable v-model="log.queryParams.courseId" placeholder="请选择课程" clearable size="small"
+                       @change="courseChange(log.queryParams.courseId)">
+              <el-option
+                v-for="dict in courseLists"
+                :key="dict.dictValue"
+                :label="dict.dictLabel"
+                :value="dict.dictValue"
+              />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="小节" prop="videoId">
+            <el-select filterable v-model="log.queryParams.videoId" placeholder="请选择小节" clearable size="small">
+              <el-option
+                v-for="dict in videoList"
+                :key="dict.dictValue"
+                :label="dict.dictLabel"
+                :value="dict.dictValue"
+              />
+            </el-select>
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQueryWatchLog">搜索</el-button>
+          </el-form-item>
+        </el-form>
+        <el-table v-loading="log.loading" :data="log.list">
+          <el-table-column label="编号" align="center" prop="id"/>
+          <el-table-column label="所属企微主体" align="center" prop="corpName"/>
+          <el-table-column label="所属企微" align="center" prop="qwUserName"/>
+          <!--          <el-table-column label="企微" align="center" prop="qwUserName"/>-->
+          <el-table-column label="项目" align="center" prop="projectName"/>
+          <el-table-column label="课程" align="center" prop="courseName"/>
+          <el-table-column label="小节" align="aligner" prop="videoName"/>
+          <el-table-column label="记录时间" align="center" prop="createTime"/>
+          <el-table-column label="是否完课" align="center" prop="logType">
+            <template slot-scope="scope">
+              <el-tag v-if="scope.row.logType == 2" type="success">已完课</el-tag>
+              <el-tag v-else type="success">未完课</el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column label="完课时间" align="center" prop="finishTime"/>
+        </el-table>
+
+        <pagination
+          v-show="log.total>0"
+          :total="log.total"
+          :page.sync="log.queryParams.pageNum"
+          :limit.sync="log.queryParams.pageSize"
+          @pagination="logList"
+        />
+      </div>
+    </el-drawer>
+
+    <el-drawer
+      :with-header="false"
+      size="75%"
+      :title="show.title" :visible.sync="show.open">
+      <!--         <userDetails  ref="userDetails" />-->
+      <userDetailsByNew  ref="userDetailsByNew" />
+    </el-drawer>
+  </div>
+</template>
+
+<script>
+import { listUser, getUser, delUser, addUser, updateUser, exportUser, addPoint,checkIsSales } from "@/api/his/user";
+import { getCompanyUserList, changeCompanyUser, getCompanyList } from '@/api/company/companyUser';
+import userDetails from '../../components/his/userDetails.vue';
+import userDetailsByNew from './userDetails.vue';
+import {listQwCompany} from "@/api/qw/qwCompany";
+import {getQwUserListLikeName} from "@/api/qw/qwUser";
+import { listRepeatExternalContact, getWatchLogList, exportRepeatExternalContact } from '@/api/qw/externalContact'
+import {courseList} from "@/api/course/courseRedPacketLog";
+
+export default {
+  name: "qwUser",
+  components: {userDetails,userDetailsByNew},
+  data() {
+    return {
+      userIds: [],
+      projectOptions: [],
+      courseLists: [],
+      videoList: [],
+      //重粉记录的参数
+      log: {
+        open: false,
+        loading: true,
+        list: [],
+        total: 0,
+        queryParams: {
+          pageNum: 1,
+          pageSize: 10,
+          externalUserId: null,
+          fsUserId: null,
+          projectId: null,
+          courseId: null,
+          videoId: null,
+        },
+      },
+      sTime:null,
+      eTime:null,
+      createTime:null,
+      // 企业微信客户表格数据
+      externalContactList: [],
+      // 性别字典
+      genderOptions: [],
+      // 来源字典
+      addWayOptions: [],
+      statusOptions:[],
+      transferStatusOptions:[],
+      isBindMiniOptions:[
+        {dictLabel:"已绑定",dictValue:'isBindMini'},
+        {dictLabel:"未绑定",dictValue:'noBindMini'},
+      ],
+      qwUserSuggestions: [],       // 已展示的数据
+      showQwUserDropdown: false,   // 控制下拉框显示
+      qwUserLoading: false,        // 加载状态
+      qwUserNoMore: false,         // 是否还有更多数据
+      qwUserPageNum: 1,            // 当前页码
+      qwUserPageSize: 10,          // 每页数量
+      qwUserTotal: 0,               // 总数
+      salesCompanyList:[],
+      companyList:[],
+      qwCompanyList:[],
+      // 提交加载状态
+      submitLoading: false,
+
+      // 确认对话框
+      confirmDialog: {
+        visible: false,
+        // 暂存表单数据,等待确认后提交
+        pendingForm: null
+      },
+
+      // 记录状态是否从非禁用改为禁用
+      isChangingToDisable: false,
+
+      userIsPromoterOptions:[],
+      companyName: null,
+      companyUserNickName: null,
+      companyOptions: [],
+      companyUserOptions: [],
+      show:{
+              title:"用户详情",
+              open:false,
+            },
+      userOptions: [],
+      // 用户等级
+      userLevelOptions:[],
+      // 遮罩层
+      loading: true,
+      // 导出遮罩层
+      exportLoading: false,
+      // 选中数组
+      ids: [],
+      orOptions:[],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        nickName: null,
+        avatar: null,
+        phone: null,
+        phoneMk: null,
+        integral: null,
+        status: null,
+        tuiUserId: null,
+        tuiTime: null,
+        tuiUserCount: null,
+        maOpenId: null,
+        mpOpenId: null,
+        unionId: null,
+        isDel: null,
+        userCode: null,
+        lastIp: null,
+        balance: null,
+        sTime:null,
+        eTime:null,
+        isBuy:null,
+        source:null,
+        companyName: null,
+        userId: null
+      },
+
+    }
+  },
+  created() {
+    this.getList();
+    listQwCompany().then(response => {
+      this.qwCompanyList = response.rows;
+    });
+
+    getCompanyList().then(response => {
+      this.companyList = response.data;
+    });
+    this.getDicts("sys_qw_transfer_status").then(response => {
+      this.transferStatusOptions = response.data;
+    });
+    this.getDicts("sys_qw_external_contact_status").then(response => {
+      this.statusOptions = response.data;
+    });
+    this.getDicts("sys_qw_externalContact_addWay").then(response => {
+      this.addWayOptions = response.data;
+    });
+    this.getDicts("sys_sex").then(response => {
+      this.genderOptions = response.data;
+    });
+  },
+  methods: {
+    handleQueryWatchLog() {
+      this.log.queryParams.pageNum = 1;
+      this.log.queryParams.pageSize = 10;
+      this.logList();
+    },
+    logList() {
+      getWatchLogList(this.log.queryParams).then(e => {
+        this.log.loading = false;
+        this.log.list = e.rows;
+        this.log.total = e.total;
+      });
+    },
+    /** 重粉查看操作 */
+    showLog(row) {
+      this.log.queryParams.fsUserId = row.fsUserId;
+      this.log.open = true;
+      this.log.loading = true;
+      courseList().then(response => {
+        this.courseLists = response.list;
+        this.logList();
+      })
+    },
+    handledetails(row){
+      this.show.open=true;
+      setTimeout(() => {
+        this.$refs.userDetailsByNew.getDetails(row.fsUserId);
+      }, 1);
+    },
+    // 选择企微用户
+    selectQwUser(key,value) {
+      this.queryParams.qwUserName = value;
+      this.queryParams.qwUserId = key;
+      this.showQwUserDropdown = false;
+      this.handleQuery(); // 可选:自动触发查询
+    },
+    handleScroll(e) {
+      const container = e.target;
+      const scrollTop = container.scrollTop;
+      const scrollHeight = container.scrollHeight;
+      const clientHeight = container.clientHeight;
+
+      // 距离底部小于 20px 触发加载
+      if (scrollHeight - scrollTop - clientHeight < 20 && !this.qwUserLoading && !this.qwUserNoMore) {
+        this.qwUserPageNum += 1;
+        this.fetchQwUsers(this.queryParams.qwUserName);
+      }
+    },
+    fetchQwUsers(query) {
+      const params = {
+        qwUserName: query,
+        pageNum: this.qwUserPageNum,
+        pageSize: this.qwUserPageSize
+      };
+
+      this.qwUserLoading = true;
+
+      getQwUserListLikeName(params).then(res => {
+        const list = res.data.list || [];
+        const total = res.data.total || 0;
+
+        this.qwUserSuggestions = [...this.qwUserSuggestions, ...list];
+        this.qwUserTotal = total;
+
+        // 判断是否还有更多数据
+        if (this.qwUserSuggestions.length >= total) {
+          this.qwUserNoMore = true;
+        }
+
+        this.showQwUserDropdown = true;
+      }).finally(() => {
+        this.qwUserLoading = false;
+      });
+    },
+    onQwUserNameClear() {
+      this.queryParams.qwUserId = null;  // 同时清空 qwUserId
+    },
+    // 延迟隐藏下拉框,防止点击失效
+    hideDropdownWithDelay() {
+      setTimeout(() => {
+        this.showQwUserDropdown = false;
+      }, 200);
+    },
+    // 搜索企微用户
+    searchQwUser(query) {
+      if (!query.trim()) {
+        this.qwUserSuggestions = [];
+        this.showQwUserDropdown = false;
+        this.qwUserNoMore = false;
+        this.qwUserPageNum = 1;
+        return;
+      }
+      this.queryParams.qwUserName = query;
+      this.qwUserPageNum = 1;
+      this.qwUserNoMore = false;
+      this.qwUserSuggestions = [];
+      this.fetchQwUsers(query);
+    },
+    updateCorpId(){
+      // 重置销售公司选择
+      if (this.queryParams.corpId && this.queryParams.corpId !== "" && this.queryParams.corpId != null) {
+        // 找到选中的企微公司
+        const selectedCorp = this.qwCompanyList.find(item => item.corpId === this.queryParams.corpId);
+
+        if (selectedCorp && selectedCorp.companyIds) {
+          // 将 companyIds 字符串分割成数组(如 "1,22,25" -> ['1', '22', '25'])
+          const companyIdArray = selectedCorp.companyIds.split(',').map(id => id.trim()).filter(id => id);
+
+          // 从 companyList 中筛选出 companyId 在数组中的公司
+          this.salesCompanyList = this.companyList.filter(item =>
+            companyIdArray.includes(String(item.companyId))
+          );
+        } else {
+          this.salesCompanyList = this.companyList;
+        }
+      } else {
+        this.salesCompanyList = this.companyList;
+      }
+    },
+
+    change(){
+      if(this.createTime!=null){
+        this.queryParams.sTime=this.createTime[0];
+        this.queryParams.eTime=this.createTime[1];
+      }else{
+        this.queryParams.sTime=null;
+        this.queryParams.eTime=null;
+      }
+    },
+    /** 查询用户列表 */
+    getList() {
+      this.loading = true;
+      const { qwUserName, ...queryParams } = this.queryParams;
+      listRepeatExternalContact(queryParams).then(response => {
+        this.externalContactList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        userId: null,
+        externalUserId: null,
+        name: null,
+        companyUserId:null,
+        customerId:null,
+        avatar: null,
+        type: null,
+        gender: null,
+        remark: null,
+        description: null,
+        tagIds: null,
+        remarkMobiles: null,
+        remarkCorpName: null,
+        addWay: null,
+        operUserid: null,
+        corpId: null,
+        companyId: null,
+        transferStatus:null,
+        status:null,
+        sTime:null,
+        eTime:null,
+        createTime:null,
+        transferTime:null,
+        transferNum:null,
+        lossTime:null,
+        delTime:null,
+        state:null,
+        wayId:null,
+        stageStatus:null,
+        customerName:null
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.queryParams.transferStatus=null;
+      this.createTime=null;
+      this.queryParams.sTime=null;
+      this.queryParams.eTime=null;
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.userIds = selection.map(item => item.fsUserId)
+      this.single = selection.length!==1
+      this.multiple = !selection.length
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      const { qwUserName, ...queryParams } = this.queryParams;
+      let finalQueryParams = { ...queryParams };
+      if (this.userIds != null && this.userIds.length > 0) {
+        finalQueryParams = { ...queryParams, userIds: this.userIds };
+      }
+      this.$confirm('是否确认导出所有重粉企业微信客户数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(() => {
+          this.exportLoading = true;
+          return exportRepeatExternalContact(finalQueryParams);
+        }).then(response => {
+          this.download(response.msg);
+          this.exportLoading = false;
+        }).catch(() => {
+          this.exportLoading = false;
+      });
+    },
+  }
+};
+</script>
+<style scoped>
+/* CSS 样式 */
+.tag-container {
+  display: flex;
+  flex-wrap: wrap; /* 超出宽度时自动换行 */
+  gap: 8px; /* 设置标签之间的间距 */
+}
+.name-background {
+  display: inline-block;
+  background-color: #abece6; /* 背景颜色 */
+  padding: 4px 8px; /* 调整内边距,让背景包裹文字 */
+  border-radius: 4px; /* 可选:设置圆角 */
+}
+/* CSS 样式 */
+.tag-container {
+  display: flex;
+  flex-wrap: wrap; /* 超出宽度时自动换行 */
+  gap: 8px; /* 设置标签之间的间距 */
+}
+.name-background {
+  display: inline-block;
+  background-color: #abece6; /* 背景颜色 */
+  padding: 4px 8px; /* 调整内边距,让背景包裹文字 */
+  border-radius: 4px; /* 可选:设置圆角 */
+}
+.tag-box {
+  padding: 8px 12px;
+  border: 1px solid #989797;
+  border-radius: 4px;
+  cursor: pointer;
+  display: inline-block;
+}
+
+.tag-selected {
+  background-color: #00bc98;
+  color: #fff;
+  border-color: #00bc98;
+}
+
+.el-tag + .el-tag {
+  margin-left: 10px;
+}
+
+
+
+.button-new-tag {
+  margin-left: 10px;
+  height: 32px;
+  line-height: 30px;
+  padding-top: 0;
+  padding-bottom: 0;
+}
+.input-new-tag {
+  width: 90px;
+  margin-left: 10px;
+  vertical-align: bottom;
+}
+
+
+.suggestion-box {
+  position: absolute;
+  z-index: 999;
+  background: #fff;
+  border: 1px solid #ddd;
+  max-height: 200px;
+  overflow-y: auto;
+  width: 100%;
+}
+
+.suggestion-item {
+  padding: 10px;
+  cursor: pointer;
+}
+.suggestion-item:hover {
+  background-color: #f5f7fa;
+}
+/* 新增的滚动容器样式(不影响原有样式) */
+.scroll-wrapper {
+  max-height: 130px; /* 大约三行的高度 */
+  overflow-y: auto;  /* 垂直滚动 */
+  padding-right: 5px; /* 为滚动条留出空间 */
+}
+
+/* 美化滚动条(可选) */
+.scroll-wrapper::-webkit-scrollbar {
+  width: 6px;
+}
+.scroll-wrapper::-webkit-scrollbar-thumb {
+  background: rgba(0, 0, 0, 0.2);
+  border-radius: 3px;
+}
+
+.tag-container {
+  max-height: 200px;
+  overflow-y: auto;
+  padding: 1px;
+  border: 1px solid #ebeef5;
+  border-radius: 1px;
+  background-color: #fafafa;
+}
+.tag-list {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 8px;
+}
+.scroll-hint {
+  text-align: center;
+  color: #909399;
+  font-size: 12px;
+  padding: 1px 0;
+}
+.container {
+  max-width: 800px;
+  margin: 0 auto;
+  padding: 10px;
+}
+.title {
+  text-align: center;
+  color: #303133;
+  margin-bottom: 30px;
+}
+.demo-table {
+  width: 100%;
+  margin-bottom: 30px;
+}
+.instructions {
+  background-color: #f5f7fa;
+  padding: 15px;
+  border-radius: 1px;
+  margin-bottom: 20px;
+}
+</style>