cuDeptIdIndex.vue 33 KB

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