部署与运行

一个目录、一个数据库

ERPLite 是单体应用:Web 宿主 + 浏览器端产物 + 一个数据库。没有 Redis、没有消息队列、没有独立的报表服务, 一台 2 核 4G 的机器就够 10–30 人同时用。数据库默认 SQLite(库就是文件), 也能直接换成 SQL Server、PostgreSQL、MySQL、Oracle 或达梦。

环境要求

需要什么

.NET 10

编译需要 SDK;运行只需 ASP.NET Core 运行时。Linux / Windows 均可。

数据库

默认 SQLite,库就是文件,不用装数据库服务;也可接 SQL Server / MySQL / PostgreSQL / Oracle / 达梦,连接串在宿主配置里指定。

反向代理

Nginx / IIS / Caddy 均可。手机端扫码需要 HTTPS,证书在这一层配。

可选的容器

仓库 Deploy/Dockerfile 已备好;数据卷挂到库与附件目录即可。

数据库

默认 SQLite,但不是只能 SQLite

数据层由 Known 框架统一抽象:实体映射、CRUD、事务、分页、建表都走同一套接口, 底下接哪个库由宿主里那一行注册决定。开源版默认 SQLite,是因为它让「下载 → 跑起来」只剩一步; 生产上该用你们的 SQL Server、PostgreSQL、MySQL、Oracle 还是达梦,就把那一行换掉。

SQLite

默认档
db.AddSQLite<Microsoft.Data.Sqlite.SqliteFactory>(conn)

库就是文件,不用装数据库服务。开了 WAL 读不阻塞写,单文件撑得住几十人同用,备份即拷文件。

SQL Server

生产档
db.AddSQLServer<Microsoft.Data.SqlClient.SqlClientFactory>(conn)

Windows 域环境、要和既有 .NET 系统打交道时最省事;备份交给作业计划。

PostgreSQL

生产档
db.AddPostgreSQL<Npgsql.NpgsqlFactory>(conn)

Linux 上最常见的搭配,云上托管实例多,统计类查询顺手。

MySQL / MariaDB

生产档
db.AddMySQL<MySqlConnector.MySqlConnectorFactory>(conn)

运维熟悉度高,托管实例便宜,小团队上手快。

Oracle

生产档
db.AddOracle<Oracle.ManagedDataAccess.Client.OracleClientFactory>(conn)

已经有 Oracle 统一运维与备份体系的场景,不必为了它另立一套数据库。

达梦 DM

国产化
db.AddDM<Dm.DmClientFactory>(conn)

信创要求下的国产库,框架层已适配,换库仍是同一行注册。

AppServer.cs
// 默认:库就是文件,免装数据库服务
db.AddSQLite<Microsoft.Data.Sqlite.SqliteFactory>(conn);

// 生产:换成你们已经在运维的那个库
db.AddSQLServer<Microsoft.Data.SqlClient.SqlClientFactory>(conn);

// 同一排还有这几行,签名一模一样
db.AddPostgreSQL<Npgsql.NpgsqlFactory>(conn);
db.AddMySQL<MySqlConnector.MySqlConnectorFactory>(conn);
db.AddOracle<Oracle.ManagedDataAccess.Client.OracleClientFactory>(conn);
db.AddDM<Dm.DmClientFactory>(conn);

换库只有三步

装目标库的 provider 包 → 把 AddSQLite 换成对应那一行 → 把连接串写进配置的 ConnString。业务代码与页面一行不动, 因为它们只认实体与 IExtensionRepository,不认方言。

要改的只有一类地方

业务层有几处按月聚合的原生 SQL 用了 SQLite 的 strftime(产量、考勤、库龄、账龄), 换库时按目标库的日期函数改写这几段即可。这类改写属于实施范围,商业合作里可以代为完成。

测试口径不藏着

开源版的全量用例(580 余条)目前跑在 SQLite 上。切到别的库要按目标库再跑一轮回归—— 这是换库的真实成本,写在页面上比事后解释便宜。

