index.vue 41 KB

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