Browse Source

Merge remote-tracking branch 'origin/master'

吴树波 1 week ago
parent
commit
f4599d1981

+ 7 - 7
.env.development

@@ -1,19 +1,19 @@
 # 页面标题
-VUE_APP_TITLE =互联网医院管理系统
+VUE_APP_TITLE =木易华康SCRM销售端
 # 公司名称
-VUE_APP_COMPANY_NAME =银川鑫泰互联网医院有限公司
+VUE_APP_COMPANY_NAME =福州市木易华康医药有限公司
 # ICP备案号
-VUE_APP_ICP_RECORD =宁ICP备2022001349号
+VUE_APP_ICP_RECORD =闽ICP备2020016609号-3
 # ICP网站访问地址
 VUE_APP_ICP_URL =https://beian.miit.gov.cn
 # 网站LOG
-VUE_APP_LOG_URL =@/assets/logo/crm.png
+VUE_APP_LOG_URL =@/assets/logo/myhk.png
 
-# 开发环境配置
-ENV = 'development'
+# 生产环境配置
+ENV = 'production'
 
 # FS管理系统/开发环境
-VUE_APP_BASE_API = '/dev-api'
+VUE_APP_BASE_API = '/prod-api'
 
 # 路由懒加载
 VUE_CLI_BABEL_TRANSPILE_MODULES = true

+ 1 - 0
package.json

@@ -17,6 +17,7 @@
     "build:prod-jnmy": "vue-cli-service build --mode prod-jnmy",
     "build:prod-hdt": "vue-cli-service build --mode prod-hdt",
     "build:prod-yzt": "vue-cli-service build --mode prod-yzt",
+    "build:prod-myhk": "vue-cli-service build --mode prod-myhk",
     "preview": "node build/index.js --preview",
     "lint": "eslint --ext .js,.vue src",
     "test:unit": "jest --clearCache && vue-cli-service test:unit",

+ 7 - 1
src/api/qw/sopLogs.js

@@ -18,7 +18,13 @@ export function listQwSopLogsList(query) {
   })
 }
 
-
+//修改 执行记录为待发送
+export function editCourseQwSopLogs(id) {
+  return request({
+    url: '/qw/sopLogs/editCourseQwSopLogs/' + id,
+    method: 'put'
+  })
+}
 
 // 查询企业微信SOP  定时任务详细
 export function getQwSopLogs(id) {

+ 88 - 2
src/api/qw/user.js

@@ -149,8 +149,23 @@ export function exportUser(query) {
     params: query
   })
 }
-
-
+/**
+ * 登录企业微信(发起登录)
+ */
+export function getQwIpad(data) {
+  return request({
+    url: '/qw/user/getQwIpad',
+    method: 'post',
+    data: data
+  })
+}
+export function delQwIpad(data) {
+  return request({
+    url: '/qw/user/delQwIpad',
+    method: 'post',
+    data: data
+  })
+}
 /**
  * 登录企业微信(发起登录)
  */
@@ -161,6 +176,55 @@ export function loginQwCode(data) {
     data: data
   })
 }
+/**
+ * 登录企业微信(发起登录)
+ */
+export function loginQwIpad(data) {
+  return request({
+    url: '/qw/user/loginQwIpad',
+    method: 'post',
+    data: data
+  })
+}
+
+/**
+ * 获取登录状态
+ */
+export function qrCodeStatus(data) {
+  return request({
+    url: '/qw/user/qrCodeStatus',
+    method: 'post',
+    data: data
+  })
+}
+export function qrCodeVerify(data) {
+  return request({
+    url: '/qw/user/qrCodeVerify',
+    method: 'post',
+    data: data
+  })
+}
+export function outLoginQwIpad(data) {
+  return request({
+    url: '/qw/user/outLoginQwIpad',
+    method: 'post',
+    data: data
+  })
+}
+export function twoCode(data) {
+  return request({
+    url: '/qw/user/twoCode',
+    method: 'post',
+    data: data
+  })
+}
+export function twoCodeStatus(data) {
+  return request({
+    url: '/qw/user/twoCodeStatus',
+    method: 'post',
+    data: data
+  })
+}
 /**
  * 取redis里的登录二维码
  */
@@ -234,6 +298,15 @@ export function handleInputAuthAppKey(data) {
   })
 }
 
+// 分配异地主机
+export function handleAllocateRemoteHost(data) {
+  return request({
+    url: '/qw/user/allocateRemoteHost',
+    method: 'post',
+    data
+  });
+}
+
 /**
 * 企业微信员工账号 绑定 云主机
 */
@@ -263,3 +336,16 @@ export function selectCloudAP(data) {
     data: data
   })
 }
+
+/**
+ * 模糊查询企微用户列表
+ * @param params 参数
+ * @returns {*}
+ */
+export function getQwUserListLikeName(params) {
+  return request({
+    url: '/qw/user/getQwUserListLikeName',
+    method: 'get',
+    params: params
+  })
+}

+ 7 - 3
src/components/Tip/index.vue

@@ -1,6 +1,8 @@
 <template>
   <div v-if="show" class="title">
-    <p>{{ title }}</p>
+    <p>
+      <i class="el-icon-warning"></i>
+      {{ title }}</p>
   </div>
 </template>
 
@@ -27,13 +29,15 @@ export default {
   border-radius: 2px;
   padding: 4px 8px;
   width: 100%;
+  text-align: left;
 
   p {
     margin: 0;
+    padding-left: 0;
     white-space: pre-line;
-    font-size: 12px;
+    font-size: 14px;
     line-height: 24px;
+    text-align: left;
   }
 }
-
 </style>

+ 3 - 1
src/views/course/courseFinishTemp/index.vue

