dpz.core
dpz.core 是一个基于 .NET 10 (ASP.NET Core) 构建的现代化个人综合平台/CMS 系统。该项目采用分层架构设计,集成了内容管理、身份认证、实时通讯、多媒体管理等丰富功能,旨在打造一个高性能、可扩展的个人数字化中心。
在线站点: https://core.dpangzi.com
API 文档: https://core.dpangzi.com/code
认证中心: https://auth.dpangzi.com
API 服务: https://api.dpangzi.com
🚀 快速开始
前置要求
- .NET 10 SDK
- Node.js (用于前端资源构建)
- MongoDB (数据库)
- Redis (缓存和 SignalR 消息底板)
- Docker (可选,用于容器化部署)
本地开发
- 克隆仓库
git clone https://github.com/pengqian089/dpz.core.git
cd dpz.core
- 配置数据库连接
编辑 appsettings.json 或使用 AgileConfig 配置中心:
{
"ConnectionStrings": {
"mongodb": "mongodb://localhost:27017/YourDatabase"
},
"AgileConfig": {
"appId": "your-app-id",
"secret": "your-secret",
"nodes": "http://your-agile-config-server",
"env": "DEV"
}
}
- 构建前端资源
cd src/Dpz.Core.Web
# 安装依赖(首次运行)
npm install -g clean-css-cli
npm install esbuild --save-dev
# 执行构建
.\build.ps1
- 运行项目
cd src/Dpz.Core.Web
dotnet run
访问:http://localhost:5000
测试
项目包含多个测试项目:
# 运行所有测试
dotnet test
# 运行特定测试项目
dotnet test src/Dpz.Core.Backup.Test/Dpz.Core.Backup.Test.csproj
dotnet test src/Dpz.Core.Service.Network.Test/Dpz.Core.Service.Network.Test.csproj
🏗️ 项目结构
项目采用典型的分层架构,主要包含以下核心模块:
核心应用层
- Dpz.Core.Web: 核心 Web 前端/后端应用(MVC),处理用户界面、交互逻辑及页面渲染。版本 5.2.1
- Dpz.Core.Auth: 基于 OpenIddict 的统一认证中心(SSO),提供 OAuth2/OIDC 认证服务。版本 1.1.0
- Dpz.Core.WebApi: 对外 RESTful API 服务,支持 JSON/XML/MessagePack 格式。版本 3.2.1
- Dpz.Core.Web.Jobs: 后台任务管理应用,基于 Hangfire
业务逻辑层
- Dpz.Core.Service: 核心业务逻辑层,封装了所有领域服务(文章、评论、弹幕、多媒体等)
- Dpz.Core.Service.Network: 网络服务(邮件发送等)
- Dpz.Core.Service.ObjectStorage: 对象存储服务(又拍云集成)
- Dpz.Core.Shard.Service: 分片服务接口定义
- Dpz.Core.Shard.Implement.Service: 分片服务实现
数据访问层
- Dpz.Core.MongodbAccess: 基于 MongoDB 的数据访问层,实现了仓储模式和工作单元
- Dpz.Core.Cache.Redis: Redis 缓存实现
- Dpz.Core.Backup: 数据备份与恢复服务
基础设施层
- Dpz.Core.Infrastructure: 基础设施层,提供通用工具和底层支持
- Dpz.Core.Hangfire: Hangfire 后台任务集成
- Dpz.Core.Authenticator: 双因素认证(2FA)实现
- Dpz.Core.Observer: 观察者模式实现
实体与视图模型
- Dpz.Core.Entity.Base: 实体基类定义
- Dpz.Core.Public.Entity: 公共(基于 TwoFactorAuthenticator)。
- 安全防护: IP 限流、爬虫拦截(RejectBotsMiddleware)、日志审计。
- 数据备份: 自动化的数据库备份与恢复机制(Dpz.Core.Backup)。
- 输入验证: HTML 安全清理(HtmlSanitizer)y**: 枚举库(可独立发布为 NuGet 包)
辅助组件
- Dpz.Core.MvcPager: MVC 分页组件
- Dpz.Core.Web.Cache.InMemory: 内存缓存实现
📖 详细文档
各核心模块都有独立的 README 文档:
- Dpz.Core.Web - Web 应用详细说明
- Dpz.Core.Auth - 认证中心架构与部署
- Dpz.Core.WebApi - API 服务接口文档
- Dpz.Core.MongodbAccess - 数据访问层使用指南
- Dpz.Core.Infrastructure - 基础设施组件说明
- Dpz.Core.EnumLibrary - 枚举库发布说明
- Dpz.Core.Web.Jobs - 后台任务配置
✨ 功能特性
📝 内容管理
- 博客文章: 支持 Markdown 编写、分类、标签及全文检索。
- 动态 (Mumble): 类似微博/推特的微型博客,记录碎片化想法。
- 代码片段: 管理和分享常用代码块,支持语法高亮。
- 动态页面: 自定义页面内容管理,灵活的页面配置。
- 书签管理: 网址收藏与分类管理。
- 时间线: 个人时间轴事件记录。
💬 互动社交
- 评论系统: 支持多级评论、表情包、Markdown 格式。
- 实时聊天: 基于 SignalR 的即时通讯,支持群聊,使用 Redis 作为消息底板。
- 弹幕系统: 视频或页面的实时弹幕互动,支持颜色自定义。
🎬 多媒体与娱乐
- 音乐管理: 音乐播放、歌词展示与管理。
- 视频管理: 视频播放、弹幕、元数据管理,支持缩略图生成。
- 图片管理: 相册与图片存储,支持 Banner 管理,基于 ImageSharp 处理。
- Steam 集成: 展示 Steam 游戏库及游戏状态。
🛡️ 系统与安全
- 统一认证: 集中式账号管理,支持 2FA 双因素认证。
- 安全防护: IP 限流、爬虫拦截、日志审计。
- 数据备份: 自动化的备份与恢复机制。
🛠 技术栈
- 框架: .NET 10.0 (ASP.NET Core)
- 数据库: MongoDB 3.5.2 (主要存储), Redis (缓存/SignalR 底板)
- ORM/数据访问: 自研 Repository 模式 (Dpz.Core.MongodbAccess)
- 认证授权: OpenIddict 7.2.0, JWT Bearer 认证
- 配置中心: AgileConfig 1.8.0
- 后台任务: Hangfire
- 实时通讯: SignalR (Redis Backplane)
- 日志监控: Serilog, Seq
- 前端构建: esbuild + clean-css (JavaScript/CSS 打包与压缩)
- Markdown: Markdig 1.1.1
- 图片处理: SixLabors.ImageSharp 3.1.12
- 设备检测: DeviceDetector.NET 6.5.0, Wangkanai.Detection 8.20.0
- Web 优化: WebMarkupMin 2.20.2, Brotli/Gzip 压缩
- Web 服务器: Kestrel, Caddy (反向代理)
📏 编码约定
命名规范
- 私有字段成员使用
_前缀,并使用驼峰命名 - 参数、变量使用驼峰命名
- 类、结构体、接口、方法、属性、事件等使用 Pascal 命名
- 异步方法命名应该以 Async 结尾
- 命名空间应该使用
项目名.目录(.子目录) - 命名空间使用文件作用域命名空间
类型与可空性
- 按照语义严格遵循 Nullable(可空值类型、可空引用类型)
- 返回单个对象时,需要根据语义返回可空引用类型或者不可空引用类型
- 返回集合/数组时,除必要外(例如
byte[]?),如果没有数据都应该返回一个没有任何项的空数集合/数组 - 参数类型应该尽可能的抽象,返回值的类型应该尽可能的具体
- 语义冲突时,入参和出参应该分离,而不是共用一个类型
- 不应该存在公开的字段
代码风格
- 缩进使用 4 个空格
ifforforeachwhile等代码块,即使只有一行代码,也请使用大括号- 每行代码的最大长度:100 字符
- 原则上,不得使用行尾注释
- 如果只有一个构造函数的情况下,应该使用主构造函数
异步与性能
- 异步方法的签名应该添加
CancellationToken cancellationToken = default参数 IEnumerable<T>类型不应该重复枚举
日志规范
- 记录日志时,禁止拼接、内插字符串,而是应该使用结构化日志
⚙️ 配置说明
AgileConfig 配置中心
项目主要依赖 AgileConfig 进行分布式配置管理。通过环境变量或 appsettings.json 配置 AgileConfig 连接信息:
{
"AgileConfig": {
"appId": "Dpz.Core.Web",
"secret": "your-secret-key",
"nodes": "http://agileconfig-server:5000,http://backup-server:5000",
"env": "PROD",
"name": "dpz.core",
"tag": "tag1,tag2"
}
}
环境变量覆盖:
# Docker 部署时通过 -e 参数覆盖环境
docker run -e "AgileConfig:env=STAGING" ...
支持的环境标识:
DEV- 开发环境TEST- 测试环境STAGING- 预发布环境PROD- 生产环境
数据库连接
MongoDB 连接字符串配置:
{
"ConnectionStrings": {
"mongodb": "mongodb://username:password@host:27017/database?authSource=admin"
}
}
Redis 连接字符串(用于缓存和 SignalR):
{
"Redis": {
"Configuration": "localhost:6379,password=your-password",
"InstanceName": "dpz.core:"
}
}
对象存储配置
又拍云对象存储配置示例:
{
"UpYun": {
"BucketName": "your-bucket",
"OperatorName": "your-operator",
"OperatorPassword": "your-password",
"Domain": "https://your-domain.com"
}
}
🔧 运维与部署参考 (DevOps)
以下命令主要用于服务器维护和相关服务的部署。
🚀 前端资源构建
项目使用 PowerShell 脚本自动化前端资源构建流程。
# 进入 Dpz.Core.Web 目录
cd src/Dpz.Core.Web
# 执行构建脚本(需要提前安装 Node.js 和相关依赖)
# npm install -g clean-css-cli
# npm install esbuild --save-dev
.\build.ps1
构建流程说明:
- CSS 压缩: 使用
clean-css-cli合并并压缩 CSS 文件,生成global.min.css及 sourcemap - JavaScript 打包: 使用
esbuild打包压缩 JavaScript 文件 - 文件哈希: 为静态资源生成 MD5 哈希文件名(8位前缀)
- 资源清单: 生成
assets-manifest.json映射文件,用于版本管理
Docker 资源清理
# 删除所有未使用的Docker资源
sudo docker system prune -a --volumes
删除内容包括:停止的容器、未使用的网络、未引用的卷(⚠️)、悬挂镜像、未使用的镜像、构建缓存。
🐳 核心应用部署
Dpz.Core.Web 部署
cd /home/ubuntu/project/dpz.core/src
sudo docker build -t dpz.core -f Dpz.Core.Web/Dockerfile .
sudo docker run --restart=always \
--name dpz.core \
-e TZ=Asia/Shanghai \
-p 2372:8080 \
-d dpz.core:latest
Dpz.Core.Auth 部署
cd /home/ubuntu/project/dpz.core/src
sudo docker build -t dpz.core.auth -f Dpz.Core.Auth/Dockerfile .
sudo docker run --restart=always \
--name dpz.core.auth \
-e TZ=Asia/Shanghai \
-p 2377:8080 \
-d dpz.core.auth:latest
Dpz.Core.WebApi 部署
cd /home/ubuntu/project/dpz.core/src
sudo docker build -t dpz.webapi -f Dpz.Core.WebApi/Dockerfile .
sudo docker run --restart=always \
--name dpz.webapi \
-e TZ=Asia/Shanghai \
-v /home/ubuntu/project/dpz.core:/app/code \
-p 2376:8080 \
-d dpz.webapi:latest
导出 git 提交日志
git log --stat --since="2025-12-03" > detailed_log.txt
Seq 日志服务部署
# 拉取镜像
sudo docker pull docker.1ms.run/datalust/seq:latest
sudo docker run \
--name seq \
-d \
--restart unless-stopped \
-e ACCEPT_EULA=Y \
-e SEQ_API_CANONICALURI=https://logs.dpangzi.com \
-v /home/ubuntu/seq/data:/data \
-p 2370:80 \
-p 5341:5341 \
docker.1ms.run/datalust/seq:latest
SSH Key 生成
ssh-keygen -t rsa -C "pengqian089@hotmail.com"
cat ~/.ssh/id_rsa.pub
Caddy Web 服务器
# 验证配置文件
caddy validate --config /etc/caddy/Caddyfile
# 格式化配置文件
sudo caddy fmt --overwrite --config /etc/caddy/Caddyfile
# 重新加载配置文件
caddy reload --config /etc/caddy/Caddyfile
Redis 安装
sudo apt update
sudo apt install redis-server
# 编辑配置: bind 127.0.0.1 ::1, requirepass foobared
sudo vim /etc/redis/redis.conf
sudo systemctl restart redis.server
第三方服务部署
Alist (文件列表程序)
sudo docker pull xhofe/alist:latest
sudo docker run \
--restart=unless-stopped \
-v /home/ubuntu/alist:/opt/alist/data \
-p 2375:5244 \
-e PUID=0 \
-e PGID=0 \
-e UMASK=022 \
-e TZ=Asia/Shanghai \
--name="alist" \
-d xhofe/alist
Docker 镜像源配置参考:
{
"registry-mirrors": [
"https://docker.1ms.run",
"https://docker.xuanyuan.me"
]
}
OpenList
sudo docker run \
--user $(id -u):$(id -g) \
--restart=unless-stopped \
-v /home/pengqian/program/openlist/data:/opt/openlist/data \
-v /home/pengqian/program/openlist/storage:/opt/openlist/storage \
-p 6830:5244 \
-e UMASK=022 \
--name="openlist" \
-d openlistteam/openlist:latest
Jellyfin (媒体服务器)
sudo docker pull jellyfin/jellyfin
sudo docker run \
--name jellyfin \
-p 8096:8096 \
-v /home/pengqian/program/jellyfin/config:/config \
-v /home/pengqian/program/jellyfin/cache:/cache \
-v /home/pengqian/program/jellyfin/media:/media \
--restart unless-stopped \
-d jellyfin/jellyfin
Gitea (Git 服务)
mkdir -p /home/pengqian/program/gitea/{data,db}
sudo docker run -d \
--name gitea \
-p 3379:3000 \
-p 222:22 \
-v /home/pengqian/program/gitea/data:/data \
-v /home/pengqian/program/gitea/db:/data/gitea/db \
-e USER_UID=$(id -u) \
-e USER_GID=$(id -g) \
--restart unless-stopped \
-d gitea/gitea:latest
Aria2 (下载工具)
端口说明:
- 6800 TCP: RPC 控制端口
- 6888 TCP: BitTorrent 监听端口
- 6888 UDP: DHT 网络端口
sudo docker run -d \
--name aria2 \
-p 6800:6800 \
-p 6888:6888 \
-p 6888:6888/udp \
-v /home/pengqian/program/aria2/config:/config \
-v /home/pengqian/program/aria2/downloads:/downloads \
-e RPC_SECRET=YourSecurePassword \
--restart unless-stopped \
p3terx/aria2-pro:latest
qBittorrent
sudo docker run -d \
--name qbittorrent \
-p 3373:3373 \
-p 6881:6881 \
-p 6881:6881/udp \
-e PUID=1000 \
-e PGID=1000 \
-e UMASK=002 \
-e TZ="Asia/Shanghai" \
-e WEBUI_PORT=3373 \
-v /home/pengqian/program/qbt/config:/config \
-v /home/pengqian/program/qbt/downloads:/downloads \
-v /home/pengqian/program/openlist/data:/opt/openlist/data \
--restart unless-stopped \
docker.1ms.run/linuxserver/qbittorrent:latest
💡 常见问题 (FAQ)
MongoDB 事务支持
MongoDB 单实例默认不支持事务。如需使用事务功能(如 IUnitOfWork),需要将 MongoDB 配置为副本集模式。
单实例配置为副本集:
# 启动 MongoDB 时添加 --replSet 参数
mongod --replSet rs0
# 进入 MongoDB shell 初始化副本集
mongo
> rs.initiate()
前端资源构建失败
确保已安装必要的 npm 包:
npm install -g clean-css-cli
cd src/Dpz.Core.Web
npm install esbuild --save-dev
Docker 镜像拉取缓慢
使用国内镜像源加速,配置 /etc/docker/daemon.json:
{
"registry-mirrors": [
"https://docker.1ms.run",
"https://docker.xuanyuan.me"
]
}
重启 Docker 服务:
sudo systemctl restart docker
🤝 贡献指南
欢迎提交 Issue 和 Pull Request!
开发流程
- Fork 本仓库
- 创建功能分支 (git checkout -b feature/AmazingFeature)
- 提交更改 (git commit -m 'Add some AmazingFeature')
- 推送到分支 (git push origin feature/AmazingFeature)
- 开启 Pull Request
代码规范
请遵循项目的编码约定,确保代码风格一致。
测试要求
- 新功能必须包含单元测试
- 所有测试必须通过才能合并
- 保持测试覆盖率
📜 许可证
Copyright © dpangzi. All rights reserved.
本项目为个人学习和研究项目,代码仅供参考。
🔗 相关链接
- 在线演示: https://core.dpangzi.com
- API 文档: https://core.dpangzi.com/code
- GitHub: https://github.com/pengqian089/dpz.core
- 作者主页: https://dpangzi.com
📧 联系方式
- Email: pengqian089@hotmail.com
- GitHub: @pengqian089
⭐ 如果这个项目对您有帮助,欢迎给个 Star!