index on master: a53bb07 feat: 登陆拦截逻辑

master
xjs 2025-03-03 12:22:37 +08:00
parent a53bb0789a
commit 281e672aee
13 changed files with 199 additions and 14 deletions

View File

@ -121,6 +121,8 @@
"newDetail": true,
"newsDetail": true,
"useNewsList": true,
"newsList": true
"newsList": true,
"useLogin": true,
"useWxInfo": true
}
}

2
env/.env vendored
View File

@ -2,7 +2,7 @@ VITE_APP_TITLE = '六维志愿'
VITE_APP_PORT = 9000
VITE_UNI_APPID = 'H57F2ACE4'
VITE_WX_APPID = 'wxa2abb91f64032a2b'
VITE_WX_APPID = '__UNI__7AE2402'
# h5部署网站的base配置到 manifest.config.ts 里的 h5.router.base
VITE_APP_PUBLIC_BASE=

View File

@ -3,7 +3,7 @@
<view
class="tabbar-item h-[100rpx] flex flex-col justify-center w-full items-center text-center"
v-for="(item, index) in tabbarList"
:key="index"
:key="item.id"
:class="[item.centerItem ? 'center-item' : '']"
@click="changeItem(item)"
>

View File

@ -18,7 +18,7 @@
class="truncate flex flex-col py-[32rpx]"
style="border-bottom: 2rpx solid #eee"
v-for="item in newsList"
:key="item"
:key="item.id"
@click="handleClick(item)"
>
<text class="truncate text-[28rpx] text-[#333333] font-normal mb-[16rpx] max-w-[80%]">

View File

@ -0,0 +1,115 @@
<template>
<wd-overlay :show="show" @click="handleClose">
<view
class="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 z-[10071] flex flex-col items-center bg-white p-[40rpx] rounded-[32rpx]"
>
<image
class="w-[200rpx] h-[200rpx]"
src="https://api.static.ycymedu.com/images/logo.png"
mode="aspectFit"
></image>
<view class="flex flex-col items-center">
<text class="text-[26rpx] mt-[20rpx] mb-[40rpx]" :selectable="false">
{{ phone ? '申请使用您的手机号' : '申请获取您的个人信息' }}
</text>
<wd-button
size="large"
custom-class="w-[493rpx] mb-[40rpx]"
@click="handleClick"
open-type="getPhoneNumber"
@getphonenumber="getPhoneNumber"
>
手机号快捷登录
</wd-button>
<view class="flex items-center flex-nowrap" @click="checked = true">
<wd-radio-group v-model="checked" custom-class="mr-10rpx">
<wd-radio :value="true" shape="dot"></wd-radio>
</wd-radio-group>
<view class="flex items-center">
<text class="text-[24rpx]">已阅读并同意服务条款隐私条款</text>
</view>
</view>
</view>
<wd-toast />
</view>
</wd-overlay>
</template>
<script lang="ts" setup>
import { useToast } from 'wot-design-uni'
import { useLogin, useWxInfo } from '@/hooks/useUserInfo'
import { getSessionKey } from '@/service/index/api'
import { useUserStore } from '@/store'
const props = defineProps({
show: {
type: Boolean,
default: false,
},
})
defineOptions({
options: {
styleIsolation: 'shared',
},
})
const emits = defineEmits(['update:close'])
const toast = useToast()
const userStore = useUserStore()
const handleClose = () => {
emits('update:close', false)
}
const phone = ref(true) //
const checked = ref(false) //
const getPhoneInfo = ref(null)
const getPhoneNumber = async (e: any) => {
if (e.errMsg == 'getPhoneNumber:ok') {
let _getPhoneInfo = {
iv: e.iv,
encryptedData: e.encryptedData,
code: e.code,
}
getPhoneInfo.value = _getPhoneInfo
getUserInfo(e.code)
// this.phone = false
} else if (e.errMsg == 'getPhoneNumber:fail not login') {
toast.warning('请先登录')
} else {
toast.warning('获取手机号失败')
}
}
const handleClick = () => {
if (!checked.value) {
toast.warning('您需先同意《服务条款》和《隐私条款》')
}
}
const getUserInfo = async (code: string) => {
let userInfo = (await useLogin()) as { code: string; errMsg: string }
console.log(userInfo)
if (userInfo.errMsg == 'login:ok') {
const resp = await getSessionKey({ JsCode: userInfo.code })
if (resp.code == 200) {
}
// useWxInfo({ code, OpenId: (resp.result as { openId: string }).openId })
} else {
toast.warning('您需先授权')
}
}
const parsePhoneNumber = (code: string, openId: string) => {
//
}
</script>
<style lang="scss" scoped>
:deep(.wd-radio) {
--wot-radio-margin: 0;
}
</style>

27
src/hooks/useUserInfo.ts Normal file
View File

@ -0,0 +1,27 @@
import { getWxInfo } from '@/service/index/api'
//uniapp 登陆获取用户信息
export const useLogin = () => {
return new Promise(function (resolve, reject) {
uni.login({
success: function (res) {
if (res.code) {
resolve(res)
} else {
reject(res)
}
},
fail: function (err) {
reject(err)
},
})
})
}
export const useWxInfo = ({ code, OpenId }) => {
getWxInfo({ code, OpenId }).then((res) => {
if (res.code === 200) {
console.log(res.result)
}
})
}

