41 KiB
用户模块(UserSrc)—— 功能与代码目录文档
本文档为用户模块(源码目录
UserSrc/)的完整上下文说明,供其他对话/开发者直接使用。内容全部基于仓库中实际读取到的源代码整理;未读到或无法确认的内容已明确标注,不做臆测。
一、平台背景与模块位置
本仓库是一个捕鱼 + 棋牌游戏运营平台后端,解决方案文件为 Template0524.sln。
总体技术栈
- 运行时/框架:.NET 8(各项目
TargetFramework均为net8.0) - 数据库:MongoDB(业务数据,通过自研
MongoRepository访问)、PostgreSQL(CAP 消息存储 / 部分后台数据) - 缓存/会话:Redis(RedisHelper、RedisService)
- 消息:RabbitMQ(通过
DotNetCore.CAP实现事件总线,CAP 采用 PostgreSQL 作为存储) - 实时通信:SignalR(使用 StackExchange.Redis 作为背板)
- 网关:Ocelot
- 日志:NLog(
nlog.config,由UserHost.csproj链接拷贝) - IoC:Autofac(
AutofacServiceProviderFactory+ 自研ApplicationModule约定注入) - 定时任务:自研
ScheduledService(CronJobService)
网关路由(平台总览,来自项目背景说明)
- 网关监听:
http://localhost:8001 /adminapi→ AdminHost(5241)/api、/loginhub→ UserHost(本模块,5245)/customerapi、/customerHub→ CustomerHost(5247)/chess、/chessgamehub→ ChessGameHost(5242)/fishingroomhub→ FishRoomHost(5244)/gamehub→ FishGameHost(5248)
本模块位置
- 模块源码根目录:
UserSrc/ - 进程入口项目:
UserSrc/UserHost(Program.cs) - 网关前缀:
/api(HTTP 接口)、/loginhub(SignalR Hub) - SignalR 使用 Redis 作为背板(
ChannelPrefix = "GameHub")
说明:
RedisService项目引用了UserSrc/UserDomain;CommonService、AdminService也引用了它(即UserSrc/UserDomain/UserDomain.csproj)。这是本模块实体被其它模块共享的关键点。
二、模块简介
定位:用户模块(UserSrc)是平台的账号与大厅(大厅资产/活动)服务,负责玩家的注册登录、个人资料、资产(金币/钻石/经验/VIP)、商城、邮件、签到、排行榜、任务、战令、抽奖/刮刮卡/召唤卡、公告/FAQ、靓号、游戏与活动配置下发,以及登录态维护(SignalR LoginHub)。
主要职责
- 账号:手机号注册、微信注册、手机号+验证码/密码登录、微信登录、改密、绑定微信/手机号、实名认证、登出/在线态维护。
- 资产:金币、钻石、经验、等级、VIP 等级、道具(背包/炮台/翅膀/战神)的统一增减(
UpdateAssets),并写入user_reward流水。 - 大厅:保险箱存取、救济金、签到、金币商城、钻石商城、返利(捕鱼返利)、排行榜、VIP 礼包、战令、任务。
- 周边:邮件、公告、FAQ、反馈、图片上传、游戏配置/活动配置读取、靓号。
核心业务流程/数据流
- 注册/登录:
LoginController→UserService.Register/RegisterWeiXin/Login/LoginByPassword/LoginWx→ 校验/查重(分布式锁)→ 新建或读取UserEntity→LoginToken签发 JWT → 返回UserToken(继承UserEntity,附带Token)。登录成功后若玩家此前在棋牌/捕鱼房间中,会触发旧房间结算(HandleLoginRoomSettlementAsync)。 - 大厅资产:各类接口最终汇聚到
UserService.UpdateAssets(UserAssetParam),在分布式锁user:asset:update:{userId}内变更Assets/Props/Static、写user_reward流水,并通过 CAP 发布Topic_0524_UserAssetSyncFrontend与 SignalR 推送前端。 - 登录态/实时:前台连接 SignalR
/loginhub,调用Bind(userId)绑定连接(写 Redis 登录态、处理旧连接踢下线、必要时 CAP 发布「登录绑定」等待旧房间结算结果),订阅者把后台通知/配置变更/击杀公告/资产变动实时推给前端。
三、业务功能清单
3.1 登录注册 —— LoginController(路由前缀 api/Login)
对应 Service:IUserService(UserService/User/UserService.cs);微信辅助:WXBaseHelper(Common.WX)。
| 接口 | 方法 | 用途 |
|---|---|---|
GetAccessToken |
GET | 获取微信 access_token(WXBaseHelper.GetAccessToken) |
GetSessionToken |
GET js_code |
用微信 code 换取 session/access(GetAccessTokenByCode) |
registerWX |
POST | 微信注册(RegisterWeiXin),已存在则直接登录 |
register |
POST | 手机号+账号+昵称+密码注册(Register),分布式锁查重 |
SendMobileCode |
GET mobile |
发送手机验证码(当前实现为固定 000000,写 Redis) |
LoginWx |
GET openId |
微信登录(LoginWx) |
Login |
GET mobile,code |
验证码或密码登录(Login 内部同时兼容两种) |
LoginByPassword |
GET mobile,password |
密码登录(LoginByPassword) |
GetDateTime |
GET | 返回服务器时间信息(DateTimeResponse,含时区/时间戳) |
ResetPassword |
GET mobile,password,code |
验证码重置密码(UpdatePassword) |
客户端 IP 由 GetClientIp() 读取 X-Forwarded-For 或连接地址。
3.2 大厅 —— HallController(路由前缀 api/Hall,[Authorize])
对应 Service:IUserService、ITaskService、IBattleOrderService、IActivityConfigService、IGameConfigService。
| 接口 | 方法 | 用途 / Service |
|---|---|---|
SaveSafeBox |
GET gold |
存入保险箱 UserService.SaveSafeBox |
GetSafeBox |
GET gold,password |
取出保险箱 UserService.GetSafeBox |
SetSafeBoxPassword |
GET password |
设置保险箱密码 |
ResetSafeBoxPassword |
GET password,code |
验证码重置保险箱密码 |
GetRelief |
GET | 领取救济金 GetReliefGold |
SynthesisFragment |
GET propNumber |
碎片合成 SyntheticFragments |
BuyProp |
GET propNumber,count |
购买道具 BuyProps |
UseVipExp |
GET count |
使用 VIP 经验包 UseVipExp |
BuyGold |
GET number,count |
钻石换金币(金币商城)BuyGold |
BuyDiamond |
GET number,count |
购买钻石(生成订单)BuyDiamond |
SignIn |
GET | 每日签到 Sign |
ChangeCannon / UnloadCannon |
GET number |
切换/卸下炮台 |
ChangeWing / UnloadWing |
GET number |
切换/卸下翅膀 |
ChangeGodWar / UnloadGodWar |
GET number |
切换/卸下战神 |
GetVipDayGift |
GET | 领取 VIP 每日礼包 |
GetVipGift |
GET vipLevel |
领取 VIP 权益礼包 |
GetUserTaskList |
GET taskType |
用户任务列表 TaskService.GetUserTaskList |
DistributeRewards |
GET id |
领取单个任务奖励 |
GetUserRewardList |
POST | 资产变动流水分页 GetUserRewardList |
GetBattleOrder |
GET | 战令详情 BattleOrderService.GetUserBattleOrderWithConfigAsync |
GetBattleOrderLevelStatus |
GET | 战令等级奖励状态 |
ReceiveAllBattleOrderRewards |
GET | 一键领取战令奖励 |
ReceiveBattleOrderLevelReward |
GET level |
领取指定等级战令奖励 |
BuyBattleOrderLevel |
GET levelCount |
购买战令等级 |
BuyBattleOrderAdvance |
GET type |
购买战令进阶(普通/豪华/至尊) |
ReceiveAllTaskRewards |
GET | 一键领取任务奖励(转战令经验)TaskService.ReceiveAllTaskRewardsAsync |
GetRanking |
GET type |
排行榜 UserService.GetRanking(受活动配置维护开关控制) |
SendBroadcast |
GET message |
大喇叭全服广播 SendBroadcast |
GetChessRoomPartitionCount |
GET | ([AllowAnonymous])统计中国象棋房间分区总数,读 IGameConfigService |
3.3 用户资料/邮件/返利 —— UserController(路由前缀 api/User,[Authorize])
对应 Service:IUserService。
- 资料:
RealNameAuth(实名认证)、UpdateUserName(改名,消耗改名卡)、BindWX、BindMobile、UpdateAvatar、UpdateAvatarFrame、GetUser、GetUserAssets、GetUserList。 - 邮件:
SendEmail、GetEmail、RewardEmail(type=1单封、否则一键领取)、DeleteEmail、ReadEmailMore、GetNoReadCount、GetEmailByPage。 - 捕鱼返利:
GetFishingReturnInfo、ClaimFishingReturn(对应UserService.RecordFishingConsume/GetFishingReturnInfo/ClaimFishingReturn)。
3.4 反馈 —— FeedbackController(UserApi/User/FeedbackController.cs,路由 api/Feedback,[Authorize])
对应 Service:IUserFeedbackService(UserService/User/UserFeedbackService.cs)。
Submit提交反馈、MyList我的反馈分页、Detail反馈详情。
3.5 抽奖(彩蛋)—— LotteryController(路由前缀 api/Lottery,[Authorize])
对应 Service:ILotteryService + IActivityConfigService + IGameConfigService。
Config抽奖配置(含已抽奖项)、Draw抽奖(poolType)、UserStatus用户抽奖状态、DrawnPrizes已抽奖项列表。
注意:抽奖业务实现位于
CommonService项目(CommonService/LotteryService.cs,其namespace为UserService),本模块内UserSrc/UserService/User/LotteryService.cs已被UserService.csproj通过<Compile Remove>排除编译(遗留文件,见第五节)。
3.6 刮刮卡 —— ScratchCardController(路由前缀 api/ScratchCard,[Authorize])
对应 Service:IScratchCardService(UserService/ScratchCard/ScratchCardService.cs)。
draw使用刮刮卡(道具编号40005)抽奖,扣道具并发奖,写scratch_card_record。
3.7 召唤卡 —— SummonCardController(路由前缀 api/SummonCard,[Authorize])
对应 Service:ISummonCardService(UserService/SummonCard/SummonCardService.cs)。
use在有效捕鱼房间内使用召唤卡(道具编号40006),扣除道具后 CAP 发布Topic_0524_SummonCardFish。
3.8 公告 —— NoticeController(路由前缀 api/Notice)
对应 Service:INoticeService。
list(POST)公告分页、get(匿名)公告详情、get/newone(匿名)最新公告。
3.9 FAQ —— FaqController(路由前缀 adminapi/Faq)
对应 Service:IFaqService。注意该 Controller 虽位于 UserApi 程序集,但路由前缀为 adminapi/[controller]。
CategoryTree分类树、Questions按分类取问题、QuestionList(POST)问题分页、QuestionDetail问题详情。
3.10 游戏配置/活动配置 —— GameConfigController、ActivityConfigController(api/GameConfig、api/ActivityConfig)
对应 Service:IGameConfigService、IActivityConfigService(均带 Redis 缓存)。
GameConfigController:Get返回GameConfig。ActivityConfigController:Get返回ActivityConfig;子项diamondShopList、goldShopList、signConfigs、reliefConfig、registerConfig、fishingReturnConfig、battleOrderConfig、lotteryConfig、rankingRewardConfig。
3.11 靓号 —— BeautifulNumberController(路由前缀 api/BeautifulNumber,[Authorize])
对应 Service:IBeautifulNumberService。
available可购靓号分页、check/{number}靓号校验。
3.12 字典 —— DictController(路由前缀 api/Dict)
GetByCode、GetListByCode:读 MongoDB 集合SystemDic(Domain.Admin.Admin)。
3.13 图片上传 —— ImageUploadController(路由前缀 api/ImageUpload)
upload(POST,IFormFile):保存到wwwroot/uploads,限制扩展名(jpg/jpeg/png/gif/bmp/webp)与 5MB,返回{ path }。
3.14 SignalR 登录 Hub —— LoginHub(路由 /loginhub)
对应文件:UserService/Hubs/LoginHub.cs。仅 WebSockets 传输。
- 服务端方法:
Bind(userId)(绑定登录态、踢旧连接、按需触发旧房间结算)、DismissPendingRoom(userId)(CAP 发布Topic_0524_DismissPendingRoom)。 - 向前端推送的事件:
AccountKicked、KickToMainPage、LoginSettlementCompleted、NewEmail、BackpackUpdated、LevelChanged、AssetUpdated、ChangeConfig、Broadcast、KillAnnouncement。
四、项目结构与技术要点
4.1 四个 csproj
| 项目 | 路径 | 类型 | 关键 NuGet | 关键项目引用 |
|---|---|---|---|---|
| UserHost | UserSrc/UserHost/UserHost.csproj |
Web(进程入口,Exe) | NewtonsoftJson 8.0.24、SignalR.StackExchangeRedis 8.0.0、NLog.Web.AspNetCore 6.1.2、Autofac 8.3.0、Autofac.Extensions.DependencyInjection 10.0.0、AutoMapper 14.0.0、DotNetCore.CAP 8.3.4(含 Dashboard/PostgreSql/RabbitMQ) | ScheduledService、RedisService、UserApi、UserService、SharpAbp.Infrastructure.Api |
| UserApi | UserSrc/UserApi/UserApi.csproj |
类库(OutputType=Exe,Program.cs 为占位) |
AutoMapper 14.0.0、Microsoft.AspNetCore.Mvc.Core 2.3.0 | CommonService、CommonInfrastructure、Common、SharpAbp.Infrastructure.Api、RedisService、UserDomain、UserService、AdminSrc/AdminDomain |
| UserService | UserSrc/UserService/UserService.csproj |
类库 | AutoMapper 14.0.0、Cronos 0.8.4、DotNetCore.CAP 8.3.4、MongoDB.Driver 3.6.0 | AdminDomain、CommonDomain、CommonInfrastructure、JWTHelper、MongoRepository、RedisHelper、ScheduledService、UserDomain |
| UserDomain | UserSrc/UserDomain/UserDomain.csproj |
类库 | DotNetCore.CAP 8.3.4、MongoDB.Bson/Driver 3.6.0 | CommonDomain、MongoRepository |
依赖关系:UserHost → (UserApi → (CommonService,UserService,UserDomain,AdminDomain,RedisService,Common,CommonInfrastructure),UserService → UserDomain/CommonDomain/…) ;UserDomain 仅依赖 CommonDomain + MongoRepository。
UserService.csproj 特殊点:通过 <Compile Remove="User\LotteryService.cs" /> 排除该文件编译(同时 <None Include> 保留为内容)。
4.2 进程入口要点(UserHost/Program.cs)
- 设置环境变量
SERVICE_NAME、INSTANCE_ID(供日志/实例标识)。 - MVC:
AddControllers().AddApplicationPart(typeof(AssemblyMarker).Assembly)—— 显式把 UserApi 程序集的 Controller 暴露给本进程,并AddControllersAsServices();JSON 日期格式yyyy-MM-dd HH:mm:ss(Newtonsoft)。 - 配置:加载
Config/system.json;绑定MongoDbSettings;注册IHttpContextAccessor、IRequestApi、AutoMapper(typeof(AutoMapperConfig))、WXBaseHelper。 - 健康检查:
/health(自定义 JSON 输出)。 - SignalR:
AddSignalR+.AddJsonProtocol().AddStackExchangeRedis(builder.Configuration["RedisConfig:ConnectionString"]),ChannelPrefix = "GameHub";MaximumReceiveMessageSize=64KB、KeepAliveInterval=15s、ClientTimeoutInterval=70s。 - CORS 策略
"Cors"(允许任意来源、任意头/方法、允许凭据)。 - JWT:
AddCustomJwt(JWTHelper);Redis:AddRedisCache(RedisHelper);CAP:本模块扩展AddCap(UserHost/Extension/CapExtension.cs)。 - 定时任务:
AddCronJob<EveryDayTask>(0 0 0 * * *)、AddCronJob<RankingRewardJob>(0 0 0 * * *),时区本地。 - Autofac:
UseServiceProviderFactory(new AutofacServiceProviderFactory())+RegisterModule<AutofacModule>()。 - 管道:
UseDeveloperExceptionPage(Development)→UseCors("Cors")→UseRouting→MapHub<LoginHub>("/loginhub", WebSockets)→UseAuthentication→UseAuthorization→UseApiLogging→MapControllers→UseGlobalExceptionHandler→MapHealthChecks("/health")。
4.3 SignalR / Redis / CAP 配置
- SignalR 背板:Redis(
RedisConfig:ConnectionString,defaultDatabase=2),频道前缀GameHub。 - Redis:
RedisConfig(Host/Port/Password/Database=1/ConnectionString)。IRedisService提供验证码、登录态(RedisUserCid)、房间(GameRoom)、待回房(pending fish/chess room)、IncrBy等能力(实现位于RedisService项目)。 - CAP(
UserHost/Extension/CapExtension.cs):x.UseDashboard();消息代理UseRabbitMQ(Host/UserName/Password/VirtualHost 来自CapConfig,ExchangeName = "cap.exchange");存储UsePostgreSql(CapConfig:PGLogHost,schemapublic)。- 成功消息保留 7 天、失败重试 5 次/间隔 10s,
FailedThresholdCallback记录失败信息。 - 注册订阅者:
UserMQService、AdminNotifySubscriber、LoginResultSubscriber、ConfigChangedSubscriber、KillAnnounceSubscriber、AssetSyncFrontendSubscriber、CommonService.Lottery.LotteryPrizeHandler、CommonService.Lottery.LotteryPrizeSubscriber。
4.4 DI 注册位置
- 约定式注册:
UserHost/Middleware/AutofacModule.cs(继承SharpAbp.Infrastructure.Api.Autofac.ApplicationModule)。GetServiceAssemblies()扫描三个程序集:UserService(接口程序集,typeof(IUserService).Assembly)、UserService.User.UserService所在程序集、CommonService(typeof(ApiLogService).Assembly)。即IUserService/ITaskService/各 Service 由其接口自动匹配实现注入。 - 显式注册:
Program.cs(见 4.2)与CapExtension.cs(见 4.3)。
4.5 中间件
AutofacModule(DI)。ApiLoggingMiddleware(UseApiLogging):只记录以/api开头且非 OPTIONS 的请求,写 MongoDBApiLog(请求/响应体脱敏Data、耗时、Token、设备/来源/IP/Sign 等头信息)。
4.6 配置与端口(观察到的实际值,注意不一致)
UserHost/appsettings.json、appsettings.Development.json:仅日志级别与AllowedHosts。UserHost/Config/system.json:"urls": "http://*:8001";JwtConfig(SecretKey、关闭 Issuer/Audience/Lifetime 校验等);ConnectionStrings.PgSqlConnection、CapConfig(RabbitMQ +PGLogHost);RedisConfig(Database=1,ConnectionStringdefaultDatabase=2);MongoDbSettings(mongodb://localhost:27017);WXConfig(微信 AppId/Secret/Url)。
UserHost/Properties/launchSettings.json:httpprofile 为http://localhost:8001;另有httpsprofile(https://localhost:7000;http://localhost:5017)。UserHost/docker-compose.yaml:容器0524user,端口映射5245:80。
⚠️ 存在端口信息不一致:平台总览称网关 8001、UserHost 5245;而
Config/system.json与 launchSettings 的 http profile 均写成 8001。文档据实记录,不作判断。
五、代码目录说明(完整目录树)
UserSrc/
├── UserApi/ # HTTP 接口层(Controller 程序集,被 UserHost 通过 ApplicationPart 加载)
│ ├── UserApi.csproj # net8.0;引用 CommonService/UserService/UserDomain/AdminDomain/RedisService 等
│ ├── Program.cs # 占位控制台入口(仅 "Hello, World!"),真实入口在 UserHost
│ ├── AssemblyMarker.cs # 空类,供 UserHost 定位 UserApi 程序集(AddApplicationPart)
│ ├── Login/
│ │ ├── LoginController.cs # 注册/登录/验证码/改密/时间接口(api/Login)
│ │ └── DateTimeResponse.cs # 服务器时间响应模型
│ ├── Hall/
│ │ └── HallController.cs # 大厅:保险箱/道具/商城/签到/炮台/战令/任务/排行榜(api/Hall)
│ ├── User/
│ │ ├── UserController.cs # 用户资料/资产/邮件/返利(api/User)
│ │ ├── FeedbackController.cs # 用户反馈(api/Feedback)
│ │ └── ImageUploadController.cs # 图片上传(api/ImageUpload)
│ ├── Lottery/
│ │ └── LotteryController.cs # 抽奖/彩蛋(api/Lottery)
│ ├── ScratchCard/
│ │ └── ScratchCardController.cs # 刮刮卡(api/ScratchCard)
│ ├── SummonCard/
│ │ └── SummonCardController.cs # 召唤卡(api/SummonCard)
│ ├── Notices/
│ │ └── NoticeController.cs # 公告(api/Notice)
│ ├── Faq/
│ │ └── FaqController.cs # FAQ(注意前缀为 adminapi/Faq)
│ ├── GameConfigs/
│ │ ├── GameConfigController.cs # 游戏配置(api/GameConfig)
│ │ └── ActivityConfigController.cs # 活动配置(api/ActivityConfig)
│ ├── BeautifulNumber/
│ │ └── BeautifulNumberController.cs # 靓号(api/BeautifulNumber)
│ └── Dict/
│ └── DictController.cs # 系统字典(api/Dict,读 SystemDic)
│
├── UserService/ # 业务服务层
│ ├── UserService.csproj # net8.0;排除 User\LotteryService.cs 编译
│ ├── AutoMapperConfig.cs # AutoMapper 映射:UserEntity→UserToken、BaseProduct(Count)、AddKillFishLogCapParam→KillFishLog 等
│ ├── User/
│ │ ├── IUserService.cs # 用户服务接口(注册登录/资产/邮件/保险箱/商城/返利等)
│ │ ├── UserService.cs # 用户服务实现(本模块核心,2000+ 行)
│ │ ├── IUserMQService.cs / UserMQService.cs # CAP 订阅:任务完成/资产变更/金币结算/击杀鱼日志
│ │ ├── IUserLoginLogService.cs / UserLoginLogService.cs # 登录日志查询
│ │ ├── IUserFeedbackService.cs / UserFeedbackService.cs # 反馈服务
│ │ ├── ILotteryService.cs # 抽奖接口定义(namespace UserService)
│ │ ├── LotteryService.cs # 【已排除编译】遗留文件(namespace CommonService)
│ │ ├── Param/ # 服务入参
│ │ │ ├── UserAssetParam.cs # 资产变更参数(核心)
│ │ │ ├── UpdateUserDataParam.cs
│ │ │ ├── SendEmailParam.cs
│ │ │ ├── RegisterUserWeiXinParam.cs
│ │ │ ├── RegisterUserParam.cs
│ │ │ ├── GetUserRewardListParam.cs
│ │ │ ├── GetEmailPageParam.cs
│ │ │ ├── GameCoinsSettlementParam.cs
│ │ │ ├── AddUserPropParam.cs
│ │ │ └── AddKillFishLogCapParam.cs
│ │ └── Response/
│ │ ├── UserToken.cs # 登录令牌响应(继承 UserEntity + Token)
│ │ ├── RewardEmailResponse.cs
│ │ └── RankingResponse.cs # 排行榜响应
│ ├── Tasks/
│ │ ├── ITaskService.cs / TaskService.cs # 任务:日/时任务生成、完成、领奖、战令经验
│ │ └── Param/
│ │ ├── GiftResponse.cs # 礼包响应(Gold/Diamond/Exp/Product)
│ │ ├── GetUserTaskListParam.cs
│ │ ├── GetTaskListParam.cs
│ │ └── CompletedTaskParam.cs # CAP 任务完成消息体
│ ├── BattleOrder/
│ │ ├── IBattleOrderService.cs / BattleOrderService.cs # 战令:等级/经验/领奖/购买等级/购买进阶
│ ├── ScratchCard/
│ │ ├── IScratchCardService.cs / ScratchCardService.cs # 刮刮卡抽奖(道具 40005)
│ ├── SummonCard/
│ │ ├── ISummonCardService.cs / SummonCardService.cs # 召唤卡(道具 40006)
│ ├── Notices/
│ │ ├── INoticeService.cs / NoticeService.cs # 公告
│ │ ├── IFaqService.cs / FaqService.cs # FAQ 分类/问题
│ │ └── Param/
│ │ ├── GetNoticeListParam.cs
│ │ ├── AddNoticeParam.cs
│ │ └── UpdateNoticeParam.cs
│ ├── GameConfigs/
│ │ ├── IGameConfigService.cs / GameConfigService.cs # 游戏配置(Redis 缓存 + Mongo)
│ │ └── IActivityConfigService.cs / ActivityConfigService.cs # 活动配置(Redis 缓存 + Mongo,含过期自动停)
│ ├── BeautifulNumber/
│ │ ├── IBeautifulNumberService.cs / BeautifulNumberService.cs # 靓号查询/购买/校验
│ ├── ImageUpload/
│ │ ├── IImageUploadService.cs / ImageUploadService.cs # 图片上传(限制类型/大小)
│ ├── Hubs/
│ │ ├── LoginHub.cs # SignalR Hub(路由 /loginhub)
│ │ ├── LoginResultSubscriber.cs # 订阅「登录结果通知」→ 完成等待 + 推送前端
│ │ ├── LoginSettlementWaiter.cs # 登录结算等待器(内存 TaskCompletionSource)
│ │ ├── AdminNotifySubscriber.cs # 订阅 BackgroundOperation.NotifyUser → 前端推送
│ │ ├── ConfigChangedSubscriber.cs # 订阅「配置变更」→ 全员 ChangeConfig
│ │ ├── KillAnnounceSubscriber.cs # 订阅「全局击杀公告」→ 调 UserService 广播
│ │ └── AssetSyncFrontendSubscriber.cs # 订阅「用户资产同步前端」→ 前端 AssetUpdated
│ ├── Jobs/
│ │ ├── EveryDayTask.cs # 每日 0 点任务(Redis 分布式锁 lock:everyday)
│ │ ├── EveryHourTask.cs # 每小时任务(锁 lock:everyhour;注:Program.cs 未注册该 Job)
│ │ └── RankingRewardJob.cs # 排行榜奖励 Job(锁 lock:rankingreward)
│ └── Response/
│ └── BattleOrderResponse.cs # 战令相关响应模型(Hall 使用)
│
├── UserDomain/ # 领域模型(被 RedisService/CommonService/AdminService 等引用)
│ ├── UserDomain.csproj # 声明了空的 Response\ 文件夹(无 .cs)
│ ├── Entity/
│ │ ├── UserEntity.cs # 用户主实体(集合 user):BaseInfo/Assets/Props/保险箱/VIP/返利等 + Init/LevelVerify/VipLevelVerify
│ │ ├── Order.cs # 订单(集合 order)
│ │ ├── Notice.cs # 公告(集合 notice)
│ │ ├── LotteryEntities.cs # 抽奖记录/用户抽奖状态(lottery_record、lottery_user_status)
│ │ ├── KillFishLog.cs # 击杀鱼日志(按月分表 kill_fish_log{yyyyMMdd},Fish 库)
│ │ ├── UserBattleOrder.cs # 用户战令(集合 user_battle_order)
│ │ ├── ScratchCardRecord.cs # 刮刮卡中奖记录
│ │ ├── UserFeedback.cs # 用户反馈
│ │ ├── UserTask.cs # 用户任务
│ │ ├── UserReward.cs # 资产变动流水(集合 user_reward)
│ │ ├── UserLoginLog.cs # 登录日志
│ │ └── UserEmail.cs # 用户邮件
│ ├── Enum/
│ │ ├── UserAssetChangeTypeEnum.cs # 增加=1 / 减少=2
│ │ ├── RewardSource.cs # 资产来源枚举(邮件/救济金/保险箱/商城/签到/充值/战令/活动…99 后台操作)
│ │ └── BattleOrderType.cs # 战令类型:普通=1/豪华=2/至尊=3
│ └── Param/
│ ├── UserLoginLogQueryParam.cs
│ └── FeedbackParam.cs # AddFeedbackParam/FeedbackQueryParam/ReplyFeedbackParam
│
└── UserHost/ # 进程入口(Web)
├── UserHost.csproj # net8.0 Web;链接 nlog.config
├── UserHost.csproj.user # 本地用户配置(IDE)
├── Program.cs # 启动装配(见 4.2)
├── appsettings.json / appsettings.Development.json # 基础配置(日志/AllowedHosts)
├── docker-compose.yaml # 容器 0524user,映射 5245:80
├── .dockerignore
├── Properties/launchSettings.json # http: localhost:8001;https: 7000/5017
├── Config/system.json # urls/JWT/PG/CAP/Redis/Mongo/WX 配置
├── Extension/CapExtension.cs # CAP 配置与订阅者注册
├── Middleware/
│ ├── AutofacModule.cs # Autofac 约定式 DI
│ └── ApiLoggingMiddleware.cs # /api 请求日志中间件
└── wwwroot/
├── index.html
└── uploads/ # 静态图片(40001~40301.png 等)
关于根目录 UserDomain/ 遗留文件夹(重要,勿混淆)
仓库根目录还存在一个同名但不同的文件夹 UserDomain/(注意不是 UserSrc/UserDomain/):
- 路径:
UserDomain/Response/BattleOrderResponse.cs - 内容:仅一个
namespace UserDomain.Response的文件,内含BattleOrderResponse/UserBattleOrderInfo/BattleOrderConfigInfo/BattleOrderLevelInfo/BattleOrderAdvanceInfo/ReceiveBattleOrderRewardResponse/BattleOrderRewardItem/BuyBattleOrderLevelResponse/BuyBattleOrderAdvanceResponse等类。 - 特征:该文件夹没有
.csproj,不属于任何项目,也不被解决方案/其它项目引用(历史遗留)。 - 与正式项目的区别:
- 本模块正式领域项目是
UserSrc/UserDomain/UserDomain.csproj(集合实体/枚举/Param,其 csproj 里声明的Response\文件夹为空)。 - 战令响应模型实际使用的定义在
UserSrc/UserService/Response/BattleOrderResponse.cs(namespace UserService.Response,被HallController引用)。 - 根目录
UserDomain/Response/BattleOrderResponse.cs是被搬迁遗留下的副本,含若干正式项目中已不存在的额外类(如BattleOrderRewardItem、ReceiveBattleOrderRewardResponse的不同字段)。
- 本模块正式领域项目是
结论:讨论「UserDomain」时请以 UserSrc/UserDomain/(有 csproj 的正式项目)为准;根目录 UserDomain/ 为无害的历史遗留,可直接忽略。
六、关键文件索引
| 文件相对路径 | 职责 |
|---|---|
UserSrc/UserHost/Program.cs |
进程入口与装配(MVC/SignalR/Redis/JWT/CAP/Autofac/健康检查/管道) |
UserSrc/UserHost/Extension/CapExtension.cs |
CAP(RabbitMQ + PostgreSQL)配置与订阅者注册 |
UserSrc/UserHost/Middleware/AutofacModule.cs |
Autofac 约定式 DI(扫描 UserService/CommonService 程序集) |
UserSrc/UserHost/Middleware/ApiLoggingMiddleware.cs |
/api 请求响应日志(写入 ApiLog) |
UserSrc/UserHost/Config/system.json |
端口/JWT/PG/CAP/Redis/Mongo/微信 配置 |
UserSrc/UserApi/AssemblyMarker.cs |
供 UserHost 定位并加载 UserApi 程序集 |
UserSrc/UserApi/Login/LoginController.cs |
注册登录、验证码、改密、服务器时间 |
UserSrc/UserApi/Hall/HallController.cs |
大厅核心接口(保险箱/资产/商城/签到/战令/任务/排行榜) |
UserSrc/UserApi/User/UserController.cs |
资料/资产/邮件/返利 |
UserSrc/UserApi/User/FeedbackController.cs |
用户反馈 |
UserSrc/UserApi/User/ImageUploadController.cs |
图片上传 |
UserSrc/UserApi/Lottery/LotteryController.cs |
抽奖(彩蛋) |
UserSrc/UserApi/ScratchCard/ScratchCardController.cs |
刮刮卡 |
UserSrc/UserApi/SummonCard/SummonCardController.cs |
召唤卡 |
UserSrc/UserApi/Notices/NoticeController.cs |
公告 |
UserSrc/UserApi/Faq/FaqController.cs |
FAQ(前缀 adminapi/Faq) |
UserSrc/UserApi/GameConfigs/GameConfigController.cs |
游戏配置读取 |
UserSrc/UserApi/GameConfigs/ActivityConfigController.cs |
活动配置读取 |
UserSrc/UserApi/BeautifulNumber/BeautifulNumberController.cs |
靓号 |
UserSrc/UserApi/Dict/DictController.cs |
系统字典 |
UserSrc/UserService/User/UserService.cs |
本模块核心业务实现(注册登录/资产/商城/邮件/保险箱/返利/排行榜) |
UserSrc/UserService/User/IUserService.cs |
用户服务接口 |
UserSrc/UserService/User/UserMQService.cs |
CAP 订阅(任务/资产/结算/击杀鱼日志) |
UserSrc/UserService/User/UserFeedbackService.cs |
反馈服务实现 |
UserSrc/UserService/User/UserLoginLogService.cs |
登录日志服务 |
UserSrc/UserService/Tasks/TaskService.cs |
任务与战令经验 |
UserSrc/UserService/BattleOrder/BattleOrderService.cs |
战令业务 |
UserSrc/UserService/ScratchCard/ScratchCardService.cs |
刮刮卡业务 |
UserSrc/UserService/SummonCard/SummonCardService.cs |
召唤卡业务 |
UserSrc/UserService/Notices/NoticeService.cs |
公告服务 |
UserSrc/UserService/Notices/FaqService.cs |
FAQ 服务 |
UserSrc/UserService/GameConfigs/GameConfigService.cs |
游戏配置(缓存策略) |
UserSrc/UserService/GameConfigs/ActivityConfigService.cs |
活动配置(缓存策略) |
UserSrc/UserService/BeautifulNumber/BeautifulNumberService.cs |
靓号服务 |
UserSrc/UserService/ImageUpload/ImageUploadService.cs |
图片上传服务 |
UserSrc/UserService/Hubs/LoginHub.cs |
SignalR 登录 Hub(/loginhub) |
UserSrc/UserService/Hubs/LoginResultSubscriber.cs |
登录结算结果订阅并推送前端 |
UserSrc/UserService/Hubs/LoginSettlementWaiter.cs |
登录结算等待器 |
UserSrc/UserService/Hubs/AdminNotifySubscriber.cs |
后台通知 CAP 订阅 → 前端推送 |
UserSrc/UserService/Hubs/ConfigChangedSubscriber.cs |
配置变更 CAP 订阅 → 全员刷新 |
UserSrc/UserService/Hubs/KillAnnounceSubscriber.cs |
击杀公告 CAP 订阅 |
UserSrc/UserService/Hubs/AssetSyncFrontendSubscriber.cs |
资产同步前端 CAP 订阅 |
UserSrc/UserService/Jobs/EveryDayTask.cs |
每日 0 点定时任务 |
UserSrc/UserService/Jobs/RankingRewardJob.cs |
排行榜奖励定时任务 |
UserSrc/UserService/AutoMapperConfig.cs |
AutoMapper 映射配置 |
UserSrc/UserDomain/Entity/UserEntity.cs |
用户主实体及内嵌模型(Assets/Props/PlayerFactor/StaticInfo 等) |
UserSrc/UserDomain/Entity/UserReward.cs |
资产变动流水实体 |
UserSrc/UserDomain/Enum/RewardSource.cs |
资产来源枚举(流水用) |
UserSrc/UserDomain/Param/FeedbackParam.cs |
反馈相关入参 |
UserDomain/Response/BattleOrderResponse.cs |
根目录遗留副本(无 csproj,未使用) |
七、与其他模块的交互
7.1 CAP / RabbitMQ 消息主题
主题常量定义于 CommonDomain/TopicKeys.cs(前缀统一为 Topic_0524_)。本模块涉及:
本模块发布(Publish)
| 主题(常量 → 实际值) | 发布位置 | 说明 |
|---|---|---|
TopicKeys.登录绑定 → Topic_0524_LoginBind |
LoginHub.Bind |
玩家重新登录后请求旧房间结算,携带 LoginBindMessage{UserId,OperationId} |
TopicKeys.拒绝回房 → Topic_0524_DismissPendingRoom |
LoginHub.DismissPendingRoom |
放弃回旧房间 |
TopicKeys.任务完成 → Topic_0524_CompletedTask |
UserService.LoginToken(登录任务)、UserService.BuyDiamondPayCallBack(充值任务) |
上报任务进度 |
TopicKeys.用户资产变更 → Topic_0524_UserAssetsChanged |
BattleOrderService(购买战令等级/进阶) |
触发资产扣减 |
TopicKeys.用户资产同步前端 → Topic_0524_UserAssetSyncFrontend |
UserService.BuyGold、UserService.GameCoinsSettlement、UserService.UpdateAssets |
资产变更通知前端 |
TopicKeys.召唤卡出鱼 → Topic_0524_SummonCardFish |
SummonCardService.Use |
通知鱼房生成 Boss/黄金鱼 |
"BackgroundOperation.NotifyUser"(字符串) |
UserService.UpdateAssets(升级 level_change) |
后台→前端通知 |
"Lottery.DrawPrize"(字符串,在 CommonService/LotteryService.cs) |
抽奖发奖 | 抽奖中奖事件 |
本模块订阅(Subscribe)
| 主题 | 订阅者 | 处理 |
|---|---|---|
Topic_0524_登录结果通知(TopicKeys.登录结果通知) |
LoginResultSubscriber |
结束等待、向前端推 LoginSettlementCompleted |
Topic_0524_配置变更(TopicKeys.配置变更) |
ConfigChangedSubscriber |
全员推 ChangeConfig(ActivityConfig=1/GameConfig=2) |
Topic_0524_全局击杀公告 |
KillAnnounceSubscriber |
调 UserService.SendKillAnnouncement 全服推 KillAnnouncement |
Topic_0524_用户资产同步前端 |
AssetSyncFrontendSubscriber |
向前端推 AssetUpdated |
BackgroundOperation.NotifyUser |
AdminNotifySubscriber |
new_email/backpack_*/level_change/资产 多类前端推送 |
Topic_0524_任务完成 |
UserMQService.CompletedTask |
任务计数/完成 |
Topic_0524_用户资产变更 |
UserMQService.UserAssetChange |
调 UserService.UpdateAssets |
Topic_0524_游戏金币结算 |
UserMQService.GameCoinsSettlement |
调 UserService.GameCoinsSettlement |
Topic_0524_击杀鱼日志 |
UserMQService.KillFishLog |
映射写入 KillFishLog |
"test" |
UserMQService.Test |
占位 |
另外,
CapExtension还注册了CommonService.Lottery.LotteryPrizeSubscriber/LotteryPrizeHandler(抽奖发奖处理,位于 CommonService 项目)。
7.2 Redis Key / 登录态 / 验证码
通过 IRedisService(RedisService 项目)访问,本模块使用到:
- 验证码:
RedisKey.VerificationCode({ServicePrefix}:verification_code:{0},按手机号),写入 TTL 5 分钟(RedisService.SetVerificationCode)。登录/改密/绑手机/重置保险箱密码均校验它。当前SendMobileCode固定下发000000。 - 登录态(RedisUserCid):
GetRedisUserCId/SetRedisUserCId(含LoginCId、CId、RoomId)、SetLoginUserId/GetLoginUserId(cid→userId)/RemoveLoginUserId、RemoveUserId。用于 LoginHub 绑定/踢线、判断在线。 - 待回房:
GetPendingFishRoomId、GetPendingChessRoomId(登录时判断玩家是否需回到捕鱼/象棋房间)。 - 房间:
GetGameRoom/SetGameRoom(读取/更新房间玩家,用于旧房间结算与召唤卡校验)。 - 分布式锁:
IDistributedLock.TryExecuteAsync。注册用RedisKey.DistributedLockPrefix + "user:register:mobile:{mobile}"(RedisKey.DistributedLockPrefix={ServicePrefix}:lock:);资产/保险箱用user:asset:update:{userId}、user:safebox:{userId};Job 用lock:everyday/lock:everyhour/lock:rankingreward。 - 捕鱼返利消费:
fishing:consume:{userId}:{yyyyMMdd}(IncrBy累加,领取时刷入UserEntity.FishingReturn)。 - 配置缓存:
GetGameConfig/SetGameConfig、GetActivityConfig/SetActivityConfig、GetFishingKillConfig/SetFishingKillConfig、SetSystemGoldDay。
7.3 HTTP 调用(外部)
- 微信:
LoginController通过WXBaseHelper调用微信接口(WXConfig.Url = https://api.weixin.qq.com)——GetAccessToken、按js_code换取会话(GetAccessTokenByCode)。 - 模块内未见对其余外部 HTTP 服务的直接调用。
7.4 共享实体 / 项目引用(跨模块耦合点)
UserSrc/UserDomain(UserDomain.csproj)被以下项目引用:RedisService、CommonService、AdminService、UserService、UserApi。其Entity/Enum/Param是跨模块共享的领域模型(如UserReward、LotteryRecord、KillFishLog、UserLoginLog、UserFeedback等)。UserApi引用AdminSrc/AdminDomain(靓号BeautifulNumberConfig、字典SystemDic等)与CommonService(抽奖实现、ApiLogService)。UserService引用CommonDomain(GameConfig/ActivityConfig/FaqCategory/FaqQuestion/GameTask/GameTypeEnum/TopicKeys/BaseProduct等)与AdminDomain。
7.5 与棋牌/捕鱼服务的登录绑定流程(涉及)
- 玩家连接
/loginhub并调用Bind(userId);LoginHub写入/更新 Redis 登录态(LoginCId/CId),并踢掉旧连接(AccountKicked、KickToMainPage,必要时Abort旧连接)。 - 若 Redis 中存在该用户的房间(
RoomId)或 pending 捕鱼/象棋房间,则生成OperationId,向Topic_0524_LoginBind发布LoginBindMessage,并在LoginSettlementWaiter上等待(超时 15s)。 - 对应游戏服务处理旧房间并回发
Topic_0524_LoginBindResult;LoginResultSubscriber收到后LoginSettlementWaiter.Complete,并通过 Hub 向该用户组推LoginSettlementCompleted{roomId,success}。 - 玩家也可调用
DismissPendingRoom,发Topic_0524_DismissPendingRoom放弃回旧房间。 - 另一条路径:HTTP 登录(
UserService.Login/LoginWx/LoginByPassword)成功后调用HandleLoginRoomSettlementAsync,若玩家仍在房间内,则用GameCoinsSettlement对房间内金币变化做落库结算并移出房间、清空 Redis 房间态。
补充:
UserService.GameCoinsSettlement也作为 CAP 订阅(Topic_0524_GameCoinsSettlement)被UserMQService调用,用于游戏服务的金币结算入账,并回推Topic_0524_UserAssetSyncFrontend与 SignalRAssetUpdated。