index.vue 8.1 KB

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