|
@@ -1,255 +1,308 @@
|
|
|
<template>
|
|
|
- <el-form ref="formRef" size="large" class="login-content-form" :model="state.ruleForm" :rules="rules">
|
|
|
- <el-form-item class="login-animation1" prop="username">
|
|
|
- <el-input type="text" :placeholder="$t('message.account.accountPlaceholder1')" v-model="ruleForm.username"
|
|
|
- clearable autocomplete="off">
|
|
|
- <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.accountPlaceholder2')"
|
|
|
- v-model="ruleForm.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="ruleForm.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="ruleForm.captchaImgBase" @click="refreshCaptcha" />
|
|
|
- </el-button>
|
|
|
- </el-col>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item class="login-animation4">
|
|
|
- <el-button type="primary" class="login-content-submit" round @keyup.enter="loginClick" @click="loginClick"
|
|
|
- :loading="loading.signIn">
|
|
|
- <span>{{ $t('message.account.accountBtnText') }}</span>
|
|
|
- </el-button>
|
|
|
- </el-form-item>
|
|
|
- </el-form>
|
|
|
+ <el-form ref="formRef" size="large" class="login-content-form" :model="state.ruleForm" :rules="rules">
|
|
|
+ <el-form-item class="login-animation1" prop="username">
|
|
|
+ <el-input
|
|
|
+ type="text"
|
|
|
+ :placeholder="$t('message.account.accountPlaceholder1')"
|
|
|
+ v-model="ruleForm.username"
|
|
|
+ clearable
|
|
|
+ autocomplete="off">
|
|
|
+ <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.accountPlaceholder2')"
|
|
|
+ v-model="ruleForm.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="ruleForm.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="ruleForm.captchaImgBase" @click="refreshCaptcha" />
|
|
|
+ </el-button>
|
|
|
+ </el-col>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item class="login-animation4">
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ class="login-content-submit"
|
|
|
+ round
|
|
|
+ @keyup.enter="loginClick"
|
|
|
+ @click="loginClick"
|
|
|
+ :loading="loading.signIn">
|
|
|
+ <span>{{ $t('message.account.accountBtnText') }}</span>
|
|
|
+ </el-button>
|
|
|
+ <el-button type="primary" class="login-content-submit" round @click="qrLoginClick"> 企业微信扫码登录</el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
</template>
|
|
|
|
|
|
<script lang="ts">
|
|
|
-import { toRefs, reactive, defineComponent, computed, onMounted, onUnmounted, ref } from 'vue';
|
|
|
-import { useRoute, useRouter } from 'vue-router';
|
|
|
-import { ElMessage, FormInstance, FormRules } from 'element-plus';
|
|
|
-import { useI18n } from 'vue-i18n';
|
|
|
-import Cookies from 'js-cookie';
|
|
|
-import { storeToRefs } from 'pinia';
|
|
|
-import { useThemeConfig } from '/@/stores/themeConfig';
|
|
|
-import { initFrontEndControlRoutes } from '/@/router/frontEnd';
|
|
|
-import { initBackEndControlRoutes } from '/@/router/backEnd';
|
|
|
-import { Session } from '/@/utils/storage';
|
|
|
-import { formatAxis } from '/@/utils/formatTime';
|
|
|
-import { NextLoading } from '/@/utils/loading';
|
|
|
-import * as loginApi from '/@/views/system/login/api';
|
|
|
-import { useUserInfo } from '/@/stores/userInfo';
|
|
|
-import { DictionaryStore } from '/@/stores/dictionary';
|
|
|
-import { SystemConfigStore } from '/@/stores/systemConfig';
|
|
|
-import { BtnPermissionStore } from '/@/plugin/permission/store.permission';
|
|
|
-import { Md5 } from 'ts-md5';
|
|
|
-import { errorMessage } from '/@/utils/message';
|
|
|
+import { toRefs, reactive, defineComponent, computed, onMounted, onUnmounted, ref } from 'vue'
|
|
|
+import { useRoute, useRouter } from 'vue-router'
|
|
|
+import { ElMessage, FormInstance, FormRules } from 'element-plus'
|
|
|
+import { useI18n } from 'vue-i18n'
|
|
|
+import Cookies from 'js-cookie'
|
|
|
+import { storeToRefs } from 'pinia'
|
|
|
+import { useThemeConfig } from '/@/stores/themeConfig'
|
|
|
+import { initFrontEndControlRoutes } from '/@/router/frontEnd'
|
|
|
+import { initBackEndControlRoutes } from '/@/router/backEnd'
|
|
|
+import { Session } from '/@/utils/storage'
|
|
|
+import { formatAxis } from '/@/utils/formatTime'
|
|
|
+import { NextLoading } from '/@/utils/loading'
|
|
|
+import * as loginApi from '/@/views/system/login/api'
|
|
|
+import { useUserInfo } from '/@/stores/userInfo'
|
|
|
+import { DictionaryStore } from '/@/stores/dictionary'
|
|
|
+import { SystemConfigStore } from '/@/stores/systemConfig'
|
|
|
+import { BtnPermissionStore } from '/@/plugin/permission/store.permission'
|
|
|
+import { Md5 } from 'ts-md5'
|
|
|
+import { errorMessage } from '/@/utils/message'
|
|
|
+import { getWorkWeChatCode, postWorkWeChatCode } from '../api'
|
|
|
|
|
|
export default defineComponent({
|
|
|
- name: 'loginAccount',
|
|
|
- setup() {
|
|
|
- const { t } = useI18n();
|
|
|
- const storesThemeConfig = useThemeConfig();
|
|
|
- const { themeConfig } = storeToRefs(storesThemeConfig);
|
|
|
- const { userInfos } = storeToRefs(useUserInfo());
|
|
|
- const route = useRoute();
|
|
|
- const router = useRouter();
|
|
|
- const state = reactive({
|
|
|
- isShowPassword: false,
|
|
|
- ruleForm: {
|
|
|
- username: '',
|
|
|
- password: '',
|
|
|
- captcha: '',
|
|
|
- captchaKey: '',
|
|
|
- captchaImgBase: '',
|
|
|
- },
|
|
|
- loading: {
|
|
|
- signIn: false,
|
|
|
- },
|
|
|
- });
|
|
|
- const rules = reactive<FormRules>({
|
|
|
- username: [
|
|
|
- { required: true, message: '请填写账号', trigger: 'blur' },
|
|
|
- ],
|
|
|
- password: [
|
|
|
- {
|
|
|
- required: true,
|
|
|
- message: '请填写密码',
|
|
|
- trigger: 'blur',
|
|
|
- },
|
|
|
- ],
|
|
|
- captcha: [
|
|
|
- {
|
|
|
- required: true,
|
|
|
- message: '请填写验证码',
|
|
|
- trigger: 'blur',
|
|
|
- },
|
|
|
- ],
|
|
|
- })
|
|
|
- const formRef = ref();
|
|
|
- // 时间获取
|
|
|
- const currentTime = computed(() => {
|
|
|
- return formatAxis(new Date());
|
|
|
- });
|
|
|
- // 是否关闭验证码
|
|
|
- const isShowCaptcha = computed(() => {
|
|
|
- return SystemConfigStore().systemConfig['base.captcha_state'];
|
|
|
- });
|
|
|
-
|
|
|
- const getCaptcha = async () => {
|
|
|
- loginApi.getCaptcha().then((ret: any) => {
|
|
|
- state.ruleForm.captchaImgBase = ret.data.image_base;
|
|
|
- state.ruleForm.captchaKey = ret.data.key;
|
|
|
- });
|
|
|
- };
|
|
|
- const refreshCaptcha = async () => {
|
|
|
- loginApi.getCaptcha().then((ret: any) => {
|
|
|
- state.ruleForm.captchaImgBase = ret.data.image_base;
|
|
|
- state.ruleForm.captchaKey = ret.data.key;
|
|
|
- });
|
|
|
- };
|
|
|
- const loginClick = async () => {
|
|
|
- if (!formRef.value) return
|
|
|
- await formRef.value.validate((valid: any) => {
|
|
|
- if (valid) {
|
|
|
- loginApi.login({ ...state.ruleForm, password: Md5.hashStr(state.ruleForm.password) }).then((res: any) => {
|
|
|
- if (res.code === 2000) {
|
|
|
- Session.set('token', res.data.access);
|
|
|
- Cookies.set('username', res.data.name);
|
|
|
- if (!themeConfig.value.isRequestRoutes) {
|
|
|
- // 前端控制路由,2、请注意执行顺序
|
|
|
- initFrontEndControlRoutes();
|
|
|
- loginSuccess();
|
|
|
- } else {
|
|
|
- // 模拟后端控制路由,isRequestRoutes 为 true,则开启后端控制路由
|
|
|
- // 添加完动态路由,再进行 router 跳转,否则可能报错 No match found for location with path "/"
|
|
|
- initBackEndControlRoutes();
|
|
|
- // 执行完 initBackEndControlRoutes,再执行 signInSuccess
|
|
|
- loginSuccess();
|
|
|
- }
|
|
|
- } else if (res.code === 4000) {
|
|
|
- // 登录错误之后,刷新验证码
|
|
|
- refreshCaptcha();
|
|
|
- }
|
|
|
- });
|
|
|
- } else {
|
|
|
- errorMessage("请填写登录信息")
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
- };
|
|
|
- const getUserInfo = () => {
|
|
|
- useUserInfo().setUserInfos();
|
|
|
- };
|
|
|
-
|
|
|
-
|
|
|
- // 登录成功后的跳转
|
|
|
- const loginSuccess = () => {
|
|
|
- //登录成功获取用户信息,获取系统字典数据
|
|
|
- getUserInfo();
|
|
|
- //获取所有字典
|
|
|
- DictionaryStore().getSystemDictionarys();
|
|
|
-
|
|
|
- // 初始化登录成功时间问候语
|
|
|
- let currentTimeInfo = currentTime.value;
|
|
|
- // 登录成功,跳到转首页
|
|
|
- // 如果是复制粘贴的路径,非首页/登录页,那么登录成功后重定向到对应的路径中
|
|
|
- if (route.query?.redirect) {
|
|
|
- router.push({
|
|
|
- path: <string>route.query?.redirect,
|
|
|
- query: Object.keys(<string>route.query?.params).length > 0 ? JSON.parse(<string>route.query?.params) : '',
|
|
|
- });
|
|
|
- } else {
|
|
|
- router.push('/');
|
|
|
- }
|
|
|
- // 登录成功提示
|
|
|
- // 关闭 loading
|
|
|
- state.loading.signIn = true;
|
|
|
- const signInText = t('message.signInText');
|
|
|
- ElMessage.success(`${currentTimeInfo},${signInText}`);
|
|
|
- // 添加 loading,防止第一次进入界面时出现短暂空白
|
|
|
- NextLoading.start();
|
|
|
- };
|
|
|
- onMounted(() => {
|
|
|
- getCaptcha();
|
|
|
- //获取系统配置
|
|
|
- SystemConfigStore().getSystemConfigs();
|
|
|
- });
|
|
|
-
|
|
|
-
|
|
|
- return {
|
|
|
- refreshCaptcha,
|
|
|
- loginClick,
|
|
|
- loginSuccess,
|
|
|
- isShowCaptcha,
|
|
|
- state,
|
|
|
- formRef,
|
|
|
- rules,
|
|
|
- ...toRefs(state),
|
|
|
- };
|
|
|
- },
|
|
|
-});
|
|
|
+ name: 'loginAccount',
|
|
|
+ setup() {
|
|
|
+ const { t } = useI18n()
|
|
|
+ const storesThemeConfig = useThemeConfig()
|
|
|
+ const { themeConfig } = storeToRefs(storesThemeConfig)
|
|
|
+ const { userInfos } = storeToRefs(useUserInfo())
|
|
|
+ const route = useRoute()
|
|
|
+ const router = useRouter()
|
|
|
+ const state = reactive({
|
|
|
+ isShowPassword: false,
|
|
|
+ ruleForm: {
|
|
|
+ username: '',
|
|
|
+ password: '',
|
|
|
+ captcha: '',
|
|
|
+ captchaKey: '',
|
|
|
+ captchaImgBase: '',
|
|
|
+ },
|
|
|
+ loading: {
|
|
|
+ signIn: false,
|
|
|
+ },
|
|
|
+ })
|
|
|
+ const rules = reactive<FormRules>({
|
|
|
+ username: [{ required: true, message: '请填写账号', trigger: 'blur' }],
|
|
|
+ password: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: '请填写密码',
|
|
|
+ trigger: 'blur',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ captcha: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: '请填写验证码',
|
|
|
+ trigger: 'blur',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ })
|
|
|
+ const formRef = ref()
|
|
|
+ // 时间获取
|
|
|
+ const currentTime = computed(() => {
|
|
|
+ return formatAxis(new Date())
|
|
|
+ })
|
|
|
+ // 是否关闭验证码
|
|
|
+ const isShowCaptcha = computed(() => {
|
|
|
+ return SystemConfigStore().systemConfig['base.captcha_state']
|
|
|
+ })
|
|
|
+
|
|
|
+ const getCaptcha = async () => {
|
|
|
+ loginApi.getCaptcha().then((ret: any) => {
|
|
|
+ state.ruleForm.captchaImgBase = ret.data.image_base
|
|
|
+ state.ruleForm.captchaKey = ret.data.key
|
|
|
+ })
|
|
|
+ }
|
|
|
+ const refreshCaptcha = async () => {
|
|
|
+ loginApi.getCaptcha().then((ret: any) => {
|
|
|
+ state.ruleForm.captchaImgBase = ret.data.image_base
|
|
|
+ state.ruleForm.captchaKey = ret.data.key
|
|
|
+ })
|
|
|
+ }
|
|
|
+ const loginClick = async () => {
|
|
|
+ if (!formRef.value) return
|
|
|
+ await formRef.value.validate((valid: any) => {
|
|
|
+ if (valid) {
|
|
|
+ loginApi.login({ ...state.ruleForm, password: Md5.hashStr(state.ruleForm.password) }).then((res: any) => {
|
|
|
+ if (res.code === 2000) {
|
|
|
+ Session.set('token', res.data.access)
|
|
|
+ Cookies.set('username', res.data.name)
|
|
|
+ if (!themeConfig.value.isRequestRoutes) {
|
|
|
+ // 前端控制路由,2、请注意执行顺序
|
|
|
+ initFrontEndControlRoutes()
|
|
|
+ loginSuccess()
|
|
|
+ } else {
|
|
|
+ // 模拟后端控制路由,isRequestRoutes 为 true,则开启后端控制路由
|
|
|
+ // 添加完动态路由,再进行 router 跳转,否则可能报错 No match found for location with path "/"
|
|
|
+ initBackEndControlRoutes()
|
|
|
+ // 执行完 initBackEndControlRoutes,再执行 signInSuccess
|
|
|
+ loginSuccess()
|
|
|
+ }
|
|
|
+ } else if (res.code === 4000) {
|
|
|
+ // 登录错误之后,刷新验证码
|
|
|
+ refreshCaptcha()
|
|
|
+ }
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ errorMessage('请填写登录信息')
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ const getUserInfo = () => {
|
|
|
+ useUserInfo().setUserInfos()
|
|
|
+ }
|
|
|
+
|
|
|
+ // 登录成功后的跳转
|
|
|
+ const loginSuccess = () => {
|
|
|
+ //登录成功获取用户信息,获取系统字典数据
|
|
|
+ getUserInfo()
|
|
|
+ //获取所有字典
|
|
|
+ DictionaryStore().getSystemDictionarys()
|
|
|
+
|
|
|
+ // 初始化登录成功时间问候语
|
|
|
+ let currentTimeInfo = currentTime.value
|
|
|
+ // 登录成功,跳到转首页
|
|
|
+ // 如果是复制粘贴的路径,非首页/登录页,那么登录成功后重定向到对应的路径中
|
|
|
+ if (route.query?.redirect) {
|
|
|
+ router.push({
|
|
|
+ path: <string>route.query?.redirect,
|
|
|
+ query: Object.keys(<string>route.query?.params).length > 0 ? JSON.parse(<string>route.query?.params) : '',
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ router.push('/')
|
|
|
+ }
|
|
|
+ // 登录成功提示
|
|
|
+ // 关闭 loading
|
|
|
+ state.loading.signIn = true
|
|
|
+ const signInText = t('message.signInText')
|
|
|
+ ElMessage.success(`${currentTimeInfo},${signInText}`)
|
|
|
+ // 添加 loading,防止第一次进入界面时出现短暂空白
|
|
|
+ NextLoading.start()
|
|
|
+ }
|
|
|
+
|
|
|
+ const qrCode = ref('')
|
|
|
+
|
|
|
+ async function qrLoginClick() {
|
|
|
+ try {
|
|
|
+ const response = await getWorkWeChatCode()
|
|
|
+ window.location.href = response.data
|
|
|
+ qrCode.value = response.data
|
|
|
+ // if (qrCode.value) {
|
|
|
+ console.log(123, this.$route.query.code)
|
|
|
+ // await WorkWeChatCodeLogin()
|
|
|
+ // }
|
|
|
+ } catch (error) {
|
|
|
+ console.log('error:', error)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ async function WorkWeChatCodeLogin() {
|
|
|
+ const post = {
|
|
|
+ code: qrCode.value,
|
|
|
+ state: 'Wechat',
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ const response = await postWorkWeChatCode(post)
|
|
|
+ console.log('response', response.data)
|
|
|
+ } catch (error) {
|
|
|
+ console.log('error:', error)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ onMounted(() => {
|
|
|
+ getCaptcha()
|
|
|
+ //获取系统配置
|
|
|
+ SystemConfigStore().getSystemConfigs()
|
|
|
+ })
|
|
|
+
|
|
|
+ return {
|
|
|
+ refreshCaptcha,
|
|
|
+ loginClick,
|
|
|
+ loginSuccess,
|
|
|
+ isShowCaptcha,
|
|
|
+ state,
|
|
|
+ formRef,
|
|
|
+ rules,
|
|
|
+ ...toRefs(state),
|
|
|
+ qrLoginClick,
|
|
|
+ qrCode,
|
|
|
+ WorkWeChatCodeLogin,
|
|
|
+ }
|
|
|
+ },
|
|
|
+})
|
|
|
</script>
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
.login-content-form {
|
|
|
- margin-top: 20px;
|
|
|
-
|
|
|
- @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: 300;
|
|
|
- margin-top: 15px;
|
|
|
- }
|
|
|
+ margin-top: 20px;
|
|
|
+
|
|
|
+ @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: 300;
|
|
|
+ margin-top: 15px;
|
|
|
+ }
|
|
|
}
|
|
|
</style>
|