添加测试号、生产环境可以查看debug

This commit is contained in:
wangxiaowei
2025-10-05 18:05:58 +08:00
parent bdfa0a90f4
commit 168084029a
11 changed files with 184 additions and 49 deletions

2
.gitignore vendored
View File

@ -14,6 +14,7 @@ dist
# Editor directories and files
.idea
.history
*.suo
*.ntvs*
*.njsproj
@ -29,6 +30,7 @@ docs/.vitepress/cache
src/types
# lock 文件还是不要了,我主要的版本写死就好了
# pnpm-lock.yaml
# package-lock.json

11
env/.env vendored
View File

@ -5,18 +5,21 @@ VITE_UNI_APPID = '__UNI__D1E5001'
VITE_WX_APPID = 'wxa2abb91f64032a2b'
# h5部署网站的base配置到 manifest.config.ts 里的 h5.router.base
VITE_APP_PUBLIC_BASE=/
VITE_APP_PUBLIC_BASE = '/h5'
# 登录页面
VITE_LOGIN_URL = '/pages/login/login'
# 第一个请求地址
VITE_SERVER_BASEURL = 'https://mnp.zhuzhuda.cn'
VITE_SERVER_BASEURL = 'https://cz.stnav.com/gzhapi'
VITE_UPLOAD_BASEURL = 'https://mnp.zhuzhuda.cn/upload'
VITE_UPLOAD_BASEURL = 'https://cz.stnav.com/upload'
# h5是否需要配置代理
VITE_APP_PROXY=false
VITE_APP_PROXY_PREFIX = '/api'
# 第二个请求地址 (目前alova中可以使用)
VITE_API_SECONDARY_URL = 'https://mnp.zhuzhuda.cn'
VITE_API_SECONDARY_URL = 'https://cz.stnav.com'
# 公众号APPID
VITE_WX_SERVICE_ACCOUNT_APPID = 'wx0224f558e3b3f499'

2
env/.env.production vendored
View File

@ -1,6 +1,6 @@
# 变量必须以 VITE_ 为前缀才能暴露给外部读取
NODE_ENV = 'development'
# 是否去除console 和 debugger
VITE_DELETE_CONSOLE = true
VITE_DELETE_CONSOLE = false
# 是否开启sourcemap
VITE_SHOW_SOURCEMAP = false

View File

