增加兼容性显示

This commit is contained in:
小朱
2025-07-17 18:40:22 +08:00
parent 1e95ad2dcc
commit 4bfaaa97c4
3 changed files with 135 additions and 4 deletions

View File

@@ -29,6 +29,7 @@ interface GameInfo {
system?: string[]
supportedOnCurrentPlatform?: boolean
currentPlatform?: string
panelCompatibleOnCurrentPlatform?: boolean
}
interface Games {
@@ -134,6 +135,11 @@ const GameDeploymentPage: React.FC = () => {
const [onlineGameTypeFilter, setOnlineGameTypeFilter] = useState<string>('all')
const [onlineGameSearchQuery, setOnlineGameSearchQuery] = useState('')
// 面板兼容性确认对话框状态
const [showCompatibilityModal, setShowCompatibilityModal] = useState(false)
const [compatibilityModalAnimating, setCompatibilityModalAnimating] = useState(false)
const [pendingGameInstall, setPendingGameInstall] = useState<{ key: string; info: GameInfo } | null>(null)
const socketRef = useRef<Socket | null>(null)
const currentDownloadId = useRef<string | null>(null)
const currentMoreGameDeploymentId = useRef<string | null>(null)
@@ -1039,6 +1045,21 @@ const GameDeploymentPage: React.FC = () => {
return
}
// 检查面板是否兼容当前平台
if (gameInfo.panelCompatibleOnCurrentPlatform === false) {
// 显示兼容性确认对话框
setPendingGameInstall({ key: gameKey, info: gameInfo })
setShowCompatibilityModal(true)
setTimeout(() => setCompatibilityModalAnimating(true), 10)
return
}
// 直接打开安装对话框
openInstallModal(gameKey, gameInfo)
}
// 打开安装对话框的通用函数
const openInstallModal = (gameKey: string, gameInfo: GameInfo) => {
setSelectedGame({ key: gameKey, info: gameInfo })
setInstanceName(gameInfo.game_nameCN)
setInstallPath('')
@@ -1054,6 +1075,26 @@ const GameDeploymentPage: React.FC = () => {
}, 300)
}
// 关闭兼容性确认对话框
const handleCloseCompatibilityModal = () => {
setCompatibilityModalAnimating(false)
setTimeout(() => {
setShowCompatibilityModal(false)
setPendingGameInstall(null)
}, 300)
}
// 确认继续安装不兼容的游戏
const handleConfirmIncompatibleInstall = () => {
if (pendingGameInstall) {
handleCloseCompatibilityModal()
// 延迟一点时间等待对话框关闭动画完成
setTimeout(() => {
openInstallModal(pendingGameInstall.key, pendingGameInstall.info)
}, 350)
}
}
// 关闭创建实例对话框
const handleCloseCreateInstanceModal = () => {
setCreateInstanceModalAnimating(false)
@@ -1679,12 +1720,18 @@ const GameDeploymentPage: React.FC = () => {
className={`w-full py-2 px-4 rounded-lg transition-colors flex items-center justify-center space-x-2 ${
gameInfo.supportedOnCurrentPlatform === false
? 'bg-gray-400 cursor-not-allowed text-gray-200'
: gameInfo.panelCompatibleOnCurrentPlatform === false
? 'bg-orange-600 hover:bg-orange-700 text-white'
: 'bg-blue-600 hover:bg-blue-700 text-white'
}`}
>
<Download className="w-4 h-4" />
<span>
{gameInfo.supportedOnCurrentPlatform === false ? '平台不兼容' : '安装游戏'}
{gameInfo.supportedOnCurrentPlatform === false
? '平台不兼容'
: gameInfo.panelCompatibleOnCurrentPlatform === false
? '面板不兼容'
: '安装游戏'}
</span>
</button>
</div>
@@ -3429,6 +3476,71 @@ const GameDeploymentPage: React.FC = () => {
</div>
</div>
)}
{/* 面板兼容性确认对话框 */}
{showCompatibilityModal && pendingGameInstall && (
<div className={`fixed inset-0 bg-black/50 flex items-center justify-center z-50 transition-opacity duration-300 ${
compatibilityModalAnimating ? 'opacity-100' : 'opacity-0'
}`}>
<div className={`bg-white dark:bg-gray-800 rounded-lg shadow-xl w-full max-w-md mx-4 transform transition-all duration-300 ${
compatibilityModalAnimating ? 'scale-100 opacity-100' : 'scale-95 opacity-0'
}`}>
<div className="flex items-center justify-between p-6 border-b border-gray-200 dark:border-gray-700">
<h3 className="text-lg font-semibold text-gray-900 dark:text-white flex items-center space-x-2">
<AlertCircle className="w-5 h-5 text-orange-500" />
<span></span>
</h3>
<button
onClick={handleCloseCompatibilityModal}
className="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300"
>
<X className="w-5 h-5" />
</button>
</div>
<div className="p-6">
<div className="bg-orange-50 dark:bg-orange-900/20 border border-orange-200 dark:border-orange-800 rounded-lg p-4 mb-4">
<div className="flex items-start space-x-3">
<AlertCircle className="w-5 h-5 text-orange-500 flex-shrink-0 mt-0.5" />
<div>
<h4 className="text-sm font-medium text-orange-800 dark:text-orange-200 mb-1">
</h4>
<p className="text-sm text-orange-700 dark:text-orange-300">
</p>
</div>
</div>
</div>
<div className="bg-gray-50 dark:bg-gray-700 rounded-lg p-3">
<p className="text-sm text-gray-600 dark:text-gray-400">
<strong>:</strong> {pendingGameInstall.info.game_nameCN}
</p>
<p className="text-sm text-gray-600 dark:text-gray-400 mt-1">
<strong>:</strong> {pendingGameInstall.info.currentPlatform}
</p>
</div>
</div>
<div className="flex space-x-3 p-6 border-t border-gray-200 dark:border-gray-700">
<button
onClick={handleCloseCompatibilityModal}
className="flex-1 px-4 py-2 text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-600 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-500 transition-colors"
>
</button>
<button
onClick={handleConfirmIncompatibleInstall}
className="flex-1 px-4 py-2 bg-orange-600 hover:bg-orange-700 text-white rounded-lg transition-colors flex items-center justify-center space-x-2"
>
<Download className="w-4 h-4" />
<span></span>
</button>
</div>
</div>
</div>
)}
</div>
)
}

