154 lines
8.9 KiB
Transact-SQL
154 lines
8.9 KiB
Transact-SQL
/* ─────────────────────────────────────────────────────────────
|
||
本地开发库(AML-local-dev.bak 还原后)的架构补齐脚本
|
||
|
||
.bak 是某个时间点的库快照,没有 __EFMigrationsHistory,DbMigrator 无从判断
|
||
增量 → 后续后端迁移新增的表 / 列在本地库里全部缺失,调用相关接口会 500。
|
||
本脚本把这些 DDL 按迁移原样补上(全部带存在性判断,可重复执行):
|
||
|
||
20260718121851_PaygOfflineOrderManage 隨付即用(PAYG)下单与线下订单管理
|
||
20260719120000_AddAgentUserSettingAndPaymentMethod 代理归属国家 + 支持的支付网关
|
||
20260720000000_SplitOrderTypeAddOrderSource 订单来源与业务意图拆分
|
||
20260723000000_AddTenantIndustry 行业配置表(含 10 条行业种子)
|
||
20260724000000_AddTenantIndustryNameTranslations 行业名称多语言 JSON 列
|
||
|
||
另外补上 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
|
||
|
||
/* ── 5) AddTenantIndustry ──────────────────────────────────── */
|
||
IF OBJECT_ID('AML_TenantIndustrys') IS NULL
|
||
CREATE TABLE AML_TenantIndustrys (
|
||
Id uniqueidentifier NOT NULL CONSTRAINT PK_AML_TenantIndustrys PRIMARY KEY,
|
||
Code nvarchar(64) NOT NULL,
|
||
Name nvarchar(256) NULL,
|
||
EditionId uniqueidentifier NULL, -- 行业→Edition 映射,购买时用;由后台维护
|
||
DisplayOrder int NOT NULL,
|
||
Enabled bit NOT 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_TenantIndustrys_IsDeleted DEFAULT 0,
|
||
DeleterId uniqueidentifier NULL,
|
||
DeletionTime datetime2 NULL
|
||
);
|
||
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = 'UIX_AML_TenantIndustrys_Code')
|
||
CREATE UNIQUE INDEX UIX_AML_TenantIndustrys_Code ON AML_TenantIndustrys(Code);
|
||
|
||
-- 迁移里的 10 条行业种子(原 TenantIndustry.json),EditionId 留空
|
||
MERGE AML_TenantIndustrys AS t
|
||
USING (VALUES
|
||
('A1B2C3D4-0001-4A01-9A01-000000000001', 'Crypto', 'Crypto - crypto currency', 10),
|
||
('A1B2C3D4-0002-4A02-9A02-000000000002', 'DPMS', 'DPMS - precious metal and stone', 20),
|
||
('A1B2C3D4-0003-4A03-9A03-000000000003', 'Insurance', 'Insurance', 30),
|
||
('A1B2C3D4-0004-4A04-9A04-000000000004', 'MSO', 'MSO - Money Services Operator', 40),
|
||
('A1B2C3D4-0005-4A05-9A05-000000000005', 'NGO', 'NGO - Non-profit Organization', 50),
|
||
('A1B2C3D4-0006-4A06-9A06-000000000006', 'RealEstate', 'Real Estate - real estate agents', 60),
|
||
('A1B2C3D4-0007-4A07-9A07-000000000007', 'SecuritiesTrades', 'Securities Trades', 70),
|
||
('A1B2C3D4-0008-4A08-9A08-000000000008', 'TCSP', 'TCSP - Trust and Company Services', 80),
|
||
('A1B2C3D4-0009-4A09-9A09-000000000009', 'CPA', 'CPA', 90),
|
||
('A1B2C3D4-0010-4A10-9A10-000000000010', 'Others', 'Others', 100)
|
||
) AS s (Id, Code, Name, DisplayOrder) ON t.Code = s.Code
|
||
WHEN NOT MATCHED THEN
|
||
INSERT (Id, Code, Name, DisplayOrder, Enabled, CreationTime, IsDeleted)
|
||
VALUES (CONVERT(uniqueidentifier, s.Id), s.Code, s.Name, s.DisplayOrder, 1, '2026-07-23T00:00:00', 0);
|
||
|
||
/* ── 6) AddTenantIndustryNameTranslations ──────────────────── */
|
||
-- 行业名称多语言 JSON:{"zh-Hans":"","zh-Hant":"","en":"","ja":""},可空
|
||
IF COL_LENGTH('AML_TenantIndustrys', 'NameTranslations') IS NULL
|
||
ALTER TABLE AML_TenantIndustrys ADD NameTranslations nvarchar(max) NULL;
|
||
|
||
PRINT '本地库架构补齐完成';
|