login.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  1. <template>
  2. <view class="login-page">
  3. <!-- 顶部插画区 -->
  4. <view class="login-header">
  5. <image class="header-bg" src="/static/desk-img/1-2.png" mode="aspectFill"></image>
  6. <view class="header-mask"></view>
  7. <view class="header-content">
  8. <view class="header-top">
  9. <image class="logo" src="/static/desk-img/1-1.png" mode="aspectFit"></image>
  10. <u-icon name="setting-fill" color="#2979ff" size="22" @click="setIp"></u-icon>
  11. </view>
  12. <view class="welcome-text">您好,欢迎使用</view>
  13. <view class="platform-name">“一通三防”智能管控平台</view>
  14. </view>
  15. </view>
  16. <!-- 登录表单 -->
  17. <view class="login-body" v-if="!ipShow">
  18. <view class="form-area">
  19. <view class="input-item">
  20. <u-icon name="account-fill" color="#2979ff" size="22"></u-icon>
  21. <input
  22. class="input-field"
  23. placeholder="账号"
  24. placeholder-class="input-placeholder"
  25. v-model="userName"
  26. />
  27. </view>
  28. <view class="input-item">
  29. <u-icon name="lock-fill" color="#2979ff" size="22"></u-icon>
  30. <input
  31. class="input-field"
  32. placeholder="密码"
  33. placeholder-class="input-placeholder"
  34. :password="!showPassword"
  35. v-model="password"
  36. />
  37. <u-icon
  38. :name="showPassword ? 'eye-fill' : 'eye-off'"
  39. color="#2979ff"
  40. size="22"
  41. @click="changePassword"
  42. ></u-icon>
  43. </view>
  44. <view class="sso-link" @click="changeloginType">切换单点登录</view>
  45. </view>
  46. <view class="footer-area">
  47. <button
  48. class="login-btn"
  49. :loading="loading"
  50. :disabled="loading"
  51. @tap="onLogin"
  52. >
  53. {{ loading ? "登录中..." : "登录" }}
  54. </button>
  55. <!-- #ifdef APP-PLUS -->
  56. <view class="version-text">当前版本:{{ version }}</view>
  57. <!-- #endif -->
  58. </view>
  59. </view>
  60. <!-- 登录加载弹窗 -->
  61. <view class="cu-load load-modal" v-if="loading">
  62. <image src="/static/desk-img/144.png" mode="aspectFit" class="round"></image>
  63. <view class="gray-text">登录中...</view>
  64. </view>
  65. <!-- IP 配置 -->
  66. <view class="ip-panel" v-if="ipShow">
  67. <view class="IPSet">
  68. <span class="text-style">
  69. <u-button
  70. :plain="true"
  71. color="#18a5ff"
  72. size="small"
  73. :text="IPSet ? IPSet : '选择IP地址'"
  74. @tap="changeIP()"
  75. ></u-button>
  76. </span>
  77. <u-picker
  78. :show="ipShow1"
  79. :columns="IpConfig"
  80. @cancel="ipShow = false"
  81. @confirm="selectIpAddr"
  82. keyName="label"
  83. ></u-picker>
  84. </view>
  85. </view>
  86. </view>
  87. </template>
  88. <script>
  89. import { ACCESS_TOKEN, USER_NAME, USER_INFO } from "@/common/util/constants";
  90. import { mapActions } from "vuex";
  91. import configService from "@/common/service/config.service.js";
  92. import { AesEncryption, getLoginCipher } from "@/common/util/cipher.js";
  93. import api from "@/api/api";
  94. export default {
  95. data() {
  96. return {
  97. ipShow: false,
  98. ipShow1: false,
  99. shape: "", //round 圆形
  100. loading: false,
  101. userName: "",
  102. password: "",
  103. phoneNo: "",
  104. smsCode: "",
  105. showPassword: false, //是否显示明文
  106. smsCountDown: 0,
  107. smsCountInterval: null,
  108. toggleDelay: false,
  109. version: "",
  110. //第三方登录相关信息
  111. thirdType: "",
  112. thirdLoginInfo: "",
  113. thirdLoginState: false,
  114. bindingPhoneModal: false,
  115. thirdUserUuid: "",
  116. IPValue: "",
  117. PortValue: "",
  118. fullIPVal: "", //完整IP地址
  119. IPSet: "",
  120. IpConfig: [
  121. [
  122. {
  123. label: "大柳塔井",
  124. value: "http://10.248.135.10:9999",
  125. code: "dlt",
  126. },
  127. {
  128. label: "活鸡兔井",
  129. value: "http://10.248.135.121:9999",
  130. code: "hjt",
  131. },
  132. {
  133. label: "寸草塔二矿",
  134. value: "http://10.246.63.5:9999",
  135. code: "cctr",
  136. },
  137. {
  138. label: "乌兰木伦",
  139. value: "http://10.246.183.35:9999",
  140. code: "wlml",
  141. },
  142. {
  143. label: "哈拉沟煤矿",
  144. value: "http://10.248.223.12:9999",
  145. code: "hlg",
  146. },
  147. { label: "布尔台", value: "http://10.246.95.4:9999", code: "brt" },
  148. { label: "上湾", value: "http://10.246.167.205:9999", code: "sw" },
  149. { label: "锦界", value: "http://10.248.151.42:9999", code: "jj" },
  150. { label: "补连塔", value: "http://10.246.175.16:9999", code: "blt" },
  151. { label: "寸草塔", value: "http://10.246.23.171:9999", code: "cct" },
  152. { label: "柳塔", value: "http://10.246.87.121:9999", code: "lt" },
  153. { label: "石圪台", value: "http://10.246.191.13:9999", code: "sgt" },
  154. { label: "榆家梁", value: "http://10.248.143.211:9999", code: "yjl" },
  155. { label: "保德", value: "http://10.248.210.152:9999", code: "bd" },
  156. ],
  157. ],
  158. };
  159. },
  160. onLoad: function (option) {
  161. console.log("=======option.ticket======" + JSON.stringify(option.ticket));
  162. this.loginCas(option.ticket);
  163. // #ifdef APP-PLUS
  164. var that = this;
  165. plus.runtime.getProperty(plus.runtime.appid, function (wgtinfo) {
  166. that.version = wgtinfo.version;
  167. });
  168. // #endif
  169. },
  170. computed: {
  171. hasBaseUrl() {
  172. return configService.hasBaseUrl;
  173. },
  174. isSendSMSEnable() {
  175. return this.smsCountDown <= 0 && this.phoneNo.length > 4;
  176. },
  177. getSendBtnText() {
  178. if (this.smsCountDown > 0) {
  179. return this.smsCountDown + "秒后发送";
  180. } else {
  181. return "发送验证码";
  182. }
  183. },
  184. canSMSLogin() {
  185. return this.userName.length > 4 && this.smsCode.length > 4;
  186. },
  187. canPwdLogin() {
  188. return this.userName.length > 4 && this.password.length > 4;
  189. },
  190. },
  191. methods: {
  192. ...mapActions(["mLogin", "PhoneLogin", "ThirdLogin"]),
  193. // 判断是否在APP环境中
  194. isApp() {
  195. return typeof plus !== "undefined";
  196. },
  197. onLogin: function () {
  198. if (!this.userName || this.userName.length == 0) {
  199. this.$tip.toast("请填写用户名");
  200. return;
  201. }
  202. if (!this.password || this.password.length == 0) {
  203. this.$tip.toast("请填写密码");
  204. return;
  205. }
  206. let loginParams = {
  207. username: this.userName,
  208. password: this.password,
  209. clientId: uni.getStorageSync("push_cid"),
  210. };
  211. // 加密
  212. const loginCipher = getLoginCipher();
  213. const encryption = new AesEncryption({
  214. key: loginCipher.key,
  215. iv: loginCipher.iv,
  216. });
  217. loginParams.password = encryption.encryptByAES(loginParams.password);
  218. this.loading = true;
  219. this.mLogin(loginParams)
  220. .then((res) => {
  221. this.loading = false;
  222. if (res.data.success) {
  223. if (this.isApp()) {
  224. // console.log('当前是APP环境');
  225. this.saveClientId();
  226. } else {
  227. this.getPermissionList();
  228. }
  229. // #ifdef APP-PLUS
  230. // #endif
  231. // #ifndef APP-PLUS
  232. // #endif
  233. } else {
  234. this.$tip.alert(res.data.message);
  235. }
  236. })
  237. .catch((err) => {
  238. let msg = err.data.message || "请求出现错误,请稍后再试";
  239. this.loading = false;
  240. this.$tip.alert(msg);
  241. })
  242. .finally(() => {
  243. this.loading = false;
  244. });
  245. },
  246. loginCas(value) {
  247. var than = this;
  248. // this.$tip.success(configService.apiUrl);
  249. var ser = configService.apiUrl;
  250. ser = ser.replace(9999, 8092);
  251. // this.$tip.success(ser);
  252. new Promise((resolve, reject) => {
  253. api
  254. .validateCasLogin(
  255. "",
  256. "?ticket=" + value + "&service=" + encodeURIComponent(ser)
  257. )
  258. .then((response) => {
  259. // than.$tip.success("登录成功1");
  260. // if (response.data.code == 200) {
  261. // uni.setStorageSync(ACCESS_TOKEN, response.data.result.token);
  262. // } else {
  263. // }
  264. const result = response.data.result;
  265. const userInfo = result.userInfo;
  266. uni.setStorageSync(ACCESS_TOKEN, result.token);
  267. uni.setStorageSync(USER_INFO, userInfo);
  268. console.log("userInfo=" + userInfo);
  269. than.$store.commit("SET_TOKEN", result.token);
  270. console.log("result.token=" + result.token);
  271. than.$store.commit("SET_DICT", result.sysAllDictItems);
  272. than.$store.commit("SET_AVATAR", userInfo.avatar);
  273. than.$store.commit("SET_NAME", {
  274. username: userInfo.username,
  275. realname: userInfo.realname,
  276. });
  277. // than.$tip.success("loginCas=");
  278. than.getPermissionList();
  279. })
  280. .catch((error) => {
  281. // debugger;
  282. console.log("catch===>response", error);
  283. // uni.navigateTo({
  284. // url: "/pages/home/home",
  285. // });
  286. });
  287. });
  288. },
  289. //获取权限菜单
  290. getPermissionList() {
  291. new Promise((resolve, reject) => {
  292. api
  293. .getPermission({})
  294. .then((response) => {
  295. console.log(response, "权限菜单----------------");
  296. if (response.statusCode == 200) {
  297. let data = response.data.result.menuApp;
  298. let dataBtn = response.data.result.appauth;
  299. uni.setStorageSync("menuPermission", data);
  300. uni.setStorageSync("btnPermission", dataBtn);
  301. this.$tip.success("登录成功!");
  302. uni.navigateTo({
  303. url: "/pages/index/index",
  304. });
  305. } else {
  306. reject(response);
  307. }
  308. })
  309. .catch((error) => {
  310. console.log("catch===>response", response);
  311. reject(error);
  312. });
  313. });
  314. },
  315. saveClientId() {
  316. this.getPermissionList();
  317. // var info = plus.push.getClientInfo();
  318. // var cid = info.clientid;
  319. // this.$http
  320. // .get("/sys/user/saveClientId", { params: { clientId: cid } })
  321. // .then((res) => {
  322. // console.log("res::saveClientId>", res);
  323. // //获取权限菜单
  324. // this.getPermissionList();
  325. // });
  326. },
  327. changePassword() {
  328. this.showPassword = !this.showPassword;
  329. },
  330. onSMSSend() {
  331. let smsParams = {};
  332. smsParams.mobile = this.phoneNo;
  333. smsParams.smsmode = "0";
  334. let checkPhone = new RegExp(/^[1]([3-9])[0-9]{9}$/);
  335. if (!smsParams.mobile || smsParams.mobile.length == 0) {
  336. this.$tip.toast("请输入手机号");
  337. return false;
  338. }
  339. if (!checkPhone.test(smsParams.mobile)) {
  340. this.$tip.toast("请输入正确的手机号");
  341. return false;
  342. }
  343. this.$http.post("/sys/sms", smsParams).then((res) => {
  344. if (res.data.success) {
  345. this.smsCountDown = 60;
  346. this.startSMSTimer();
  347. } else {
  348. this.smsCountDown = 0;
  349. this.$tip.toast(res.data.message);
  350. }
  351. });
  352. },
  353. startSMSTimer() {
  354. this.smsCountInterval = setInterval(() => {
  355. this.smsCountDown--;
  356. if (this.smsCountDown <= 0) {
  357. clearInterval(this.smsCountInterval);
  358. }
  359. }, 1000);
  360. },
  361. onSMSLogin() {
  362. let checkPhone = new RegExp(/^[1]([3-9])[0-9]{9}$/);
  363. if (!this.phoneNo || this.phoneNo.length == 0) {
  364. this.$tip.toast("请填写手机号");
  365. return;
  366. }
  367. if (!checkPhone.test(this.phoneNo)) {
  368. this.$tip.toast("请输入正确的手机号");
  369. return false;
  370. }
  371. if (!this.smsCode || this.smsCode.length == 0) {
  372. this.$tip.toast("请填短信验证码");
  373. return;
  374. }
  375. let loginParams = {
  376. mobile: this.phoneNo,
  377. captcha: this.smsCode,
  378. };
  379. this.PhoneLogin(loginParams)
  380. .then((res) => {
  381. console.log("res====》", res);
  382. if (res.data.success) {
  383. this.$tip.success("登录成功!");
  384. uni.navigateTo({
  385. url: "/pages/inedx/inedx",
  386. });
  387. } else {
  388. this.$tip.error(res.data.message);
  389. }
  390. })
  391. .catch((err) => {
  392. let msg =
  393. ((err.response || {}).data || {}).message ||
  394. err.data.message ||
  395. "请求出现错误,请稍后再试";
  396. this.$tip.error(msg);
  397. });
  398. },
  399. loginSuccess() {
  400. // 登陆成功,重定向到主页
  401. this.$Router.replace({ name: "index" });
  402. },
  403. requestFailed(err) {
  404. this.$message.warning("登录失败");
  405. },
  406. changeloginType() {
  407. console.log("changeloginType====");
  408. console.log(configService, "changeloginType====");
  409. var tourl = configService.apiUrl;
  410. tourl = tourl.replace(9999, 8092);
  411. // this.$tip.success("tourl="+tourl);
  412. var rastourl =
  413. "https://id.shendong.com.cn/default" + "/login?service=" + tourl;
  414. // rastourl ="http://182.92.126.35:8092/?ticket=234";
  415. console.log("===========" + rastourl);
  416. this.openBrowser(rastourl);
  417. // window.location.href='/pages/index/index?ticket=123'
  418. // this.$router.push({ path: '/pages/index/index?ticket=123',query:"2w354" })
  419. },
  420. openBrowser(url) {
  421. // 使用uni.navigateTo打开内置浏览器
  422. console.log("----url---------------" + url);
  423. // this.$tip.success("url="+url);
  424. uni.navigateTo({
  425. url: "/pages/webview/webview?url=" + encodeURIComponent(url),
  426. });
  427. },
  428. setIp() {
  429. console.log("点击成功");
  430. this.ipShow = !this.ipShow;
  431. },
  432. changeIP() {
  433. this.ipShow1 = true;
  434. },
  435. selectIpAddr(e) {
  436. this.ipShow1 = false;
  437. const fullURL = e.value[0].value;
  438. this.IPSet = e.value[0].label;
  439. const apiCode = e.value[0].code;
  440. configService.apiUrl = fullURL;
  441. uni.setStorageSync("apiUrl", configService.apiUrl);
  442. uni.setStorageSync("apiCode", apiCode);
  443. setTimeout(() => {
  444. uni.getStorageSync("apiUrl");
  445. }, 100);
  446. uni.navigateTo({ url: "/pages/login/login" });
  447. },
  448. },
  449. beforeDestroy() {
  450. if (this.smsCountInterval) {
  451. clearInterval(this.smsCountInterval);
  452. }
  453. },
  454. };
  455. </script>
  456. <style scoped>
  457. .login-page {
  458. min-height: 100vh;
  459. background: #ffffff;
  460. display: flex;
  461. flex-direction: column;
  462. position: relative;
  463. overflow: hidden;
  464. }
  465. /* ===== 顶部插画 ===== */
  466. .login-header {
  467. position: relative;
  468. width: 100%;
  469. height: 520rpx;
  470. flex-shrink: 0;
  471. }
  472. .header-bg {
  473. position: absolute;
  474. left: 0;
  475. top: 0;
  476. width: 100%;
  477. height: 100%;
  478. z-index: 0;
  479. }
  480. .header-mask {
  481. position: absolute;
  482. left: 0;
  483. bottom: 0;
  484. width: 100%;
  485. height: 160rpx;
  486. background: linear-gradient(to bottom, rgba(255, 255, 255, 0), #ffffff);
  487. z-index: 1;
  488. }
  489. .header-content {
  490. position: relative;
  491. z-index: 2;
  492. padding: 88rpx 48rpx 0;
  493. box-sizing: border-box;
  494. }
  495. .header-top {
  496. display: flex;
  497. flex-direction: row;
  498. align-items: center;
  499. justify-content: space-between;
  500. margin-bottom: 36rpx;
  501. }
  502. .logo {
  503. width: 72rpx;
  504. height: 84rpx;
  505. }
  506. .welcome-text {
  507. font-size: 36rpx;
  508. color: #1a1a1a;
  509. font-weight: 500;
  510. line-height: 1.4;
  511. margin-bottom: 12rpx;
  512. }
  513. .platform-name {
  514. font-size: 40rpx;
  515. color: #111111;
  516. font-weight: 700;
  517. line-height: 1.4;
  518. letter-spacing: 1rpx;
  519. }
  520. /* ===== 表单区 ===== */
  521. .login-body {
  522. flex: 1;
  523. display: flex;
  524. flex-direction: column;
  525. justify-content: space-between;
  526. padding: 40rpx 48rpx 80rpx;
  527. box-sizing: border-box;
  528. background: #ffffff;
  529. }
  530. .form-area {
  531. width: 100%;
  532. }
  533. .input-item {
  534. display: flex;
  535. flex-direction: row;
  536. align-items: center;
  537. height: 96rpx;
  538. padding: 0 28rpx;
  539. margin-bottom: 28rpx;
  540. background: #eff3ff;
  541. border-radius: 16rpx;
  542. box-sizing: border-box;
  543. }
  544. .input-field {
  545. flex: 1;
  546. height: 96rpx;
  547. margin-left: 20rpx;
  548. font-size: 30rpx;
  549. color: #333333;
  550. }
  551. .input-placeholder {
  552. color: #9aa3b5;
  553. font-size: 30rpx;
  554. }
  555. .sso-link {
  556. margin-top: 8rpx;
  557. text-align: right;
  558. font-size: 26rpx;
  559. color: #2979ff;
  560. }
  561. /* ===== 底部登录 ===== */
  562. .footer-area {
  563. width: 100%;
  564. padding-bottom: env(safe-area-inset-bottom);
  565. }
  566. .login-btn {
  567. width: 100%;
  568. height: 96rpx;
  569. line-height: 96rpx;
  570. background: #007aff;
  571. color: #ffffff;
  572. font-size: 34rpx;
  573. font-weight: 600;
  574. border-radius: 48rpx;
  575. border: none;
  576. text-align: center;
  577. padding: 0;
  578. }
  579. .login-btn::after {
  580. border: none;
  581. }
  582. .login-btn[disabled] {
  583. opacity: 0.75;
  584. }
  585. .version-text {
  586. margin-top: 24rpx;
  587. text-align: center;
  588. font-size: 24rpx;
  589. color: #999999;
  590. }
  591. /* ===== IP 配置 ===== */
  592. .ip-panel {
  593. flex: 1;
  594. background: #ffffff;
  595. padding: 40rpx 48rpx;
  596. }
  597. .IPSet {
  598. display: flex;
  599. flex-direction: column;
  600. }
  601. .text-style {
  602. margin: 20px;
  603. }
  604. </style>