- 添加邀请记录、统计、来源统计、小程序码等数据模型 - 实现小程序码生成、邀请关系绑定、邀请场景处理等接口 - 新增扫码登录相关接口,支持生成二维码、检查状态、确认登录等操作 - 实现二维码内容解析和设备信息获取工具函数 - 添加礼品卡核销相关接口和解密工具函数 - 集成环境配置管理,支持开发、生产、测试环境切换 - 在过期时间页面集成登录二维码和核销二维码处理逻辑 - 添加邀请参数解析工具函数,支持从小程序启动参数中提取邀请信息
324 lines
8.8 KiB
TypeScript
324 lines
8.8 KiB
TypeScript
import {useState, useEffect, useCallback} from 'react';
|
||
import Taro from '@tarojs/taro';
|
||
import {AppInfo} from '@/api/cms/cmsWebsite/model';
|
||
import {getShopInfo} from '@/api/layout';
|
||
|
||
// 本地存储键名
|
||
const SHOP_INFO_STORAGE_KEY = 'shop_info';
|
||
const SHOP_INFO_CACHE_TIME_KEY = 'shop_info_cache_time';
|
||
|
||
// 缓存有效期(毫秒)- 默认30分钟
|
||
const CACHE_DURATION = 30 * 60 * 1000;
|
||
|
||
/**
|
||
* 商店信息Hook
|
||
* 提供商店信息的获取、缓存和管理功能
|
||
*/
|
||
export const useShopInfo = () => {
|
||
const [shopInfo, setShopInfo] = useState<AppInfo | null>(null);
|
||
const [loading, setLoading] = useState(true);
|
||
const [error, setError] = useState<string | null>(null);
|
||
|
||
// 从本地存储加载商店信息
|
||
const loadShopInfoFromStorage = useCallback(() => {
|
||
try {
|
||
const cachedData = Taro.getStorageSync(SHOP_INFO_STORAGE_KEY);
|
||
const cacheTime = Taro.getStorageSync(SHOP_INFO_CACHE_TIME_KEY);
|
||
|
||
if (cachedData && cacheTime) {
|
||
const now = Date.now();
|
||
const timeDiff = now - cacheTime;
|
||
|
||
// 检查缓存是否过期
|
||
if (timeDiff < CACHE_DURATION) {
|
||
const shopData = typeof cachedData === 'string' ? JSON.parse(cachedData) : cachedData;
|
||
setShopInfo(shopData);
|
||
setLoading(false);
|
||
return true; // 返回true表示使用了缓存
|
||
} else {
|
||
// 缓存过期,清除旧数据
|
||
Taro.removeStorageSync(SHOP_INFO_STORAGE_KEY);
|
||
Taro.removeStorageSync(SHOP_INFO_CACHE_TIME_KEY);
|
||
}
|
||
}
|
||
} catch (error) {
|
||
console.error('加载商店信息缓存失败:', error);
|
||
}
|
||
return false; // 返回false表示没有使用缓存
|
||
}, []);
|
||
|
||
// 保存商店信息到本地存储
|
||
const saveShopInfoToStorage = useCallback((data: AppInfo) => {
|
||
try {
|
||
Taro.setStorageSync(SHOP_INFO_STORAGE_KEY, data);
|
||
Taro.setStorageSync(SHOP_INFO_CACHE_TIME_KEY, Date.now());
|
||
} catch (error) {
|
||
console.error('保存商店信息缓存失败:', error);
|
||
}
|
||
}, []);
|
||
|
||
// 从服务器获取商店信息
|
||
const fetchShopInfo = useCallback(async () => {
|
||
try {
|
||
setLoading(true);
|
||
setError(null);
|
||
|
||
const data = await getShopInfo();
|
||
setShopInfo(data);
|
||
|
||
// 保存到本地存储
|
||
saveShopInfoToStorage(data);
|
||
|
||
return data;
|
||
} catch (error) {
|
||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||
console.error('获取商店信息失败:', error);
|
||
setError(errorMessage);
|
||
|
||
// 如果网络请求失败,尝试使用缓存数据(即使过期)
|
||
const cachedData = Taro.getStorageSync(SHOP_INFO_STORAGE_KEY);
|
||
if (cachedData) {
|
||
const shopData = typeof cachedData === 'string' ? JSON.parse(cachedData) : cachedData;
|
||
setShopInfo(shopData);
|
||
console.warn('网络请求失败,使用缓存数据');
|
||
}
|
||
|
||
return null;
|
||
} finally {
|
||
setLoading(false);
|
||
}
|
||
}, [saveShopInfoToStorage]);
|
||
|
||
// 刷新商店信息
|
||
const refreshShopInfo = useCallback(async () => {
|
||
try {
|
||
setLoading(true);
|
||
setError(null);
|
||
|
||
const data = await getShopInfo();
|
||
setShopInfo(data);
|
||
|
||
// 保存到本地存储
|
||
saveShopInfoToStorage(data);
|
||
|
||
return data;
|
||
} catch (error) {
|
||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||
console.error('刷新商店信息失败:', error);
|
||
setError(errorMessage);
|
||
return null;
|
||
} finally {
|
||
setLoading(false);
|
||
}
|
||
}, [saveShopInfoToStorage]);
|
||
|
||
// 清除缓存
|
||
const clearCache = useCallback(() => {
|
||
try {
|
||
Taro.removeStorageSync(SHOP_INFO_STORAGE_KEY);
|
||
Taro.removeStorageSync(SHOP_INFO_CACHE_TIME_KEY);
|
||
setShopInfo(null);
|
||
setError(null);
|
||
} catch (error) {
|
||
console.error('清除商店信息缓存失败:', error);
|
||
}
|
||
}, []);
|
||
|
||
// 获取应用名称
|
||
const getAppName = useCallback(() => {
|
||
return shopInfo?.appName || '商城';
|
||
}, [shopInfo]);
|
||
|
||
// 获取网站名称(兼容旧方法名)
|
||
const getWebsiteName = useCallback(() => {
|
||
return shopInfo?.appName || '商城';
|
||
}, [shopInfo]);
|
||
|
||
// 获取应用Logo
|
||
const getAppLogo = useCallback(() => {
|
||
return shopInfo?.logo || shopInfo?.icon || '';
|
||
}, [shopInfo]);
|
||
|
||
// 获取网站Logo(兼容旧方法名)
|
||
const getWebsiteLogo = useCallback(() => {
|
||
return shopInfo?.logo || shopInfo?.icon || '';
|
||
}, [shopInfo]);
|
||
|
||
// 获取应用图标
|
||
const getAppIcon = useCallback(() => {
|
||
return shopInfo?.icon || shopInfo?.logo || '';
|
||
}, [shopInfo]);
|
||
|
||
// 获取深色模式Logo(AppInfo中无此字段,使用普通Logo)
|
||
const getDarkLogo = useCallback(() => {
|
||
return shopInfo?.logo || shopInfo?.icon || '';
|
||
}, [shopInfo]);
|
||
|
||
// 获取应用域名
|
||
const getDomain = useCallback(() => {
|
||
return shopInfo?.domain || '';
|
||
}, [shopInfo]);
|
||
|
||
// 获取应用描述
|
||
const getDescription = useCallback(() => {
|
||
return shopInfo?.description || '';
|
||
}, [shopInfo]);
|
||
|
||
// 获取应用关键词
|
||
const getKeywords = useCallback(() => {
|
||
return shopInfo?.keywords || '';
|
||
}, [shopInfo]);
|
||
|
||
// 获取应用标题
|
||
const getTitle = useCallback(() => {
|
||
return shopInfo?.title || shopInfo?.appName || '';
|
||
}, [shopInfo]);
|
||
|
||
// 获取小程序二维码
|
||
const getMpQrCode = useCallback(() => {
|
||
return shopInfo?.mpQrCode || '';
|
||
}, [shopInfo]);
|
||
|
||
// 获取联系电话(AppInfo中无此字段,从config中获取)
|
||
const getPhone = useCallback(() => {
|
||
return (shopInfo?.config as any)?.phone || '';
|
||
}, [shopInfo]);
|
||
|
||
// 获取邮箱(AppInfo中无此字段,从config中获取)
|
||
const getEmail = useCallback(() => {
|
||
return (shopInfo?.config as any)?.email || '';
|
||
}, [shopInfo]);
|
||
|
||
// 获取地址(AppInfo中无此字段,从config中获取)
|
||
const getAddress = useCallback(() => {
|
||
return (shopInfo?.config as any)?.address || '';
|
||
}, [shopInfo]);
|
||
|
||
// 获取ICP备案号(AppInfo中无此字段,从config中获取)
|
||
const getIcpNo = useCallback(() => {
|
||
return (shopInfo?.config as any)?.icpNo || '';
|
||
}, [shopInfo]);
|
||
|
||
// 获取应用状态
|
||
const getStatus = useCallback(() => {
|
||
return {
|
||
running: shopInfo?.running || 0,
|
||
statusText: shopInfo?.statusText || '',
|
||
statusIcon: shopInfo?.statusIcon || '',
|
||
expired: shopInfo?.expired || false,
|
||
expiredDays: shopInfo?.expiredDays || 0,
|
||
soon: shopInfo?.soon || 0
|
||
};
|
||
}, [shopInfo]);
|
||
|
||
// 获取应用配置
|
||
const getConfig = useCallback(() => {
|
||
return shopInfo?.config || {};
|
||
}, [shopInfo]);
|
||
|
||
// 获取应用设置
|
||
const getSetting = useCallback(() => {
|
||
return shopInfo?.setting || {};
|
||
}, [shopInfo]);
|
||
|
||
// 获取服务器时间
|
||
const getServerTime = useCallback(() => {
|
||
return shopInfo?.serverTime || {};
|
||
}, [shopInfo]);
|
||
|
||
// 获取导航菜单
|
||
const getNavigation = useCallback(() => {
|
||
return {
|
||
topNavs: shopInfo?.topNavs || [],
|
||
bottomNavs: shopInfo?.bottomNavs || []
|
||
};
|
||
}, [shopInfo]);
|
||
|
||
// 检查是否支持搜索(从config中获取)
|
||
const isSearchEnabled = useCallback(() => {
|
||
return (shopInfo?.config as any)?.search === true;
|
||
}, [shopInfo]);
|
||
|
||
// 获取应用版本信息
|
||
const getVersionInfo = useCallback(() => {
|
||
return {
|
||
version: shopInfo?.version || 10,
|
||
expirationTime: shopInfo?.expirationTime || '',
|
||
expired: shopInfo?.expired || false,
|
||
expiredDays: shopInfo?.expiredDays || 0,
|
||
soon: shopInfo?.soon || 0
|
||
};
|
||
}, [shopInfo]);
|
||
|
||
// 检查应用是否过期
|
||
const isExpired = useCallback(() => {
|
||
return shopInfo?.expired === true;
|
||
}, [shopInfo]);
|
||
|
||
// 获取过期天数
|
||
const getExpiredDays = useCallback(() => {
|
||
return shopInfo?.expiredDays || 0;
|
||
}, [shopInfo]);
|
||
|
||
// 检查是否即将过期
|
||
const isSoonExpired = useCallback(() => {
|
||
return (shopInfo?.soon || 0) > 0;
|
||
}, [shopInfo]);
|
||
|
||
// 初始化时加载商店信息
|
||
useEffect(() => {
|
||
const initShopInfo = async () => {
|
||
// 先尝试从缓存加载
|
||
const hasCache = loadShopInfoFromStorage();
|
||
|
||
// 如果没有缓存或需要刷新,则从服务器获取
|
||
if (!hasCache) {
|
||
await fetchShopInfo();
|
||
}
|
||
};
|
||
|
||
initShopInfo();
|
||
}, []); // 空依赖数组,只在组件挂载时执行一次
|
||
|
||
return {
|
||
// 状态
|
||
shopInfo,
|
||
loading,
|
||
error,
|
||
|
||
// 方法
|
||
fetchShopInfo,
|
||
refreshShopInfo,
|
||
clearCache,
|
||
|
||
// 新的工具方法(基于AppInfo字段)
|
||
getAppName,
|
||
getAppLogo,
|
||
getAppIcon,
|
||
getDescription,
|
||
getKeywords,
|
||
getTitle,
|
||
getMpQrCode,
|
||
getDomain,
|
||
getConfig,
|
||
getSetting,
|
||
getServerTime,
|
||
getNavigation,
|
||
getStatus,
|
||
getVersionInfo,
|
||
isExpired,
|
||
getExpiredDays,
|
||
isSoonExpired,
|
||
|
||
// 兼容旧方法名
|
||
getWebsiteName,
|
||
getWebsiteLogo,
|
||
getDarkLogo,
|
||
getPhone,
|
||
getEmail,
|
||
getAddress,
|
||
getIcpNo,
|
||
isSearchEnabled
|
||
};
|
||
};
|