login.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751
  1. <!-- 登录 -->
  2. <template>
  3. <view id="login">
  4. <!-- 服务信息 -->
  5. <view class="login-title-box">
  6. <image v-if="serverData.logo" class="logo-img" :src="serverData.logo"></image>
  7. <image v-else class="logo-img" :src="logoImg"></image>
  8. <p class="logo-title">{{serverData.title?serverData.title:'运维管理端'}}</p>
  9. </view>
  10. <!-- 选中服务信息 -->
  11. <view class="ip-max-box">
  12. <view class="ip-box-null"></view>
  13. <view class="ip-big-box" @click="showListBox(1)">
  14. <view class="ip-min-box" v-if="serverData.agreement && serverData.ip">
  15. <view class="ip-box-text">{{serverData.agreement}}://</view>
  16. <view class="ip-box-text">{{serverData.ip}}</view>
  17. </view>
  18. <view class="ip-text-box" v-else>
  19. <view class="ip-box-text">请选择服务</view>
  20. </view>
  21. <view class="ip-box-icon" :class="serverData.type?'ip-box-icon-true':'ip-box-icon-false'"></view>
  22. </view>
  23. <view class="ip-box-null"></view>
  24. </view>
  25. <!-- 登录窗口 -->
  26. <view class="login-max-big-box">
  27. <view class="login-input-box">
  28. <view>账号</view>
  29. <input type="text" v-model="username" placeholder="请输入账号" :maxlength="20">
  30. </view>
  31. <view class="login-input-box">
  32. <view>密码</view>
  33. <input type="password" v-model="password" placeholder="请输入密码" :maxlength="20">
  34. </view>
  35. <view class="login-input-box">
  36. <input v-model="code" placeholder="请输入验证码" :maxlength="10">
  37. <image :src="codeImg" @click="authCaptcha"></image>
  38. </view>
  39. <view class="login-button">
  40. <view @click="login">登录</view>
  41. </view>
  42. </view>
  43. <!-- 选择弹窗 -->
  44. <view class="position-max-big-box" v-if="serverIpAddressType">
  45. <view class="position-big-box">
  46. <view class="positon-title-box">
  47. <view class="positon-title">服务列表</view>
  48. <view class="positon-off" @click="showListBox(2)">关闭</view>
  49. </view>
  50. <view class="positon-list-box">
  51. <view class="positon-list-null" v-if="!serverIpAddress[0]">暂无数据</view>
  52. <view class="positon-for-box" @click="checkItem(index)"
  53. v-for="(item,index) in serverIpAddress" :key="index">
  54. <view class="positon-for-title-box">
  55. <view>{{item.name}}</view>
  56. <view>{{item.agreement}}://{{item.ip}}</view>
  57. </view>
  58. <view class="psoiton-check-box">
  59. <image v-if="checkIndex == index" :src="checkImg"></image>
  60. </view>
  61. </view>
  62. </view>
  63. <view class="positon-button-box">
  64. <view class="positon-button-left" @click="showListBox(3)">编辑</view>
  65. <view class="positon-button-del" @click="showListBox(5)">删除</view>
  66. <view class="positon-button-right" @click="showListBox(4)">确定</view>
  67. </view>
  68. </view>
  69. </view>
  70. <!-- 新增弹窗 -->
  71. <view class="position-max-big-box" v-if="serverIpAddressAddType">
  72. <view class="position-big-box">
  73. <view class="positon-title-box">
  74. <view class="positon-title">{{addTitle}}</view>
  75. <view class="positon-off" @click="showAddBox(2)">关闭</view>
  76. </view>
  77. <view class="positon-list-box">
  78. <view class="add-input-box">
  79. <view class="add-input-icon">*</view>
  80. <view class="add-input-title">服务名称:</view>
  81. <input class="add-input" v-model="addForm.name" type="text" placeholder="请输入服务名称" placeholder-style="color:#999;">
  82. </view>
  83. <view class="add-input-box">
  84. <view class="add-input-icon">*</view>
  85. <view class="add-input-title">协议:</view>
  86. <picker class="add-input" @change="agreementChange" :value="agreementIndex" :range="agreementArray">
  87. <view
  88. :class="!addForm.agreement?'add-input-placeholder':''">
  89. {{addForm.agreement?addForm.agreement:'请选择协议'}}
  90. </view>
  91. </picker>
  92. </view>
  93. <view class="add-input-box">
  94. <view class="add-input-icon">*</view>
  95. <view class="add-input-title">地址:</view>
  96. <input class="add-input" v-model="addForm.ip" type="text" placeholder="请输入IP地址" placeholder-style="color:#999;">
  97. </view>
  98. </view>
  99. <view class="positon-button-box">
  100. <view class="positon-button-right" @click="showAddBox(3)">保存</view>
  101. </view>
  102. </view>
  103. </view>
  104. </view>
  105. </template>
  106. <script>
  107. import md5 from '@/utils/md5.js'
  108. import { Encrypt,Decrypt} from '@/utils/secret'
  109. import { authConfigInfo,authCaptcha,login,systemMenuGetRouters,getConfigByType } from '@/api/index.js'
  110. export default {
  111. data() {
  112. return {
  113. //选中服务器
  114. serverData:{},
  115. //服务器列表
  116. serverIpAddress:[],
  117. serverIpAddressType:false,
  118. checkIndex:null,
  119. logoImg:require('@/images/logo.png'),
  120. checkImg:require('@/images/check.png'),
  121. //新增相关
  122. serverIpAddressAddType:false,
  123. addForm:{},
  124. addType:null,
  125. agreementArray:['http','https'],
  126. agreementIndex:0,
  127. //账号密码
  128. username:'',
  129. password:'',
  130. code:'',
  131. codeImg:'',
  132. uuid:'',
  133. //新增窗口名称
  134. addTitle:'',
  135. }
  136. },
  137. onLoad(option) {
  138. },
  139. onShow(){
  140. this.getServerIpAddress();
  141. },
  142. methods: {
  143. //初始化
  144. getServerIpAddress(){
  145. //获取本地服务器数据
  146. let list = uni.getStorageSync('serverIpAddress');
  147. this.$set(this,'serverIpAddress',list[0]?list:[]);
  148. },
  149. //使用ip地址
  150. setIpConfig(data){
  151. let self = this;
  152. uni.setStorageSync('serverConfig',data)
  153. setTimeout(function(){
  154. self.authConfigInfo(data);
  155. },200);
  156. },
  157. //获取验证码
  158. async authCaptcha(){
  159. if(this.serverData.type){
  160. const {data} = await authCaptcha();
  161. if(data.code == 200){
  162. this.$set(this,'codeImg',"data:image/gif;base64," + data.data.image);
  163. this.$set(this,'uuid',data.data.uuid);
  164. }
  165. }
  166. },
  167. //获取首页配置
  168. async authConfigInfo(item){
  169. let self = this;
  170. const {data} = await authConfigInfo({type:'1'});
  171. if(!data){
  172. this.$set(this,'serverData',{
  173. title:null,
  174. logo:null,
  175. name:item.name,
  176. agreement:item.agreement,
  177. ip:item.ip,
  178. type:false,
  179. });
  180. this.$set(this,'uuid','');
  181. this.$set(this,'codeImg','');
  182. }else if(data.code==200){
  183. let obj = JSON.parse(JSON.parse(data.data)[0].configValue);
  184. this.$set(this,'serverData',{
  185. title:obj.schoolName,
  186. logo:item.agreement + '://' + item.ip + obj.circularLogo,
  187. // logo:'https://img1.baidu.com/it/u=2134768505,3615749700&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500',
  188. name:item.name,
  189. agreement:item.agreement,
  190. ip:item.ip,
  191. type:true,
  192. });
  193. self.authCaptcha();
  194. }else{
  195. this.$set(this,'serverData',{
  196. title:obj.schoolName,
  197. logo:item.agreement + '://' + item.ip + obj.circularLogo,
  198. // logo:'https://img1.baidu.com/it/u=2134768505,3615749700&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500',
  199. name:item.name,
  200. agreement:item.agreement,
  201. ip:item.ip,
  202. type:false,
  203. });
  204. this.$set(this,'uuid','');
  205. this.$set(this,'codeImg','');
  206. }
  207. },
  208. //展示服务器列表按钮
  209. showListBox(type){
  210. let self = this;
  211. if(type == 1){
  212. //开启
  213. this.$set(this,'checkIndex',null);
  214. uni.showActionSheet({
  215. itemList: ['新增', '切换'],
  216. success (res) {
  217. if(res.tapIndex == 0){
  218. self.showAddBox(1)
  219. }else if(res.tapIndex == 1){
  220. self.$set(self,'serverIpAddressType',true);
  221. }
  222. },
  223. fail (res) {
  224. }
  225. });
  226. }else if(type == 2){
  227. //关闭
  228. this.$set(this,'serverIpAddressType',false);
  229. }else if(type == 3){
  230. //选中编辑
  231. if(this.checkIndex != null){
  232. this.$set(this,'addTitle','编辑服务');
  233. this.$set(this,'addType',2);
  234. this.$set(this,'addForm',JSON.parse(JSON.stringify(this.serverIpAddress[this.checkIndex])));
  235. this.$set(this,'serverIpAddressType',false);
  236. this.$set(this,'serverIpAddressAddType',true);
  237. }else{
  238. uni.showToast({
  239. mask:true,
  240. icon:"none",
  241. position:"center",
  242. title: '请选择服务',
  243. duration: 1000
  244. });
  245. }
  246. }else if(type == 4){
  247. //选中确定
  248. if(this.checkIndex != null){
  249. this.setIpConfig(JSON.parse(JSON.stringify(this.serverIpAddress[this.checkIndex])));
  250. this.$set(this,'serverIpAddressType',false);
  251. }else{
  252. uni.showToast({
  253. mask:true,
  254. icon:"none",
  255. position:"center",
  256. title: '请选择服务',
  257. duration: 1000
  258. });
  259. }
  260. }else if(type == 5){
  261. //选中删除
  262. if(this.checkIndex != null){
  263. this.serverIpAddress.splice(this.checkIndex,1);
  264. this.$set(this,'checkIndex',null);
  265. uni.setStorageSync('serverIpAddress',this.serverIpAddress);
  266. }else{
  267. uni.showToast({
  268. mask:true,
  269. icon:"none",
  270. position:"center",
  271. title: '请选择服务',
  272. duration: 1000
  273. });
  274. }
  275. }
  276. },
  277. //选中服务器
  278. checkItem(index){
  279. this.$set(this,'checkIndex',index)
  280. },
  281. //新增服务按钮
  282. showAddBox(type){
  283. let self = this;
  284. if(type == 1){
  285. //开启
  286. self.$set(self,'addTitle','新增服务');
  287. self.$set(self,'addForm',{
  288. name:'',
  289. agreement:'',
  290. ip:'',
  291. });
  292. self.$set(self,'addType',1);
  293. self.$set(self,'serverIpAddressAddType',true);
  294. }else if(type == 2){
  295. //关闭
  296. self.$set(self,'serverIpAddressAddType',false);
  297. }else if(type == 3){
  298. //提交
  299. if(!this.addForm.name){
  300. uni.showToast({
  301. mask:true,
  302. icon:"none",
  303. position:"center",
  304. title: '请输入服务名称',
  305. duration: 1000
  306. });
  307. return
  308. }
  309. if(!this.addForm.agreement){
  310. uni.showToast({
  311. mask:true,
  312. icon:"none",
  313. position:"center",
  314. title: '请选择协议',
  315. duration: 1000
  316. });
  317. return
  318. }
  319. if(!this.addForm.ip){
  320. uni.showToast({
  321. mask:true,
  322. icon:"none",
  323. position:"center",
  324. title: '请输入IP地址',
  325. duration: 1000
  326. });
  327. return
  328. }
  329. let obj = JSON.parse(JSON.stringify(this.addForm))
  330. if(this.addType == 1){
  331. //新增
  332. this.serverIpAddress.push(obj);
  333. uni.setStorageSync('serverIpAddress',this.serverIpAddress);
  334. this.setIpConfig(obj);
  335. this.$set(self,'serverIpAddressAddType',false);
  336. }else if(this.addType == 2){
  337. //编辑
  338. this.$set(self.serverIpAddress,this.checkIndex,obj);
  339. uni.setStorageSync('serverIpAddress',this.serverIpAddress);
  340. this.setIpConfig(obj);
  341. this.$set(self,'serverIpAddressAddType',false);
  342. }
  343. }
  344. },
  345. //选中协议
  346. agreementChange(event){
  347. this.$set(this,'agreementIndex',event.target.value);
  348. this.$set(this.addForm,'agreement',this.agreementArray[event.target.value]);
  349. },
  350. //登录
  351. async login(){
  352. let self = this;
  353. if(!this.serverData.type){
  354. uni.showToast({
  355. mask:true,
  356. icon:"none",
  357. position:"center",
  358. title: '当前服务不可用,请选择其他服务.',
  359. duration: 2000
  360. });
  361. }else{
  362. if(!this.username){
  363. uni.showToast({
  364. mask:true,
  365. icon:"none",
  366. position:"center",
  367. title: '请输入账号',
  368. duration: 1000
  369. });
  370. return
  371. }
  372. if(!this.password){
  373. uni.showToast({
  374. mask:true,
  375. icon:"none",
  376. position:"center",
  377. title: '请输入密码',
  378. duration: 1000
  379. });
  380. return
  381. }
  382. if(!this.code){
  383. uni.showToast({
  384. mask:true,
  385. icon:"none",
  386. position:"center",
  387. title: '请输入验证码',
  388. duration: 1000
  389. });
  390. return
  391. }
  392. let obj = {
  393. account:this.username,
  394. password:md5.hex_md5(this.password),
  395. code:this.code,
  396. uuid:this.uuid,
  397. }
  398. const {data} = await login(obj)
  399. if(data.code == 200){
  400. if(data.data.userType == 0){
  401. uni.setStorageSync('token',data.data.token);
  402. // 等待配置与字段获取到后跳转
  403. Promise.all([
  404. //获取路由判断权限
  405. this.systemMenuGetRouters(),
  406. this.getConfigByType(),
  407. ]).then((result)=>{
  408. uni.reLaunch({
  409. url: '/pages/basicsModule/home',
  410. });
  411. }).catch((error) => {
  412. wx.showToast({
  413. title: '数据异常,请稍候再试!',
  414. icon: "none",
  415. duration: 3000
  416. });
  417. })
  418. }else{
  419. uni.showToast({
  420. mask:true,
  421. icon:"none",
  422. position:"center",
  423. title: '只限系统用户登录',
  424. duration: 1000
  425. });
  426. }
  427. }else{
  428. uni.showToast({
  429. mask: true,
  430. icon: "none",
  431. position: "center",
  432. title: data.message,
  433. duration: 2000
  434. });
  435. setTimeout(function(){
  436. self.authCaptcha();
  437. },1800);
  438. }
  439. }
  440. },
  441. //获取路由
  442. async systemMenuGetRouters(){
  443. let self = this;
  444. const {data} = await systemMenuGetRouters();
  445. if(data.code==200){
  446. let permissionsList = [];
  447. forListFunction(data.data);
  448. function forListFunction(newList){
  449. for(let i=0;i<newList.length;i++){
  450. if(newList[i].perms){
  451. permissionsList.push(newList[i].perms)
  452. }
  453. if(newList[i].child){
  454. forListFunction(newList[i].child)
  455. }
  456. }
  457. }
  458. uni.setStorageSync('permissions',permissionsList)
  459. }
  460. },
  461. //获取公共配置
  462. async getConfigByType(){
  463. let self = this;
  464. const {data} = await getConfigByType({ category: 2, configType: 5 });
  465. if(data.code==200){
  466. let obj = JSON.parse(data.data.configValue)
  467. uni.setStorageSync('fileBrowseEnvironment',Decrypt(obj.fileBrowseEnvironment))
  468. }
  469. },
  470. }
  471. }
  472. </script>
  473. <style lang="stylus" scoped>
  474. #login{
  475. flex:1;
  476. display: flex;
  477. flex-direction: column;
  478. overflow: hidden;
  479. .login-title-box{
  480. .logo-img{
  481. display: block;
  482. width:200rpx;
  483. height:200rpx;
  484. margin:40rpx auto 0;
  485. }
  486. .logo-title{
  487. text-align: center;
  488. font-size:36rpx;
  489. font-weight:700;
  490. line-height:40rpx;
  491. margin-top:40rpx;
  492. }
  493. }
  494. .ip-max-box{
  495. margin-top:40rpx;
  496. display: flex
  497. .ip-big-box{
  498. display: flex
  499. border:1rpx solid #dedede;
  500. border-radius:8rpx;
  501. padding:0 15px;
  502. box-shadow: 0 0 8px 1px rgba(0, 0, 0, 0.1);
  503. background-color: #fff;
  504. .ip-min-box{
  505. display: flex
  506. .ip-box-text{
  507. height:60rpx;
  508. line-height:60rpx;
  509. color: #666;
  510. font-size:26rpx;
  511. }
  512. }
  513. .ip-text-box{
  514. .ip-box-text{
  515. height:60rpx;
  516. line-height:60rpx;
  517. color: #666;
  518. font-size:26rpx;
  519. }
  520. }
  521. .ip-box-icon{
  522. width:20rpx;
  523. height:20rpx;
  524. border-radius:50%;
  525. margin:20rpx 0 0 20rpx;
  526. }
  527. .ip-box-icon-true{
  528. background-color: #32cd32;
  529. }
  530. .ip-box-icon-false{
  531. background-color: #ff4500;
  532. }
  533. }
  534. .ip-box-null{
  535. flex:1;
  536. }
  537. }
  538. .position-max-big-box{
  539. z-index:100;
  540. position: absolute;
  541. bottom:0;
  542. left:0;
  543. width:100%;
  544. height:100%;
  545. background-color: rgba(0,0,0,0.6);
  546. .position-big-box{
  547. width:80%;
  548. height:80%;
  549. margin-left:10%;
  550. margin-top:10%;
  551. border-radius:16rpx;
  552. display: flex;
  553. flex-direction:column;
  554. overflow: hidden;
  555. .positon-title-box{
  556. display: flex;
  557. position: relative;
  558. background-color: #fff;
  559. border-bottom:1px solid #dedede;
  560. .positon-title{
  561. flex:1;
  562. line-height:100rpx;
  563. text-align:center;
  564. font-size:30rpx;
  565. }
  566. .positon-off{
  567. flex:1;
  568. position: absolute;
  569. right:20rpx;
  570. top:20rpx;
  571. width:100rpx;
  572. line-height:60rpx;
  573. font-size:28rpx;
  574. background-color: #999;
  575. color: #fff;
  576. text-align: center;
  577. border-radius:6rpx;
  578. }
  579. }
  580. .positon-list-box{
  581. flex:1;
  582. background-color: #fff;
  583. padding:20rpx;
  584. overflow-y: scroll;
  585. overflow-x: hidden;
  586. .positon-list-null{
  587. font-size:28rpx;
  588. text-align:center;
  589. line-height:100rpx;
  590. color:#999;
  591. }
  592. .positon-for-box:nth-child(odd){
  593. background-color: #dddddd;
  594. }
  595. .positon-for-box:nth-child(even){
  596. background-color: #eeeeee;
  597. }
  598. .positon-for-box{
  599. display: flex;
  600. padding:15rpx 20rpx 10rpx;
  601. .positon-for-title-box{
  602. flex:1;
  603. display: flex;
  604. flex-direction: column;
  605. view{
  606. color:#333;
  607. }
  608. view:nth-child(1){
  609. line-height:50rpx;
  610. font-size:28rpx;
  611. }
  612. view:nth-child(2){
  613. line-height:40rpx;
  614. font-size:24rpx;
  615. }
  616. }
  617. .psoiton-check-box{
  618. width:60rpx;
  619. height:100rpx;
  620. image{
  621. display: block;
  622. height:30rpx;
  623. width:38rpx;
  624. margin-top:30rpx;
  625. }
  626. }
  627. }
  628. .add-input-box{
  629. display: flex;
  630. margin:40rpx 0 0 0;
  631. .add-input-icon{
  632. width:30rpx;
  633. text-align: right;
  634. color:#FF6666;
  635. margin-right:10rpx;
  636. font-size:28rpx;
  637. line-height:60rpx;
  638. }
  639. .add-input-title{
  640. color:#333;
  641. width:150rpx;
  642. font-size:28rpx;
  643. line-height:60rpx;
  644. }
  645. .add-input{
  646. display: block
  647. flex:1;
  648. margin-right:40rpx;
  649. border:1px solid #dedede;
  650. border-radius:8rpx;
  651. height:60rpx;
  652. line-height:60rpx;
  653. font-size:24rpx;
  654. padding:0 20rpx;
  655. input{
  656. height:60rpx;
  657. line-height:60rpx;
  658. font-size:24rpx;
  659. }
  660. }
  661. .add-input-placeholder{
  662. color: #999 !important;
  663. }
  664. }
  665. }
  666. .positon-button-box{
  667. height:80rpx;
  668. border-top:1px solid #dedede;
  669. display:flex;
  670. .positon-button-left{
  671. flex:1;
  672. line-height:80rpx;
  673. color:#fff;
  674. background-color:#3ea3e9;
  675. text-align: center;
  676. font-size:24rpx;
  677. }
  678. .positon-button-del{
  679. flex:1;
  680. line-height:80rpx;
  681. color:#fff;
  682. background-color:#FF6666;
  683. text-align: center;
  684. font-size:24rpx;
  685. }
  686. .positon-button-right{
  687. flex:1;
  688. line-height:80rpx;
  689. color:#fff;
  690. background-color:#0183FA;
  691. text-align: center;
  692. font-size:24rpx;
  693. }
  694. }
  695. }
  696. }
  697. .login-max-big-box{
  698. margin:100rpx auto;
  699. width:600rpx;
  700. height:460rpx;
  701. background-color: #fff;
  702. box-shadow: 0 0 8px 1px rgba(0, 0, 0, 0.1);
  703. border-radius:12rpx;
  704. overflow: hidden;
  705. .login-input-box{
  706. display: flex;
  707. width:500rpx;
  708. margin:40rpx auto 0;
  709. border:1px solid #dedede;
  710. border-radius:8rpx;
  711. view{
  712. text-align: center;
  713. width:100rpx;
  714. border-right:1px solid #dedede;
  715. line-height:60rpx;
  716. font-size:26rpx;
  717. color:#333;
  718. }
  719. input{
  720. padding:0 20rpx;
  721. flex:1;
  722. height:60rpx;
  723. font-size:26rpx;
  724. line-height:60rpx;
  725. color:#333;
  726. }
  727. image{
  728. border-left:1px solid #dedede;
  729. width:160rpx;
  730. height:60rpx;
  731. }
  732. }
  733. .login-button{
  734. border-radius:8rpx;
  735. text-align: center;
  736. width:260rpx;
  737. margin:40rpx auto 0;
  738. background-color:#0183FA;
  739. color:#fff;
  740. height:60rpx;
  741. font-size:26rpx;
  742. line-height:60rpx;
  743. }
  744. }
  745. }
  746. </style>