@ -2,6 +2,7 @@
import { onHide, onLaunch, onShow } from '@dcloudio/uni-app'
import { navigateToInterceptor } from '@/router/interceptor'
import 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only'
import {snsapiBaseAuthorize} from '@/hooks/useWeiXin'
onLaunch((options) => {
// 处理直接进入页面路由的情况如h5直接输入路由、微信小程序分享后进入等
@ -13,6 +14,9 @@
else {
navigateToInterceptor.invoke({ url: '/' })
}
// 微信静默授权
snsapiBaseAuthorize()
})
onShow((options) => {
console.log('App Show', options)

View File

@ -1,5 +1,22 @@
import type { ICaptcha, IUpdateInfo, IUpdatePassword, IUserInfoVo, IUserLogin } from './types/login'
import { http } from '@/http/http'
// import { http } from '@/http/http'
import { API_DOMAINS, http } from '@/http/alova'
/**
* 微信静默授权登录参数
*/
export interface IWxSnsapiBaseLoginForm {
code: string
}
/**
* 微信静默授权登录
*/
export function wxSnsapiBaseLogin(loginForm: IWxSnsapiBaseLoginForm) {
return http.Get<IUserLogin>('/login/oaLogin', {params: loginForm})
}
/**
* 登录表单
@ -16,7 +33,7 @@ export interface ILoginForm {
* @returns ICaptcha 验证码
*/
export function getCode() {
return http.get<ICaptcha>('/user/getCode')
return http.Get<ICaptcha>('/user/getCode')
}
/**
@ -24,35 +41,35 @@ export function getCode() {
* @param loginForm 登录表单
*/
export function login(loginForm: ILoginForm) {
return http.post<IUserLogin>('/user/login', loginForm)
return http.Post<IUserLogin>('/user/login', loginForm)
}
/**
* 获取用户信息
*/
export function getUserInfo() {
return http.get<IUserInfoVo>('/user/info')
return http.Get<IUserInfoVo>('/user/info')
}
/**
* 退出登录
*/
export function logout() {
return http.get<void>('/user/logout')
return http.Get<void>('/user/logout')
}
/**
* 修改用户信息
*/
export function updateInfo(data: IUpdateInfo) {
return http.post('/user/updateInfo', data)
return http.Get('/user/updateInfo', data)
}
/**
* 修改用户密码
*/
export function updateUserPassword(data: IUpdatePassword) {
return http.post('/user/updatePassword', data)
return http.Post('/user/updatePassword', data)
}
/**
@ -79,5 +96,5 @@ export function getWxCode() {
* @returns Promise 包含登录结果
*/
export function wxLogin(data: { code: string }) {
return http.post<IUserLogin>('/user/wxLogin', data)
return http.Post<IUserLogin>('/user/wxLogin', data)
}

File diff suppressed because one or more lines are too long

56
src/hooks/useWeiXin.ts Normal file
View File

@ -0,0 +1,56 @@
import {wxSnsapiBaseLogin} from '@/api/login'
// import {setUserInfo, getUserInfo} from '@/store/user'
/**
* 微信静默授权
*/
const getUrlCode = (): { [key: string]: string | undefined } => {
// 截取url中的code方法
const url = location.search
// this.winUrl = url;
let theRequest: { [key: string]: string | undefined } = {}
if (url.indexOf('?') != -1) {
let str = url.slice(1)
let strs = str.split('&')
for (let i = 0; i < strs.length; i++) {
theRequest[strs[i].split('=')[0]] = strs[i].split('=')[1]
}
}
return theRequest
}
/**
* 微信静默授权登录
*/
export function snsapiBaseAuthorize() {
let local = window.location.href // 获取页面url
let appid = import.meta.env.VITE_WX_SERVICE_ACCOUNT_APPID // 公众号的APPID
console.log("🚀 ~ snsapiBaseAuthorize ~ appid:", appid)
let code = getUrlCode().code // 截取code
// 获取之前的code
let oldCode = uni.getStorageSync('wechatCode')
if (code == null || code === '' || code == 'undefined' || code == oldCode) {
// 如果没有code就去请求获取code
console.log('当前没有code进入授权页面')
let uri = encodeURIComponent(local)
// 设置旧的code为0避免死循环
uni.setStorageSync('wechatCode',0)
window.location.href =
`https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${uri}&response_type=code&scope=snsapi_userinfo&state=123#wechat_redirect`
} else {
console.log('存在code使用code换取用户信息')
// 保存最新code
uni.setStorageSync('wechatCode',code)
console.log("🚀 ~ snsapiBaseAuthorize ~ code:", code)
// 使用code换取用户信息
wxSnsapiBaseLogin({code}).then(res=>{
console.log("🚀 ~ snsapiBaseAuthorize ~ res:", res)
}).catch(err=>{
// 失败就重新授权
uni.setStorageSync('wechatCode',0)
console.log('请求失败', err)
})
}
}

View File

@ -119,8 +119,7 @@
"type": "page",
"layout": "default",
"style": {
"navigationBarTitleText": "",
"navigationBarBackgroundColor": "#fff"
"navigationStyle": "custom"
}
},
{
@ -128,8 +127,7 @@
"type": "page",
"layout": "default",
"style": {
"navigationBarTitleText": "",
"navigationBarBackgroundColor": "#fff"
"navigationStyle": "custom"
}
},
{

View File

@ -17,7 +17,7 @@
<view class="text-36rpx leading-50rpx text-#303133 mr-38rpx">
预约茶艺师
</view>
<view class="flex items-center line-1" @click="Home.toCity">
<view class="flex items-center line-1" @click="Index.handleToCity">
<view class="">
<wd-icon name="location" size="32rpx"></wd-icon>
</view>
@ -27,7 +27,7 @@
</view>
</template>
</wd-navbar>
<view class="search-box relative">
<view class="search-box relative" @click="Index.handleToSearch">
<wd-search placeholder="茶艺师名称" cancel-txt="搜索" placeholder-left hide-cancel custom-input-class="!h-72rpx">
</wd-search>
<view class="absolute top-1/2 -translate-y-1/2 right-34rpx w-142rpx h-64rpx leading-64rpx text-center rounded-32rpx bg-#4C9F44 text-#fff font-400 text-32rpx">
@ -55,7 +55,7 @@
</view>
<view>
<view class="mt-16rpx relative w-690rpx h-260rpx mx-30rpx">
<view class="mt-16rpx relative w-690rpx h-260rpx mx-30rpx" @click="Index.handleToGroupReserve">
<wd-img width="690rpx" height="260rpx" :src="`${OSS}images/h5/home/home_image2.png`" mode="scaleToFill" />
<view class="h-64rpx absolute bottom-0 right-0 bg-[#4C9F44] text-[#fff] flex items-center px-26rpx rounded">
<text class="mr-8rpx">一键约</text>
@ -77,14 +77,14 @@
class="h-64rpx rounded-12rpx px-24rpx py-12rpx flex items-center justify-center font-400 text-28rpx mr-20rpx"
:class="selectedLevel.includes(item.value) ? 'bg-[#4C9F44] text-[#fff]' : 'bg-[#FFF] text-[#606266]'"
v-for="(item, index) in TeaSpecialistLevels" :key="index"
@click="Home.handleToggleTeaSpecialistLevel(item.value)">
@click="Index.handleToggleTeaSpecialistLevel(item.value)">
{{ item.label }}
</view>
</view>
<mescroll-body @init="mescrollInit" @down="downCallback" @up="Home.upCallback"
<mescroll-body @init="mescrollInit" @down="downCallback" @up="Index.upCallback"
:fixed="true">
<view class="flex items-center bg-white p-20rpx rounded-10rpx mx-30rpx mb-20rpx" v-for="(item, index) in 100" :key="index" @click="Home.handleToReserveTeaSpecialist(item)">
<view class="flex items-center bg-white p-20rpx rounded-10rpx mx-30rpx mb-20rpx" v-for="(item, index) in 100" :key="index" @click="Index.handleToReserveTeaSpecialist(item)">
<view class="mr-28rpx relative">
<wd-img width="200rpx" height="200rpx" :src="`${OSS}images/home/home_image5.png`"></wd-img>
<view class="tea-specialist-time absolute top-6rpx left-0 text-[#fff] font-400 text-18rpx leading-26rpx flex items-center justify-center">
@ -161,14 +161,16 @@
onLoad(() => {
})
const Home = {
toCity: () => {
const Index = {
// 城市
handleToCity: () => {
uni.navigateTo({
url: '/pages/city/city'
})
},
toSearch: () => {
// 搜索
handleToSearch: () => {
uni.navigateTo({
url: '/pages/search/search'
})
@ -224,6 +226,13 @@
// 如果未选择该等级,则添加选择
selectedLevel.value.push(value);
}
},
// 跳转到团体预约页面
handleToGroupReserve: () => {
uni.navigateTo({
url: '/pages/reservve/group-tea-specialist'
})
}
}
</script>

View File

@ -1,8 +1,7 @@
<route lang="jsonc" type="page">{
"layout": "default",
"style": {
"navigationBarTitleText": "",
"navigationBarBackgroundColor": "#fff"
"navigationStyle": "custom"
}
}</route>
@ -19,16 +18,16 @@
<wd-img :src="`${OSS}images/logo.png`" width="100%" height="100%" mode="aspectFill"></wd-img>
</view>
<view class="mt-124rpx mx-60rpx box-border">
<wd-button open-type="getPhoneNumber" @getphonenumber="login.handleGetPhoneNumber" custom-class="!bg-[#4C9F44] !rounded-8rpx !text-[#fff] !text-30rpx !leading-42rpx !h-90rpx !w-[100%] box-border">手机号一键登录</wd-button>
<view class="text-30rpx font-400 text-[#303133] leading-42rpx text-center mt-32rpx">其它手机号登录</view>
<wd-button open-type="getPhoneNumber" @getphonenumber="Login.handleGetPhoneNumber" custom-class="!bg-[#4C9F44] !rounded-8rpx !text-[#fff] !text-30rpx !leading-42rpx !h-90rpx !w-[100%] box-border">手机号一键登录</wd-button>
<view class="text-30rpx font-400 text-[#303133] leading-42rpx text-center mt-32rpx" @click="Login.handleToOtherMobileLogin">其它手机号登录</view>
</view>
<view class="flex items-center mx-32rpx mt-64rpx">
<view class="w-32rpx h-32rpx">
<wd-checkbox v-model="agree" @change="login.handleAgree" checked-color="#4C9F44" size="large"> </wd-checkbox>
<view class="w-32rpx h-32rpx mr-12rpx">
<wd-checkbox v-model="agree" @change="Login.handleAgree" checked-color="#4C9F44" size="large"> </wd-checkbox>
</view>
<view class="font-400 text-26rpx leading-40rpx text-[#8F959E] m l-14rpx flex-1" @click="agree = !agree">
我已阅读并同意 <text class="text-[#4C9F44]" @click.stop="login.handleToService">服务协议</text> <text class="text-[#4C9F44]" @click.stop="login.handleToPrivacy">隐私政策</text>未注册手机号登录后将自动你为您创建账号
我已阅读并同意 <text class="text-[#4C9F44]" @click.stop="Login.handleToService">服务协议</text> <text class="text-[#4C9F44]" @click.stop="Login.handleToPrivacy">隐私政策</text>未注册手机号登录后将自动你为您创建账号
</view>
</view>
</view>
@ -40,13 +39,62 @@
const agree = ref<boolean>(false)
const login = {
const Login = {
handleLogin: () => {
uni.login({
provider: 'weixin',
success: (loginRes) => {
console.log("🚀 ~ loginRes:", loginRes)
// if (!agree.value) {
// uni.showToast({
// title: '请同意服务协议和隐私政策',
// icon: 'none'
// })
// return
// }
// // 发送 loginRes.code 到后台换取 openId, sessionKey, unionId
// uni.request({
// url: 'https://your-backend-api.com/login', // 替换为你的后台登录接口
// method: 'POST',
// data: {
// code: loginRes.code
// },
// success: (res) => {
// console.log('登录成功,返回数据:', res.data);
// // 这里可以存储用户信息到本地,或者进行页面跳转等操作
// },
// fail: (err) => {
// console.error('登录请求失败:', err);
// uni.showToast({
// title: '登录失败,请稍后重试',
// icon: 'none'
// });
// }
// });
},
fail: (err) => {
console.error('登录失败:', err);
uni.showToast({
title: '登录失败,请稍后重试',
icon: 'none'
});
}
});
},
// 获取手机号
handleGetPhoneNumber: (e: object) => {
console.log("🚀 ~ e:", e)
},
// 跳转到其他手机号登录页面
handleToOtherMobileLogin: () => {
uni.navigateTo({
url: '/pages/login/mobile'
})
},
handleAgree: (e: any) => {
console.log('e', e)
},

View File

@ -1,8 +1,7 @@
<route lang="jsonc" type="page">{
"layout": "default",
"style": {
"navigationBarTitleText": "",
"navigationBarBackgroundColor": "#fff"
"navigationStyle": "custom"
}
}</route>