From fa3ac93010bea3805438ee3ab0a182bfbf7423da Mon Sep 17 00:00:00 2001 From: baoshiwei <baoshiwei@shlanbao.cn> Date: 星期一, 27 五月 2024 16:19:31 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/master' --- src/views/system/loginmini/MiniLogin.vue | 563 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 563 insertions(+), 0 deletions(-) diff --git a/src/views/system/loginmini/MiniLogin.vue b/src/views/system/loginmini/MiniLogin.vue new file mode 100644 index 0000000..5d8bd7e --- /dev/null +++ b/src/views/system/loginmini/MiniLogin.vue @@ -0,0 +1,563 @@ +<template> + <div :class="prefixCls" class="login-background-img"> + <AppLocalePicker class="absolute top-4 right-4 enter-x xl:text-gray-600" :showText="false" /> + <AppDarkModeToggle class="absolute top-3 right-7 enter-x" /> + <div class="aui-logo" v-if="!getIsMobile"> + <div> + <h3> + <img :src="logoImg" alt="jeecg" /> + </h3> + </div> + </div> + <div v-else class="aui-phone-logo"> + <img :src="logoImg" alt="jeecg" /> + </div> + <div v-show="type === 'login'"> + <div class="aui-content"> + <div class="aui-container"> + <div class="aui-form"> + <div class="aui-image"> + <div>Lanpu</div> + <div>鏅鸿兘涓嵂骞茬嚗鏈烘暟瀛楀寲杞﹂棿</div> + <!-- <div class="aui-image-text">--> + <!-- <img :src="adTextImg" />--> + <!-- </div>--> + </div> + <div class="aui-formBox"> + <div class="aui-formWell"> + <div class="aui-flex aui-form-nav investment_title"> + <div class="aui-flex-box" :class="activeIndex === 'accountLogin' ? 'activeNav on' : ''" @click="loginClick('accountLogin')" + >{{ t('sys.login.signInFormTitle') }} + </div> + <div class="aui-flex-box" :class="activeIndex === 'phoneLogin' ? 'activeNav on' : ''" @click="loginClick('phoneLogin')" + >{{ t('sys.login.mobileSignInFormTitle') }} + </div> + </div> + <div class="aui-form-box" style="height: 180px"> + <a-form ref="loginRef" :model="formData" v-if="activeIndex === 'accountLogin'" @keyup.enter.native="loginHandleClick"> + <div class="aui-account"> + <div class="aui-inputClear"> + <i class="icon icon-code"></i> + <a-form-item> + <a-input class="fix-auto-fill" :placeholder="t('sys.login.userName')" v-model:value="formData.username" /> + </a-form-item> + </div> + <div class="aui-inputClear"> + <i class="icon icon-password"></i> + <a-form-item> + <a-input class="fix-auto-fill" type="password" :placeholder="t('sys.login.password')" v-model:value="formData.password" /> + </a-form-item> + </div> + <!-- <div class="aui-inputClear"> + <i class="icon icon-code"></i> + <a-form-item> + <a-input class="fix-auto-fill" type="text" :placeholder="t('sys.login.inputCode')" v-model:value="formData.inputCode" /> + </a-form-item> + <div class="aui-code"> + <img v-if="randCodeData.requestCodeSuccess" :src="randCodeData.randCodeImage" @click="handleChangeCheckCode" /> + <img v-else style="margin-top: 2px; max-width: initial" :src="codeImg" @click="handleChangeCheckCode" /> + </div> + </div> --> + <div class="aui-flex"> + <div class="aui-flex-box"> + <div class="aui-choice"> + <a-input class="fix-auto-fill" type="checkbox" v-model:value="rememberMe" /> + <span style="margin-left: 5px">{{ t('sys.login.rememberMe') }}</span> + </div> + </div> + <div class="aui-forget"> + <a @click="forgetHandelClick"> {{ t('sys.login.forgetPassword') }}</a> + </div> + </div> + </div> + </a-form> + <a-form v-else ref="phoneFormRef" :model="phoneFormData" @keyup.enter.native="loginHandleClick"> + <div class="aui-account phone"> + <div class="aui-inputClear phoneClear"> + <a-input class="fix-auto-fill" :placeholder="t('sys.login.mobile')" v-model:value="phoneFormData.mobile" /> + </div> + <div class="aui-inputClear"> + <a-input class="fix-auto-fill" :maxlength="6" :placeholder="t('sys.login.smsCode')" v-model:value="phoneFormData.smscode" /> + <div v-if="showInterval" class="aui-code" @click="getLoginCode"> + <a>{{ t('component.countdown.normalText') }}</a> + </div> + <div v-else class="aui-code"> + <span class="aui-get-code code-shape">{{ t('component.countdown.sendText', [unref(timeRuning)]) }}</span> + </div> + </div> + </div> + </a-form> + </div> + <div class="aui-formButton"> + <div class="aui-flex"> + <a-button :loading="loginLoading" class="aui-link-login aui-flex-box" type="primary" @click="loginHandleClick"> + {{ t('sys.login.loginButton') }}</a-button + > + </div> + <div class="aui-flex"> + <a class="aui-linek-code aui-flex-box" @click="codeHandleClick">{{ t('sys.login.qrSignInFormTitle') }}</a> + </div> + <div class="aui-flex"> + <a class="aui-linek-code aui-flex-box" @click="registerHandleClick">{{ t('sys.login.registerButton') }}</a> + </div> + </div> + </div> + <a-form @keyup.enter.native="loginHandleClick"> + <div class="aui-flex aui-third-text"> + <div class="aui-flex-box aui-third-border"> + <span>{{ t('sys.login.otherSignIn') }}</span> + </div> + </div> + <div class="aui-flex" :class="`${prefixCls}-sign-in-way`"> + <div class="aui-flex-box"> + <div class="aui-third-login"> + <a title="github" @click="onThirdLogin('github')"><GithubFilled /></a> + </div> + </div> + <div class="aui-flex-box"> + <div class="aui-third-login"> + <a title="浼佷笟寰俊" @click="onThirdLogin('wechat_enterprise')"><icon-font class="item-icon" type="icon-qiyeweixin3" /></a> + </div> + </div> + <div class="aui-flex-box"> + <div class="aui-third-login"> + <a title="閽夐拤" @click="onThirdLogin('dingtalk')"><DingtalkCircleFilled /></a> + </div> + </div> + <div class="aui-flex-box"> + <div class="aui-third-login"> + <a title="寰俊" @click="onThirdLogin('wechat_open')"><WechatFilled /></a> + </div> + </div> + </div> + </a-form> + </div> + </div> + </div> + </div> + </div> + <div v-show="type === 'forgot'" :class="`${prefixCls}-form`"> + <MiniForgotpad ref="forgotRef" @go-back="goBack" @success="handleSuccess" /> + </div> + <div v-show="type === 'register'" :class="`${prefixCls}-form`"> + <MiniRegister ref="registerRef" @go-back="goBack" @success="handleSuccess" /> + </div> + <div v-show="type === 'codeLogin'" :class="`${prefixCls}-form`"> + <MiniCodelogin ref="codeRef" @go-back="goBack" @success="handleSuccess" /> + </div> + <!-- 绗笁鏂圭櫥褰曠浉鍏冲脊妗� --> + <ThirdModal ref="thirdModalRef" /> + </div> +</template> +<script lang="ts" setup name="login-mini"> + import { getCaptcha, getCodeInfo } from '/@/api/sys/user' + import { computed, onMounted, reactive, ref, toRaw, unref } from 'vue' + import codeImg from '/@/assets/images/checkcode.png' + import { Rule } from '/@/components/Form' + import { useUserStore } from '/@/store/modules/user' + import { useMessage } from '/@/hooks/web/useMessage' + import { useI18n } from '/@/hooks/web/useI18n' + import { SmsEnum } from '/@/views/sys/login/useLogin' + import ThirdModal from '/@/views/sys/login/ThirdModal.vue' + import MiniForgotpad from './MiniForgotpad.vue' + import MiniRegister from './MiniRegister.vue' + import MiniCodelogin from './MiniCodelogin.vue' + import logoImg from '/@/assets/loginmini/icon/lanpu_logo.png' + import adTextImg from '/@/assets/loginmini/icon/jeecg_ad_text.png' + import { AppLocalePicker, AppDarkModeToggle } from '/@/components/Application' + import { useLocaleStore } from '/@/store/modules/locale' + import { useDesign } from '/@/hooks/web/useDesign' + import { useAppInject } from '/@/hooks/web/useAppInject' + import { GithubFilled, WechatFilled, DingtalkCircleFilled, createFromIconfontCN } from '@ant-design/icons-vue' + + const IconFont = createFromIconfontCN({ + scriptUrl: '//at.alicdn.com/t/font_2316098_umqusozousr.js', + }) + const { prefixCls } = useDesign('mini-login') + const { notification, createMessage } = useMessage() + const userStore = useUserStore() + const { t } = useI18n() + const localeStore = useLocaleStore() + const showLocale = localeStore.getShowPicker + const randCodeData = reactive<any>({ + randCodeImage: '', + requestCodeSuccess: false, + checkKey: null, + }) + const rememberMe = ref<string>('0') + //鎵嬫満鍙风櫥褰曡繕鏄处鍙风櫥褰� + const activeIndex = ref<string>('accountLogin') + const type = ref<string>('login') + //璐﹀彿鐧诲綍琛ㄥ崟瀛楁 + const formData = reactive<any>({ + inputCode: '', + username: '', + password: '', + }) + //鎵嬫満鐧诲綍琛ㄥ崟瀛楁 + const phoneFormData = reactive<any>({ + mobile: '', + smscode: '', + }) + const loginRef = ref() + //绗笁鏂圭櫥褰曞脊绐� + const thirdModalRef = ref() + //鎵爜鐧诲綍 + const codeRef = ref() + //鏄惁鏄剧ず鑾峰彇楠岃瘉鐮� + const showInterval = ref<boolean>(true) + //60s + const timeRuning = ref<number>(60) + //瀹氭椂鍣� + const timer = ref<any>(null) + //蹇樿瀵嗙爜 + const forgotRef = ref() + //娉ㄥ唽 + const registerRef = ref() + const loginLoading = ref<boolean>(false) + const { getIsMobile } = useAppInject() + + defineProps({ + sessionTimeout: { + type: Boolean, + }, + }) + + /** + * 鑾峰彇楠岃瘉鐮� + */ + // function handleChangeCheckCode() { + // formData.inputCode = '' + + // randCodeData.checkKey = 1629428467008 + // getCodeInfo(randCodeData.checkKey).then((res) => { + // randCodeData.randCodeImage = res + // randCodeData.requestCodeSuccess = true + // }) + // } + + /** + * 鍒囨崲鐧诲綍鏂瑰紡 + */ + function loginClick(type) { + activeIndex.value = type + } + + /** + * 璐﹀彿鎴栬�呮墜鏈虹櫥褰� + */ + async function loginHandleClick() { + if (unref(activeIndex) === 'accountLogin') { + accountLogin() + } else { + //鎵嬫満鍙风櫥褰� + phoneLogin() + } + } + + async function accountLogin() { + if (!formData.username) { + createMessage.warn(t('sys.login.accountPlaceholder')) + return + } + if (!formData.password) { + createMessage.warn(t('sys.login.passwordPlaceholder')) + return + } + try { + loginLoading.value = true + const { userInfo } = await userStore.login( + toRaw({ + password: formData.password, + username: formData.username, + captcha: formData.inputCode, + checkKey: randCodeData.checkKey, + mode: 'none', //涓嶈榛樿鐨勯敊璇彁绀� + }) + ) + if (userInfo) { + notification.success({ + message: t('sys.login.loginSuccessTitle'), + description: `${t('sys.login.loginSuccessDesc')}: ${userInfo.realname}`, + duration: 3, + }) + } + } catch (error) { + notification.error({ + message: t('sys.api.errorTip'), + description: error.message || t('sys.login.networkExceptionMsg'), + duration: 3, + }) + // handleChangeCheckCode() + } finally { + loginLoading.value = false + } + } + + /** + * 鎵嬫満鍙风櫥褰� + */ + async function phoneLogin() { + if (!phoneFormData.mobile) { + createMessage.warn(t('sys.login.mobilePlaceholder')) + return + } + if (!phoneFormData.smscode) { + createMessage.warn(t('sys.login.smsPlaceholder')) + return + } + try { + loginLoading.value = true + const { userInfo }: any = await userStore.phoneLogin({ + mobile: phoneFormData.mobile, + captcha: phoneFormData.smscode, + mode: 'none', //涓嶈榛樿鐨勯敊璇彁绀� + }) + if (userInfo) { + notification.success({ + message: t('sys.login.loginSuccessTitle'), + description: `${t('sys.login.loginSuccessDesc')}: ${userInfo.realname}`, + duration: 3, + }) + } + } catch (error) { + notification.error({ + message: t('sys.api.errorTip'), + description: error.message || t('sys.login.networkExceptionMsg'), + duration: 3, + }) + } finally { + loginLoading.value = false + } + } + + /** + * 鑾峰彇鎵嬫満楠岃瘉鐮� + */ + async function getLoginCode() { + if (!phoneFormData.mobile) { + createMessage.warn(t('sys.login.mobilePlaceholder')) + return + } + const result = await getCaptcha({ mobile: phoneFormData.mobile, smsmode: SmsEnum.FORGET_PASSWORD }) + if (result) { + const TIME_COUNT = 60 + if (!unref(timer)) { + timeRuning.value = TIME_COUNT + showInterval.value = false + timer.value = setInterval(() => { + if (unref(timeRuning) > 0 && unref(timeRuning) <= TIME_COUNT) { + timeRuning.value = timeRuning.value - 1 + } else { + showInterval.value = true + clearInterval(unref(timer)) + timer.value = null + } + }, 1000) + } + } + } + + /** + * 绗笁鏂圭櫥褰� + * @param type + */ + function onThirdLogin(type) { + thirdModalRef.value.onThirdLogin(type) + } + + /** + * 蹇樿瀵嗙爜 + */ + function forgetHandelClick() { + type.value = 'forgot' + setTimeout(() => { + forgotRef.value.initForm() + }, 300) + } + + /** + * 杩斿洖鐧诲綍椤甸潰 + */ + function goBack() { + activeIndex.value = 'accountLogin' + type.value = 'login' + } + + /** + * 蹇樿瀵嗙爜/娉ㄥ唽璐﹀彿鍥炶皟浜嬩欢 + * @param value + */ + function handleSuccess(value) { + Object.assign(formData, value) + Object.assign(phoneFormData, { mobile: '', smscode: '' }) + type.value = 'login' + activeIndex.value = 'accountLogin' + // handleChangeCheckCode() + } + + /** + * 娉ㄥ唽 + */ + function registerHandleClick() { + type.value = 'register' + setTimeout(() => { + registerRef.value.initForm() + }, 300) + } + + /** + * 娉ㄥ唽 + */ + function codeHandleClick() { + type.value = 'codeLogin' + setTimeout(() => { + codeRef.value.initFrom() + }, 300) + } + + onMounted(() => { + //鍔犺浇楠岃瘉鐮� + // handleChangeCheckCode() + }) +</script> + +<style lang="less" scoped> + @import '/@/assets/loginmini/style/home.less'; + @import '/@/assets/loginmini/style/base.less'; + + :deep(.ant-input:focus) { + box-shadow: none; + } + .aui-get-code { + float: right; + position: relative; + z-index: 3; + background: #ffffff; + color: #1573e9; + border-radius: 100px; + padding: 5px 16px; + margin: 7px; + border: 1px solid #1573e9; + top: 12px; + } + + .aui-get-code:hover { + color: #1573e9; + } + + .code-shape { + border-color: #dadada !important; + color: #aaa !important; + } + + :deep(.jeecg-dark-switch) { + position: absolute; + margin-right: 10px; + } + .aui-link-login { + height: 42px; + padding: 10px 15px; + font-size: 14px; + border-radius: 8px; + margin-top: 15px; + margin-bottom: 8px; + } + .aui-phone-logo { + position: absolute; + margin-left: 10px; + width: 60px; + top: 2px; + z-index: 4; + } + .top-3 { + top: 0.45rem; + } +</style> + +<style lang="less"> + @prefix-cls: ~'@{namespace}-mini-login'; + @dark-bg: #293146; + + html[data-theme='dark'] { + .@{prefix-cls} { + background-color: @dark-bg !important; + background-image: none; + + &::before { + background-image: url(/@/assets/svg/login-bg-dark.svg); + } + .aui-inputClear { + background-color: #232a3b !important; + } + .ant-input, + .ant-input-password { + background-color: #232a3b !important; + } + + .ant-btn:not(.ant-btn-link):not(.ant-btn-primary) { + border: 1px solid #4a5569 !important; + } + + &-form { + background: @dark-bg !important; + } + + .app-iconify { + color: #fff !important; + } + .aui-inputClear input, + .aui-input-line input, + .aui-choice { + color: #c9d1d9 !important; + } + + .aui-formBox { + background-color: @dark-bg !important; + } + .aui-third-text span { + background-color: @dark-bg !important; + } + .aui-form-nav .aui-flex-box { + color: #c9d1d9 !important; + } + + .aui-formButton .aui-linek-code { + background: @dark-bg !important; + color: white !important; + } + .aui-code-line { + border-left: none !important; + } + .ant-checkbox-inner, + .aui-success h3 { + border-color: #c9d1d9; + } + } + + input.fix-auto-fill, + .fix-auto-fill input { + -webkit-text-fill-color: #c9d1d9 !important; + box-shadow: inherit !important; + } + + &-sign-in-way { + .anticon { + font-size: 22px !important; + color: #888 !important; + cursor: pointer !important; + + &:hover { + color: @primary-color !important; + } + } + } + .ant-divider-inner-text { + font-size: 12px !important; + color: @text-color-secondary !important; + } + .aui-third-login a { + background: transparent; + } + } +</style> -- Gitblit v1.9.3