index.vue 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. <script setup lang="ts" name="loginIndex">
  2. import { defineAsyncComponent, onMounted, reactive, computed } from 'vue';
  3. import { storeToRefs } from 'pinia';
  4. import { useThemeConfig } from '/@/stores/themeConfig';
  5. import { NextLoading } from '/@/utils/loading';
  6. import logoMini from '/@/assets/logo-mini.svg';
  7. import loginMain from '/@/assets/login-main.svg';
  8. import loginBg from '/@/assets/login-bg.svg';
  9. import { SystemConfigStore } from '/@/stores/systemConfig'
  10. import { getBaseURL } from "/@/utils/baseUrl";
  11. // 引入组件
  12. const Account = defineAsyncComponent(() => import('/@/views/system/login/component/account.vue'));
  13. const Mobile = defineAsyncComponent(() => import('/@/views/system/login/component/mobile.vue'));
  14. const Scan = defineAsyncComponent(() => import('/@/views/system/login/component/scan.vue'));
  15. import _ from "lodash-es";
  16. // 定义变量内容
  17. const storesThemeConfig = useThemeConfig();
  18. const { themeConfig } = storeToRefs(storesThemeConfig);
  19. const state = reactive({
  20. tabsActiveName: 'account',
  21. isScan: false,
  22. });
  23. // 获取布局配置信息
  24. const getThemeConfig = computed(() => {
  25. return themeConfig.value;
  26. });
  27. const systemConfigStore = SystemConfigStore()
  28. const { systemConfig } = storeToRefs(systemConfigStore)
  29. const getSystemConfig = computed(() => {
  30. return systemConfig.value
  31. })
  32. const siteLogo = computed(() => {
  33. if (!_.isEmpty(getSystemConfig.value['login.site_logo'])) {
  34. return getSystemConfig.value['login.site_logo']
  35. }
  36. return logoMini
  37. });
  38. const siteBg = computed(() => {
  39. if (!_.isEmpty(getSystemConfig.value['login.login_background'])) {
  40. return getSystemConfig.value['login.login_background']
  41. }
  42. });
  43. function showScan() {
  44. state.isScan = !state.isScan;
  45. }
  46. // 页面加载时
  47. onMounted(() => {
  48. NextLoading.done();
  49. });
  50. </script>
  51. <template>
  52. <div class="login-container flex z-10">
  53. <div class="login-left">
  54. <div class="login-left-logo">
  55. <img :src="siteLogo" />
  56. <div class="login-left-logo-text">
  57. <span>{{ getSystemConfig['login.site_title'] || getThemeConfig.globalViceTitle }}</span>
  58. <span class="login-left-logo-text-msg">{{
  59. getSystemConfig['login.site_name'] || getThemeConfig.globalViceTitleMsg }}</span>
  60. </div>
  61. </div>
  62. <div class="login-left-img">
  63. <img :src="loginMain" />
  64. </div>
  65. <img :src="loginBg" class="login-left-waves" />
  66. </div>
  67. <div class="login-right flex z-10">
  68. <div class="login-right-warp flex-margin">
  69. <span class="login-right-warp-one"></span>
  70. <span class="login-right-warp-two"></span>
  71. <div class="login-right-warp-mian">
  72. <div class="login-right-warp-main-title">{{ getSystemConfig['login.site_title'] ||
  73. getThemeConfig.globalTitle }} 欢迎您!</div>
  74. <div class="login-right-warp-main-form">
  75. <div v-if="!state.isScan">
  76. <el-tabs v-model="state.tabsActiveName">
  77. <el-tab-pane :label="$t('message.label.one1')" name="account">
  78. <Account />
  79. </el-tab-pane>
  80. <!-- TODO 手机号码登录未接入,展示隐藏 -->
  81. <!-- <el-tab-pane :label="$t('message.label.two2')" name="mobile">
  82. <Mobile />
  83. </el-tab-pane> -->
  84. </el-tabs>
  85. </div>
  86. <Scan v-if="state.isScan" :isScan="state.isScan" />
  87. <div class="login-content-main-sacn" @click="showScan">
  88. <i :class="state.isScan ? 'icon-diannao1' : 'icon-barcode-qr'" class="iconfont"></i>
  89. <div class="login-content-main-sacn-delta"></div>
  90. </div>
  91. </div>
  92. </div>
  93. </div>
  94. </div>
  95. <div class="login-authorization z-10">
  96. <p>Copyright © {{ getSystemConfig['login.copyright'] || '2021-2024 django-vue-admin.com' }} 版权所有</p>
  97. <p class="la-other">
  98. <a href="https://beian.miit.gov.cn" target="_blank">{{ getSystemConfig['login.keep_record'] ||
  99. '晋ICP备18005113号-3' }}</a>
  100. |
  101. <a :href="getSystemConfig['login.help_url'] ? getSystemConfig['login.help_url'] : 'https://django-vue-admin.com'"
  102. target="_blank">帮助</a>
  103. |
  104. <a
  105. :href="getSystemConfig['login.privacy_url'] ? getBaseURL(getSystemConfig['login.privacy_url']) : '#'">隐私</a>
  106. |
  107. <a
  108. :href="getSystemConfig['login.clause_url'] ? getBaseURL(getSystemConfig['login.clause_url']) : '#'">条款</a>
  109. </p>
  110. </div>
  111. </div>
  112. <div v-if="siteBg">
  113. <img :src="siteBg" class="fixed inset-0 z-1 w-full h-full" />
  114. </div>
  115. </template>
  116. <style scoped lang="scss">
  117. .login-container {
  118. height: 100%;
  119. background: var(--el-color-white);
  120. .login-left {
  121. flex: 1;
  122. position: relative;
  123. background-color: rgba(211, 239, 255, 1);
  124. margin-right: 100px;
  125. .login-left-logo {
  126. display: flex;
  127. align-items: center;
  128. position: absolute;
  129. top: 50px;
  130. left: 80px;
  131. z-index: 1;
  132. animation: logoAnimation 0.3s ease;
  133. img {
  134. width: 52px;
  135. height: 52px;
  136. }
  137. .login-left-logo-text {
  138. display: flex;
  139. flex-direction: column;
  140. span {
  141. margin-left: 10px;
  142. font-size: 16px;
  143. color: var(--el-color-primary);
  144. }
  145. .login-left-logo-text-msg {
  146. font-size: 12px;
  147. color: var(--el-color-primary);
  148. }
  149. }
  150. }
  151. .login-left-img {
  152. position: absolute;
  153. top: 50%;
  154. left: 50%;
  155. transform: translate(-50%, -50%);
  156. width: 100%;
  157. height: 52%;
  158. img {
  159. width: 100%;
  160. height: 100%;
  161. animation: error-num 0.6s ease;
  162. }
  163. }
  164. .login-left-waves {
  165. position: absolute;
  166. top: 0;
  167. right: -100px;
  168. }
  169. }
  170. .login-right {
  171. width: 700px;
  172. .login-right-warp {
  173. border: 1px solid var(--el-color-primary-light-3);
  174. border-radius: 3px;
  175. width: 500px;
  176. height: 500px;
  177. position: relative;
  178. overflow: hidden;
  179. background-color: var(--el-color-white);
  180. .login-right-warp-one,
  181. .login-right-warp-two {
  182. position: absolute;
  183. display: block;
  184. width: inherit;
  185. height: inherit;
  186. &::before,
  187. &::after {
  188. content: '';
  189. position: absolute;
  190. z-index: 1;
  191. }
  192. }
  193. .login-right-warp-one {
  194. &::before {
  195. filter: hue-rotate(0deg);
  196. top: 0px;
  197. left: 0;
  198. width: 100%;
  199. height: 3px;
  200. background: linear-gradient(90deg, transparent, var(--el-color-primary));
  201. animation: loginLeft 3s linear infinite;
  202. }
  203. &::after {
  204. filter: hue-rotate(60deg);
  205. top: -100%;
  206. right: 2px;
  207. width: 3px;
  208. height: 100%;
  209. background: linear-gradient(180deg, transparent, var(--el-color-primary));
  210. animation: loginTop 3s linear infinite;
  211. animation-delay: 0.7s;
  212. }
  213. }
  214. .login-right-warp-two {
  215. &::before {
  216. filter: hue-rotate(120deg);
  217. bottom: 2px;
  218. right: -100%;
  219. width: 100%;
  220. height: 3px;
  221. background: linear-gradient(270deg, transparent, var(--el-color-primary));
  222. animation: loginRight 3s linear infinite;
  223. animation-delay: 1.4s;
  224. }
  225. &::after {
  226. filter: hue-rotate(300deg);
  227. bottom: -100%;
  228. left: 0px;
  229. width: 3px;
  230. height: 100%;
  231. background: linear-gradient(360deg, transparent, var(--el-color-primary));
  232. animation: loginBottom 3s linear infinite;
  233. animation-delay: 2.1s;
  234. }
  235. }
  236. .login-right-warp-mian {
  237. display: flex;
  238. flex-direction: column;
  239. height: 100%;
  240. .login-right-warp-main-title {
  241. height: 130px;
  242. line-height: 130px;
  243. font-size: 27px;
  244. text-align: center;
  245. letter-spacing: 3px;
  246. animation: logoAnimation 0.3s ease;
  247. animation-delay: 0.3s;
  248. color: var(--el-text-color-primary);
  249. }
  250. .login-right-warp-main-form {
  251. flex: 1;
  252. padding: 0 50px 50px;
  253. .login-content-main-sacn {
  254. position: absolute;
  255. top: 2px;
  256. right: 12px;
  257. width: 50px;
  258. height: 50px;
  259. overflow: hidden;
  260. cursor: pointer;
  261. transition: all ease 0.3s;
  262. color: var(--el-color-primary);
  263. &-delta {
  264. position: absolute;
  265. width: 35px;
  266. height: 70px;
  267. z-index: 2;
  268. top: 2px;
  269. right: 21px;
  270. background: var(--el-color-white);
  271. transform: rotate(-45deg);
  272. }
  273. &:hover {
  274. opacity: 1;
  275. transition: all ease 0.3s;
  276. color: var(--el-color-primary) !important;
  277. }
  278. i {
  279. width: 47px;
  280. height: 50px;
  281. display: inline-block;
  282. font-size: 48px;
  283. position: absolute;
  284. right: 1px;
  285. top: 0px;
  286. }
  287. }
  288. }
  289. }
  290. }
  291. }
  292. .login-authorization {
  293. position: fixed;
  294. bottom: 30px;
  295. left: 0;
  296. right: 0;
  297. text-align: center;
  298. p {
  299. font-size: 14px;
  300. color: rgba(0, 0, 0, 0.5);
  301. }
  302. a {
  303. color: var(--el-color-primary);
  304. margin: 0 5px;
  305. }
  306. }
  307. }
  308. </style>