View File

@ -55,7 +55,7 @@
},
"quickapp": {},
"mp-weixin": {
"appid": "wxa2abb91f64032a2b",
"appid": "__UNI__7AE2402",
"setting": {
"urlCheck": false
},

View File

@ -60,7 +60,10 @@
{
"path": "pages/login/index",
"type": "page",
"style": {}
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "新高考选科"
}
},
{
"path": "pages/aiService/index/index",
@ -70,7 +73,6 @@
{
"path": "pages/evaluation/index/index",
"type": "page",
"layout": "demo",
"style": {
"navigationBarTitleText": "测评师"
},
@ -79,7 +81,7 @@
{
"path": "pages/expert/index/index",
"type": "page",
"layout": "demo",
"layout": "pages",
"style": {
"navigationBarTitleText": "测评师"
},

View File

@ -1,6 +1,5 @@
<route lang="json5" type="page">
{
layout: 'demo',
style: {
navigationBarTitleText: '测评师',
},

View File

@ -1,6 +1,6 @@
<route lang="json5" type="page">
{
layout: 'demo',
layout: 'pages',
style: {
navigationBarTitleText: '测评师',
},

View File

@ -1,12 +1,40 @@
<route lang="json5" type="page">
{
style: {
navigationStyle: 'custom',
navigationBarTitleText: '新高考选科',
},
}
</route>
<template>
<view class="login">
<view class="logo">
<view class="h-screen flex flex-col">
<wd-navbar safeAreaInsetTop custom-class="bg-transparent!" :bordered="false" fixed>
<template #title>
<text class="text-[#1F2329] text-[36rpx] font-medium">新高考选科</text>
</template>
</wd-navbar>
<view class="flex flex-col justify-center items-center flex-1 pb-safe">
<image
class="pic"
class="w-[424rpx] h-[424rpx]"
src="https://api.static.ycymedu.com/images/logo.png"
mode="aspectFit"
></image>
<wd-button @click="handleLogin"></wd-button>
</view>
<view style="width: 360rpx" class="w-[360rpx]">登陆</view>
<LoginMask v-bind:show="show" />
</view>
</template>
<script setup lang="ts">
import { useUserStore } from '@/store/user'
import LoginMask from '@/components/login/LoginMask.vue'
const userStore = useUserStore()
const { token } = userStore.userInfo as unknown as IUserInfo
const show = ref(false)
const handleLogin = () => {
show.value = true
}
</script>

View File

@ -64,3 +64,11 @@ export const getNewsList = (params: {
}) => {
return http.get('/api/ZyNews/newsPage', params)
}
export const getSessionKey = (params: { JsCode: string }) => {
return http.get('/api/sysWxOpen/wxOpenId', params)
}
export const getWxInfo = (params: { code: string; OpenId: string }) => {
return http.get('/api/weChatUserEx/wxInfo', params)
}

View File

@ -94,6 +94,7 @@ declare global {
const useCssModule: typeof import('vue')['useCssModule']
const useCssVars: typeof import('vue')['useCssVars']
const useId: typeof import('vue')['useId']
const useLogin: typeof import('../hooks/useUserInfo')['useLogin']
const useModel: typeof import('vue')['useModel']
const useNatureList: typeof import('../hooks/useFilterSchool')['useNatureList']
const useNavbarWeixin: typeof import('../hooks/useNavbarWeixin')['default']
@ -109,6 +110,7 @@ declare global {
const useUniversityType: typeof import('../hooks/useFilterSchool')['useUniversityType']
const useUpload: typeof import('../hooks/useUpload')['default']
const useUpload2: typeof import('../hooks/useUpload2')['default']
const useWxInfo: typeof import('../hooks/useUserInfo')['useWxInfo']
const watch: typeof import('vue')['watch']
const watchEffect: typeof import('vue')['watchEffect']
const watchPostEffect: typeof import('vue')['watchPostEffect']
@ -210,6 +212,7 @@ declare module 'vue' {
readonly useCssModule: UnwrapRef<typeof import('vue')['useCssModule']>
readonly useCssVars: UnwrapRef<typeof import('vue')['useCssVars']>
readonly useId: UnwrapRef<typeof import('vue')['useId']>
readonly useLogin: UnwrapRef<typeof import('../hooks/useUserInfo')['useLogin']>
readonly useModel: UnwrapRef<typeof import('vue')['useModel']>
readonly useNatureList: UnwrapRef<typeof import('../hooks/useFilterSchool')['useNatureList']>
readonly useNavbarWeixin: UnwrapRef<typeof import('../hooks/useNavbarWeixin')['default']>
@ -223,6 +226,7 @@ declare module 'vue' {
readonly useUniversityRank: UnwrapRef<typeof import('../hooks/useUnSortType')['useUniversityRank']>
readonly useUniversityType: UnwrapRef<typeof import('../hooks/useFilterSchool')['useUniversityType']>
readonly useUpload: UnwrapRef<typeof import('../hooks/useUpload')['default']>
readonly useWxInfo: UnwrapRef<typeof import('../hooks/useUserInfo')['useWxInfo']>
readonly watch: UnwrapRef<typeof import('vue')['watch']>
readonly watchEffect: UnwrapRef<typeof import('vue')['watchEffect']>
readonly watchPostEffect: UnwrapRef<typeof import('vue')['watchPostEffect']>