“增加小游网站SEO等公共信息的类”

This commit is contained in:
lenomar 2025-07-17 18:35:14 +08:00
parent 67af964370
commit 9fd956ae39
16 changed files with 486 additions and 78 deletions

View File

@ -2,6 +2,11 @@ namespace iyixiGames.Domain.DTOs.AdSitting;
public class GoogleDTOs
{
/// <summary>
/// Adsence pub id
/// </summary>
public string? PubId { get; set; }
// Google自动广告
/// <summary>
/// Google自动广告
@ -24,7 +29,7 @@ public class GoogleDTOs
public int? AmpAutoAdIsOpen { get; set; }
// Body位置
/// <summary>
/// Body位置
/// Body位置 展示广告
/// </summary>
public string? BodyPosition { get; set; }
// Body位置是否开启开启为1不开启为0int 类型
@ -34,7 +39,7 @@ public class GoogleDTOs
public int? BodyPositionIsOpen { get; set; }
// List位置
/// <summary>
/// List位置
/// List位置 多重广告
/// </summary>
public string? ListPosition { get; set; }
// List位置是否开启开启为1不开启为0int 类型
@ -44,7 +49,7 @@ public class GoogleDTOs
public int? ListPositionIsOpen { get; set; }
// Footer位置
/// <summary>
/// Footer位置
/// Footer位置 展示广告
/// </summary>
public string? FooterPosition { get; set; }
// Footer位置是否开启开启为1不开启为0int 类型

View File

@ -1,30 +1,153 @@
using System.ComponentModel.DataAnnotations;
namespace iyixiGames.Domain.DTOs.Seo;
public class SeoDTOs
{
/// <summary>
/// 网站描述
/// </summary>
[Required(ErrorMessage = "网站描述是必填项。")]
[StringLength(255, MinimumLength = 3, ErrorMessage = "网站描述长度必须在3到255个字符之间。")]
public string? Description { get; set; }
/// <summary>
/// 网站关键字
/// </summary>
[Required(ErrorMessage = "网站关键字是必填项。")]
[StringLength(255, MinimumLength = 3, ErrorMessage = "网站关键字长度必须在3到255个字符之间。")]
public string? Keywords { get; set; }
/// <summary>
/// 网站标题
/// </summary>
[Required(ErrorMessage = "网站标题是必填项。")]
[StringLength(255, MinimumLength = 3, ErrorMessage = "网站标题长度必须在3到255个字符之间。")]
public string? Title { get; set; }
/// <summary>
/// 网站canonical
/// </summary>
[Required(ErrorMessage = "网站canonical是必填项。")]
[StringLength(255, MinimumLength = 3, ErrorMessage = "网站canonical长度必须在3到255个字符之间。")]
public string? Canonical { get; set; }
/// <summary>
/// 网站 Alternate
/// </summary>
[Required(ErrorMessage = "网站Alternate是必填项。")]
[StringLength(255, MinimumLength = 3, ErrorMessage = "网站Alternate长度必须在3到255个字符之间。")]
public List<HreFlangDTOs>? Alternate { get; set; }
/// <summary>
/// OgTitle
/// </summary>
[Required(ErrorMessage = "网站标题是必填项。")]
[StringLength(255, MinimumLength = 3, ErrorMessage = "网站标题长度必须在3到255个字符之间。")]
public string? OgTitle { get; set; }
/// <summary>
/// OgDescription
/// </summary>
[Required(ErrorMessage = "网站描述是必填项。")]
[StringLength(255, MinimumLength = 3, ErrorMessage = "网站描述长度必须在3到255个字符之间。")]
public string? OgDescription { get; set; }
/// <summary>
/// OgType
/// </summary>
[Required(ErrorMessage = "网站类型是必填项。")]
[StringLength(255, MinimumLength = 3, ErrorMessage = "网站类型长度必须在3到255个字符之间。")]
public string? OgType { get; set; }
/// <summary>
/// OgUrl
/// </summary>
[Required(ErrorMessage = "网站URL是必填项。")]
[Url(ErrorMessage = "URL格式不正确。")]
public string? OgUrl { get; set; }
/// <summary>
/// OgImage
/// </summary>
[Required(ErrorMessage = "网站图片是必填项。")]
[Url(ErrorMessage = "图片地址格式不正确。")]
public string? OgImage { get; set; }
/// <summary>
/// OgLocale
/// </summary>
[Required(ErrorMessage = "网站语言是必填项。")]
[StringLength(10, MinimumLength = 2, ErrorMessage = "网站语言长度必须在2到10个字符之间。")]
public string? OgLocale { get; set; }
/// <summary>
/// OgSiteName
/// </summary>
[Required(ErrorMessage = "网站名称是必填项。")]
[StringLength(100, MinimumLength = 3, ErrorMessage = "网站名称长度必须在3到100个字符之间。")]
public string? OgSiteName { get; set; }
/// <summary>
/// TwitterCard
/// </summary>
[Required(ErrorMessage = "网站TwitterCard是必填项。")]
[StringLength(50, ErrorMessage = "TwitterCard长度不能超过50个字符。")]
public string? TwitterCard { get; set; }
/// <summary>
/// TwitterSite
/// </summary>
[Required(ErrorMessage = "网站TwitterSite是必填项。")]
[StringLength(50, ErrorMessage = "TwitterSite长度不能超过50个字符。")]
public string? TwitterSite { get; set; }
/// <summary>
/// TwitterCreator
/// </summary>
[Required(ErrorMessage = "网站TwitterCreator是必填项。")]
[StringLength(50, ErrorMessage = "TwitterCreator长度不能超过50个字符。")]
public string? TwitterCreator { get; set; }
/// <summary>
/// TwitterTitle
/// </summary>
[Required(ErrorMessage = "网站TwitterTitle是必填项。")]
[StringLength(255, ErrorMessage = "TwitterTitle长度不能超过255个字符。")]
public string? TwitterTitle { get; set; }
/// <summary>
/// TwitterDescription
/// </summary>
[Required(ErrorMessage = "网站TwitterDescription是必填项。")]
[StringLength(255, ErrorMessage = "TwitterDescription长度不能超过255个字符。")]
public string? TwitterDescription { get; set; }
/// <summary>
/// TwitterImage
/// </summary>
[Required(ErrorMessage = "网站TwitterImage是必填项。")]
[Url(ErrorMessage = "图片地址格式不正确。")]
public string? TwitterImage { get; set; }
/// <summary>
/// TwitterImageAlt
/// </summary>
[Required(ErrorMessage = "网站TwitterImageAlt是必填项。")]
[StringLength(255, MinimumLength = 3, ErrorMessage = "网站TwitterImageAlt长度必须在3到255个字符之间。")]
public string? TwitterImageAlt { get; set; }
/// <summary>
/// Icon
/// </summary>
[Required(ErrorMessage = "网站Icon是必填项。")]
[Url(ErrorMessage = "Icon地址格式不正确。")]
public string? Icon { get; set; }
/// <summary>
/// ShortIcon
/// </summary>
[Required(ErrorMessage = "网站ShortIcon是必填项。")]
[Url(ErrorMessage = "ShortIcon地址格式不正确。")]
public string? ShortIcon { get; set; }
}

View File

@ -0,0 +1,33 @@
using System.ComponentModel.DataAnnotations;
namespace iyixiGames.Domain.DTOs.Sites;
public class BaseDTOs
{
/// <summary>
/// 网站名称
/// </summary>
[Required(ErrorMessage = "网站名称是必填项。")]
[StringLength(100, MinimumLength = 3, ErrorMessage = "网站名称长度必须在3到100个字符之间。")]
public string Name { get; set; } = string.Empty;
/// <summary>
/// 网站域名
/// </summary>
[Required(ErrorMessage = "网站域名是必填项。")]
[Url(ErrorMessage = "域名格式不正确。")]
public string Domain { get; set; } = string.Empty;
/// <summary>
/// 网站所有者ID
/// </summary>
[Required(ErrorMessage = "网站所有者ID是必填项。")]
public string OwnerUserId { get; set; } = string.Empty;
/// <summary>
/// 网站Logod地址
/// </summary>
[Required(ErrorMessage = "网站Logo是必填项。")]
[Url(ErrorMessage = "Logo地址格式不正确。")]
public string? Logo { get; set; }
}

View File

@ -1,4 +1,5 @@
using System.ComponentModel.DataAnnotations;
using iyixiGames.Domain.DTOs.Seo;
namespace iyixiGames.Domain.DTOs.Sites
{
@ -16,12 +17,19 @@ namespace iyixiGames.Domain.DTOs.Sites
[Required(ErrorMessage = "网站域名是必填项。")]
[Url(ErrorMessage = "域名格式不正确。")]
public string Domain { get; set; } = string.Empty;
/// <summary>
/// 网站Logod地址
/// </summary>
[Required(ErrorMessage = "网站Logo是必填项。")]
[Url(ErrorMessage = "Logo地址格式不正确。")]
public string? Logo { get; set; }
[Required(ErrorMessage = "网站所有者ID是必填项。")]
public string OwnerUserId { get; set; } = string.Empty;
public List<SiteTeamMemberDTO>? TeamMembers { get; set; } // 创建时可以指定团队成员
public SiteSeoDTO? Seo { get; set; }
public SeoDTOs? Seo { get; set; }
public SiteSettingsDTO? Settings { get; set; }
// Analytics 通常不由创建者直接设置,而是在后台生成
}

View File

@ -1,5 +1,8 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using iyixiGames.Domain.DTOs.Seo;
namespace iyixiGames.Domain.Entities
{
@ -11,6 +14,7 @@ namespace iyixiGames.Domain.Entities
public string Id { get; set; } = Guid.NewGuid().ToString("N"); // 网站唯一标识符
public string Name { get; set; } = string.Empty; // 网站名称
public string Domain { get; set; } = string.Empty; // 网站域名 (例如: https://game-pixel.fun)
public string? Logo { get; set; } // 网站Logo
public string OwnerUserId { get; set; } = string.Empty; // 网站所有者的用户ID
// 可选属性:关联团队成员
@ -45,18 +49,192 @@ namespace iyixiGames.Domain.Entities
}
/// <summary>
/// 表示网站的 SEO 信息
/// 表示网站的全局 SEO 配置
/// </summary>
public class SiteSeo
{
public string SiteId { get; set; } = string.Empty; // 关联的网站ID作为主键
public string Description { get; set; } = string.Empty; // SEO 描述
public string Keywords { get; set; } = string.Empty; // SEO 关键词,可以用逗号分隔
/// <summary>
/// 主键通常全局SEO配置只有一个记录可以使用固定ID或Guid。
/// 如果你计划为每个页面配置SEO则需要一个合适的Id策略。
/// 这里假设是全局配置ID可为固定值如 "global-seo"。
/// </summary>
[Key] // 标识为主键
public string Id { get; set; } = Guid.NewGuid().ToString(); // 示例使用固定字符串作为ID表示全局唯一的SEO配置
// 导航属性
/// <summary>
/// 网站ID
/// </summary>
[MaxLength(255)]
public string SiteId { get; set; } = string.Empty;
/// <summary>
/// 网站描述 (meta description)
/// </summary>
[MaxLength(255)] // 对应 SeoDTOs 中的 StringLength
public string Description { get; set; } = string.Empty;
/// <summary>
/// 网站关键字 (meta keywords)
/// </summary>
[MaxLength(255)]
public string Keywords { get; set; } = string.Empty;
/// <summary>
/// 网站标题 (meta title)
/// </summary>
[MaxLength(255)]
public string Title { get; set; } = string.Empty;
/// <summary>
/// 网站 Canonical URL
/// </summary>
[MaxLength(255)]
public string Canonical { get; set; } = string.Empty;
/// <summary>
/// 网站 Alternate Hreflang (存储为 JSON 字符串或独立实体列表)
/// 由于 List<HreFlangDTOs> 无法直接映射到单一数据库列,
/// 这里可以将其序列化为 JSON 字符串存储,或者创建独立的 Hreflang 实体并建立关系。
/// 考虑到简单性,先用字符串存储。
/// </summary>
// 注意:这里我们选择将 HreFlangDTOs 列表序列化为 JSON 字符串存储
// 你也可以创建一个独立的 Hreflang 实体和表,并与 SiteSeo 建立一对多关系。
[MaxLength(2000)] // 预留足够空间存储 JSON 字符串,根据实际 Alternate 数量调整
public string AlternateJson { get; set; } = "[]"; // 默认空 JSON 数组
/// <summary>
/// Open Graph Title
/// </summary>
[MaxLength(255)]
public string OgTitle { get; set; } = string.Empty;
/// <summary>
/// Open Graph Description
/// </summary>
[MaxLength(255)]
public string OgDescription { get; set; } = string.Empty;
/// <summary>
/// Open Graph Type (e.g., "website", "article")
/// </summary>
[MaxLength(255)]
public string OgType { get; set; } = string.Empty;
/// <summary>
/// Open Graph URL
/// </summary>
[MaxLength(500)] // URL 长度可能较长
public string OgUrl { get; set; } = string.Empty;
/// <summary>
/// Open Graph Image URL
/// </summary>
[MaxLength(500)] // URL 长度可能较长
public string OgImage { get; set; } = string.Empty;
/// <summary>
/// Open Graph Locale (e.g., "en_US", "zh_CN")
/// </summary>
[MaxLength(10)]
public string OgLocale { get; set; } = string.Empty;
/// <summary>
/// Open Graph Site Name
/// </summary>
[MaxLength(100)]
public string OgSiteName { get; set; } = string.Empty;
/// <summary>
/// Twitter Card Type (e.g., "summary", "summary_large_image")
/// </summary>
[MaxLength(50)]
public string TwitterCard { get; set; } = string.Empty;
/// <summary>
/// Twitter Site Handle (e.g., "@yourtwitterhandle")
/// </summary>
[MaxLength(50)]
public string TwitterSite { get; set; } = string.Empty;
/// <summary>
/// Twitter Creator Handle
/// </summary>
[MaxLength(50)]
public string TwitterCreator { get; set; } = string.Empty;
/// <summary>
/// Twitter Title
/// </summary>
[MaxLength(255)]
public string TwitterTitle { get; set; } = string.Empty;
/// <summary>
/// Twitter Description
/// </summary>
[MaxLength(255)]
public string TwitterDescription { get; set; } = string.Empty;
/// <summary>
/// Twitter Image URL
/// </summary>
[MaxLength(500)]
public string TwitterImage { get; set; } = string.Empty;
/// <summary>
/// Twitter Image Alt Text
/// </summary>
[MaxLength(255)]
public string TwitterImageAlt { get; set; } = string.Empty;
/// <summary>
/// Favicon URL
/// </summary>
[MaxLength(500)]
public string Icon { get; set; } = string.Empty;
/// <summary>
/// Short Favicon URL (for older browsers/devices)
/// </summary>
[MaxLength(500)]
public string ShortIcon { get; set; } = string.Empty;
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
/// <summary>
/// 最后更新时间
/// </summary>
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
// ================================================================
// 注意HreFlangDTOs 列表不能直接映射到数据库列。
// 你可以选择在 Model 中添加一个 [NotMapped] 属性,用于方便地存取。
// 在保存到数据库前将其序列化为 AlternateJson读取后再反序列化。
// ================================================================
[NotMapped] // 这个属性不会被映射到数据库
public List<HreFlang>? Alternate { get; set; } = new List<HreFlang>();
/// <summary>
/// 导航属性
/// </summary>
public Site Site { get; set; } = null!;
}
public class HreFlang
{
[Key]
public string Id { get; set; }=Guid.NewGuid().ToString();
[Required]
[StringLength(255, MinimumLength = 3, ErrorMessage = "网站标题长度必须在3到255个字符之间。")]
public string? Href { get; set; }
[Required]
[StringLength(10, MinimumLength = 2, ErrorMessage = "网站语言长度必须在2到10个字符之间。")]
public string? Lang { get; set; }
}
/// <summary>
/// 表示网站的分析数据。
/// </summary>

View File

@ -1,3 +1,4 @@
using iyixiGames.Domain.DTOs.AdSitting;
using Microsoft.AspNetCore.Mvc;
namespace iyixiGames.miniGame.ViewComponents;
@ -6,39 +7,20 @@ public class AdSittingViewComponent : ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync(string routStr)
{
switch (routStr)
var adSitting = new GoogleDTOs()
{
case "Head":
var adSitting = new List<string>
{
"head",
"ca-pub-9479337834161326"
};
return View(routStr, adSitting);
case "Body":
adSitting = new List<string>
{
"body",
"&lt;script async src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9479337834161326&quot;\n&nbsp; &nbsp; &nbsp;crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;\n&lt;!-- hf_001 --&gt;\n&lt;ins class=&quot;adsbygoogle&quot;\n&nbsp; &nbsp; &nbsp;style=&quot;display:block&quot;\n&nbsp; &nbsp; &nbsp;data-ad-client=&quot;ca-pub-9479337834161326&quot;\n&nbsp; &nbsp; &nbsp;data-ad-slot=&quot;1367425129&quot;\n&nbsp; &nbsp; &nbsp;data-ad-format=&quot;auto&quot;\n&nbsp; &nbsp; &nbsp;data-full-width-responsive=&quot;true&quot;&gt;&lt;/ins&gt;\n&lt;script&gt;\n&nbsp; &nbsp; &nbsp;(adsbygoogle = window.adsbygoogle || []).push({});\n&lt;/script&gt;"
};
return View(routStr, adSitting);
case "List":
adSitting = new List<string>
{
"list",
""
};
return View(routStr, adSitting);
case "Footer":
adSitting = new List<string>
{
"footer",
""
};
return View(routStr, adSitting);
default:
return View();
}
PubId = "ca-pub-9479337834161326",
AutoAd = "ca-pub-9479337834161326",
AutoAdIsOpen = 1,
AmpAutoAd = "ca-pub-9479337834161326",
AmpAutoAdIsOpen = 1,
BodyPosition = "1367425129",
BodyPositionIsOpen = 1,
ListPosition = "5682081797",
ListPositionIsOpen = 1,
FooterPosition = "1367425129",
FooterPositionIsOpen = 1
};
return View(routStr, adSitting);
}
}