View File

@@ -21,7 +21,8 @@
"tip": "游戏端口7777 UDP配置文件位置Config/Game.ini存档位置位于映射的通用游戏存档路径目录中温馨提示请将保存位置映射到容器外部防止存档丢失",
"image":"https://shared.cdn.queniuqe.com/store_item_assets/steam/apps/526870/header.jpg",
"url":"https://store.steampowered.com/app/526870/_/",
"system":["Windows","Linux"]
"system":["Windows","Linux"],
"system_info":["Linux"]
},
"L4D2": {
"game_nameCN": "求生之路2",

View File

@@ -25,6 +25,7 @@ interface SteamGameInfo {
image: string
url: string
system?: Platform[]
system_info?: Platform[] // 面板兼容的系统列表
}
// 获取当前平台
@@ -53,6 +54,17 @@ function isGameSupportedOnCurrentPlatform(game: SteamGameInfo): boolean {
return game.system.includes(currentPlatform)
}
// 检查面板是否兼容当前平台
function isPanelCompatibleOnCurrentPlatform(game: SteamGameInfo): boolean {
// 如果游戏没有定义system_info字段默认面板兼容
if (!game.system_info || game.system_info.length === 0) {
return true
}
const currentPlatform = getCurrentPlatform()
return game.system_info.includes(currentPlatform)
}
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
@@ -86,17 +98,23 @@ router.get('/games', authenticateToken, async (req: Request, res: Response) => {
const allGames: { [key: string]: SteamGameInfo } = JSON.parse(gamesData)
const currentPlatform = getCurrentPlatform()
const filteredGames: { [key: string]: SteamGameInfo & { supportedOnCurrentPlatform: boolean, currentPlatform: Platform } } = {}
const filteredGames: { [key: string]: SteamGameInfo & {
supportedOnCurrentPlatform: boolean,
currentPlatform: Platform,
panelCompatibleOnCurrentPlatform: boolean
} } = {}
// 添加平台信息到所有游戏(不再过滤不兼容的游戏)
for (const [gameKey, gameInfo] of Object.entries(allGames)) {
const isSupported = isGameSupportedOnCurrentPlatform(gameInfo)
const isPanelCompatible = isPanelCompatibleOnCurrentPlatform(gameInfo)
// 返回所有游戏,包括不支持当前平台的游戏
filteredGames[gameKey] = {
...gameInfo,
supportedOnCurrentPlatform: isSupported,
currentPlatform
currentPlatform,
panelCompatibleOnCurrentPlatform: isPanelCompatible
}
}