index.vue 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. <template>
  2. <div class="login flex justify-center items-center h-full">
  3. <img class="logo" src="../../assets/imgs/login_logo.png" />
  4. <div class="login-bg flex justify-center items-center">
  5. <div class="login-bg-inner-box text-center">
  6. <img src="../../assets/imgs/login_bg_inner.png" />
  7. <div class="title1">欢 迎 使 用</div>
  8. <div class="title2">项目质量控制管理平台</div>
  9. </div>
  10. </div>
  11. <div class="login-box">
  12. <div class="title1 flex justify-between items-center">
  13. <span>{{ forgetStatus ? '忘记密码' : '输入信息' }}</span>
  14. <t-button
  15. variant="outline"
  16. theme="primary"
  17. v-if="forgetStatus"
  18. @click="forgetStatus = false"
  19. >
  20. <template #icon><RollbackIcon /></template>
  21. 返回登录
  22. </t-button>
  23. </div>
  24. <div class="title2">{{
  25. `请输入${forgetStatus ? '新的' : ''}账号与密码`
  26. }}</div>
  27. <t-form
  28. v-if="!forgetStatus"
  29. ref="form"
  30. :data="formData"
  31. :label-width="0"
  32. class="login-form"
  33. :rules="rules"
  34. >
  35. <t-form-item name="loginName">
  36. <t-input
  37. v-model="formData.loginName"
  38. clearable
  39. placeholder="请输入账号"
  40. size="large"
  41. @enter="loginHandle"
  42. >
  43. <template #prefix-icon>
  44. <desktop-icon />
  45. </template>
  46. </t-input>
  47. </t-form-item>
  48. <t-form-item name="password">
  49. <t-input
  50. v-model="formData.password"
  51. type="password"
  52. clearable
  53. placeholder="请输入密码"
  54. size="large"
  55. @enter="loginHandle"
  56. >
  57. <template #prefix-icon>
  58. <lock-on-icon />
  59. </template>
  60. </t-input>
  61. </t-form-item>
  62. <t-link theme="primary" class="m-t-20px" @click="forgetStatus = true"
  63. >忘记密码</t-link
  64. >
  65. <t-button
  66. block
  67. class="m-t-30px"
  68. @click="loginHandle"
  69. size="large"
  70. theme="primary"
  71. >登 录</t-button
  72. >
  73. </t-form>
  74. <ForgetPwd v-else @success="findSuccess" />
  75. </div>
  76. </div>
  77. <!-- <button @click="loginHandle" class="m-t-10px">登录!</button> -->
  78. </template>
  79. <script setup name="Login">
  80. import { ref, reactive, computed, watch } from 'vue';
  81. import { DesktopIcon, LockOnIcon, RollbackIcon } from 'tdesign-icons-vue-next';
  82. import { useRoute, useRouter } from 'vue-router';
  83. import { useUserStore } from '@/store';
  84. import { MessagePlugin } from 'tdesign-vue-next';
  85. import { getBase64 } from '@/utils/crypto';
  86. import ForgetPwd from './forget-pwd.vue';
  87. const forgetStatus = ref(false);
  88. const form = ref(null);
  89. const route = useRoute();
  90. const router = useRouter();
  91. const formData = reactive({
  92. loginName: '',
  93. password: '',
  94. });
  95. const rules = {
  96. loginName: [
  97. { required: true, message: '请输入账号', type: 'error', trigger: 'change' },
  98. ],
  99. password: [
  100. { required: true, message: '请输入密码', type: 'error', trigger: 'change' },
  101. ],
  102. };
  103. const userStore = useUserStore();
  104. const loginHandle = () => {
  105. form.value.validate().then(async (result) => {
  106. const redirect = route.query.redirect
  107. ? route.query.redirect
  108. : '/my-workbenches';
  109. if (result === true) {
  110. await userStore.login({
  111. loginName: formData.loginName,
  112. password: getBase64(formData.password),
  113. type: 'ACCOUNT',
  114. });
  115. await userStore.requestUserMenu();
  116. if (redirect) {
  117. router.push(redirect);
  118. } else {
  119. router.push({ name: userStore.menus[0].name });
  120. }
  121. }
  122. });
  123. };
  124. const findSuccess = () => {
  125. forgetStatus.value = false;
  126. formData.loginName = '';
  127. formData.password = '';
  128. };
  129. </script>
  130. <style lang="less" scoped>
  131. .login {
  132. background: linear-gradient(180deg, #f4f9ff 0%, #d7eaff 100%);
  133. position: relative;
  134. min-height: 550px;
  135. .logo {
  136. width: 180px;
  137. z-index: 100;
  138. top: 48px;
  139. left: 48px;
  140. position: absolute;
  141. }
  142. .login-bg {
  143. position: absolute;
  144. top: 80px;
  145. bottom: 80px;
  146. left: 0;
  147. width: 70%;
  148. z-index: 99;
  149. background: url(../../assets//imgs/login_bg_grid.png) center center
  150. no-repeat;
  151. background-size: contain;
  152. .login-bg-inner-box {
  153. img {
  154. height: 260px;
  155. margin-bottom: 20px;
  156. }
  157. .title1 {
  158. font-size: 32px;
  159. color: #262626;
  160. margin-bottom: 15px;
  161. font-weight: bold;
  162. line-height: 40px;
  163. }
  164. .title2 {
  165. font-size: 20px;
  166. color: #8c8c8c;
  167. line-height: 28px;
  168. }
  169. }
  170. }
  171. .login-box {
  172. width: 350px;
  173. background: #fff;
  174. box-shadow: 0px 2px 12px 0px rgba(0, 0, 0, 0.08);
  175. border-radius: 8px;
  176. border: 1px solid #e5e6eb;
  177. padding: 24px;
  178. position: absolute;
  179. left: 60%;
  180. z-index: 101;
  181. .title1 {
  182. span {
  183. font-size: 20px;
  184. font-weight: bold;
  185. color: #262626;
  186. line-height: 32px;
  187. }
  188. }
  189. .title2 {
  190. font-size: 14px;
  191. color: #8c8c8c;
  192. line-height: 24px;
  193. margin-top: 4px;
  194. margin-bottom: 28px;
  195. }
  196. }
  197. }
  198. </style>