@@ -396,6 +396,7 @@
           </el-switch>
           <span v-if="form.isAllCompanyUser == '1'" style="margin-left: 10px;color: #13ce66">是</span>
           <span v-else style="margin-left: 10px;color: #ff4949">否</span>
+          <Tip :title="'是否 全选整个销售公司的销售,作用于这个课程小节,当这个小节有客户完课时,发送此设置的内容'" />
         </el-form-item>
         <el-form-item label="所属销售" prop="companyUserIds" v-if="form.isAllCompanyUser == '2'">
           <el-select v-model="companyUserIds" remote multiple placeholder="请选择" filterable style="width: 100%;">
@@ -428,10 +429,11 @@ import {
 import { getUserList } from '@/api/company/companyUser'
 import { courseList, videoList } from '@/api/qw/sop'
 import ImageUpload from '@/views/qw/sop/ImageUpload.vue'
+import Tip from "../../../components/Tip/index.vue";
 
 export default {
   name: "CourseFinishTemp",
-  components: {ImageUpload},
+  components: {Tip, ImageUpload},
   data() {
     return {
       //上传语音的遮罩层

+ 1 - 1
src/views/course/courseUserStatistics/qw/statistics.vue

@@ -451,7 +451,7 @@
 </template>
 
 <script>
-import { listCourseWatchLog, getCourseWatchLog, delCourseWatchLog, addCourseWatchLog, updateCourseWatchLog, exportCourseWatchLog,statisticsList,qwWatchLogStatisticsList,qwWatchLogAllStatisticsList } from "@/api/course/courseWatchLog";
+import { listCourseWatchLog, getCourseWatchLog, delCourseWatchLog, addCourseWatchLog, updateCourseWatchLog, exportCourseWatchLog,statisticsList,qwWatchLogStatisticsList,qwWatchLogAllStatisticsList } from "@/api/course/qw/courseWatchLog";
 import { courseList,videoList } from '@/api/course/courseRedPacketLog'
 export default {
   name: "CourseWatchLog",

+ 18 - 18
src/views/course/courseWatchLog/index.vue

@@ -1,24 +1,24 @@
 <template>
   <div class="app-container">
     <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px">
-      <el-form-item label="会员ID" prop="userId">
-        <el-input
-          v-model="queryParams.userId"
-          placeholder="请输入会员ID"
-          clearable
-          size="small"
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="会员昵称" prop="nickName">
-        <el-input
-          v-model="queryParams.nickName"
-          placeholder="请输入会员昵称"
-          clearable
-          size="small"
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
+<!--      <el-form-item label="会员ID" prop="userId">-->
+<!--        <el-input-->
+<!--          v-model="queryParams.userId"-->
+<!--          placeholder="请输入会员ID"-->
+<!--          clearable-->
+<!--          size="small"-->
+<!--          @keyup.enter.native="handleQuery"-->
+<!--        />-->
+<!--      </el-form-item>-->
+<!--      <el-form-item label="会员昵称" prop="nickName">-->
+<!--        <el-input-->
+<!--          v-model="queryParams.nickName"-->
+<!--          placeholder="请输入会员昵称"-->
+<!--          clearable-->
+<!--          size="small"-->
+<!--          @keyup.enter.native="handleQuery"-->
+<!--        />-->
+<!--      </el-form-item>-->
       <el-form-item label="企微客户昵称" prop="nickName" >
         <el-input
           v-model="queryParams.externalUserName"

+ 18 - 18
src/views/course/courseWatchLog/watchLog.vue

@@ -21,24 +21,24 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="会员ID" prop="userId">
-        <el-input
-          v-model="queryParams.userId"
-          placeholder="请输入会员ID"
-          clearable
-          size="small"
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="会员昵称" prop="nickName">
-        <el-input
-          v-model="queryParams.nickName"
-          placeholder="请输入会员昵称"
-          clearable
-          size="small"
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
+<!--      <el-form-item label="会员ID" prop="userId">-->
+<!--        <el-input-->
+<!--          v-model="queryParams.userId"-->
+<!--          placeholder="请输入会员ID"-->
+<!--          clearable-->
+<!--          size="small"-->
+<!--          @keyup.enter.native="handleQuery"-->
+<!--        />-->
+<!--      </el-form-item>-->
+<!--      <el-form-item label="会员昵称" prop="nickName">-->
+<!--        <el-input-->
+<!--          v-model="queryParams.nickName"-->
+<!--          placeholder="请输入会员昵称"-->
+<!--          clearable-->
+<!--          size="small"-->
+<!--          @keyup.enter.native="handleQuery"-->
+<!--        />-->
+<!--      </el-form-item>-->
       <el-form-item label="企微客户昵称" prop="nickName">
         <el-input
           v-model="queryParams.externalUserName"

+ 2 - 2
src/views/qw/externalContact/myExternalContact.vue

@@ -364,7 +364,7 @@
       <el-table-column label="修改" align="center" class-name="small-padding fixed-width" width="120px" fixed="right">
         <template slot-scope="scope">
           <el-button
-            v-if="scope.row.status==0||scope.row.status==2"
+            v-show="scope.row.status==0||scope.row.status==2"
             size="mini"
             type="text"
             icon="el-icon-edit"
@@ -401,7 +401,7 @@
             <span v-else>绑定会员</span>
           </el-button>
 
-          <el-button v-if="scope.row.fsUserId"
+          <el-button v-show="scope.row.fsUserId"
             size="mini"
             type="text"
             icon="el-icon-thumb"

+ 11 - 0
src/views/qw/sop/addSop.vue

@@ -314,6 +314,7 @@
                 }">
               </el-time-select>
             </el-form-item>
+            <Tip :title="'起始时间-结束时间之内的进线客户,进入【当日营期】,时间之外的,进入【次日营期】'" />
           </div>
         </div>
 <!--        <el-form-item v-if="form.autoSopTime.autoSopType==1" label="过期消息是否发送" prop="autoSopSend"-->
@@ -355,6 +356,14 @@
           </div>
           <Tip title="选择想要发送的模板规则" />
         </el-form-item>
+
+        <el-form-item label="开启评论/弹幕" prop="openCommentStatus">
+          <el-radio-group v-model="form.openCommentStatus">
+            <el-radio :label="1" >开启评论</el-radio>
+            <el-radio :label="2" >开启弹幕</el-radio>
+            <el-radio :label="3" >关闭</el-radio>
+          </el-radio-group>
+        </el-form-item>
       </el-form>
       <div slot="footer" class="dialog-footer" style="display: flex;justify-content: flex-end;">
         <el-button type="primary" @click="submitForm">确 定</el-button>
@@ -548,6 +557,7 @@ export default {
         sendType: [{required: true, message: "不能为空", trigger: "submit"}],
         startTime: [{required: true, message: "开始时间不能为空", trigger: "submit"}],
         tempId: [{required: true, message: "模板不能为空", trigger: "submit"}],
+        openCommentStatus:[{ required: true, message: '开启评论/弹幕不能为空', trigger: 'change' }]
       }
     };
   },
@@ -868,6 +878,7 @@ export default {
         createTime: null,
         isRating: null,
         autoSopTime: {autoSopType: 2, autoStartTime: '00:00', autoEndTime: '24:00', autoSopSend: 2},
+        openCommentStatus: 0,
       };
       this.resetForm("form");
       this.tags = null;

+ 20 - 1
src/views/qw/sop/updateSop.vue

@@ -56,16 +56,19 @@
               :label="2"
             >企微</el-radio>
           </el-radio-group>
+          <Tip title="针对于企业微信平台" />
         </el-form-item>
         <el-form-item label="小转天数" prop="minConversionDay">
           <el-input class="el-input" v-model="form.minConversionDay" placeholder="请输入" style="width: 300px">
             <template slot="append">天</template>
           </el-input>
+          <Tip title="第一次提醒销售,去联系客户,在【催课看板】处显示,哪些需要联系的客户" />
         </el-form-item>
         <el-form-item label="大转天数" prop="maxConversionDay">
           <el-input class="el-input" v-model="form.maxConversionDay" placeholder="请输入" style="width: 300px">
             <template slot="append">天</template>
           </el-input>
+          <Tip title="第二次提醒销售,去联系客户,在【催课看板】处显示,哪些需要联系的客户" />
         </el-form-item>
 
         <div v-if="form.type==2">
@@ -78,6 +81,7 @@
                 :label="parseInt(dict.dictValue)"
               >{{dict.dictLabel}}</el-radio>
             </el-radio-group>
+            <Tip title="选择模板类型" />
           </el-form-item>
           <el-form-item label="选择员工" prop="qwUserIds" style="margin-top: 2%">
             <div>
@@ -172,6 +176,7 @@
               :label="2"
             >次日开始</el-radio>
           </el-radio-group>
+          <Tip :title="'这个选项仅作用于【新客户】进线时或【给客户打标签时】,是进入当日的营期 还是 次日的营期'" />
         </el-form-item>
         <div style="display: flex; align-items: center; flex-wrap: nowrap;">
           <div v-if="form.autoSopTime.autoSopType==1" style="display: flex; align-items: center">
@@ -208,6 +213,10 @@
                 }">
               </el-time-select>
             </el-form-item>
+            <div style="color: #999;font-size: 14px;display: flex;align-items: center;">
+              <i class="el-icon-info"></i>
+              起始时间-结束时间之内的进线客户,进入【当日营期】,时间之外的,进入【次日营期】
+            </div>
           </div>
         </div>
         <el-form-item label="任务过期时间" prop="expiryTime">
@@ -215,6 +224,7 @@
             <el-input-number  v-model="form.expiryTime"  :min="1" :max="100" ></el-input-number>
             (小时)
           </el-row>
+          <Tip title="发送sop任务消息的过期时间,超过这个时间,消息将不再发送(作废),比如:9点的消息,设置3个小时过期,12点之后还未发送 则这条消息将过期且不再发送" />
         </el-form-item>
         <el-form-item label="模板" prop="tempId">
           <div @click="selectListSopTemp(form.sendType,0)" style="cursor: pointer; border: 1px solid #e6e6e6; background-color: white; overflow: hidden; flex-grow: 1;">
@@ -238,6 +248,14 @@
 <!--            <div v-if="tempListLoading" slot="prefix" class="select-prefix">正在查询相应模板...</div>-->
 <!--          </el-select>-->
         </el-form-item>
+
+        <el-form-item label="开启评论/弹幕" prop="openCommentStatus">
+          <el-radio-group v-model="form.openCommentStatus">
+            <el-radio :label="1" >开启评论</el-radio>
+            <el-radio :label="2" >开启弹幕</el-radio>
+            <el-radio :label="3" >关闭</el-radio>
+          </el-radio-group>
+        </el-form-item>
       </el-form>
       <div slot="footer" class="dialog-footer" style="float: right;" >
         <el-button v-if="handleType==1" type="primary" @click="submitForm">确 定</el-button>
@@ -299,10 +317,11 @@ import { getMyQwUserList,getMyQwCompanyList } from "@/api/qw/user";
 import {sopListWxUserGroup} from "@/api/wxUser/wxUserGroup";
 import source from "echarts/src/data/Source";
 import SopTemp from "@/views/qw/sopTemp/sopTemp.vue";
+import Tip from "../../../components/Tip/index.vue";
 // import { ElMessageBox } from 'element-plus';
 export default {
   name: "updateSop",
-  components: {SopTemp, CustomerGroupDetails, qwUserList,ImageUpload,sopLogsDetails},
+  components: {Tip, SopTemp, CustomerGroupDetails, qwUserList,ImageUpload,sopLogsDetails},
   data() {
     return {
       updateQwUserDialog:{

+ 46 - 12
src/views/qw/sopUserLogs/sopUserLogsSchedule.vue

@@ -53,19 +53,35 @@
 
     <el-row :gutter="10" class="mb8">
       <el-col :span="1.5">
-        <el-button
-          type="warning"
-          icon="el-icon-s-promotion"
-          size="medium"
-          :disabled="multiple"
-          @click="handleCampSendMsg"
-          v-if="filterMode == 1"
-          v-hasPermi="['qw:sopUserLogsInfo:msg']"
-        >营期一键群发</el-button>
+        <el-tooltip class="item" effect="dark" content="此功能用于给 选中的 营期 内【所有的】客户发送 消息【或者发送草稿-/-清楚草稿】" placement="top">
+          <el-button
+            type="warning"
+            icon="el-icon-s-promotion"
+            size="medium"
+            :disabled="multiple"
+            @click="handleCampSendMsg"
+            v-hasPermi="['qw:sopUserLogsInfo:msg']"
+          >营期一键群发(或草稿)</el-button>
+        </el-tooltip>
       </el-col>
 
+      <el-col :span="1.5">
+        <el-tooltip class="item" effect="dark" content="删除营期之后,将不会在给原营期的客户发送消息,ps:删除之后不可恢复" placement="top">
+          <el-button
+            type="danger"
+            icon="el-icon-s-promotion"
+            size="medium"
+            :disabled="multiple"
+            @click="handleDeleteUserLogs"
+            v-hasPermi="['qw:sopUserLogs:remove']"
+          >批量删除营期</el-button>
+
+        </el-tooltip>
+      </el-col>
     </el-row>
-
+    <Tip :title="'【营期一键群发】:此功能用于给 选中的 营期 内【所有的】客户发送 消息【或者发送草稿-/-清楚草稿】'" />
+    <Tip :title="'【批量删除营期】:此功能用于删除选中的【整个营期】,删除之后将不会在给原营期的客户发送消息,ps:删除之后不可恢复'" />
+    <Tip :title="'【天数】:【列表:营期时间】对应列表中的天数是几 就代表着 插件助手 会发送【任务模板】里的第几天的消息'" />
 
     <el-table border v-loading="loading" :data="sopUserLogsList" @selection-change="handleSelectionChange">
       <el-table-column type="selection" width="55" align="center" />
@@ -149,14 +165,15 @@ import {
   updateSopUserLogs,
   exportSopUserLogs,
   repairSopUserLogs
-} from "@/api/qw/sopUserLogs";
+} from "../../../api/qw/sopUserLogs";
 import sopLogsDetails from "@/views/qw/sopLogs/sopLogsList.vue";
 import SopUserLogsInfoDetails from "@/views/qw/sopUserLogsInfo/sopUserLogsInfoDetails.vue";
 import {syncMyExternalContact} from "@/api/qw/externalContact";
 import SendMsgOpenTool from "@/views/qw/sopUserLogsInfo/sendMsgOpenTool.vue";
+import Tip from "../../../components/Tip/index.vue";
 export default {
   name: "sopUserLogsSchedule",
-  components: {SendMsgOpenTool, SopUserLogsInfoDetails, sopLogsDetails},
+  components: {Tip, SendMsgOpenTool, SopUserLogsInfoDetails, sopLogsDetails},
   props:{
     rowDetailFrom:{},
   },
@@ -265,6 +282,23 @@ export default {
 
     },
 
+    /**
+     *  删除营期
+     */
+    handleDeleteUserLogs(){
+      const ids =  this.ids;
+      this.$confirm('是否确认删除编号为"' + ids + '"的数据项【注意!!删除后不可恢复,请谨慎操作】?', "警告", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(function() {
+        return delSopUserLogs(ids);
+      }).then(() => {
+        this.getList();
+        this.msgSuccess("删除成功");
+      }).catch(() => {});
+    },
+
     // 取消按钮
     cancel() {
       this.open = false;

+ 7 - 9
src/views/qw/sopUserLogsInfo/sopUserLogsInfoDetails.vue

@@ -1,12 +1,10 @@
 <template>
   <div class="app-container">
-    <el-alert
-      title="注意事项"
-      type="warning"
-      description="搜索【客户备注】【标签】 只能搜索/筛选出 【当前页】的数据)"
-      :closable="false"
-      show-icon>
-    </el-alert>
+    <Tip :title="'搜索【客户备注】【标签】【进线时间】 只能搜索/筛选出 【当前页】的数据)【可以用客户id来搜(客户id来源-》企微/我的企微客户-》列表的企微客户ID)'" />
+    <Tip :title="'【一键群发】:用于给 选中的 客户 发送插件信息'" />
+    <Tip :title="'【批量修改客户营期】:选中 相应的客户 修改到 想进的相应的营期'" />
+    <Tip :title="'【官方群发许可】:只有这里显示为【是】的,才能通过模板中的 官方群发 来发送(允许条件是 客户点击过【非官方群发】发送的课程!)'" />
+
     <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px">
 <!--      <el-form-item label="企微员工账号" prop="qwUserId">-->
 <!--        <el-input-->
@@ -64,7 +62,6 @@
         <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
@@ -448,10 +445,11 @@ import {addCourseFinishTemp, updateCourseFinishTemp} from "@/api/course/courseFi
 import {allListTagGroup} from "@/api/qw/tagGroup";
 import {listTag} from "@/api/qw/tag";
 import {searchTags} from "../../../api/qw/tag";
+import Tip from "../../../components/Tip/index.vue";
 
 export default {
   name: "sopUserLogsInfoDetails",
-  components: {ImageUpload},
+  components: {Tip, ImageUpload},
   data() {
     return {
       //上传语音的遮罩层

+ 274 - 231
src/views/qw/user/index.vue

@@ -1,4 +1,5 @@
 <template>
+
   <div class="app-container">
     <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px">
       <el-form-item label="企微主体" prop="corpId">
@@ -67,7 +68,12 @@
       <el-table-column label="企微账号" align="center" prop="qwUserId" />
       <el-table-column label="企微昵称" align="center" prop="qwUserName" />
       <el-table-column label="员工称呼" align="center" prop="welcomeText" />
-<!--      <el-table-column label="所属部门" align="center" prop="departmentName" />-->
+      <el-table-column label="所属部门" align="center" prop="isDel">
+        <template slot-scope="scope">
+          <el-tag v-if="scope.row.isDel == 0" type="success">正常</el-tag>
+          <el-tag v-else type="error">离职</el-tag>
+        </template>
+      </el-table-column>
       <el-table-column label="联系我二维码" align="center" prop="contactWay" >
         <template slot-scope="scope">
           <el-image
@@ -80,12 +86,12 @@
       </el-table-column>
       <el-table-column label="绑定的AI客服" align="center" prop="fastGptRoleName" />
       <el-table-column label="授权码" align="center" prop="appKey" />
-<!--      <el-table-column label="企微状态" align="center" prop="loginStatus">-->
-<!--        <template slot-scope="scope">-->
-<!--          <el-tag v-if="scope.row.loginStatus == 1 && scope.row.toolStatus==1" type="success">在线</el-tag>-->
-<!--          <el-tag v-else type="danger">离线</el-tag>-->
-<!--        </template>-->
-<!--      </el-table-column>-->
+     <el-table-column label="ai状态" align="center" prop="loginStatus">
+        <template slot-scope="scope">
+          <el-tag v-if="scope.row.ipadStatus == 1" type="success">在线</el-tag>
+          <el-tag v-else type="danger">离线</el-tag>
+        </template>
+      </el-table-column>
 <!--      <el-table-column label="插件状态" align="center" prop="toolStatus">-->
 <!--        <template slot-scope="scope">-->
 <!--          <el-tag v-if="scope.row.toolStatus == 1" type="success">在线</el-tag>-->
@@ -114,29 +120,60 @@
             修改员工称呼
           </el-button>
 
-<!--          <el-button-->
-<!--            v-if="scope.row.toolStatus==1"-->
-<!--            size="mini"-->
-<!--            type="text"-->
-<!--            icon="el-icon-sunny"-->
-<!--            plain-->
-<!--            @click="handleLoginQwCode(scope.row)"-->
-<!--            v-hasPermi="['qw:user:login']"-->
-<!--          >-->
-<!--            登录企微-->
-<!--          </el-button>-->
-<!--          <el-button-->
-<!--            v-if="scope.row.appKey!=null && scope.row.toolStatus === 1 && scope.row.loginStatus === 1"-->
-<!--            size="mini"-->
-<!--            type="text"-->
-<!--            icon="el-icon-moon"-->
-<!--            plain-->
-<!--            @click="handleLoginOutQwStatus(scope.row)"-->
-<!--            v-hasPermi="['qw:user:login']"-->
-<!--          >-->
-<!--            退出企微-->
-<!--          </el-button>-->
-
+          <el-button
+            v-if="scope.row.serverStatus==1&&scope.row.ipadStatus!=1"
+            size="mini"
+            type="text"
+            icon="el-icon-sunny"
+            plain
+            @click="handleLoginQwCode(scope.row)"
+            v-hasPermi="['qw:user:login']"
+          >
+            登录企微
+          </el-button>
+         <el-button
+			v-if="scope.row.serverStatus==1&&scope.row.ipadStatus==1"
+            size="mini"
+            type="text"
+            icon="el-icon-moon"
+            plain
+            @click="handleLoginOutQwStatus(scope.row)"
+            v-hasPermi="['qw:user:login']"
+          >
+            退出企微
+          </el-button>
+		<el-button
+			v-if="scope.row.ipadStatus==1"
+		   size="mini"
+		   type="text"
+		   icon="el-icon-moon"
+		   plain
+		   @click="handleTwoCode(scope.row)"
+		   v-hasPermi="['qw:user:login']">
+		   二次验证
+		 </el-button>
+		 <el-button
+		 	v-if="scope.row.serverStatus!=1"
+		    size="mini"
+		    type="text"
+		    icon="el-icon-moon"
+		    plain
+		    @click="handleGetQwIpad(scope.row)"
+		    v-hasPermi="['qw:user:login']"
+		  >
+		    获取Ai主机
+		  </el-button>
+		  <el-button
+		  	v-if="scope.row.serverStatus==1 && scope.row.ipadStatus!=1"
+		     size="mini"
+		     type="text"
+		     icon="el-icon-moon"
+		     plain
+		     @click="handleDelQwIpad(scope.row)"
+		     v-hasPermi="['qw:user:login']"
+		   >
+		     解绑Ai主机
+		   </el-button>
         </template>
       </el-table-column>
       <el-table-column label="主机" align="center" class-name="small-padding fixed-width" width="110px" fixed="right">
@@ -163,17 +200,17 @@
           >
             绑定主机
           </el-button>
-          <el-button
-            v-if="scope.row.loginCodeUrl!=null"
-            size="mini"
-            type="text"
-            icon="el-icon-video-camera-solid"
-            plain
-            @click="handleCloudAP(scope.row.loginCodeUrl)"
-            v-hasPermi="['qw:user:cloudAP']"
-          >
-            获取主机帐密
-          </el-button>
+<!--          <el-button-->
+<!--            v-if="scope.row.loginCodeUrl!=null"-->
+<!--            size="mini"-->
+<!--            type="text"-->
+<!--            icon="el-icon-video-camera-solid"-->
+<!--            plain-->
+<!--            @click="handleCloudAP(scope.row.loginCodeUrl)"-->
+<!--            v-hasPermi="['qw:user:cloudAP']"-->
+<!--          >-->
+<!--            获取主机帐密-->
+<!--          </el-button>-->
           <el-button
             v-if="scope.row.loginCodeUrl!=null"
             size="mini"
@@ -275,36 +312,63 @@
     </el-dialog>
     <!--二维码   -->
     <el-dialog
-      :title="qwLogin.title"
-      :visible.sync="qwLogin.open"
+      title="企微二次认证"
+      :visible.sync="qwLoginTwo.open"
       width="600px"
       append-to-body
       custom-class="qr-login-dialog"
     >
       <div class="qr-login-container">
-        <!-- 包裹 el-image 的 div,控制加载状态 -->
-        <div class="image-wrapper" v-loading="imageLoading" element-loading-text="加载中..." element-loading-spinner="el-icon-loading">
-          <!-- 如果图片未加载或加载失败,显示一个占位图 -->
+        <div class="image-wrapper" v-loading="imageLoading" >
           <el-image
-            :src="'data:image/png;base64,' + qwLogin.codeUrl"
+            :src="'data:image/png;base64,' +qwLoginTwo.codeUrl"
             style="display: block; margin: 0 auto; width: 300px; height: 300px;"
-            @click="handleQrCodeClick"
           />
         </div>
-        <p class="qr-login-instructions">使用企业微信扫码授权登录</p>
-        <el-input
-          v-model="qwLogin.code"
-          placeholder="请输入六位验证码 按回车"
-          clearable
-          size="small"
-          type="text"
-          maxlength="6"
-          class="verification-code-input"
-          @input="validateCode"
-          @keyup.native.enter="handleLoginQwCodeMsg"
-        />
-      </div>
+        <p class="qr-login-instructions">二次验证二维码</p>
+		</div>
+		<div slot="footer" class="dialog-footer" >
+		  <el-button type="primary" @click="qwLoginTwo.open=false">确 定</el-button>
+		</div>
     </el-dialog>
+
+	<el-dialog
+	  :title="qwLogin.title"
+	  :visible.sync="qwLogin.open"
+	  width="600px"
+	  append-to-body
+	  custom-class="qr-login-dialog"
+	>
+	  <div class="qr-login-container">
+	    <div class="image-wrapper" v-loading="imageLoading" >
+	      <el-image
+	        :src="'data:image/png;base64,' +qwLogin.codeUrl"
+	        style="display: block; margin: 0 auto; width: 300px; height: 300px;"
+	      />
+	    </div>
+	    <p class="qr-login-instructions">使用企业微信扫码授权登录</p>
+	  </div>
+	</el-dialog>
+
+	<el-dialog
+	  title="输入企微验证码"
+	  :visible.sync="qwCode.open"
+	  width="600px"
+	  append-to-body>
+	 <el-form  :model="qwCode"  label-width="80px" @submit.native.prevent="handleSubmit">
+	     <el-form-item label="验证码" prop="companyName">
+	       <el-input v-model="qwCode.code" placeholder="输入企微6位验证码" />
+	     </el-form-item>
+	</el-form>
+
+	<div slot="footer" class="dialog-footer">
+	  <el-button type="primary" @click="submitCodeForm">确 定</el-button>
+
+	</div>
+	</el-dialog>
+
+
+
     <!-- 大图预览对话框 -->
     <el-dialog
       :visible.sync="dialogVisible"
@@ -333,12 +397,21 @@ import {
   relieveFastGptRoleById,
   staffListUser,
   loginQwCode,
+  loginQwIpad,
   modifyLoginQwStatus,
   loginQwCodeMsg,
   getQwCodeUrl,
+  twoCode,
+  twoCodeStatus,
+  qrCodeStatus,
+  getQwIpad,
+  delQwIpad,
   logoutQwLogout,
+  qrCodeVerify,
+  outLoginQwIpad,
   loginQwCodeUrl,
   getLoginQwStatus,
+  handleAllocateRemoteHost,
   qwBindCloudHost, qwUnbindCloudHost, handleAuthAppKey, handleInputAuthAppKey, selectCloudAP
 } from '@/api/qw/user'
 import fastGptRole from "@/views/fastGpt/fastGptRole/fastGptRole";
@@ -399,7 +472,18 @@ export default {
         code:null,
         appKey:null,
       },
-
+	 qwLoginTwo:{
+        title:"",
+        open:false,
+        codeUrl:null,
+        code:null,
+        appKey:null,
+     },
+	qwCode:{
+        title:"",
+        open:false,
+        code:null,
+      },
       cloudAPOpen:{
         open:false,
         admin:null,
@@ -414,9 +498,9 @@ export default {
         id:null,
         welcomeText:null,
       },
-      qrCodeInterval:null,
+      twoCodeInterval:null,
       loginQwInterval:null,
-      loginOutQwInterval:null,
+
       imageLoading: true, // 控制加载状态
       // 查询参数
       queryParams: {
@@ -426,6 +510,7 @@ export default {
         corpId: null,
         qwUserName: null,
       },
+	  qwUserId:null,
       companyUserList:[],
       // 表单参数
       form: {
@@ -463,41 +548,18 @@ export default {
     'qwLogin.open'(newVal) {
       if (!newVal) {
         // 如果弹窗关闭,清除定时器
-        this.beforeDestroy();
+        clearInterval(this.loginQwInterval);
 
       }
     },
   },
   methods: {
-    // handleChangeIP(row){
-    //   this.updateIp.open = true
-    //   this.updateIpForm.id = row.id
-    //   this.updateIpForm.newIp = null;
-    // },
-    // submitUpdateIpForm(){
-    //   if (this.updateIpForm.newIp==null){
-    //     this.$message.warning("请填写IP")
-    //     return
-    //   }
-    //   const data = {
-    //     id : this.updateIpForm.id,
-    //     loginCodeUrl : this.updateIpForm.newIp
-    //   }
-    //
-    //   updateUser(data).then(response => {
-    //     this.msgSuccess("绑定成功");
-    //     this.updateIp.open = false;
-    //     this.getList();
-    //   });
-    // },
-    /** 查询企微用户列表 */
     getList() {
       this.loading = true;
       staffListUser(this.queryParams).then(response => {
         this.userList = response.rows;
         this.total = response.total;
         this.loading = false;
-
       });
 
     },
@@ -523,172 +585,153 @@ export default {
     },
     //登录
     handleLoginQwCode(val){
-
-      // v-if="scope.row.appKey!=null && scope.row.toolStatus === 1 && scope.row.loginStatus === 0"
       if (val.appKey==null || val.appKey===''){
         return this.$message.warning("没有授权码,无法登录企业微信,请授权");
       }
+      loginQwIpad({qwUserId:val.id}).then(res => {
+		this.qwUserId=val.id;
+        this.qwLogin.code=null;
+        this.imageLoading=false;
+		console.log(res)
+		if(res.msg=="success"){
+			this.qwLogin.codeUrl=res.qrCode64
+			this.qwLogin.open=true;
+			this.loginQwPolling();
+		}else{
+			this.$message.success(res.msg);
+			this.getList()
+		}
 
-      if (val.toolStatus===0 || val.toolStatus==null ){
-        return this.$message.warning("插件离线了,无法登录企业微信,请联系管理员~");
-      }
-
-      if (val.loginStatus===1 && val.toolStatus===1){
-        return this.$message.success("已经登录了,无需重复登录");
-      }
-
-      loginQwCode({appKey:val.appKey}).then(res => {
-        this.qwLogin.appKey=val.appKey;
-        this.qwLogin.open=true;
-        this.imageLoading=true;
+      })
+    },
 
-        //定时器 获取登录状态(有自动登录的)
-        this.loginQwPolling();
+	handleTwoCode(val){
 
-        // 调用后台接口获取新的二维码URL
-        loginQwCodeUrl({ appKey: this.qwLogin.appKey }).then(res => {
-          getQwCodeUrl({appKey:this.qwLogin.appKey}).then(res=>{
-            this.qwLogin.codeUrl=res.base64 // 更新二维码URL
-          }).catch(()=>{
-            this.resetQwLogin();
-          }).finally(()=>{
-            this.imageLoading=false;
-          })
+		twoCode({ qwUserId: val.id }).then(res => {
+		console.log(res)
+		this.qwLoginTwo.open=true;
+		this.qwLoginTwo.codeUrl=res.qrCode
 
         });
 
-        // setTimeout(()=>{
-        //
-        //     getQwCodeUrl({appKey:val.appKey}).then(res=>{
-        //       this.qwLogin.codeUrl=res.base64
-        //     }).catch(()=>{
-        //       this.resetQwLogin();
-        //     }).finally(()=>{
-        //       this.imageLoading=false;
-        //     })
-        //
-        // },3000)
-
-        // 启动定时器,每隔45秒更新一次二维码
-        this.startQrCodePolling();
-
-      })
-    },
-
-    // 每隔45秒请求一次二维码
-    startQrCodePolling() {
-      this.qrCodeInterval = setInterval(() => {
-        this.refreshQrCode();
-      }, 45000);  // 45秒更新一次
-    },
 
+	},
+	twoCodePolling() {
+	  this.twoCodeInterval = setInterval(() => {
+	    twoCodeStatus({ qwUserId: this.qwUserId }).then(res => {
+			console.log(res)
+
+	      if (res.msg==104001) {
+			this.$message.success('登录成功');
+			this.clearDl()
+	        clearInterval(this.loginQwInterval);
+	      }else if(res.msg==100004){
+			  this.clearDl()
+		  }
+	    });
+	  }, 3000);
+	},
     loginQwPolling() {
-      let elapsedTime = 0;  // 记录已执行的时间(单位:秒)
-
       this.loginQwInterval = setInterval(() => {
-        // 每次轮询后增加已执行的时间
-        elapsedTime += 5;  // 因为每 3 秒执行一次
-
-        // 请求登录状态
-        getLoginQwStatus({ appKey: this.qwLogin.appKey }).then(res => {
-          if (res.status==1) {
-            this.$message.success('登录成功');
-            clearInterval(this.loginQwInterval);  // 登录成功,停止轮询
-            this.resetQwLogin();
-          }
-          // 判断是否超过最大轮询时间(60秒)
-          if (elapsedTime >= 90) {
-            clearInterval(this.loginQwInterval);  // 超过90秒停止轮询
-            this.$message.warning('登录超时,请稍后再试!')
-            this.resetQwLogin();
-          }
+        qrCodeStatus({ qwUserId: this.qwUserId }).then(res => {
+			console.log(res)
+			if (res.msg==22) {
+				this.$message.success('账号企业不一致请重新扫码登录');
+				this.clearDl();
+			}
+          if (res.msg==104001) {
+			this.$message.success('登录成功');
+			this.clearDl()
+
+          }else if(res.msg==100004){
+			  this.qwCode.open=true;
+			  clearInterval(this.loginQwInterval);
+		  }
         });
-      }, 3000);  // 每 3 秒更新一次
-    },
-
-    // 退出时清除定时器
-    beforeDestroy() {
-      if (this.qrCodeInterval) {
-        clearInterval(this.qrCodeInterval);  // 清除定时器
-      }
-      if (this.loginQwInterval) {
-        clearInterval(this.loginQwInterval);  // 清除定时器
-      }
-      if (this.loginOutQwInterval){
-        clearInterval(this.loginOutQwInterval);  // 清除定时器
-      }
-      this.resetQwLogin();
-    },
-
-    // 刷新二维码
-    refreshQrCode() {
-      // 调用后台接口获取新的二维码URL
-      loginQwCodeUrl({ appKey: this.qwLogin.appKey }).then(res => {
-        getQwCodeUrl({appKey:this.qwLogin.appKey}).then(res=>{
-          this.qwLogin.codeUrl=res.base64 // 更新二维码URL
-        }).catch(()=>{
-          this.resetQwLogin();
-        }).finally(()=>{
-          this.imageLoading=false;
-        })
-
-      });
+      }, 3000);
     },
+	submitCodeForm(){
+
+		qrCodeVerify({ code: this.qwCode.code,qwUserId: this.qwUserId }).then(res => {
+			console.log(res)
+
+			this.$message.success('验证成功账号信息确认中。。。。');
+			this.qwCode.open=false;
+			 this.loginQwInterval = setTimeout(() => {
+			     qrCodeStatus({ qwUserId: this.qwUserId }).then(res => {
+			         console.log(res);
+			         if (res.msg == 23) {
+			             this.$message.error('账号不一致请重新扫码登录');
+			             this.clearDl();
+			         }
+					 if (res.msg == 22) {
+					     this.$message.error('账号企业不一致请重新扫码登录');
+					     this.clearDl();
+					 }
+			         if (res.msg == 104001) {
+			             this.$message.success('登录成功');
+			             this.clearDl();
+			         }
+			     });
+			 }, 4000);
+		});
+	},
+
+	clearDl(){
+		this.qwCode.open=false;
+		this.qwLogin.open=false;
+		clearInterval(this.loginQwInterval);
+		this.getList()
+	},
 
-    handleQrCodeClick(){
-      this.imageLoading=true;
-      // 调用后台接口获取新的二维码URL
-      loginQwCodeUrl({ appKey: this.qwLogin.appKey }).then(res => {
-
-        setTimeout(()=>{
-          getQwCodeUrl({appKey:this.qwLogin.appKey}).then(res=>{
-
-            //确保万一再调用一下刷新二维码
-            this.qwLogin.codeUrl=res.base64 // 更新二维码URL
-
-          }).catch(()=>{
-            this.resetQwLogin();
-          }).finally(()=>{
-            this.imageLoading=false;
-          })
-
-        },3000)
 
 
-      });
-    },
     //退出
     handleLoginOutQwStatus(val){
-      this.loading=true;
-      logoutQwLogout({appKey:val.appKey,loginStatus:0}).then(res => {
-
-        let elapsedTime = 0;  // 记录已执行的时间(单位:秒)
-
-        this.loginOutQwInterval = setInterval(() => {
-          // 每次轮询后增加已执行的时间
-          elapsedTime += 3;  // 因为每 3 秒执行一次
-
-          // 请求登录状态
-          getLoginQwStatus({ appKey: val.appKey }).then(res => {
-            if (res.status==0) {
-              this.$message.success('退出成功');
-              clearInterval(this.loginOutQwInterval);  // 登录成功,停止轮询
-              this.resetQwLogin();
-            }
-
-            // 判断是否超过最大轮询时间(60秒)
-            if (elapsedTime >= 90) {
-              clearInterval(this.loginOutQwInterval);  // 超过90秒停止轮询
-              this.$message.warning('退出超时,请多等待后刷新页面!')
-              this.resetQwLogin();
-
-            }
-          });
-        }, 3000);  // 每 3 秒更新一次
+      outLoginQwIpad({qwUserId: val.id}).then(res => {
 
+        this.$message.success("退出登录成功");
+		this.getList()
       })
+
     },
 
+
+	handleGetQwIpad(val){
+    getQwIpad({ qwUserId: val.id }).then(res => {
+      this.$message.success("获取主机成功");
+      this.getList();
+    }).catch(error => {
+      console.log(error);
+      if (error.code  === 501) {
+        this.$confirm(
+          '当前区域没有多余的名额,将为你分配异地名额,会导致企业微信需要扫脸重新登录,并且半个小时后需要进行验证',
+          '提示',
+          {
+            confirmButtonText: '确定',
+            cancelButtonText: '取消',
+            type: 'warning',
+            dangerouslyUseHTMLString: true
+          }
+        ).then(() => {
+          return handleAllocateRemoteHost({ qwUserId: val.id });
+        }).then(res => {
+          this.$message.success('异地主机分配成功');
+          this.getList();
+        }).catch(() => {
+          this.$message.info('已取消异地主机分配');
+        });
+      } else {
+        this.$message.error('获取主机失败');
+      }
+    });
+	},
+	handleDelQwIpad(val){
+	  delQwIpad({qwUserId: val.id}).then(res => {
+	    this.$message.success("解绑主机成功");
+		this.getList()
+	  })
+	},
     //传验证码
     handleLoginQwCodeMsg(){
       loginQwCodeMsg({appKey: this.qwLogin.appKey,code:this.qwLogin.code}).then(res => {