chore(docker): 本地开发栈补齐 PAYG 配置与 .bak 架构补齐脚本

- docker-compose.local.yml: 新增 AppConfig__TwoC__TenantId 与
    IsMockupPayment,隨付即用(PAYG)建单需校验 2C 池租户,否则报
    "TwoC.TenantId is not configured"
  - 新增 local-schema-catchup.sql:AML-local-dev.bak 快照缺
    __EFMigrationsHistory,DbMigrator 无从增量,补上 PAYG /
    AgentUserSetting / SplitOrderType 三个迁移的 DDL,并回补
    IsDeleted 的 DEFAULT 0 约束(全部带存在性判断,可重复执行)
  - 文档 docker-compose-local-dev.md 更名为 readme.md
main
fengruixiang 2026-07-22 11:12:01 +08:00
parent b2b41e59e4
commit ba133c4fb5
3 changed files with 113 additions and 0 deletions

View File

@ -114,6 +114,13 @@ services:
# 真实支付链(下单 → 收银台 → PaymentWebhook → 订单转已支付)。 # 真实支付链(下单 → 收银台 → PaymentWebhook → 订单转已支付)。
# 若只想跳过支付、快速拿到已开通的租户,改回 "true" 即可。 # 若只想跳过支付、快速拿到已开通的租户,改回 "true" 即可。
AppConfig__Portal__IsMockupPayment: "false" AppConfig__Portal__IsMockupPayment: "false"
# 隨付即用(PAYG / CreatePayAsYouGoOrder):支付成功后把检测链接挂到 2C 池租户下,
# 建单时就会校验此项,未配置直接报 "TwoC.TenantId is not configured"。
# 取本地库 SaasTenants 里名为 "2C" 的租户 Id。
AppConfig__TwoC__TenantId: "3A1C1F4F-32A8-26B9-743D-5B12DE3B49E8"
# PAYG 在线单的模拟支付:true 会在建单后自造一次成功回调(跳过收银台)。
# 与上面订阅单的 IsMockupPayment 同理,要测真实收银台链路就置 false。
AppConfig__TwoC__IsMockupPayment: "false"
# RabbitMQ: use the bundled broker service and run the background consumer. # RabbitMQ: use the bundled broker service and run the background consumer.
AppConfig__RabbitMQConfig__HostName: "rabbitmq" AppConfig__RabbitMQConfig__HostName: "rabbitmq"
AppConfig__RabbitMQConfig__EnableConsumer: "true" AppConfig__RabbitMQConfig__EnableConsumer: "true"

View File

