loginView.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. <script setup lang="ts">
  2. import ErrorTips from './components/ErrorTips.vue'
  3. const loginForm = ref({
  4. username: '',
  5. password: '',
  6. email: '',
  7. code: ''
  8. })
  9. const status = ref('login')
  10. watch(status, () => {
  11. loginForm.value = {
  12. username: '',
  13. password: '',
  14. email: '',
  15. code: ''
  16. }
  17. loginError.value = {
  18. username: false,
  19. password: false,
  20. email: false,
  21. code: false
  22. }
  23. // getCode()
  24. })
  25. const loginError = ref({
  26. username: false,
  27. password: false,
  28. email: false,
  29. code: false
  30. })
  31. const verificationCode = ref()
  32. // 获取验证码
  33. const getCode = () => {
  34. $api.getVerifcationCode().then((res) => {
  35. verificationCode.value = `data:image/png;base64,${res}`
  36. console.log(res)
  37. })
  38. }
  39. // getCode()
  40. // 验证当前用户是否存在
  41. const handleCheckUser = () => {
  42. // 这里是验证用户是否存在的逻辑
  43. $api.isUserNameExit({ uname: loginForm.value.username }).then((res) => {
  44. if (res.code === 200) {
  45. if (res.data.msg !== 'no_exist') {
  46. isUserNameExit.value = true
  47. } else {
  48. loginError.value.username = true
  49. isUserNameExit.value = false
  50. }
  51. } else {
  52. isUserNameExit.value = false
  53. }
  54. })
  55. }
  56. // 点击登录按钮
  57. const handleLogin = () => {
  58. // 这里是登录逻辑
  59. $api
  60. .login({
  61. uname: loginForm.value.username,
  62. psw: loginForm.value.password,
  63. verifcation_code: loginForm.value.code
  64. })
  65. .then((res) => {
  66. console.log(res)
  67. })
  68. }
  69. const isUserNameExit = ref(false)
  70. const handleForgot = () => {
  71. status.value = 'reset'
  72. isUserNameExit.value = false
  73. handleDeleteEmailTips()
  74. }
  75. const handleSendPassword = () => {
  76. // 这里是发送密码逻辑
  77. $api
  78. .forgotPassword({
  79. login: loginForm.value.username,
  80. email: loginForm.value.email
  81. })
  82. .then((res) => {
  83. if (res.code === 200) {
  84. isEmailTips.value = true
  85. }
  86. })
  87. }
  88. const isEmailTips = ref(false)
  89. const handleDeleteEmailTips = (type: string) => {
  90. isEmailTips.value = false
  91. if (type) {
  92. loginError.value[type] = false
  93. }
  94. }
  95. const errorTipsRef = ref()
  96. </script>
  97. <template>
  98. <div class="login">
  99. <el-card class="login-card" v-if="status === 'login'">
  100. <div class="title">
  101. <span class="welcome">Welcome to KLN Portal</span>
  102. <span class="tips">Login to your account</span>
  103. </div>
  104. <div class="send-email-tips" :style="{ display: isEmailTips ? 'block' : 'none' }">
  105. <span class="font_family icon-icon_confirm_b success-icon"></span>
  106. New Password sent to registered email.
  107. <span
  108. @click="handleDeleteEmailTips"
  109. class="font_family icon-icon_reject_b delete-icon"
  110. ></span>
  111. </div>
  112. <div class="login-form">
  113. <div class="label">
  114. <span>User Name</span>
  115. </div>
  116. <el-input
  117. ref="userNameRef"
  118. :class="{ 'is-error': loginError.username }"
  119. v-model="loginForm.username"
  120. class="user-name"
  121. placeholder="Please input user name"
  122. @focus="handleDeleteEmailTips('username')"
  123. @change="handleCheckUser"
  124. >
  125. <template #prefix>
  126. <span class="font_family icon-icon_username_b"></span>
  127. </template>
  128. <template #suffix>
  129. <span v-if="isUserNameExit" class="font_family icon-icon_confirm_b confirm-icon"></span>
  130. </template>
  131. </el-input>
  132. <div class="error" v-if="loginError.username">This account does not exist.</div>
  133. <div class="label">
  134. <span>Password</span>
  135. <span class="forgot-password" @click="handleForgot">Forgot Password?</span>
  136. </div>
  137. <el-input
  138. ref="passWordRef"
  139. :class="{ 'is-error': loginError.password }"
  140. v-model="loginForm.password"
  141. type="password"
  142. placeholder="Please input password"
  143. show-password
  144. @focus="handleDeleteEmailTips('password')"
  145. ><template #prefix>
  146. <span class="font_family icon-icon_password_b"></span>
  147. </template>
  148. </el-input>
  149. <div class="error" v-if="loginError.password">Incorrect password. Please try again.</div>
  150. <el-input
  151. ref="codeRef"
  152. :class="{ 'is-error': loginError.code }"
  153. class="verification-code"
  154. v-model="loginForm.code"
  155. placeholder="Verification Code"
  156. @focus="handleDeleteEmailTips('code')"
  157. >
  158. <template #append>
  159. <img class="verification-code-img" :src="verificationCode" alt="" />
  160. </template>
  161. </el-input>
  162. <div class="error" v-if="loginError.code">Incorrect verification code.</div>
  163. <el-button @click="handleLogin" class="el-button--dark login-btn">Login</el-button>
  164. </div>
  165. <template #footer>
  166. <div class="license">
  167. <span>© 2024 KTreker from <span class="company">Kerry Logistics</span></span>
  168. <span>Version 0.67</span>
  169. </div>
  170. </template>
  171. </el-card>
  172. <el-card class="login-card" v-else>
  173. <div class="title">
  174. <span class="welcome">Password Retrieval</span>
  175. <span class="tips">We'll send you new password in email</span>
  176. </div>
  177. <div class="login-form">
  178. <div class="label">
  179. <span>User Name</span>
  180. </div>
  181. <el-input
  182. ref="userNameRef"
  183. :class="{ 'is-error': loginError.username }"
  184. v-model="loginForm.username"
  185. class="user-name"
  186. placeholder="Please input user name"
  187. @focus="handleDeleteEmailTips('username')"
  188. >
  189. <template #prefix>
  190. <span class="font_family icon-icon_username_b"></span>
  191. </template>
  192. <template #suffix>
  193. <span v-if="isUserNameExit" class="font_family icon-icon_confirm_b confirm-icon"></span>
  194. </template>
  195. </el-input>
  196. <div class="error" v-if="loginError.username">
  197. This is the prompt information given by the verification
  198. </div>
  199. <div class="label">
  200. <span>Email Address</span>
  201. </div>
  202. <el-input
  203. ref="passWordRef"
  204. :class="{ 'is-error': loginError.email }"
  205. v-model="loginForm.email"
  206. placeholder="Please input your email address"
  207. @focus="handleDeleteEmailTips('email')"
  208. ><template #prefix>
  209. <span class="font_family icon-icon_email_b"></span>
  210. </template>
  211. </el-input>
  212. <div class="error" v-if="loginError.password">
  213. This is the prompt information given by the verification
  214. </div>
  215. <el-input
  216. ref="codeRef"
  217. :class="{ 'is-error': loginError.code }"
  218. class="verification-code"
  219. v-model="loginForm.code"
  220. placeholder="Verification Code"
  221. @focus="handleDeleteEmailTips('code')"
  222. ><template #append>
  223. <img class="verification-code-img" src="./image/code.png" alt="" /> </template
  224. ></el-input>
  225. <div class="error" v-if="loginError.code">
  226. This is the prompt information given by the verification
  227. </div>
  228. <el-button @click="handleSendPassword" class="el-button--dark login-btn"
  229. >Send Password</el-button
  230. >
  231. <div @click="status = 'login'" class="back-text">
  232. <span class="font_family icon-icon_back_b"></span>
  233. <span class="text"> Back to login</span>
  234. </div>
  235. </div>
  236. <template #footer>
  237. <div class="license">
  238. <span>© 2024 KTreker from <span class="company">Kerry Logistics</span></span>
  239. <span>Version 0.67</span>
  240. </div>
  241. </template>
  242. </el-card>
  243. <ErrorTips ref="errorTipsRef" @forget-password="status = 'reset'"></ErrorTips>
  244. </div>
  245. </template>
  246. <style lang="scss" scoped>
  247. .login {
  248. display: flex;
  249. justify-content: center;
  250. align-items: center;
  251. height: 100%;
  252. background: url(../src/image/bg-image.png) no-repeat center center;
  253. background-size: cover;
  254. }
  255. .login-card {
  256. width: 400px;
  257. .title {
  258. display: flex;
  259. flex-direction: column;
  260. align-items: center;
  261. margin-bottom: 24px;
  262. .welcome {
  263. margin-bottom: 16px;
  264. font-size: 24px;
  265. font-weight: 700;
  266. }
  267. }
  268. .send-email-tips {
  269. display: flex;
  270. align-items: center;
  271. height: 40px;
  272. padding: 12px;
  273. padding-left: 14px;
  274. background-color: #e5f6f1;
  275. border-radius: 6px;
  276. color: var(--color-success);
  277. .success-icon {
  278. display: inline-flex;
  279. align-items: center;
  280. justify-content: center;
  281. height: 16px;
  282. width: 16px;
  283. margin-right: 4px;
  284. font-size: 14px;
  285. color: #fff;
  286. background-color: var(--color-success);
  287. border-radius: 50%;
  288. }
  289. .delete-icon {
  290. margin-left: 6px;
  291. color: var(--color-success);
  292. cursor: pointer;
  293. }
  294. }
  295. :deep(.el-card__body) {
  296. padding: 40px;
  297. padding-bottom: 16px;
  298. }
  299. .login-btn {
  300. width: 100%;
  301. height: 40px;
  302. margin-top: 16px;
  303. }
  304. }
  305. .login-form {
  306. display: flex;
  307. flex-direction: column;
  308. align-items: flex-start;
  309. .el-input {
  310. height: 40px;
  311. .confirm-icon {
  312. display: inline-flex;
  313. align-items: center;
  314. justify-content: center;
  315. height: 16px;
  316. width: 16px;
  317. margin-right: 4px;
  318. font-size: 14px;
  319. color: #fff;
  320. background-color: var(--color-success);
  321. border-radius: 50%;
  322. }
  323. &.is-error {
  324. :deep(.el-input__wrapper) {
  325. box-shadow: 0 0 0 1px var(--color-danger) inset;
  326. }
  327. }
  328. :deep(.el-input__prefix) {
  329. margin: 0 4px;
  330. background-color: transparent;
  331. }
  332. }
  333. .verification-code {
  334. margin-top: 16px;
  335. .verification-code-img {
  336. width: 130px;
  337. height: 38px;
  338. object-fit: cover;
  339. }
  340. :deep(.el-input-group__append) {
  341. padding: 0;
  342. padding-right: 1px;
  343. }
  344. }
  345. .el-input.user-name {
  346. :deep(.el-input__wrapper) {
  347. padding-right: 6px;
  348. }
  349. }
  350. .label {
  351. display: flex;
  352. justify-content: space-between;
  353. width: 100%;
  354. margin-top: 16px;
  355. font-size: 12px;
  356. line-height: 18px;
  357. span {
  358. color: var(--color-neutral-2);
  359. }
  360. .forgot-password {
  361. color: var(--color-theme);
  362. cursor: pointer;
  363. }
  364. }
  365. .error {
  366. font-size: 12px;
  367. color: var(--color-danger);
  368. line-height: 14px;
  369. }
  370. .back-text {
  371. width: 100%;
  372. height: 20px;
  373. margin-top: 24px;
  374. margin-bottom: 8px;
  375. text-align: center;
  376. cursor: pointer;
  377. span {
  378. color: var(--color-theme);
  379. }
  380. .text {
  381. display: inline-block;
  382. transform: translateY(-2px);
  383. font-size: 12px;
  384. }
  385. }
  386. }
  387. .license {
  388. display: flex;
  389. flex-direction: column;
  390. align-items: center;
  391. font-size: 12px;
  392. .company {
  393. color: var(--color-theme);
  394. }
  395. span {
  396. color: var(--color-neutral-2);
  397. }
  398. }
  399. </style>