28 KiB
客服模块(CustomerSrc)—— 功能与代码目录文档
本文档为「客服模块(CustomerSrc)」的完整上下文说明,供其他对话 / 开发者理解本模块时使用。所有内容均基于
d:\BUYUHouDuanNet\BuYu\CustomerSrc\下的实际源代码整理,路径统一以解决方案根目录d:\BUYUHouDuanNet\BuYu为基准使用相对路径。
一、平台背景与模块位置
本模块是「捕鱼 + 棋牌游戏运营平台后端」的一部分。平台整体技术栈与运行形态如下:
- 解决方案:
Template0524.sln - 技术栈:.NET 8 + MongoDB + Redis + RabbitMQ(通过 DotNetCore.CAP 集成)+ SignalR + Ocelot 网关 + NLog + Autofac + AutoMapper
- 网关(Ocelot):监听
http://localhost:8001,按前缀将请求反向代理到各业务进程:/adminapi→ AdminHost(5241)/api、/loginhub→ UserHost(5245)/customerapi、/customerHub→ CustomerHost(5247,本模块)/chess、/chessgamehub→ ChessGameHost(5242)/fishingroomhub→ FishRoomHost(5244)/gamehub→ FishGameHost(5248)
本模块(客服 / 客服 IM)在解决方案中的位置:
- 源码根目录:
CustomerSrc/,解决方案中作为独立解决方案文件夹CustomerSrc存在(Template0524.sln第 68~80 行)。 - 进程入口:
CustomerSrc/CustomerHost,对外监听端口在Gateway/ocelot.json中被指向 5247(DownstreamPathTemplate为/customerapi/{everything}与/customerHub/{everything},下游 Host 均为localhost:5247)。 - 对外路由前缀:
/customerapi(HTTP 接口)与/customerHub(SignalR 长连接 Hub)。
补充说明(与代码核对):
CustomerSrc/CustomerHost/docker-compose.yaml将容器端口5247:80映射,即容器内在 80 端口提供服务、宿主机映射为 5247;CustomerSrc/CustomerHost/Config/system.json中urls为http://*:8006;CustomerSrc/CustomerHost/Properties/launchSettings.json中开发调试地址为https://localhost:38200;http://localhost:38201。三者为不同运行方式下的监听配置,网关实际指向的是 5247。
二、模块简介
2.1 定位与职责
CustomerSrc 是一个客服 IM(即时会话)模块,为游戏平台的用户与人工客服之间提供一对一的在线聊天能力。核心职责:
- 客服在线状态管理:客服上线 / 下线,并把在线客服写入 Redis 列表,供用户发起会话时选择。
- 会话(Conversation)生命周期管理:用户发起会话、按在线客服负载分配客服、结束会话。
- 消息(Message)收发与存储:以 MongoDB 持久化每条消息,并通过 SignalR 实时推送给会话组。
- 客服工作台支持:客服查看自己的会话列表、历史消息、未读数、标记已读。
- 图片上传:为聊天消息提供图片上传能力。
2.2 业务角色与关键约定
- 用户(玩家):会话发起方,
SenderType = 1。 - 客服:会话接待方,
SenderType = 2(由后台 Admin 模块创建客服账号并维护,见第七节)。 - 会话状态
Status:1= 进行中,2= 已结束(EndConversation会置为 2 并写入EndTime)。 - 消息内容类型
ContentType:整型标识(1 文本 / 2 图片等由前端约定,代码中仅透传存储,不做枚举约束)。 - 在线标记:在线客服 ID 列表存放于 Redis 列表键
customer-service:online(由RedisKey.CUSTOMER_ONLINE_KEY→RedisKeyGenerator.CustomerKey("online")生成,前缀映射customer→customer-service)。
2.3 核心业务流程(以代码为准)
(一)客服上线
- 后台把某用户的
CustomerEntity加入客服集合(Admin 模块负责,见第七节)。 - 客服端调用
POST /customerapi/customer/status,status = 1;服务端UpdateCustomerStatus更新 / 新建customer记录,并将该用户 ID 加入 Redis 在线列表customer-service:online;status != 1时从列表移除。 - 前端建立 SignalR 连接
/customerHub,OnConnectedAsync会依据 JWT 中的uid声明把连接加入分组customer_{uid},客服由此接收分配给自己的新会话事件。
(二)用户发起会话
- 用户(或前端)调用
POST /customerapi/customer/start,或通过 Hub 方法StartConversation/SendMessage(当conversationId为空且SenderType == 1时自动发起)。 - 服务端
StartConversation读取 Redis 在线客服列表 → 对每位在线客服统计其「进行中会话数」(Status == 1)→ 选取会话数最少的客服(负载均衡)→ 生成ConversationEntity并落库;若无客服在线则返回「暂无客服在线」。 - Hub 侧在会话创建成功后,向该客服所在分组
customer_{CustomerId}广播事件OnNewConversation,并把发起者连接加入会话分组。
(三)收发消息
- 客户端调用
POST /customerapi/customer/message,或通过 Hub 方法SendMessage(...)。 - 服务端
SendMessage生成MessageEntity(含会话 ID、发送者类型 / ID / 名称 / 头像、内容类型、内容、时间)写入 MongoDB。 - Hub 侧写入成功后,向会话分组
conversationId广播OnMessageReceived事件(携带GuId、ConversationId、SenderType、SenderId、SenderName、SenderAvatar、ContentType、Content、CreateTime)。
(四)客服接待与收尾
- 客服调用
GET /customerapi/customer/conversations?customerId=xxx获取自己的会话列表(含最后一条消息、未读数、消息明细)。 - 进入会话后调用
GET /customerapi/customer/messages/{conversationId}拉取历史消息。 - 客服调用
POST /customerapi/customer/mark-read标记已读(更新该用户会话的LastReadTime)。 - 会话结束后调用
POST /customerapi/customer/end,Status置 2、写入EndTime。
(五)用户侧查询
GET /customerapi/customer/my-conversations:从 JWT 取当前登录用户uid,返回该用户最近 1 条会话(含消息与未读数)。
三、业务功能清单
3.1 HTTP 接口 —— CustomerController
路由前缀:customerapi/[controller],即实际路径 /customerapi/customer/...。
控制器继承 BaseController(CommonInfrastructure),返回统一响应体(BaseResponse / ListResponse)。
| 方法 | 路由(相对 /customerapi/customer) |
请求参数 | 用途 |
|---|---|---|---|
| POST | /start |
StartConversationParam { UserId, UserName } |
用户发起会话,返回 ConversationEntity;无在线客服时返回失败 |
| POST | /message |
SendMessageParam { ConversationId, SenderType, SenderId, SenderName, SenderAvatar, ContentType, Content } |
发送一条消息并落库 |
| GET | /messages/{conversationId} |
路径参数 conversationId |
获取某会话的全部历史消息(按时间升序) |
| GET | /conversations |
查询参数 customerId(可空) |
客服获取会话列表;为空时返回全部会话 |
| GET | /my-conversations |
无(取 JWT uid) |
当前用户最近一条会话(含 Messages、LastMessage、UnreadCount) |
| POST | /end |
EndConversationParam { ConversationId } |
结束会话(Status=2,写 EndTime) |
| GET | /online |
无 | 获取当前在线客服列表(CustomerEntity) |
| POST | /status |
UpdateStatusParam { UserId, Status } |
客服上线 / 下线,维护 Redis 在线列表 |
| POST | /mark-read |
MarkReadParam { CustomerId, UserId } |
客服标记会话已读(更新 LastReadTime) |
| GET | /chatlog/{conversationId} |
路径参数 conversationId |
获取会话聊天记录(内部复用 GetMessages) |
3.2 HTTP 接口 —— ImageUploadController
路由前缀:customerapi/[controller],实际路径 /customerapi/imageupload/upload。
| 方法 | 路由 | 用途 |
|---|---|---|
| POST | /customerapi/imageupload/upload |
接收 IFormFile file,以 GUID 重命名后保存到 wwwroot/uploads/,返回 { Path = "uploads/{guid}{ext}" } |
3.3 SignalR Hub —— CustomerHub
连接地址:/customerHub(仅允许 WebSockets 传输,见 Program.cs 的 MapHub 配置)。
客户端 → 服务端可调用方法:
| 方法 | 参数 | 作用 |
|---|---|---|
JoinConversation |
conversationId |
把当前连接加入会话分组 conversationId |
LeaveConversation |
conversationId |
退出会话分组 |
JoinCustomerQueue |
customerId |
加入分组 customer_{customerId}(客服队列) |
LeaveCustomerQueue |
customerId |
退出分组 customer_{customerId} |
SendMessage |
conversationId, senderType, senderId, senderName, senderAvatar, contentType, content, guId="" |
发送消息;当 conversationId 为空且 senderType==1 时先自动发起会话(并广播 OnNewConversation),随后广播 OnMessageReceived |
StartConversation |
userId, userName |
发起会话,向调用方回发 OnConversationStarted,并向对应客服分组广播 OnNewConversation |
服务端 → 客户端推送事件:
| 事件名 | 触发时机 | 附带数据 |
|---|---|---|
OnMessageReceived |
消息写入成功后,向会话分组广播 | GuId, ConversationId, SenderType, SenderId, SenderName, SenderAvatar, ContentType, Content, CreateTime |
OnConversationStarted |
StartConversation 成功,回发给发起连接 |
ConversationEntity |
OnNewConversation |
新会话创建成功,向客服分组 customer_{CustomerId} 广播 |
conversationId, customerId, customerName, userId, userName, status, createTime |
ErrorMessage |
参数错误 / 会话创建失败 / 异常 | 错误字符串 |
连接生命周期:
OnConnectedAsync:读取Context.User的uid声明,非空则加入分组customer_{uid}。OnDisconnectedAsync:仅调用基类实现(不做额外清理)。
四、项目结构与技术要点
CustomerSrc 由 4 个项目组成,依赖关系如下(→ 表示引用):
CustomerHost (可执行进程, Web SDK, net8.0)
→ CustomerApi
→ RedisService
→ SharpAbp.Infrastructure.Api
→ (间接)CustomerService → CustomerService.Domain
CustomerApi (Web SDK, net8.0, 实为类库,含 AssemblyMarker)
→ CustomerService
→ CommonDomain / CommonInfrastructure / Common / JWTHelper
→ MongoRepository / RabbitMQHelper / RedisHelper / SharpAbp.Infrastructure.Api
→ RedisService / CommonService
CustomerService (类库, net8.0)
→ CustomerService.Domain
→ CommonDomain / CommonInfrastructure / Common / JWTHelper
→ MongoRepository / RabbitMQHelper / RedisHelper / RedisService
CustomerService.Domain (类库, net8.0)
→ CommonDomain
→ MongoRepository
4.1 各 csproj 框架与关键依赖
| 项目 | SDK / 目标框架 | 关键 NuGet 包 | 关键项目引用 |
|---|---|---|---|
CustomerSrc/CustomerApi/CustomerApi.csproj |
Microsoft.NET.Sdk.Web,net8.0 |
无自有 PackageReference(依赖由引用项目传递) | CommonDomain、CommonInfrastructure、Common、JWTHelper、MongoRepository、RabbitMQHelper、RedisHelper、SharpAbp.Infrastructure.Api、RedisService、CommonService、CustomerService |
CustomerSrc/CustomerHost/CustomerHost.csproj |
Microsoft.NET.Sdk.Web,net8.0 |
Microsoft.AspNetCore.Mvc.NewtonsoftJson 8.0.24、Microsoft.AspNetCore.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、DotNetCore.CAP.Dashboard 8.3.4、DotNetCore.CAP.PostgreSql 8.3.4、DotNetCore.CAP.RabbitMQ 8.3.4 | RedisService、CustomerApi、SharpAbp.Infrastructure.Api |
CustomerSrc/CustomerService/CustomerService.csproj |
Microsoft.NET.Sdk,net8.0 |
AutoMapper 14.0.0 | CommonDomain、CommonInfrastructure、Common、JWTHelper、MongoRepository、RabbitMQHelper、RedisHelper、RedisService、CustomerService.Domain |
CustomerSrc/CustomerService.Domain/CustomerService.Domain.csproj |
Microsoft.NET.Sdk,net8.0 |
MongoDB.Bson 3.6.0 | CommonDomain、MongoRepository |
CustomerHost.csproj 另外通过
<None>引入解决方案根的nlog.config(CopyToOutputDirectory=PreserveNewest),并声明把Config/system.json、docker-compose.yaml、Dockerfile复制到输出目录;项目内含wwwroot\uploads\文件夹占位。
4.2 进程入口要点(CustomerHost/Program.cs)
- 环境变量:启动时设置
SERVICE_NAME(默认取入口程序集名,即 CustomerHost)与INSTANCE_ID(默认default)。 - 控制器装配:
AddControllers().AddApplicationPart(typeof(AssemblyMarker).Assembly)显式加载CustomerApi程序集中的控制器;AddControllersAsServices()使控制器走 DI 容器。 - JSON 序列化:追加 Newtonsoft.Json 配置,日期格式
yyyy-MM-dd HH:mm:ss,DateTimeZoneHandling = Local。 - 配置加载:
AddJsonFile(Path.Combine("Config","system.json")),绑定MongoDbSettings与IMongoDbSettings。 - AutoMapper:
AddAutoMapper(typeof(CustomerService.AutoMapperConfig))。 - 健康检查:
AddHealthChecks().AddCheck("self", ...),映射/health返回 JSON 明细。 - SignalR 配置:
AddSignalR设置MaximumReceiveMessageSize=64KB、StreamBufferCapacity=512、ClientTimeoutInterval=70s、KeepAliveInterval=15s;启用AddJsonProtocol()与AddStackExchangeRedis(RedisConfig:ConnectionString),Redis 频道前缀RedisChannel.Literal("CustomerHub")(多实例横向扩展时的背板)。 - CORS:名为
Cors的策略,允许任意 Origin / Header / Method,且AllowCredentials()。 - 鉴权 / 缓存 / 消息:
AddCustomJwt(JWTHelper 扩展)、AddRedisCache(RedisHelper 扩展)、AddCap(自定义 CAP 扩展,见 4.4)。 - DI 容器:
UseServiceProviderFactory(new AutofacServiceProviderFactory())+RegisterModule<AutofacModule>()。 - 中间件管线(顺序):开发环境异常页 →
UseCors("Cors")→ 静态文件(RequestPath = "/uploads",物理目录wwwroot,启动时自动创建wwwroot/uploads)→UseRouting→UseAuthentication→UseAuthorization→UseApiLogging()→MapHub<CustomerHub>("/customerHub", WebSockets)→MapControllers()→UseGlobalExceptionHandler()→MapHealthChecks("/health")→Run。
4.3 DI 注册位置(CustomerHost/Middleware/AutofacModule.cs)
AutofacModule 继承 SharpAbp.Infrastructure.Api.Autofac.ApplicationModule:
CurrentAssembly= CustomerHost 程序集。GetServiceAssemblies()返回ICustomerService所在程序集(CustomerService)、CustomerService.Customer.CustomerService所在程序集、ApiLogService所在程序集(CommonService)。- 基类
ApplicationModule.Load统一注册:MongoBaseRepository<>→IMongoBaseRepository<>(InstancePerLifetimeScope)MongoBaseService<>→IMongoBaseService<>(InstancePerLifetimeScope)RedisService→IRedisService- 各程序集中类名以
Service结尾的非抽象类型按接口注册;类名以Repository结尾的同样按接口注册。
因此 ICustomerService / CustomerService 以及三个 IMongoBaseRepository<T> 均通过 Autofac 自动注入。
4.4 CAP / RabbitMQ 配置(CustomerHost/Extension/CapExtension.cs)
AddCap 扩展注册 DotNetCore.CAP:
- 启用 Dashboard(
UseDashboard())。 - 传输层用 RabbitMQ:Host/UserName/Password/VirtualHost 取自
CapConfig:*,交换机名cap.exchange。 - 存储层用 PostgreSQL:连接串
CapConfig:PGLogHost,Schemapublic。 - 成功消息保留 7 天;失败重试 5 次、间隔 10(秒);提供
FailedThresholdCallback回调(当前回调体为空实现)。
说明:本模块代码中未发现发布 / 订阅任何 CAP 消息或
[CapSubscribe]处理器;CAP 仅完成框架级接入与 Dashboard 可用。
4.5 SignalR 分组模型
| 分组名 | 含义 | 加入方式 |
|---|---|---|
{conversationId} |
单个会话的参与者 | JoinConversation,或发送 / 发起消息时自动加入 |
customer_{customerId} |
某客服的所有连接(客服队列) | JoinCustomerQueue,客服连接建立时按 uid 自动加入 |
4.6 API 日志中间件(CustomerHost/Middleware/ApiLoggingMiddleware.cs)
- 仅当请求路径 以
/api段开头(StartsWithSegments("/api"))且非OPTIONS时记录日志;记录前读取请求体(POST)、包裹响应流以捕获响应体,并对响应体中的BaseResponse.Data做脱敏(置空后再序列化)。 - 采集 Header:
Token、Version、User-Agent、Source、DeviceId、Device、Ip、Sign,组装ApiLog后经IApiLogService.InsertOneAsync落库。
注意(实测代码行为):本模块对外路由前缀为
/customerapi,其首段为customerapi,不等于/api段,因此ApiLoggingMiddleware的判断条件不会命中的/customerapi/*请求,即本模块 HTTP 接口目前不会被该中间件记录(仅经典的/api前缀才记录)。
五、代码目录说明
以下目录树基于
CustomerSrc/实际文件(已排除bin/、obj/编译产物)完整列出。
CustomerSrc/
├── CustomerApi/ # HTTP 接口 + SignalR Hub 定义(类库工程,含 AssemblyMarker)
│ ├── Controllers/
│ │ ├── CustomerController.cs # 客服会话/消息相关接口(start/message/messages/conversations/end/online/status/mark-read/chatlog)
│ │ └── ImageUploadController.cs # 聊天图片上传接口(/customerapi/imageupload/upload)
│ ├── Hubs/
│ │ └── CustomerHub.cs # SignalR Hub:加入分组、发送消息、发起会话及事件广播
│ ├── Properties/
│ │ └── launchSettings.json # CustomerApi 调试配置(applicationUrl https://localhost:8007/)
│ ├── wwwroot/
│ │ └── uploads/ # 图片上传落盘目录
│ │ └── e6f31921718c4a10aed90f483f005130.png # 已上传的示例图片文件
│ ├── .dockerignore # Docker 构建忽略规则
│ ├── CustomerApi.csproj # Web SDK / net8.0,引用 CustomerService 等
│ └── Program.cs # 占位入口:提示使用 CustomerHost 运行;定义 AssemblyMarker
│
├── CustomerHost/ # 进程入口(可执行 Web 工程)
│ ├── Config/
│ │ └── system.json # 运行配置:urls、JWT、PG、CAP、Redis、Mongo、CustomerService 段
│ ├── Extension/
│ │ └── CapExtension.cs # AddCap 扩展:CAP + RabbitMQ + PostgreSQL 存储 + Dashboard
│ ├── Middleware/
│ │ ├── ApiLoggingMiddleware.cs # /api 请求日志采集中间件(含响应脱敏)
│ │ └── AutofacModule.cs # Autofac 模块:注册 Service/Repository 程序集
│ ├── Properties/
│ │ └── launchSettings.json # 调试端口配置(https://localhost:38200;http://localhost:38201)
│ ├── CustomerHost.csproj # Web SDK / net8.0,含 SignalR/CAP/NLog/Autofac 等包
│ ├── docker-compose.yaml # 容器编排:0524customer 镜像,端口 5247:80
│ └── Program.cs # 进程入口:DI、SignalR、CORS、JWT、Redis、CAP、中间件与 Hub 映射
│
├── CustomerService/ # 业务服务层
│ ├── Customer/
│ │ ├── ICustomerService.cs # 客服服务接口(会话/消息/在线状态/已读)
│ │ └── CustomerService.cs # 客服服务实现(Mongo + Redis)
│ ├── AutoMapperConfig.cs # AutoMapper Profile(当前为空配置)
│ └── CustomerService.csproj # 类库 / net8.0,AutoMapper 14.0.0
│
└── CustomerService.Domain/ # 领域模型层
├── Entity/
│ ├── ConversationEntity.cs # 会话实体(集合 conversation)
│ ├── CustomerEntity.cs # 客服实体(集合 customer)
│ └── MessageEntity.cs # 消息实体(集合 message)
├── Response/
│ └── ConversationResponse.cs # 会话响应模型(继承会话实体 + 最后消息/未读数/消息列表)
└── CustomerService.Domain.csproj # 类库 / net8.0,MongoDB.Bson 3.6.0
六、关键文件索引
| 文件相对路径 | 职责 |
|---|---|
CustomerSrc/CustomerHost/Program.cs |
进程入口:服务注册(控制器 / SignalR / CORS / JWT / Redis / CAP / AutoMapper / 健康检查)、Autofac 容器、中间件管线、/customerHub 与 /health 映射 |
CustomerSrc/CustomerHost/Config/system.json |
运行配置:urls=http://*:8006、JwtConfig、ConnectionStrings:PgSqlConnection、CapConfig、RedisConfig、MongoDbSettings、CustomerService 段 |
CustomerSrc/CustomerHost/Middleware/AutofacModule.cs |
Autofac 模块,声明需要扫描注册 Service/Repository 的程序集 |
CustomerSrc/CustomerHost/Middleware/ApiLoggingMiddleware.cs |
/api 请求日志中间件(请求/响应采集、响应脱敏、落库 ApiLog) |
CustomerSrc/CustomerHost/Extension/CapExtension.cs |
AddCap 扩展:CAP + RabbitMQ + PostgreSQL + Dashboard |
CustomerSrc/CustomerHost/docker-compose.yaml |
容器编排,端口映射 5247:80 |
CustomerSrc/CustomerHost/Properties/launchSettings.json |
本地调试端口配置 |
CustomerSrc/CustomerApi/Program.cs |
占位入口(提示由 CustomerHost 运行),并定义 AssemblyMarker 供 Host 加载程序集 |
CustomerSrc/CustomerApi/Controllers/CustomerController.cs |
客服 HTTP 接口:发起/结束会话、收发消息、会话与消息查询、在线客服、状态更新、标记已读;含各请求参数类 |
CustomerSrc/CustomerApi/Controllers/ImageUploadController.cs |
图片上传接口,保存至 wwwroot/uploads 并返回相对路径 |
CustomerSrc/CustomerApi/Hubs/CustomerHub.cs |
SignalR Hub:分组加入/退出、发送消息、发起会话、连接生命周期、事件广播(OnMessageReceived / OnConversationStarted / OnNewConversation / ErrorMessage) |
CustomerSrc/CustomerService/Customer/ICustomerService.cs |
客服服务接口定义 |
CustomerSrc/CustomerService/Customer/CustomerService.cs |
客服服务实现:会话负载分配、消息落库、会话/消息查询、在线状态(Redis)、标记已读、客服查询 |
CustomerSrc/CustomerService/AutoMapperConfig.cs |
AutoMapper Profile(当前无映射配置) |
CustomerSrc/CustomerService.Domain/Entity/ConversationEntity.cs |
会话实体,BsonCollection("conversation", data_0524_customer) |
CustomerSrc/CustomerService.Domain/Entity/MessageEntity.cs |
消息实体,BsonCollection("message", data_0524_customer) |
CustomerSrc/CustomerService.Domain/Entity/CustomerEntity.cs |
客服实体,BsonCollection("customer", data_0524_customer) |
CustomerSrc/CustomerService.Domain/Response/ConversationResponse.cs |
会话响应模型(继承 ConversationEntity,增加 LastMessage / UnreadCount / Messages) |
CustomerSrc/CustomerHost/CustomerHost.csproj |
Host 工程文件(包与项目引用、静态文件复制) |
CustomerSrc/CustomerApi/CustomerApi.csproj |
API 工程文件(项目引用) |
CustomerSrc/CustomerService/CustomerService.csproj |
服务层工程文件 |
CustomerSrc/CustomerService.Domain/CustomerService.Domain.csproj |
领域层工程文件 |
七、与其他模块的交互
7.1 MongoDB 集合
所有实体继承 MongoRepository.MongoBaseEntity(含 _id(GUID 字符串,默认 Guid.NewGuid().ToString("N"))、isdelete、CreateInfo),并通过 [BsonCollection(集合名, ServiceDatabases.Customer)] 指定数据库。ServiceDatabases.Customer = "data_0524_customer"。
| 实体 | 集合名 | 数据库 | 主要字段(Bson 名) |
|---|---|---|---|
ConversationEntity |
conversation |
data_0524_customer |
userid、username、useravatar、customerid、customername、customeravatar、status、createtime、endtime、lastreadtime |
MessageEntity |
message |
data_0524_customer |
conversationid、sendertype、senderid、sendername、senderavatar、contenttype、content、createtime |
CustomerEntity |
customer |
data_0524_customer |
userid、username、status、avatar、createtime |
访问方式:IMongoBaseRepository<T>(FindOneAsync / FilterByAsync / InsertOneAsync / ReplaceOneAsync / UpdateManyAsync 等)。
7.2 Redis
- 在线客服列表:键
customer-service:online(RedisKey.CUSTOMER_ONLINE_KEY→RedisKeyGenerator.CustomerKey("online"),前缀映射customer→customer-service)。通过ICache(Common.Redis,来自 RedisHelper)的AddToList/RemoveFromList/GetList维护,元素为客服的用户 ID 字符串。- 上线(
UpdateCustomerStatus(status==1)):先从列表移除再追加,写入该客服 ID。 - 下线:从列表移除。
- 分配客服(
StartConversation/GetOnlineCustomerList):读取列表 → 逐个查customer集合校验Status==1→ 返回有效在线客服。 - 附:
RedisKeyConstants.CustomerOnlineKey("game0524:customer:online")为另一套常量定义,但本模块实际使用的是RedisKey.CUSTOMER_ONLINE_KEY。
- 上线(
- SignalR 背板:
AddStackExchangeRedis(RedisConfig:ConnectionString),频道前缀CustomerHub,用于多实例间广播。system.json中RedisConfig.ConnectionString = "localhost:6379,password=123456,defaultDatabase=2,abortConnect=false",另Database=1。
7.3 CAP / RabbitMQ
- 通过
AddCap接入,交换机cap.exchange,存储为 PostgreSQL(publicSchema,连接串CapConfig:PGLogHost)。本模块代码未定义任何 CAP 发布/订阅消息,仅框架级接入与 Dashboard。
7.4 HTTP / 项目引用依赖
- 通过
CommonInfrastructure(BaseController、ControllerExtension.ToResult/ToListResult/...、BaseResponse/ListResponse)、Common(BaseResponse、CommonResponseCodeEnum、RedisKey、ICache)、JWTHelper(AddCustomJwt)、RedisHelper(AddRedisCache)、MongoRepository(IMongoBaseRepository)、SharpAbp.Infrastructure.Api(ApplicationModule、UseGlobalExceptionHandler)、CommonService(ApiLogService/IApiLogService)等基础设施项目协作。 - 未发现本模块主动发起对其他业务进程的 HTTP 调用。
7.5 与 Admin 模块(客服管理)的关系
- 后台客服账号与「客服管理」属于 Admin 模块:
AdminSrc/AdminService/Customer/CustomerService.cs提供AddCustomer等能力(新增客服、校验「该用户已是客服」),并在AdminSrc/AdminDomain/Admin/ENum/EnumOperationModule.cs中以Customer = 8「客服管理」登记操作模块。 - 两侧共用同一套
CustomerEntity集合(data_0524_customer.customer)与前端页面AdminSrc/AdminHost/wwwroot/admin/dist/views/customer/service.html;CustomerSrc 负责在线会话与消息,Admin 负责客服的创建与运营管理。
7.6 网关映射
Gateway/ocelot.json 中:
/customerapi/{everything}→localhost:5247/customerHub/{everything}→localhost:5247
即外部统一经网关 http://localhost:8001 访问本模块的 HTTP 接口与 SignalR Hub。