feat: 首页更新

This commit is contained in:
2025-11-13 16:47:10 +08:00
parent 9ef9233797
commit 54bf84b19b
1244 changed files with 3507 additions and 951 deletions

145
utils/image.ts Normal file
View File

@@ -0,0 +1,145 @@
/**
* 图片处理工具函数
* 支持外部 URLHTTP/HTTPS 和 Data URI和本地路径/images/...
*
* 本地路径格式:/images/game/{typeName}/{color|dark|light}_{play_id}.png
* 例如:/images/game/chess/color_101.png
*
* 注意React Native 中不支持本地文件路径的动态 require()
* 本地路径会被 Expo 的静态资源服务器处理
*/
/**
* 判断是否为有效的外部 URL
* @param source 图片源
* @returns 是否为有效的外部 URL
*/
export const isExternalUrl = (source: string | undefined): boolean => {
if (!source) return false;
return /^https?:\/\//.test(source) || /^data:image\//.test(source);
};
/**
* 判断是否为本地路径
* @param source 图片源
* @returns 是否为本地路径
*/
export const isLocalPath = (source: string | undefined): boolean => {
if (!source) return false;
return /^\/images\//.test(source);
};
/**
* 获取图片 URI
*
* 验证并返回有效的图片 URI
* 支持外部 URLHTTP/HTTPS 和 Data URI和本地路径/images/...
*
* @param source 图片源URL 或本地路径)
* @returns 有效的图片 URI如果无效返回 undefined
*
* @example
* ```typescript
* // 外部 URL
* const uri = getImageSource('https://example.com/image.png');
* // 返回: 'https://example.com/image.png'
*
* // Data URI
* const uri = getImageSource('data:image/png;base64,iVBORw0KGgo...');
* // 返回: 'data:image/png;base64,iVBORw0KGgo...'
*
* // 本地路径
* const uri = getImageSource('/images/game/chess/color_101.png');
* // 返回: '/images/game/chess/color_101.png'
*
* // 无效的 URL
* const uri = getImageSource('invalid-url');
* // 返回: undefined
* ```
*/
export const getImageSource = (source: string | undefined): string | undefined => {
if (!source) return undefined;
// 支持外部 URL
if (isExternalUrl(source)) {
return source;
}
// 支持本地路径
if (isLocalPath(source)) {
return source;
}
// 其他格式不支持
return undefined;
};
/**
* 将本地路径转换为可用的 require 对象
*
* 在 React Native 中,本地资源必须使用 require() 加载
* 这个函数使用预定义的图片映射表来获取资源
*
* @param localPath 本地路径,例如 /images/game/chess/color_101.png
* @returns require 对象,如果路径无效返回 undefined
*
* @example
* ```typescript
* const source = convertLocalPathToUri('/images/game/chess/color_101.png');
* // 返回: require('../assets/images/game/chess/color_101.png')
* ```
*/
export const convertLocalPathToUri = (localPath: string): any => {
if (!localPath || !isLocalPath(localPath)) {
return undefined;
}
try {
// 使用图片映射表获取本地资源
const { getGameImageFromPath } = require('@/constants/gameImages');
return getGameImageFromPath(localPath);
} catch (error) {
// 如果获取失败,返回 undefined
if (__DEV__) {
console.warn(`Failed to load image: ${localPath}`, error);
}
return undefined;
}
};
/**
* 获取图片源(带默认值)
*
* 如果主图片 URL 无效,返回默认图片 URL
*
* @param source 图片源URL
* @param defaultSource 默认图片源URL
* @returns 有效的图片 URI
*
* @example
* ```typescript
* // 如果主图片无效,使用默认图片
* const uri = getImageSourceWithDefault(
* item.imageUrl,
* 'https://via.placeholder.com/200'
* );
* ```
*/
export const getImageSourceWithDefault = (
source: string | undefined,
defaultSource: string
): string | undefined => {
const imageSource = getImageSource(source);
if (imageSource) {
return imageSource;
}
return getImageSource(defaultSource);
};
export default {
getImageSource,
getImageSourceWithDefault,
isExternalUrl,
isLocalPath,
convertLocalPathToUri,
};

View File

@@ -19,11 +19,7 @@ export { default as storageManager, STORAGE_KEYS } from './storageManager';
export { default as config, printConfig } from './config';
// Date utilities
export {
formatDate,
formatRelativeTime,
formatChatTime,
isToday,
isYesterday,
} from './date';
export { formatDate, formatRelativeTime, formatChatTime, isToday, isYesterday } from './date';
// Image utilities
export { getImageSource, getImageSourceWithDefault, isExternalUrl } from './image';

View File

@@ -304,7 +304,10 @@ api.interceptors.response.use(
});
}
if (includes([500, 502, 503], error.response?.status) && includes(['371130'], `${error.config?.headers?.cmdId}`)) {
if (
includes([500, 502, 503], error.response?.status) &&
includes(['371130'], `${error.config?.headers?.cmdId}`)
) {
router.replace('/maintenance' as any);
}

View File

@@ -35,32 +35,32 @@ const getBetPlatform = (): PlatformType => {
const uuid = (len: number, radix: number) => {
const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
const uuid: any[] = [];
const _uuid: any[] = [];
radix = radix || chars.length;
if (len) {
// Compact form
for (let i = 0; i < len; i++) uuid[i] = chars[0 | (Math.random() * radix)];
for (let i = 0; i < len; i++) _uuid[i] = chars[0 | (Math.random() * radix)];
} else {
// rfc4122, version 4 form
/* eslint-disable */
let r;
// rfc4122 requires these characters
uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
uuid[14] = '4';
_uuid[8] = _uuid[13] = _uuid[18] = _uuid[23] = '-';
_uuid[14] = '4';
// Fill in random data. At i==19 set the high bits of clock sequence as
// per rfc4122, sec. 4.1.5
for (let i = 0; i < 36; i++) {
if (!uuid[i]) {
if (!_uuid[i]) {
r = 0 | (Math.random() * 16);
uuid[i] = chars[i == 19 ? (r & 0x3) | 0x8 : r];
_uuid[i] = chars[i == 19 ? (r & 0x3) | 0x8 : r];
}
}
/* eslint-enable */
}
return uuid.join('');
return _uuid.join('');
};
// 格式化要发送的数据
@@ -137,7 +137,7 @@ export const transformRequest = (config: any) => {
let userInfo = {
cust_id: '',
cust_name: '',
access_token: ''
access_token: '',
};
// if (['17', '3310052', '310111', '310122', '310400', '4', '402', '401', '310635'].includes(cmdId)) {

View File

@@ -304,4 +304,3 @@ const storageManager = {
};
export default storageManager;