forked from gxwebsoft/mp-10550
feat(auth): 添加统一认证工具和优化登录流程
- 新增 auth 工具模块,包含 isLoggedIn、goToRegister、ensureLoggedIn 方法 - 将硬编码的服务器URL更新为 glt-server 域名 - 重构多个页面的登录检查逻辑,使用统一的认证工具 - 在用户注册/登录流程中集成邀请关系处理 - 更新注册页面配置和实现,支持跳转参数传递 - 优化分销商二维码页面的加载状态和错误处理 - 在水票使用页面添加无票时的购买引导 - 统一文件上传和API请求的服务器地址 - 添加加密库类型定义文件
This commit is contained in:
@@ -16,6 +16,7 @@ import "./index.scss";
|
||||
import {useCart} from "@/hooks/useCart";
|
||||
import {useConfig} from "@/hooks/useConfig";
|
||||
import {parseInviteParams, saveInviteParams, trackInviteSource} from "@/utils/invite";
|
||||
import { ensureLoggedIn } from '@/utils/auth'
|
||||
|
||||
const GoodsDetail = () => {
|
||||
const [statusBarHeight, setStatusBarHeight] = useState<number>(44);
|
||||
@@ -62,13 +63,7 @@ const GoodsDetail = () => {
|
||||
const handleAddToCart = () => {
|
||||
if (!goods) return;
|
||||
|
||||
if (!Taro.getStorageSync('UserId')) {
|
||||
return Taro.showToast({
|
||||
title: '请先登录',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
});
|
||||
}
|
||||
if (!ensureLoggedIn(`/shop/goodsDetail/index?id=${goods.goodsId}`)) return
|
||||
|
||||
// 如果有规格,显示规格选择器
|
||||
if (specs.length > 0) {
|
||||
@@ -90,13 +85,7 @@ const GoodsDetail = () => {
|
||||
const handleBuyNow = () => {
|
||||
if (!goods) return;
|
||||
|
||||
if (!Taro.getStorageSync('UserId')) {
|
||||
return Taro.showToast({
|
||||
title: '请先登录',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
});
|
||||
}
|
||||
if (!ensureLoggedIn(`/shop/orderConfirm/index?goodsId=${goods.goodsId}`)) return
|
||||
|
||||
// 如果有规格,显示规格选择器
|
||||
if (specs.length > 0) {
|
||||
|
||||
@@ -43,6 +43,7 @@ import dayjs from 'dayjs'
|
||||
import type {ShopStore} from "@/api/shop/shopStore/model";
|
||||
import {getShopStore, listShopStore} from "@/api/shop/shopStore";
|
||||
import {getSelectedStoreFromStorage, saveSelectedStoreToStorage} from "@/utils/storeSelection";
|
||||
import { ensureLoggedIn, isLoggedIn } from '@/utils/auth'
|
||||
|
||||
|
||||
const OrderConfirm = () => {
|
||||
@@ -88,6 +89,16 @@ const OrderConfirm = () => {
|
||||
const router = Taro.getCurrentInstance().router;
|
||||
const goodsId = router?.params?.goodsId;
|
||||
|
||||
// 页面级兜底:未登录直接进入下单页时,引导去注册/登录并回跳
|
||||
useEffect(() => {
|
||||
if (!goodsId) {
|
||||
// 也可能是 orderData 模式;这里只做最小兜底
|
||||
if (!ensureLoggedIn('/shop/orderConfirm/index')) return
|
||||
return
|
||||
}
|
||||
if (!ensureLoggedIn(`/shop/orderConfirm/index?goodsId=${goodsId}`)) return
|
||||
}, [goodsId])
|
||||
|
||||
const isTicketTemplateActive =
|
||||
!!ticketTemplate &&
|
||||
ticketTemplate.enabled !== false &&
|
||||
@@ -607,6 +618,9 @@ const OrderConfirm = () => {
|
||||
|
||||
// 统一的数据加载函数
|
||||
const loadAllData = async () => {
|
||||
// 未登录时不发起接口请求;页面会被登录兜底逻辑引导走注册/登录页
|
||||
if (!isLoggedIn()) return
|
||||
|
||||
try {
|
||||
setLoading(true)
|
||||
setError('')
|
||||
@@ -694,12 +708,14 @@ const OrderConfirm = () => {
|
||||
|
||||
useDidShow(() => {
|
||||
// 返回/切换到该页面时,刷新一下当前已选门店
|
||||
if (!isLoggedIn()) return
|
||||
setSelectedStore(getSelectedStoreFromStorage())
|
||||
loadAllData()
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
// 切换商品时重置配送时间,避免沿用上一次选择
|
||||
if (!isLoggedIn()) return
|
||||
setSendTime(dayjs().startOf('day').toDate())
|
||||
setSendTimePickerVisible(false)
|
||||
loadAllData()
|
||||
|
||||
@@ -2,8 +2,6 @@ import {useEffect, useState} from "react";
|
||||
import {Image, Button, Cell, CellGroup, Input, Space} from '@nutui/nutui-react-taro'
|
||||
import {Location, ArrowRight} from '@nutui/icons-react-taro'
|
||||
import Taro from '@tarojs/taro'
|
||||
import {ShopGoods} from "@/api/shop/shopGoods/model";
|
||||
import {getShopGoods} from "@/api/shop/shopGoods";
|
||||
import {View} from '@tarojs/components';
|
||||
import {listShopUserAddress} from "@/api/shop/shopUserAddress";
|
||||
import {ShopUserAddress} from "@/api/shop/shopUserAddress/model";
|
||||
@@ -12,14 +10,12 @@ import {useCart, CartItem} from "@/hooks/useCart";
|
||||
import Gap from "@/components/Gap";
|
||||
import {Payment} from "@/api/system/payment/model";
|
||||
import {PaymentHandler, PaymentType, buildCartOrder} from "@/utils/payment";
|
||||
import { ensureLoggedIn } from '@/utils/auth'
|
||||
|
||||
const OrderConfirm = () => {
|
||||
const [goods, setGoods] = useState<ShopGoods | null>(null);
|
||||
const [address, setAddress] = useState<ShopUserAddress>()
|
||||
const [payment, setPayment] = useState<Payment>()
|
||||
const [payment] = useState<Payment>()
|
||||
const [checkoutItems, setCheckoutItems] = useState<CartItem[]>([]);
|
||||
const router = Taro.getCurrentInstance().router;
|
||||
const goodsId = router?.params?.goodsId;
|
||||
|
||||
const {
|
||||
cartItems,
|
||||
@@ -27,13 +23,18 @@ const OrderConfirm = () => {
|
||||
} = useCart();
|
||||
|
||||
const reload = async () => {
|
||||
const address = await listShopUserAddress({isDefault: true});
|
||||
if (address.length > 0) {
|
||||
console.log(address, '111')
|
||||
setAddress(address[0])
|
||||
const addressList = await listShopUserAddress({isDefault: true});
|
||||
if (addressList.length > 0) {
|
||||
setAddress(addressList[0])
|
||||
}
|
||||
}
|
||||
|
||||
// 页面级兜底:防止未登录时进入结算页导致接口报错/仅提示“请先登录”
|
||||
useEffect(() => {
|
||||
// redirect 到当前结算页,登录成功后返回继续支付
|
||||
if (!ensureLoggedIn('/shop/orderConfirmCart/index')) return
|
||||
}, [])
|
||||
|
||||
// 加载结算商品数据
|
||||
const loadCheckoutItems = () => {
|
||||
try {
|
||||
@@ -57,6 +58,8 @@ const OrderConfirm = () => {
|
||||
* 统一支付入口
|
||||
*/
|
||||
const onPay = async () => {
|
||||
if (!ensureLoggedIn('/shop/orderConfirmCart/index')) return
|
||||
|
||||
// 基础校验
|
||||
if (!address) {
|
||||
Taro.showToast({
|
||||
@@ -77,7 +80,7 @@ const OrderConfirm = () => {
|
||||
// 构建订单数据
|
||||
const orderData = buildCartOrder(
|
||||
checkoutItems.map(item => ({
|
||||
goodsId: item.goodsId!,
|
||||
goodsId: item.goodsId,
|
||||
quantity: item.quantity || 1
|
||||
})),
|
||||
address.id,
|
||||
@@ -102,16 +105,11 @@ const OrderConfirm = () => {
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (goodsId) {
|
||||
getShopGoods(Number(goodsId)).then(res => {
|
||||
setGoods(res);
|
||||
}).catch(error => {
|
||||
console.error("Failed to fetch goods detail:", error);
|
||||
});
|
||||
}
|
||||
if (!ensureLoggedIn('/shop/orderConfirmCart/index')) return
|
||||
|
||||
reload().then();
|
||||
loadCheckoutItems();
|
||||
}, [goodsId, cartItems]);
|
||||
}, [cartItems]);
|
||||
|
||||
// 计算总价
|
||||
const getTotalPrice = () => {
|
||||
@@ -157,19 +155,19 @@ const OrderConfirm = () => {
|
||||
</CellGroup>
|
||||
|
||||
<CellGroup>
|
||||
{checkoutItems.map((goods, _) => (
|
||||
<Cell key={goods.goodsId}>
|
||||
{checkoutItems.map((item) => (
|
||||
<Cell key={item.goodsId}>
|
||||
<Space>
|
||||
<Image src={goods.image} mode={'aspectFill'} style={{
|
||||
<Image src={item.image} mode={'aspectFill'} style={{
|
||||
width: '80px',
|
||||
height: '80px',
|
||||
}} lazyLoad={false}/>
|
||||
<View className={'flex flex-col'}>
|
||||
<View className={'font-medium w-full'}>{goods.name}</View>
|
||||
<View className={'font-medium w-full'}>{item.name}</View>
|
||||
<View className={'number text-gray-400 text-sm py-2'}>80g/袋</View>
|
||||
<Space className={'flex justify-start items-center'}>
|
||||
<View className={'text-red-500'}>¥{goods.price}</View>
|
||||
<View className={'text-gray-500 text-sm'}>x {goods.quantity}</View>
|
||||
<View className={'text-red-500'}>¥{item.price}</View>
|
||||
<View className={'text-gray-500 text-sm'}>x {item.quantity}</View>
|
||||
</Space>
|
||||
</View>
|
||||
</Space>
|
||||
|
||||
Reference in New Issue
Block a user