五步

从源码到能登录

第一步是克隆,而且得拉两个仓库——ERPLite 引用 Known 框架的源码,只拉一个编不过。 首次启动会非破坏式建表(现有表只加列不删列),并种下账号与角色;演示数据开关关掉就是一个干净的空库。

01

拉取源码

两个仓库放在同一个父目录下(主仓引用 ../Known/Known)。只想看代码不编译的话,拉第一条就够了。

git clone https://gitee.com/known/ERPLite.git
git clone https://gitee.com/known/Known.git
02

编译与发布

整仓一起编(含 ../Known 框架引用)。发布产物只有一个目录,前端产物由 Web 宿主一并带走。

dotnet publish ERPLiteWeb/ERPLiteWeb.csproj -c Release -o publish
03

配库与账号

连接串指向数据卷里的库文件(默认 SQLite;换生产库改的就是这一处,加宿主里那一行注册);引导账号口令走环境变量注入,不写进版本库。

Admin__BootstrapPassword=<强口令>
ConnString=Data Source=/data/erplite.db
04

启动

首次启动非破坏建表并种下账号与角色;演示数据开关关掉就是一个干净的空库。

cd publish && dotnet ERPLiteWeb.dll --urls http://0.0.0.0:8080
05

上线前必改

关掉演示数据与演示账号、注入引导口令、把备份目录指到独立数据卷;容器部署直接用 Deploy/Dockerfile。

"ERPLite": { "SeedDemoData": false }
上线前必改

四件不做会出事的事

演示档能跑通,不代表生产能直接开。下面四条属于「交付前必须逐条打勾」。

  • 关掉演示数据与演示账号,改掉公司名 "ERPLite": { "SeedDemoData": false }。不关的话,那七个口令相同的入口会一直躺在真实工厂的账号表里;CompanyName 不改,报表页眉与打印抬头仍是「示例集团」。
  • 用环境变量注入引导口令 Admin__BootstrapPassword。留空即关闭这条保底登录路——它只在库里读不出管理员时才生效,但仍是最后一道门。
  • 把库与附件挪到数据卷 连接串指向数据卷;附件默认落在库旁边 uploads/,备份默认 data/backups/。三处在一起,迁移就是整包带走。
  • 配上 HTTPS 与反向代理 手机扫码依赖 getUserMedia,http 下浏览器直接拒绝;Cookie 也需要 HTTPS 才算可靠。
备份下载端点自己判权。整库快照里有工资表与成本单价,文件名又按时间戳可猜, 只验「登录了没有」等于任何进得来的人都拖得走全厂账本——所以它按按钮级授权码逐人判定。
数据与备份

三个目录,构成全部状态

# 发布目录(随版本覆盖,不放数据)
publish/
├─ ERPLiteWeb.dll
├─ wwwroot/            # 前端产物与静态资源
└─ appsettings.json    # 连接串与基座选项

# 数据目录(独立数据卷,随备份走)
data/
├─ erplite.db          # 全部业务数据,含账套
├─ erplite.db-wal      # WAL 日志(热备时一并拷)
├─ uploads/            # 附件:合同、发票、签收单照片
└─ backups/            # 整库快照,手工 + 每日自动

恢复

停服务 → 用备份文件覆盖 erplite.db → 同时删掉同目录的 -wal / -shm → 启动。 库文件与 WAL 不配套是恢复失败最常见的原因,所以备份脚本连同这两个文件一起收。

并发

默认的 SQLite 档开了 WAL,读不阻塞写,单文件库撑得住几十人同用。 但它是单写者模型:要上百人并发或跨机房,换数据库比加机器管用——上面那几行注册就是为这一步准备的。

先用演示实例验证业务

部署前先在在线演示里把你们的单据流走一遍:订单 → 发货 → 应收 → 凭证。走得通再谈主数据导入。