@tarsiidae/sport-socket
v1.0.46
Published
[](https://www.npmjs.com/package/@tarsiidae/sport-socket) [](LICENSE) [
- 📦 完整类型 - 完整的TypeScript类型支持,覆盖所有hooks和事件推送
📦 安装
# 使用 yarn
yarn add @tarsiidae/sport-socket
# 使用 npm
npm install @tarsiidae/sport-socket
# 使用 pnpm
pnpm add @tarsiidae/sport-socket🚀 快速开始
1. 初始化Provider
首先使用 PubProvider 包裹你的应用:
import { PubProvider } from '@tarsiidae/sport-socket';
function App() {
return (
<PubProvider>
<YourApp />
</PubProvider>
);
}2. 配置WebSocket连接
使用 useOkSocket Hook 配置连接:
import { useOkSocket } from '@tarsiidae/sport-socket';
function YourComponent() {
useOkSocket({
url: `${config?.wsHost}/api/ws/app/im`,
token: g_token, // 用户token
uid, // 用户id
platformId: 1,
lang: 'zh',
oddsType: 'EU',
});
return <div>Your component content</div>;
}💡 提示: 系统会根据用户是否登录自动切换socket连接状态
🛒 购物车功能
购物车高阶组件
import { withCart, useCart } from '@tarsiidae/sport-socket';
const Cart = withCart(() => {
const { data, clearable, betType, toggleBetType, oddsType } = useCart();
return (
<div>
<h2>购物车</h2>
{clearable && <button onClick={clearCart}>清空购物车</button>}
<button onClick={toggleBetType}>
切换为{betType === 'parlay' ? '单关' : '串关'}
</button>
{data.map((item) => (
<BetItem
key={item.oid}
mid={item.matchOdd?.matchInfo?.id ?? ''}
oid={item.oid}
/>
))}
{betType === 'parlay' ? <Parlays /> : <Single />}
</div>
);
});投注项组件
import { withBetItem, useBetItem } from '@tarsiidae/sport-socket';
const BetItem = withBetItem(() => {
const {
odd,
removeFromCart,
cartItem,
status,
supportParlay,
showSupportParlay,
} = useBetItem();
return (
<div>
<button onClick={removeFromCart}>移除</button>
<div>{cartItem?.league?.name}</div>
<div>
{odd?.detailName}: {odd?.odds}
</div>
{showSupportParlay && (
<span>{supportParlay ? '支持串关' : '不支持串关'}</span>
)}
</div>
);
});🏆 赛事功能
赛事列表组件
import { withMatch, useMatch } from '@tarsiidae/sport-socket';
const MatchItem = withMatch(() => {
const {
status,
matchOdd,
addCart,
getIsSelected,
countDownTime,
handicapType,
} = useMatch();
return (
<div>
<div>
{matchOdd?.matchInfo?.homeName} vs {matchOdd?.matchInfo?.awayName}
</div>
<div>状态: {status?.statusName}</div>
<div>时间: {countDownTime}</div>
{handicapType === 'europe' &&
europePlays?.map((play) => (
<EuroPlayItem key={play.playCateCode} {...play} />
))}
</div>
);
});赛事详情组件
const MatchDetailItem = withMatch(() => {
const { status, matchOdd, typeCodePlays, countDownTime } = useMatch();
return (
<div>
<div>
{matchOdd?.matchInfo?.homeName} vs {matchOdd?.matchInfo?.awayName}
</div>
<div>详情状态: {status?.statusName}</div>
<div>时间: {countDownTime}</div>
{typeCodePlays?.map((cate) => (
<div key={cate.code}>
<h3>{cate.name}</h3>
{cate.plays?.map((play) => (
<EuroPlayItem key={play.playCateCode} {...play} />
))}
</div>
))}
</div>
);
});🎯 单注和串关
单注组件
import { withSingle, useSingle } from '@tarsiidae/sport-socket';
const Single = withSingle(() => {
const { singleBetAmount, betRange, winMoney, setSingleBetAmount } =
useSingle();
return (
<div>
<input
type='text'
value={singleBetAmount}
onChange={(e) => setSingleBetAmount(e.target.value)}
placeholder='请输入投注金额'
/>
<div>
投注范围: {betRange.min}-{betRange.max}
</div>
<div>可赢金额: {winMoney}</div>
</div>
);
});串关组件
import { withParlays, useParlays } from '@tarsiidae/sport-socket';
const Parlays = withParlays(() => {
const {
totalBetCount,
totalBetMoney,
totalWinMoney,
parlays,
setParlayBetMoney,
} = useParlays();
const { data } = useCart();
return (
<div>
{data.map((item) => (
<BetItem
key={item.oid}
mid={item.matchOdd?.matchInfo?.id ?? ''}
oid={item.oid}
/>
))}
{parlays?.map((item) => (
<ParlayItem key={item.combKey} {...item} />
))}
<div>注数: {totalBetCount}</div>
<div>投注: {totalBetMoney}</div>
<div>可赢: {totalWinMoney}</div>
</div>
);
});📡 事件订阅
公共推送和用户数据推送
import { usePub } from '@tarsiidae/sport-socket';
function YourComponent() {
usePub((data, topic) => {
if (data.eventType === 'USER_MONEY') {
console.log('更新用户余额', data.money);
}
if (data.eventType === 'MATCH_STATUS_CHANGE') {
console.log('赛事状态变化', data);
}
});
return <div>Your component</div>;
}🔧 高级功能
自动订阅管理
组件内部已经集成了完整的订阅和取消订阅逻辑:
- 自动订阅: 当赛事进入视口时自动订阅
- 自动取消: 当赛事离开视口且不在购物车中时自动取消订阅
- 统一管理: 同一场赛事使用同一个赛事详情topic订阅(冠军除外)
- 智能计数: 自动管理订阅计数,确保订阅状态正确
Web Worker 支持
所有数据处理都在 Web Worker 中进行,不会阻塞 UI 渲染
完整的 TypeScript 支持
所有 hooks 和组件都有完整的类型定义:
// 完整的类型支持
declare interface UseCartRes extends GetCombinationsRes {
/** 购物车数据 */
data: CartItemProps[];
/** 购物车是否可清空 */
clearable: boolean;
/** 投注类型, 单关或者串关 */
betType: BetType;
/** 切换投注类型, 单关或者串关 */
toggleBetType: () => void;
/** 盘口 */
oddsType: OddsType;
/** 是否支持串关 */
supportParlay: boolean;
/** 串关投注列表 */
betList: BetOddsListItem[];
/** 串关投注金额列表 */
stakeList: BetStakeList[];
/** 单注可赢金额 */
singleBetWinMoney: number;
/** 单注预购赔率 */
bookOdds: number | undefined;
/** 单注预购投注信息 */
bookOddsList: BetOddsListItem[];
/** 单注预约投注可赢金额 */
bookWinMoney: number;
}📚 API 参考
Hooks
useOkSocket(config)- 配置 WebSocket 连接usePub(callback)- 订阅公共推送事件useMatch()- 获取赛事数据(在 withMatch 中使用)useCart()- 获取购物车数据(在 withCart 中使用)useBetItem()- 获取投注项数据(在 withBetItem 中使用)useSingle()- 获取单注数据(在 withSingle 中使用)useParlays()- 获取串关数据(在 withParlays 中使用)useQuickBet()- 获取快速投注数据(在 withQuickBet 中使用)
高阶组件
withMatch(Component)- 赛事高阶组件withCart(Component)- 购物车高阶组件withBetItem(Component)- 投注项高阶组件withSingle(Component)- 单注高阶组件withParlays(Component)- 串关高阶组件withQuickBet(Component)- 快捷投注高阶组件、、
工具函数
useSimpleSelectData(gameType)- 获取简单盘口选择数据useHandicapType()- 获取盘口类型useClearCart()- 清空购物车useCartLen()- 获取购物车长度useGetQuickBetInfo()- 获取快速投注信息useEnableQuickBet()- 获取和设置是否启用快速投注useQuickBetAmount()- 获取和设置快速投注金额useParlayOrderInfo()- 获取串关投注成功后,订单信息; 在串关投注成功后,保存数据useBookOddsLimit()- 获取单注预购赔率限制信息isBookOddsLowerThanCurrentOdds- 单注预购赔率是否低于当前赔率isBookOddsHigherThanMax- 单注预购赔率是否高于最大值(欧洲盘255,香港盘254)
useIsSingleEndLen()- 获取单注的末位比分长度useEnableBooking()- 获取和设置是否开启预约投注enableBooking- 是否开启预约投注setEnableBooking- 设置是否开启预约投注
useSetEndOddBetFailed()- 设置末位比分投注失败
📄 许可证
MIT License - 详见 LICENSE 文件