View File

@ -0,0 +1,19 @@
using iyixiGames.Domain.DTOs.Sites;
using Microsoft.AspNetCore.Mvc;
namespace iyixiGames.miniGame.ViewComponents;
public class BaseSetViewComponent : ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync(string routStr)
{
var baseDTOs = new BaseDTOs()
{
Name = "iyixiGames",
Domain = "iyixiGames.com",
OwnerUserId = "iyixiGames",
Logo = "https://iyixiGames.com/logo.png"
};
return View(routStr, baseDTOs);
}
}

View File

@ -15,7 +15,7 @@
<span class="category">动作 / 冒险</span>
</div>
<div class="game-meta-large">
<a class="btn-play" asp-area="" asp-controller="Games" asp-action="PlayGame" asp-route-id="123">="">立即游玩</a>
<a class="btn-play" asp-area="" asp-controller="Games" asp-action="PlayGame" asp-route-id="123">立即游玩</a>
</div>
</div>
</div>

View File

@ -1,16 +1,61 @@
@{
ViewData["Title"] = "Games";
Layout = "";
}
<!DOCTYPE html>
<html>
<html lang="zh-CN">
<head>
<title>title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>正在玩: 太空冒险 - 游戏天堂</title>
<link rel="stylesheet" href="/css/style.css">
<link rel="stylesheet" href="/css/theme.css">
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
background: #000;
}
.game-container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.back-button {
position: fixed;
top: 20px;
left: 20px;
z-index: 1000;
background: rgba(0,0,0,0.7);
color: white;
padding: 10px 15px;
border-radius: 5px;
text-decoration: none;
font-weight: bold;
display: flex;
align-items: center;
}
.back-button:hover {
background: rgba(0,0,0,0.9);
}
iframe {
width: 100%;
height: 100%;
border: none;
}
</style>
</head>
<body>
<div>
<a href="/detail.html?id=game1" class="back-button">
🔙
</a>
<div class="game-container">
<iframe src="/games/game1/index.html" allowfullscreen></iframe>
</div>
<script src="/js/script.js"></script>
</body>
</html>

