Skip to content

Commit 481a4ff

Browse files
committed
添加 axios 依赖,更新 Steam API 相关功能,优化游戏卡片组件和已玩游戏列表展示
1 parent 8b6b0b7 commit 481a4ff

File tree

8 files changed

+252
-76
lines changed

8 files changed

+252
-76
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"dependencies": {
1313
"astro": "^5.5.4",
1414
"astro-seo": "^0.8.4",
15+
"axios": "^1.9.0",
1516
"pinyin-pro": "^3.26.0"
1617
},
1718
"devDependencies": {}

post/如何愉快的访问Steam api.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,14 @@ V 社的官方 API 文档,文档的介绍比较详细,但 api 总量少,
1919

2020
非常多 api 而且不需要使用 key ,任何人都可以访问,但是几乎没注释,很难看懂 [https://api.steampowered.com/ISteamWebAPIUtil/GetSupportedAPIList/v0001/](https://api.steampowered.com/ISteamWebAPIUtil/GetSupportedAPIList/v0001/)
2121

22+
## Steam Work 文献库
23+
24+
有中文,接口很丰富详细 [https://partner.steamgames.com/doc/api](https://partner.steamgames.com/doc/api)
25+
2226
## xpaw 大佬整理的 api 文档
2327

2428
非常详细,伟大![https://steamapi.xpaw.me/](https://steamapi.xpaw.me/)
2529

26-
## steam 的语言代码
30+
## Steam 的语言代码
2731

2832
[https://partner.steamgames.com/doc/store/localization/languages?l=schinese](https://partner.steamgames.com/doc/store/localization/languages?l=schinese)

src/components/GameCard.astro

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,13 @@
11
---
2-
import * as steamApi from "../utils/steamApi.ts";
3-
4-
const { img, appid, playtime } = Astro.props;
2+
const { imgurl, name, playtime } = Astro.props;
53
const playtimeHours = Math.floor(playtime / 60);
6-
7-
const appDetails = (await steamApi.appdetails(appid))?.[appid]?.data;
8-
const name = appDetails?.name|| '';
94
---
105

116
<div class="card">
12-
<img src={img} alt={`${name} image`} />
7+
<img src={imgurl} alt={`${name} image`} />
138
<div class="card-content">
14-
<h3>{name}</h3>{playtimeHours}
15-
<p>这是一个极简风格的卡片,拥有圆角、阴影和左右结构。</p>
9+
<h3>{name}</h3>{playtimeHours} H
10+
<p></p>
1611
</div>
1712
</div>
1813

@@ -25,12 +20,14 @@ const name = appDetails?.name|| '';
2520
overflow: hidden;
2621
max-width: 600px;
2722
width: 90%;
23+
margin-top: 1.25rem;
24+
margin-bottom: 1.25rem;
2825
}
2926

3027
.card img {
31-
width: 150px;
32-
height: 150px;
33-
object-fit: cover;
28+
width: auto;
29+
height: 100px;
30+
margin: 2rem;
3431
}
3532

3633
.card-content {

src/components/PlayedGames.astro

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,47 @@
11
---
2-
import type { PlayedGame } from "../utils/steamApi.ts";
2+
import type { MyPlayedGame, PlayedGame } from "../utils/steamApi.ts";
33
import * as steamApi from "../utils/steamApi.ts";
4-
import { Image } from "astro:assets";
5-
import GameCard from "./GameCard.astro";
4+
import GameCard from "../components//GameCard.astro";
5+
6+
const appList: { applist: { apps: { appid: string; name: string }[] } } =
7+
await steamApi.getAppList();
8+
const apps = appList.applist.apps;
9+
10+
let playedGames: MyPlayedGame[] = (await steamApi.playedGames()).map(game => ({
11+
...game,
12+
name: apps.find((app) => app.appid == game.appid)?.name || '',
13+
imgurl: steamApi.imageUrl(game.appid.toString())
14+
}));
15+
//TODO
16+
// const otherGames = [{
17+
// name:'Escape from Tarkov',
18+
// imgurl: 'https://cdn.cloudflare.steamstatic.com/steam/apps/255710/header.jpg',
19+
// }]
20+
// playedGames.push()
21+
22+
23+
playedGames = playedGames.filter((game) => game.playtime_forever > 1000);
24+
// const ENABLE_REQUEST = import.meta.env.ENABLE_REQUEST || false;
25+
// console.log(ENABLE_REQUEST);
26+
// if (ENABLE_REQUEST === true) {
27+
// const appids = playedGames.map((game) => game.appid);
28+
// const appdetails = await steamApi.appdetails(appids);
29+
// appdetails.map();
30+
// }
31+
632
7-
let playedGames: PlayedGame[] = await steamApi.playedGames();
8-
let imageUrl = steamApi.chineseImageUrl("322330");
933
---
1034

1135
<div>
12-
<p>
13-
<!-- {JSON.stringify(steamInfo)} -->
14-
</p>
15-
<Image src={imageUrl} alt="dst game header" width="512" height="512" />
16-
1736
{
1837
playedGames.map((game) => {
19-
const { appid, playtime_forever, img_icon_url } = game;
20-
const delay = (ms: number) => new Promise(res => setTimeout(res, ms));
21-
if(import.meta.env.ENABLE_REQUEST)delay(500);
38+
const { appid, name, playtime_forever } = game;
2239
return (
2340
<GameCard
24-
img={img_icon_url}
25-
playtime={playtime_forever}
2641
appid={appid}
42+
name={name}
43+
playtime={playtime_forever}
44+
imgurl={steamApi.imageUrl(game.appid.toString())}
2745
/>
2846
);
2947
})

src/pages/lab.astro

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
---
2-
import MainLayout from "../layouts/MainLayout.astro";
32
import tacImage from "../../public/assets/images/avatar.png";
43
import DropMenu from "../components/DropMenu.astro";
54
import Prose from "../components/Prose.astro";

src/utils/steamApi.ts

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
import { get } from "./utils";
1+
import get from "axios";
22

33
// 定义表示 Steam 游戏数据的接口
44
export interface PlayedGame {
5-
appid: number;
6-
name: string;
5+
appid: string;
76
playtime_2weeks: number;
87
playtime_forever: number;
98
img_icon_url: string;
@@ -13,58 +12,83 @@ export interface PlayedGame {
1312
playtime_deck_forever: number;
1413
}
1514

15+
export interface MyPlayedGame extends PlayedGame {
16+
name: string;
17+
imgurl: string;
18+
}
19+
1620
const { STEAM_API_KEY, STEAM_ID } = import.meta.env;
1721
if (!STEAM_API_KEY) throw Error("STEAM_API_KEY not configured!");
1822
if (!STEAM_ID) throw Error("STEAM_ID not configured!");
1923

2024
const API_URL = "https://api.steampowered.com";
25+
const API_HTTP_URL = "http://api.steampowered.com";
2126
const WEB_URL = "https://store.steampowered.com";
2227
const CDN_URL = "https://shared.fastly.steamstatic.com";
28+
const CF_CDN_URL = "https://cdn.cloudflare.steamstatic.com";
2329

2430
//获取我玩过的游戏列表
2531
export const playedGames = async (): Promise<PlayedGame[]> => {
2632
const path = "/IPlayerService/GetOwnedGames/v0001/";
2733
const res = await get(`${API_URL}${path}`, {
28-
key: STEAM_API_KEY,
29-
steamid: STEAM_ID,
30-
include_played_free_games: "true", // 包括免费游戏
31-
include_appinfo: "false", // 包括应用
34+
params: {
35+
key: STEAM_API_KEY,
36+
steamid: STEAM_ID,
37+
include_played_free_games: "true", // 包括免费游戏
38+
include_appinfo: "false", // 包括应用}
39+
},
3240
});
33-
return sortPlayedGame((await res?.json()).response.games);
41+
const games = res.data.response.games;
42+
return await sortPlayedGame(games);
3443
};
3544

36-
const sortPlayedGame = (games: PlayedGame[]): PlayedGame[] => {
45+
const sortPlayedGame = async (games: PlayedGame[]): Promise<PlayedGame[]> => {
3746
return games.sort(
3847
(game1, game2) => game2.playtime_forever - game1.playtime_forever
3948
);
4049
};
4150

4251
//获取指定应用详情
43-
export const appdetails = async (appid: string) => {
52+
export const appdetails = async (
53+
appids: string | string[],
54+
filters?: string | string[]
55+
) => {
4456
const path = "/api/appdetails";
4557
const res = await get(`${WEB_URL}${path}`, {
46-
appids: appid,
47-
l: "schinese",
48-
cc: "CN",
58+
params: {
59+
appids,
60+
filters,
61+
l: "schinese",
62+
cc: "CN",
63+
},
4964
});
50-
51-
52-
return await res?.json().catch(() => ({}));
65+
return await res.data;
5366
};
5467

5568
//获取指定应用中文封面url
5669
export const chineseImageUrl = (appid: string) =>
57-
`${CDN_URL}/store_item_assets/steam/apps/${appid}/header_schinese.jpg`;
70+
`${CF_CDN_URL}/steam/apps/${appid}/header_schinese.jpg`;
71+
//获取指定应用封面url
72+
export const imageUrl = (appid: string) =>
73+
`${CF_CDN_URL}/steam/apps/${appid}/header.jpg`;
5874

5975
//获取指定应用中文封面
6076
export const chineseImage = async (appid: string) => {
6177
const res = await get(chineseImageUrl(appid));
62-
return res?.blob();
78+
return res.data;
6379
};
6480
export const getGlobalAchievement = async (appid: string) => {
6581
const path = "ISteamUserStats/GetGlobalAchievementPercentagesForApp/v0002/";
6682
const res = await get(`${API_URL}${path}`, {
67-
gameid: appid,
83+
params: {
84+
gameid: appid,
85+
},
6886
});
69-
return await res?.json();
87+
return await res.data;
88+
};
89+
90+
export const getAppList = async () => {
91+
const path = "/ISteamApps/GetAppList/v2/";
92+
const res = await get(`${API_HTTP_URL}${path}`);
93+
return await res.data;
7094
};

src/utils/utils.ts

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -63,30 +63,3 @@ switch (PATH_MODULE) {
6363
}
6464

6565
const ENABLE_REQUEST = import.meta.env.ENABLE_REQUEST || false; //频繁请求可能导致被api封禁,仅在调试完毕后开启
66-
67-
export let get = async (
68-
url: string,
69-
params?:
70-
| string
71-
| string[][]
72-
| Record<string, string>
73-
| URLSearchParams
74-
| undefined,
75-
headers?: HeadersInit
76-
) => {
77-
const queryString = new URLSearchParams(params).toString();
78-
let response;
79-
try {
80-
response = await fetch(`${url}?${queryString}`, {
81-
method: "GET",
82-
headers: headers,
83-
});
84-
} catch (err) {
85-
console.log(err);
86-
}
87-
return response;
88-
};
89-
90-
if (!ENABLE_REQUEST) {
91-
get = async () => new Response("{}", { status: 200 }); // 模拟成功的空响应
92-
}

0 commit comments

Comments
 (0)