@ -0,0 +1,106 @@
/* ─────────────────────────────────────────────────────────────
本地开发库(AML-local-dev.bak 还原后)的架构补齐脚本
.bak 是某个时间点的库快照,没有 __EFMigrationsHistory,DbMigrator 无从判断
增量 → 后续后端迁移新增的表 / 列在本地库里全部缺失,调用相关接口会 500。
本脚本把这些 DDL 按迁移原样补上(全部带存在性判断,可重复执行):
20260718121851_PaygOfflineOrderManage 隨付即用(PAYG)下单与线下订单管理
20260719120000_AddAgentUserSettingAndPaymentMethod 代理归属国家 + 支持的支付网关
20260720000000_SplitOrderTypeAddOrderSource 订单来源与业务意图拆分
另外补上 IsDeleted 的 DEFAULT 0 约束:.bak 还原后部分表丢了默认值约束,
而 EF 的 INSERT 并不显式带该列 → 报 "Cannot insert the value NULL into column 'IsDeleted'"。
用法:
docker exec -i aml-mssql /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U sa -P 'Aml@Local2026' -C -d AbpAML -i /dev/stdin < local-schema-catchup.sql
───────────────────────────────────────────────────────────── */
SET NOCOUNT ON;
/* ── 1) IsDeleted 默认值约束(.bak 还原丢失)───────────────── */
DECLARE @sql nvarchar(max) = N'';
SELECT @sql = @sql + N'ALTER TABLE [' + t.name + N'] ADD CONSTRAINT [DF_' + t.name + N'_IsDeleted] DEFAULT 0 FOR [IsDeleted];' + CHAR(10)
FROM sys.tables t
JOIN sys.columns c ON c.object_id = t.object_id AND c.name = 'IsDeleted'
WHERE c.default_object_id = 0;
EXEC sp_executesql @sql;
/* ── 2) PaygOfflineOrderManage ─────────────────────────────── */
IF COL_LENGTH('AMLPortal_Orders', 'ContactEmail') IS NULL
ALTER TABLE AMLPortal_Orders ADD ContactEmail nvarchar(max) NULL;
IF COL_LENGTH('AMLPortal_Orders', 'SubjectName') IS NULL
ALTER TABLE AMLPortal_Orders ADD SubjectName nvarchar(max) NULL;
IF COL_LENGTH('AMLPortal_Orders', 'SubjectType') IS NULL
ALTER TABLE AMLPortal_Orders ADD SubjectType nvarchar(max) NULL;
IF OBJECT_ID('AML_ConsumerLinks') IS NOT NULL AND COL_LENGTH('AML_ConsumerLinks', 'PaidOrderId') IS NULL
ALTER TABLE AML_ConsumerLinks ADD PaidOrderId uniqueidentifier NULL;
IF OBJECT_ID('AML_OrderProcessLogs') IS NULL
CREATE TABLE AML_OrderProcessLogs (
Id uniqueidentifier NOT NULL CONSTRAINT PK_AML_OrderProcessLogs PRIMARY KEY,
OrderKind int NOT NULL,
OrderId uniqueidentifier NOT NULL,
Action nvarchar(max) NULL,
Remark nvarchar(max) NULL,
OperatorName nvarchar(max) NULL,
ExtraProperties nvarchar(max) NULL,
ConcurrencyStamp nvarchar(40) NULL,
CreationTime datetime2 NOT NULL,
CreatorId uniqueidentifier NULL,
LastModificationTime datetime2 NULL,
LastModifierId uniqueidentifier NULL,
IsDeleted bit NOT NULL CONSTRAINT DF_AML_OrderProcessLogs_IsDeleted DEFAULT 0,
DeleterId uniqueidentifier NULL,
DeletionTime datetime2 NULL
);
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = 'IX_AML_OrderProcessLogs_OrderId')
CREATE INDEX IX_AML_OrderProcessLogs_OrderId ON AML_OrderProcessLogs(OrderId);
/* ── 3) AddAgentUserSettingAndPaymentMethod ────────────────── */
IF OBJECT_ID('AMLPortal_AgentUserSettings') IS NULL
CREATE TABLE AMLPortal_AgentUserSettings (
Id uniqueidentifier NOT NULL CONSTRAINT PK_AMLPortal_AgentUserSettings PRIMARY KEY,
AgentUserId uniqueidentifier NOT NULL,
CountryCode nvarchar(max) NULL,
ExtraProperties nvarchar(max) NULL,
ConcurrencyStamp nvarchar(40) NULL,
CreationTime datetime2 NOT NULL,
CreatorId uniqueidentifier NULL,
LastModificationTime datetime2 NULL,
LastModifierId uniqueidentifier NULL,
IsDeleted bit NOT NULL CONSTRAINT DF_AMLPortal_AgentUserSettings_IsDeleted DEFAULT 0,
DeleterId uniqueidentifier NULL,
DeletionTime datetime2 NULL
);
IF OBJECT_ID('AMLPortal_AgentUserPaymentMethods') IS NULL
CREATE TABLE AMLPortal_AgentUserPaymentMethods (
Id uniqueidentifier NOT NULL CONSTRAINT PK_AMLPortal_AgentUserPaymentMethods PRIMARY KEY,
AgentUserId uniqueidentifier NOT NULL,
PaymentGateway int NOT NULL, -- PaymentGatewayEnums:100=线下 / 200=QFPay
ExtraProperties nvarchar(max) NULL,
ConcurrencyStamp nvarchar(40) NULL,
CreationTime datetime2 NOT NULL,
CreatorId uniqueidentifier NULL,
LastModificationTime datetime2 NULL,
LastModifierId uniqueidentifier NULL,
IsDeleted bit NOT NULL CONSTRAINT DF_AMLPortal_AgentUserPaymentMethods_IsDeleted DEFAULT 0,
DeleterId uniqueidentifier NULL,
DeletionTime datetime2 NULL
);
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = 'IX_AMLPortal_AgentUserSettings_AgentUserId')
CREATE INDEX IX_AMLPortal_AgentUserSettings_AgentUserId ON AMLPortal_AgentUserSettings(AgentUserId);
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = 'IX_AMLPortal_AgentUserPaymentMethods_AgentUserId')
CREATE INDEX IX_AMLPortal_AgentUserPaymentMethods_AgentUserId ON AMLPortal_AgentUserPaymentMethods(AgentUserId);
/* ── 4) SplitOrderTypeAddOrderSource ───────────────────────── */
IF COL_LENGTH('AMLPortal_Orders', 'OrderSource') IS NULL
BEGIN
ALTER TABLE AMLPortal_Orders ADD OrderSource int NOT NULL CONSTRAINT DF_AMLPortal_Orders_OrderSource DEFAULT 1;
-- 存量线下手工补录单:OrderType=300(OfflineManual) → 续费(200) + 来源后台手工补录(2)
-- 走动态 SQL:同一批次里新加的列,静态语句在编译期就会报「列名无效」
EXEC(N'UPDATE AMLPortal_Orders SET OrderType = 200, OrderSource = 2 WHERE OrderType = 300;');
END
PRINT '本地库架构补齐完成';