123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380 |
- <template>
- <div class="login-wrapper">
- <div class="login_left">
- <div class="version">
- <a class="xn-color-a0a0a0" :href="sysBaseConfig.SNOWY_SYS_COPYRIGHT_URL" target="_blank">{{
- sysBaseConfig.SNOWY_SYS_COPYRIGHT
- }}</a>
- <div class="xn-color-a0a0a0">鄂ICP备20000826号-1</div>
- </div>
- </div>
- <div class="login_right">
- <div class="login_head">
- <img class="login-logo" :src="sysBaseConfig.SNOWY_SYS_LOGO" />
- <span class="login-title">{{ sysBaseConfig.SNOWY_SYS_NAME }}</span>
- </div>
- <div class="login_form">
- <div class="form_head">登录</div>
- <a-form ref="loginForm" :model="ruleForm" :rules="rules" layout="vertical">
- <!-- 用户名 -->
- <a-form-item label="用户名" name="account">
- <a-input v-model:value="ruleForm.account" placeholder="用户名" size="large" @keyup.enter="login"> </a-input>
- </a-form-item>
- <!-- 密码 -->
- <a-form-item label="密码" name="password">
- <a-input-password
- v-model:value="ruleForm.password"
- placeholder="密码"
- size="large"
- autocomplete="off"
- @keyup.enter="login"
- >
- </a-input-password>
- </a-form-item>
- <!-- 验证码 -->
- <a-form-item label="验证码" name="validCode" v-if="captchaOpen === 'true'">
- <a-row :gutter="8">
- <a-col :span="17">
- <a-input v-model:value="ruleForm.validCode" placeholder="验证码" size="large" @keyup.enter="login">
- </a-input>
- </a-col>
- <a-col :span="7">
- <img :src="validCodeBase64" class="login-validCode-img" @click="loginCaptcha" />
- </a-col>
- </a-row>
- </a-form-item>
- <!-- 记住登录状态 -->
- <a-form-item>
- <a-checkbox v-model:checked="ruleForm.autologin">记住用户名密码</a-checkbox>
- </a-form-item>
- <!-- 登录按钮 -->
- <a-form-item>
- <a-button type="primary" class="w-full" :loading="loading" round size="large" @click="login"
- >{{ $t('login.signIn') }}
- </a-button>
- </a-form-item>
- </a-form>
- <!-- <div class="form_foot">没有账号?点击<router-link to="/findpwd" class="nav-link">注册</router-link></div> -->
- </div>
- <div class="login_official">
- <img src="/src/assets/images/login/official.jpg" class="code" />
- </div>
- <div class="tip">扫码关注公众号,实时获取预警信息</div>
- </div>
- </div>
- </template>
- <script setup>
- import loginApi from '@/api/auth/loginApi'
- const PhoneLoginForm = defineAsyncComponent(() => import('./phoneLoginForm.vue'))
- import ThreeLogin from './threeLogin.vue'
- import smCrypto from '@/utils/smCrypto'
- import { required } from '@/utils/formRules'
- import { afterLogin } from './util'
- import configData from '@/config'
- import configApi from '@/api/dev/configApi'
- import tool from '@/utils/tool'
- import { globalStore, iframeStore, keepAliveStore, viewTagsStore } from '@/store'
- const { proxy } = getCurrentInstance()
- const activeKey = ref('userAccount')
- const captchaOpen = ref(configData.SYS_BASE_CONFIG.SNOWY_SYS_DEFAULT_CAPTCHA_OPEN)
- const validCodeBase64 = ref('')
- const loading = ref(false)
- const ruleForm = reactive({
- account: 'superAdmin',
- password: '123456',
- validCode: '',
- validCodeReqNo: '',
- autologin: false
- })
- const rules = reactive({
- account: [required('请输入用户名', 'blur')],
- password: [required(proxy.$t('login.PWError'), 'blur')]
- })
- const lang = ref([
- {
- name: '简体中文',
- value: 'zh-cn'
- },
- {
- name: 'English',
- value: 'en'
- }
- ])
- const config = ref({
- lang: tool.data.get('APP_LANG') || proxy.$CONFIG.LANG,
- theme: tool.data.get('APP_THEME') || 'default'
- })
- const store = globalStore()
- const kStore = keepAliveStore()
- const iStore = iframeStore()
- const vStore = viewTagsStore()
- const setSysBaseConfig = store.setSysBaseConfig
- const clearKeepLive = kStore.clearKeepLive
- const clearIframeList = iStore.clearIframeList
- const clearViewTags = vStore.clearViewTags
- const sysBaseConfig = computed(() => {
- return store.sysBaseConfig
- })
- onMounted(() => {
- let formData = ref(configData.SYS_BASE_CONFIG)
- getAutologin() //记住登录状态
- configApi
- .configSysBaseList()
- .then((data) => {
- if (data) {
- data.forEach((item) => {
- formData.value[item.configKey] = item.configValue
- })
- captchaOpen.value = formData.value.SNOWY_SYS_DEFAULT_CAPTCHA_OPEN
- tool.data.set('SNOWY_SYS_BASE_CONFIG', formData.value)
- setSysBaseConfig(formData.value)
- refreshSwitch()
- }
- })
- .catch(() => {})
- })
- onBeforeMount(() => {
- clearViewTags()
- clearKeepLive()
- clearIframeList()
- })
- // 监听语言
- watch(
- () => config.value.lang,
- (newValue) => {
- proxy.$i18n.locale = newValue
- tool.data.set('APP_LANG', newValue)
- }
- )
- // 主题
- watch(
- () => config.value.theme,
- (newValue) => {
- document.body.setAttribute('data-theme', newValue)
- }
- )
- //记住状态
- const getAutologin = () => {
- let account = tool.data.get('account')
- let password = tool.data.get('password')
- let autologin = tool.data.get('autologin')
- ruleForm.account = account === undefined ? ruleForm.account : account
- ruleForm.password = password === undefined ? ruleForm.password : password
- ruleForm.autologin = autologin === undefined ? ruleForm.account : autologin
- }
- // 通过开关加载内容
- const refreshSwitch = () => {
- // 判断是否开启验证码
- if (captchaOpen.value === 'true') {
- // 加载验证码
- loginCaptcha()
- // 加入校验
- rules.validCode = [required(proxy.$t('login.validError'), 'blur')]
- }
- }
- // 获取验证码
- const loginCaptcha = () => {
- loginApi.getPicCaptcha().then((data) => {
- validCodeBase64.value = data.validCodeBase64
- ruleForm.validCodeReqNo = data.validCodeReqNo
- })
- }
- //登陆
- const loginForm = ref()
- const login = async () => {
- loginForm.value
- .validate()
- .then(async () => {
- loading.value = true
- const loginData = {
- account: ruleForm.account,
- // 密码进行SM2加密,传输过程中看到的只有密文,后端存储使用hash
- password: smCrypto.doSm2Encrypt(ruleForm.password),
- validCode: ruleForm.validCode,
- validCodeReqNo: ruleForm.validCodeReqNo
- }
- //是否记住登录状态
- if (ruleForm.autologin) {
- tool.data.set('loginForm', ruleForm.account)
- tool.data.set('password', ruleForm.password)
- tool.data.set('autologin', ruleForm.autologin)
- } else {
- tool.data.remove('account')
- tool.data.remove('password')
- tool.data.remove('autologin')
- }
- // 获取token
- try {
- const loginToken = await loginApi.login(loginData)
- await afterLogin(loginToken)
- } catch (err) {
- loading.value = false
- if (captchaOpen.value === 'true') {
- loginCaptcha()
- }
- }
- })
- .catch(() => {})
- }
- const configLang = (key) => {
- config.value.lang = key
- }
- // logo链接
- const handleLink = (e) => {
- if (!sysBaseConfig.value.SNOWY_SYS_COPYRIGHT_URL) {
- e?.stopPropagation()
- e?.preventDefault()
- }
- }
- </script>
- <style lang="less" scoped>
- .login-wrapper {
- width: 100%;
- min-height: 850px;
- height: 100vh;
- display: flex;
- position: relative;
- background-image: url('/src/assets/images/login/bg.png'); /* 背景图 */
- background-size: cover;
- background-position: center;
- .login_left {
- flex: 7.5;
- position: relative;
- .version {
- font-size: 13px;
- position: absolute;
- bottom: 20px;
- left: 20px;
- a {
- text-decoration: none;
- }
- div {
- margin-top: 8px;
- }
- }
- }
- .login_right {
- flex: 2.5;
- padding: 0 50px 50px;
- padding-top: 5%;
- background-color: rgba(0, 0, 0, 0.6);
- // 标题logo区域
- .login_head {
- display: flex;
- align-items: center;
- .login-logo {
- width: 50px;
- height: 45px;
- }
- .login-title {
- padding: 0 15px;
- font-size: 28px;
- color: #ffffff;
- }
- }
- // 登录表单
- .login_form {
- width: 100%;
- padding: 0 5px;
- display: flex;
- flex-direction: column;
- // 登录名称
- .form_head {
- font-size: 24px;
- color: #fff;
- margin: 60px 0 40px;
- }
- // 登录按钮
- .w-full {
- background-color: #016de8;
- margin-top: 10px;
- }
- // 注册
- .form_foot {
- font-size: 14px;
- .nav-link {
- text-decoration: none;
- color: #0052cc;
- }
- .nav-link:hover {
- text-decoration: underline;
- }
- }
- }
- :deep(.ant-form-item) {
- margin-bottom: 35px;
- label {
- font-size: 15px;
- color: #676767;
- }
- .ant-input,
- .ant-input-affix-wrapper,
- .ant-input-password-icon {
- background-color: #1a1a1a;
- color: #a0a0a0;
- border-color: #1a1a1a;
- }
- .ant-input::placeholder {
- font-size: 13px;
- color: #a0a0a0;
- }
- .ant-input:hover,
- .ant-input-affix-wrapper:hover {
- background-color: #1a1a1a;
- border-color: #1a1a1a;
- }
- }
- // 公众号
- .login_official {
- width: max-content;
- text-align: center;
- padding: 4px;
- box-sizing: border-box;
- margin: 80px auto 20px;
- border: 1px solid #a0a0a0;
- .code {
- width: 100px;
- height: 100px;
- }
- }
- // 提示扫码
- .tip {
- font-size: 13px;
- color: #a0a0a0;
- text-align: center;
- }
- }
- }
- </style>
|