index.vue 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495
  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="companyId">
  5. <el-select filterable v-model="queryParams.companyId" placeholder="请选择公司名" clearable size="small" @change="handleCompanyChange">
  6. <el-option
  7. v-for="item in myCompanyList"
  8. :key="item.companyId"
  9. :label="item.companyName"
  10. :value="item.companyId"
  11. />
  12. </el-select>
  13. </el-form-item>
  14. <el-form-item label="企微主体" prop="corpId">
  15. <el-select v-model="queryParams.corpId" placeholder="企微主体" size="small" @change="handleCorpChange">
  16. <el-option
  17. v-for="dict in myQwCompanyList"
  18. :key="dict.dictValue"
  19. :label="dict.dictLabel"
  20. :value="dict.dictValue"
  21. />
  22. </el-select>
  23. </el-form-item>
  24. <el-form-item label="企微部门">
  25. <!-- <treeselect :clearable="false" v-model="queryParams.deptId" :options="deptOptions" :show-count="true" placeholder="请选择归属部门"/>-->
  26. <treeselect
  27. :clearable="false"
  28. v-model="queryParams.deptId"
  29. :options="deptOptions"
  30. :show-count="true"
  31. placeholder="请选择归属部门"
  32. :load-options="loadOptions"
  33. :normalizer="normalizer"
  34. />
  35. </el-form-item>
  36. <el-form-item label="企微账号" prop="qwUserId">
  37. <el-input
  38. v-model="queryParams.qwUserId"
  39. placeholder="请输入企微账号"
  40. clearable
  41. size="small"
  42. @keyup.enter.native="handleQuery"
  43. />
  44. </el-form-item>
  45. <el-form-item label="企微昵称" prop="qwUserName">
  46. <el-input
  47. v-model="queryParams.qwUserName"
  48. placeholder="请输入企微昵称"
  49. clearable
  50. size="small"
  51. @keyup.enter.native="handleQuery"
  52. />
  53. </el-form-item>
  54. <el-form-item label="授权码" prop="appKey">
  55. <el-input
  56. v-model="queryParams.appKey"
  57. placeholder="请输入授权码"
  58. clearable
  59. size="small"
  60. @keyup.enter.native="handleQuery"
  61. />
  62. </el-form-item>
  63. <el-form-item label="ipad状态" prop="loginStatus">
  64. <el-select v-model="queryParams.loginStatus" placeholder="请选择ipad状态" clearable>
  65. <el-option
  66. v-for="item in loginStatusOption"
  67. :key="item.value"
  68. :label="item.label"
  69. :value="item.value">
  70. </el-option>
  71. </el-select>
  72. </el-form-item>
  73. <el-form-item label="员工状态" prop="isDel">
  74. <el-select v-model="queryParams.isDel" placeholder="请选择员工状态" clearable>
  75. <el-option
  76. v-for="item in optionsStatus"
  77. :key="item.value"
  78. :label="item.label"
  79. :value="item.value">
  80. </el-option>
  81. </el-select>
  82. </el-form-item>
  83. <el-form-item>
  84. <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
  85. <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
  86. </el-form-item>
  87. </el-form>
  88. <el-row :gutter="10" class="mb8">
  89. <el-col :span="1.5">
  90. <el-button
  91. type="primary"
  92. :disabled="multiple"
  93. plain
  94. icon="el-icon-edit"
  95. size="mini"
  96. @click="updateSendType"
  97. >修改发送方式
  98. </el-button>
  99. </el-col>
  100. <el-col :span="1.5">
  101. <el-button
  102. type="warning"
  103. plain
  104. icon="el-icon-download"
  105. size="mini"
  106. :loading="exportLoading"
  107. @click="handleExport"
  108. v-hasPermi="['qw:user:export']"
  109. >导出</el-button>
  110. </el-col>
  111. <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
  112. </el-row>
  113. <el-table border v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
  114. <el-table-column type="selection" width="55" align="center" />
  115. <el-table-column label="企微成员ID" align="center" prop="id" />
  116. <el-table-column label="企微账号" align="center" prop="qwUserId" />
  117. <el-table-column label="企微昵称" align="center" prop="qwUserName" />
  118. <el-table-column label="员工称呼" align="center" prop="welcomeText" />
  119. // 部门
  120. <el-table-column label="部门" align="center" prop="departmentName" />
  121. <el-table-column label="员工状态" align="center" prop="isDel">
  122. <template slot-scope="scope">
  123. <el-tag v-if="scope.row.isDel == 0" type="success">正常</el-tag>
  124. <el-tag v-else type="error">离职</el-tag>
  125. </template>
  126. </el-table-column>
  127. <el-table-column label="联系我二维码" align="center" prop="contactWay" >
  128. <template slot-scope="scope">
  129. <el-image
  130. v-if="scope.row.contactWay!=null"
  131. style="width: 100px; height: 100px"
  132. :src="scope.row.contactWay"
  133. fit="contain"
  134. @click="openImageViewer(scope.row.contactWay)"/>
  135. </template>
  136. </el-table-column>
  137. <el-table-column label="绑定的AI客服" align="center" prop="fastGptRoleName" />
  138. <el-table-column label="授权码" align="center" prop="appKey" />
  139. <el-table-column label="发送方式" align="center" prop="sendMsgType">
  140. <template slot-scope="scope">
  141. <el-tag v-if="scope.row.sendMsgType == 0">方式一</el-tag>
  142. <el-tag v-if="scope.row.sendMsgType == 1" type="success">方式二</el-tag>
  143. <el-tag v-if="scope.row.sendMsgType == 2" type="warning">掉线通知</el-tag>
  144. </template>
  145. </el-table-column>
  146. <el-table-column label="vid" align="center" prop="vid" />
  147. <el-table-column label="uid" align="center" prop="uid" />
  148. <el-table-column label="serverId" align="center" prop="serverId" />
  149. <el-table-column label="ipad状态" align="center" prop="loginStatus">
  150. <template slot-scope="scope">
  151. <el-tag v-if="scope.row.ipadStatus == 1" type="success">在线</el-tag>
  152. <el-tag v-else type="danger">离线</el-tag>
  153. </template>
  154. </el-table-column>
  155. <!-- <el-table-column label="插件状态" align="center" prop="toolStatus">-->
  156. <!-- <template slot-scope="scope">-->
  157. <!-- <el-tag v-if="scope.row.toolStatus == 1" type="success">在线</el-tag>-->
  158. <!-- <el-tag v-else type="danger">离线</el-tag>-->
  159. <!-- </template>-->
  160. <!-- </el-table-column>-->
  161. <!-- <el-table-column label="插件版本" align="center" prop="version"/>-->
  162. <!-- <el-table-column label="服务器地址" align="center" prop="loginCodeUrl">-->
  163. <!-- <template slot-scope="scope">-->
  164. <!-- <el-tooltip class="item" effect="dark" :content="scope.row.loginCodeUrl" placement="top">-->
  165. <!-- <div style="display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; text-overflow: ellipsis;">-->
  166. <!-- <span>{{ scope.row.loginCodeUrl }}</span>-->
  167. <!-- </div>-->
  168. <!-- </el-tooltip>-->
  169. <!-- </template>-->
  170. <!-- </el-table-column>-->
  171. <!-- <el-table-column label="自动发课" align="center" prop="isAuto">-->
  172. <!-- <template slot-scope="scope">-->
  173. <!-- <dict-tag :options="isAutoOptions" :value="scope.row.isAuto"/>-->
  174. <!-- </template>-->
  175. <!-- </el-table-column>-->
  176. <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="120px" fixed="right">
  177. <template slot-scope="scope">
  178. <el-button
  179. size="mini"
  180. type="text"
  181. icon="el-icon-user-solid"
  182. plain
  183. @click="handleAppellation(scope.row)"
  184. >
  185. 修改员工称呼
  186. </el-button>
  187. <el-button
  188. size="mini"
  189. type="text"
  190. icon="el-icon-user-solid"
  191. plain
  192. @click="handleAutoRemark(scope.row)"
  193. >
  194. 完课备注修改
  195. </el-button>
  196. <el-button
  197. v-if="scope.row.serverStatus==1&&scope.row.ipadStatus!=1"
  198. size="mini"
  199. type="text"
  200. icon="el-icon-sunny"
  201. plain
  202. @click="handleLoginQwCode(scope.row)"
  203. v-hasPermi="['qw:user:login']"
  204. >
  205. 登录企微
  206. </el-button>
  207. <el-button
  208. v-if="scope.row.serverStatus==1&&scope.row.ipadStatus==1"
  209. size="mini"
  210. type="text"
  211. icon="el-icon-moon"
  212. plain
  213. @click="handleLoginOutQwStatus(scope.row)"
  214. v-hasPermi="['qw:user:login']"
  215. >
  216. 退出企微
  217. </el-button>
  218. <el-button
  219. v-if="scope.row.ipadStatus==1"
  220. size="mini"
  221. type="text"
  222. icon="el-icon-moon"
  223. plain
  224. @click="handleTwoCode(scope.row)"
  225. v-hasPermi="['qw:user:login']">
  226. 二次验证
  227. </el-button>
  228. <!-- <el-button-->
  229. <!-- v-if="scope.row.serverStatus!=1"-->
  230. <!-- size="mini"-->
  231. <!-- type="text"-->
  232. <!-- icon="el-icon-moon"-->
  233. <!-- plain-->
  234. <!-- @click="handleGetQwIpad(scope.row)"-->
  235. <!-- v-hasPermi="['qw:user:login']"-->
  236. <!-- >-->
  237. <!-- 获取Ai主机-->
  238. <!-- </el-button>-->
  239. <!-- <el-button-->
  240. <!-- v-if="scope.row.serverStatus==1 && scope.row.ipadStatus!=1"-->
  241. <!-- size="mini"-->
  242. <!-- type="text"-->
  243. <!-- icon="el-icon-moon"-->
  244. <!-- plain-->
  245. <!-- @click="handleDelQwIpad(scope.row)"-->
  246. <!-- v-hasPermi="['qw:user:login']"-->
  247. <!-- >-->
  248. <!-- 解绑Ai主机-->
  249. <!-- </el-button>-->
  250. <!-- <el-button-->
  251. <!-- v-if="scope.row.isAuto=='00'"-->
  252. <!-- size="mini"-->
  253. <!-- type="text"-->
  254. <!-- icon="el-icon-moon"-->
  255. <!-- plain-->
  256. <!-- @click="handleUpdateIsAuto(scope.row,'01')"-->
  257. <!-- v-hasPermi="['qw:user:isauto']"-->
  258. <!-- >-->
  259. <!-- 启用插件-->
  260. <!-- </el-button>-->
  261. <!-- <el-button-->
  262. <!-- v-if="scope.row.isAuto=='01'"-->
  263. <!-- size="mini"-->
  264. <!-- type="text"-->
  265. <!-- icon="el-icon-moon"-->
  266. <!-- plain-->
  267. <!-- @click="handleUpdateIsAuto(scope.row,'00')"-->
  268. <!-- v-hasPermi="['qw:user:isauto']"-->
  269. <!-- >-->
  270. <!-- 禁用插件-->
  271. <!-- </el-button>-->
  272. </template>
  273. </el-table-column>
  274. <el-table-column label="主机" align="center" class-name="small-padding fixed-width" width="110px" fixed="right">
  275. <template slot-scope="scope">
  276. <el-button
  277. v-if="scope.row.appKey==null"
  278. size="mini"
  279. type="text"
  280. icon="el-icon-s-check"
  281. plain
  282. v-hasPermi="['qw:user:authAppKey']"
  283. @click="uploadAuthorizeKey2(scope.row)"
  284. >授权key
  285. </el-button>
  286. <!-- <el-button
  287. v-if="scope.row.loginCodeUrl==null && scope.row.appKey !=null"
  288. v-show="false"
  289. size="mini"
  290. type="text"
  291. icon="el-icon-sunny"
  292. plain
  293. @click="handleBindCloudHost(scope.row)"
  294. v-hasPermi="['qw:user:loginIp']"
  295. >
  296. 绑定主机
  297. </el-button>-->
  298. <!-- <el-button-->
  299. <!-- v-if="scope.row.loginCodeUrl!=null"-->
  300. <!-- size="mini"-->
  301. <!-- type="text"-->
  302. <!-- icon="el-icon-video-camera-solid"-->
  303. <!-- plain-->
  304. <!-- @click="handleCloudAP(scope.row.loginCodeUrl)"-->
  305. <!-- v-hasPermi="['qw:user:cloudAP']"-->
  306. <!-- >-->
  307. <!-- 获取主机帐密-->
  308. <!-- </el-button>-->
  309. <!-- <el-button-->
  310. <!-- v-if="scope.row.loginCodeUrl!=null"-->
  311. <!-- size="mini"-->
  312. <!-- type="text"-->
  313. <!-- icon="el-icon-moon"-->
  314. <!-- plain-->
  315. <!-- @click="handleUnbindCloudHost(scope.row)"-->
  316. <!-- v-hasPermi="['qw:user:loginIpOut']"-->
  317. <!-- >-->
  318. <!-- 解除主机-->
  319. <!-- </el-button>-->
  320. <el-button
  321. size="mini"
  322. type="text"
  323. :icon="scope.row.videoGetStatus == 0 ? 'el-icon-circle-check' : 'el-icon-remove-outline'"
  324. plain
  325. @click="changeVideoStatus(scope.row)"
  326. >
  327. {{ scope.row.videoGetStatus == 0 ? "开启" : "禁用" }}视频号接收
  328. </el-button>
  329. </template>
  330. </el-table-column>
  331. <el-table-column label="AI客服" align="center" class-name="small-padding fixed-width" width="100px" fixed="right">
  332. <template slot-scope="scope">
  333. <el-button
  334. size="mini"
  335. type="text"
  336. icon="el-icon-connection"
  337. plain
  338. v-if="scope.row.fastGptRoleName!=null"
  339. @click="bindFastGptRole(scope.row)"
  340. >换绑AI客服</el-button>
  341. <el-button
  342. size="mini"
  343. type="text"
  344. plain
  345. icon="el-icon-link"
  346. v-else
  347. @click="bindFastGptRole(scope.row)"
  348. >绑定AI客服</el-button>
  349. <el-button
  350. size="mini"
  351. type="text"
  352. icon="el-icon-unlock"
  353. plain
  354. v-if="scope.row.fastGptRoleName!=null"
  355. @click="relieveFastGptRole(scope.row)"
  356. >解绑AI客服</el-button>
  357. <el-button
  358. size="mini"
  359. type="text"
  360. icon="el-icon-unlock"
  361. plain
  362. v-hasPermi="['qw:user:aiStatus']"
  363. v-if="scope.row.aiStatus == 0 && projectFrom === 'sxjz'"
  364. @click="updateFastGptRoleStatus(scope.row)"
  365. >Ai客服下线</el-button>
  366. <el-button
  367. size="mini"
  368. type="text"
  369. icon="el-icon-unlock"
  370. plain
  371. v-hasPermi="['qw:user:aiStatus']"
  372. v-if="scope.row.aiStatus == 1 && projectFrom === 'sxjz'"
  373. @click="updateFastGptRoleStatus(scope.row)"
  374. >Ai客服上线</el-button>
  375. </template>
  376. </el-table-column>
  377. </el-table>
  378. <pagination
  379. v-show="total>0"
  380. :total="total"
  381. :page.sync="queryParams.pageNum"
  382. :limit.sync="queryParams.pageSize"
  383. @pagination="getList"
  384. />
  385. <!-- 绑定AI客服-->
  386. <el-dialog :title="bindAiTitle" :visible.sync="bindAiOpen" width="1200px" append-to-body>
  387. <fast-gpt-role ref="fastGptRole" @refreshFastGptList="refreshFastGptList" ></fast-gpt-role>
  388. </el-dialog>
  389. <!-- <el-dialog :visible.sync="updateIp.open" width="600px" append-to-body>-->
  390. <!-- <el-form ref="updateIpForm" :model="updateIpForm" :rules="updateIpRule" label-width="100px">-->
  391. <!-- <el-form-item label="新云主机IP" prop="Ip">-->
  392. <!-- <el-input v-model="updateIpForm.newIp" placeholder="请输入新IP" />-->
  393. <!-- </el-form-item>-->
  394. <!-- </el-form>-->
  395. <!-- <div slot="footer" class="dialog-footer" >-->
  396. <!-- <el-button type="primary" @click="submitUpdateIpForm">确 定</el-button>-->
  397. <!-- </div>-->
  398. <!-- </el-dialog>-->
  399. <el-dialog title="云主机信息" :visible.sync="cloudAPOpen.open" append-to-body>
  400. <el-card class="box-card">
  401. <div slot="header" class="clearfix">
  402. <span>账号:{{cloudAPOpen.admin}}</span>
  403. </div>
  404. <div slot="header" class="clearfix">
  405. <span>密码:{{cloudAPOpen.passWord}}</span>
  406. </div>
  407. </el-card>
  408. </el-dialog>
  409. <el-dialog :title="callOpen.title" :visible.sync="callOpen.open" width="500px" append-to-body>
  410. <el-form ref="callOpenFrom" :model="callOpenFrom" :rules="callOpenRule" label-width="110px">
  411. <el-form-item label="员工称呼" prop="welcomeText">
  412. <el-input v-model="callOpenFrom.welcomeText" placeholder="请输入员工称呼" />
  413. </el-form-item>
  414. </el-form>
  415. <div slot="footer" class="dialog-footer" >
  416. <el-button type="primary" @click="submitCallOpenFrom">确 定</el-button>
  417. </div>
  418. </el-dialog>
  419. <el-dialog :title="editRemarkOpen.title" :visible.sync="editRemarkOpen.open" width="500px" append-to-body>
  420. <el-form ref="callOpenFrom" :model="editRemarkOpen" label-width="110px">
  421. <el-radio-group v-model="editRemarkOpen.isSendMsg">
  422. <el-card>
  423. <el-row :gutter="20">
  424. <el-col>
  425. <el-radio
  426. :label="1"
  427. style="font-size: 16px; margin: 10px 0;"
  428. >添加【完课备注】在最【旧备注-(前面)】</el-radio>
  429. </el-col>
  430. <el-col>
  431. <el-radio
  432. :label="2"
  433. style="font-size: 16px; margin: 10px 0;"
  434. >添加【完课备注】在最【旧备注-(后面)】</el-radio>
  435. </el-col>
  436. <el-col>
  437. <el-radio
  438. :label="3"
  439. style="font-size: 16px; margin: 10px 0;"
  440. >使用简洁版备注【*日期完】,在【旧备注-前面】</el-radio>
  441. </el-col>
  442. <el-col>
  443. <el-radio
  444. :label="4"
  445. style="font-size: 16px; margin: 10px 0;"
  446. >使用简洁版备注【*日期完】,在【旧备注-后面】</el-radio>
  447. </el-col>
  448. <el-col>
  449. <el-radio
  450. :label="5"
  451. style="font-size: 16px; margin: 10px 0;"
  452. >不用完课备注</el-radio>
  453. </el-col>
  454. </el-row>
  455. </el-card>
  456. </el-radio-group>
  457. </el-form>
  458. <div slot="footer" class="dialog-footer">
  459. <el-button type="primary" @click="submitEditRemarkOpenFrom">确 定</el-button>
  460. </div>
  461. </el-dialog>
  462. <el-dialog title="授权key" :visible.sync="authorizeKeyOpen" width="500px" append-to-body>
  463. <el-form ref="authorizeKeyFrom" :model="authorizeKeyFrom" :rules="authorizeKeyRule" label-width="110px">
  464. <el-form-item label="授权的key值" prop="appKey">
  465. <el-input v-model="authorizeKeyFrom.appKey" placeholder="请输入授权key" type="Number"/>
  466. </el-form-item>
  467. </el-form>
  468. <div slot="footer" class="dialog-footer" >
  469. <el-button type="primary" @click="submitAuthorizeKeyForm">确 定</el-button>
  470. </div>
  471. </el-dialog>
  472. <!--二维码 -->
  473. <el-dialog
  474. title="企微二次认证"
  475. :visible.sync="qwLoginTwo.open"
  476. width="600px"
  477. append-to-body
  478. custom-class="qr-login-dialog"
  479. >
  480. <div class="qr-login-container">
  481. <div class="image-wrapper" v-loading="imageLoading" >
  482. <el-image
  483. :src="'data:image/png;base64,' +qwLoginTwo.codeUrl"
  484. style="display: block; margin: 0 auto; width: 300px; height: 300px;"
  485. />
  486. </div>
  487. <p class="qr-login-instructions">二次验证二维码</p>
  488. </div>
  489. <div slot="footer" class="dialog-footer" >
  490. <el-button type="primary" @click="qwLoginTwo.open=false">确 定</el-button>
  491. </div>
  492. </el-dialog>
  493. <el-dialog
  494. :title="qwLogin.title"
  495. :visible.sync="qwLogin.open"
  496. width="600px"
  497. append-to-body
  498. custom-class="qr-login-dialog"
  499. >
  500. <div class="qr-login-container">
  501. <div class="image-wrapper" v-loading="imageLoading" >
  502. <el-image
  503. :src="'data:image/png;base64,' +qwLogin.codeUrl"
  504. style="display: block; margin: 0 auto; width: 300px; height: 300px;"
  505. />
  506. </div>
  507. <p class="qr-login-instructions">使用企业微信扫码授权登录</p>
  508. </div>
  509. </el-dialog>
  510. <el-dialog
  511. title="输入企微验证码"
  512. :visible.sync="qwCode.open"
  513. width="600px"
  514. append-to-body>
  515. <el-form :model="qwCode" label-width="80px" @submit.native.prevent="handleSubmit">
  516. <el-form-item label="验证码" prop="companyName">
  517. <el-input v-model="qwCode.code" placeholder="输入企微6位验证码" />
  518. </el-form-item>
  519. </el-form>
  520. <div slot="footer" class="dialog-footer">
  521. <el-button type="primary" @click="submitCodeForm">确 定</el-button>
  522. </div>
  523. </el-dialog>
  524. <!-- 大图预览对话框 -->
  525. <el-dialog
  526. :visible.sync="dialogVisible"
  527. :modal="false"
  528. width="1200"
  529. append-to-body>
  530. <img
  531. :src="this.dialogImageUrl"
  532. style="display: block; max-width: 100%; margin: 0 auto"
  533. />
  534. </el-dialog>
  535. <el-dialog
  536. :visible.sync="updateSendOpen"
  537. width="1000px"
  538. append-to-body>
  539. <el-form label-width="80px">
  540. <p>是否修改企微账号发送方式:
  541. <el-tag style="margin-left: 10px" v-for="name in names">{{ name }}</el-tag>
  542. </p>
  543. <el-form-item label="发送方式" prop="type">
  544. <el-radio-group v-model="type">
  545. <el-radio
  546. :label="0"
  547. >方式一
  548. </el-radio>
  549. <el-radio
  550. :label="1"
  551. >方式二
  552. </el-radio>
  553. <el-radio
  554. :label="2"
  555. >掉线通知
  556. </el-radio>
  557. </el-radio-group>
  558. </el-form-item>
  559. </el-form>
  560. <div slot="footer" class="dialog-footer">
  561. <el-button type="primary" @click="submitUpdateSendTypeForm">确 定</el-button>
  562. </div>
  563. </el-dialog>
  564. </div>
  565. </template>
  566. <script>
  567. import {
  568. updateIsAuto,
  569. updateUser,
  570. getMyQwCompanyList,
  571. relieveFastGptRoleById,
  572. loginQwIpad,
  573. loginQwCodeMsg,
  574. twoCode,
  575. twoCodeStatus,
  576. qrCodeStatus,
  577. updateSendType,
  578. getQwIpad,
  579. delQwIpad,
  580. qrCodeVerify,
  581. outLoginQwIpad,
  582. changeVideoStatus,
  583. handleAllocateRemoteHost,
  584. qwBindCloudHost, qwUnbindCloudHost, handleAuthAppKey,
  585. handleInputAuthAppKey, selectCloudAP, staffListUser, exportStaff, updateFastGptRoleStatusById, staffListPost
  586. } from '../../../api/qw/user'
  587. import fastGptRole from "@/views/fastGpt/fastGptRole/fastGptRole";
  588. import { treeselect } from "@/api/qw/qwDept";
  589. import Treeselect from "@riophae/vue-treeselect";
  590. import "@riophae/vue-treeselect/dist/vue-treeselect.css";
  591. import {getCompanyList} from "../../../api/company/company";
  592. export default {
  593. name: "cuDeptIdIndex",
  594. components: { fastGptRole,Treeselect},
  595. data() {
  596. return {
  597. deptOptions:[], // 企微部门
  598. isAutoOptions:[],
  599. updateIp:{
  600. open:false,
  601. title: "修改云主机IP"
  602. },
  603. updateIpForm:{
  604. id:null,
  605. newIp:null,
  606. },
  607. projectFrom:process.env.VUE_APP_PROJECT_FROM,
  608. authorizeKeyOpen:false,
  609. authorizeKeyFrom:{
  610. id:null,
  611. appKey:null,
  612. qwUserId:null,
  613. qwUserName:null
  614. },
  615. updateIpRule:{},
  616. newIp:null,
  617. //放大图片
  618. dialogImageUrl:null,
  619. dialogVisible:false,
  620. optionsStatus: [{
  621. value: 0,
  622. label: '正常'
  623. }, {
  624. value: 2,
  625. label: '离职'
  626. }],
  627. loginStatusOption: [{
  628. value: 0,
  629. label: '离线'
  630. }, {
  631. value: 1,
  632. label: '在线'
  633. }],
  634. // 遮罩层
  635. loading: true,
  636. names: [],
  637. // 导出遮罩层
  638. exportLoading: false,
  639. // 选中数组
  640. ids: [],
  641. // 非单个禁用
  642. single: true,
  643. // 非多个禁用
  644. multiple: true,
  645. // 显示搜索条件
  646. showSearch: true,
  647. updateSendOpen: false,
  648. // 总条数
  649. total: 0,
  650. //公司列表
  651. myQwCompanyList:[],
  652. //销售公司
  653. myCompanyList: [],
  654. // 企微用户表格数据
  655. userList: [],
  656. allowSelectOptions:[],
  657. // 弹出层标题
  658. bindAiTitle: "",
  659. bindAiOpen: false,
  660. qwLogin:{
  661. title:"",
  662. open:false,
  663. codeUrl:null,
  664. code:null,
  665. appKey:null,
  666. },
  667. qwLoginTwo:{
  668. title:"",
  669. open:false,
  670. codeUrl:null,
  671. code:null,
  672. appKey:null,
  673. },
  674. qwCode:{
  675. title:"",
  676. open:false,
  677. code:null,
  678. },
  679. cloudAPOpen:{
  680. open:false,
  681. admin:null,
  682. passWord:null,
  683. },
  684. callOpen:{
  685. open:false,
  686. title: '修改员工称呼',
  687. },
  688. callOpenFrom:{
  689. id:null,
  690. welcomeText:null,
  691. },
  692. isAutoForm:{
  693. id:null,
  694. isAuto:null,
  695. },
  696. editRemarkOpen: {
  697. open: false,
  698. title: '修改员工自动给完课客户打备注的规则',
  699. id:null,
  700. isSendMsg:null,
  701. },
  702. twoCodeInterval:null,
  703. type: 0,
  704. loginQwInterval:null,
  705. imageLoading: true, // 控制加载状态
  706. // 查询参数
  707. queryParams: {
  708. pageNum: 1,
  709. pageSize: 10,
  710. qwUserId: null,
  711. loginStatus: null,
  712. corpId: null,
  713. qwUserName: null,
  714. deptId:null,
  715. companyId: null,
  716. },
  717. qwUserId:null,
  718. companyUserList:[],
  719. // 表单参数
  720. form: {
  721. isSendMsg: '2',
  722. },
  723. authorizeKeyRule:{
  724. appKey:[{required:true,message:"授权码不能为空",trigger:"blur"}]
  725. },
  726. callOpenRule:{
  727. // welcomeText:[{required:true,message:"员工称呼不能为空",trigger:"blur"}]
  728. },
  729. // 表单校验
  730. rules: {
  731. },
  732. //欢迎语表单校验
  733. weclomeRules:{
  734. welcomeText:[{required:true,message:"消息文本不能为空",trigger:"blur"}]
  735. },
  736. };
  737. },
  738. created() {
  739. Promise.all([
  740. this.getDicts("qw_user_is_auto"),
  741. getCompanyList()
  742. ]).then(responses => {
  743. this.myCompanyList = responses[1].data;
  744. if(this.myCompanyList && this.myCompanyList.length > 0){
  745. this.queryParams.companyId = this.myCompanyList[0].companyId;
  746. }
  747. return getMyQwCompanyList(this.queryParams.companyId);
  748. }).then(response => {
  749. this.myQwCompanyList = response.data;
  750. if(this.myQwCompanyList && this.myQwCompanyList.length > 0){
  751. this.queryParams.corpId = this.myQwCompanyList[0].dictValue;
  752. if(this.queryParams.corpId){
  753. this.getTreeselect();
  754. }
  755. }
  756. // 最后获取列表数据
  757. this.getList();
  758. this.loading = false;
  759. });
  760. },
  761. watch: {
  762. // 监听弹窗的可见性变化
  763. 'qwLogin.open'(newVal) {
  764. if (!newVal) {
  765. // 如果弹窗关闭,清除定时器
  766. clearInterval(this.loginQwInterval);
  767. }
  768. },
  769. },
  770. methods: {
  771. /** 公司选择改变事件 */
  772. handleCompanyChange(companyId) {
  773. this.queryParams.corpId = null;
  774. this.queryParams.deptId = null;
  775. // 根据选择的公司获取对应的企微主体列表
  776. if (companyId) {
  777. getMyQwCompanyList(companyId).then(response => {
  778. this.myQwCompanyList = response.data;
  779. if (this.myQwCompanyList && this.myQwCompanyList.length > 0) {
  780. this.queryParams.corpId = this.myQwCompanyList[0].dictValue;
  781. if(this.queryParams.corpId){
  782. return this.getTreeselect(); // 返回Promise
  783. }
  784. } else {
  785. this.myQwCompanyList = [];
  786. this.queryParams.corpId = null;
  787. }
  788. }).then(() => {
  789. // 在所有异步操作完成后调用getList
  790. this.getList();
  791. }).catch(error => {
  792. console.error('获取企微主体列表失败:', error);
  793. this.myQwCompanyList = [];
  794. this.queryParams.corpId = null;
  795. this.getList(); // 即使出错也要调用getList
  796. });
  797. } else {
  798. this.myQwCompanyList = [];
  799. this.queryParams.corpId = null;
  800. this.getList(); // 没有companyId时也调用getList
  801. }
  802. },
  803. handleCorpChange(corpId) {
  804. this.queryParams.deptId = null;
  805. if (corpId) {
  806. // 等待 getTreeselect 完成后再调用 getList
  807. this.getTreeselect().then(() => {
  808. this.getList();
  809. });
  810. } else {
  811. this.getList(); // 没有 corpId 时也调用 getList
  812. }
  813. },
  814. /** 查询部门下拉树结构 */
  815. getTreeselect() {
  816. let query = {
  817. corpId: this.queryParams.corpId
  818. }
  819. // 企微主体不能为空
  820. if (!query.corpId) {
  821. this.$message.error("请选择企微主体");
  822. // 返回一个已解决的 Promise
  823. return Promise.resolve();
  824. }
  825. return treeselect(query).then((response) => {
  826. this.deptOptions = response.data;
  827. if (response.data != null && response.data.length > 0) {
  828. this.queryParams.deptId = response.data[0].id;
  829. }
  830. });
  831. },
  832. /** 树形选择器格式化 */
  833. normalizer(node) {
  834. return {
  835. id: node.id,
  836. label: node.label || node.name,
  837. children: node.children,
  838. // 判断是否为叶子节点,没有子节点时不能再展开
  839. isLeaf: !node.children || node.children.length === 0
  840. }
  841. },
  842. /** 动态加载选项 */
  843. loadOptions({ action, parentNode, callback }) {
  844. if (action === 'LOAD_CHILDREN') {
  845. // 根据父节点加载子节点
  846. let query = {
  847. corpId: this.queryParams.corpId,
  848. parentId: parentNode.id
  849. };
  850. treeselect(query).then(response => {
  851. const children = response.data || [];
  852. parentNode.children = children;
  853. // 根据实际子节点数量更新父节点的叶子节点状态
  854. parentNode.isLeaf = !children || children.length === 0;
  855. callback();
  856. }).catch(error => {
  857. console.error('加载子节点失败:', error);
  858. // 加载失败时设置为空数组和叶子节点
  859. parentNode.children = [];
  860. parentNode.isLeaf = true;
  861. callback();
  862. });
  863. }
  864. },
  865. getList() {
  866. this.loading = true;
  867. staffListUser(this.queryParams).then(response => {
  868. this.userList = response.rows;
  869. this.total = response.total;
  870. this.loading = false;
  871. });
  872. },
  873. changeVideoStatus(val){
  874. changeVideoStatus(val.id).then(res => {
  875. this.$message.success("修改状态成功");
  876. this.getList()
  877. })
  878. },
  879. //绑定AI客服
  880. bindFastGptRole(row) {
  881. this.bindAiTitle = "绑定AI客服";
  882. this.bindAiOpen = true;
  883. setTimeout(() => {
  884. this.$refs.fastGptRole.handleBindAiData(row)
  885. }, 200);
  886. },
  887. handleAppellation(val) {
  888. this.callOpen.open = true;
  889. this.callOpenFrom.welcomeText = val.welcomeText;
  890. this.callOpenFrom.id = val.id;
  891. },
  892. handleAutoRemark(val) {
  893. this.editRemarkOpen.open = true;
  894. this.editRemarkOpen.id = val.id;
  895. this.editRemarkOpen.isSendMsg = val.isSendMsg;
  896. },
  897. //登录
  898. handleLoginQwCode(val) {
  899. if (val.appKey == null || val.appKey === '') {
  900. return this.$message.warning("没有授权码,无法登录企业微信,请授权");
  901. }
  902. loginQwIpad({qwUserId: val.id}).then(res => {
  903. this.qwUserId = val.id;
  904. this.qwLogin.code = null;
  905. this.imageLoading = false;
  906. console.log(res)
  907. if (res.msg == "success") {
  908. this.qwLogin.codeUrl = res.qrCode64
  909. this.qwLogin.open = true;
  910. this.loginQwPolling();
  911. } else {
  912. this.$message.success(res.msg);
  913. this.getList()
  914. }
  915. })
  916. },
  917. handleTwoCode(val) {
  918. twoCode({qwUserId: val.id}).then(res => {
  919. console.log(res)
  920. this.qwLoginTwo.open = true;
  921. this.qwLoginTwo.codeUrl = res.qrCode
  922. });
  923. },
  924. twoCodePolling() {
  925. this.twoCodeInterval = setInterval(() => {
  926. twoCodeStatus({qwUserId: this.qwUserId}).then(res => {
  927. console.log(res)
  928. if (res.msg == 104001) {
  929. this.$message.success('登录成功');
  930. this.clearDl()
  931. clearInterval(this.loginQwInterval);
  932. } else if (res.msg == 100004) {
  933. this.clearDl()
  934. }
  935. });
  936. }, 3000);
  937. },
  938. loginQwPolling() {
  939. this.loginQwInterval = setInterval(() => {
  940. qrCodeStatus({qwUserId: this.qwUserId}).then(res => {
  941. console.log(res)
  942. if (res.msg == 22) {
  943. this.$message.success('账号企业不一致请重新扫码登录');
  944. this.clearDl();
  945. }
  946. if (res.msg == 23) {
  947. this.$message.success('账号不匹配,请同步信息后重新扫码登录');
  948. this.clearDl();
  949. }
  950. if (res.msg == 104001) {
  951. this.$message.success('登录成功');
  952. this.clearDl()
  953. } else if (res.msg == 100004) {
  954. this.qwCode.open = true;
  955. clearInterval(this.loginQwInterval);
  956. }
  957. });
  958. }, 3000);
  959. },
  960. submitCodeForm() {
  961. qrCodeVerify({code: this.qwCode.code, qwUserId: this.qwUserId}).then(res => {
  962. console.log(res)
  963. this.$message.success('验证成功账号信息确认中。。。。');
  964. this.qwCode.open = false;
  965. this.loginQwInterval = setTimeout(() => {
  966. qrCodeStatus({qwUserId: this.qwUserId}).then(res => {
  967. console.log(res);
  968. if (res.msg == 23) {
  969. this.$message.error('账号不一致请重新扫码登录');
  970. this.clearDl();
  971. }
  972. if (res.msg == 22) {
  973. this.$message.error('账号企业不一致请重新扫码登录');
  974. this.clearDl();
  975. }
  976. if (res.msg == 104001) {
  977. this.$message.success('登录成功');
  978. this.clearDl();
  979. }
  980. });
  981. }, 4000);
  982. });
  983. },
  984. clearDl() {
  985. this.qwCode.open = false;
  986. this.qwLogin.open = false;
  987. clearInterval(this.loginQwInterval);
  988. this.getList()
  989. },
  990. //退出
  991. handleLoginOutQwStatus(val) {
  992. outLoginQwIpad({qwUserId: val.id}).then(res => {
  993. this.$message.success("退出登录成功");
  994. this.getList()
  995. })
  996. },
  997. handleGetQwIpad(val) {
  998. getQwIpad({qwUserId: val.id}).then(res => {
  999. this.$message.success("获取主机成功");
  1000. this.getList();
  1001. }).catch(error => {
  1002. console.log(error);
  1003. if (error.code === 501) {
  1004. this.$confirm(
  1005. '当前区域没有多余的名额,将为你分配异地名额,会导致企业微信需要扫脸重新登录,并且半个小时后需要进行验证',
  1006. '提示',
  1007. {
  1008. confirmButtonText: '确定',
  1009. cancelButtonText: '取消',
  1010. type: 'warning',
  1011. dangerouslyUseHTMLString: true
  1012. }
  1013. ).then(() => {
  1014. return handleAllocateRemoteHost({qwUserId: val.id});
  1015. }).then(res => {
  1016. this.$message.success('异地主机分配成功');
  1017. this.getList();
  1018. }).catch(() => {
  1019. this.$message.info('已取消异地主机分配');
  1020. });
  1021. } else {
  1022. this.$message.error('获取主机失败');
  1023. }
  1024. });
  1025. },
  1026. handleDelQwIpad(val) {
  1027. delQwIpad({qwUserId: val.id}).then(res => {
  1028. this.$message.success("解绑主机成功");
  1029. }).finally(res => {
  1030. this.getList();
  1031. })
  1032. },
  1033. handleUpdateIsAuto(val,code) {
  1034. this.isAutoForm={
  1035. id:val.id,
  1036. isAuto:code
  1037. }
  1038. updateIsAuto(this.isAutoForm).then(res => {
  1039. if (code==='00'){
  1040. this.$message.success('禁用成功');
  1041. }else {
  1042. this.$message.success('启用成功');
  1043. }
  1044. this.getList();
  1045. });
  1046. },
  1047. //传验证码
  1048. handleLoginQwCodeMsg() {
  1049. loginQwCodeMsg({appKey: this.qwLogin.appKey, code: this.qwLogin.code}).then(res => {
  1050. this.qwLogin.open = false;
  1051. this.$message.success("登录成功");
  1052. })
  1053. },
  1054. validateCode() {
  1055. // 只允许输入数字并限制长度为6
  1056. this.qwLogin.code = this.qwLogin.code.replace(/\D/g, "").slice(0, 6);
  1057. },
  1058. handleCloudAP(urlAP) {
  1059. selectCloudAP({ipAddress: urlAP}).then(res => {
  1060. this.cloudAPOpen.open = true
  1061. this.cloudAPOpen.admin = res.data.apAdmin;
  1062. this.cloudAPOpen.passWord = res.data.apPassword;
  1063. })
  1064. },
  1065. handleUnbindCloudHost(val) {
  1066. const appKey = val.appKey;
  1067. this.$confirm(
  1068. '确定要给企微账号:<span style="color: green;">' + val.qwUserId + '' +
  1069. '</span><br>企微昵称:<span style="color: red;">【' + val.qwUserName + '】</span>' +
  1070. '</span><br><span style="color: orange;">解绑【Ps:解绑后此云主机可能会分配给他人】</span></span>',
  1071. "警告",
  1072. {
  1073. confirmButtonText: "确定",
  1074. cancelButtonText: "取消",
  1075. type: "warning",
  1076. dangerouslyUseHTMLString: true // 允许使用 HTML 字符串
  1077. }
  1078. ).then(() => {
  1079. return qwUnbindCloudHost(appKey);
  1080. }).then(response => {
  1081. this.$message.success('解绑成功');
  1082. }).finally(res => {
  1083. this.getList();
  1084. })
  1085. },
  1086. handleAuthorizeKey(val) {
  1087. this.authorizeKeyFrom.id = val.id;
  1088. this.authorizeKeyFrom.qwUserId = val.qwUserId;
  1089. this.authorizeKeyFrom.qwUserName = val.qwUserName;
  1090. this.authorizeKeyOpen = true;
  1091. },
  1092. submitAuthorizeKeyForm() {
  1093. this.$refs["authorizeKeyFrom"].validate(valid => {
  1094. if (valid) {
  1095. if (this.authorizeKeyFrom.id != null && this.authorizeKeyFrom.appKey != null) {
  1096. this.uploadAuthorizeKey();
  1097. }
  1098. }
  1099. });
  1100. },
  1101. submitCallOpenFrom() {
  1102. this.$refs["callOpenFrom"].validate(valid => {
  1103. if (valid) {
  1104. if (this.callOpenFrom.id != null && this.callOpenFrom.welcomeText != null) {
  1105. updateUser(this.callOpenFrom).then(res => {
  1106. this.$message.success('修改成功');
  1107. this.callOpen.open = false;
  1108. this.getList();
  1109. });
  1110. }
  1111. }
  1112. });
  1113. },
  1114. submitEditRemarkOpenFrom() {
  1115. if (this.editRemarkOpen.id != null && this.editRemarkOpen.isSendMsg != null) {
  1116. updateUser(this.editRemarkOpen).then(res => {
  1117. this.$message.success('修改成功');
  1118. this.editRemarkOpen.open = false;
  1119. this.getList();
  1120. });
  1121. } else {
  1122. this.$message.error("请选择条件")
  1123. }
  1124. },
  1125. uploadAuthorizeKey() {
  1126. this.$confirm(
  1127. '确定要给企微账号:<span style="color: green;">' + this.authorizeKeyFrom.qwUserId + '' +
  1128. '</span><br>企微昵称:<span style="color: red;">【' + this.authorizeKeyFrom.qwUserName + '】</span>' +
  1129. '</span><br>授权key:<span style="color: #04adf6;">【' + this.authorizeKeyFrom.appKey + '】</span>?',
  1130. "警告",
  1131. {
  1132. confirmButtonText: "确定",
  1133. cancelButtonText: "取消",
  1134. type: "warning",
  1135. dangerouslyUseHTMLString: true // 允许使用 HTML 字符串
  1136. }
  1137. ).then(() => {
  1138. this.authorizeKeyOpen = false;
  1139. return handleInputAuthAppKey(this.authorizeKeyFrom);
  1140. }).then(response => {
  1141. this.msgSuccess("授权key完成");
  1142. }).finally(res => {
  1143. this.resetAuthorizeKeyFrom();
  1144. this.getList();
  1145. })
  1146. },
  1147. uploadAuthorizeKey2(val) {
  1148. const id = val.id;
  1149. this.$confirm(
  1150. '确定要给企微账号:<span style="color: green;">' + val.qwUserId + '' +
  1151. '</span><br>企微昵称:<span style="color: red;">【' + val.qwUserName + '】</span>' +
  1152. '</span><br>授权key</span>?',
  1153. "警告",
  1154. {
  1155. confirmButtonText: "确定",
  1156. cancelButtonText: "取消",
  1157. type: "warning",
  1158. dangerouslyUseHTMLString: true // 允许使用 HTML 字符串
  1159. }
  1160. ).then(() => {
  1161. return handleAuthAppKey({id: id});
  1162. }).then(response => {
  1163. this.msgSuccess("授权key完成");
  1164. }).finally(res => {
  1165. this.resetAuthorizeKeyFrom();
  1166. this.getList();
  1167. })
  1168. },
  1169. handleBindCloudHost(val) {
  1170. if (val.appKey == null || val.appKey == '') {
  1171. return this.$message.warning('没有授权码,无法绑定主机,请联系管理员');
  1172. }
  1173. const appKey = val.appKey;
  1174. this.$confirm(
  1175. '确定要给企微账号:<span style="color: green;">' + val.qwUserId + '' +
  1176. '</span><br>企微昵称:<span style="color: red;">【' + val.qwUserName + '】</span>' +
  1177. '</span><br><span style="color: dodgerblue;">绑定云主机?</span></span>',
  1178. "警告",
  1179. {
  1180. confirmButtonText: "确定",
  1181. cancelButtonText: "取消",
  1182. type: "warning",
  1183. dangerouslyUseHTMLString: true // 允许使用 HTML 字符串
  1184. }
  1185. ).then(() => {
  1186. return qwBindCloudHost(appKey);
  1187. }).then(response => {
  1188. this.$message.success('绑定成功,请登录云主机进行配置~~');
  1189. }).finally(res => {
  1190. this.getList();
  1191. })
  1192. },
  1193. openImageViewer(url) {
  1194. // 打开大图预览对话框
  1195. this.dialogImageUrl = url
  1196. this.dialogVisible = true;
  1197. },
  1198. //刷新页面
  1199. refreshFastGptList() {
  1200. this.bindAiOpen = false;
  1201. this.getList();
  1202. },
  1203. // 取消按钮
  1204. cancel() {
  1205. this.open = false;
  1206. this.reset();
  1207. },
  1208. // 表单重置
  1209. reset() {
  1210. this.form = {
  1211. id: null,
  1212. qwUserId: null,
  1213. corpId: null,
  1214. qwUserName: null,
  1215. companyId: null,
  1216. };
  1217. this.resetForm("form");
  1218. },
  1219. //重置授权
  1220. resetAuthorizeKeyFrom() {
  1221. this.authorizeKeyFrom = {
  1222. id: null,
  1223. appKey: null,
  1224. qwUserId: null,
  1225. qwUserName: null
  1226. };
  1227. },
  1228. //重置登录
  1229. resetQwLogin() {
  1230. this.qwLogin = {
  1231. title: "",
  1232. open: false,
  1233. codeUrl: null,
  1234. code: null,
  1235. corpId: null,
  1236. qwUserId: null,
  1237. }
  1238. this.qwLogin.open = false;
  1239. this.loading = false;
  1240. this.getList();
  1241. },
  1242. //解绑AI客服
  1243. relieveFastGptRole(row) {
  1244. this.$confirm('是否确认解绑AI客服?', "警告", {
  1245. confirmButtonText: "确定",
  1246. cancelButtonText: "取消",
  1247. type: "warning"
  1248. }).then(function () {
  1249. return relieveFastGptRoleById(row.id);
  1250. }).then(() => {
  1251. this.getList();
  1252. this.msgSuccess("解绑成功");
  1253. })
  1254. },
  1255. updateFastGptRoleStatus(row) {
  1256. this.$confirm('是否修改该销售的AI客服?', "警告", {
  1257. confirmButtonText: "确定",
  1258. cancelButtonText: "取消",
  1259. type: "warning"
  1260. }).then(function () {
  1261. return updateFastGptRoleStatusById(row.id);
  1262. }).then(() => {
  1263. this.getList();
  1264. this.msgSuccess("修改成功");
  1265. })
  1266. },
  1267. /** 搜索按钮操作 */
  1268. handleQuery() {
  1269. this.queryParams.pageNum = 1;
  1270. this.getList();
  1271. },
  1272. /** 重置按钮操作 */
  1273. resetQuery() {
  1274. this.resetForm("queryForm");
  1275. this.deptOptions = null;
  1276. this.queryParams.deptId = null;
  1277. Promise.all([
  1278. this.getDicts("qw_user_is_auto"),
  1279. getCompanyList()
  1280. ]).then(responses => {
  1281. this.myCompanyList = responses[1].data;
  1282. if(this.myCompanyList && this.myCompanyList.length > 0){
  1283. this.queryParams.companyId = this.myCompanyList[0].companyId;
  1284. }
  1285. return getMyQwCompanyList(this.queryParams.companyId);
  1286. }).then(response => {
  1287. this.myQwCompanyList = response.data;
  1288. if(this.myQwCompanyList && this.myQwCompanyList.length > 0){
  1289. this.queryParams.corpId = this.myQwCompanyList[0].dictValue;
  1290. if(this.queryParams.corpId){
  1291. this.getTreeselect();
  1292. }
  1293. }
  1294. this.queryParams.loginStatus = null;
  1295. this.handleQuery();
  1296. });
  1297. },
  1298. // 多选框选中数据
  1299. handleSelectionChange(selection) {
  1300. this.ids = selection.map(item => item.id)
  1301. this.names = selection.map(item => item.qwUserName)
  1302. this.single = selection.length !== 1
  1303. this.multiple = !selection.length
  1304. },
  1305. /** 提交按钮 */
  1306. submitForm() {
  1307. this.$refs["form"].validate(valid => {
  1308. if (valid) {
  1309. if (this.form.id != null) {
  1310. // updateUser(this.form).then(response => {
  1311. // this.msgSuccess("绑定成功");
  1312. // this.open = false;
  1313. // this.getList();
  1314. //
  1315. // });
  1316. } else {
  1317. // addUser(this.form).then(response => {
  1318. // this.msgSuccess("新增成功");
  1319. // this.open = false;
  1320. // this.getList();
  1321. // });
  1322. }
  1323. }
  1324. });
  1325. },
  1326. /** 导出按钮操作 */
  1327. handleExport() {
  1328. const queryParams = this.queryParams;
  1329. this.$confirm('是否确认导出所有企微员工数据项?', "警告", {
  1330. confirmButtonText: "确定",
  1331. cancelButtonText: "取消",
  1332. type: "warning"
  1333. }).then(() => {
  1334. this.exportLoading = true;
  1335. return exportStaff(queryParams);
  1336. }).then(response => {
  1337. this.download(response.msg);
  1338. this.exportLoading = false;
  1339. }).catch(() => {
  1340. });
  1341. },
  1342. updateSendType() {
  1343. this.updateSendOpen = true;
  1344. },
  1345. cleanUpdateSendType() {
  1346. this.updateSendOpen = false;
  1347. },
  1348. submitUpdateSendTypeForm(){
  1349. updateSendType({ids: this.ids, type: this.type}).then(e => {
  1350. this.updateSendOpen = false;
  1351. this.$message.success("修改成功");
  1352. this.getList();
  1353. });
  1354. },
  1355. }
  1356. };
  1357. </script>
  1358. <style>
  1359. .text-container {
  1360. max-height: 7.5em; /* 设置最大高度为6行,根据字体大小调整 */
  1361. overflow-y: auto; /* 内容超出时显示滚动条 */
  1362. line-height: 1.5em; /* 行高设置,确保每行高度一致 */
  1363. }
  1364. .qr-login-dialog .el-dialog__body {
  1365. display: flex;
  1366. flex-direction: column;
  1367. align-items: center;
  1368. text-align: center;
  1369. padding: 20px;
  1370. }
  1371. .qr-login-container {
  1372. width: 100%;
  1373. }
  1374. .qr-login-instructions {
  1375. font-size: 14px;
  1376. color: #666;
  1377. margin: 10px 0;
  1378. }
  1379. .verification-code-input {
  1380. margin-top: 15px;
  1381. width: 80%;
  1382. }
  1383. .vue-treeselect{
  1384. width: 217px;
  1385. height: 36px;
  1386. }
  1387. </style>