View File

@ -3,7 +3,20 @@
@if (Model.AmpAutoAdIsOpen == 1)
{
// 自动广告AMP
<amp-auto-ads type="adsense"
data-ad-client="@Model.AmpAutoAd">
data-ad-client="@Model.PubId">
</amp-auto-ads>
}
@if (Model.BodyPositionIsOpen == 1)
{
<ins class="adsbygoogle"
style="display:block"
data-ad-client="@Model.PubId"
data-ad-slot="@Model.BodyPosition"
data-ad-format="auto"
data-full-width-responsive="true"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
}

View File

@ -1,3 +1,3 @@
@model List<string>
<p style="color: #f65e3b">哈哈哈</p>
<p style="color: #f65e3b"></p>

View File

@ -1,6 +1,17 @@
@model List<string>
@using iyixiGames.Domain.DTOs.AdSitting
@model GoogleDTOs
@if (Model[0] == "footer")
@if (Model.FooterPositionIsOpen == 1)
{
@Model[1]
// 展示广告
<!-- hf_001 -->
<ins class="adsbygoogle"
style="display:block"
data-ad-client="@Model.PubId"
data-ad-slot="@Model.FooterPosition"
data-ad-format="auto"
data-full-width-responsive="true"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
}

View File

@ -1,13 +1,14 @@
@model iyixiGames.Domain.DTOs.AdSitting.GoogleDTOs
@if (Model.AutoAdIsOpen == 1)
@if (Model.AutoAdIsOpen == 1 || Model.BodyPositionIsOpen == 1 || Model.ListPositionIsOpen == 1 || Model.FooterPositionIsOpen == 1)
{
//@Model[1]
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=@Model.AutoAd"
//自动广告
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=@Model.PubId"
crossorigin="anonymous"></script>
}
@if(Model.AmpAutoAdIsOpen==1)
@if (Model.AmpAutoAdIsOpen == 1)
{
// 自动广告AMP
<script async custom-element="amp-auto-ads"
src="https://cdn.ampproject.org/v0/amp-auto-ads-0.1.js">
</script>

View File

@ -4,27 +4,13 @@
@if (Model.ListPositionIsOpen == 1)
{
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9479337834161326"
crossorigin="anonymous"></script>
<!-- hf_001 -->
<ins class="adsbygoogle"
style="display:block"
data-ad-client="ca-pub-9479337834161326"
data-ad-slot="1367425129"
data-ad-format="auto"
data-full-width-responsive="true"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9479337834161326"
crossorigin="anonymous"></script>
// 多重广告
<ins class="adsbygoogle"
style="display:block"
data-ad-format="autorelaxed"
data-ad-client="ca-pub-9479337834161326"
data-ad-slot="5682081797"></ins>
data-ad-client="@Model.PubId"
data-ad-slot="@Model.ListPosition"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
}

View File

@ -0,0 +1,5 @@
@using iyixiGames.Domain.DTOs.Sites
@model BaseDTOs
<title>@ViewData["Title"] - @Model.Name - @Model.Domain</title>
<link rel="shortcut icon" href="@Model.Logo" type="image/png" />

View File

@ -3,13 +3,12 @@
<head>
<meta charset="UTF-8">
@await Component.InvokeAsync("NavigationSEO")
<title>@ViewData["Title"] - 游戏天堂 - 发现并玩最好的在线游戏</title>
@await Component.InvokeAsync("BaseSet","Base")
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css"/>
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true"/>
<link rel="stylesheet" href="~/iyixiGames.miniGame.styles.css" asp-append-version="true"/>
<link rel="stylesheet" href="/css/style.css">
<link rel="stylesheet" href="/css/theme.css">
<link rel="shortcut icon" href="/images/logo.png" type="image/png">
@await Component.InvokeAsync("AdSitting", "Head")
</head>
<body>
@ -41,13 +40,13 @@
</div>
</div>
</header>
@await Component.InvokeAsync("AdSitting", "List")
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
@await Component.InvokeAsync("AdSitting", "Footer")
<footer class="site-footer">
<div class="container">
<div class="footer-columns">