src/api/ai/user.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/hooks/useLogin.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/utils/global.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/login/index_yw.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
vite.config.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/api/ai/user.ts
@@ -33,3 +33,14 @@ ...extraData, }); }; export const userBindingWechat = async (params, req: any = request) => { return req({ url: '/user/user_bindingWeChat', method: 'POST', data: params, }); }; src/hooks/useLogin.ts
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,95 @@ import { ElMessage } from 'element-plus'; import { storeToRefs } from 'pinia'; import { useRoute } from 'vue-router'; import router from '../router'; import { initBackEndControlRoutes } from '../router/backEnd'; import { initFrontEndControlRoutes } from '../router/frontEnd'; import { useUserInfo } from '../stores/userInfo'; import { NextLoading } from '../utils/loading'; import { accessSessionKey, clearAccessTokens } from '../utils/request'; import { Local } from '../utils/storage'; import profileMan from '/@/assets/profile/man.svg'; import { useThemeConfig } from '../stores/themeConfig'; import { formatAxis } from '/@/utils/formatTime'; import { nextTick } from 'vue'; const getQueryParams = (params: any) => { const paramsObj = JSON.parse(params) ?? {}; const wechatKeys = ['isWxLogin', 'wxcode', 'wxstate']; const queryParams = {}; for (const key in paramsObj) { if (Object.prototype.hasOwnProperty.call(paramsObj, key)) { const element = paramsObj[key]; if (!wechatKeys.includes(key)) { queryParams[key] = element; } } } return queryParams; }; export const useLogin = () => { const storesThemeConfig = useThemeConfig(); const { themeConfig } = storeToRefs(storesThemeConfig); // ç»å½æååç跳转 const signInSuccess = (isNoPower: boolean | undefined, currentTime) => { if (isNoPower) { ElMessage.warning('æ¨æ²¡æç»å½æé'); clearAccessTokens(); } else { // åå§åç»å½æåæ¶é´é®åè¯ const currentTimeInfo = currentTime; // ç»å½æåï¼è·³å°è½¬é¦é¡µ // 妿æ¯å¤å¶ç²è´´çè·¯å¾ï¼éé¦é¡µ/ç»å½é¡µï¼é£ä¹ç»å½æååéå®åå°å¯¹åºçè·¯å¾ä¸ // console.log(route.query, 199); const currentRoute = router.currentRoute.value; if (currentRoute.query?.redirect) { router.push({ path: <string>currentRoute.query?.redirect, query: Object.keys(<string>currentRoute.query?.params).length > 0 ? getQueryParams(<string>currentRoute.query?.params) : '', }); setTimeout(() => { nextTick(() => { NextLoading.done(); }); }, 4000); } else { router.push('/'); } // ç»å½æåæç¤º const signInText = '欢è¿åæ¥ï¼'; ElMessage.success(`${currentTimeInfo}ï¼${signInText}`); // æ·»å loadingï¼é²æ¢ç¬¬ä¸æ¬¡è¿å ¥ç颿¶åºç°çæç©ºç½ // NextLoading.start(); } // state.loading.signIn = false; }; const handleAfterLogin = async (res) => { const currentTime = formatAxis(new Date()); Local.set(accessSessionKey, res.hswatersession); await useUserInfo().setUserInfos({ userName: res.name, phoneNumber: res.phone, photo: profileMan, }); //ç¼åç¨æ·ä¿¡æ¯ // state.loading.signIn = true; if (!themeConfig.value.isRequestRoutes) { // å端æ§å¶è·¯ç±ï¼2ãè¯·æ³¨ææ§è¡é¡ºåº const isNoPower = await initFrontEndControlRoutes(); // console.log(isNoPower,172) signInSuccess(isNoPower, currentTime); } else { // 模æå端æ§å¶è·¯ç±ï¼isRequestRoutes 为 trueï¼åå¼å¯å端æ§å¶è·¯ç± // æ·»å å®å¨æè·¯ç±ï¼åè¿è¡ router 跳转ï¼å¦åå¯è½æ¥é No match found for location with path "/" const isNoPower = await initBackEndControlRoutes(); // æ§è¡å® initBackEndControlRoutesï¼åæ§è¡ signInSuccess // console.log(isNoPower,178) signInSuccess(isNoPower, currentTime); } }; return { handleAfterLogin, }; }; src/main.ts
@@ -13,6 +13,7 @@ import '/@/theme/index.scss'; import * as ElementPlusIconsVue from '@element-plus/icons-vue'; import { gotoRoute } from '/@/utils/route'; import { checkWxOperate } from './utils/global'; const app = createApp(App); for (const [key, component] of Object.entries(ElementPlusIconsVue)) { @@ -29,3 +30,6 @@ } gotoRoute({ name }); }; checkWxOperate(); src/utils/global.ts
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,97 @@ import { ElMessage } from 'element-plus'; import { PostLogin, userBindingWechat } from '../api/ai/user'; import { SERVE_URL } from '../constants'; import { useLogin } from '../hooks/useLogin'; import { userInfoKey } from './request'; import { Local } from './storage'; const resolveWechatInfo = () => { const url = window.location.href; const hashParams = url.split('#')[1]; if (!hashParams) return; const [path, queryString] = hashParams.split('?'); if (!queryString) return; const params = new URLSearchParams(queryString); const wxcode = params.get('wxcode'); const isLogin = params.get('isWxLogin'); if (!wxcode) return; return { wxcode, isLogin }; }; export const checkWechatLogin = async (wxcode: string) => { const { handleAfterLogin } = useLogin(); // const loadingInstance = ElLoadingService({ // // text: 'å è½½ä¸...', // target: '.layout-parent', // }); const res = await PostLogin( { weixin_code: wxcode, }, { noAuth: true, handleFail: false, } ); if (res?.json_ok) { handleAfterLogin(res); Local.remove('isWechatLogin'); // ä½¿ç¨æ°å°åæ¿æ¢å½å页é¢,ç§»é¤å¾®ä¿¡ç»å½åæ° // const newUrl = window.location.href.split('?')[0]; // window.history.replaceState({}, '', SERVE_URL); // window.location.href = SERVE_URL; // window.location.reload(); } else { // isShowLogin.value = true; Local.set('isWechatLogin', true); Local.set('wechatLoginMsgInfo', { type: 'error', value: res?.json_msg ?? 'ç»å½å¤±è´¥ï¼è¯·æ£æ¥æ¯å¦å·²ç»å®å¾®ä¿¡', }); window.location.href = SERVE_URL; } }; export const handleBindWechat = async (wxcode: string) => { const userInfo = Local.get(userInfoKey); const res = await userBindingWechat({ weixin_code: wxcode, user_name: userInfo.userName, }); if (res?.json_ok) { ElMessage.success('ç»å®æå'); const userInfo = Local.get(userInfoKey); Local.set(userInfoKey, { ...userInfo, isBindWechat: true, wechatNickname: res.json_url, }); setTimeout(() => { window.location.href = SERVE_URL; }, 700); } else { ElMessage.error(res?.json_msg ?? 'ç»å®å¤±è´¥'); setTimeout(() => { window.location.href = SERVE_URL; }, 2000); } }; export const checkWxOperate = () => { const result = resolveWechatInfo(); if (!result) return; if (result.isLogin === 'Y') { checkWechatLogin(result.wxcode); } else { handleBindWechat(result.wxcode); } }; src/views/login/index_yw.vue
@@ -22,12 +22,27 @@ <div class="login-right-warp-main-title">{{ getThemeConfig.globalTitle }} æ¬¢è¿æ¨ï¼</div> <div class="login-right-warp-main-form"> <div v-if="!state.isScan"> <el-tabs v-model="state.tabsActiveName"> <el-tabs v-model="state.tabsActiveName" @tab-change="handleTabChange"> <el-tab-pane :label="$t('message.label.one1')" name="account"> <Account @login="handleAfterLogin"/> <Account @login="handleAfterLogin" /> </el-tab-pane> <el-tab-pane :label="$t('message.label.two2')" name="mobile"> <Mobile @login="handleAfterLogin"/> <Mobile @login="handleAfterLogin" /> </el-tab-pane> <el-tab-pane label="微信" name="wechat"> <div id="wechat-login" class="flex justify-center items-center"> <div class="flex flex-col items-center justify-center"> <iframe ref="wechatQrRef" sandbox="allow-top-navigation allow-scripts" style="width: 300px; height: 213px; overflow: hidden" frameborder="0" ></iframe> <span class="relative top-[-10px]" :class="{ 'text-red-400': wechatTip.type === 'error' }">{{ wechatTip.value }}</span> </div> </div> </el-tab-pane> </el-tabs> </div> @@ -46,20 +61,22 @@ </template> <script setup lang="ts" name="loginIndex"> import { storeToRefs } from 'pinia'; import { computed, defineAsyncComponent, onMounted, reactive } from 'vue'; import { useRoute } from 'vue-router'; import { useThemeConfig } from '/@/stores/themeConfig'; import { NextLoading } from '/@/utils/loading'; import { ElMessage } from 'element-plus'; import { storeToRefs } from 'pinia'; import { computed, defineAsyncComponent, nextTick, onMounted, reactive, ref } from 'vue'; import { useI18n } from 'vue-i18n'; import { useRoute } from 'vue-router'; import profileMan from '/@/assets/profile/man.svg'; import router from '/@/router'; import { initBackEndControlRoutes } from '/@/router/backEnd'; import { initFrontEndControlRoutes } from '/@/router/frontEnd'; import { useThemeConfig } from '/@/stores/themeConfig'; import { useUserInfo } from '/@/stores/userInfo'; import { clearAccessTokens, accessSessionKey } from '/@/utils/request'; import { NextLoading } from '/@/utils/loading'; import { accessSessionKey, clearAccessTokens } from '/@/utils/request'; import { Local } from '/@/utils/storage'; import profileMan from '/@/assets/profile/man.svg'; import { SERVE_URL } from '/@/constants'; import { useLogin } from '/@/hooks/useLogin'; const storesThemeConfig = useThemeConfig(); const { themeConfig } = storeToRefs(storesThemeConfig); @@ -71,12 +88,23 @@ const LayoutFooter = defineAsyncComponent(() => import('/@/layout/footer/index.vue')); const route = useRoute(); // 设置 footer æ¾ç¤º/éè const isFooter = computed(() => { return themeConfig.value.isFooter && !route.meta.isIframe; }); const getActiveLoginName = () => { const isWechatLogin = Local.get('isWechatLogin'); if (isWechatLogin) { Local.remove('isWechatLogin'); return 'wechat'; } return 'account'; }; const state = reactive({ tabsActiveName: 'account', tabsActiveName: getActiveLoginName(), isScan: false, }); @@ -87,66 +115,97 @@ const loginMain = window.globalConfig.SoftWareInfo.loginMain; const logoMini = window.globalConfig.SoftWareInfo.logoMini; const loginBg = window.globalConfig.SoftWareInfo.loginBg; const { t } = useI18n(); // ç»å½æååç跳转 const signInSuccess = (isNoPower: boolean | undefined, currentTime) => { if (isNoPower) { ElMessage.warning('æ¨æ²¡æç»å½æé'); clearAccessTokens(); } else { // åå§åç»å½æåæ¶é´é®åè¯ let currentTimeInfo = currentTime; // ç»å½æåï¼è·³å°è½¬é¦é¡µ // 妿æ¯å¤å¶ç²è´´çè·¯å¾ï¼éé¦é¡µ/ç»å½é¡µï¼é£ä¹ç»å½æååéå®åå°å¯¹åºçè·¯å¾ä¸ // console.log(route.query, 199); 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('/'); } // ç»å½æåæç¤º const signInText = t('message.signInText'); ElMessage.success(`${currentTimeInfo}ï¼${signInText}`); // æ·»å loadingï¼é²æ¢ç¬¬ä¸æ¬¡è¿å ¥ç颿¶åºç°çæç©ºç½ NextLoading.start(); } // state.loading.signIn = false; }; const handleAfterLogin = async (res, currentTime) => { Local.set(accessSessionKey, res.hswatersession); await useUserInfo().setUserInfos({ userName: res.name, phoneNumber: res.phone, photo: profileMan, }); //ç¼åç¨æ·ä¿¡æ¯ // state.loading.signIn = true; if (!themeConfig.value.isRequestRoutes) { // å端æ§å¶è·¯ç±ï¼2ãè¯·æ³¨ææ§è¡é¡ºåº const isNoPower = await initFrontEndControlRoutes(); // console.log(isNoPower,172) signInSuccess(isNoPower, currentTime); } else { // 模æå端æ§å¶è·¯ç±ï¼isRequestRoutes 为 trueï¼åå¼å¯å端æ§å¶è·¯ç± // æ·»å å®å¨æè·¯ç±ï¼åè¿è¡ router 跳转ï¼å¦åå¯è½æ¥é No match found for location with path "/" const isNoPower = await initBackEndControlRoutes(); // æ§è¡å® initBackEndControlRoutesï¼åæ§è¡ signInSuccess // console.log(isNoPower,178) signInSuccess(isNoPower, currentTime); } }; const { handleAfterLogin } = useLogin(); // 页é¢å è½½æ¶ onMounted(() => { NextLoading.done(); if (state.tabsActiveName === 'wechat') { nextTick(() => { openWechatLogin(); }); } }); const scanClick = () => { // state.isScan = !state.isScan; return; }; //#region ====================== 微信ç»é ====================== //åæ¢ç¨æ·ç»å½é¡µé¢ const handleTabChange = (item) => { resetWechatTip(); switch (item) { case 'wechat': // getWechartQrCode(); openWechatLogin(); break; case 'accountUser': break; case 'phoneUser': break; } }; const getWechatTipInfo = () => { const wechatLoginMsgInfo = Local.get('wechatLoginMsgInfo'); if (wechatLoginMsgInfo) { Local.remove('wechatLoginMsgInfo'); return wechatLoginMsgInfo; } return { type: 'info', value: '使ç¨å¾®ä¿¡æ«ä¸æ«ç»é' }; }; const wechatTip = ref(getWechatTipInfo()); const resetWechatTip = () => { wechatTip.value = { type: 'info', value: '使ç¨å¾®ä¿¡æ«ä¸æ«ç»é', }; }; const wechatQrRef = ref<HTMLIFrameElement>(); const openWechatLogin = () => { if (!wechatQrRef.value) return; const url = `${SERVE_URL}JJJHHH/home?isWxLogin=Y`; const appid = 'wx4ea2dca37170074c'; const state = (new Date().getTime() / 1000).toString(); const base64 = btoa(` .impowerBox .title {display:none;} .impowerBox .status.status_browser p:nth-of-type(2){ display: none; } .impowerBox .qrcode { width: 170px; margin-top:0; } .impowerBox .status{ } .info{ display: none; } #tpl_for_iframe{ height:100%; overflow: hidden; display: flex; flex-direction: column; align-items: center; justify-content: center; } `); const wechatAuthUrl = `https://open.weixin.qq.com/connect/qrconnect?appid=${appid}&redirect_uri=${encodeURIComponent( `http://apiv3.xpump.net/User/wxUserLoginCB.html?from=wi&url=${url}` )}&response_type=code&scope=snsapi_login&state=${state}&href=data:text/css;base64,${base64}#wechat_redirect`; wechatQrRef.value.src = wechatAuthUrl; }; //#endregion </script> <style scoped lang="scss"> vite.config.ts
@@ -45,7 +45,7 @@ host: '0.0.0.0', port: env.VITE_PORT as unknown as number, open: JSON.parse(env.VITE_OPEN), hmr: true, hmr: false, proxy: { '/gitee': { target: 'https://gitee.com',