Login.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  1. <template>
  2. <div class="register absolute">
  3. <div style="text-align: right; padding-right: 10px; padding-top: 0.66rem">
  4. <router-link to="/" style="font-size: 18px; color: white;"
  5. >跳过,看好货 ></router-link
  6. >
  7. </div>
  8. <div class="shading">
  9. <div class="pictrue acea-row row-center-wrapper">
  10. <img :src="logoUrl" v-if="logoUrl" />
  11. <img src="@assets/images/logo2.png" v-else />
  12. </div>
  13. </div>
  14. <div class="whiteBg" v-if="formItem === 1">
  15. <div class="title acea-row row-center-wrapper">
  16. <div
  17. class="item"
  18. :class="current === index ? 'on' : ''"
  19. v-for="(item, index) in navList"
  20. @click="navTap(index)"
  21. :key="index"
  22. >
  23. {{ item }}
  24. </div>
  25. </div>
  26. <div class="list" :hidden="current !== 0">
  27. <form @submit.prevent="submit">
  28. <div class="item">
  29. <div class="acea-row row-between-wrapper">
  30. <svg class="icon" aria-hidden="true">
  31. <use xlink:href="#icon-phone_"></use>
  32. </svg>
  33. <input
  34. type="text"
  35. placeholder="输入手机号码"
  36. v-model="account"
  37. required
  38. />
  39. </div>
  40. </div>
  41. <div class="item">
  42. <div class="acea-row row-between-wrapper">
  43. <svg class="icon" aria-hidden="true">
  44. <use xlink:href="#icon-code_"></use>
  45. </svg>
  46. <input
  47. type="password"
  48. placeholder="填写登录密码"
  49. v-model="password"
  50. required
  51. />
  52. </div>
  53. </div>
  54. </form>
  55. <div style="display: flex;">
  56. <div class="remeber">
  57. <img :src="check_img" @click="remeberClick" />
  58. <div class="text">记住密码</div>
  59. </div>
  60. <div
  61. class="forgetPwd"
  62. @click="$router.push({ name: 'RetrievePassword' })"
  63. >
  64. <span class="iconfont icon-wenti"></span>忘记密码
  65. </div>
  66. </div>
  67. </div>
  68. <div class="list" :hidden="current !== 1">
  69. <div class="item">
  70. <div class="acea-row row-between-wrapper">
  71. <svg class="icon" aria-hidden="true">
  72. <use xlink:href="#icon-phone_"></use>
  73. </svg>
  74. <input type="text" placeholder="输入手机号码" v-model="account" />
  75. </div>
  76. </div>
  77. <div class="item">
  78. <div class="align-left">
  79. <svg class="icon" aria-hidden="true">
  80. <use xlink:href="#icon-code_1"></use>
  81. </svg>
  82. <input
  83. type="text"
  84. placeholder="填写验证码"
  85. class="codeIput"
  86. v-model="captcha"
  87. />
  88. <button
  89. class="code"
  90. :disabled="disabled"
  91. :class="disabled === true ? 'on' : ''"
  92. @click="code"
  93. >
  94. {{ text }}
  95. </button>
  96. </div>
  97. </div>
  98. <div class="item" v-if="isShowCode">
  99. <div class="align-left">
  100. <svg class="icon" aria-hidden="true">
  101. <use xlink:href="#icon-code_"></use>
  102. </svg>
  103. <input
  104. type="text"
  105. placeholder="填写验证码"
  106. class="codeIput"
  107. v-model="codeVal"
  108. />
  109. <div class="code" @click="again"><img :src="codeUrl" /></div>
  110. </div>
  111. </div>
  112. </div>
  113. <div class="logon" @click="loginMobile" :hidden="current !== 1">登录</div>
  114. <div class="logon" @click="submit" :hidden="current === 1">登录</div>
  115. <div class="tip">
  116. 没有账号?
  117. <span @click="formItem = 2" class="font-color-red">立即注册</span>
  118. </div>
  119. </div>
  120. <div class="whiteBg" v-else>
  121. <div class="title">注册账号</div>
  122. <div class="list">
  123. <div class="item">
  124. <div>
  125. <svg class="icon" aria-hidden="true">
  126. <use xlink:href="#icon-phone_"></use>
  127. </svg>
  128. <input type="text" placeholder="输入手机号码" v-model="account" />
  129. </div>
  130. </div>
  131. <div class="item">
  132. <div class="align-left">
  133. <svg class="icon" aria-hidden="true">
  134. <use xlink:href="#icon-code_1"></use>
  135. </svg>
  136. <input
  137. type="text"
  138. placeholder="填写验证码"
  139. class="codeIput"
  140. v-model="captcha"
  141. />
  142. <button
  143. class="code"
  144. :disabled="disabled"
  145. :class="disabled === true ? 'on' : ''"
  146. @click="code"
  147. >
  148. {{ text }}
  149. </button>
  150. </div>
  151. </div>
  152. <div class="item">
  153. <div>
  154. <svg class="icon" aria-hidden="true">
  155. <use xlink:href="#icon-code_"></use>
  156. </svg>
  157. <input
  158. type="password"
  159. placeholder="填写您的登录密码"
  160. v-model="password"
  161. />
  162. </div>
  163. </div>
  164. <div class="item" v-if="isShowCode">
  165. <div class="align-left">
  166. <svg class="icon" aria-hidden="true">
  167. <use xlink:href="#icon-code_"></use>
  168. </svg>
  169. <input
  170. type="text"
  171. placeholder="填写验证码"
  172. class="codeIput"
  173. v-model="codeVal"
  174. />
  175. <div class="code" @click="again"><img :src="codeUrl" /></div>
  176. </div>
  177. </div>
  178. </div>
  179. <div class="logon" @click="register">注册</div>
  180. <div class="tip">
  181. 已有账号?
  182. <span @click="formItem = 1" class="font-color-red">立即登录</span>
  183. </div>
  184. </div>
  185. <!-- <div class="bottom"></div> -->
  186. </div>
  187. </template>
  188. <script>
  189. import sendVerifyCode from "@mixins/SendVerifyCode";
  190. import {
  191. login,
  192. loginMobile,
  193. registerVerify,
  194. register,
  195. getCodeApi
  196. } from "@api/user";
  197. import attrs, { required, alpha_num, chs_phone } from "@utils/validate";
  198. import { validatorDefaultCatch } from "@utils/dialog";
  199. import { getLogo } from "@api/public";
  200. import cookie from "@utils/store/cookie";
  201. import { VUE_APP_API_URL } from "@utils";
  202. const BACK_URL = "login_back_url";
  203. import check_on from "@assets/images/check_on.png";
  204. import check_off from "@assets/images/check_off.png";
  205. import router from "@/router";
  206. export default {
  207. name: "Login",
  208. mixins: [sendVerifyCode],
  209. data: function() {
  210. return {
  211. navList: ["账号登录", "快速登录"],
  212. current: 0,
  213. account: "",
  214. password: "",
  215. captcha: "",
  216. formItem: 1,
  217. type: "login",
  218. logoUrl: "",
  219. keyCode: "",
  220. codeUrl: "",
  221. codeVal: "",
  222. isShowCode: false,
  223. remembed: true,
  224. check_img: check_on
  225. };
  226. },
  227. watch: {
  228. $route(n) {
  229. if (n.name === "Login") {
  230. this.loadSave();
  231. }
  232. }
  233. },
  234. mounted: function() {
  235. this.getCode();
  236. this.getLogoImage();
  237. this.loadSave();
  238. },
  239. methods: {
  240. loadSave() {
  241. const acc = window.localStorage.getItem("account");
  242. const pwd = window.localStorage.getItem("password");
  243. console.log(acc, pwd);
  244. this.account = acc ? acc : "";
  245. if (this.$store.state.app.autoLogin) {
  246. this.password = pwd ? pwd : "";
  247. }
  248. },
  249. again() {
  250. this.codeUrl =
  251. VUE_APP_API_URL +
  252. "/sms_captcha?" +
  253. "key=" +
  254. this.keyCode +
  255. Date.parse(new Date());
  256. },
  257. getCode() {
  258. getCodeApi()
  259. .then(res => {
  260. this.keyCode = res.data.key;
  261. })
  262. .catch(res => {
  263. this.$dialog.error(res.msg);
  264. });
  265. },
  266. async getLogoImage() {
  267. let that = this;
  268. getLogo(2).then(res => {
  269. that.logoUrl = res.data.logo_url;
  270. });
  271. },
  272. async loginMobile() {
  273. var that = this;
  274. const { account, captcha } = that;
  275. try {
  276. await that
  277. .$validator({
  278. account: [
  279. required(required.message("手机号码")),
  280. chs_phone(chs_phone.message())
  281. ],
  282. captcha: [
  283. required(required.message("验证码")),
  284. alpha_num(alpha_num.message("验证码"))
  285. ]
  286. })
  287. .validate({ account, captcha });
  288. } catch (e) {
  289. return validatorDefaultCatch(e);
  290. }
  291. loginMobile({
  292. phone: that.account,
  293. captcha: that.captcha,
  294. spread: cookie.get("spread")
  295. })
  296. .then(res => {
  297. let data = res.data;
  298. let expires_time = data.expires_time.substring(0, 19);
  299. expires_time = expires_time.replace(/-/g, "/");
  300. expires_time = new Date(expires_time).getTime() - 28800000;
  301. // const expires_time = new Date(data.expires_time).getTime() / 1000;
  302. const datas = {
  303. token: data.token,
  304. expires_time: expires_time
  305. };
  306. this.$store.commit("LOGIN", datas);
  307. this.$store.dispatch("USERINFO", true);
  308. const backUrl = cookie.get(BACK_URL) || "/";
  309. cookie.remove(BACK_URL);
  310. that.$router.replace({ path: backUrl });
  311. })
  312. .catch(res => {
  313. that.$dialog.error(res.msg);
  314. });
  315. },
  316. async register() {
  317. var that = this;
  318. const { account, captcha, password } = that;
  319. try {
  320. await that
  321. .$validator({
  322. account: [
  323. required(required.message("手机号码")),
  324. chs_phone(chs_phone.message())
  325. ],
  326. captcha: [
  327. required(required.message("验证码")),
  328. alpha_num(alpha_num.message("验证码"))
  329. ],
  330. password: [
  331. required(required.message("密码")),
  332. attrs.range([6, 16], attrs.range.message("密码")),
  333. alpha_num(alpha_num.message("密码"))
  334. ]
  335. })
  336. .validate({ account, captcha, password });
  337. } catch (e) {
  338. return validatorDefaultCatch(e);
  339. }
  340. register({
  341. account: that.account,
  342. captcha: that.captcha,
  343. password: that.password,
  344. spread: cookie.get("spread")
  345. })
  346. .then(res => {
  347. that.$dialog.success(res.msg);
  348. that.formItem = 1;
  349. })
  350. .catch(res => {
  351. that.$dialog.error(res.msg);
  352. });
  353. },
  354. async code() {
  355. var that = this;
  356. const { account } = that;
  357. try {
  358. await that
  359. .$validator({
  360. account: [
  361. required(required.message("手机号码")),
  362. chs_phone(chs_phone.message())
  363. ]
  364. })
  365. .validate({ account });
  366. } catch (e) {
  367. return validatorDefaultCatch(e);
  368. }
  369. if (that.formItem == 2) that.type = "register";
  370. await registerVerify({
  371. phone: that.account,
  372. type: that.type,
  373. key: that.keyCode,
  374. code: that.codeVal
  375. })
  376. .then(res => {
  377. that.$dialog.success(res.msg);
  378. that.sendCode();
  379. })
  380. .catch(res => {
  381. if (res.data.status === 402) {
  382. that.codeUrl = `${VUE_APP_API_URL}/sms_captcha?key=${that.keyCode}`;
  383. that.isShowCode = true;
  384. }
  385. that.$dialog.error(res.msg);
  386. });
  387. },
  388. navTap: function(index) {
  389. this.current = index;
  390. },
  391. async submit() {
  392. const { account, password, codeVal } = this;
  393. try {
  394. await this.$validator({
  395. account: [
  396. required(required.message("账号")),
  397. attrs.range([5, 16], attrs.range.message("账号")),
  398. alpha_num(alpha_num.message("账号"))
  399. ],
  400. password: [
  401. required(required.message("密码")),
  402. attrs.range([6, 16], attrs.range.message("密码")),
  403. alpha_num(alpha_num.message("密码"))
  404. ],
  405. codeVal: this.isShowCode
  406. ? [
  407. required(required.message("验证码")),
  408. attrs.length(4, attrs.length.message("验证码")),
  409. alpha_num(alpha_num.message("验证码"))
  410. ]
  411. : []
  412. }).validate({ account, password, codeVal });
  413. } catch (e) {
  414. return validatorDefaultCatch(e);
  415. }
  416. login({ account, password, code: codeVal })
  417. .then(({ data }) => {
  418. let expires_time = data.expires_time.substring(0, 19);
  419. expires_time = expires_time.replace(/-/g, "/");
  420. expires_time = new Date(expires_time).getTime() - 28800000;
  421. const datas = {
  422. token: data.token,
  423. expires_time: expires_time
  424. };
  425. this.$store.commit("LOGIN", datas);
  426. const backUrl = cookie.get(BACK_URL) || "/";
  427. cookie.remove(BACK_URL);
  428. this.$router.replace({ path: backUrl });
  429. // let newTime = Math.round(new Date() / 1000);
  430. // this.$store.commit("LOGIN", data.token, dayjs(data.expires_time))
  431. window.localStorage.setItem("account", account);
  432. window.localStorage.setItem("password", password);
  433. })
  434. .catch(e => {
  435. this.$dialog.error(e.msg);
  436. });
  437. },
  438. remeberClick() {
  439. this.remembed = !this.remembed;
  440. this.check_img = this.remembed ? check_on : check_off;
  441. console.log(this.remembed);
  442. this.$store.commit("AUTOLOGIN", this.remembed);
  443. }
  444. }
  445. };
  446. </script>
  447. <style scoped>
  448. .code img {
  449. width: 100%;
  450. height: 100%;
  451. }
  452. .remeber {
  453. display: flex;
  454. margin-top: 0.2rem;
  455. margin-left: 0.2rem;
  456. margin-right: 2rem;
  457. }
  458. .remeber .text {
  459. text-align: center;
  460. /* font-size: 13px; */
  461. color: #666;
  462. line-height: 0.2rem;
  463. margin-top: 0.1rem;
  464. }
  465. .remeber img {
  466. width: 0.4rem;
  467. height: 0.4rem;
  468. margin-right: 0.1rem;
  469. }
  470. </style>