index.vue 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. <template>
  2. <div class="view-account">
  3. <div class="view-account-container">
  4. <div class="view-account-left">
  5. <img :src="loginMain" />
  6. </div>
  7. <div class="view-account-form">
  8. <div class="view-account-form-wrap">
  9. <div class="formTitle">
  10. <img :src="loginLogo" />
  11. </div>
  12. <n-form
  13. ref="formRef"
  14. label-placement="left"
  15. size="large"
  16. :model="formInline"
  17. :rules="rules"
  18. >
  19. <n-form-item path="username">
  20. <n-input v-model:value="formInline.username" placeholder="请输入用户名">
  21. <template #prefix>
  22. <img :src="useIcon" class="prefixIcon" alt="" />
  23. </template>
  24. </n-input>
  25. </n-form-item>
  26. <n-form-item path="password">
  27. <n-input
  28. v-model:value="formInline.password"
  29. type="text"
  30. showPasswordOn="click"
  31. placeholder="请输入密码"
  32. autocomplete="off"
  33. :class="[showPwd ? '' : 'no-pwd']"
  34. :loading="loading"
  35. @keydown.enter="
  36. (event:any) => {
  37. event.target.blur();
  38. handleSubmit(event);
  39. }
  40. "
  41. >
  42. <template #prefix>
  43. <img :src="lockIcon" class="prefixIcon" alt="" />
  44. </template>
  45. <template #suffix>
  46. <img
  47. :src="showPwd ? closeEye : openEye"
  48. class="pwdIcon"
  49. alt=""
  50. @click="
  51. () => {
  52. showPwd = !showPwd
  53. }
  54. "
  55. />
  56. </template>
  57. </n-input>
  58. </n-form-item>
  59. <n-form-item class="default-color">
  60. <div class="flex justify-between">
  61. <div class="flex-initial">
  62. <n-checkbox v-model:checked="autoLogin">记住密码</n-checkbox>
  63. </div>
  64. <!-- <div class="flex-initial order-last">
  65. <a href="javascript:">忘记密码</a>
  66. </div> -->
  67. </div>
  68. </n-form-item>
  69. <n-form-item>
  70. <n-button
  71. class="submitBtm"
  72. type="primary"
  73. @click="handleSubmit"
  74. size="large"
  75. :loading="loading"
  76. block
  77. >
  78. 登录
  79. </n-button>
  80. </n-form-item>
  81. </n-form>
  82. </div>
  83. </div>
  84. </div>
  85. </div>
  86. </template>
  87. <script lang="ts" setup>
  88. import { reactive, ref } from 'vue'
  89. import { useRoute, useRouter } from 'vue-router'
  90. import { useUserStore } from '@/store/modules/user'
  91. import { useMessage } from 'naive-ui'
  92. import { ResultEnum } from '@/enums/httpEnum'
  93. import { storage } from '@/utils/storage'
  94. import { PageEnum } from '@/enums/pageEnum'
  95. import { websiteConfig } from '@/config/website.config'
  96. import loginMain from './images/login-main.png'
  97. import loginLogo from './images/login-logo.png'
  98. import lockIcon from './images/lock-icon.png'
  99. import useIcon from './images/user-icon.png'
  100. import openEye from './images/openEye.png'
  101. import closeEye from './images/closeEye.png'
  102. import { useTabsViewStore } from '@/store/modules/tabsView'
  103. import { TABS_ROUTES } from '@/store/mutation-types'
  104. interface FormState {
  105. username: string
  106. password: string
  107. grant_type: string
  108. loginType: string
  109. client_id: string
  110. client_secret: string
  111. }
  112. const formRef = ref()
  113. const message = useMessage()
  114. const loading = ref(false)
  115. const autoLogin = ref(true)
  116. const LOGIN_NAME = PageEnum.BASE_LOGIN_NAME
  117. const tabsViewStore = useTabsViewStore()
  118. const showPwd = ref(false)
  119. let formInline = reactive({
  120. username: '',
  121. password: '',
  122. isCaptcha: true
  123. })
  124. const formInlineHistory = storage.get('userInfo')
  125. if (formInlineHistory) {
  126. formInline = reactive({ ...JSON.parse(formInlineHistory) })
  127. }
  128. const rules = {
  129. username: { required: true, message: '请输入用户名', trigger: 'blur' },
  130. password: { required: true, message: '请输入密码', trigger: 'blur' }
  131. }
  132. const userStore = useUserStore()
  133. const router = useRouter()
  134. const route = useRoute()
  135. const handleSubmit = (e: any) => {
  136. e.preventDefault()
  137. localStorage.removeItem(TABS_ROUTES)
  138. formRef.value.validate(async (errors: any) => {
  139. if (!errors) {
  140. const { username, password } = formInline
  141. message.loading('登录中...')
  142. loading.value = true
  143. const params: FormState = {
  144. username,
  145. password,
  146. loginType: 'password',
  147. grant_type: 'password',
  148. client_id: 'dayaedu-backend',
  149. client_secret: 'dayaedu-backend'
  150. }
  151. try {
  152. const some = (await userStore.login(params)) as any
  153. message.destroyAll()
  154. if (some.code == ResultEnum.SUCCESS) {
  155. // 判断是否勾选自动登录
  156. if (autoLogin) {
  157. storage.set('userInfo', JSON.stringify(formInline))
  158. } else {
  159. storage.remove('userInfo')
  160. }
  161. // route.query?.redirect ||
  162. tabsViewStore.closeAllTabs()
  163. const toPath = decodeURIComponent('/' as string)
  164. message.success('登录成功,即将进入系统')
  165. if (route.name === LOGIN_NAME) {
  166. router.replace('/').then(() => {
  167. loading.value = false
  168. })
  169. } else {
  170. router.replace(toPath).then(() => {
  171. loading.value = false
  172. })
  173. }
  174. }
  175. } catch {
  176. loading.value = false
  177. } finally {
  178. // loading.value = false
  179. }
  180. }
  181. // else {
  182. // message.error('请填写完整信息,并且进行验证码校验')
  183. // }
  184. })
  185. }
  186. </script>
  187. <style lang="less" scoped>
  188. .no-pwd {
  189. font-family: 'dotfont';
  190. ::v-deep .n-input__input-el {
  191. -webkit-text-security: disc !important;
  192. -moz-text-security: disc !important;
  193. }
  194. }
  195. .view-account {
  196. background: url('./images/login-bg.png') no-repeat 100% 100%;
  197. background-size: 100%;
  198. display: flex;
  199. flex-direction: column;
  200. justify-content: center;
  201. align-items: center;
  202. min-height: 100vh;
  203. width: 100vw;
  204. background-color: #e9f7ff;
  205. overflow: auto;
  206. &-container {
  207. display: flex;
  208. flex-direction: row;
  209. justify-content: space-between;
  210. align-items: center;
  211. width: 1038px;
  212. height: 516px;
  213. background: #e8f2fe;
  214. border-radius: 18px 73px 18px 73px;
  215. border: 4px solid #ffffff;
  216. // margin: 10% auto 0;
  217. }
  218. &-left {
  219. margin-right: 10px;
  220. img {
  221. width: 475px;
  222. height: 433px;
  223. }
  224. }
  225. &-form {
  226. margin-right: 18px;
  227. width: 506px;
  228. height: 480px;
  229. background: #ffffff;
  230. box-shadow: 0px 1 14px 0px rgba(141, 141, 141, 0.05);
  231. border-radius: 21px 62px 21px 62px;
  232. .n-input {
  233. --n-border: 1px solid #dedede !important;
  234. --n-border-radius: 13px !important;
  235. }
  236. /deep/ .n-base-suffix {
  237. display: none !important;
  238. }
  239. .view-account-form-wrap {
  240. position: relative;
  241. padding: 25px 80px 0;
  242. .prefixIcon {
  243. width: 16px;
  244. height: 16px;
  245. margin-right: 5px;
  246. }
  247. .pwdIcon {
  248. width: 18px;
  249. height: 18px;
  250. cursor: pointer;
  251. }
  252. .formTitle {
  253. display: flex;
  254. flex-direction: row;
  255. align-items: center;
  256. width: 209px;
  257. height: 101px;
  258. margin: 0 auto 38px;
  259. img {
  260. width: inherit;
  261. height: inherit;
  262. }
  263. }
  264. }
  265. }
  266. .submitBtm {
  267. margin-top: 20px;
  268. background: #3594fa;
  269. border-radius: 12px;
  270. font-size: 16px;
  271. font-weight: 600;
  272. color: #ffffff;
  273. line-height: 22px;
  274. }
  275. &-top {
  276. padding: 32px 0;
  277. text-align: center;
  278. &-desc {
  279. font-size: 14px;
  280. color: #808695;
  281. }
  282. }
  283. &-other {
  284. width: 100%;
  285. }
  286. .default-color {
  287. color: #515a6e;
  288. .ant-checkbox-wrapper {
  289. color: #515a6e;
  290. }
  291. }
  292. }
  293. </style>