index.vue 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024
  1. <template>
  2. <div class="app-container">
  3. <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px">
  4. <el-form-item label="企微主体" prop="corpId">
  5. <el-select v-model="queryParams.corpId" placeholder="企微主体" size="small" @change="updateCorpId()">
  6. <el-option
  7. v-for="dict in myQwCompanyList"
  8. :key="dict.dictValue"
  9. :label="dict.dictLabel"
  10. :value="dict.dictValue"
  11. />
  12. </el-select>
  13. </el-form-item>
  14. <el-form-item label="企微账号" prop="qwUserId">
  15. <el-input
  16. v-model="queryParams.qwUserId"
  17. placeholder="请输入企微账号"
  18. clearable
  19. size="small"
  20. @keyup.enter.native="handleQuery"
  21. />
  22. </el-form-item>
  23. <el-form-item label="企微昵称" prop="qwUserName">
  24. <el-input
  25. v-model="queryParams.qwUserName"
  26. placeholder="请输入企微昵称"
  27. clearable
  28. size="small"
  29. @keyup.enter.native="handleQuery"
  30. />
  31. </el-form-item>
  32. <el-form-item label="授权码" prop="appKey">
  33. <el-input
  34. v-model="queryParams.appKey"
  35. placeholder="请输入授权码"
  36. clearable
  37. size="small"
  38. @keyup.enter.native="handleQuery"
  39. />
  40. </el-form-item>
  41. <el-form-item>
  42. <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
  43. <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
  44. </el-form-item>
  45. </el-form>
  46. <el-row :gutter="10" class="mb8">
  47. <el-col :span="1.5">
  48. <el-button
  49. type="warning"
  50. plain
  51. icon="el-icon-download"
  52. size="mini"
  53. :loading="exportLoading"
  54. @click="handleExport"
  55. v-hasPermi="['qw:user:export']"
  56. >导出</el-button>
  57. </el-col>
  58. <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
  59. </el-row>
  60. <el-table border v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
  61. <el-table-column label="企微成员ID" align="center" prop="id" />
  62. <el-table-column label="企微账号" align="center" prop="qwUserId" />
  63. <el-table-column label="企微昵称" align="center" prop="qwUserName" />
  64. <el-table-column label="员工称呼" align="center" prop="welcomeText" />
  65. <el-table-column label="所属部门" align="center" prop="isDel">
  66. <template slot-scope="scope">
  67. <el-tag v-if="scope.row.isDel == 0" type="success">正常</el-tag>
  68. <el-tag v-else type="error">离职</el-tag>
  69. </template>
  70. </el-table-column>
  71. <el-table-column label="联系我二维码" align="center" prop="contactWay" >
  72. <template slot-scope="scope">
  73. <el-image
  74. v-if="scope.row.contactWay!=null"
  75. style="width: 100px; height: 100px"
  76. :src="scope.row.contactWay"
  77. fit="contain"
  78. @click="openImageViewer(scope.row.contactWay)"/>
  79. </template>
  80. </el-table-column>
  81. <el-table-column label="绑定的AI客服" align="center" prop="fastGptRoleName" />
  82. <el-table-column label="授权码" align="center" prop="appKey" />
  83. <el-table-column label="ai状态" align="center" prop="loginStatus">
  84. <template slot-scope="scope">
  85. <el-tag v-if="scope.row.ipadStatus == 1" type="success">在线</el-tag>
  86. <el-tag v-else type="danger">离线</el-tag>
  87. </template>
  88. </el-table-column>
  89. <!-- <el-table-column label="插件状态" align="center" prop="toolStatus">-->
  90. <!-- <template slot-scope="scope">-->
  91. <!-- <el-tag v-if="scope.row.toolStatus == 1" type="success">在线</el-tag>-->
  92. <!-- <el-tag v-else type="danger">离线</el-tag>-->
  93. <!-- </template>-->
  94. <!-- </el-table-column>-->
  95. <!-- <el-table-column label="插件版本" align="center" prop="version"/>-->
  96. <el-table-column label="服务器地址" align="center" prop="loginCodeUrl">
  97. <template slot-scope="scope">
  98. <el-tooltip class="item" effect="dark" :content="scope.row.loginCodeUrl" placement="top">
  99. <div style="display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; text-overflow: ellipsis;">
  100. <span>{{ scope.row.loginCodeUrl }}</span>
  101. </div>
  102. </el-tooltip>
  103. </template>
  104. </el-table-column>
  105. <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="120px" fixed="right">
  106. <template slot-scope="scope">
  107. <el-button
  108. size="mini"
  109. type="text"
  110. icon="el-icon-user-solid"
  111. plain
  112. @click="handleAppellation(scope.row)"
  113. >
  114. 修改员工称呼
  115. </el-button>
  116. <el-button
  117. v-if="scope.row.serverStatus==1&&scope.row.ipadStatus!=1"
  118. size="mini"
  119. type="text"
  120. icon="el-icon-sunny"
  121. plain
  122. @click="handleLoginQwCode(scope.row)"
  123. v-hasPermi="['qw:user:login']"
  124. >
  125. 登录企微
  126. </el-button>
  127. <el-button
  128. v-if="scope.row.serverStatus==1&&scope.row.ipadStatus==1"
  129. size="mini"
  130. type="text"
  131. icon="el-icon-moon"
  132. plain
  133. @click="handleLoginOutQwStatus(scope.row)"
  134. v-hasPermi="['qw:user:login']"
  135. >
  136. 退出企微
  137. </el-button>
  138. <el-button
  139. v-if="scope.row.ipadStatus==1"
  140. size="mini"
  141. type="text"
  142. icon="el-icon-moon"
  143. plain
  144. @click="handleTwoCode(scope.row)"
  145. v-hasPermi="['qw:user:login']">
  146. 二次验证
  147. </el-button>
  148. <el-button
  149. v-if="scope.row.serverStatus!=1"
  150. size="mini"
  151. type="text"
  152. icon="el-icon-moon"
  153. plain
  154. @click="handleGetQwIpad(scope.row)"
  155. v-hasPermi="['qw:user:login']"
  156. >
  157. 获取Ai主机
  158. </el-button>
  159. <el-button
  160. v-if="scope.row.serverStatus==1 && scope.row.ipadStatus!=1"
  161. size="mini"
  162. type="text"
  163. icon="el-icon-moon"
  164. plain
  165. @click="handleDelQwIpad(scope.row)"
  166. v-hasPermi="['qw:user:login']"
  167. >
  168. 解绑Ai主机
  169. </el-button>
  170. </template>
  171. </el-table-column>
  172. <el-table-column label="主机" align="center" class-name="small-padding fixed-width" width="110px" fixed="right">
  173. <template slot-scope="scope">
  174. <el-button
  175. v-if="scope.row.appKey==null"
  176. size="mini"
  177. type="text"
  178. icon="el-icon-s-check"
  179. plain
  180. v-hasPermi="['qw:user:authAppKey']"
  181. @click="uploadAuthorizeKey2(scope.row)"
  182. >授权key
  183. </el-button>
  184. <el-button
  185. v-if="scope.row.loginCodeUrl==null && scope.row.appKey !=null"
  186. size="mini"
  187. type="text"
  188. icon="el-icon-sunny"
  189. plain
  190. @click="handleBindCloudHost(scope.row)"
  191. v-hasPermi="['qw:user:loginIp']"
  192. >
  193. 绑定主机
  194. </el-button>
  195. <!-- <el-button-->
  196. <!-- v-if="scope.row.loginCodeUrl!=null"-->
  197. <!-- size="mini"-->
  198. <!-- type="text"-->
  199. <!-- icon="el-icon-video-camera-solid"-->
  200. <!-- plain-->
  201. <!-- @click="handleCloudAP(scope.row.loginCodeUrl)"-->
  202. <!-- v-hasPermi="['qw:user:cloudAP']"-->
  203. <!-- >-->
  204. <!-- 获取主机帐密-->
  205. <!-- </el-button>-->
  206. <el-button
  207. v-if="scope.row.loginCodeUrl!=null"
  208. size="mini"
  209. type="text"
  210. icon="el-icon-moon"
  211. plain
  212. @click="handleUnbindCloudHost(scope.row)"
  213. v-hasPermi="['qw:user:loginIpOut']"
  214. >
  215. 解除主机
  216. </el-button>
  217. </template>
  218. </el-table-column>
  219. <el-table-column label="AI客服" align="center" class-name="small-padding fixed-width" width="100px" fixed="right">
  220. <template slot-scope="scope">
  221. <el-button
  222. size="mini"
  223. type="text"
  224. icon="el-icon-connection"
  225. plain
  226. v-if="scope.row.fastGptRoleName!=null"
  227. @click="bindFastGptRole(scope.row)"
  228. >换绑AI客服</el-button>
  229. <el-button
  230. size="mini"
  231. type="text"
  232. plain
  233. icon="el-icon-link"
  234. v-else
  235. @click="bindFastGptRole(scope.row)"
  236. >绑定AI客服</el-button>
  237. <el-button
  238. size="mini"
  239. type="text"
  240. icon="el-icon-unlock"
  241. plain
  242. v-if="scope.row.fastGptRoleName!=null"
  243. @click="relieveFastGptRole(scope.row)"
  244. >解绑AI客服</el-button>
  245. </template>
  246. </el-table-column>
  247. </el-table>
  248. <pagination
  249. v-show="total>0"
  250. :total="total"
  251. :page.sync="queryParams.pageNum"
  252. :limit.sync="queryParams.pageSize"
  253. @pagination="getList"
  254. />
  255. <!-- 绑定AI客服-->
  256. <el-dialog :title="bindAiTitle" :visible.sync="bindAiOpen" width="1200px" append-to-body>
  257. <fast-gpt-role ref="fastGptRole" @refreshFastGptList="refreshFastGptList" ></fast-gpt-role>
  258. </el-dialog>
  259. <!-- <el-dialog :visible.sync="updateIp.open" width="600px" append-to-body>-->
  260. <!-- <el-form ref="updateIpForm" :model="updateIpForm" :rules="updateIpRule" label-width="100px">-->
  261. <!-- <el-form-item label="新云主机IP" prop="Ip">-->
  262. <!-- <el-input v-model="updateIpForm.newIp" placeholder="请输入新IP" />-->
  263. <!-- </el-form-item>-->
  264. <!-- </el-form>-->
  265. <!-- <div slot="footer" class="dialog-footer" >-->
  266. <!-- <el-button type="primary" @click="submitUpdateIpForm">确 定</el-button>-->
  267. <!-- </div>-->
  268. <!-- </el-dialog>-->
  269. <el-dialog title="云主机信息" :visible.sync="cloudAPOpen.open" append-to-body>
  270. <el-card class="box-card">
  271. <div slot="header" class="clearfix">
  272. <span>账号:{{cloudAPOpen.admin}}</span>
  273. </div>
  274. <div slot="header" class="clearfix">
  275. <span>密码:{{cloudAPOpen.passWord}}</span>
  276. </div>
  277. </el-card>
  278. </el-dialog>
  279. <el-dialog :title="callOpen.title" :visible.sync="callOpen.open" width="500px" append-to-body>
  280. <el-form ref="callOpenFrom" :model="callOpenFrom" :rules="callOpenRule" label-width="110px">
  281. <el-form-item label="员工称呼" prop="welcomeText">
  282. <el-input v-model="callOpenFrom.welcomeText" placeholder="请输入员工称呼" />
  283. </el-form-item>
  284. </el-form>
  285. <div slot="footer" class="dialog-footer" >
  286. <el-button type="primary" @click="submitCallOpenFrom">确 定</el-button>
  287. </div>
  288. </el-dialog>
  289. <el-dialog title="授权key" :visible.sync="authorizeKeyOpen" width="500px" append-to-body>
  290. <el-form ref="authorizeKeyFrom" :model="authorizeKeyFrom" :rules="authorizeKeyRule" label-width="110px">
  291. <el-form-item label="授权的key值" prop="appKey">
  292. <el-input v-model="authorizeKeyFrom.appKey" placeholder="请输入授权key" type="Number"/>
  293. </el-form-item>
  294. </el-form>
  295. <div slot="footer" class="dialog-footer" >
  296. <el-button type="primary" @click="submitAuthorizeKeyForm">确 定</el-button>
  297. </div>
  298. </el-dialog>
  299. <!--二维码 -->
  300. <el-dialog
  301. title="企微二次认证"
  302. :visible.sync="qwLoginTwo.open"
  303. width="600px"
  304. append-to-body
  305. custom-class="qr-login-dialog"
  306. >
  307. <div class="qr-login-container">
  308. <div class="image-wrapper" v-loading="imageLoading" >
  309. <el-image
  310. :src="'data:image/png;base64,' +qwLoginTwo.codeUrl"
  311. style="display: block; margin: 0 auto; width: 300px; height: 300px;"
  312. />
  313. </div>
  314. <p class="qr-login-instructions">二次验证二维码</p>
  315. </div>
  316. <div slot="footer" class="dialog-footer" >
  317. <el-button type="primary" @click="qwLoginTwo.open=false">确 定</el-button>
  318. </div>
  319. </el-dialog>
  320. <el-dialog
  321. :title="qwLogin.title"
  322. :visible.sync="qwLogin.open"
  323. width="600px"
  324. append-to-body
  325. custom-class="qr-login-dialog"
  326. >
  327. <div class="qr-login-container">
  328. <div class="image-wrapper" v-loading="imageLoading" >
  329. <el-image
  330. :src="'data:image/png;base64,' +qwLogin.codeUrl"
  331. style="display: block; margin: 0 auto; width: 300px; height: 300px;"
  332. />
  333. </div>
  334. <p class="qr-login-instructions">使用企业微信扫码授权登录</p>
  335. </div>
  336. </el-dialog>
  337. <el-dialog
  338. title="输入企微验证码"
  339. :visible.sync="qwCode.open"
  340. width="600px"
  341. append-to-body>
  342. <el-form :model="qwCode" label-width="80px" @submit.native.prevent="handleSubmit">
  343. <el-form-item label="验证码" prop="companyName">
  344. <el-input v-model="qwCode.code" placeholder="输入企微6位验证码" />
  345. </el-form-item>
  346. </el-form>
  347. <div slot="footer" class="dialog-footer">
  348. <el-button type="primary" @click="submitCodeForm">确 定</el-button>
  349. </div>
  350. </el-dialog>
  351. <!-- 大图预览对话框 -->
  352. <el-dialog
  353. :visible.sync="dialogVisible"
  354. :modal="false"
  355. width="1200"
  356. append-to-body>
  357. <img
  358. :src="this.dialogImageUrl"
  359. style="display: block; max-width: 100%; margin: 0 auto"
  360. />
  361. </el-dialog>
  362. </div>
  363. </template>
  364. <script>
  365. import {
  366. listUser,
  367. getUser,
  368. delUser,
  369. addUser,
  370. updateUser,
  371. exportUser,
  372. updateUserWeclome,
  373. getMyQwCompanyList,
  374. relieveFastGptRoleById,
  375. staffListUser,
  376. loginQwCode,
  377. loginQwIpad,
  378. modifyLoginQwStatus,
  379. loginQwCodeMsg,
  380. getQwCodeUrl,
  381. twoCode,
  382. twoCodeStatus,
  383. qrCodeStatus,
  384. getQwIpad,
  385. delQwIpad,
  386. logoutQwLogout,
  387. qrCodeVerify,
  388. outLoginQwIpad,
  389. loginQwCodeUrl,
  390. getLoginQwStatus,
  391. qwBindCloudHost, qwUnbindCloudHost, handleAuthAppKey, handleInputAuthAppKey, selectCloudAP
  392. } from '@/api/qw/user'
  393. import fastGptRole from "@/views/fastGpt/fastGptRole/fastGptRole";
  394. import {updateSop, updateSopQwUser} from "@/api/qw/sop";
  395. export default {
  396. name: "User",
  397. components: { fastGptRole},
  398. data() {
  399. return {
  400. updateIp:{
  401. open:false,
  402. title: "修改云主机IP"
  403. },
  404. updateIpForm:{
  405. id:null,
  406. newIp:null,
  407. },
  408. authorizeKeyOpen:false,
  409. authorizeKeyFrom:{
  410. id:null,
  411. appKey:null,
  412. qwUserId:null,
  413. qwUserName:null
  414. },
  415. updateIpRule:{},
  416. newIp:null,
  417. //放大图片
  418. dialogImageUrl:null,
  419. dialogVisible:false,
  420. // 遮罩层
  421. loading: false,
  422. // 导出遮罩层
  423. exportLoading: false,
  424. // 选中数组
  425. ids: [],
  426. // 非单个禁用
  427. single: true,
  428. // 非多个禁用
  429. multiple: true,
  430. // 显示搜索条件
  431. showSearch: true,
  432. // 总条数
  433. total: 0,
  434. //公司列表
  435. myQwCompanyList:[],
  436. // 企微用户表格数据
  437. userList: [],
  438. allowSelectOptions:[],
  439. // 弹出层标题
  440. bindAiTitle: "",
  441. bindAiOpen: false,
  442. qwLogin:{
  443. title:"",
  444. open:false,
  445. codeUrl:null,
  446. code:null,
  447. appKey:null,
  448. },
  449. qwLoginTwo:{
  450. title:"",
  451. open:false,
  452. codeUrl:null,
  453. code:null,
  454. appKey:null,
  455. },
  456. qwCode:{
  457. title:"",
  458. open:false,
  459. code:null,
  460. },
  461. cloudAPOpen:{
  462. open:false,
  463. admin:null,
  464. passWord:null,
  465. },
  466. callOpen:{
  467. open:false,
  468. title: '修改员工称呼',
  469. },
  470. callOpenFrom:{
  471. id:null,
  472. welcomeText:null,
  473. },
  474. twoCodeInterval:null,
  475. loginQwInterval:null,
  476. imageLoading: true, // 控制加载状态
  477. // 查询参数
  478. queryParams: {
  479. pageNum: 1,
  480. pageSize: 10,
  481. qwUserId: null,
  482. corpId: null,
  483. qwUserName: null,
  484. },
  485. qwUserId:null,
  486. companyUserList:[],
  487. // 表单参数
  488. form: {
  489. isSendMsg: '2',
  490. },
  491. authorizeKeyRule:{
  492. appKey:[{required:true,message:"授权码不能为空",trigger:"blur"}]
  493. },
  494. callOpenRule:{
  495. welcomeText:[{required:true,message:"员工称呼不能为空",trigger:"blur"}]
  496. },
  497. // 表单校验
  498. rules: {
  499. },
  500. //欢迎语表单校验
  501. weclomeRules:{
  502. welcomeText:[{required:true,message:"消息文本不能为空",trigger:"blur"}]
  503. },
  504. };
  505. },
  506. created() {
  507. getMyQwCompanyList().then(response => {
  508. this.myQwCompanyList = response.data;
  509. if(this.myQwCompanyList!=null && this.myQwCompanyList.length > 0){
  510. this.queryParams.corpId=this.myQwCompanyList[0].dictValue;
  511. this.getList();
  512. }
  513. });
  514. },
  515. watch: {
  516. // 监听弹窗的可见性变化
  517. 'qwLogin.open'(newVal) {
  518. if (!newVal) {
  519. // 如果弹窗关闭,清除定时器
  520. clearInterval(this.loginQwInterval);
  521. }
  522. },
  523. },
  524. methods: {
  525. getList() {
  526. this.loading = true;
  527. staffListUser(this.queryParams).then(response => {
  528. this.userList = response.rows;
  529. this.total = response.total;
  530. this.loading = false;
  531. });
  532. },
  533. updateCorpId(){
  534. this.reset();
  535. this.getList();
  536. },
  537. //绑定AI客服
  538. bindFastGptRole(row){
  539. this.bindAiTitle="绑定AI客服";
  540. this.bindAiOpen=true;
  541. setTimeout(() => {
  542. this.$refs.fastGptRole.handleBindAiData(row)
  543. }, 200);
  544. },
  545. handleAppellation(val){
  546. this.callOpen.open=true;
  547. this.callOpenFrom.welcomeText=val.welcomeText;
  548. this.callOpenFrom.id=val.id;
  549. },
  550. //登录
  551. handleLoginQwCode(val){
  552. if (val.appKey==null || val.appKey===''){
  553. return this.$message.warning("没有授权码,无法登录企业微信,请授权");
  554. }
  555. loginQwIpad({qwUserId:val.id}).then(res => {
  556. this.qwUserId=val.id;
  557. this.qwLogin.code=null;
  558. this.imageLoading=false;
  559. console.log(res)
  560. if(res.msg=="success"){
  561. this.qwLogin.codeUrl=res.qrCode64
  562. this.qwLogin.open=true;
  563. this.loginQwPolling();
  564. }else{
  565. this.$message.success(res.msg);
  566. this.getList()
  567. }
  568. })
  569. },
  570. handleTwoCode(val){
  571. twoCode({ qwUserId: val.id }).then(res => {
  572. console.log(res)
  573. this.qwLoginTwo.open=true;
  574. this.qwLoginTwo.codeUrl=res.qrCode
  575. });
  576. },
  577. twoCodePolling() {
  578. this.twoCodeInterval = setInterval(() => {
  579. twoCodeStatus({ qwUserId: this.qwUserId }).then(res => {
  580. console.log(res)
  581. if (res.msg==104001) {
  582. this.$message.success('登录成功');
  583. this.clearDl()
  584. clearInterval(this.loginQwInterval);
  585. }else if(res.msg==100004){
  586. this.clearDl()
  587. }
  588. });
  589. }, 3000);
  590. },
  591. loginQwPolling() {
  592. this.loginQwInterval = setInterval(() => {
  593. qrCodeStatus({ qwUserId: this.qwUserId }).then(res => {
  594. console.log(res)
  595. if (res.msg==22) {
  596. this.$message.success('账号企业不一致请重新扫码登录');
  597. this.clearDl();
  598. }
  599. if (res.msg==104001) {
  600. this.$message.success('登录成功');
  601. this.clearDl()
  602. }else if(res.msg==100004){
  603. this.qwCode.open=true;
  604. clearInterval(this.loginQwInterval);
  605. }
  606. });
  607. }, 3000);
  608. },
  609. submitCodeForm(){
  610. qrCodeVerify({ code: this.qwCode.code,qwUserId: this.qwUserId }).then(res => {
  611. console.log(res)
  612. this.$message.success('验证成功账号信息确认中。。。。');
  613. this.qwCode.open=false;
  614. this.loginQwInterval = setTimeout(() => {
  615. qrCodeStatus({ qwUserId: this.qwUserId }).then(res => {
  616. console.log(res);
  617. if (res.msg == 23) {
  618. this.$message.error('账号不一致请重新扫码登录');
  619. this.clearDl();
  620. }
  621. if (res.msg == 22) {
  622. this.$message.error('账号企业不一致请重新扫码登录');
  623. this.clearDl();
  624. }
  625. if (res.msg == 104001) {
  626. this.$message.success('登录成功');
  627. this.clearDl();
  628. }
  629. });
  630. }, 4000);
  631. });
  632. },
  633. clearDl(){
  634. this.qwCode.open=false;
  635. this.qwLogin.open=false;
  636. clearInterval(this.loginQwInterval);
  637. this.getList()
  638. },
  639. //退出
  640. handleLoginOutQwStatus(val){
  641. outLoginQwIpad({qwUserId: val.id}).then(res => {
  642. this.$message.success("退出登录成功");
  643. this.getList()
  644. })
  645. },
  646. handleGetQwIpad(val){
  647. getQwIpad({qwUserId: val.id}).then(res => {
  648. this.$message.success("获取主机成功");
  649. this.getList()
  650. })
  651. },
  652. handleDelQwIpad(val){
  653. delQwIpad({qwUserId: val.id}).then(res => {
  654. this.$message.success("解绑主机成功");
  655. this.getList()
  656. })
  657. },
  658. //传验证码
  659. handleLoginQwCodeMsg(){
  660. loginQwCodeMsg({appKey: this.qwLogin.appKey,code:this.qwLogin.code}).then(res => {
  661. this.qwLogin.open=false;
  662. this.$message.success("登录成功");
  663. })
  664. },
  665. validateCode() {
  666. // 只允许输入数字并限制长度为6
  667. this.qwLogin.code = this.qwLogin.code.replace(/\D/g, "").slice(0, 6);
  668. },
  669. handleCloudAP(urlAP){
  670. selectCloudAP({ipAddress:urlAP}).then(res => {
  671. this.cloudAPOpen.open=true
  672. this.cloudAPOpen.admin=res.data.apAdmin;
  673. this.cloudAPOpen.passWord=res.data.apPassword;
  674. })
  675. },
  676. handleUnbindCloudHost(val){
  677. const appKey=val.appKey;
  678. this.$confirm(
  679. '确定要给企微账号:<span style="color: green;">' +val.qwUserId + '' +
  680. '</span><br>企微昵称:<span style="color: red;">【' + val.qwUserName + '】</span>' +
  681. '</span><br><span style="color: orange;">解绑【Ps:解绑后此云主机可能会分配给他人】</span></span>',
  682. "警告",
  683. {
  684. confirmButtonText: "确定",
  685. cancelButtonText: "取消",
  686. type: "warning",
  687. dangerouslyUseHTMLString: true // 允许使用 HTML 字符串
  688. }
  689. ).then(() => {
  690. return qwUnbindCloudHost(appKey);
  691. }).then(response => {
  692. this.$message.success('解绑成功');
  693. }).finally(res=>{
  694. this.getList();
  695. })
  696. },
  697. handleAuthorizeKey(val){
  698. this.authorizeKeyFrom.id=val.id;
  699. this.authorizeKeyFrom.qwUserId=val.qwUserId;
  700. this.authorizeKeyFrom.qwUserName=val.qwUserName;
  701. this.authorizeKeyOpen=true;
  702. },
  703. submitAuthorizeKeyForm(){
  704. this.$refs["authorizeKeyFrom"].validate(valid => {
  705. if (valid) {
  706. if (this.authorizeKeyFrom.id != null && this.authorizeKeyFrom.appKey != null) {
  707. this.uploadAuthorizeKey();
  708. }
  709. }
  710. });
  711. },
  712. submitCallOpenFrom(){
  713. this.$refs["callOpenFrom"].validate(valid => {
  714. if (valid) {
  715. if (this.callOpenFrom.id != null && this.callOpenFrom.welcomeText != null) {
  716. updateUser(this.callOpenFrom).then(res=>{
  717. this.$message.success('修改成功');
  718. this.callOpen.open=false;
  719. this.getList();
  720. });
  721. }
  722. }
  723. });
  724. },
  725. uploadAuthorizeKey(){
  726. this.$confirm(
  727. '确定要给企微账号:<span style="color: green;">' + this.authorizeKeyFrom.qwUserId + '' +
  728. '</span><br>企微昵称:<span style="color: red;">【' + this.authorizeKeyFrom.qwUserName + '】</span>' +
  729. '</span><br>授权key:<span style="color: #04adf6;">【' + this.authorizeKeyFrom.appKey + '】</span>?',
  730. "警告",
  731. {
  732. confirmButtonText: "确定",
  733. cancelButtonText: "取消",
  734. type: "warning",
  735. dangerouslyUseHTMLString: true // 允许使用 HTML 字符串
  736. }
  737. ).then(() => {
  738. this.authorizeKeyOpen=false;
  739. return handleInputAuthAppKey(this.authorizeKeyFrom);
  740. }).then(response => {
  741. this.msgSuccess("授权key完成");
  742. }).finally(res=>{
  743. this.resetAuthorizeKeyFrom();
  744. this.getList();
  745. })
  746. },
  747. uploadAuthorizeKey2(val){
  748. const id=val.id;
  749. this.$confirm(
  750. '确定要给企微账号:<span style="color: green;">' +val.qwUserId + '' +
  751. '</span><br>企微昵称:<span style="color: red;">【' + val.qwUserName + '】</span>' +
  752. '</span><br>授权key</span>?',
  753. "警告",
  754. {
  755. confirmButtonText: "确定",
  756. cancelButtonText: "取消",
  757. type: "warning",
  758. dangerouslyUseHTMLString: true // 允许使用 HTML 字符串
  759. }
  760. ).then(() => {
  761. return handleAuthAppKey({id:id});
  762. }).then(response => {
  763. this.msgSuccess("授权key完成");
  764. }).finally(res=>{
  765. this.resetAuthorizeKeyFrom();
  766. this.getList();
  767. })
  768. },
  769. handleBindCloudHost(val){
  770. if (val.appKey == null || val.appKey == '') {
  771. return this.$message.warning('没有授权码,无法绑定主机,请联系管理员');
  772. }
  773. const appKey=val.appKey;
  774. this.$confirm(
  775. '确定要给企微账号:<span style="color: green;">' +val.qwUserId + '' +
  776. '</span><br>企微昵称:<span style="color: red;">【' + val.qwUserName + '】</span>' +
  777. '</span><br><span style="color: dodgerblue;">绑定云主机?</span></span>',
  778. "警告",
  779. {
  780. confirmButtonText: "确定",
  781. cancelButtonText: "取消",
  782. type: "warning",
  783. dangerouslyUseHTMLString: true // 允许使用 HTML 字符串
  784. }
  785. ).then(() => {
  786. return qwBindCloudHost(appKey);
  787. }).then(response => {
  788. this.$message.success('绑定成功,请登录云主机进行配置~~');
  789. }).finally(res=>{
  790. this.getList();
  791. })
  792. },
  793. openImageViewer(url) {
  794. // 打开大图预览对话框
  795. this.dialogImageUrl=url
  796. this.dialogVisible = true;
  797. },
  798. //刷新页面
  799. refreshFastGptList(){
  800. this.bindAiOpen=false;
  801. this.getList();
  802. },
  803. // 取消按钮
  804. cancel() {
  805. this.open = false;
  806. this.reset();
  807. },
  808. // 表单重置
  809. reset() {
  810. this.form = {
  811. id: null,
  812. qwUserId: null,
  813. corpId: null,
  814. qwUserName: null,
  815. };
  816. this.resetForm("form");
  817. },
  818. //重置授权
  819. resetAuthorizeKeyFrom(){
  820. this.authorizeKeyFrom={
  821. id:null,
  822. appKey:null,
  823. qwUserId:null,
  824. qwUserName:null
  825. };
  826. },
  827. //重置登录
  828. resetQwLogin(){
  829. this.qwLogin={
  830. title:"",
  831. open:false,
  832. codeUrl:null,
  833. code:null,
  834. corpId:null,
  835. qwUserId:null,
  836. }
  837. this.qwLogin.open=false;
  838. this.loading=false;
  839. this.getList();
  840. },
  841. //解绑AI客服
  842. relieveFastGptRole(row){
  843. this.$confirm('是否确认解绑AI客服?', "警告", {
  844. confirmButtonText: "确定",
  845. cancelButtonText: "取消",
  846. type: "warning"
  847. }).then(function() {
  848. return relieveFastGptRoleById(row.id);
  849. }).then(() => {
  850. this.getList();
  851. this.msgSuccess("解绑成功");
  852. })
  853. },
  854. /** 搜索按钮操作 */
  855. handleQuery() {
  856. this.queryParams.pageNum = 1;
  857. this.getList();
  858. },
  859. /** 重置按钮操作 */
  860. resetQuery() {
  861. this.resetForm("queryForm");
  862. this.queryParams.corpId=this.myQwCompanyList[0].dictValue;
  863. this.handleQuery();
  864. },
  865. // 多选框选中数据
  866. handleSelectionChange(selection) {
  867. this.ids = selection.map(item => item.id)
  868. this.single = selection.length!==1
  869. this.multiple = !selection.length
  870. },
  871. /** 提交按钮 */
  872. submitForm() {
  873. this.$refs["form"].validate(valid => {
  874. if (valid) {
  875. if (this.form.id != null) {
  876. // updateUser(this.form).then(response => {
  877. // this.msgSuccess("绑定成功");
  878. // this.open = false;
  879. // this.getList();
  880. //
  881. // });
  882. } else {
  883. // addUser(this.form).then(response => {
  884. // this.msgSuccess("新增成功");
  885. // this.open = false;
  886. // this.getList();
  887. // });
  888. }
  889. }
  890. });
  891. },
  892. /** 导出按钮操作 */
  893. handleExport() {
  894. const queryParams = this.queryParams;
  895. this.$confirm('是否确认导出所有企微用户数据项?', "警告", {
  896. confirmButtonText: "确定",
  897. cancelButtonText: "取消",
  898. type: "warning"
  899. }).then(() => {
  900. this.exportLoading = true;
  901. return exportUser(queryParams);
  902. }).then(response => {
  903. this.download(response.msg);
  904. this.exportLoading = false;
  905. }).catch(() => {});
  906. }
  907. }
  908. };
  909. </script>
  910. <style>
  911. .text-container {
  912. max-height: 7.5em; /* 设置最大高度为6行,根据字体大小调整 */
  913. overflow-y: auto; /* 内容超出时显示滚动条 */
  914. line-height: 1.5em; /* 行高设置,确保每行高度一致 */
  915. }
  916. .qr-login-dialog .el-dialog__body {
  917. display: flex;
  918. flex-direction: column;
  919. align-items: center;
  920. text-align: center;
  921. padding: 20px;
  922. }
  923. .qr-login-container {
  924. width: 100%;
  925. }
  926. .qr-login-instructions {
  927. font-size: 14px;
  928. color: #666;
  929. margin: 10px 0;
  930. }
  931. .verification-code-input {
  932. margin-top: 15px;
  933. width: 80%;
  934. }
  935. </style>