123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549 |
- <template>
- <div class="login-container flex z-10">
- <div class="login-left">
- <div class="login-left-logo">
- <img :src="siteLogo" /><!-- siteLogo -->
- <div class="login-left-logo-text">
- <span>{{ getSystemConfig['login.site_title'] || getThemeConfig.globalViceTitle }}</span><!-- -->
- <span class="login-left-logo-text-msg" style="margin-top: 5px">{{
- getSystemConfig['login.site_name'] || getThemeConfig.globalViceTitleMsg
- }}</span>
- </div>
- </div>
- </div>
- <div class="login-right flex z-10">
- <div class="login-right-warp flex-margin">
- <!-- <span class="login-right-warp-one"></span>-->
- <!-- <span class="login-right-warp-two"></span>-->
- <div class="login-right-warp-mian">
- <div class="login-right-warp-main-title">
- 超级管理员登陆
- </div>
- <div class="login-right-warp-main-form pt-4">
- <el-form ref="superformRef" size="large" class="login-content-form" :model="superForm"
- :rules="superRules" @keyup.enter="loginClick">
- <el-form-item class="login-animation1" prop="username">
- <el-input type="text" placeholder="请输入登录账号" v-model="superForm.username" clearable>
- <template #prefix>
- <el-icon class="el-input__icon"><ele-User /></el-icon>
- </template>
- </el-input>
- </el-form-item>
- <el-form-item class="login-animation2" prop="password">
- <el-input :type="isShowPassword ? 'text' : 'password'"
- :placeholder="$t('message.account.accountPlaceholder4')"
- v-model="superForm.password">
- <template #prefix>
- <el-icon class="el-input__icon"><ele-Unlock /></el-icon>
- </template>
- <template #suffix>
- <i class="iconfont el-input__icon login-content-password"
- :class="isShowPassword ? 'icon-yincangmima' : 'icon-xianshimima'"
- @click="isShowPassword = !isShowPassword">
- </i>
- </template>
- </el-input>
- </el-form-item>
- <el-form-item class="login-animation3" v-if="isShowCaptcha" prop="captcha">
- <el-col :span="15">
- <el-input type="text" maxlength="4"
- :placeholder="$t('message.account.accountPlaceholder3')"
- v-model="superForm.captcha" clearable autocomplete="off">
- <template #prefix>
- <el-icon class="el-input__icon"><ele-Position /></el-icon>
- </template>
- </el-input>
- </el-col>
- <el-col :span="1"></el-col>
- <el-col :span="8">
- <el-button class="login-content-captcha">
- <el-image :src="superForm.captchaImgBase" @click="refreshCaptcha" />
- </el-button>
- </el-col>
- </el-form-item>
- <el-form-item class="login-animation4">
- <el-button type="primary" class="login-content-submit w-full" round @click="loginClick"
- :loading="loading.signIn">
- <span>{{ $t('message.account.accountBtnText') }}</span>
- </el-button>
- </el-form-item>
- </el-form>
- </div>
- </div>
- </div>
- </div>
- <div class="login-authorization z-10">
- <!-- <p>Copyright © {{ getSystemConfig['login.copyright'] || '2021-2024 北京信码新创科技有限公司' }} 版权所有</p> -->
- <!-- <p class="la-other" style="margin-top: 5px">
- <a href="https://beian.miit.gov.cn" target="_blank">{{ getSystemConfig['login.keep_record'] || '京ICP备2021031018号' }}</a>
- |
- <a :href="getSystemConfig['login.help_url'] ? getSystemConfig['login.help_url'] : '#'" target="_blank">帮助</a>
- |
- <a :href="getSystemConfig['login.privacy_url'] ? getBaseURL(getSystemConfig['login.privacy_url']) : '#'">隐私</a>
- |
- <a :href="getSystemConfig['login.clause_url'] ? getBaseURL(getSystemConfig['login.clause_url']) : '#'">条款</a>
- </p> -->
- </div>
- </div>
- <div v-if="loginBg">
- <img :src="loginBg" class="loginBg fixed inset-0 z-1 w-full h-full" />
- </div>
- </template>
- <script setup lang="ts" name="loginIndex">
- import { defineAsyncComponent, onMounted, reactive, computed, watch, ref } from 'vue';
- import { storeToRefs } from 'pinia';
- import { useThemeConfig } from '/@/stores/themeConfig';
- import { NextLoading } from '/@/utils/loading';
- import logoMini from '/@/assets/logo-mini.svg';
- import loginMain from '/@/assets/login-main.svg';
- import loginBg from '/@/assets/login_background.jpg';
- import { SystemConfigStore } from '/@/stores/systemConfig';
- import { getBaseURL } from '/@/utils/baseUrl';
- import { useI18n } from 'vue-i18n';
- import * as api from './api';
- import * as loginApi from '/@/views/system/login/api';
- import { useUserInfo } from '/@/stores/userInfo';
- import { ElMessage } from 'element-plus';
- import { useRouter } from 'vue-router';
- import { Md5 } from 'ts-md5';
- import Cookies from 'js-cookie';
- import { Session } from '/@/utils/storage';
- import * as _ from 'lodash-es';
- // 引入组件
- const Account = defineAsyncComponent(() => import('/@/views/system/login/component/account.vue'));
- const Mobile = defineAsyncComponent(() => import('/@/views/system/login/component/mobile.vue'));
- const Scan = defineAsyncComponent(() => import('/@/views/system/login/component/scan.vue'));
- const ChangePwd = defineAsyncComponent(() => import('/@/views/system/login/component/changePwd.vue'));
- const { userInfos } = storeToRefs(useUserInfo());
- // 定义变量内容
- const storesThemeConfig = useThemeConfig();
- const { themeConfig } = storeToRefs(storesThemeConfig);
- const state = reactive({
- tabsActiveName: 'account',
- isScan: false,
- });
- const { t } = useI18n();
- watch(
- () => userInfos.value.pwd_change_count,
- (val) => {
- if (val === 0) {
- state.tabsActiveName = 'changePwd';
- } else {
- state.tabsActiveName = 'account';
- }
- },
- { deep: true, immediate: true }
- );
- // 获取布局配置信息
- const getThemeConfig = computed(() => {
- return themeConfig.value;
- });
- const systemConfigStore = SystemConfigStore();
- const { systemConfig } = storeToRefs(systemConfigStore);
- const getSystemConfig = computed(() => {
- return systemConfig.value;
- });
- const siteLogo = computed(() => {
- if (!_.isEmpty(getSystemConfig.value['login.site_logo'])) {
- return getSystemConfig.value['login.site_logo'];
- }
- return logoMini;
- });
- const siteBg = computed(() => {
- if (!_.isEmpty(getSystemConfig.value['login.login_background'])) {
- return getSystemConfig.value['login.login_background'];
- }
- });
- const superLogin = ref(true);
- // 添加loading状态
- const loading = reactive({
- signIn: false,
- });
- /* 超级管理员登录表单 */
- const superForm = ref({
- username: '', // 设置默认用户名
- password: '',
- captcha: '',
- captchaKey: '',
- captchaImgBase: '',
- });
- // 添加表单校验规则
- const superRules = reactive({
- username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
- password: [
- {
- required: true,
- message: '请填写密码',
- trigger: 'blur',
- },
- ],
- captcha: [
- {
- required: true,
- message: '请填写验证码',
- trigger: 'blur',
- },
- ],
- });
- const superformRef = ref();
- const router = useRouter();
- const formRef = ref();
- // 添加 formatAxis 函数定义
- const formatAxis = (date: Date): string => {
- const hours = date.getHours();
- const minutes = date.getMinutes();
- // 格式化时间为 HH:MM 格式
- return `${hours < 10 ? '0' + hours : hours}:${minutes < 10 ? '0' + minutes : minutes}`;
- };
- // 时间获取
- const currentTime = computed(() => {
- return formatAxis(new Date());
- });
- // 是否关闭验证码
- const isShowCaptcha = computed(() => {
- return SystemConfigStore().systemConfig['base.captcha_state'];
- });
- const getCaptcha = async () => {
- loginApi.getCaptcha().then((ret: any) => {
- console.log(ret);
- superForm.value.captchaImgBase = ret.data.image_base;
- superForm.value.captchaKey = ret.data.key;
- console.log(superForm);
- });
- };
- const applyBtnClick = async () => {
- window.open(getBaseURL('/api/system/apply_for_trial/'));
- };
- const refreshCaptcha = async () => {
- superForm.value.captcha = '';
- loginApi.getCaptcha().then((ret: any) => {
- superForm.value.captchaImgBase = ret.data.image_base;
- superForm.value.captchaKey = ret.data.key;
- });
- };
- // 添加登录方法
- const loginClick = async () => {
- if (!superformRef.value) return;
- await superformRef.value.validate(async (valid: boolean) => {
- if (valid) {
- try {
- loading.signIn = true;
- // 创建一个简单的登录数据对象,避免直接使用响应式对象
- const loginData = {
- username: superForm.value.username,
- password: superForm.value.password,
- captcha: superForm.value.captcha,
- captchaKey: superForm.value.captchaKey,
- captchaImgBase: superForm.value.captchaImgBase,
- };
- /* const res = */
- loginApi.login({ ...loginData, password: Md5.hashStr(loginData.password) }).then((res: any) => {
- console.log(res);
- if (res?.code === 2000) {
- ElMessage.success('登录成功');
- Cookies.set('username', res.data.username);
- Session.set('token', res.data.access);
- Session.set('superKey',res.data.role_info[0].key)
- Session.set('merchant_info', res.data.merchant_info);
- router.push('/');
- } else {
- ElMessage.error(res?.msg || '登录失败');
- }
- })
- } catch (error: any) {
- console.error('登录失败:', error);
- ElMessage.error(error?.message || '登录失败,请稍后重试');
- } finally {
- loading.signIn = false;
- }
- }
- });
- };
- const isShowPassword = ref(false);
- /* 跳转至超级管理员登录 */
- const goSuper = async () => {
- superLogin.value = !superLogin.value;
- };
- // 页面加载时
- onMounted(() => {
- getCaptcha();
- NextLoading.done();
- });
- </script>
- <style scoped lang="scss">
- .login-container {
- height: 100%;
- background: var(--el-color-white);
- .login-left {
- flex: 1;
- position: relative;
- background-color: rgba(211, 239, 255, 1);
- margin-right: 100px;
- .login-left-logo {
- display: flex;
- align-items: center;
- position: absolute;
- top: 50px;
- left: 80px;
- z-index: 1;
- animation: logoAnimation 0.3s ease;
- img {
- width: 52px;
- height: 52px;
- }
- .login-left-logo-text {
- display: flex;
- flex-direction: column;
- span {
- margin-left: 10px;
- font-size: 16px;
- color: var(--el-color-primary);
- }
- .login-left-logo-text-msg {
- font-size: 12px;
- color: var(--el-color-primary);
- }
- }
- }
- .login-left-img {
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- width: 100%;
- height: 52%;
- img {
- width: 100%;
- height: 100%;
- animation: error-num 0.6s ease;
- }
- }
- .login-left-waves {
- position: absolute;
- top: 0;
- right: -100px;
- }
- }
- .login-right {
- width: 700px;
- .login-right-warp {
- //border: 1px solid var(--el-color-primary-light-3);
- border-radius: 10px;
- width: 450px;
- height: 501px;
- position: relative;
- overflow: hidden;
- //background-color: var(--el-color-white);
- .login-right-warp-one,
- .login-right-warp-two {
- position: absolute;
- display: block;
- width: inherit;
- height: inherit;
- &::before,
- &::after {
- content: '';
- position: absolute;
- z-index: 1;
- }
- }
- .login-right-warp-one {
- &::before {
- filter: hue-rotate(0deg);
- top: 0px;
- left: 0;
- width: 100%;
- height: 3px;
- background: linear-gradient(90deg, transparent, var(--el-color-primary));
- animation: loginLeft 3s linear infinite;
- }
- &::after {
- filter: hue-rotate(60deg);
- top: -100%;
- right: 2px;
- width: 3px;
- height: 100%;
- background: linear-gradient(180deg, transparent, var(--el-color-primary));
- animation: loginTop 3s linear infinite;
- animation-delay: 0.7s;
- }
- }
- .login-right-warp-two {
- &::before {
- filter: hue-rotate(120deg);
- bottom: 2px;
- right: -100%;
- width: 100%;
- height: 3px;
- background: linear-gradient(270deg, transparent, var(--el-color-primary));
- animation: loginRight 3s linear infinite;
- animation-delay: 1.4s;
- }
- &::after {
- filter: hue-rotate(300deg);
- bottom: -100%;
- left: 0px;
- width: 3px;
- height: 100%;
- background: linear-gradient(360deg, transparent, var(--el-color-primary));
- animation: loginBottom 3s linear infinite;
- animation-delay: 2.1s;
- }
- }
- .login-right-warp-mian {
- display: flex;
- flex-direction: column;
- height: 100%;
- background: #fff;
- .login-right-warp-main-title {
- height: 130px;
- line-height: 130px;
- font-size: 32px;
- font-weight: 600;
- text-align: center;
- letter-spacing: 3px;
- animation: logoAnimation 0.3s ease;
- animation-delay: 0.3s;
- color: var(--el-text-color-primary);
- }
- .login-right-warp-main-form {
- flex: 1;
- padding: 0 50px 50px;
- .login-content-main-sacn {
- position: absolute;
- top: 2px;
- right: 12px;
- width: 50px;
- height: 50px;
- overflow: hidden;
- cursor: pointer;
- transition: all ease 0.3s;
- color: var(--el-color-primary);
- &-delta {
- position: absolute;
- width: 35px;
- height: 70px;
- z-index: 2;
- top: 2px;
- right: 21px;
- background: var(--el-color-white);
- transform: rotate(-45deg);
- }
- &:hover {
- opacity: 1;
- transition: all ease 0.3s;
- color: var(--el-color-primary) !important;
- }
- i {
- width: 47px;
- height: 50px;
- display: inline-block;
- font-size: 48px;
- position: absolute;
- right: 1px;
- top: 0px;
- }
- }
- }
- }
- }
- }
- .login-authorization {
- position: absolute;
- bottom: 30px;
- left: 0;
- right: 0;
- text-align: center;
- p {
- font-size: 14px;
- color: rgba(0, 0, 0, 0.5);
- }
- a {
- color: var(--el-color-primary);
- margin: 0 5px;
- }
- }
- }
- .login-content-form {
- @for $i from 1 through 4 {
- .login-animation#{$i} {
- opacity: 0;
- animation-name: error-num;
- animation-duration: 0.5s;
- animation-fill-mode: forwards;
- animation-delay: calc($i/10) + s;
- }
- }
- .login-content-password {
- display: inline-block;
- width: 20px;
- cursor: pointer;
- &:hover {
- color: #909399;
- }
- }
- .login-content-captcha {
- width: 100%;
- padding: 0;
- font-weight: bold;
- letter-spacing: 5px;
- }
- .login-content-submit {
- width: 100%;
- letter-spacing: 2px;
- font-weight: 800;
- margin-top: 15px;
- }
- }
- </style>
|