LoginView.vue 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. <script setup>
  2. import { ref, unref } from 'vue';
  3. import { useRouter } from 'vue-router';
  4. import { NButton } from 'naive-ui';
  5. import { SvgIcon } from '@/components';
  6. import { useUserStore } from '@/stores/modules/userStore';
  7. import { userApi } from '@/api/user';
  8. import { TheArchival } from "@/components"
  9. import CryptoJS from 'crypto-js';
  10. const SECRET_KEY = 'qwertasdfg159753'
  11. const router = useRouter();
  12. const userStore = useUserStore();
  13. const errorMsg = ref('');
  14. const loading = ref(false);
  15. const loginFormData = ref({
  16. username: '',
  17. password: ''
  18. })
  19. const handleSubmit = async () => {
  20. const { username, password } = unref(loginFormData);
  21. if (!username) {
  22. return errorMsg.value = '请输入用户名称'
  23. }
  24. if (!password) {
  25. return errorMsg.value = '请输入登录密码'
  26. }
  27. try {
  28. loading.value = true;
  29. const { token } = await userApi.postLogin({ username, password: AES_ECB_ENCRYPT(password), type: 0 });
  30. userStore.setUserInfo({ token });
  31. const { user } = await userApi.getUserInfo();
  32. errorMsg.value = '';
  33. userStore.setUserInfo({ ...user });
  34. router.push(user.userName === 'xinyi001' ? "/answer" : "/");
  35. }
  36. catch (error) {
  37. errorMsg.value = error.msg;
  38. }
  39. finally {
  40. loading.value = false;
  41. }
  42. }
  43. // 加密
  44. function AES_ECB_ENCRYPT(text) {
  45. var keyHex = CryptoJS.enc.Utf8.parse(SECRET_KEY);
  46. var messageHex = CryptoJS.enc.Utf8.parse(text);
  47. var encrypted = CryptoJS.AES.encrypt(messageHex, keyHex, {
  48. "mode": CryptoJS.mode.ECB
  49. });
  50. return encrypted.toString();
  51. }
  52. // 解密
  53. function AES_ECB_DECRYPT(textBase64) {
  54. var keyHex = CryptoJS.enc.Utf8.parse(SECRET_KEY);
  55. var decrypt = CryptoJS.AES.decrypt(textBase64, keyHex, {
  56. "mode": CryptoJS.mode.ECB,
  57. "padding": CryptoJS.pad.Pkcs7
  58. });
  59. return CryptoJS.enc.Utf8.stringify(decrypt);
  60. }
  61. // console.log( "AES_ECB_DECRYPTA", ES_ECB_DECRYPT("QtBKjsD3TVlsn7efq7+xYg==") );
  62. </script>
  63. <template>
  64. <div class="login-viewport">
  65. <div class="logo absolute w-[106px] space-x-[6px] h-[28px] top-[14px] left-[20px]">
  66. <img src="@/assets/svgs/common/logo.svg" alt="logo" />
  67. <span class="text">LibraAI智能体运营平台</span>
  68. </div>
  69. <main class="main flex items-center space-x-[98px]">
  70. <div class="text-[#07233C] pb-[90px]">
  71. <div class="text-title mb-[8px] text-[36px] font-bold leading-[44px]">
  72. <p class="text-[#2454FF]">LibraAI</p>
  73. <p>智能体运营平台</p>
  74. </div>
  75. <p class="w-[540px] text-[18px] text-justify leading-[26px]">
  76. 国内首家水务行业大模型,赋能水务行业<br>
  77. 为水务行业提供创新应用和全面支持
  78. </p>
  79. </div>
  80. <div class="login-form w-[442px] h-[454px] bg-white rounded-[16px]">
  81. <p class="title pl-[2px] mb-[30px] text-[28px] leading-[40px] font-bold">系统登录</p>
  82. <div class="form-inner w-full">
  83. <ul class="form-inp-list">
  84. <li class="inp-item-inner">
  85. <input type="text" placeholder="请输入用户名称" v-model="loginFormData.username">
  86. </li>
  87. <li class="inp-item-inner">
  88. <input type="password" placeholder="请输入登录密码" v-model="loginFormData.password">
  89. </li>
  90. </ul>
  91. <div class="waring-feedback h-[32px] text-[12px] text-[#FF7152]">
  92. <p class="flex items-center justify-center h-full space-x-[8px] bg-[#FFF1F0]" v-show="errorMsg">
  93. <SvgIcon name="login-warning-tips"></SvgIcon>
  94. <span>{{ errorMsg }}</span>
  95. </p>
  96. </div>
  97. </div>
  98. <NButton block color="#2454FF" size="large" :loading="loading" @click="handleSubmit">登 录</NButton>
  99. <TheArchival class="info"></TheArchival>
  100. </div>
  101. </main>
  102. </div>
  103. </template>
  104. <style scoped lang="scss">
  105. .n-button {
  106. height: 54px;
  107. &:hover {
  108. background: #1d43cc;
  109. }
  110. }
  111. .login-viewport {
  112. position: relative;
  113. @include flex(x, center, center);
  114. height: 100vh;
  115. background: url("@/assets/images/login/bg-login.png") no-repeat;
  116. background-size: 100% 100%;
  117. overflow: hidden;
  118. .logo {
  119. @include flex(x, center, center);
  120. .text {
  121. font-size: 11px;
  122. font-family: AlimamaShuHeiTi;
  123. font-weight: bold;
  124. line-height: 12px;
  125. }
  126. }
  127. .text-title {
  128. font-family: AlimamaShuHeiTi;
  129. p:nth-child(1) {
  130. background: linear-gradient(92.36deg, #5ABBF2 4.56%, #2454FF 20.02%);
  131. -webkit-background-clip: text;
  132. -webkit-text-fill-color: transparent;
  133. }
  134. }
  135. .login-form {
  136. position: relative;
  137. @include flex(y, start, between);
  138. padding: 63px 61px 66px 61px;
  139. .info {
  140. position: absolute;
  141. left: 50%;
  142. bottom: -60px;
  143. text-align: center;
  144. white-space: nowrap;
  145. transform: translateX(-50%);
  146. }
  147. .title {
  148. background: url("@/assets/images/login/bg-title.png") left bottom no-repeat;
  149. }
  150. .form-inp-list {
  151. width: 100%;
  152. margin-bottom: 8px;
  153. .inp-item-inner {
  154. border-radius: 2px;
  155. overflow: hidden;
  156. input {
  157. width: 100%;
  158. padding: 16px 20px;
  159. background: #F2F4F9;
  160. font-size: 16px;
  161. line-height: 22px;
  162. color: #1A2029;
  163. outline: none;
  164. &::placeholder {
  165. color: #989EA7;
  166. }
  167. }
  168. &:nth-child(1) {
  169. margin-bottom: 18px;
  170. }
  171. }
  172. }
  173. }
  174. }
  175. </style>