diff --git a/db.sql b/db.sql index c108792..64f875d 100644 --- a/db.sql +++ b/db.sql @@ -6,10 +6,49 @@ -- 2. The source spec references `t_sales_product_allocation_rule`, but no concrete table definition exists. The actual design stores -- allocation scheme on `t_sales_product` and provider rows on `t_sales_product_allocation_provider`. -- 3. `t_order` keeps SenderId/RecipientId/DeclarationId for compatibility with the original spec, while child tables also keep OrderId. +-- 4. Incremental `sql/migrate_*.sql` scripts are retired; this file is the single source of truth for OMS DDL. +-- 5. Data-permission tables (`user_org_perm` etc.) live here when RBAC and OMS share one MySQL database. SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; +DROP TABLE IF EXISTS `data_perm_access_log`; +DROP TABLE IF EXISTS `data_perm_change_log`; +DROP TABLE IF EXISTS `data_perm_template_item`; +DROP TABLE IF EXISTS `data_perm_template`; +DROP TABLE IF EXISTS `data_perm_field_mask`; +DROP TABLE IF EXISTS `data_resource`; +DROP TABLE IF EXISTS `user_filter_rule`; +DROP TABLE IF EXISTS `role_filter_rule`; +DROP TABLE IF EXISTS `user_secret_perm`; +DROP TABLE IF EXISTS `role_secret_perm`; +DROP TABLE IF EXISTS `user_biz_perm`; +DROP TABLE IF EXISTS `role_biz_perm`; +DROP TABLE IF EXISTS `user_data_scope`; +DROP TABLE IF EXISTS `role_data_scope`; +DROP TABLE IF EXISTS `role_org_perm`; +DROP TABLE IF EXISTS `user_org_perm`; +DROP TABLE IF EXISTS `t_xhs_media`; +DROP TABLE IF EXISTS `t_xhs_ai_provider`; +DROP TABLE IF EXISTS `t_xhs_human_config`; +DROP TABLE IF EXISTS `t_xhs_skill`; +DROP TABLE IF EXISTS `t_xhs_analysis_session`; +DROP TABLE IF EXISTS `t_xhs_publish_record`; +DROP TABLE IF EXISTS `t_xhs_task`; +DROP TABLE IF EXISTS `t_xhs_agent`; +DROP TABLE IF EXISTS `C_inbound_box_line`; +DROP TABLE IF EXISTS `C_inbound_box`; +DROP TABLE IF EXISTS `C_inbound_notice`; +DROP TABLE IF EXISTS `C_parcel_item`; +DROP TABLE IF EXISTS `C_parcel`; +DROP TABLE IF EXISTS `C_inventory`; +DROP TABLE IF EXISTS `C_sku_platform_map`; +DROP TABLE IF EXISTS `C_sku`; +DROP TABLE IF EXISTS `C_bin_location`; +DROP TABLE IF EXISTS `t_sales_store_order_line`; +DROP TABLE IF EXISTS `t_sales_store_order`; +DROP TABLE IF EXISTS `t_sales_store`; +DROP TABLE IF EXISTS `t_customer_account_flow`; DROP TABLE IF EXISTS `t_system_batch_email_record`; DROP TABLE IF EXISTS `t_system_batch_email_account`; DROP TABLE IF EXISTS `t_system_batch_email_template`; @@ -55,6 +94,7 @@ DROP TABLE IF EXISTS `t_order_task`; DROP TABLE IF EXISTS `t_order_batch_job_item`; DROP TABLE IF EXISTS `t_order_batch_job`; DROP TABLE IF EXISTS `t_order_template`; +DROP TABLE IF EXISTS `t_order_exception_event`; DROP TABLE IF EXISTS `t_order`; CREATE TABLE `t_order` ( @@ -92,6 +132,8 @@ CREATE TABLE `t_order` ( `PreviousOrderStatus` VARCHAR(32) NULL COMMENT '进入异常状态前的订单状态', `WarehouseId` INT NULL COMMENT '仓库ID', `CustomerId` INT NULL COMMENT '客户ID', + `OrganizationId` CHAR(36) NULL COMMENT '数据归属组织', + `SecretLevel` TINYINT NOT NULL DEFAULT 2 COMMENT '数据密级 1-4', `SenderId` INT NULL COMMENT '发件人ID', `RecipientId` INT NULL COMMENT '收件人ID', `DeclarationId` INT NULL COMMENT '申报信息ID', @@ -124,7 +166,8 @@ CREATE TABLE `t_order` ( KEY `idx_ord_warehouse_status` (`WarehouseId`, `OrderStatus`), KEY `idx_ord_sender` (`SenderId`), KEY `idx_ord_recipient` (`RecipientId`), - KEY `idx_ord_declaration` (`DeclarationId`) + KEY `idx_ord_declaration` (`DeclarationId`), + KEY `idx_ord_org_secret_ctime` (`OrganizationId`, `SecretLevel`, `CreateTime`) ) COMMENT='订单表'; CREATE TABLE `t_order_template` ( @@ -876,6 +919,7 @@ CREATE TABLE `t_customer` ( `Salesman` VARCHAR(32) NULL COMMENT '所属销售员账号', `CustomerService` VARCHAR(32) NULL COMMENT '所属顾问', `CustomerGroup` TINYINT NULL COMMENT '客户分组:0-普通客户,1-VIP1,2-VIP2,3-VIP3,4-VIP4,5-VIP5', + `OrganizationId` CHAR(36) NULL COMMENT '归属销售组织 FK organization.Id', `LastLoginIp` VARCHAR(64) NULL COMMENT '最后在线IP', `LastLoginTime` DATETIME NULL COMMENT '最后在线时间', `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', @@ -890,12 +934,14 @@ CREATE TABLE `t_customer` ( UNIQUE KEY `uk_cus_openid` (`WechatOpenid`), KEY `idx_cus_parent_status` (`ParentCustomerId`, `Status`), KEY `idx_cus_status_group` (`Status`, `CustomerGroup`), - KEY `idx_cus_sales_service` (`Salesman`, `CustomerService`) + KEY `idx_cus_sales_service` (`Salesman`, `CustomerService`), + KEY `idx_cus_organization` (`OrganizationId`) ) COMMENT='客户表'; CREATE TABLE `t_recharge_record` ( `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键,自增,步长 1', `CustomerId` INT NOT NULL COMMENT '客户ID(主账号/子账号关联主账号ID)', + `SecretLevel` TINYINT NOT NULL DEFAULT 3 COMMENT '数据密级 1-4', `SerialNumber` VARCHAR(64) NOT NULL COMMENT '流水号', `RechargeTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '充值提交时间', `PayType` TINYINT NOT NULL COMMENT '支付方式:1-微信,2-支付宝', @@ -1139,9 +1185,307 @@ CREATE TABLE `t_warehouse_address` ( KEY `idx_wa_type` (`WarehouseType`) ) COMMENT='仓库地址表'; --- 小红书(LIKE AI → OMS)模块,详见 sql/migrate_t_xhs.sql 与设计文档 docs/小红书模块设计-063001.md -CREATE TABLE IF NOT EXISTS `t_xhs_agent` ( +-- --------------------------------------------------------------------------- +-- 客户账户资金流水 +-- --------------------------------------------------------------------------- +CREATE TABLE `t_customer_account_flow` ( + `Id` int NOT NULL AUTO_INCREMENT, + `CustomerId` int NOT NULL COMMENT '客户 ID', + `SerialNumber` varchar(64) NOT NULL COMMENT '流水号', + `BizType` varchar(32) NOT NULL COMMENT '业务类型 recharge/orderPay', + `BizId` int DEFAULT NULL COMMENT '关联业务主键', + `BizNo` varchar(64) DEFAULT NULL COMMENT '关联业务单号', + `Amount` decimal(18,2) NOT NULL COMMENT '变动金额,正入账负出账', + `BalanceBefore` decimal(18,2) NOT NULL COMMENT '变动前余额', + `BalanceAfter` decimal(18,2) NOT NULL COMMENT '变动后余额', + `Currency` varchar(8) NOT NULL DEFAULT 'CNY' COMMENT '币种', + `Remark` varchar(512) DEFAULT NULL COMMENT '备注', + `IsDeleted` tinyint(1) NOT NULL DEFAULT '0', + `ConcurrencyStamp` char(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', + `CreateUserId` int NOT NULL DEFAULT '0', + `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `UpdateUserId` int DEFAULT NULL, + `UpdateTime` datetime DEFAULT NULL, + PRIMARY KEY (`Id`), + UNIQUE KEY `uk_customer_account_flow_serial` (`SerialNumber`), + KEY `idx_customer_account_flow_customer_time` (`CustomerId`, `CreateTime`), + KEY `idx_customer_account_flow_biz` (`BizType`, `BizId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='客户账户资金流水'; + +-- --------------------------------------------------------------------------- +-- 仓储模块(C_*)+ 店铺订单(t_sales_store*) +-- --------------------------------------------------------------------------- + +CREATE TABLE `C_sku` ( + `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', + `CustomerId` INT NOT NULL COMMENT '客户ID → t_customer.Id', + `SkuCode` VARCHAR(64) NOT NULL COMMENT '库内SKU编码', + `SkuName` VARCHAR(256) NOT NULL COMMENT 'SKU名称', + `SkuImageUrl` VARCHAR(512) NULL COMMENT '图片URL', + `WeightG` DECIMAL(10,2) NULL COMMENT '重量(g)', + `LengthCm` DECIMAL(10,2) NULL COMMENT '长(cm)', + `WidthCm` DECIMAL(10,2) NULL COMMENT '宽(cm)', + `HeightCm` DECIMAL(10,2) NULL COMMENT '高(cm)', + `Remark` VARCHAR(512) NULL COMMENT '备注', + `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', + `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', + `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', + `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `UpdateUserId` INT NULL COMMENT '更新人', + `UpdateTime` DATETIME NULL COMMENT '更新时间', + PRIMARY KEY (`Id`), + UNIQUE KEY `uk_c_sku_code` (`CustomerId`, `SkuCode`), + KEY `idx_c_sku_customer` (`CustomerId`, `IsDeleted`) +) COMMENT='仓储-SKU主数据'; + +CREATE TABLE `C_bin_location` ( + `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', + `WarehouseId` INT NOT NULL COMMENT '仓库ID → t_warehouse_address.Id', + `BinCode` VARCHAR(32) NOT NULL COMMENT '库位编码', + `BinName` VARCHAR(64) NULL COMMENT '库位展示名', + `ZoneCode` VARCHAR(32) NULL COMMENT '库区编码', + `IsEnabled` TINYINT NOT NULL DEFAULT 1 COMMENT '是否启用:0-否,1-是', + `Remark` VARCHAR(512) NULL COMMENT '备注', + `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', + `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', + `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', + `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `UpdateUserId` INT NULL COMMENT '更新人', + `UpdateTime` DATETIME NULL COMMENT '更新时间', + PRIMARY KEY (`Id`), + UNIQUE KEY `uk_c_bin_wh_code` (`WarehouseId`, `BinCode`), + KEY `idx_c_bin_warehouse` (`WarehouseId`, `IsEnabled`) +) COMMENT='仓储-库位主数据'; + +CREATE TABLE `C_inventory` ( + `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', + `CustomerId` INT NOT NULL COMMENT '客户ID', + `WarehouseId` INT NOT NULL COMMENT '仓库ID', + `SkuId` INT NOT NULL COMMENT 'SKU ID → C_sku.Id', + `BinLocationId` INT NOT NULL COMMENT '库位ID → C_bin_location.Id', + `Qty` INT NOT NULL DEFAULT 0 COMMENT '可用库存数量', + `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', + `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', + `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', + `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `UpdateUserId` INT NULL COMMENT '更新人', + `UpdateTime` DATETIME NULL COMMENT '更新时间', + PRIMARY KEY (`Id`), + UNIQUE KEY `uk_c_inventory` (`CustomerId`, `WarehouseId`, `SkuId`, `BinLocationId`), + KEY `idx_c_inv_sku_wh` (`CustomerId`, `SkuId`, `WarehouseId`) +) COMMENT='仓储-库存余额(按库位)'; + +CREATE TABLE `C_inbound_notice` ( + `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', + `CustomerId` INT NOT NULL COMMENT '客户ID', + `WarehouseId` INT NOT NULL COMMENT '仓库ID', + `NoticeNo` VARCHAR(32) NOT NULL COMMENT '入库单号 IN+雪花', + `MarkReference` VARCHAR(64) NULL COMMENT '唛头参考号', + `InboundType` VARCHAR(16) NOT NULL DEFAULT 'normal' COMMENT 'normal/return', + `ReceiptStatus` VARCHAR(16) NOT NULL DEFAULT 'forecasted' COMMENT 'forecasted/received/completed', + `ExpectedArrivalTime` DATETIME NULL COMMENT '预计到货时间', + `ActualArrivalTime` DATETIME NULL COMMENT '实际到货时间', + `Remark` VARCHAR(512) NULL COMMENT '备注', + `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', + `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', + `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', + `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `UpdateUserId` INT NULL COMMENT '更新人', + `UpdateTime` DATETIME NULL COMMENT '更新时间', + PRIMARY KEY (`Id`), + UNIQUE KEY `uk_c_inbound_notice_no` (`NoticeNo`), + KEY `idx_c_inbound_customer_status` (`CustomerId`, `ReceiptStatus`, `CreateTime`) +) COMMENT='仓储-入库预报主表'; + +CREATE TABLE `C_inbound_box` ( + `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', + `InboundNoticeId` INT NOT NULL COMMENT '入库预报ID → C_inbound_notice.Id', + `BoxSeqNo` VARCHAR(16) NOT NULL COMMENT '箱序号', + `MarkBoxNo` VARCHAR(64) NULL COMMENT '箱唛号/箱号', + `WeightG` DECIMAL(10,2) NULL COMMENT '箱重(g)', + `LengthCm` DECIMAL(10,2) NULL COMMENT '长(cm)', + `WidthCm` DECIMAL(10,2) NULL COMMENT '宽(cm)', + `HeightCm` DECIMAL(10,2) NULL COMMENT '高(cm)', + `IsReceived` TINYINT NOT NULL DEFAULT 0 COMMENT '是否已收货:0-否,1-是', + `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', + `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', + `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', + `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `UpdateUserId` INT NULL COMMENT '更新人', + `UpdateTime` DATETIME NULL COMMENT '更新时间', + PRIMARY KEY (`Id`), + KEY `idx_c_inbound_box_notice` (`InboundNoticeId`, `IsDeleted`) +) COMMENT='仓储-入库预报箱'; + +CREATE TABLE `C_inbound_box_line` ( + `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', + `InboundBoxId` INT NOT NULL COMMENT '入库箱ID → C_inbound_box.Id', + `SkuId` INT NOT NULL COMMENT 'SKU ID → C_sku.Id', + `SkuCode` VARCHAR(64) NOT NULL COMMENT '冗余SKU编码', + `PlannedQty` INT NOT NULL DEFAULT 0 COMMENT '计划入库数量', + `ReceivedQty` INT NULL COMMENT '实收数量', + `BinLocationId` INT NULL COMMENT '上架库位ID → C_bin_location.Id', + `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', + `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', + `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', + `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `UpdateUserId` INT NULL COMMENT '更新人', + `UpdateTime` DATETIME NULL COMMENT '更新时间', + PRIMARY KEY (`Id`), + KEY `idx_c_inbound_box_line_box` (`InboundBoxId`, `IsDeleted`), + KEY `idx_c_inbound_box_line_sku` (`SkuId`) +) COMMENT='仓储-入库箱内SKU行'; + +CREATE TABLE `C_parcel` ( + `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', + `CustomerId` INT NOT NULL COMMENT '客户ID', + `WarehouseId` INT NOT NULL COMMENT '仓库ID', + `TrackingNo` VARCHAR(64) NOT NULL COMMENT '快递单号', + `CarrierName` VARCHAR(64) NULL COMMENT '快递公司', + `LifecycleStatus` VARCHAR(16) NOT NULL DEFAULT 'inTransit' COMMENT 'inTransit/arrived/stored', + `ArrivalTime` DATETIME NULL COMMENT '到仓时间', + `Remark` VARCHAR(512) NULL COMMENT '备注', + `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', + `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', + `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', + `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `UpdateUserId` INT NULL COMMENT '更新人', + `UpdateTime` DATETIME NULL COMMENT '更新时间', + PRIMARY KEY (`Id`), + UNIQUE KEY `uk_c_parcel_tracking` (`CustomerId`, `TrackingNo`, `WarehouseId`), + KEY `idx_c_parcel_status` (`CustomerId`, `LifecycleStatus`) +) COMMENT='仓储-客户包裹'; + +CREATE TABLE `C_parcel_item` ( + `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', + `ParcelId` INT NOT NULL COMMENT '包裹ID → C_parcel.Id', + `ProductName` VARCHAR(512) NULL COMMENT '商品名称', + `Quantity` INT NOT NULL DEFAULT 0 COMMENT '数量', + `SkuId` INT NULL COMMENT '库内SKU ID → C_sku.Id', + `SkuCode` VARCHAR(64) NULL COMMENT '冗余SKU编码', + `BinLocationId` INT NULL COMMENT '上架库位ID', + `Remark` VARCHAR(512) NULL COMMENT '备注', + `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', + `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', + `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', + `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `UpdateUserId` INT NULL COMMENT '更新人', + `UpdateTime` DATETIME NULL COMMENT '更新时间', + PRIMARY KEY (`Id`), + KEY `idx_c_parcel_item_parcel` (`ParcelId`, `IsDeleted`) +) COMMENT='仓储-包裹明细'; + +CREATE TABLE `C_sku_platform_map` ( + `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', + `CustomerId` INT NOT NULL COMMENT '客户ID', + `StoreId` INT NOT NULL COMMENT '店铺ID → t_sales_store.Id', + `PlatformSku` VARCHAR(128) NOT NULL COMMENT '平台listing SKU', + `SkuId` INT NOT NULL COMMENT '库内SKU ID → C_sku.Id', + `SkuCode` VARCHAR(64) NOT NULL COMMENT '冗余SKU编码', + `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', + `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', + `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', + `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `UpdateUserId` INT NULL COMMENT '更新人', + `UpdateTime` DATETIME NULL COMMENT '更新时间', + PRIMARY KEY (`Id`), + UNIQUE KEY `uk_c_sku_map` (`StoreId`, `PlatformSku`), + KEY `idx_c_sku_map_customer` (`CustomerId`, `SkuId`) +) COMMENT='仓储-平台SKU映射'; + +-- --------------------------------------------------------------------------- +-- 订单域 — 店铺(t_sales_*,接口阶段使用) +-- --------------------------------------------------------------------------- + +CREATE TABLE `t_sales_store` ( + `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', + `CustomerId` INT NOT NULL COMMENT '客户ID', + `PlatformCode` VARCHAR(32) NOT NULL COMMENT 'lazada/shopee/tiktok/temu/manual', + `StoreNickname` VARCHAR(128) NOT NULL COMMENT '店铺昵称', + `PlatformStoreId` VARCHAR(64) NULL COMMENT '平台侧店铺ID', + `PlatformAccount` VARCHAR(128) NULL COMMENT '平台账号', + `SiteCountry` VARCHAR(8) NULL COMMENT '开户站点国家码', + `SellerId` VARCHAR(64) NULL COMMENT '平台卖家ID', + `AuthStatus` VARCHAR(16) NOT NULL DEFAULT 'active' COMMENT 'active/expired/revoked', + `AuthTime` DATETIME NULL COMMENT '授权时间', + `TokenExpireTime` DATETIME NULL COMMENT 'AccessToken过期时间', + `RefreshExpireTime` DATETIME NULL COMMENT 'RefreshToken过期时间', + `AccessToken` VARCHAR(2048) NULL COMMENT 'AccessToken(加密存储)', + `RefreshToken` VARCHAR(2048) NULL COMMENT 'RefreshToken(加密存储)', + `TokenExtraJson` JSON NULL COMMENT '平台扩展Token信息', + `IsAutoFulfill` TINYINT NOT NULL DEFAULT 0 COMMENT '是否自动发货:0-否,1-是', + `Remark` VARCHAR(512) NULL COMMENT '备注', + `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', + `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', + `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', + `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `UpdateUserId` INT NULL COMMENT '更新人', + `UpdateTime` DATETIME NULL COMMENT '更新时间', + PRIMARY KEY (`Id`), + KEY `idx_sales_store_customer` (`CustomerId`, `IsDeleted`), + KEY `idx_sales_store_platform` (`CustomerId`, `PlatformCode`, `AuthStatus`) +) COMMENT='销售店铺授权'; + +CREATE TABLE `t_sales_store_order` ( + `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', + `CustomerId` INT NOT NULL COMMENT '客户ID', + `StoreId` INT NOT NULL COMMENT '店铺ID → t_sales_store.Id', + `PlatformCode` VARCHAR(32) NOT NULL COMMENT '平台编码', + `PlatformOrderNo` VARCHAR(64) NOT NULL COMMENT '平台订单号', + `OrderCountry` VARCHAR(8) NULL COMMENT '订单国家', + `ItemCount` INT NULL COMMENT '商品行数', + `TotalAmount` DECIMAL(18,4) NULL COMMENT '订单总额', + `Currency` VARCHAR(8) NULL COMMENT '币种', + `PlatformOrderTime` DATETIME NULL COMMENT '平台下单时间', + `FulfillStatus` VARCHAR(32) NOT NULL DEFAULT 'pending' COMMENT '履约状态', + `PlatformStatus` VARCHAR(64) NULL COMMENT '平台原始状态码', + `PlatformStatusLabel` VARCHAR(128) NULL COMMENT '平台状态展示文案', + `ShippingLabelNo` VARCHAR(64) NULL COMMENT '面单号', + `ShippingLabelUrl` VARCHAR(512) NULL COMMENT '面单URL', + `IsMultiLabel` TINYINT NOT NULL DEFAULT 0 COMMENT '是否多面单', + `CustomTags` VARCHAR(512) NULL COMMENT '自定义标签', + `IsSuspended` TINYINT NOT NULL DEFAULT 0 COMMENT '是否搁置', + `WarehouseId` INT NULL COMMENT '发货仓库ID', + `LinkedOrderId` INT NULL COMMENT '关联小包订单 t_order.Id', + `LastSyncTime` DATETIME NULL COMMENT '最近同步时间', + `PlatformExtraJson` JSON NULL COMMENT '平台扩展字段', + `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', + `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', + `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', + `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `UpdateUserId` INT NULL COMMENT '更新人', + `UpdateTime` DATETIME NULL COMMENT '更新时间', + PRIMARY KEY (`Id`), + UNIQUE KEY `uk_store_order_no` (`StoreId`, `PlatformOrderNo`), + KEY `idx_store_order_customer_status` (`CustomerId`, `FulfillStatus`, `PlatformOrderTime`) +) COMMENT='销售店铺订单'; + +CREATE TABLE `t_sales_store_order_line` ( + `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', + `StoreOrderId` INT NOT NULL COMMENT '店铺订单ID → t_sales_store_order.Id', + `PlatformLineId` VARCHAR(64) NULL COMMENT '平台行ID', + `PlatformSku` VARCHAR(128) NULL COMMENT '平台SKU', + `ProductName` VARCHAR(512) NULL COMMENT '商品名称', + `ProductImageUrl` VARCHAR(512) NULL COMMENT '商品图片', + `VariantText` VARCHAR(256) NULL COMMENT '规格属性', + `UnitPrice` DECIMAL(18,4) NULL COMMENT '单价', + `Quantity` INT NOT NULL DEFAULT 0 COMMENT '数量', + `Currency` VARCHAR(8) NULL COMMENT '币种', + `IsShipExcluded` TINYINT NOT NULL DEFAULT 0 COMMENT '是否拒绝发货', + `MappedSkuId` INT NULL COMMENT '映射库内SKU → C_sku.Id', + `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', + `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', + `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', + `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `UpdateUserId` INT NULL COMMENT '更新人', + `UpdateTime` DATETIME NULL COMMENT '更新时间', + PRIMARY KEY (`Id`), + KEY `idx_store_order_line_order` (`StoreOrderId`, `IsDeleted`) +) COMMENT='销售店铺订单明细'; + +-- 小红书(LIKE AI → OMS)模块,详见设计文档 docs/小红书模块设计-063001.md +CREATE TABLE `t_xhs_agent` ( `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', `CustomerId` INT NOT NULL COMMENT '客户ID → t_customer.Id', `DeviceId` VARCHAR(64) NOT NULL COMMENT 'Agent 本机设备标识', @@ -1165,7 +1509,7 @@ CREATE TABLE IF NOT EXISTS `t_xhs_agent` ( KEY `idx_xhs_agent_customer` (`CustomerId`, `Status`) ) COMMENT='小红书本地 Agent 设备表'; -CREATE TABLE IF NOT EXISTS `t_xhs_task` ( +CREATE TABLE `t_xhs_task` ( `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', `CustomerId` INT NOT NULL COMMENT '客户ID', `AgentId` INT NULL COMMENT '指定执行的 Agent;NULL 表示任意在线 Agent', @@ -1195,7 +1539,7 @@ CREATE TABLE IF NOT EXISTS `t_xhs_task` ( KEY `idx_xhs_task_source` (`Source`, `SourceRefId`) ) COMMENT='小红书 Agent 任务队列表'; -CREATE TABLE IF NOT EXISTS `t_xhs_publish_record` ( +CREATE TABLE `t_xhs_publish_record` ( `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', `CustomerId` INT NOT NULL COMMENT '客户ID', `TaskId` INT NULL COMMENT '关联 t_xhs_task.Id', @@ -1224,7 +1568,7 @@ CREATE TABLE IF NOT EXISTS `t_xhs_publish_record` ( KEY `idx_xhs_publish_task` (`TaskId`) ) COMMENT='小红书发布记录表'; -CREATE TABLE IF NOT EXISTS `t_xhs_analysis_session` ( +CREATE TABLE `t_xhs_analysis_session` ( `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', `CustomerId` INT NOT NULL COMMENT '客户ID', `SessionName` VARCHAR(128) NULL COMMENT '用户备注名', @@ -1245,7 +1589,7 @@ CREATE TABLE IF NOT EXISTS `t_xhs_analysis_session` ( KEY `idx_xhs_analysis_customer` (`CustomerId`, `CreateTime`) ) COMMENT='小红书内容分析会话表'; -CREATE TABLE IF NOT EXISTS `t_xhs_skill` ( +CREATE TABLE `t_xhs_skill` ( `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', `CustomerId` INT NOT NULL COMMENT '客户ID;0 表示系统预置', `ExternalId` VARCHAR(32) NOT NULL COMMENT '对外稳定 ID', @@ -1265,7 +1609,7 @@ CREATE TABLE IF NOT EXISTS `t_xhs_skill` ( KEY `idx_xhs_skill_customer` (`CustomerId`, `SortOrder`) ) COMMENT='小红书技能卡片表'; -CREATE TABLE IF NOT EXISTS `t_xhs_human_config` ( +CREATE TABLE `t_xhs_human_config` ( `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', `CustomerId` INT NOT NULL COMMENT '客户ID', `BehaviorJson` JSON NOT NULL COMMENT 'human_behavior 配置', @@ -1281,7 +1625,7 @@ CREATE TABLE IF NOT EXISTS `t_xhs_human_config` ( UNIQUE KEY `uk_xhs_human_customer` (`CustomerId`) ) COMMENT='小红书拟人行为与防封配置表'; -CREATE TABLE IF NOT EXISTS `t_xhs_ai_provider` ( +CREATE TABLE `t_xhs_ai_provider` ( `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', `CustomerId` INT NOT NULL COMMENT '客户ID;0 表示全局', `ProviderKey` VARCHAR(32) NOT NULL COMMENT 'ai_chatgpt / ai_zhipu 等', @@ -1303,7 +1647,7 @@ CREATE TABLE IF NOT EXISTS `t_xhs_ai_provider` ( KEY `idx_xhs_ai_customer` (`CustomerId`, `Enabled`) ) COMMENT='小红书 AI 提供商配置表'; -CREATE TABLE IF NOT EXISTS `t_xhs_media` ( +CREATE TABLE `t_xhs_media` ( `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', `CustomerId` INT NOT NULL COMMENT '客户ID', `FileName` VARCHAR(256) NOT NULL COMMENT '原始文件名', @@ -1320,4 +1664,282 @@ CREATE TABLE IF NOT EXISTS `t_xhs_media` ( KEY `idx_xhs_media_customer` (`CustomerId`, `CreateTime`) ) COMMENT='小红书创作上传媒体表'; +-- --------------------------------------------------------------------------- +-- 数据权限(RBAC 侧表;若与 OMS 分库,请只在 RBAC 库执行本段) +-- --------------------------------------------------------------------------- +CREATE TABLE `user_org_perm` ( + `Id` CHAR(36) NOT NULL COMMENT '主键 GUID', + `UserId` CHAR(36) NOT NULL COMMENT 'FK user.Id', + `OrganizationId` CHAR(36) NOT NULL COMMENT 'FK organization.Id', + `OrgScope` TINYINT NOT NULL DEFAULT 2 COMMENT '1=仅本级 2=本级+所有下级', + `EffectiveTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '生效时间', + `ExpireTime` DATETIME NULL COMMENT '过期时间,NULL=永久', + `IsTemporary` TINYINT NOT NULL DEFAULT 0 COMMENT '是否临时授权:0否 1是', + `IsDeleted` TINYINT NOT NULL DEFAULT 0, + `CreateUserId` INT NOT NULL DEFAULT 0, + `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + `UpdateUserId` INT NULL, + `UpdateTime` DATETIME NULL, + PRIMARY KEY (`Id`), + KEY `idx_user_org_perm_user` (`UserId`, `IsDeleted`), + KEY `idx_user_org_perm_org` (`OrganizationId`), + KEY `idx_user_org_perm_expire` (`ExpireTime`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户组织数据权限'; + +-- --------------------------------------------------------------------------- +-- 2. 角色组织权限(角色继承 / 模板绑定) +-- --------------------------------------------------------------------------- +CREATE TABLE `role_org_perm` ( + `Id` CHAR(36) NOT NULL, + `RoleId` CHAR(36) NOT NULL COMMENT 'FK role.Id', + `OrganizationId` CHAR(36) NOT NULL, + `OrgScope` TINYINT NOT NULL DEFAULT 2, + `IsDeleted` TINYINT NOT NULL DEFAULT 0, + `CreateUserId` INT NOT NULL DEFAULT 0, + `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + `UpdateUserId` INT NULL, + `UpdateTime` DATETIME NULL, + PRIMARY KEY (`Id`), + UNIQUE KEY `uk_role_org_perm` (`RoleId`, `OrganizationId`, `IsDeleted`), + KEY `idx_role_org_perm_role` (`RoleId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色组织数据权限'; + +-- --------------------------------------------------------------------------- +-- 3. 数据范围(个人/小组/部门/组织树/全局) +-- --------------------------------------------------------------------------- +CREATE TABLE `role_data_scope` ( + `Id` CHAR(36) NOT NULL, + `RoleId` CHAR(36) NOT NULL, + `DataScope` TINYINT NOT NULL COMMENT '1个人 2小组 3部门 4组织树 5全局', + `DataResourceCode` VARCHAR(32) NULL COMMENT 'NULL=全局默认;Order/Customer/Recharge 等', + `IsDeleted` TINYINT NOT NULL DEFAULT 0, + `CreateUserId` INT NOT NULL DEFAULT 0, + `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + `UpdateUserId` INT NULL, + `UpdateTime` DATETIME NULL, + PRIMARY KEY (`Id`), + UNIQUE KEY `uk_role_data_scope` (`RoleId`, `DataResourceCode`, `IsDeleted`), + KEY `idx_role_data_scope_role` (`RoleId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色数据范围'; + +CREATE TABLE `user_data_scope` ( + `Id` CHAR(36) NOT NULL, + `UserId` CHAR(36) NOT NULL, + `DataScope` TINYINT NOT NULL, + `DataResourceCode` VARCHAR(32) NULL, + `EffectiveTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + `ExpireTime` DATETIME NULL, + `IsTemporary` TINYINT NOT NULL DEFAULT 0, + `IsDeleted` TINYINT NOT NULL DEFAULT 0, + `CreateUserId` INT NOT NULL DEFAULT 0, + `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + `UpdateUserId` INT NULL, + `UpdateTime` DATETIME NULL, + PRIMARY KEY (`Id`), + UNIQUE KEY `uk_user_data_scope` (`UserId`, `DataResourceCode`, `IsDeleted`), + KEY `idx_user_data_scope_user` (`UserId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户数据范围(覆盖角色默认)'; + +-- --------------------------------------------------------------------------- +-- 4. 业务维度 +-- --------------------------------------------------------------------------- +CREATE TABLE `role_biz_perm` ( + `Id` CHAR(36) NOT NULL, + `RoleId` CHAR(36) NOT NULL, + `BizType` VARCHAR(32) NOT NULL COMMENT 'product_line/kpi_area/customer_group/warehouse/region', + `BizId` VARCHAR(64) NOT NULL COMMENT '业务主键字符串', + `BizName` VARCHAR(128) NULL COMMENT '冗余展示名', + `IsDeleted` TINYINT NOT NULL DEFAULT 0, + `CreateUserId` INT NOT NULL DEFAULT 0, + `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`Id`), + KEY `idx_role_biz_perm_role` (`RoleId`, `BizType`), + KEY `idx_role_biz_perm_biz` (`BizType`, `BizId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色业务维度权限'; + +CREATE TABLE `user_biz_perm` ( + `Id` CHAR(36) NOT NULL, + `UserId` CHAR(36) NOT NULL, + `BizType` VARCHAR(32) NOT NULL, + `BizId` VARCHAR(64) NOT NULL, + `BizName` VARCHAR(128) NULL, + `EffectiveTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + `ExpireTime` DATETIME NULL, + `IsTemporary` TINYINT NOT NULL DEFAULT 0, + `IsDeleted` TINYINT NOT NULL DEFAULT 0, + `CreateUserId` INT NOT NULL DEFAULT 0, + `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`Id`), + KEY `idx_user_biz_perm_user` (`UserId`, `BizType`), + KEY `idx_user_biz_perm_biz` (`BizType`, `BizId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户业务维度权限'; + +-- --------------------------------------------------------------------------- +-- 5. 密级 +-- --------------------------------------------------------------------------- +CREATE TABLE `role_secret_perm` ( + `Id` CHAR(36) NOT NULL, + `RoleId` CHAR(36) NOT NULL, + `SecretLevel` TINYINT NOT NULL COMMENT '1公开 2内部 3机密 4绝密', + `DataResourceCode` VARCHAR(32) NULL, + `IsDeleted` TINYINT NOT NULL DEFAULT 0, + `CreateUserId` INT NOT NULL DEFAULT 0, + `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`Id`), + KEY `idx_role_secret_perm_role` (`RoleId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色密级权限'; + +CREATE TABLE `user_secret_perm` ( + `Id` CHAR(36) NOT NULL, + `UserId` CHAR(36) NOT NULL, + `SecretLevel` TINYINT NOT NULL, + `DataResourceCode` VARCHAR(32) NULL, + `EffectiveTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + `ExpireTime` DATETIME NULL, + `IsTemporary` TINYINT NOT NULL DEFAULT 0, + `IsDeleted` TINYINT NOT NULL DEFAULT 0, + `CreateUserId` INT NOT NULL DEFAULT 0, + `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`Id`), + KEY `idx_user_secret_perm_user` (`UserId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户密级权限'; + +-- --------------------------------------------------------------------------- +-- 6. 自定义过滤规则(JSON AST,禁止存 SQL) +-- --------------------------------------------------------------------------- +CREATE TABLE `role_filter_rule` ( + `Id` CHAR(36) NOT NULL, + `RoleId` CHAR(36) NOT NULL, + `DataResourceCode` VARCHAR(32) NOT NULL, + `FilterContent` JSON NOT NULL COMMENT '过滤条件 AST', + `FilterHash` CHAR(64) NOT NULL COMMENT 'SHA256(FilterContent)', + `IsDeleted` TINYINT NOT NULL DEFAULT 0, + `CreateUserId` INT NOT NULL DEFAULT 0, + `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + `UpdateUserId` INT NULL, + `UpdateTime` DATETIME NULL, + PRIMARY KEY (`Id`), + UNIQUE KEY `uk_role_filter_rule` (`RoleId`, `DataResourceCode`, `IsDeleted`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色自定义过滤'; + +CREATE TABLE `user_filter_rule` ( + `Id` CHAR(36) NOT NULL, + `UserId` CHAR(36) NOT NULL, + `DataResourceCode` VARCHAR(32) NOT NULL, + `FilterContent` JSON NOT NULL, + `FilterHash` CHAR(64) NOT NULL, + `EffectiveTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + `ExpireTime` DATETIME NULL, + `IsTemporary` TINYINT NOT NULL DEFAULT 0, + `IsDeleted` TINYINT NOT NULL DEFAULT 0, + `CreateUserId` INT NOT NULL DEFAULT 0, + `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + `UpdateUserId` INT NULL, + `UpdateTime` DATETIME NULL, + PRIMARY KEY (`Id`), + UNIQUE KEY `uk_user_filter_rule` (`UserId`, `DataResourceCode`, `IsDeleted`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户自定义过滤'; + +-- --------------------------------------------------------------------------- +-- 7. 数据资源注册(模块接入清单) +-- --------------------------------------------------------------------------- +CREATE TABLE `data_resource` ( + `Id` CHAR(36) NOT NULL, + `Code` VARCHAR(32) NOT NULL COMMENT 'Order/Customer/Recharge/ChannelProduct/Xhs', + `Name` VARCHAR(64) NOT NULL, + `Description` VARCHAR(256) NULL, + `MainTable` VARCHAR(64) NULL COMMENT '主表名,如 t_order', + `OrgField` VARCHAR(64) NULL COMMENT '组织字段名', + `OwnerField` VARCHAR(64) NULL COMMENT '负责人字段名', + `SecretLevelField` VARCHAR(64) NULL DEFAULT 'SecretLevel', + `IsEnabled` TINYINT NOT NULL DEFAULT 1, + `SortOrder` INT NOT NULL DEFAULT 0, + `IsDeleted` TINYINT NOT NULL DEFAULT 0, + `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`Id`), + UNIQUE KEY `uk_data_resource_code` (`Code`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='数据权限资源注册'; + +-- --------------------------------------------------------------------------- +-- 8. 字段脱敏配置 +-- --------------------------------------------------------------------------- +CREATE TABLE `data_perm_field_mask` ( + `Id` CHAR(36) NOT NULL, + `DataResourceCode` VARCHAR(32) NOT NULL, + `FieldName` VARCHAR(64) NOT NULL COMMENT 'DTO/表字段名', + `SecretLevel` TINYINT NOT NULL COMMENT '达到此密级才脱敏', + `MaskType` VARCHAR(32) NOT NULL DEFAULT 'partial' COMMENT 'partial/full/hide', + `MaskPattern` VARCHAR(128) NULL COMMENT '如 phone: 3,4 保留首尾', + `IsEnabled` TINYINT NOT NULL DEFAULT 1, + `IsDeleted` TINYINT NOT NULL DEFAULT 0, + `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`Id`), + UNIQUE KEY `uk_field_mask` (`DataResourceCode`, `FieldName`, `IsDeleted`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='字段级脱敏配置'; + +-- --------------------------------------------------------------------------- +-- 9. 权限模板 +-- --------------------------------------------------------------------------- +CREATE TABLE `data_perm_template` ( + `Id` CHAR(36) NOT NULL, + `Name` VARCHAR(64) NOT NULL, + `Code` VARCHAR(32) NOT NULL COMMENT '模板编码,如 SalesStaff', + `Description` VARCHAR(256) NULL, + `RoleCode` VARCHAR(64) NULL COMMENT '可选绑定 RBAC role.Code,分配角色时自动套用', + `IsBuiltIn` TINYINT NOT NULL DEFAULT 0 COMMENT '内置模板不可删', + `IsDeleted` TINYINT NOT NULL DEFAULT 0, + `CreateUserId` INT NOT NULL DEFAULT 0, + `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + `UpdateUserId` INT NULL, + `UpdateTime` DATETIME NULL, + PRIMARY KEY (`Id`), + UNIQUE KEY `uk_data_perm_template_code` (`Code`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='数据权限模板'; + +CREATE TABLE `data_perm_template_item` ( + `Id` CHAR(36) NOT NULL, + `TemplateId` CHAR(36) NOT NULL, + `DimensionType` VARCHAR(32) NOT NULL COMMENT 'org/data_scope/biz/secret/filter', + `ItemContent` JSON NOT NULL COMMENT '维度配置 JSON', + `SortOrder` INT NOT NULL DEFAULT 0, + `IsDeleted` TINYINT NOT NULL DEFAULT 0, + PRIMARY KEY (`Id`), + KEY `idx_template_item_tpl` (`TemplateId`, `DimensionType`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='数据权限模板明细'; + +-- --------------------------------------------------------------------------- +-- 10. 审计 +-- --------------------------------------------------------------------------- +CREATE TABLE `data_perm_change_log` ( + `Id` BIGINT NOT NULL AUTO_INCREMENT, + `TargetType` VARCHAR(16) NOT NULL COMMENT 'user/role/template', + `TargetId` CHAR(36) NOT NULL, + `Action` VARCHAR(16) NOT NULL COMMENT 'create/update/delete/apply_template', + `BeforeJson` JSON NULL, + `AfterJson` JSON NULL, + `OperatorUserId` CHAR(36) NOT NULL COMMENT '操作人 user.Id', + `OperatorMapId` INT NULL COMMENT '操作人 mapId', + `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`Id`), + KEY `idx_perm_change_target` (`TargetType`, `TargetId`, `CreateTime`), + KEY `idx_perm_change_operator` (`OperatorUserId`, `CreateTime`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='数据权限配置变更日志'; + +CREATE TABLE `data_perm_access_log` ( + `Id` BIGINT NOT NULL AUTO_INCREMENT, + `UserId` CHAR(36) NOT NULL, + `MapId` INT NULL, + `DataResourceCode` VARCHAR(32) NOT NULL, + `ApiPath` VARCHAR(256) NOT NULL, + `HttpMethod` VARCHAR(8) NOT NULL DEFAULT 'GET', + `AppliedScopeJson` JSON NULL COMMENT '生效五维快照', + `RowCount` INT NULL COMMENT '返回行数', + `ElapsedMs` INT NULL, + `ClientIp` VARCHAR(64) NULL, + `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`Id`), + KEY `idx_perm_access_user_time` (`UserId`, `CreateTime`), + KEY `idx_perm_access_resource` (`DataResourceCode`, `CreateTime`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='数据权限访问审计(可采样)'; + SET FOREIGN_KEY_CHECKS = 1; diff --git a/scripts/order_batch_job_tables.sql b/scripts/order_batch_job_tables.sql index efcda15..2bd2e6a 100644 --- a/scripts/order_batch_job_tables.sql +++ b/scripts/order_batch_job_tables.sql @@ -3,7 +3,7 @@ -- -- 注意:必须使用 DROP + CREATE,不能用 IF NOT EXISTS。 -- 若表已存在,IF NOT EXISTS 会跳过建表,表/字段注释不会写入。 --- 若表内已有业务数据,请勿执行本脚本,改用 sql/migrate_t_order_batch_job_comments.sql +-- 若表内已有业务数据,请勿直接 DROP;对照根目录 db.sql 中对应表定义手工补列。 SET FOREIGN_KEY_CHECKS = 0; diff --git a/sql/README.md b/sql/README.md new file mode 100644 index 0000000..41907d1 --- /dev/null +++ b/sql/README.md @@ -0,0 +1,7 @@ +# sql/ + +OMS / 共用库的建表脚本已统一到仓库根目录 `db.sql`。 + +- 新环境:直接执行 `db.sql`(会 DROP 后重建,勿在有生产数据的库上执行) +- 已有库:用 diff 对比 `db.sql` 与现库结构后手工 ALTER,不再维护 `migrate_*.sql` +- 数据权限表(`user_org_perm` 等)若 RBAC 与 OMS 分库,请只在 RBAC 库执行 `db.sql` 末尾对应段落 diff --git a/sql/diagnose_data_perm_bad_guids.sql b/sql/diagnose_data_perm_bad_guids.sql deleted file mode 100644 index a97359a..0000000 --- a/sql/diagnose_data_perm_bad_guids.sql +++ /dev/null @@ -1,62 +0,0 @@ --- 数据权限表:诊断 CHAR(36) 非法 GUID --- 症状:GET /rbac/data-perm/template/list → Could not parse CHAR(36) value as Guid: 1 --- 或其它 data-perm 接口同类报错 --- --- ⚠️ 在 API 实际连接的 RBAC 库执行(与 user/role/menu 同库) - -SET @GUID_RE = '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$'; - -SELECT 'data_perm_template bad Id' AS section, t.`Id`, t.`Name`, t.`Code`, t.`CreateUserId` -FROM `data_perm_template` t -WHERE t.`Id` NOT REGEXP @GUID_RE; - -SELECT 'data_perm_template_item bad Id/TemplateId' AS section, i.`Id`, i.`TemplateId`, i.`DimensionType` -FROM `data_perm_template_item` i -WHERE i.`Id` NOT REGEXP @GUID_RE - OR i.`TemplateId` NOT REGEXP @GUID_RE; - -SELECT 'data_resource bad Id' AS section, r.`Id`, r.`Code`, r.`Name` -FROM `data_resource` r -WHERE r.`Id` NOT REGEXP @GUID_RE; - -SELECT 'data_perm_field_mask bad Id' AS section, f.`Id`, f.`DataResourceCode`, f.`FieldName` -FROM `data_perm_field_mask` f -WHERE f.`Id` NOT REGEXP @GUID_RE; - -SELECT 'user_org_perm bad Id/UserId/OrganizationId' AS section, p.`Id`, p.`UserId`, p.`OrganizationId` -FROM `user_org_perm` p -WHERE p.`Id` NOT REGEXP @GUID_RE - OR p.`UserId` NOT REGEXP @GUID_RE - OR p.`OrganizationId` NOT REGEXP @GUID_RE; - -SELECT 'role_org_perm bad Id/RoleId/OrganizationId' AS section, p.`Id`, p.`RoleId`, p.`OrganizationId` -FROM `role_org_perm` p -WHERE p.`Id` NOT REGEXP @GUID_RE - OR p.`RoleId` NOT REGEXP @GUID_RE - OR p.`OrganizationId` NOT REGEXP @GUID_RE; - -SELECT 'user_data_scope bad Id/UserId' AS section, p.`Id`, p.`UserId`, p.`DataResourceCode` -FROM `user_data_scope` p -WHERE p.`Id` NOT REGEXP @GUID_RE - OR p.`UserId` NOT REGEXP @GUID_RE; - -SELECT 'role_data_scope bad Id/RoleId' AS section, p.`Id`, p.`RoleId`, p.`DataResourceCode` -FROM `role_data_scope` p -WHERE p.`Id` NOT REGEXP @GUID_RE - OR p.`RoleId` NOT REGEXP @GUID_RE; - -SELECT 'data_perm_change_log bad TargetId' AS section, l.`Id`, l.`TargetType`, l.`TargetId`, l.`Action` -FROM `data_perm_change_log` l -WHERE l.`TargetId` NOT REGEXP @GUID_RE; - -SELECT 'data_perm_access_log bad UserId' AS section, l.`Id`, l.`UserId`, l.`DataResourceCode`, l.`ApiPath` -FROM `data_perm_access_log` l -WHERE l.`UserId` NOT REGEXP @GUID_RE; - --- 常见脏值快捷统计 -SELECT 'template Id=1' AS hint, COUNT(*) AS cnt FROM `data_perm_template` WHERE TRIM(`Id`) IN ('0', '1', '2'); -SELECT 'template_item Id=1' AS hint, COUNT(*) AS cnt FROM `data_perm_template_item` WHERE TRIM(`Id`) IN ('0', '1', '2'); -SELECT 'template dp prefix' AS hint, COUNT(*) AS cnt FROM `data_perm_template` WHERE `Id` LIKE 'dp%'; -SELECT 'template dr prefix' AS hint, COUNT(*) AS cnt FROM `data_perm_template` WHERE `Id` LIKE 'dr%'; -SELECT 'data_resource dr000001 prefix' AS hint, COUNT(*) AS cnt FROM `data_resource` WHERE `Id` LIKE 'dr000001-%'; -SELECT 'field_mask fm000001 prefix' AS hint, COUNT(*) AS cnt FROM `data_perm_field_mask` WHERE `Id` LIKE 'fm000001-%'; diff --git a/sql/diagnose_rbac_bad_guids.sql b/sql/diagnose_rbac_bad_guids.sql deleted file mode 100644 index 4f848df..0000000 --- a/sql/diagnose_rbac_bad_guids.sql +++ /dev/null @@ -1,56 +0,0 @@ --- RBAC 库:诊断所有 CHAR(36) / GUID 字段中的非法值(如 "0") --- 症状:登录 / get-menu-tree → Could not parse CHAR(36) value as Guid: 0 --- --- ⚠️ 必须在 API 实际连接的 RBAC 库执行 --- 本地前端 dev(localhost:5173)默认代理到 http://api.nanafa.com/admin → 修本机库无效 - -SET @GUID_RE = '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$'; - -SELECT 'menu bad rows' AS section, m.`Id`, m.`Name`, m.`Route`, m.`PId`, m.`CreateUserId`, m.`UpdateUserId`, m.`ConcurrencyStamp` -FROM `menu` m -WHERE (m.`PId` IS NOT NULL AND m.`PId` NOT REGEXP @GUID_RE) - OR (m.`CreateUserId` IS NOT NULL AND m.`CreateUserId` NOT REGEXP @GUID_RE) - OR (m.`UpdateUserId` IS NOT NULL AND m.`UpdateUserId` NOT REGEXP @GUID_RE) - OR (m.`ConcurrencyStamp` IS NOT NULL AND m.`ConcurrencyStamp` NOT REGEXP @GUID_RE); - -SELECT 'role bad rows' AS section, r.`Id`, r.`Code`, r.`Name`, r.`CreateUserId`, r.`UpdateUserId`, r.`ConcurrencyStamp` -FROM `role` r -WHERE (r.`CreateUserId` IS NOT NULL AND CAST(r.`CreateUserId` AS CHAR) NOT REGEXP @GUID_RE) - OR (r.`UpdateUserId` IS NOT NULL AND CAST(r.`UpdateUserId` AS CHAR) NOT REGEXP @GUID_RE) - OR (r.`ConcurrencyStamp` IS NOT NULL AND r.`ConcurrencyStamp` NOT REGEXP @GUID_RE); - -SELECT 'user bad rows' AS section, u.`Id`, u.`Account`, u.`OrganizationId`, u.`ConcurrencyStamp` -FROM `user` u -WHERE (u.`OrganizationId` IS NOT NULL AND u.`OrganizationId` <> '' AND u.`OrganizationId` NOT REGEXP @GUID_RE) - OR (u.`ConcurrencyStamp` IS NOT NULL AND u.`ConcurrencyStamp` NOT REGEXP @GUID_RE); - -SELECT 'user_role bad rows' AS section, ur.`Id`, ur.`UserId`, ur.`RoleId` -FROM `user_role` ur -WHERE (ur.`UserId` IS NOT NULL AND ur.`UserId` NOT REGEXP @GUID_RE) - OR (ur.`RoleId` IS NOT NULL AND ur.`RoleId` NOT REGEXP @GUID_RE); - -SELECT 'role_permission bad rows' AS section, rp.`Id`, rp.`RoleId`, rp.`PermissionCode`, rp.`CreateUserId` -FROM `role_permission` rp -WHERE (rp.`RoleId` IS NOT NULL AND rp.`RoleId` NOT REGEXP @GUID_RE) - OR (rp.`CreateUserId` IS NOT NULL AND CAST(rp.`CreateUserId` AS CHAR) NOT REGEXP @GUID_RE); - -SELECT 'user_role bad CreateUserId' AS section, ur.`Id`, ur.`UserId`, ur.`RoleId`, ur.`CreateUserId` -FROM `user_role` ur -WHERE ur.`CreateUserId` IS NOT NULL AND CAST(ur.`CreateUserId` AS CHAR) NOT REGEXP @GUID_RE; - -SELECT 'organization bad rows' AS section, o.`Id`, o.`Name`, o.`ParentId`, o.`LeaderId` -FROM `organization` o -WHERE (o.`ParentId` IS NOT NULL AND o.`ParentId` <> '' AND o.`ParentId` NOT REGEXP @GUID_RE) - OR (o.`LeaderId` IS NOT NULL AND o.`LeaderId` <> '' AND o.`LeaderId` NOT REGEXP @GUID_RE) - OR (o.`ConcurrencyStamp` IS NOT NULL AND o.`ConcurrencyStamp` NOT REGEXP @GUID_RE); - --- 快速查 menu 里最常见的脏值(勿只查 Id 列) -SELECT 'menu CreateUserId=0' AS hint, COUNT(*) AS cnt FROM `menu` WHERE CAST(`CreateUserId` AS CHAR) = '0'; -SELECT 'menu UpdateUserId=0' AS hint, COUNT(*) AS cnt FROM `menu` WHERE CAST(`UpdateUserId` AS CHAR) = '0'; -SELECT 'menu PId=0' AS hint, COUNT(*) AS cnt FROM `menu` WHERE CAST(`PId` AS CHAR) = '0'; - -SELECT 'role_permission CreateUserId=0' AS hint, COUNT(*) AS cnt -FROM `role_permission` WHERE CAST(`CreateUserId` AS CHAR) = '0'; - -SELECT 'user_role CreateUserId=0' AS hint, COUNT(*) AS cnt -FROM `user_role` WHERE CAST(`CreateUserId` AS CHAR) = '0'; diff --git a/sql/fix_data_perm_audit_menu.sql b/sql/fix_data_perm_audit_menu.sql deleted file mode 100644 index 27b6611..0000000 --- a/sql/fix_data_perm_audit_menu.sql +++ /dev/null @@ -1,10 +0,0 @@ --- 数据权限审计菜单:accessLog → audit(与前端路由一致) --- 若未执行过旧 seed 可跳过;已存在错误 Route/Component 时执行本脚本 - -UPDATE `menu` -SET - `Route` = '/system/dataPerm/audit', - `Component` = 'views/system/dataPerm/audit/index', - `UpdateTime` = NOW() -WHERE `Id` = 'da100001-0000-4000-8000-000000000004' - OR (`Route` = '/system/dataPerm/accessLog' AND `PermissionCode` = 'Rbac.DataPerm.Audit'); diff --git a/sql/fix_data_perm_menu_invalid_guids.sql b/sql/fix_data_perm_menu_invalid_guids.sql deleted file mode 100644 index eba625b..0000000 --- a/sql/fix_data_perm_menu_invalid_guids.sql +++ /dev/null @@ -1,25 +0,0 @@ --- 修复 menu 表非法 GUID(Id/PId 含非十六进制字符,如 dp100001 中的 p) --- 症状:登录 / get-menu-tree → Could not parse CHAR(36) value as Guid: dp100001-... --- GUID 仅允许 0-9、a-f --- --- ⚠️ 在 RBAC 库执行 - -SELECT 'before fix' AS stage, `Id`, `PId`, `Name`, `Route`, `PermissionCode` -FROM `menu` -WHERE `Id` LIKE 'dp100001-%' - OR `PId` LIKE 'dp100001-%'; - --- 先改子节点 PId,再改 Id -UPDATE `menu` -SET `PId` = REPLACE(`PId`, 'dp100001-', 'da100001-') -WHERE `PId` LIKE 'dp100001-%'; - -UPDATE `menu` -SET `Id` = REPLACE(`Id`, 'dp100001-', 'da100001-') -WHERE `Id` LIKE 'dp100001-%'; - -SELECT 'after fix (should be empty)' AS stage, `Id`, `PId`, `Name`, `Route` -FROM `menu` -WHERE `Id` LIKE 'dp100001-%' - OR `PId` LIKE 'dp100001-%' - OR (`Id` NOT REGEXP '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$'); diff --git a/sql/fix_data_perm_role_permission_bad_guids.sql b/sql/fix_data_perm_role_permission_bad_guids.sql deleted file mode 100644 index b659964..0000000 --- a/sql/fix_data_perm_role_permission_bad_guids.sql +++ /dev/null @@ -1,32 +0,0 @@ --- 修复 role_permission.CreateUserId = '0' 导致登录失败 --- 症状:POST /rbac/auth/login → Could not parse CHAR(36) value as Guid: 0 --- 原因:seed_data_perm_rbac_menu.sql 曾写入 CreateUserId = 0 --- --- ⚠️ 在 RBAC 库(fake_simple_admin 或 API 连接的 RBAC 库)执行 - -SET @ADMIN_USER_ID = ( - SELECT `Id` FROM `user` - WHERE `Account` = 'admin' AND (`IsDeleted` = 0 OR `IsDeleted` IS NULL) - LIMIT 1 -); -SET @ADMIN_USER_ID = IFNULL( - @ADMIN_USER_ID, - (SELECT `Id` FROM `user` WHERE `IsDeleted` = 0 OR `IsDeleted` IS NULL ORDER BY `CreateTime` LIMIT 1) -); - -SELECT @ADMIN_USER_ID AS admin_user_id_used; - -SELECT 'before fix' AS stage, rp.`Id`, rp.`RoleId`, rp.`PermissionCode`, rp.`CreateUserId` -FROM `role_permission` rp -WHERE CAST(rp.`CreateUserId` AS CHAR) = '0' - OR (rp.`CreateUserId` IS NOT NULL AND rp.`CreateUserId` NOT REGEXP '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$'); - -UPDATE `role_permission` -SET `CreateUserId` = @ADMIN_USER_ID -WHERE CAST(`CreateUserId` AS CHAR) = '0' - OR (`CreateUserId` IS NOT NULL AND `CreateUserId` NOT REGEXP '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$'); - -SELECT 'after fix (should be empty)' AS stage, rp.`Id`, rp.`RoleId`, rp.`PermissionCode`, rp.`CreateUserId` -FROM `role_permission` rp -WHERE CAST(rp.`CreateUserId` AS CHAR) = '0' - OR (rp.`CreateUserId` IS NOT NULL AND rp.`CreateUserId` NOT REGEXP '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$'); diff --git a/sql/fix_data_perm_template_bad_guids.sql b/sql/fix_data_perm_template_bad_guids.sql deleted file mode 100644 index 8a9b9d0..0000000 --- a/sql/fix_data_perm_template_bad_guids.sql +++ /dev/null @@ -1,101 +0,0 @@ --- 修复 data_perm_* 表非法 GUID(如 Id='1'、dp/dr 前缀含非 hex 字符) --- 症状:GET /rbac/data-perm/template/list → Could not parse CHAR(36) value as Guid: 1 --- --- ⚠️ 在 RBAC 库执行;执行前先跑 diagnose_data_perm_bad_guids.sql 确认脏数据 --- 若库中从未跑过 install_data_permission.sql,请先执行该脚本再跑本修复 - -SET @GUID_RE = '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$'; - -SELECT 'before fix — bad template rows' AS stage, t.`Id`, t.`Name`, t.`Code` -FROM `data_perm_template` t -WHERE t.`Id` NOT REGEXP @GUID_RE; - --- 1) 旧种子前缀 dp/dr → da(与 install_data_permission.sql 一致) -UPDATE `data_perm_template_item` -SET `TemplateId` = REPLACE(`TemplateId`, 'dp000001-', 'da000001-') -WHERE `TemplateId` LIKE 'dp000001-%'; - -UPDATE `data_perm_template_item` -SET `Id` = REPLACE(`Id`, 'dp200001-', 'da200001-') -WHERE `Id` LIKE 'dp200001-%'; - -UPDATE `data_perm_template_item` -SET `Id` = REPLACE(`Id`, 'dr200001-', 'da200001-') -WHERE `Id` LIKE 'dr200001-%'; - -UPDATE `data_perm_template` -SET `Id` = REPLACE(`Id`, 'dp000001-', 'da000001-') -WHERE `Id` LIKE 'dp000001-%'; - -UPDATE `data_perm_template` -SET `Id` = REPLACE(`Id`, 'dr000001-', 'da000001-') -WHERE `Id` LIKE 'dr000001-%'; - -UPDATE `data_resource` -SET `Id` = REPLACE(`Id`, 'dr000001-', 'da300001-') -WHERE `Id` LIKE 'dr000001-%'; - -UPDATE `data_resource` -SET `Id` = REPLACE(`Id`, 'dr300001-', 'da300001-') -WHERE `Id` LIKE 'dr300001-%'; - -UPDATE `data_resource` -SET `Id` = REPLACE(`Id`, 'dp300001-', 'da300001-') -WHERE `Id` LIKE 'dp300001-%'; - -UPDATE `data_perm_field_mask` -SET `Id` = REPLACE(`Id`, 'fm000001-', 'fa000001-') -WHERE `Id` LIKE 'fm000001-%'; - --- 2) 删除无法自动映射的脏模板 -DELETE FROM `data_perm_template_item` -WHERE `TemplateId` IN ( - SELECT `Id` FROM ( - SELECT `Id` FROM `data_perm_template` WHERE TRIM(`Id`) NOT REGEXP @GUID_RE - ) AS bad_tpl -); - -DELETE FROM `data_perm_template` -WHERE TRIM(`Id`) NOT REGEXP @GUID_RE; - --- 3) 重新插入内置模板(与 install_data_permission.sql §12 一致,可重复执行) -INSERT INTO `data_perm_template` (`Id`, `Name`, `Code`, `Description`, `RoleCode`, `IsBuiltIn`, `CreateUserId`, `CreateTime`) VALUES -('da000001-0000-4000-8000-000000000001', '普通销售', 'SalesStaff', '个人级+指定产品线+密级1-2', NULL, 1, 0, NOW()), -('da000001-0000-4000-8000-000000000002', '销售主管', 'SalesSupervisor', '部门级+全部产品线+密级1-3', NULL, 1, 0, NOW()), -('da000001-0000-4000-8000-000000000003', '分公司经理', 'BranchManager', '组织树级+密级1-3', NULL, 1, 0, NOW()), -('da000001-0000-4000-8000-000000000004', '总部产品经理', 'ProductManager', '全局级+单产品线+密级1-2', NULL, 1, 0, NOW()), -('da000001-0000-4000-8000-000000000005', '财务专员', 'FinanceStaff', '组织树级+密级含3-4', NULL, 1, 0, NOW()), -('da000001-0000-4000-8000-000000000006', '客服专员', 'CsStaff', '个人级+密级1-2', NULL, 1, 0, NOW()) -ON DUPLICATE KEY UPDATE - `Name` = VALUES(`Name`), - `Description` = VALUES(`Description`), - `IsBuiltIn` = VALUES(`IsBuiltIn`); - -INSERT INTO `data_perm_template_item` (`Id`, `TemplateId`, `DimensionType`, `ItemContent`, `SortOrder`) VALUES -('da200001-0000-4000-8000-000000000011', 'da000001-0000-4000-8000-000000000001', 'data_scope', '{"dataScope":1,"dataResourceCode":null}', 1), -('da200001-0000-4000-8000-000000000012', 'da000001-0000-4000-8000-000000000001', 'secret', '{"secretLevels":[1,2]}', 2), -('da200001-0000-4000-8000-000000000021', 'da000001-0000-4000-8000-000000000002', 'data_scope', '{"dataScope":3,"dataResourceCode":null}', 1), -('da200001-0000-4000-8000-000000000022', 'da000001-0000-4000-8000-000000000002', 'secret', '{"secretLevels":[1,2,3]}', 2), -('da200001-0000-4000-8000-000000000031', 'da000001-0000-4000-8000-000000000003', 'data_scope', '{"dataScope":4,"dataResourceCode":null}', 1), -('da200001-0000-4000-8000-000000000032', 'da000001-0000-4000-8000-000000000003', 'secret', '{"secretLevels":[1,2,3]}', 2), -('da200001-0000-4000-8000-000000000041', 'da000001-0000-4000-8000-000000000004', 'data_scope', '{"dataScope":5,"dataResourceCode":null}', 1), -('da200001-0000-4000-8000-000000000042', 'da000001-0000-4000-8000-000000000004', 'secret', '{"secretLevels":[1,2]}', 2), -('da200001-0000-4000-8000-000000000051', 'da000001-0000-4000-8000-000000000005', 'data_scope', '{"dataScope":4,"dataResourceCode":null}', 1), -('da200001-0000-4000-8000-000000000052', 'da000001-0000-4000-8000-000000000005', 'secret', '{"secretLevels":[1,2,3,4]}', 2), -('da200001-0000-4000-8000-000000000061', 'da000001-0000-4000-8000-000000000006', 'data_scope', '{"dataScope":1,"dataResourceCode":null}', 1), -('da200001-0000-4000-8000-000000000062', 'da000001-0000-4000-8000-000000000006', 'secret', '{"secretLevels":[1,2]}', 2) -ON DUPLICATE KEY UPDATE - `ItemContent` = VALUES(`ItemContent`), - `SortOrder` = VALUES(`SortOrder`); - -SELECT 'after fix — bad template' AS stage, t.`Id`, t.`Name`, t.`Code` -FROM `data_perm_template` t -WHERE t.`Id` NOT REGEXP @GUID_RE; - -SELECT 'after fix — bad data_resource' AS stage, r.`Id`, r.`Code`, r.`Name` -FROM `data_resource` r -WHERE r.`Id` NOT REGEXP @GUID_RE; - -SELECT 'after fix — bad field_mask' AS stage, f.`Id`, f.`DataResourceCode`, f.`FieldName` -FROM `data_perm_field_mask` f -WHERE f.`Id` NOT REGEXP @GUID_RE; diff --git a/sql/fix_rbac_bad_guids.sql b/sql/fix_rbac_bad_guids.sql deleted file mode 100644 index 02e2d78..0000000 --- a/sql/fix_rbac_bad_guids.sql +++ /dev/null @@ -1,95 +0,0 @@ --- RBAC 库:修复 GUID 脏数据(menu / role / user / organization 等) --- 与 diagnose_rbac_bad_guids.sql 配套;修复后重新跑诊断应无结果 --- --- ⚠️ 在 API 实际连接的 RBAC 库执行(api.nanafa.com 对应库,不是本机 oms 除非 API 连本机) - -SET @GUID_RE = '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$'; -SET @ROOT_PID = '00000000-0000-0000-0000-000000000000'; - -SET @ADMIN_USER_ID = ( - SELECT `Id` FROM `user` - WHERE `Account` = 'admin' AND (`IsDeleted` = 0 OR `IsDeleted` IS NULL) - LIMIT 1 -); -SET @ADMIN_USER_ID = IFNULL( - @ADMIN_USER_ID, - (SELECT `Id` FROM `user` WHERE `IsDeleted` = 0 OR `IsDeleted` IS NULL ORDER BY `CreateTime` LIMIT 1) -); - -SELECT @ADMIN_USER_ID AS admin_user_id_used; - --- ========== menu ========== -UPDATE `menu` -SET `CreateUserId` = @ADMIN_USER_ID -WHERE `CreateUserId` IS NOT NULL AND `CreateUserId` NOT REGEXP @GUID_RE; - -UPDATE `menu` -SET `UpdateUserId` = @ADMIN_USER_ID -WHERE `UpdateUserId` IS NOT NULL AND `UpdateUserId` NOT REGEXP @GUID_RE; - -UPDATE `menu` -SET `PId` = @ROOT_PID -WHERE `PId` IS NOT NULL AND `PId` NOT REGEXP @GUID_RE; - -UPDATE `menu` -SET `ConcurrencyStamp` = UUID() -WHERE `ConcurrencyStamp` IS NOT NULL AND `ConcurrencyStamp` NOT REGEXP @GUID_RE; - --- 小红书种子菜单(精确 Id) -UPDATE `menu` -SET `CreateUserId` = @ADMIN_USER_ID, - `UpdateUserId` = @ADMIN_USER_ID -WHERE `Id` IN ( - 'a1b2c3d4-e5f6-7890-abcd-ef1234567801', - 'a1b2c3d4-e5f6-7890-abcd-ef1234567802', - 'a1b2c3d4-e5f6-7890-abcd-ef1234567803', - 'a1b2c3d4-e5f6-7890-abcd-ef1234567804', - 'a1b2c3d4-e5f6-7890-abcd-ef1234567805', - 'a1b2c3d4-e5f6-7890-abcd-ef1234567806', - 'a1b2c3d4-e5f6-7890-abcd-ef1234567807', - 'a1b2c3d4-e5f6-7890-abcd-ef1234567808' -); - --- ========== role(若列为 CHAR(36) GUID)========== -UPDATE `role` -SET `CreateUserId` = @ADMIN_USER_ID -WHERE `CreateUserId` IS NOT NULL AND CAST(`CreateUserId` AS CHAR) NOT REGEXP @GUID_RE; - -UPDATE `role` -SET `UpdateUserId` = @ADMIN_USER_ID -WHERE `UpdateUserId` IS NOT NULL AND CAST(`UpdateUserId` AS CHAR) NOT REGEXP @GUID_RE; - -UPDATE `role` -SET `ConcurrencyStamp` = UUID() -WHERE `ConcurrencyStamp` IS NOT NULL AND `ConcurrencyStamp` NOT REGEXP @GUID_RE; - --- ========== user ========== -UPDATE `user` -SET `OrganizationId` = NULL -WHERE `OrganizationId` IS NOT NULL - AND `OrganizationId` <> '' - AND `OrganizationId` NOT REGEXP @GUID_RE; - -UPDATE `user` -SET `ConcurrencyStamp` = UUID() -WHERE `ConcurrencyStamp` IS NOT NULL AND `ConcurrencyStamp` NOT REGEXP @GUID_RE; - --- ========== organization ========== -UPDATE `organization` -SET `ParentId` = NULL -WHERE `ParentId` IS NOT NULL AND `ParentId` <> '' AND `ParentId` NOT REGEXP @GUID_RE; - -UPDATE `organization` -SET `LeaderId` = NULL -WHERE `LeaderId` IS NOT NULL AND `LeaderId` <> '' AND `LeaderId` NOT REGEXP @GUID_RE; - --- ========== role_permission / user_role(登录加载权限时会读 CreateUserId GUID)========== -UPDATE `role_permission` -SET `CreateUserId` = @ADMIN_USER_ID -WHERE `CreateUserId` IS NOT NULL AND CAST(`CreateUserId` AS CHAR) NOT REGEXP @GUID_RE; - -UPDATE `user_role` -SET `CreateUserId` = @ADMIN_USER_ID -WHERE `CreateUserId` IS NOT NULL AND CAST(`CreateUserId` AS CHAR) NOT REGEXP @GUID_RE; - --- 修复后请再执行 diagnose_rbac_bad_guids.sql 确认无脏行 diff --git a/sql/fix_xhs_menu_bad_guids.sql b/sql/fix_xhs_menu_bad_guids.sql deleted file mode 100644 index 8c26fdd..0000000 --- a/sql/fix_xhs_menu_bad_guids.sql +++ /dev/null @@ -1,56 +0,0 @@ --- 修复 menu 表 CreateUserId / UpdateUserId 非法 GUID(如 "0") --- 症状:登录或 GET /rbac/menu/get-menu-tree → Could not parse CHAR(36) value as Guid: 0 --- --- ⚠️ 在 RBAC 库执行(不是 OMS 业务库 fake_simple_admin) --- ⚠️ WHERE 中禁止写 CreateUserId = 0(整数),会触发 1292 GUID 转数字错误 - --- 1) 管理员 GUID:优先 admin 账号,否则取第一个用户 -SET @ADMIN_USER_ID = ( - SELECT `Id` FROM `user` - WHERE `Account` = 'admin' AND (`IsDeleted` = 0 OR `IsDeleted` IS NULL) - LIMIT 1 -); -SET @ADMIN_USER_ID = IFNULL( - @ADMIN_USER_ID, - (SELECT `Id` FROM `user` WHERE `IsDeleted` = 0 OR `IsDeleted` IS NULL ORDER BY `CreateTime` LIMIT 1) -); - -SELECT @ADMIN_USER_ID AS admin_user_id_used; - --- 2) 诊断:修复前查看脏数据 -SELECT `Id`, `Name`, `Route`, `CreateUserId`, `UpdateUserId` -FROM `menu` -WHERE (`CreateUserId` IS NOT NULL AND `CreateUserId` NOT REGEXP '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$') - OR (`UpdateUserId` IS NOT NULL AND `UpdateUserId` NOT REGEXP '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$'); - --- 3) 小红书种子菜单(按 Id 精确修复) -UPDATE `menu` -SET `CreateUserId` = @ADMIN_USER_ID, - `UpdateUserId` = @ADMIN_USER_ID -WHERE `Id` IN ( - 'a1b2c3d4-e5f6-7890-abcd-ef1234567801', - 'a1b2c3d4-e5f6-7890-abcd-ef1234567802', - 'a1b2c3d4-e5f6-7890-abcd-ef1234567803', - 'a1b2c3d4-e5f6-7890-abcd-ef1234567804', - 'a1b2c3d4-e5f6-7890-abcd-ef1234567805', - 'a1b2c3d4-e5f6-7890-abcd-ef1234567806', - 'a1b2c3d4-e5f6-7890-abcd-ef1234567807', - 'a1b2c3d4-e5f6-7890-abcd-ef1234567808' -); - --- 4) 兜底:全表非法 GUID(字符串比较,勿用 = 0) -UPDATE `menu` -SET `CreateUserId` = @ADMIN_USER_ID -WHERE `CreateUserId` IS NOT NULL - AND `CreateUserId` NOT REGEXP '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$'; - -UPDATE `menu` -SET `UpdateUserId` = @ADMIN_USER_ID -WHERE `UpdateUserId` IS NOT NULL - AND `UpdateUserId` NOT REGEXP '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$'; - --- 5) 修复后应无结果 -SELECT `Id`, `Name`, `CreateUserId`, `UpdateUserId` -FROM `menu` -WHERE (`CreateUserId` IS NOT NULL AND `CreateUserId` NOT REGEXP '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$') - OR (`UpdateUserId` IS NOT NULL AND `UpdateUserId` NOT REGEXP '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$'); diff --git a/sql/fix_xhs_menu_parent.sql b/sql/fix_xhs_menu_parent.sql deleted file mode 100644 index a42cbc6..0000000 --- a/sql/fix_xhs_menu_parent.sql +++ /dev/null @@ -1,53 +0,0 @@ --- 修复小红书菜单层级与「启动服务」消失问题 --- RBAC 库执行 --- --- 原因: --- 1. 一级「小红书」PId 必须为 00000000-0000-0000-0000-000000000000 --- 2. 一级目录 PermissionCode 必须为空字符串(列 NOT NULL,不可写 NULL;勿与「启动服务」同权限码) - -SET @ROOT_PID = '00000000-0000-0000-0000-000000000000'; -SET @XHS_PID = 'a1b2c3d4-e5f6-7890-abcd-ef1234567801'; - --- 一级:小红书(目录,PermissionCode 空字符串) -UPDATE `menu` -SET `PId` = @ROOT_PID, - `PermissionCode` = '', - `Route` = '/xhs', - `Component` = NULL, - `Name` = '小红书', - `IsHidden` = 0, - `IsDeleted` = 0 -WHERE `Id` = @XHS_PID; - --- 6 个子菜单挂到「小红书」下 -UPDATE `menu` -SET `PId` = @XHS_PID, - `IsHidden` = 0, - `IsDeleted` = 0 -WHERE `Id` IN ( - 'a1b2c3d4-e5f6-7890-abcd-ef1234567802', -- 启动服务 - 'a1b2c3d4-e5f6-7890-abcd-ef1234567803', -- 内容分析 - 'a1b2c3d4-e5f6-7890-abcd-ef1234567804', -- 爆款创作 - 'a1b2c3d4-e5f6-7890-abcd-ef1234567805', -- 发布记录 - 'a1b2c3d4-e5f6-7890-abcd-ef1234567806', -- 技能卡片 - 'a1b2c3d4-e5f6-7890-abcd-ef1234567807' -- 拟人设置 -); - --- 诊断 -SELECT `Name`, `Route`, `PId`, `PermissionCode`, - CASE - WHEN `Id` = @XHS_PID AND `PId` = @ROOT_PID AND (`PermissionCode` = '' OR `PermissionCode` IS NULL) THEN 'OK' - WHEN `PId` = @XHS_PID THEN 'OK-child' - ELSE 'CHECK' - END AS status -FROM `menu` -WHERE `Id` IN ( - @XHS_PID, - 'a1b2c3d4-e5f6-7890-abcd-ef1234567802', - 'a1b2c3d4-e5f6-7890-abcd-ef1234567803', - 'a1b2c3d4-e5f6-7890-abcd-ef1234567804', - 'a1b2c3d4-e5f6-7890-abcd-ef1234567805', - 'a1b2c3d4-e5f6-7890-abcd-ef1234567806', - 'a1b2c3d4-e5f6-7890-abcd-ef1234567807' -) -ORDER BY `Order`; diff --git a/sql/install_data_permission.sql b/sql/install_data_permission.sql deleted file mode 100644 index 67857bd..0000000 --- a/sql/install_data_permission.sql +++ /dev/null @@ -1,349 +0,0 @@ --- 数据权限模块 — RBAC 侧表结构 --- 设计文档:E:\oms0414\docs\数据权限设计.md --- 与 user / role / organization 同库;表名小写,与 Fake.Rbac 风格一致 --- 执行前请确认已存在 RBAC 基础表 - --- --------------------------------------------------------------------------- --- 1. 用户组织权限 --- --------------------------------------------------------------------------- -CREATE TABLE IF NOT EXISTS `user_org_perm` ( - `Id` CHAR(36) NOT NULL COMMENT '主键 GUID', - `UserId` CHAR(36) NOT NULL COMMENT 'FK user.Id', - `OrganizationId` CHAR(36) NOT NULL COMMENT 'FK organization.Id', - `OrgScope` TINYINT NOT NULL DEFAULT 2 COMMENT '1=仅本级 2=本级+所有下级', - `EffectiveTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '生效时间', - `ExpireTime` DATETIME NULL COMMENT '过期时间,NULL=永久', - `IsTemporary` TINYINT NOT NULL DEFAULT 0 COMMENT '是否临时授权:0否 1是', - `IsDeleted` TINYINT NOT NULL DEFAULT 0, - `CreateUserId` INT NOT NULL DEFAULT 0, - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `UpdateUserId` INT NULL, - `UpdateTime` DATETIME NULL, - PRIMARY KEY (`Id`), - KEY `idx_user_org_perm_user` (`UserId`, `IsDeleted`), - KEY `idx_user_org_perm_org` (`OrganizationId`), - KEY `idx_user_org_perm_expire` (`ExpireTime`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户组织数据权限'; - --- --------------------------------------------------------------------------- --- 2. 角色组织权限(角色继承 / 模板绑定) --- --------------------------------------------------------------------------- -CREATE TABLE IF NOT EXISTS `role_org_perm` ( - `Id` CHAR(36) NOT NULL, - `RoleId` CHAR(36) NOT NULL COMMENT 'FK role.Id', - `OrganizationId` CHAR(36) NOT NULL, - `OrgScope` TINYINT NOT NULL DEFAULT 2, - `IsDeleted` TINYINT NOT NULL DEFAULT 0, - `CreateUserId` INT NOT NULL DEFAULT 0, - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `UpdateUserId` INT NULL, - `UpdateTime` DATETIME NULL, - PRIMARY KEY (`Id`), - UNIQUE KEY `uk_role_org_perm` (`RoleId`, `OrganizationId`, `IsDeleted`), - KEY `idx_role_org_perm_role` (`RoleId`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色组织数据权限'; - --- --------------------------------------------------------------------------- --- 3. 数据范围(个人/小组/部门/组织树/全局) --- --------------------------------------------------------------------------- -CREATE TABLE IF NOT EXISTS `role_data_scope` ( - `Id` CHAR(36) NOT NULL, - `RoleId` CHAR(36) NOT NULL, - `DataScope` TINYINT NOT NULL COMMENT '1个人 2小组 3部门 4组织树 5全局', - `DataResourceCode` VARCHAR(32) NULL COMMENT 'NULL=全局默认;Order/Customer/Recharge 等', - `IsDeleted` TINYINT NOT NULL DEFAULT 0, - `CreateUserId` INT NOT NULL DEFAULT 0, - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `UpdateUserId` INT NULL, - `UpdateTime` DATETIME NULL, - PRIMARY KEY (`Id`), - UNIQUE KEY `uk_role_data_scope` (`RoleId`, `DataResourceCode`, `IsDeleted`), - KEY `idx_role_data_scope_role` (`RoleId`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色数据范围'; - -CREATE TABLE IF NOT EXISTS `user_data_scope` ( - `Id` CHAR(36) NOT NULL, - `UserId` CHAR(36) NOT NULL, - `DataScope` TINYINT NOT NULL, - `DataResourceCode` VARCHAR(32) NULL, - `EffectiveTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `ExpireTime` DATETIME NULL, - `IsTemporary` TINYINT NOT NULL DEFAULT 0, - `IsDeleted` TINYINT NOT NULL DEFAULT 0, - `CreateUserId` INT NOT NULL DEFAULT 0, - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `UpdateUserId` INT NULL, - `UpdateTime` DATETIME NULL, - PRIMARY KEY (`Id`), - UNIQUE KEY `uk_user_data_scope` (`UserId`, `DataResourceCode`, `IsDeleted`), - KEY `idx_user_data_scope_user` (`UserId`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户数据范围(覆盖角色默认)'; - --- --------------------------------------------------------------------------- --- 4. 业务维度 --- --------------------------------------------------------------------------- -CREATE TABLE IF NOT EXISTS `role_biz_perm` ( - `Id` CHAR(36) NOT NULL, - `RoleId` CHAR(36) NOT NULL, - `BizType` VARCHAR(32) NOT NULL COMMENT 'product_line/kpi_area/customer_group/warehouse/region', - `BizId` VARCHAR(64) NOT NULL COMMENT '业务主键字符串', - `BizName` VARCHAR(128) NULL COMMENT '冗余展示名', - `IsDeleted` TINYINT NOT NULL DEFAULT 0, - `CreateUserId` INT NOT NULL DEFAULT 0, - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - PRIMARY KEY (`Id`), - KEY `idx_role_biz_perm_role` (`RoleId`, `BizType`), - KEY `idx_role_biz_perm_biz` (`BizType`, `BizId`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色业务维度权限'; - -CREATE TABLE IF NOT EXISTS `user_biz_perm` ( - `Id` CHAR(36) NOT NULL, - `UserId` CHAR(36) NOT NULL, - `BizType` VARCHAR(32) NOT NULL, - `BizId` VARCHAR(64) NOT NULL, - `BizName` VARCHAR(128) NULL, - `EffectiveTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `ExpireTime` DATETIME NULL, - `IsTemporary` TINYINT NOT NULL DEFAULT 0, - `IsDeleted` TINYINT NOT NULL DEFAULT 0, - `CreateUserId` INT NOT NULL DEFAULT 0, - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - PRIMARY KEY (`Id`), - KEY `idx_user_biz_perm_user` (`UserId`, `BizType`), - KEY `idx_user_biz_perm_biz` (`BizType`, `BizId`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户业务维度权限'; - --- --------------------------------------------------------------------------- --- 5. 密级 --- --------------------------------------------------------------------------- -CREATE TABLE IF NOT EXISTS `role_secret_perm` ( - `Id` CHAR(36) NOT NULL, - `RoleId` CHAR(36) NOT NULL, - `SecretLevel` TINYINT NOT NULL COMMENT '1公开 2内部 3机密 4绝密', - `DataResourceCode` VARCHAR(32) NULL, - `IsDeleted` TINYINT NOT NULL DEFAULT 0, - `CreateUserId` INT NOT NULL DEFAULT 0, - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - PRIMARY KEY (`Id`), - KEY `idx_role_secret_perm_role` (`RoleId`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色密级权限'; - -CREATE TABLE IF NOT EXISTS `user_secret_perm` ( - `Id` CHAR(36) NOT NULL, - `UserId` CHAR(36) NOT NULL, - `SecretLevel` TINYINT NOT NULL, - `DataResourceCode` VARCHAR(32) NULL, - `EffectiveTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `ExpireTime` DATETIME NULL, - `IsTemporary` TINYINT NOT NULL DEFAULT 0, - `IsDeleted` TINYINT NOT NULL DEFAULT 0, - `CreateUserId` INT NOT NULL DEFAULT 0, - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - PRIMARY KEY (`Id`), - KEY `idx_user_secret_perm_user` (`UserId`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户密级权限'; - --- --------------------------------------------------------------------------- --- 6. 自定义过滤规则(JSON AST,禁止存 SQL) --- --------------------------------------------------------------------------- -CREATE TABLE IF NOT EXISTS `role_filter_rule` ( - `Id` CHAR(36) NOT NULL, - `RoleId` CHAR(36) NOT NULL, - `DataResourceCode` VARCHAR(32) NOT NULL, - `FilterContent` JSON NOT NULL COMMENT '过滤条件 AST', - `FilterHash` CHAR(64) NOT NULL COMMENT 'SHA256(FilterContent)', - `IsDeleted` TINYINT NOT NULL DEFAULT 0, - `CreateUserId` INT NOT NULL DEFAULT 0, - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `UpdateUserId` INT NULL, - `UpdateTime` DATETIME NULL, - PRIMARY KEY (`Id`), - UNIQUE KEY `uk_role_filter_rule` (`RoleId`, `DataResourceCode`, `IsDeleted`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色自定义过滤'; - -CREATE TABLE IF NOT EXISTS `user_filter_rule` ( - `Id` CHAR(36) NOT NULL, - `UserId` CHAR(36) NOT NULL, - `DataResourceCode` VARCHAR(32) NOT NULL, - `FilterContent` JSON NOT NULL, - `FilterHash` CHAR(64) NOT NULL, - `EffectiveTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `ExpireTime` DATETIME NULL, - `IsTemporary` TINYINT NOT NULL DEFAULT 0, - `IsDeleted` TINYINT NOT NULL DEFAULT 0, - `CreateUserId` INT NOT NULL DEFAULT 0, - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `UpdateUserId` INT NULL, - `UpdateTime` DATETIME NULL, - PRIMARY KEY (`Id`), - UNIQUE KEY `uk_user_filter_rule` (`UserId`, `DataResourceCode`, `IsDeleted`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户自定义过滤'; - --- --------------------------------------------------------------------------- --- 7. 数据资源注册(模块接入清单) --- --------------------------------------------------------------------------- -CREATE TABLE IF NOT EXISTS `data_resource` ( - `Id` CHAR(36) NOT NULL, - `Code` VARCHAR(32) NOT NULL COMMENT 'Order/Customer/Recharge/ChannelProduct/Xhs', - `Name` VARCHAR(64) NOT NULL, - `Description` VARCHAR(256) NULL, - `MainTable` VARCHAR(64) NULL COMMENT '主表名,如 t_order', - `OrgField` VARCHAR(64) NULL COMMENT '组织字段名', - `OwnerField` VARCHAR(64) NULL COMMENT '负责人字段名', - `SecretLevelField` VARCHAR(64) NULL DEFAULT 'SecretLevel', - `IsEnabled` TINYINT NOT NULL DEFAULT 1, - `SortOrder` INT NOT NULL DEFAULT 0, - `IsDeleted` TINYINT NOT NULL DEFAULT 0, - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - PRIMARY KEY (`Id`), - UNIQUE KEY `uk_data_resource_code` (`Code`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='数据权限资源注册'; - --- --------------------------------------------------------------------------- --- 8. 字段脱敏配置 --- --------------------------------------------------------------------------- -CREATE TABLE IF NOT EXISTS `data_perm_field_mask` ( - `Id` CHAR(36) NOT NULL, - `DataResourceCode` VARCHAR(32) NOT NULL, - `FieldName` VARCHAR(64) NOT NULL COMMENT 'DTO/表字段名', - `SecretLevel` TINYINT NOT NULL COMMENT '达到此密级才脱敏', - `MaskType` VARCHAR(32) NOT NULL DEFAULT 'partial' COMMENT 'partial/full/hide', - `MaskPattern` VARCHAR(128) NULL COMMENT '如 phone: 3,4 保留首尾', - `IsEnabled` TINYINT NOT NULL DEFAULT 1, - `IsDeleted` TINYINT NOT NULL DEFAULT 0, - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - PRIMARY KEY (`Id`), - UNIQUE KEY `uk_field_mask` (`DataResourceCode`, `FieldName`, `IsDeleted`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='字段级脱敏配置'; - --- --------------------------------------------------------------------------- --- 9. 权限模板 --- --------------------------------------------------------------------------- -CREATE TABLE IF NOT EXISTS `data_perm_template` ( - `Id` CHAR(36) NOT NULL, - `Name` VARCHAR(64) NOT NULL, - `Code` VARCHAR(32) NOT NULL COMMENT '模板编码,如 SalesStaff', - `Description` VARCHAR(256) NULL, - `RoleCode` VARCHAR(64) NULL COMMENT '可选绑定 RBAC role.Code,分配角色时自动套用', - `IsBuiltIn` TINYINT NOT NULL DEFAULT 0 COMMENT '内置模板不可删', - `IsDeleted` TINYINT NOT NULL DEFAULT 0, - `CreateUserId` INT NOT NULL DEFAULT 0, - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `UpdateUserId` INT NULL, - `UpdateTime` DATETIME NULL, - PRIMARY KEY (`Id`), - UNIQUE KEY `uk_data_perm_template_code` (`Code`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='数据权限模板'; - -CREATE TABLE IF NOT EXISTS `data_perm_template_item` ( - `Id` CHAR(36) NOT NULL, - `TemplateId` CHAR(36) NOT NULL, - `DimensionType` VARCHAR(32) NOT NULL COMMENT 'org/data_scope/biz/secret/filter', - `ItemContent` JSON NOT NULL COMMENT '维度配置 JSON', - `SortOrder` INT NOT NULL DEFAULT 0, - `IsDeleted` TINYINT NOT NULL DEFAULT 0, - PRIMARY KEY (`Id`), - KEY `idx_template_item_tpl` (`TemplateId`, `DimensionType`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='数据权限模板明细'; - --- --------------------------------------------------------------------------- --- 10. 审计 --- --------------------------------------------------------------------------- -CREATE TABLE IF NOT EXISTS `data_perm_change_log` ( - `Id` BIGINT NOT NULL AUTO_INCREMENT, - `TargetType` VARCHAR(16) NOT NULL COMMENT 'user/role/template', - `TargetId` CHAR(36) NOT NULL, - `Action` VARCHAR(16) NOT NULL COMMENT 'create/update/delete/apply_template', - `BeforeJson` JSON NULL, - `AfterJson` JSON NULL, - `OperatorUserId` CHAR(36) NOT NULL COMMENT '操作人 user.Id', - `OperatorMapId` INT NULL COMMENT '操作人 mapId', - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - PRIMARY KEY (`Id`), - KEY `idx_perm_change_target` (`TargetType`, `TargetId`, `CreateTime`), - KEY `idx_perm_change_operator` (`OperatorUserId`, `CreateTime`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='数据权限配置变更日志'; - -CREATE TABLE IF NOT EXISTS `data_perm_access_log` ( - `Id` BIGINT NOT NULL AUTO_INCREMENT, - `UserId` CHAR(36) NOT NULL, - `MapId` INT NULL, - `DataResourceCode` VARCHAR(32) NOT NULL, - `ApiPath` VARCHAR(256) NOT NULL, - `HttpMethod` VARCHAR(8) NOT NULL DEFAULT 'GET', - `AppliedScopeJson` JSON NULL COMMENT '生效五维快照', - `RowCount` INT NULL COMMENT '返回行数', - `ElapsedMs` INT NULL, - `ClientIp` VARCHAR(64) NULL, - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - PRIMARY KEY (`Id`), - KEY `idx_perm_access_user_time` (`UserId`, `CreateTime`), - KEY `idx_perm_access_resource` (`DataResourceCode`, `CreateTime`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='数据权限访问审计(可采样)'; - --- --------------------------------------------------------------------------- --- 11. 种子:数据资源注册 --- --------------------------------------------------------------------------- -INSERT INTO `data_resource` (`Id`, `Code`, `Name`, `Description`, `MainTable`, `OrgField`, `OwnerField`, `SortOrder`) VALUES -('da300001-0000-4000-8000-000000000001', 'Order', '订单', '运营后台订单查询', 't_order', 'OrganizationId', 'CreateUserId', 10), -('da300001-0000-4000-8000-000000000002', 'Customer', '客户', '客户资料列表', 't_customer', 'OrganizationId', 'Salesman', 20), -('da300001-0000-4000-8000-000000000003', 'Recharge', '充值', '充值审核列表', 't_recharge_record', NULL, 'CreateUserId', 30), -('da300001-0000-4000-8000-000000000004', 'ChannelProduct', '销售产品', '渠道产品配置', 't_sales_product', NULL, NULL, 40), -('da300001-0000-4000-8000-000000000005', 'Xhs', '小红书', '小红书模块', NULL, NULL, NULL, 50) -ON DUPLICATE KEY UPDATE - `Name` = VALUES(`Name`), - `Description` = VALUES(`Description`), - `MainTable` = VALUES(`MainTable`), - `OrgField` = VALUES(`OrgField`), - `OwnerField` = VALUES(`OwnerField`); - --- --------------------------------------------------------------------------- --- 12. 种子:内置权限模板(明细需按环境组织 Id 调整后再 apply) --- --------------------------------------------------------------------------- -INSERT INTO `data_perm_template` (`Id`, `Name`, `Code`, `Description`, `RoleCode`, `IsBuiltIn`, `CreateUserId`, `CreateTime`) VALUES -('da000001-0000-4000-8000-000000000001', '普通销售', 'SalesStaff', '个人级+指定产品线+密级1-2', NULL, 1, 0, NOW()), -('da000001-0000-4000-8000-000000000002', '销售主管', 'SalesSupervisor', '部门级+全部产品线+密级1-3', NULL, 1, 0, NOW()), -('da000001-0000-4000-8000-000000000003', '分公司经理', 'BranchManager', '组织树级+密级1-3', NULL, 1, 0, NOW()), -('da000001-0000-4000-8000-000000000004', '总部产品经理', 'ProductManager', '全局级+单产品线+密级1-2', NULL, 1, 0, NOW()), -('da000001-0000-4000-8000-000000000005', '财务专员', 'FinanceStaff', '组织树级+密级含3-4', NULL, 1, 0, NOW()), -('da000001-0000-4000-8000-000000000006', '客服专员', 'CsStaff', '个人级+密级1-2', NULL, 1, 0, NOW()) -ON DUPLICATE KEY UPDATE - `Name` = VALUES(`Name`), - `Description` = VALUES(`Description`); - -INSERT INTO `data_perm_template_item` (`Id`, `TemplateId`, `DimensionType`, `ItemContent`, `SortOrder`) VALUES --- 普通销售 -('da200001-0000-4000-8000-000000000011', 'da000001-0000-4000-8000-000000000001', 'data_scope', '{"dataScope":1,"dataResourceCode":null}', 1), -('da200001-0000-4000-8000-000000000012', 'da000001-0000-4000-8000-000000000001', 'secret', '{"secretLevels":[1,2]}', 2), --- 销售主管 -('da200001-0000-4000-8000-000000000021', 'da000001-0000-4000-8000-000000000002', 'data_scope', '{"dataScope":3,"dataResourceCode":null}', 1), -('da200001-0000-4000-8000-000000000022', 'da000001-0000-4000-8000-000000000002', 'secret', '{"secretLevels":[1,2,3]}', 2), --- 分公司经理 -('da200001-0000-4000-8000-000000000031', 'da000001-0000-4000-8000-000000000003', 'data_scope', '{"dataScope":4,"dataResourceCode":null}', 1), -('da200001-0000-4000-8000-000000000032', 'da000001-0000-4000-8000-000000000003', 'secret', '{"secretLevels":[1,2,3]}', 2), --- 总部产品经理 -('da200001-0000-4000-8000-000000000041', 'da000001-0000-4000-8000-000000000004', 'data_scope', '{"dataScope":5,"dataResourceCode":null}', 1), -('da200001-0000-4000-8000-000000000042', 'da000001-0000-4000-8000-000000000004', 'secret', '{"secretLevels":[1,2]}', 2), --- 财务专员 -('da200001-0000-4000-8000-000000000051', 'da000001-0000-4000-8000-000000000005', 'data_scope', '{"dataScope":4,"dataResourceCode":null}', 1), -('da200001-0000-4000-8000-000000000052', 'da000001-0000-4000-8000-000000000005', 'secret', '{"secretLevels":[1,2,3,4]}', 2), --- 客服专员 -('da200001-0000-4000-8000-000000000061', 'da000001-0000-4000-8000-000000000006', 'data_scope', '{"dataScope":1,"dataResourceCode":null}', 1), -('da200001-0000-4000-8000-000000000062', 'da000001-0000-4000-8000-000000000006', 'secret', '{"secretLevels":[1,2]}', 2) -ON DUPLICATE KEY UPDATE - `ItemContent` = VALUES(`ItemContent`), - `SortOrder` = VALUES(`SortOrder`); - --- --------------------------------------------------------------------------- --- 13. 种子:字段脱敏(Customer / Order) --- --------------------------------------------------------------------------- -INSERT INTO `data_perm_field_mask` (`Id`, `DataResourceCode`, `FieldName`, `SecretLevel`, `MaskType`, `MaskPattern`) VALUES -('fa000001-0000-4000-8000-000000000001', 'Customer', 'Phone', 4, 'partial', 'phone'), -('fa000001-0000-4000-8000-000000000002', 'Customer', 'Email', 4, 'partial', 'email'), -('fa000001-0000-4000-8000-000000000003', 'Customer', 'Password', 1, 'hide', NULL), -('fa000001-0000-4000-8000-000000000004', 'Order', 'PayableAmount', 3, 'hide', NULL), -('fa000001-0000-4000-8000-000000000005', 'Order', 'CostAmount', 3, 'hide', NULL), -('fa000001-0000-4000-8000-000000000006', 'Order', 'ProfitAmount', 4, 'hide', NULL) -ON DUPLICATE KEY UPDATE - `SecretLevel` = VALUES(`SecretLevel`), - `MaskType` = VALUES(`MaskType`); diff --git a/sql/install_xhs_module.sql b/sql/install_xhs_module.sql deleted file mode 100644 index b652b76..0000000 --- a/sql/install_xhs_module.sql +++ /dev/null @@ -1,219 +0,0 @@ --- 小红书模块:建表 + 业务种子数据(在 OMS 库 fake_simple_admin / oms 执行) --- 执行顺序:本文件 → seed_xhs_rbac_menu.sql(RBAC 库 menu 表)→ seed_xhs_role_permissions.sql --- --- Navicat:选中 OMS 业务库后运行本文件 - --- ========== 1. 建表 migrate_t_xhs.sql ========== --- (内容与 migrate_t_xhs.sql 相同,便于一键安装) - -CREATE TABLE IF NOT EXISTS `t_xhs_agent` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', - `CustomerId` INT NOT NULL COMMENT '客户ID → t_customer.Id', - `DeviceId` VARCHAR(64) NOT NULL COMMENT 'Agent 本机设备标识', - `DeviceName` VARCHAR(128) NULL COMMENT '用户自定义名称', - `AgentVersion` VARCHAR(32) NULL COMMENT 'Agent 版本号', - `BridgePort` INT NOT NULL DEFAULT 9333 COMMENT 'Bridge WebSocket 端口', - `Status` VARCHAR(16) NOT NULL DEFAULT 'offline' COMMENT 'online/offline', - `EngineRunning` TINYINT NOT NULL DEFAULT 0 COMMENT 'Bridge 引擎是否运行', - `ExtensionConnected` TINYINT NOT NULL DEFAULT 0 COMMENT 'Chrome 扩展是否连上 Bridge', - `XhsLoggedIn` TINYINT NOT NULL DEFAULT 0 COMMENT '小红书是否已登录', - `LastHeartbeatTime` DATETIME NULL COMMENT '最后心跳时间', - `LastError` VARCHAR(512) NULL COMMENT '最近一次 Agent 上报错误摘要', - `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', - `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', - `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `UpdateUserId` INT NULL COMMENT '更新人', - `UpdateTime` DATETIME NULL COMMENT '更新时间', - PRIMARY KEY (`Id`), - UNIQUE KEY `uk_xhs_agent_device` (`DeviceId`), - KEY `idx_xhs_agent_customer` (`CustomerId`, `Status`) -) COMMENT='小红书本地 Agent 设备表'; - -CREATE TABLE IF NOT EXISTS `t_xhs_task` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', - `CustomerId` INT NOT NULL COMMENT '客户ID', - `AgentId` INT NULL COMMENT '指定执行的 Agent;NULL 表示任意在线 Agent', - `TaskType` VARCHAR(32) NOT NULL COMMENT '任务类型', - `ToolName` VARCHAR(64) NULL COMMENT 'LIKE AI 工具名', - `Priority` INT NOT NULL DEFAULT 0 COMMENT '越大越优先', - `Status` VARCHAR(16) NOT NULL DEFAULT 'pending' COMMENT 'pending/claimed/running/succeeded/failed/cancelled', - `ArgumentsJson` JSON NOT NULL COMMENT '工具参数 JSON', - `ProgressText` VARCHAR(512) NULL COMMENT '执行过程摘要', - `ResultJson` JSON NULL COMMENT '成功时结构化结果', - `ErrorMessage` VARCHAR(1024) NULL COMMENT '失败原因', - `Source` VARCHAR(32) NOT NULL DEFAULT 'web' COMMENT 'web/schedule/skill', - `SourceRefId` VARCHAR(64) NULL COMMENT '来源关联 ID', - `ScheduledTime` DATETIME NULL COMMENT '计划执行时间', - `ClaimedAt` DATETIME NULL COMMENT 'Agent 认领时间', - `StartedAt` DATETIME NULL COMMENT '开始执行', - `FinishedAt` DATETIME NULL COMMENT '结束时间', - `IsDeleted` TINYINT NOT NULL DEFAULT 0, - `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()), - `CreateUserId` INT NOT NULL DEFAULT 0, - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `UpdateUserId` INT NULL, - `UpdateTime` DATETIME NULL, - PRIMARY KEY (`Id`), - KEY `idx_xhs_task_poll` (`CustomerId`, `Status`, `ScheduledTime`, `Priority`), - KEY `idx_xhs_task_agent` (`AgentId`, `Status`), - KEY `idx_xhs_task_source` (`Source`, `SourceRefId`) -) COMMENT='小红书 Agent 任务队列表'; - -CREATE TABLE IF NOT EXISTS `t_xhs_publish_record` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', - `CustomerId` INT NOT NULL COMMENT '客户ID', - `TaskId` INT NULL COMMENT '关联 t_xhs_task.Id', - `ToolName` VARCHAR(64) NOT NULL COMMENT 'publish_content / publish_with_video', - `Title` VARCHAR(256) NOT NULL COMMENT '笔记标题', - `ContentPreview` VARCHAR(512) NULL COMMENT '正文摘要', - `ContentFull` TEXT NULL COMMENT '完整正文', - `MediaJson` JSON NULL COMMENT '图片/视频 URL 列表', - `TagsJson` JSON NULL COMMENT '标签数组', - `Visibility` VARCHAR(32) NULL COMMENT '可见范围', - `Status` VARCHAR(16) NOT NULL DEFAULT 'draft' COMMENT 'draft/scheduled/publishing/succeeded/failed/cancelled', - `Success` TINYINT NULL COMMENT '最终是否成功', - `ResultSummary` VARCHAR(1024) NULL COMMENT 'Agent 回传结果摘要', - `ScheduledTime` DATETIME NULL COMMENT '定时发布时间', - `PublishedTime` DATETIME NULL COMMENT '实际发布完成时间', - `SkillId` INT NULL COMMENT '若来自技能卡片', - `IsDeleted` TINYINT NOT NULL DEFAULT 0, - `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()), - `CreateUserId` INT NOT NULL DEFAULT 0, - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `UpdateUserId` INT NULL, - `UpdateTime` DATETIME NULL, - PRIMARY KEY (`Id`), - KEY `idx_xhs_publish_customer_time` (`CustomerId`, `CreateTime`), - KEY `idx_xhs_publish_status_sched` (`CustomerId`, `Status`, `ScheduledTime`), - KEY `idx_xhs_publish_task` (`TaskId`) -) COMMENT='小红书发布记录表'; - -CREATE TABLE IF NOT EXISTS `t_xhs_analysis_session` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', - `CustomerId` INT NOT NULL COMMENT '客户ID', - `SessionName` VARCHAR(128) NULL COMMENT '用户备注名', - `AnalysisType` VARCHAR(32) NOT NULL COMMENT 'home_feed/search/my_feeds/feed_detail', - `Keyword` VARCHAR(128) NULL COMMENT '搜索关键词', - `TaskId` INT NULL COMMENT '采集任务 ID', - `FeedsJson` JSON NULL COMMENT '采集笔记列表', - `SelectedFeedId` VARCHAR(64) NULL COMMENT '当前选中笔记 ID', - `AiAnalysisMarkdown` MEDIUMTEXT NULL COMMENT 'AI 分析结果', - `SkillId` INT NULL COMMENT '技能配方 ID', - `IsDeleted` TINYINT NOT NULL DEFAULT 0, - `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()), - `CreateUserId` INT NOT NULL DEFAULT 0, - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `UpdateUserId` INT NULL, - `UpdateTime` DATETIME NULL, - PRIMARY KEY (`Id`), - KEY `idx_xhs_analysis_customer` (`CustomerId`, `CreateTime`) -) COMMENT='小红书内容分析会话表'; - -CREATE TABLE IF NOT EXISTS `t_xhs_skill` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', - `CustomerId` INT NOT NULL COMMENT '客户ID;0 表示系统预置', - `ExternalId` VARCHAR(32) NOT NULL COMMENT '对外稳定 ID', - `Title` VARCHAR(256) NOT NULL COMMENT '技能名称', - `SkillType` VARCHAR(32) NOT NULL DEFAULT 'ai_create' COMMENT '技能类型', - `PresetId` VARCHAR(64) NULL COMMENT '内置预设标识', - `RecipeJson` JSON NOT NULL COMMENT '配方 JSON', - `SortOrder` INT NOT NULL DEFAULT 0 COMMENT '排序', - `IsDeleted` TINYINT NOT NULL DEFAULT 0, - `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()), - `CreateUserId` INT NOT NULL DEFAULT 0, - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `UpdateUserId` INT NULL, - `UpdateTime` DATETIME NULL, - PRIMARY KEY (`Id`), - UNIQUE KEY `uk_xhs_skill_external` (`CustomerId`, `ExternalId`), - KEY `idx_xhs_skill_customer` (`CustomerId`, `SortOrder`) -) COMMENT='小红书技能卡片表'; - -CREATE TABLE IF NOT EXISTS `t_xhs_human_config` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', - `CustomerId` INT NOT NULL COMMENT '客户ID', - `BehaviorJson` JSON NOT NULL COMMENT 'human_behavior 配置', - `GuardJson` JSON NOT NULL COMMENT 'human_guard 配置', - `Version` INT NOT NULL DEFAULT 1 COMMENT '配置版本', - `IsDeleted` TINYINT NOT NULL DEFAULT 0, - `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()), - `CreateUserId` INT NOT NULL DEFAULT 0, - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `UpdateUserId` INT NULL, - `UpdateTime` DATETIME NULL, - PRIMARY KEY (`Id`), - UNIQUE KEY `uk_xhs_human_customer` (`CustomerId`) -) COMMENT='小红书拟人行为与防封配置表'; - -CREATE TABLE IF NOT EXISTS `t_xhs_ai_provider` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', - `CustomerId` INT NOT NULL COMMENT '客户ID;0 表示全局', - `ProviderKey` VARCHAR(32) NOT NULL COMMENT 'ai_chatgpt / ai_zhipu 等', - `ProviderType` VARCHAR(32) NOT NULL COMMENT 'chatgpt/doubao/deepseek/zhipu', - `DisplayName` VARCHAR(64) NOT NULL COMMENT '展示名', - `BaseUrl` VARCHAR(512) NOT NULL COMMENT 'API Base URL', - `ApiKeyEnc` VARCHAR(512) NULL COMMENT 'API Key(暂明文,后续可加密)', - `ApiSecretEnc` VARCHAR(512) NULL COMMENT 'Secret/模型名', - `IsDefault` TINYINT NOT NULL DEFAULT 0 COMMENT '是否默认', - `Enabled` TINYINT NOT NULL DEFAULT 1 COMMENT '是否启用', - `IsDeleted` TINYINT NOT NULL DEFAULT 0, - `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()), - `CreateUserId` INT NOT NULL DEFAULT 0, - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `UpdateUserId` INT NULL, - `UpdateTime` DATETIME NULL, - PRIMARY KEY (`Id`), - UNIQUE KEY `uk_xhs_ai_provider` (`CustomerId`, `ProviderKey`), - KEY `idx_xhs_ai_customer` (`CustomerId`, `Enabled`) -) COMMENT='小红书 AI 提供商配置表'; - -CREATE TABLE IF NOT EXISTS `t_xhs_media` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', - `CustomerId` INT NOT NULL COMMENT '客户ID', - `FileName` VARCHAR(256) NOT NULL COMMENT '原始文件名', - `StoragePath` VARCHAR(512) NOT NULL COMMENT '相对路径', - `PublicUrl` VARCHAR(512) NOT NULL COMMENT '对外 HTTPS URL', - `MimeType` VARCHAR(64) NULL COMMENT 'MIME', - `FileSizeBytes` BIGINT NULL COMMENT '字节数', - `IsDeleted` TINYINT NOT NULL DEFAULT 0, - `CreateUserId` INT NOT NULL DEFAULT 0, - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `UpdateUserId` INT NULL, - `UpdateTime` DATETIME NULL, - PRIMARY KEY (`Id`), - KEY `idx_xhs_media_customer` (`CustomerId`, `CreateTime`) -) COMMENT='小红书创作上传媒体表'; - --- ========== 2. 种子 seed_xhs_skills + seed_xhs_ai_providers ========== - -INSERT INTO `t_xhs_skill` ( - `CustomerId`, `ExternalId`, `Title`, `SkillType`, `PresetId`, `RecipeJson`, `SortOrder`, - `IsDeleted`, `CreateUserId`, `CreateTime` -) VALUES -(0, '5a9d3c012d50', '数字型/疑问型 · 物流知识 · 图文', 'ai_create', NULL, - '{"formula":["emotion","utility","visual","social"],"title_types":["number","question"],"body":{"domain":"物流知识","content_type":"干货教程","emotion":"生活场景","social":"知识炫耀"},"image_modes":["cover_impact"],"video_modes":[],"notes":"讲解9610的简易申报和汇总申报,退税,以及申报要求"}', - 1, 0, 0, NOW()), -(0, '7dd58bfe4770', '效率工具 · 干货教程(新号)', 'ai_create', 'efficiency_tutorial', - '{"formula":["emotion","utility","visual","social"],"title_types":["number","question"],"body":{"domain":"效率工具","content_type":"干货教程","emotion":"焦虑共鸣","social":"价值传递"},"image_modes":["cover_impact","step_cards"],"video_modes":[],"notes":"话题示例:笔记工具提升效率"}', - 2, 0, 0, NOW()), -(0, '3f6ed9f62afd', '职场发展 · 经验分享', 'ai_create', 'career_experience', - '{"formula":["emotion","utility","social"],"title_types":["story","compare"],"body":{"domain":"职场发展","content_type":"经验分享","emotion":"理想生活","social":"身份标签"},"image_modes":["cover_impact","lifestyle"],"video_modes":[],"notes":"话题示例:职场人际关系"}', - 3, 0, 0, NOW()), -(0, '61a4d4febada', '情感共鸣 · 真实场景', 'ai_create', 'emotional_relatable', - '{"formula":["emotion","social"],"title_types":["story","question"],"body":{"domain":"情感共鸣","content_type":"经验分享","emotion":"生活场景","social":"情感支持"},"image_modes":["lifestyle"],"video_modes":["vlog_clip"],"notes":"让读者觉得这也太真实了"}', - 4, 0, 0, NOW()), -(0, 'ec62cc03eea9', '避坑指南 · 观点表达', 'ai_create', 'pitfall_opinion', - '{"formula":["emotion","utility","visual","social"],"title_types":["number"],"body":{"domain":"职场发展","content_type":"避坑指南","emotion":"吐槽宣泄","social":"观点表达"},"image_modes":["info_chart"],"video_modes":["talking_head"],"notes":"话题示例:避坑指南"}', - 5, 0, 0, NOW()) -ON DUPLICATE KEY UPDATE `Title` = VALUES(`Title`), `RecipeJson` = VALUES(`RecipeJson`); - -INSERT INTO `t_xhs_ai_provider` ( - `CustomerId`, `ProviderKey`, `ProviderType`, `DisplayName`, `BaseUrl`, - `ApiKeyEnc`, `ApiSecretEnc`, `IsDefault`, `Enabled`, - `IsDeleted`, `CreateUserId`, `CreateTime` -) VALUES -(0, 'ai_zhipu', 'zhipu', '智谱 AI', 'https://open.bigmodel.cn/api/paas/v4', NULL, 'glm-4-flash', 1, 0, 0, 0, NOW()), -(0, 'ai_deepseek', 'deepseek', 'DeepSeek', 'https://api.deepseek.com/v1', NULL, 'deepseek-chat', 0, 0, 0, 0, NOW()), -(0, 'ai_chatgpt', 'chatgpt', 'OpenAI', 'https://api.openai.com/v1', NULL, 'gpt-4o-mini', 0, 0, 0, 0, NOW()) -ON DUPLICATE KEY UPDATE `DisplayName` = VALUES(`DisplayName`), `BaseUrl` = VALUES(`BaseUrl`); diff --git a/sql/migrate_drop_charging_time.sql b/sql/migrate_drop_charging_time.sql deleted file mode 100644 index 6be5730..0000000 --- a/sql/migrate_drop_charging_time.sql +++ /dev/null @@ -1,3 +0,0 @@ --- 移除卖价/买价主表「收费时机」字段(已由件重尺阶段触发算价,不再配置 ChargingTime) -ALTER TABLE `t_sales_product_price` DROP COLUMN IF EXISTS `ChargingTime`; -ALTER TABLE `t_service_channel_price` DROP COLUMN IF EXISTS `ChargingTime`; diff --git a/sql/migrate_oms_data_permission_columns.sql b/sql/migrate_oms_data_permission_columns.sql deleted file mode 100644 index 638e422..0000000 --- a/sql/migrate_oms_data_permission_columns.sql +++ /dev/null @@ -1,62 +0,0 @@ --- OMS 业务表 — 数据权限 P1 扩展字段 --- 设计文档:E:\oms0414\docs\数据权限设计.md §4.8 --- 可重复执行(information_schema 判断) - --- t_customer.OrganizationId -SET @db = DATABASE(); -SET @sql = IF( - (SELECT COUNT(*) FROM information_schema.COLUMNS - WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 't_customer' AND COLUMN_NAME = 'OrganizationId') = 0, - 'ALTER TABLE `t_customer` ADD COLUMN `OrganizationId` CHAR(36) NULL COMMENT ''归属销售组织 FK organization.Id'' AFTER `CustomerGroup`', - 'SELECT ''skip t_customer.OrganizationId'' AS msg' -); -PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; - -SET @sql = IF( - (SELECT COUNT(*) FROM information_schema.STATISTICS - WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 't_customer' AND INDEX_NAME = 'idx_cus_organization') = 0, - 'ALTER TABLE `t_customer` ADD KEY `idx_cus_organization` (`OrganizationId`)', - 'SELECT ''skip idx_cus_organization'' AS msg' -); -PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; - --- t_order.OrganizationId + SecretLevel -SET @sql = IF( - (SELECT COUNT(*) FROM information_schema.COLUMNS - WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 't_order' AND COLUMN_NAME = 'OrganizationId') = 0, - 'ALTER TABLE `t_order` ADD COLUMN `OrganizationId` CHAR(36) NULL COMMENT ''数据归属组织'' AFTER `CustomerId`', - 'SELECT ''skip t_order.OrganizationId'' AS msg' -); -PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; - -SET @sql = IF( - (SELECT COUNT(*) FROM information_schema.COLUMNS - WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 't_order' AND COLUMN_NAME = 'SecretLevel') = 0, - 'ALTER TABLE `t_order` ADD COLUMN `SecretLevel` TINYINT NOT NULL DEFAULT 2 COMMENT ''数据密级 1-4'' AFTER `OrganizationId`', - 'SELECT ''skip t_order.SecretLevel'' AS msg' -); -PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; - -SET @sql = IF( - (SELECT COUNT(*) FROM information_schema.STATISTICS - WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 't_order' AND INDEX_NAME = 'idx_ord_org_secret_ctime') = 0, - 'ALTER TABLE `t_order` ADD KEY `idx_ord_org_secret_ctime` (`OrganizationId`, `SecretLevel`, `CreateTime`)', - 'SELECT ''skip idx_ord_org_secret_ctime'' AS msg' -); -PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; - --- t_recharge_record.SecretLevel(P2 预置,可跳过) -SET @sql = IF( - (SELECT COUNT(*) FROM information_schema.COLUMNS - WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 't_recharge_record' AND COLUMN_NAME = 'SecretLevel') = 0, - 'ALTER TABLE `t_recharge_record` ADD COLUMN `SecretLevel` TINYINT NOT NULL DEFAULT 3 COMMENT ''数据密级 1-4'' AFTER `CustomerId`', - 'SELECT ''skip t_recharge_record.SecretLevel'' AS msg' -); -PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; - --- 历史订单 OrganizationId 回填:取自客户归属组织(有则更新) -UPDATE `t_order` o -INNER JOIN `t_customer` c ON c.`Id` = o.`CustomerId` AND c.`IsDeleted` = 0 -SET o.`OrganizationId` = c.`OrganizationId` -WHERE o.`OrganizationId` IS NULL - AND c.`OrganizationId` IS NOT NULL; diff --git a/sql/migrate_rbac_user_profile.sql b/sql/migrate_rbac_user_profile.sql deleted file mode 100644 index 881843d..0000000 --- a/sql/migrate_rbac_user_profile.sql +++ /dev/null @@ -1,10 +0,0 @@ --- RBAC 用户扩展:电话、工号、微信号、微信二维码 --- 执行前请确认当前库为 RBAC 库(含 `user` 表) - -ALTER TABLE `user` - ADD COLUMN `Phone` VARCHAR(32) NULL COMMENT '电话' AFTER `Avatar`, - ADD COLUMN `EmployeeNo` VARCHAR(16) NULL COMMENT '工号(NE+4位)' AFTER `Phone`, - ADD COLUMN `WechatId` VARCHAR(64) NULL COMMENT '微信号' AFTER `EmployeeNo`, - ADD COLUMN `WechatQrCode` LONGTEXT NULL COMMENT '微信二维码' AFTER `WechatId`; - -CREATE UNIQUE INDEX `IX_user_EmployeeNo` ON `user` (`EmployeeNo`); diff --git a/sql/migrate_t_auto_trigger_rule_meta.sql b/sql/migrate_t_auto_trigger_rule_meta.sql deleted file mode 100644 index 21058e4..0000000 --- a/sql/migrate_t_auto_trigger_rule_meta.sql +++ /dev/null @@ -1,18 +0,0 @@ --- t_auto_trigger 规则名与优先级(可重复执行) --- 在 OMS 业务库执行:mysql -h -u -p < migrate_t_auto_trigger_rule_meta.sql - -SET @db = DATABASE(); - -SET @exist := (SELECT COUNT(*) FROM information_schema.COLUMNS - WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 't_auto_trigger' AND COLUMN_NAME = 'RuleName'); -SET @sql := IF(@exist = 0, - 'ALTER TABLE `t_auto_trigger` ADD COLUMN `RuleName` VARCHAR(128) NULL COMMENT ''规则名称'' AFTER `Status`', - 'SELECT ''skip RuleName'''); -PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; - -SET @exist := (SELECT COUNT(*) FROM information_schema.COLUMNS - WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 't_auto_trigger' AND COLUMN_NAME = 'Priority'); -SET @sql := IF(@exist = 0, - 'ALTER TABLE `t_auto_trigger` ADD COLUMN `Priority` INT NOT NULL DEFAULT 100 COMMENT ''优先级,数值越小越先执行'' AFTER `RuleName`', - 'SELECT ''skip Priority'''); -PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; diff --git a/sql/migrate_t_customer_account_flow.sql b/sql/migrate_t_customer_account_flow.sql deleted file mode 100644 index 25f4074..0000000 --- a/sql/migrate_t_customer_account_flow.sql +++ /dev/null @@ -1,24 +0,0 @@ --- 客户账户资金流水 -CREATE TABLE IF NOT EXISTS `t_customer_account_flow` ( - `Id` int NOT NULL AUTO_INCREMENT, - `CustomerId` int NOT NULL COMMENT '客户 ID', - `SerialNumber` varchar(64) NOT NULL COMMENT '流水号', - `BizType` varchar(32) NOT NULL COMMENT '业务类型 recharge/orderPay', - `BizId` int DEFAULT NULL COMMENT '关联业务主键', - `BizNo` varchar(64) DEFAULT NULL COMMENT '关联业务单号', - `Amount` decimal(18,2) NOT NULL COMMENT '变动金额,正入账负出账', - `BalanceBefore` decimal(18,2) NOT NULL COMMENT '变动前余额', - `BalanceAfter` decimal(18,2) NOT NULL COMMENT '变动后余额', - `Currency` varchar(8) NOT NULL DEFAULT 'CNY' COMMENT '币种', - `Remark` varchar(512) DEFAULT NULL COMMENT '备注', - `IsDeleted` tinyint(1) NOT NULL DEFAULT '0', - `ConcurrencyStamp` char(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', - `CreateUserId` int NOT NULL DEFAULT '0', - `CreateTime` datetime NOT NULL, - `UpdateUserId` int DEFAULT NULL, - `UpdateTime` datetime DEFAULT NULL, - PRIMARY KEY (`Id`), - UNIQUE KEY `uk_customer_account_flow_serial` (`SerialNumber`), - KEY `idx_customer_account_flow_customer_time` (`CustomerId`, `CreateTime`), - KEY `idx_customer_account_flow_biz` (`BizType`, `BizId`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='客户账户资金流水'; diff --git a/sql/migrate_t_customer_account_flow_concurrency.sql b/sql/migrate_t_customer_account_flow_concurrency.sql deleted file mode 100644 index 74e908f..0000000 --- a/sql/migrate_t_customer_account_flow_concurrency.sql +++ /dev/null @@ -1,8 +0,0 @@ --- 已执行旧版 migrate_t_customer_account_flow.sql 的库补 ConcurrencyStamp(与 AggregateRoot 实体对齐) --- 勿在 ALTER 中使用 DEFAULT(UUID()),复制环境会报 Error 1674 -ALTER TABLE `t_customer_account_flow` - ADD COLUMN `ConcurrencyStamp` char(36) NOT NULL DEFAULT '' COMMENT '并发戳' AFTER `IsDeleted`; - -UPDATE `t_customer_account_flow` - SET `ConcurrencyStamp` = UUID() - WHERE `ConcurrencyStamp` = ''; diff --git a/sql/migrate_t_issue_template.sql b/sql/migrate_t_issue_template.sql deleted file mode 100644 index bd47f4a..0000000 --- a/sql/migrate_t_issue_template.sql +++ /dev/null @@ -1,19 +0,0 @@ --- 渠道-问题模板 -CREATE TABLE IF NOT EXISTS `t_issue_template` ( - `Id` BIGINT NOT NULL AUTO_INCREMENT, - `OrganizationId` CHAR(36) NULL COMMENT '归属组织 GUID;NULL=平台通用', - `IssueType` VARCHAR(32) NOT NULL COMMENT '问题类型 code', - `Title` VARCHAR(128) NOT NULL COMMENT '问题标题', - `Content` TEXT NOT NULL COMMENT '问题内容', - `NotifyMethod` VARCHAR(64) NOT NULL COMMENT '通知方式,逗号分隔', - `Status` TINYINT NOT NULL DEFAULT 1 COMMENT '0-禁用 1-启用', - `IsDeleted` TINYINT NOT NULL DEFAULT 0, - `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', - `CreateUserId` INT NOT NULL, - `CreateTime` DATETIME NOT NULL, - `UpdateUserId` INT NULL, - `UpdateTime` DATETIME NULL, - PRIMARY KEY (`Id`), - KEY `idx_issue_tpl_org_type` (`OrganizationId`, `IssueType`, `IsDeleted`), - KEY `idx_issue_tpl_status` (`Status`, `IsDeleted`) -) COMMENT='渠道-问题模板'; diff --git a/sql/migrate_t_issue_template_concurrency.sql b/sql/migrate_t_issue_template_concurrency.sql deleted file mode 100644 index faf631d..0000000 --- a/sql/migrate_t_issue_template_concurrency.sql +++ /dev/null @@ -1,8 +0,0 @@ --- 已执行旧版 migrate_t_issue_template.sql 的库补 ConcurrencyStamp(与 AggregateRoot 实体对齐) --- 勿在 ALTER 中使用 DEFAULT(UUID()),复制环境会报 Error 1674 -ALTER TABLE `t_issue_template` - ADD COLUMN `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT '' COMMENT '并发戳' AFTER `IsDeleted`; - -UPDATE `t_issue_template` - SET `ConcurrencyStamp` = UUID() - WHERE `ConcurrencyStamp` = ''; diff --git a/sql/migrate_t_order_batch_job_comments.sql b/sql/migrate_t_order_batch_job_comments.sql deleted file mode 100644 index 6714f1f..0000000 --- a/sql/migrate_t_order_batch_job_comments.sql +++ /dev/null @@ -1,46 +0,0 @@ --- 订单批量任务表:补表注释/字段注释(不删表、不丢数据) --- 适用于已执行旧版 order_batch_job_tables.sql(IF NOT EXISTS)的库 - -ALTER TABLE `t_order_batch_job` COMMENT='订单批量异步任务表'; - -ALTER TABLE `t_order_batch_job` - MODIFY COLUMN `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键,自增,步长 1', - MODIFY COLUMN `Action` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '批量操作类型:pay/pre-declare/intercept/parcel-create 等', - MODIFY COLUMN `Status` VARCHAR(32) NOT NULL DEFAULT 'pending' COMMENT '任务状态:pending/running/completed/failed/cancelled', - MODIFY COLUMN `Total` INT NOT NULL DEFAULT 0 COMMENT '子项总数', - MODIFY COLUMN `SuccessCount` INT NOT NULL DEFAULT 0 COMMENT '成功数', - MODIFY COLUMN `FailCount` INT NOT NULL DEFAULT 0 COMMENT '失败数', - MODIFY COLUMN `CustomerId` INT NULL COMMENT '客户ID', - MODIFY COLUMN `PayloadJson` JSON NULL COMMENT '任务级扩展参数(JSON)', - MODIFY COLUMN `RequestId` VARCHAR(64) NULL COMMENT '请求幂等ID', - MODIFY COLUMN `StartedAt` DATETIME NULL COMMENT '开始执行时间', - MODIFY COLUMN `FinishedAt` DATETIME NULL COMMENT '结束时间', - MODIFY COLUMN `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', - MODIFY COLUMN `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', - MODIFY COLUMN `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', - MODIFY COLUMN `CreateTime` DATETIME NOT NULL COMMENT '创建时间', - MODIFY COLUMN `UpdateUserId` INT NULL COMMENT '更新人', - MODIFY COLUMN `UpdateTime` DATETIME NULL COMMENT '更新时间'; - -ALTER TABLE `t_order_batch_job_item` COMMENT='订单批量异步任务明细表'; - -ALTER TABLE `t_order_batch_job_item` - MODIFY COLUMN `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键,自增,步长 1', - MODIFY COLUMN `JobId` INT NOT NULL COMMENT '批量任务ID', - MODIFY COLUMN `OrderId` INT NOT NULL COMMENT '订单ID', - MODIFY COLUMN `ServiceNo` VARCHAR(64) NULL COMMENT '运单号', - MODIFY COLUMN `Action` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '子项操作类型,通常与任务 Action 一致', - MODIFY COLUMN `Status` VARCHAR(32) NOT NULL DEFAULT 'pending' COMMENT '子项状态:pending/running/success/failed/cancelled', - MODIFY COLUMN `MessageId` VARCHAR(128) NULL COMMENT 'RabbitMQ 消息ID,用于幂等与去重', - MODIFY COLUMN `FailReason` TEXT NULL COMMENT '失败原因', - MODIFY COLUMN `PayloadJson` TEXT NULL COMMENT '子项入参快照(JSON)', - MODIFY COLUMN `ResultJson` TEXT NULL COMMENT '子项执行结果快照(JSON)', - MODIFY COLUMN `RetryCount` INT NOT NULL DEFAULT 0 COMMENT '系统重试次数', - MODIFY COLUMN `StartedAt` DATETIME NULL COMMENT '开始执行时间', - MODIFY COLUMN `FinishedAt` DATETIME NULL COMMENT '结束时间', - MODIFY COLUMN `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', - MODIFY COLUMN `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', - MODIFY COLUMN `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', - MODIFY COLUMN `CreateTime` DATETIME NOT NULL COMMENT '创建时间', - MODIFY COLUMN `UpdateUserId` INT NULL COMMENT '更新人', - MODIFY COLUMN `UpdateTime` DATETIME NULL COMMENT '更新时间'; diff --git a/sql/migrate_t_order_batch_job_concurrency.sql b/sql/migrate_t_order_batch_job_concurrency.sql deleted file mode 100644 index 412bffe..0000000 --- a/sql/migrate_t_order_batch_job_concurrency.sql +++ /dev/null @@ -1,23 +0,0 @@ --- 已执行旧版 order_batch_job_tables.sql 的库:补 ConcurrencyStamp / PayloadJson / ResultJson --- 若列已存在,对应 ALTER 会报错,跳过即可 --- 补列完成后执行 sql/migrate_t_order_batch_job_comments.sql 写入表/字段注释 - -ALTER TABLE `t_order_batch_job` - ADD COLUMN `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT '' COMMENT '并发戳' AFTER `IsDeleted`; - -UPDATE `t_order_batch_job` - SET `ConcurrencyStamp` = UUID() - WHERE `ConcurrencyStamp` = ''; - -ALTER TABLE `t_order_batch_job_item` - ADD COLUMN `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT '' COMMENT '并发戳' AFTER `IsDeleted`; - -UPDATE `t_order_batch_job_item` - SET `ConcurrencyStamp` = UUID() - WHERE `ConcurrencyStamp` = ''; - -ALTER TABLE `t_order_batch_job_item` - ADD COLUMN `PayloadJson` TEXT NULL COMMENT '子项入参快照(JSON)' AFTER `FailReason`; - -ALTER TABLE `t_order_batch_job_item` - ADD COLUMN `ResultJson` TEXT NULL COMMENT '子项执行结果快照(JSON)' AFTER `PayloadJson`; diff --git a/sql/migrate_t_order_consignee_country_name.sql b/sql/migrate_t_order_consignee_country_name.sql deleted file mode 100644 index 2912e48..0000000 --- a/sql/migrate_t_order_consignee_country_name.sql +++ /dev/null @@ -1,9 +0,0 @@ --- t_order 增加收件国家中文名称 -ALTER TABLE `t_order` - ADD COLUMN `ConsigneeCountryName` VARCHAR(64) NULL COMMENT '国家中文名称' AFTER `ConsigneeCountry`; - --- 历史数据:按二字码回填中文名 -UPDATE `t_order` o -INNER JOIN `t_country` c ON c.`CountryCode` = o.`ConsigneeCountry` -SET o.`ConsigneeCountryName` = c.`ChineseName` -WHERE o.`ConsigneeCountryName` IS NULL OR o.`ConsigneeCountryName` = ''; diff --git a/sql/migrate_t_order_downstream_integration.sql b/sql/migrate_t_order_downstream_integration.sql deleted file mode 100644 index e8ebf4c..0000000 --- a/sql/migrate_t_order_downstream_integration.sql +++ /dev/null @@ -1,6 +0,0 @@ --- 订单下游对接字段(排货确认渠道时固化,供 itfx 预报/轨迹使用) -ALTER TABLE `t_order` - ADD COLUMN `DownstreamSupplierCode` VARCHAR(64) NULL COMMENT '下游 API 服务商编码 supplierCode' AFTER `ChannelCode`, - ADD COLUMN `DownstreamAppKey` VARCHAR(128) NULL COMMENT '下游 itfx 应用 AppKey' AFTER `DownstreamSupplierCode`, - ADD COLUMN `DownstreamAppId` INT NULL COMMENT '下游 itfx 应用 Id' AFTER `DownstreamAppKey`, - ADD COLUMN `ChannelForecastCode` VARCHAR(128) NULL COMMENT '渠道预报编码 ForecastCode' AFTER `DownstreamAppId`; diff --git a/sql/migrate_t_order_exception_event.sql b/sql/migrate_t_order_exception_event.sql deleted file mode 100644 index 408605e..0000000 --- a/sql/migrate_t_order_exception_event.sql +++ /dev/null @@ -1,27 +0,0 @@ --- 订单异常事件审计表 -CREATE TABLE IF NOT EXISTS `t_order_exception_event` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', - `OrderId` INT NOT NULL COMMENT '订单Id', - `EventType` VARCHAR(32) NOT NULL COMMENT 'mark_problematic/mark_claimed/handle_processed', - `FromStatus` VARCHAR(32) NULL COMMENT '变更前OrderStatus', - `ToStatus` VARCHAR(32) NULL COMMENT '变更后OrderStatus', - `FromHandleStatus` VARCHAR(16) NULL COMMENT '变更前HandleStatus', - `ToHandleStatus` VARCHAR(16) NULL COMMENT '变更后HandleStatus', - `IssueType` VARCHAR(32) NULL COMMENT '问题类型', - `Title` VARCHAR(128) NULL COMMENT '标题快照', - `Content` TEXT NULL COMMENT '内容快照', - `IssueTemplateId` INT NULL COMMENT '模板Id', - `NotifyMethod` VARCHAR(64) NULL COMMENT '通知方式快照', - `ClaimType` VARCHAR(32) NULL COMMENT '理赔类型', - `ClaimAmount` DECIMAL(18,4) NULL COMMENT '索赔金额', - `ClaimCurrency` VARCHAR(16) NULL COMMENT '索赔币种', - `ClaimReason` VARCHAR(512) NULL COMMENT '理赔原因', - `Remark` VARCHAR(512) NULL COMMENT '操作备注', - `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', - `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '操作人', - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '操作时间', - `UpdateUserId` INT NULL COMMENT '更新人', - `UpdateTime` DATETIME NULL COMMENT '更新时间', - PRIMARY KEY (`Id`), - KEY `idx_oee_order_time` (`OrderId`, `CreateTime`) -) COMMENT='订单异常事件表'; diff --git a/sql/migrate_t_order_exception_fields.sql b/sql/migrate_t_order_exception_fields.sql deleted file mode 100644 index 1db1f43..0000000 --- a/sql/migrate_t_order_exception_fields.sql +++ /dev/null @@ -1,14 +0,0 @@ --- 问题件 / 理赔件快照字段 -ALTER TABLE `t_order` - ADD COLUMN `IssueType` VARCHAR(32) NULL COMMENT '问题类型' AFTER `HandleStatus`, - ADD COLUMN `IssueTitle` VARCHAR(128) NULL COMMENT '问题标题' AFTER `IssueType`, - ADD COLUMN `IssueContent` TEXT NULL COMMENT '问题内容' AFTER `IssueTitle`, - ADD COLUMN `IssueTemplateId` INT NULL COMMENT '问题模板Id' AFTER `IssueContent`, - ADD COLUMN `IssueRemark` VARCHAR(512) NULL COMMENT '问题备注' AFTER `IssueTemplateId`, - ADD COLUMN `IssueTime` DATETIME NULL COMMENT '标记问题件时间' AFTER `IssueRemark`, - ADD COLUMN `ClaimType` VARCHAR(32) NULL COMMENT '理赔类型' AFTER `IssueTime`, - ADD COLUMN `ClaimAmount` DECIMAL(18,4) NULL COMMENT '索赔金额' AFTER `ClaimType`, - ADD COLUMN `ClaimCurrency` VARCHAR(16) NULL COMMENT '索赔币种' AFTER `ClaimAmount`, - ADD COLUMN `ClaimReason` VARCHAR(512) NULL COMMENT '理赔原因' AFTER `ClaimCurrency`, - ADD COLUMN `ClaimTime` DATETIME NULL COMMENT '创建理赔件时间' AFTER `ClaimReason`, - ADD COLUMN `PreviousOrderStatus` VARCHAR(32) NULL COMMENT '进入异常状态前的订单状态' AFTER `ClaimTime`; diff --git a/sql/migrate_t_order_handle_status.sql b/sql/migrate_t_order_handle_status.sql deleted file mode 100644 index 8c77435..0000000 --- a/sql/migrate_t_order_handle_status.sql +++ /dev/null @@ -1,12 +0,0 @@ --- 问题件 / 已理赔 子状态:pending-待处理 processed-已处理 -ALTER TABLE `t_order` - ADD COLUMN `HandleStatus` VARCHAR(16) NULL DEFAULT 'pending' COMMENT '处理子状态:pending/processed' AFTER `OrderStatus`; - -UPDATE `t_order` - SET `HandleStatus` = 'pending' - WHERE `HandleStatus` IS NULL - AND `OrderStatus` IN ('problematic', 'claimed'); - -UPDATE `t_order` - SET `HandleStatus` = NULL - WHERE `OrderStatus` NOT IN ('problematic', 'claimed'); diff --git a/sql/migrate_t_order_is_paid.sql b/sql/migrate_t_order_is_paid.sql deleted file mode 100644 index 058f418..0000000 --- a/sql/migrate_t_order_is_paid.sql +++ /dev/null @@ -1,7 +0,0 @@ --- 订单表增加是否已支付字段,并按历史 PayTime 回填 -ALTER TABLE `t_order` - ADD COLUMN `IsPaid` TINYINT NOT NULL DEFAULT 0 COMMENT '是否已支付:0-否,1-是' AFTER `PayTime`; - -UPDATE `t_order` -SET `IsPaid` = 1 -WHERE `PayTime` IS NOT NULL; diff --git a/sql/migrate_t_order_parcel_columns.sql b/sql/migrate_t_order_parcel_columns.sql deleted file mode 100644 index fa45b98..0000000 --- a/sql/migrate_t_order_parcel_columns.sql +++ /dev/null @@ -1,44 +0,0 @@ --- t_order / t_order_fee 小包预报计费字段补齐(可重复执行) --- 在 OMS 业务库执行,例如:mysql -h -u -p < migrate_t_order_parcel_columns.sql - -SET @db = DATABASE(); - --- t_order.ExportCustomsMode -SET @exist := (SELECT COUNT(*) FROM information_schema.COLUMNS - WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 't_order' AND COLUMN_NAME = 'ExportCustomsMode'); -SET @sql := IF(@exist = 0, - 'ALTER TABLE `t_order` ADD COLUMN `ExportCustomsMode` VARCHAR(32) NULL COMMENT ''出口报关方式'' AFTER `CargoAttribute`', - 'SELECT ''skip ExportCustomsMode'''); -PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; - --- t_order.PredeclareFailReason -SET @exist := (SELECT COUNT(*) FROM information_schema.COLUMNS - WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 't_order' AND COLUMN_NAME = 'PredeclareFailReason'); -SET @sql := IF(@exist = 0, - 'ALTER TABLE `t_order` ADD COLUMN `PredeclareFailReason` VARCHAR(512) NULL COMMENT ''预报失败原因'' AFTER `IsRemote`', - 'SELECT ''skip PredeclareFailReason'''); -PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; - --- t_order.SalesProductRulesVersion -SET @exist := (SELECT COUNT(*) FROM information_schema.COLUMNS - WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 't_order' AND COLUMN_NAME = 'SalesProductRulesVersion'); -SET @sql := IF(@exist = 0, - 'ALTER TABLE `t_order` ADD COLUMN `SalesProductRulesVersion` VARCHAR(64) NULL COMMENT ''销售产品规则快照版本'' AFTER `PredeclareFailReason`', - 'SELECT ''skip SalesProductRulesVersion'''); -PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; - --- t_order.SalesProductPriceVersion -SET @exist := (SELECT COUNT(*) FROM information_schema.COLUMNS - WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 't_order' AND COLUMN_NAME = 'SalesProductPriceVersion'); -SET @sql := IF(@exist = 0, - 'ALTER TABLE `t_order` ADD COLUMN `SalesProductPriceVersion` VARCHAR(64) NULL COMMENT ''销售产品价格快照版本'' AFTER `SalesProductRulesVersion`', - 'SELECT ''skip SalesProductPriceVersion'''); -PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; - --- t_order_fee.ChargingStage -SET @exist := (SELECT COUNT(*) FROM information_schema.COLUMNS - WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 't_order_fee' AND COLUMN_NAME = 'ChargingStage'); -SET @sql := IF(@exist = 0, - 'ALTER TABLE `t_order_fee` ADD COLUMN `ChargingStage` VARCHAR(16) NULL COMMENT ''计费阶段:forecast/inbound/outbound'' AFTER `PriceEffectiveTime`', - 'SELECT ''skip ChargingStage'''); -PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; diff --git a/sql/migrate_t_order_predeclare_fail_reason.sql b/sql/migrate_t_order_predeclare_fail_reason.sql deleted file mode 100644 index 11abf72..0000000 --- a/sql/migrate_t_order_predeclare_fail_reason.sql +++ /dev/null @@ -1,11 +0,0 @@ --- t_order 预报失败原因(可重复执行) --- 在 OMS 业务库执行:mysql -h -u -p < migrate_t_order_predeclare_fail_reason.sql - -SET @db = DATABASE(); - -SET @exist := (SELECT COUNT(*) FROM information_schema.COLUMNS - WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 't_order' AND COLUMN_NAME = 'PredeclareFailReason'); -SET @sql := IF(@exist = 0, - 'ALTER TABLE `t_order` ADD COLUMN `PredeclareFailReason` VARCHAR(512) NULL COMMENT ''预报失败原因'' AFTER `IsRemote`', - 'SELECT ''skip PredeclareFailReason'''); -PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; diff --git a/sql/migrate_t_order_template_mapping.sql b/sql/migrate_t_order_template_mapping.sql deleted file mode 100644 index c7d4a3b..0000000 --- a/sql/migrate_t_order_template_mapping.sql +++ /dev/null @@ -1,12 +0,0 @@ --- 下单模板:自定义映射与样例文件 -ALTER TABLE `t_order_template` - ADD COLUMN `StandardTemplateKey` VARCHAR(64) NULL COMMENT '映射所依据的标准模板 TemplateKey' AFTER `TemplateKey`, - ADD COLUMN `MappingStatus` VARCHAR(16) NULL COMMENT 'draft/ready;标准模板为 ready' AFTER `StandardTemplateKey`, - ADD COLUMN `SourceFileName` VARCHAR(256) NULL COMMENT '客户上传样例文件名' AFTER `MappingStatus`, - ADD COLUMN `SourceFilePath` VARCHAR(512) NULL COMMENT '样例文件相对路径 /uploads/...' AFTER `SourceFileName`, - ADD COLUMN `SourceHeadersJson` TEXT NULL COMMENT '客户 Excel 表头 JSON 数组' AFTER `SourceFilePath`, - ADD COLUMN `ColumnMappingJson` TEXT NULL COMMENT '标准字段与客户列映射 JSON' AFTER `SourceHeadersJson`; - -UPDATE `t_order_template` -SET `MappingStatus` = 'ready' -WHERE `Type` = 'standard' AND (`MappingStatus` IS NULL OR `MappingStatus` = ''); diff --git a/sql/migrate_t_outbound_record_columns.sql b/sql/migrate_t_outbound_record_columns.sql deleted file mode 100644 index 5fd492f..0000000 --- a/sql/migrate_t_outbound_record_columns.sql +++ /dev/null @@ -1,13 +0,0 @@ --- 出库记录表补齐件重尺、销售产品、目的国、服务渠道字段(与 t_inbound_record 对齐) -ALTER TABLE `t_outbound_record` - ADD COLUMN `Weight` DECIMAL(10,2) NULL COMMENT '实重(kg)' AFTER `WaybillNo`, - ADD COLUMN `Length` DECIMAL(10,2) NULL COMMENT '长(cm)' AFTER `Weight`, - ADD COLUMN `Width` DECIMAL(10,2) NULL COMMENT '宽(cm)' AFTER `Length`, - ADD COLUMN `Height` DECIMAL(10,2) NULL COMMENT '高(cm)' AFTER `Width`, - ADD COLUMN `SalesProductId` INT NULL COMMENT '销售产品ID' AFTER `Height`, - ADD COLUMN `DestinationCountry` VARCHAR(8) NULL COMMENT '目的国' AFTER `SalesProductId`, - ADD COLUMN `ServiceChannelId` INT NULL COMMENT '服务渠道ID' AFTER `DestinationCountry`; - -ALTER TABLE `t_outbound_record` - ADD KEY `idx_out_product_time` (`SalesProductId`, `OperateTime`), - ADD KEY `idx_out_channel_time` (`ServiceChannelId`, `OperateTime`); diff --git a/sql/migrate_t_sales_product_customer_guide.sql b/sql/migrate_t_sales_product_customer_guide.sql deleted file mode 100644 index ef13cb9..0000000 --- a/sql/migrate_t_sales_product_customer_guide.sql +++ /dev/null @@ -1,4 +0,0 @@ --- 销售产品表增加对客说明 Markdown 字段 - -ALTER TABLE `t_sales_product` - ADD COLUMN `CustomerGuideMarkdown` MEDIUMTEXT NULL COMMENT '对客说明 Markdown' AFTER `PreStorageScript`; diff --git a/sql/migrate_t_system_batch_email.sql b/sql/migrate_t_system_batch_email.sql deleted file mode 100644 index 905272f..0000000 --- a/sql/migrate_t_system_batch_email.sql +++ /dev/null @@ -1,54 +0,0 @@ --- 批量发送邮件:模板与 SMTP 账号配置 -CREATE TABLE IF NOT EXISTS `t_system_batch_email_template` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', - `OwnerUserId` INT NOT NULL DEFAULT 0 COMMENT '所属 RBAC 用户 Id', - `TemplateName` VARCHAR(128) NOT NULL COMMENT '模板名称', - `Subject` VARCHAR(512) NOT NULL DEFAULT '' COMMENT '邮件主题', - `Content` TEXT NOT NULL COMMENT '邮件正文', - `SortOrder` INT NOT NULL DEFAULT 0 COMMENT '排序', - `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', - `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', - `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `UpdateUserId` INT NULL COMMENT '更新人', - `UpdateTime` DATETIME NULL COMMENT '更新时间', - PRIMARY KEY (`Id`), - UNIQUE KEY `uk_batch_email_tpl_owner_name` (`OwnerUserId`, `TemplateName`), - KEY `idx_batch_email_tpl_owner` (`OwnerUserId`, `SortOrder`, `Id`) -) COMMENT='批量发送邮件模板'; - -CREATE TABLE IF NOT EXISTS `t_system_batch_email_account` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', - `OwnerUserId` INT NOT NULL DEFAULT 0 COMMENT '所属 RBAC 用户 Id', - `SmtpUsername` VARCHAR(256) NOT NULL COMMENT 'SMTP 账号', - `SmtpPassword` VARCHAR(512) NOT NULL COMMENT 'SMTP 密码/授权码', - `ServerType` VARCHAR(32) NOT NULL DEFAULT 'qiye' COMMENT 'SMTP 类型', - `FromName` VARCHAR(128) NULL COMMENT '发件人显示名', - `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', - `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', - `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `UpdateUserId` INT NULL COMMENT '更新人', - `UpdateTime` DATETIME NULL COMMENT '更新时间', - PRIMARY KEY (`Id`), - UNIQUE KEY `uk_batch_email_account_owner` (`OwnerUserId`) -) COMMENT='批量发送邮件 SMTP 账号配置'; - -CREATE TABLE IF NOT EXISTS `t_system_batch_email_record` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', - `OwnerUserId` INT NOT NULL DEFAULT 0 COMMENT '所属 RBAC 用户 Id', - `ToEmail` VARCHAR(256) NOT NULL COMMENT '收件邮箱', - `Subject` VARCHAR(512) NOT NULL DEFAULT '' COMMENT '邮件主题', - `Content` TEXT NOT NULL COMMENT '邮件正文', - `SendTime` DATETIME NOT NULL COMMENT '发送时间', - `Sender` VARCHAR(128) NOT NULL DEFAULT '' COMMENT '发送人', - `SenderEmail` VARCHAR(256) NULL COMMENT '发件邮箱', - `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', - `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', - `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `UpdateUserId` INT NULL COMMENT '更新人', - `UpdateTime` DATETIME NULL COMMENT '更新时间', - PRIMARY KEY (`Id`), - KEY `idx_batch_email_record_owner_time` (`OwnerUserId`, `SendTime`, `Id`) -) COMMENT='批量发送邮件记录'; diff --git a/sql/migrate_t_system_other_config.sql b/sql/migrate_t_system_other_config.sql deleted file mode 100644 index 4353a91..0000000 --- a/sql/migrate_t_system_other_config.sql +++ /dev/null @@ -1,21 +0,0 @@ --- 系统其他配置表(含 OMS 小包轨迹服务配置) -CREATE TABLE IF NOT EXISTS `t_system_other_config` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键,自增,步长 1', - `ConfigCode` VARCHAR(64) NOT NULL COMMENT '配置编码,如 track_service', - `ConfigName` VARCHAR(128) NOT NULL COMMENT '配置名称', - `Enabled` TINYINT NOT NULL DEFAULT 0 COMMENT '是否启用:0-否,1-是', - `BaseUrl` VARCHAR(512) NULL COMMENT '服务地址', - `AppKey` VARCHAR(128) NULL COMMENT 'AppKey', - `AppSecret` VARCHAR(256) NULL COMMENT 'AppSecret', - `TimeoutSeconds` INT NOT NULL DEFAULT 30 COMMENT '超时秒数', - `Remark` VARCHAR(512) NULL COMMENT '备注', - `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', - `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', - `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `UpdateUserId` INT NULL COMMENT '更新人', - `UpdateTime` DATETIME NULL COMMENT '更新时间', - PRIMARY KEY (`Id`), - UNIQUE KEY `uk_system_other_config_code` (`ConfigCode`), - KEY `idx_system_other_config_enabled` (`Enabled`, `Id`) -) COMMENT='系统其他配置表'; diff --git a/sql/migrate_t_system_other_config_wechat_token.sql b/sql/migrate_t_system_other_config_wechat_token.sql deleted file mode 100644 index 1c86eec..0000000 --- a/sql/migrate_t_system_other_config_wechat_token.sql +++ /dev/null @@ -1,5 +0,0 @@ --- 微信公众号 access_token 持久化(仅 wechat_mp 使用,不对前端展示) -ALTER TABLE `t_system_other_config` - ADD COLUMN `AccessToken` VARCHAR(512) NULL COMMENT '微信 access_token(运行时缓存)' AFTER `Remark`, - ADD COLUMN `AccessTokenExpiresIn` INT NOT NULL DEFAULT 0 COMMENT '微信 access_token 有效期秒数 expires_in' AFTER `AccessToken`, - ADD COLUMN `AccessTokenUpdatedAt` DATETIME NULL COMMENT '微信 access_token 最近刷新时间' AFTER `AccessTokenExpiresIn`; diff --git a/sql/migrate_t_warehouse_address_drop_service_fields.sql b/sql/migrate_t_warehouse_address_drop_service_fields.sql deleted file mode 100644 index 78d4d81..0000000 --- a/sql/migrate_t_warehouse_address_drop_service_fields.sql +++ /dev/null @@ -1,6 +0,0 @@ --- 仓库地址表移除客服电话、客服微信及二维码字段 - -ALTER TABLE `t_warehouse_address` - DROP COLUMN `ServicePhone`, - DROP COLUMN `ServiceWechat`, - DROP COLUMN `ServiceWechatFiles`; diff --git a/sql/migrate_t_xhs.sql b/sql/migrate_t_xhs.sql deleted file mode 100644 index 875d619..0000000 --- a/sql/migrate_t_xhs.sql +++ /dev/null @@ -1,181 +0,0 @@ --- 小红书(LIKE AI → OMS)模块表结构 --- 设计文档:E:\oms0414\docs\小红书模块设计-063001.md - -CREATE TABLE IF NOT EXISTS `t_xhs_agent` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', - `CustomerId` INT NOT NULL COMMENT '客户ID → t_customer.Id', - `DeviceId` VARCHAR(64) NOT NULL COMMENT 'Agent 本机设备标识', - `DeviceName` VARCHAR(128) NULL COMMENT '用户自定义名称', - `AgentVersion` VARCHAR(32) NULL COMMENT 'Agent 版本号', - `BridgePort` INT NOT NULL DEFAULT 9333 COMMENT 'Bridge WebSocket 端口', - `Status` VARCHAR(16) NOT NULL DEFAULT 'offline' COMMENT 'online/offline', - `EngineRunning` TINYINT NOT NULL DEFAULT 0 COMMENT 'Bridge 引擎是否运行', - `ExtensionConnected` TINYINT NOT NULL DEFAULT 0 COMMENT 'Chrome 扩展是否连上 Bridge', - `XhsLoggedIn` TINYINT NOT NULL DEFAULT 0 COMMENT '小红书是否已登录', - `LastHeartbeatTime` DATETIME NULL COMMENT '最后心跳时间', - `LastError` VARCHAR(512) NULL COMMENT '最近一次 Agent 上报错误摘要', - `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', - `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', - `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `UpdateUserId` INT NULL COMMENT '更新人', - `UpdateTime` DATETIME NULL COMMENT '更新时间', - PRIMARY KEY (`Id`), - UNIQUE KEY `uk_xhs_agent_device` (`DeviceId`), - KEY `idx_xhs_agent_customer` (`CustomerId`, `Status`) -) COMMENT='小红书本地 Agent 设备表'; - -CREATE TABLE IF NOT EXISTS `t_xhs_task` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', - `CustomerId` INT NOT NULL COMMENT '客户ID', - `AgentId` INT NULL COMMENT '指定执行的 Agent;NULL 表示任意在线 Agent', - `TaskType` VARCHAR(32) NOT NULL COMMENT '任务类型', - `ToolName` VARCHAR(64) NULL COMMENT 'LIKE AI 工具名', - `Priority` INT NOT NULL DEFAULT 0 COMMENT '越大越优先', - `Status` VARCHAR(16) NOT NULL DEFAULT 'pending' COMMENT 'pending/claimed/running/succeeded/failed/cancelled', - `ArgumentsJson` JSON NOT NULL COMMENT '工具参数 JSON', - `ProgressText` VARCHAR(512) NULL COMMENT '执行过程摘要', - `ResultJson` JSON NULL COMMENT '成功时结构化结果', - `ErrorMessage` VARCHAR(1024) NULL COMMENT '失败原因', - `Source` VARCHAR(32) NOT NULL DEFAULT 'web' COMMENT 'web/schedule/skill', - `SourceRefId` VARCHAR(64) NULL COMMENT '来源关联 ID', - `ScheduledTime` DATETIME NULL COMMENT '计划执行时间', - `ClaimedAt` DATETIME NULL COMMENT 'Agent 认领时间', - `StartedAt` DATETIME NULL COMMENT '开始执行', - `FinishedAt` DATETIME NULL COMMENT '结束时间', - `IsDeleted` TINYINT NOT NULL DEFAULT 0, - `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()), - `CreateUserId` INT NOT NULL DEFAULT 0, - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `UpdateUserId` INT NULL, - `UpdateTime` DATETIME NULL, - PRIMARY KEY (`Id`), - KEY `idx_xhs_task_poll` (`CustomerId`, `Status`, `ScheduledTime`, `Priority`), - KEY `idx_xhs_task_agent` (`AgentId`, `Status`), - KEY `idx_xhs_task_source` (`Source`, `SourceRefId`) -) COMMENT='小红书 Agent 任务队列表'; - -CREATE TABLE IF NOT EXISTS `t_xhs_publish_record` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', - `CustomerId` INT NOT NULL COMMENT '客户ID', - `TaskId` INT NULL COMMENT '关联 t_xhs_task.Id', - `ToolName` VARCHAR(64) NOT NULL COMMENT 'publish_content / publish_with_video', - `Title` VARCHAR(256) NOT NULL COMMENT '笔记标题', - `ContentPreview` VARCHAR(512) NULL COMMENT '正文摘要', - `ContentFull` TEXT NULL COMMENT '完整正文', - `MediaJson` JSON NULL COMMENT '图片/视频 URL 列表', - `TagsJson` JSON NULL COMMENT '标签数组', - `Visibility` VARCHAR(32) NULL COMMENT '可见范围', - `Status` VARCHAR(16) NOT NULL DEFAULT 'draft' COMMENT 'draft/scheduled/publishing/succeeded/failed/cancelled', - `Success` TINYINT NULL COMMENT '最终是否成功', - `ResultSummary` VARCHAR(1024) NULL COMMENT 'Agent 回传结果摘要', - `ScheduledTime` DATETIME NULL COMMENT '定时发布时间', - `PublishedTime` DATETIME NULL COMMENT '实际发布完成时间', - `SkillId` INT NULL COMMENT '若来自技能卡片', - `IsDeleted` TINYINT NOT NULL DEFAULT 0, - `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()), - `CreateUserId` INT NOT NULL DEFAULT 0, - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `UpdateUserId` INT NULL, - `UpdateTime` DATETIME NULL, - PRIMARY KEY (`Id`), - KEY `idx_xhs_publish_customer_time` (`CustomerId`, `CreateTime`), - KEY `idx_xhs_publish_status_sched` (`CustomerId`, `Status`, `ScheduledTime`), - KEY `idx_xhs_publish_task` (`TaskId`) -) COMMENT='小红书发布记录表'; - -CREATE TABLE IF NOT EXISTS `t_xhs_analysis_session` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', - `CustomerId` INT NOT NULL COMMENT '客户ID', - `SessionName` VARCHAR(128) NULL COMMENT '用户备注名', - `AnalysisType` VARCHAR(32) NOT NULL COMMENT 'home_feed/search/my_feeds/feed_detail', - `Keyword` VARCHAR(128) NULL COMMENT '搜索关键词', - `TaskId` INT NULL COMMENT '采集任务 ID', - `FeedsJson` JSON NULL COMMENT '采集笔记列表', - `SelectedFeedId` VARCHAR(64) NULL COMMENT '当前选中笔记 ID', - `AiAnalysisMarkdown` MEDIUMTEXT NULL COMMENT 'AI 分析结果', - `SkillId` INT NULL COMMENT '技能配方 ID', - `IsDeleted` TINYINT NOT NULL DEFAULT 0, - `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()), - `CreateUserId` INT NOT NULL DEFAULT 0, - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `UpdateUserId` INT NULL, - `UpdateTime` DATETIME NULL, - PRIMARY KEY (`Id`), - KEY `idx_xhs_analysis_customer` (`CustomerId`, `CreateTime`) -) COMMENT='小红书内容分析会话表'; - -CREATE TABLE IF NOT EXISTS `t_xhs_skill` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', - `CustomerId` INT NOT NULL COMMENT '客户ID;0 表示系统预置', - `ExternalId` VARCHAR(32) NOT NULL COMMENT '对外稳定 ID', - `Title` VARCHAR(256) NOT NULL COMMENT '技能名称', - `SkillType` VARCHAR(32) NOT NULL DEFAULT 'ai_create' COMMENT '技能类型', - `PresetId` VARCHAR(64) NULL COMMENT '内置预设标识', - `RecipeJson` JSON NOT NULL COMMENT '配方 JSON', - `SortOrder` INT NOT NULL DEFAULT 0 COMMENT '排序', - `IsDeleted` TINYINT NOT NULL DEFAULT 0, - `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()), - `CreateUserId` INT NOT NULL DEFAULT 0, - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `UpdateUserId` INT NULL, - `UpdateTime` DATETIME NULL, - PRIMARY KEY (`Id`), - UNIQUE KEY `uk_xhs_skill_external` (`CustomerId`, `ExternalId`), - KEY `idx_xhs_skill_customer` (`CustomerId`, `SortOrder`) -) COMMENT='小红书技能卡片表'; - -CREATE TABLE IF NOT EXISTS `t_xhs_human_config` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', - `CustomerId` INT NOT NULL COMMENT '客户ID', - `BehaviorJson` JSON NOT NULL COMMENT 'human_behavior 配置', - `GuardJson` JSON NOT NULL COMMENT 'human_guard 配置', - `Version` INT NOT NULL DEFAULT 1 COMMENT '配置版本', - `IsDeleted` TINYINT NOT NULL DEFAULT 0, - `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()), - `CreateUserId` INT NOT NULL DEFAULT 0, - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `UpdateUserId` INT NULL, - `UpdateTime` DATETIME NULL, - PRIMARY KEY (`Id`), - UNIQUE KEY `uk_xhs_human_customer` (`CustomerId`) -) COMMENT='小红书拟人行为与防封配置表'; - -CREATE TABLE IF NOT EXISTS `t_xhs_ai_provider` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', - `CustomerId` INT NOT NULL COMMENT '客户ID;0 表示全局', - `ProviderKey` VARCHAR(32) NOT NULL COMMENT 'ai_chatgpt / ai_zhipu 等', - `ProviderType` VARCHAR(32) NOT NULL COMMENT 'chatgpt/doubao/deepseek/zhipu', - `DisplayName` VARCHAR(64) NOT NULL COMMENT '展示名', - `BaseUrl` VARCHAR(512) NOT NULL COMMENT 'API Base URL', - `ApiKeyEnc` VARCHAR(512) NULL COMMENT 'API Key(暂明文,后续可加密)', - `ApiSecretEnc` VARCHAR(512) NULL COMMENT 'Secret/模型名', - `IsDefault` TINYINT NOT NULL DEFAULT 0 COMMENT '是否默认', - `Enabled` TINYINT NOT NULL DEFAULT 1 COMMENT '是否启用', - `IsDeleted` TINYINT NOT NULL DEFAULT 0, - `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()), - `CreateUserId` INT NOT NULL DEFAULT 0, - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `UpdateUserId` INT NULL, - `UpdateTime` DATETIME NULL, - PRIMARY KEY (`Id`), - UNIQUE KEY `uk_xhs_ai_provider` (`CustomerId`, `ProviderKey`), - KEY `idx_xhs_ai_customer` (`CustomerId`, `Enabled`) -) COMMENT='小红书 AI 提供商配置表'; - -CREATE TABLE IF NOT EXISTS `t_xhs_media` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', - `CustomerId` INT NOT NULL COMMENT '客户ID', - `FileName` VARCHAR(256) NOT NULL COMMENT '原始文件名', - `StoragePath` VARCHAR(512) NOT NULL COMMENT '相对路径', - `PublicUrl` VARCHAR(512) NOT NULL COMMENT '对外 HTTPS URL', - `MimeType` VARCHAR(64) NULL COMMENT 'MIME', - `FileSizeBytes` BIGINT NULL COMMENT '字节数', - `IsDeleted` TINYINT NOT NULL DEFAULT 0, - `CreateUserId` INT NOT NULL DEFAULT 0, - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `UpdateUserId` INT NULL, - `UpdateTime` DATETIME NULL, - PRIMARY KEY (`Id`), - KEY `idx_xhs_media_customer` (`CustomerId`, `CreateTime`) -) COMMENT='小红书创作上传媒体表'; diff --git a/sql/migrate_warehouse_module.sql b/sql/migrate_warehouse_module.sql deleted file mode 100644 index ce2e99d..0000000 --- a/sql/migrate_warehouse_module.sql +++ /dev/null @@ -1,275 +0,0 @@ --- 仓储模块 + 店铺订单表结构(v0.3) --- 设计文档:E:\oms0414\docs\仓储模块设计方案.md --- 仓储表前缀:C_ ;店铺表前缀:t_sales_ --- 幂等:CREATE TABLE IF NOT EXISTS - --- --------------------------------------------------------------------------- --- 仓储域(C_*) --- --------------------------------------------------------------------------- - -CREATE TABLE IF NOT EXISTS `C_sku` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', - `CustomerId` INT NOT NULL COMMENT '客户ID → t_customer.Id', - `SkuCode` VARCHAR(64) NOT NULL COMMENT '库内SKU编码', - `SkuName` VARCHAR(256) NOT NULL COMMENT 'SKU名称', - `SkuImageUrl` VARCHAR(512) NULL COMMENT '图片URL', - `WeightG` DECIMAL(10,2) NULL COMMENT '重量(g)', - `LengthCm` DECIMAL(10,2) NULL COMMENT '长(cm)', - `WidthCm` DECIMAL(10,2) NULL COMMENT '宽(cm)', - `HeightCm` DECIMAL(10,2) NULL COMMENT '高(cm)', - `Remark` VARCHAR(512) NULL COMMENT '备注', - `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', - `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', - `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `UpdateUserId` INT NULL COMMENT '更新人', - `UpdateTime` DATETIME NULL COMMENT '更新时间', - PRIMARY KEY (`Id`), - UNIQUE KEY `uk_c_sku_code` (`CustomerId`, `SkuCode`), - KEY `idx_c_sku_customer` (`CustomerId`, `IsDeleted`) -) COMMENT='仓储-SKU主数据'; - -CREATE TABLE IF NOT EXISTS `C_bin_location` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', - `WarehouseId` INT NOT NULL COMMENT '仓库ID → t_warehouse_address.Id', - `BinCode` VARCHAR(32) NOT NULL COMMENT '库位编码', - `BinName` VARCHAR(64) NULL COMMENT '库位展示名', - `ZoneCode` VARCHAR(32) NULL COMMENT '库区编码', - `IsEnabled` TINYINT NOT NULL DEFAULT 1 COMMENT '是否启用:0-否,1-是', - `Remark` VARCHAR(512) NULL COMMENT '备注', - `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', - `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', - `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `UpdateUserId` INT NULL COMMENT '更新人', - `UpdateTime` DATETIME NULL COMMENT '更新时间', - PRIMARY KEY (`Id`), - UNIQUE KEY `uk_c_bin_wh_code` (`WarehouseId`, `BinCode`), - KEY `idx_c_bin_warehouse` (`WarehouseId`, `IsEnabled`) -) COMMENT='仓储-库位主数据'; - -CREATE TABLE IF NOT EXISTS `C_inventory` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', - `CustomerId` INT NOT NULL COMMENT '客户ID', - `WarehouseId` INT NOT NULL COMMENT '仓库ID', - `SkuId` INT NOT NULL COMMENT 'SKU ID → C_sku.Id', - `BinLocationId` INT NOT NULL COMMENT '库位ID → C_bin_location.Id', - `Qty` INT NOT NULL DEFAULT 0 COMMENT '可用库存数量', - `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', - `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', - `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `UpdateUserId` INT NULL COMMENT '更新人', - `UpdateTime` DATETIME NULL COMMENT '更新时间', - PRIMARY KEY (`Id`), - UNIQUE KEY `uk_c_inventory` (`CustomerId`, `WarehouseId`, `SkuId`, `BinLocationId`), - KEY `idx_c_inv_sku_wh` (`CustomerId`, `SkuId`, `WarehouseId`) -) COMMENT='仓储-库存余额(按库位)'; - -CREATE TABLE IF NOT EXISTS `C_inbound_notice` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', - `CustomerId` INT NOT NULL COMMENT '客户ID', - `WarehouseId` INT NOT NULL COMMENT '仓库ID', - `NoticeNo` VARCHAR(32) NOT NULL COMMENT '入库单号 IN+雪花', - `MarkReference` VARCHAR(64) NULL COMMENT '唛头参考号', - `InboundType` VARCHAR(16) NOT NULL DEFAULT 'normal' COMMENT 'normal/return', - `ReceiptStatus` VARCHAR(16) NOT NULL DEFAULT 'forecasted' COMMENT 'forecasted/received/completed', - `ExpectedArrivalTime` DATETIME NULL COMMENT '预计到货时间', - `ActualArrivalTime` DATETIME NULL COMMENT '实际到货时间', - `Remark` VARCHAR(512) NULL COMMENT '备注', - `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', - `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', - `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `UpdateUserId` INT NULL COMMENT '更新人', - `UpdateTime` DATETIME NULL COMMENT '更新时间', - PRIMARY KEY (`Id`), - UNIQUE KEY `uk_c_inbound_notice_no` (`NoticeNo`), - KEY `idx_c_inbound_customer_status` (`CustomerId`, `ReceiptStatus`, `CreateTime`) -) COMMENT='仓储-入库预报主表'; - -CREATE TABLE IF NOT EXISTS `C_inbound_box` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', - `InboundNoticeId` INT NOT NULL COMMENT '入库预报ID → C_inbound_notice.Id', - `BoxSeqNo` VARCHAR(16) NOT NULL COMMENT '箱序号', - `MarkBoxNo` VARCHAR(64) NULL COMMENT '箱唛号/箱号', - `WeightG` DECIMAL(10,2) NULL COMMENT '箱重(g)', - `LengthCm` DECIMAL(10,2) NULL COMMENT '长(cm)', - `WidthCm` DECIMAL(10,2) NULL COMMENT '宽(cm)', - `HeightCm` DECIMAL(10,2) NULL COMMENT '高(cm)', - `IsReceived` TINYINT NOT NULL DEFAULT 0 COMMENT '是否已收货:0-否,1-是', - `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', - `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', - `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `UpdateUserId` INT NULL COMMENT '更新人', - `UpdateTime` DATETIME NULL COMMENT '更新时间', - PRIMARY KEY (`Id`), - KEY `idx_c_inbound_box_notice` (`InboundNoticeId`, `IsDeleted`) -) COMMENT='仓储-入库预报箱'; - -CREATE TABLE IF NOT EXISTS `C_inbound_box_line` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', - `InboundBoxId` INT NOT NULL COMMENT '入库箱ID → C_inbound_box.Id', - `SkuId` INT NOT NULL COMMENT 'SKU ID → C_sku.Id', - `SkuCode` VARCHAR(64) NOT NULL COMMENT '冗余SKU编码', - `PlannedQty` INT NOT NULL DEFAULT 0 COMMENT '计划入库数量', - `ReceivedQty` INT NULL COMMENT '实收数量', - `BinLocationId` INT NULL COMMENT '上架库位ID → C_bin_location.Id', - `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', - `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', - `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `UpdateUserId` INT NULL COMMENT '更新人', - `UpdateTime` DATETIME NULL COMMENT '更新时间', - PRIMARY KEY (`Id`), - KEY `idx_c_inbound_box_line_box` (`InboundBoxId`, `IsDeleted`), - KEY `idx_c_inbound_box_line_sku` (`SkuId`) -) COMMENT='仓储-入库箱内SKU行'; - -CREATE TABLE IF NOT EXISTS `C_parcel` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', - `CustomerId` INT NOT NULL COMMENT '客户ID', - `WarehouseId` INT NOT NULL COMMENT '仓库ID', - `TrackingNo` VARCHAR(64) NOT NULL COMMENT '快递单号', - `CarrierName` VARCHAR(64) NULL COMMENT '快递公司', - `LifecycleStatus` VARCHAR(16) NOT NULL DEFAULT 'inTransit' COMMENT 'inTransit/arrived/stored', - `ArrivalTime` DATETIME NULL COMMENT '到仓时间', - `Remark` VARCHAR(512) NULL COMMENT '备注', - `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', - `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', - `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `UpdateUserId` INT NULL COMMENT '更新人', - `UpdateTime` DATETIME NULL COMMENT '更新时间', - PRIMARY KEY (`Id`), - UNIQUE KEY `uk_c_parcel_tracking` (`CustomerId`, `TrackingNo`, `WarehouseId`), - KEY `idx_c_parcel_status` (`CustomerId`, `LifecycleStatus`) -) COMMENT='仓储-客户包裹'; - -CREATE TABLE IF NOT EXISTS `C_parcel_item` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', - `ParcelId` INT NOT NULL COMMENT '包裹ID → C_parcel.Id', - `ProductName` VARCHAR(512) NULL COMMENT '商品名称', - `Quantity` INT NOT NULL DEFAULT 0 COMMENT '数量', - `SkuId` INT NULL COMMENT '库内SKU ID → C_sku.Id', - `SkuCode` VARCHAR(64) NULL COMMENT '冗余SKU编码', - `BinLocationId` INT NULL COMMENT '上架库位ID', - `Remark` VARCHAR(512) NULL COMMENT '备注', - `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', - `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', - `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `UpdateUserId` INT NULL COMMENT '更新人', - `UpdateTime` DATETIME NULL COMMENT '更新时间', - PRIMARY KEY (`Id`), - KEY `idx_c_parcel_item_parcel` (`ParcelId`, `IsDeleted`) -) COMMENT='仓储-包裹明细'; - -CREATE TABLE IF NOT EXISTS `C_sku_platform_map` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', - `CustomerId` INT NOT NULL COMMENT '客户ID', - `StoreId` INT NOT NULL COMMENT '店铺ID → t_sales_store.Id', - `PlatformSku` VARCHAR(128) NOT NULL COMMENT '平台listing SKU', - `SkuId` INT NOT NULL COMMENT '库内SKU ID → C_sku.Id', - `SkuCode` VARCHAR(64) NOT NULL COMMENT '冗余SKU编码', - `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', - `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', - `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `UpdateUserId` INT NULL COMMENT '更新人', - `UpdateTime` DATETIME NULL COMMENT '更新时间', - PRIMARY KEY (`Id`), - UNIQUE KEY `uk_c_sku_map` (`StoreId`, `PlatformSku`), - KEY `idx_c_sku_map_customer` (`CustomerId`, `SkuId`) -) COMMENT='仓储-平台SKU映射'; - --- --------------------------------------------------------------------------- --- 订单域 — 店铺(t_sales_*,接口阶段使用) --- --------------------------------------------------------------------------- - -CREATE TABLE IF NOT EXISTS `t_sales_store` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', - `CustomerId` INT NOT NULL COMMENT '客户ID', - `PlatformCode` VARCHAR(32) NOT NULL COMMENT 'lazada/shopee/tiktok/temu/manual', - `StoreNickname` VARCHAR(128) NOT NULL COMMENT '店铺昵称', - `PlatformStoreId` VARCHAR(64) NULL COMMENT '平台侧店铺ID', - `PlatformAccount` VARCHAR(128) NULL COMMENT '平台账号', - `SiteCountry` VARCHAR(8) NULL COMMENT '开户站点国家码', - `SellerId` VARCHAR(64) NULL COMMENT '平台卖家ID', - `AuthStatus` VARCHAR(16) NOT NULL DEFAULT 'active' COMMENT 'active/expired/revoked', - `AuthTime` DATETIME NULL COMMENT '授权时间', - `TokenExpireTime` DATETIME NULL COMMENT 'AccessToken过期时间', - `RefreshExpireTime` DATETIME NULL COMMENT 'RefreshToken过期时间', - `AccessToken` VARCHAR(2048) NULL COMMENT 'AccessToken(加密存储)', - `RefreshToken` VARCHAR(2048) NULL COMMENT 'RefreshToken(加密存储)', - `TokenExtraJson` JSON NULL COMMENT '平台扩展Token信息', - `IsAutoFulfill` TINYINT NOT NULL DEFAULT 0 COMMENT '是否自动发货:0-否,1-是', - `Remark` VARCHAR(512) NULL COMMENT '备注', - `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', - `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', - `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `UpdateUserId` INT NULL COMMENT '更新人', - `UpdateTime` DATETIME NULL COMMENT '更新时间', - PRIMARY KEY (`Id`), - KEY `idx_sales_store_customer` (`CustomerId`, `IsDeleted`), - KEY `idx_sales_store_platform` (`CustomerId`, `PlatformCode`, `AuthStatus`) -) COMMENT='销售店铺授权'; - -CREATE TABLE IF NOT EXISTS `t_sales_store_order` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', - `CustomerId` INT NOT NULL COMMENT '客户ID', - `StoreId` INT NOT NULL COMMENT '店铺ID → t_sales_store.Id', - `PlatformCode` VARCHAR(32) NOT NULL COMMENT '平台编码', - `PlatformOrderNo` VARCHAR(64) NOT NULL COMMENT '平台订单号', - `OrderCountry` VARCHAR(8) NULL COMMENT '订单国家', - `ItemCount` INT NULL COMMENT '商品行数', - `TotalAmount` DECIMAL(18,4) NULL COMMENT '订单总额', - `Currency` VARCHAR(8) NULL COMMENT '币种', - `PlatformOrderTime` DATETIME NULL COMMENT '平台下单时间', - `FulfillStatus` VARCHAR(32) NOT NULL DEFAULT 'pending' COMMENT '履约状态', - `PlatformStatus` VARCHAR(64) NULL COMMENT '平台原始状态码', - `PlatformStatusLabel` VARCHAR(128) NULL COMMENT '平台状态展示文案', - `ShippingLabelNo` VARCHAR(64) NULL COMMENT '面单号', - `ShippingLabelUrl` VARCHAR(512) NULL COMMENT '面单URL', - `IsMultiLabel` TINYINT NOT NULL DEFAULT 0 COMMENT '是否多面单', - `CustomTags` VARCHAR(512) NULL COMMENT '自定义标签', - `IsSuspended` TINYINT NOT NULL DEFAULT 0 COMMENT '是否搁置', - `WarehouseId` INT NULL COMMENT '发货仓库ID', - `LinkedOrderId` INT NULL COMMENT '关联小包订单 t_order.Id', - `LastSyncTime` DATETIME NULL COMMENT '最近同步时间', - `PlatformExtraJson` JSON NULL COMMENT '平台扩展字段', - `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', - `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', - `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `UpdateUserId` INT NULL COMMENT '更新人', - `UpdateTime` DATETIME NULL COMMENT '更新时间', - PRIMARY KEY (`Id`), - UNIQUE KEY `uk_store_order_no` (`StoreId`, `PlatformOrderNo`), - KEY `idx_store_order_customer_status` (`CustomerId`, `FulfillStatus`, `PlatformOrderTime`) -) COMMENT='销售店铺订单'; - -CREATE TABLE IF NOT EXISTS `t_sales_store_order_line` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', - `StoreOrderId` INT NOT NULL COMMENT '店铺订单ID → t_sales_store_order.Id', - `PlatformLineId` VARCHAR(64) NULL COMMENT '平台行ID', - `PlatformSku` VARCHAR(128) NULL COMMENT '平台SKU', - `ProductName` VARCHAR(512) NULL COMMENT '商品名称', - `ProductImageUrl` VARCHAR(512) NULL COMMENT '商品图片', - `VariantText` VARCHAR(256) NULL COMMENT '规格属性', - `UnitPrice` DECIMAL(18,4) NULL COMMENT '单价', - `Quantity` INT NOT NULL DEFAULT 0 COMMENT '数量', - `Currency` VARCHAR(8) NULL COMMENT '币种', - `IsShipExcluded` TINYINT NOT NULL DEFAULT 0 COMMENT '是否拒绝发货', - `MappedSkuId` INT NULL COMMENT '映射库内SKU → C_sku.Id', - `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', - `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', - `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `UpdateUserId` INT NULL COMMENT '更新人', - `UpdateTime` DATETIME NULL COMMENT '更新时间', - PRIMARY KEY (`Id`), - KEY `idx_store_order_line_order` (`StoreOrderId`, `IsDeleted`) -) COMMENT='销售店铺订单明细'; diff --git a/sql/migrate_warehouse_module_concurrency.sql b/sql/migrate_warehouse_module_concurrency.sql deleted file mode 100644 index a5eda23..0000000 --- a/sql/migrate_warehouse_module_concurrency.sql +++ /dev/null @@ -1,50 +0,0 @@ --- 已执行旧版 migrate_warehouse_module.sql 的库补 ConcurrencyStamp(与 AggregateRoot 实体对齐) --- 勿在 ALTER 中使用 DEFAULT(UUID()),复制环境会报 Error 1674 - -ALTER TABLE `C_sku` - ADD COLUMN `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT '' COMMENT '并发戳' AFTER `IsDeleted`; -UPDATE `C_sku` SET `ConcurrencyStamp` = UUID() WHERE `ConcurrencyStamp` = ''; - -ALTER TABLE `C_bin_location` - ADD COLUMN `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT '' COMMENT '并发戳' AFTER `IsDeleted`; -UPDATE `C_bin_location` SET `ConcurrencyStamp` = UUID() WHERE `ConcurrencyStamp` = ''; - -ALTER TABLE `C_inventory` - ADD COLUMN `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT '' COMMENT '并发戳' AFTER `IsDeleted`; -UPDATE `C_inventory` SET `ConcurrencyStamp` = UUID() WHERE `ConcurrencyStamp` = ''; - -ALTER TABLE `C_inbound_notice` - ADD COLUMN `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT '' COMMENT '并发戳' AFTER `IsDeleted`; -UPDATE `C_inbound_notice` SET `ConcurrencyStamp` = UUID() WHERE `ConcurrencyStamp` = ''; - -ALTER TABLE `C_inbound_box` - ADD COLUMN `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT '' COMMENT '并发戳' AFTER `IsDeleted`; -UPDATE `C_inbound_box` SET `ConcurrencyStamp` = UUID() WHERE `ConcurrencyStamp` = ''; - -ALTER TABLE `C_inbound_box_line` - ADD COLUMN `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT '' COMMENT '并发戳' AFTER `IsDeleted`; -UPDATE `C_inbound_box_line` SET `ConcurrencyStamp` = UUID() WHERE `ConcurrencyStamp` = ''; - -ALTER TABLE `C_parcel` - ADD COLUMN `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT '' COMMENT '并发戳' AFTER `IsDeleted`; -UPDATE `C_parcel` SET `ConcurrencyStamp` = UUID() WHERE `ConcurrencyStamp` = ''; - -ALTER TABLE `C_parcel_item` - ADD COLUMN `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT '' COMMENT '并发戳' AFTER `IsDeleted`; -UPDATE `C_parcel_item` SET `ConcurrencyStamp` = UUID() WHERE `ConcurrencyStamp` = ''; - -ALTER TABLE `C_sku_platform_map` - ADD COLUMN `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT '' COMMENT '并发戳' AFTER `IsDeleted`; -UPDATE `C_sku_platform_map` SET `ConcurrencyStamp` = UUID() WHERE `ConcurrencyStamp` = ''; - -ALTER TABLE `t_sales_store` - ADD COLUMN `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT '' COMMENT '并发戳' AFTER `IsDeleted`; -UPDATE `t_sales_store` SET `ConcurrencyStamp` = UUID() WHERE `ConcurrencyStamp` = ''; - -ALTER TABLE `t_sales_store_order` - ADD COLUMN `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT '' COMMENT '并发戳' AFTER `IsDeleted`; -UPDATE `t_sales_store_order` SET `ConcurrencyStamp` = UUID() WHERE `ConcurrencyStamp` = ''; - -ALTER TABLE `t_sales_store_order_line` - ADD COLUMN `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT '' COMMENT '并发戳' AFTER `IsDeleted`; -UPDATE `t_sales_store_order_line` SET `ConcurrencyStamp` = UUID() WHERE `ConcurrencyStamp` = ''; diff --git a/sql/migrate_wechat_mp_other_config.sql b/sql/migrate_wechat_mp_other_config.sql deleted file mode 100644 index 4e4c778..0000000 --- a/sql/migrate_wechat_mp_other_config.sql +++ /dev/null @@ -1,31 +0,0 @@ --- 微信公众号配置(t_system_other_config) --- 字段映射:AppKey=AppId,AppSecret=Secret,Remark=Token,BaseUrl=OAuthRedirectBase --- 请在管理端「系统 → 其他配置」填写真实 AppId / AppSecret / Token,勿将密钥提交到 Git。 - -INSERT INTO `t_system_other_config` ( - `ConfigCode`, - `ConfigName`, - `Enabled`, - `BaseUrl`, - `AppKey`, - `AppSecret`, - `Remark`, - `TimeoutSeconds`, - `IsDeleted`, - `CreateUserId` -) -SELECT - 'wechat_mp', - '微信公众号', - 1, - 'https://oms.nanafa.com', - '', - '', - '', - 30, - 0, - 0 -FROM DUAL -WHERE NOT EXISTS ( - SELECT 1 FROM `t_system_other_config` WHERE `ConfigCode` = 'wechat_mp' AND `IsDeleted` = 0 -); diff --git a/sql/parcel_billing.sql b/sql/parcel_billing.sql deleted file mode 100644 index 90017c2..0000000 --- a/sql/parcel_billing.sql +++ /dev/null @@ -1,39 +0,0 @@ --- 与 migrate_t_order_parcel_columns.sql 相同,保留此文件名便于按文档引用 --- t_order / t_order_fee 小包预报计费字段补齐(可重复执行) - -SET @db = DATABASE(); - -SET @exist := (SELECT COUNT(*) FROM information_schema.COLUMNS - WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 't_order' AND COLUMN_NAME = 'ExportCustomsMode'); -SET @sql := IF(@exist = 0, - 'ALTER TABLE `t_order` ADD COLUMN `ExportCustomsMode` VARCHAR(32) NULL COMMENT ''出口报关方式'' AFTER `CargoAttribute`', - 'SELECT ''skip ExportCustomsMode'''); -PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; - -SET @exist := (SELECT COUNT(*) FROM information_schema.COLUMNS - WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 't_order' AND COLUMN_NAME = 'PredeclareFailReason'); -SET @sql := IF(@exist = 0, - 'ALTER TABLE `t_order` ADD COLUMN `PredeclareFailReason` VARCHAR(512) NULL COMMENT ''预报失败原因'' AFTER `IsRemote`', - 'SELECT ''skip PredeclareFailReason'''); -PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; - -SET @exist := (SELECT COUNT(*) FROM information_schema.COLUMNS - WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 't_order' AND COLUMN_NAME = 'SalesProductRulesVersion'); -SET @sql := IF(@exist = 0, - 'ALTER TABLE `t_order` ADD COLUMN `SalesProductRulesVersion` VARCHAR(64) NULL COMMENT ''销售产品规则快照版本'' AFTER `PredeclareFailReason`', - 'SELECT ''skip SalesProductRulesVersion'''); -PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; - -SET @exist := (SELECT COUNT(*) FROM information_schema.COLUMNS - WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 't_order' AND COLUMN_NAME = 'SalesProductPriceVersion'); -SET @sql := IF(@exist = 0, - 'ALTER TABLE `t_order` ADD COLUMN `SalesProductPriceVersion` VARCHAR(64) NULL COMMENT ''销售产品价格快照版本'' AFTER `SalesProductRulesVersion`', - 'SELECT ''skip SalesProductPriceVersion'''); -PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; - -SET @exist := (SELECT COUNT(*) FROM information_schema.COLUMNS - WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 't_order_fee' AND COLUMN_NAME = 'ChargingStage'); -SET @sql := IF(@exist = 0, - 'ALTER TABLE `t_order_fee` ADD COLUMN `ChargingStage` VARCHAR(16) NULL COMMENT ''计费阶段:forecast/inbound/outbound'' AFTER `PriceEffectiveTime`', - 'SELECT ''skip ChargingStage'''); -PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; diff --git a/sql/seed_data_perm_rbac_menu.sql b/sql/seed_data_perm_rbac_menu.sql deleted file mode 100644 index b33a4bb..0000000 --- a/sql/seed_data_perm_rbac_menu.sql +++ /dev/null @@ -1,117 +0,0 @@ --- 数据权限管理 — RBAC 菜单与权限码种子 --- 前端路由:/system/dataPerm/users、/system/dataPerm/templates、/system/dataPerm/audit --- PermissionCode 须在 PermissionDefinitionProvider 注册后方能分配 - -SET @ADMIN_USER_ID = ( - SELECT `Id` FROM `user` - WHERE `Account` = 'admin' AND (`IsDeleted` = 0 OR `IsDeleted` IS NULL) - LIMIT 1 -); -SET @ADMIN_USER_ID = IFNULL(@ADMIN_USER_ID, '08de4226-3fd4-4a5c-83e5-70e164b15f2f'); -SET @ROOT_PID = '00000000-0000-0000-0000-000000000000'; - --- 查找「系统管理」父菜单(若无则挂根) -SET @SYSTEM_PID = ( - SELECT `Id` FROM `menu` - WHERE (`Route` = '/system' OR `Name` = '系统管理') - AND (`IsDeleted` = 0 OR `IsDeleted` IS NULL) - ORDER BY `Order` - LIMIT 1 -); -SET @SYSTEM_PID = IFNULL(@SYSTEM_PID, @ROOT_PID); - -INSERT INTO `menu` ( - `Id`, `PId`, `Name`, `PermissionCode`, `Type`, `Icon`, `Route`, `Component`, `Order`, - `IsHidden`, `IsCached`, `Description`, `IsDeleted`, - `ConcurrencyStamp`, `CreateUserId`, `CreateTime`, `UpdateUserId`, `UpdateTime` -) VALUES -( - 'da100001-0000-4000-8000-000000000001', - @SYSTEM_PID, - '数据权限', - 'Rbac.DataPerm', - 1, - 'icon-safe', - '/system/dataPerm', - NULL, - 90, - 0, 1, '多维数据权限配置', 0, - UUID(), @ADMIN_USER_ID, NOW(), @ADMIN_USER_ID, NOW() -), -( - 'da100001-0000-4000-8000-000000000002', - 'da100001-0000-4000-8000-000000000001', - '用户数据权限', - 'Rbac.DataPerm.Query', - 1, - NULL, - '/system/dataPerm/users', - 'views/system/dataPerm/users/index', - 1, - 0, 1, NULL, 0, - UUID(), @ADMIN_USER_ID, NOW(), @ADMIN_USER_ID, NOW() -), -( - 'da100001-0000-4000-8000-000000000003', - 'da100001-0000-4000-8000-000000000001', - '权限模板', - 'Rbac.DataPerm.Template', - 1, - NULL, - '/system/dataPerm/templates', - 'views/system/dataPerm/templates/index', - 2, - 0, 1, NULL, 0, - UUID(), @ADMIN_USER_ID, NOW(), @ADMIN_USER_ID, NOW() -), -( - 'da100001-0000-4000-8000-000000000004', - 'da100001-0000-4000-8000-000000000001', - '访问审计', - 'Rbac.DataPerm.Audit', - 1, - NULL, - '/system/dataPerm/audit', - 'views/system/dataPerm/audit/index', - 3, - 0, 0, NULL, 0, - UUID(), @ADMIN_USER_ID, NOW(), @ADMIN_USER_ID, NOW() -), -( - 'da100001-0000-4000-8000-000000000005', - 'da100001-0000-4000-8000-000000000002', - '保存用户权限', - 'Rbac.DataPerm.Update', - 2, - NULL, - NULL, - NULL, - 1, - 0, 0, NULL, 0, - UUID(), @ADMIN_USER_ID, NOW(), @ADMIN_USER_ID, NOW() -) -ON DUPLICATE KEY UPDATE - `Name` = VALUES(`Name`), - `PId` = VALUES(`PId`), - `PermissionCode` = VALUES(`PermissionCode`), - `Route` = VALUES(`Route`), - `Component` = VALUES(`Component`), - `Order` = VALUES(`Order`); - --- 超管角色分配数据权限(若存在 Admin 角色) -INSERT INTO `role_permission` (`Id`, `RoleId`, `PermissionCode`, `CreateUserId`, `CreateTime`) -SELECT UUID(), r.`Id`, p.`Code`, @ADMIN_USER_ID, NOW() -FROM `role` r -CROSS JOIN ( - SELECT 'Rbac.DataPerm' AS Code UNION ALL - SELECT 'Rbac.DataPerm.Query' UNION ALL - SELECT 'Rbac.DataPerm.Update' UNION ALL - SELECT 'Rbac.DataPerm.Template' UNION ALL - SELECT 'Rbac.DataPerm.Audit' -) p -WHERE r.`Code` = 'Admin' - AND (r.`IsDeleted` = 0 OR r.`IsDeleted` IS NULL) - AND NOT EXISTS ( - SELECT 1 FROM `role_permission` rp - WHERE rp.`RoleId` = r.`Id` AND rp.`PermissionCode` = p.`Code` - ); diff --git a/sql/seed_e2e_order_lifecycle.sql b/sql/seed_e2e_order_lifecycle.sql deleted file mode 100644 index 39a66bf..0000000 --- a/sql/seed_e2e_order_lifecycle.sql +++ /dev/null @@ -1,149 +0,0 @@ --- E2E 订单全链路测试主数据(固定 ID 段 900x / 99001) --- 前置:已执行 db.sql;库中已有 t_country.US --- 用法:mysql ... oms_test < sql/seed_e2e_order_lifecycle.sql --- RBAC 批量任务菜单/权限:sql/seed_order_lab_rbac_menu.sql + sql/seed_order_lab_role_permissions.sql - -SET NAMES utf8mb4; -SET FOREIGN_KEY_CHECKS = 0; - --- 清理旧 E2E 数据(子表优先) -DELETE FROM `t_sales_product_allocation_provider` WHERE `SalesProductId` = 9001; -DELETE FROM `t_sales_product_price_detail` WHERE `PriceId` = 9001; -DELETE FROM `t_sales_product_price_factor` WHERE `PriceId` = 9001; -DELETE FROM `t_sales_product_price` WHERE `Id` = 9001; -DELETE FROM `t_service_channel_price_detail` WHERE `PriceId` = 9001; -DELETE FROM `t_service_channel_price_factor` WHERE `PriceId` = 9001; -DELETE FROM `t_service_channel_price` WHERE `Id` = 9001; -DELETE FROM `t_sales_product` WHERE `Id` = 9001; -DELETE FROM `t_service_channel` WHERE `Id` = 9001; -DELETE FROM `t_weight_rounding_info` WHERE `RoundingId` = 9001; -DELETE FROM `t_weight_rounding` WHERE `Id` = 9001; -DELETE FROM `t_weight_rule_info` WHERE `RuleId` = 9001; -DELETE FROM `t_weight_rule` WHERE `Id` = 9001; -DELETE FROM `t_kpi_area_info` WHERE `AreaId` = 9001; -DELETE FROM `t_kpi_area` WHERE `Id` = 9001; -DELETE FROM `t_warehouse_address` WHERE `Id` = 9001; -DELETE FROM `t_customer` WHERE `Id` = 99001; - --- 仓库 -INSERT INTO `t_warehouse_address` ( - `Id`, `WarehouseName`, `WarehouseType`, `Recipient`, `ContactPhone`, `ShippingAddress`, - `IsDeleted`, `ConcurrencyStamp`, `CreateUserId`, `CreateTime` -) VALUES ( - 9001, 'E2E测试仓', 'main', 'E2E', '0755-00000000', '深圳市南山区测试路1号', - 0, UUID(), 0, NOW() -); - --- 价格分区(美西 → US) -INSERT INTO `t_kpi_area` ( - `Id`, `AppKey`, `AreaType`, `Name`, `SystemName`, - `IsDeleted`, `ConcurrencyStamp`, `CreateUserId`, `CreateTime` -) VALUES ( - 9001, 'oms', 'warning', '美西', 'E2E-US-WEST', - 0, UUID(), 0, NOW() -); - -INSERT INTO `t_kpi_area_info` ( - `AreaId`, `CountryCode`, `CountryName`, `IsDeleted`, `CreateUserId`, `CreateTime` -) VALUES ( - 9001, 'US', '美国', 0, 0, NOW() -); - --- 计重规则 / 进位 -INSERT INTO `t_weight_rule` ( - `Id`, `AppKey`, `Name`, `IsDeleted`, `ConcurrencyStamp`, `CreateUserId`, `CreateTime` -) VALUES ( - 9001, 'oms', 'E2E计重规则', 0, UUID(), 0, NOW() -); - -INSERT INTO `t_weight_rule_info` ( - `RuleId`, `Client`, `Condition`, `BillableWeight`, `VolumetricFactor`, - `IsDeleted`, `CreateUserId`, `CreateTime` -) VALUES ( - 9001, '全部', 'gw>=vw', 'gw', '6000', 0, 0, NOW() -); - -INSERT INTO `t_weight_rounding` ( - `Id`, `AppKey`, `Name`, `IsDeleted`, `ConcurrencyStamp`, `CreateUserId`, `CreateTime` -) VALUES ( - 9001, 'oms', 'E2E进位', 0, UUID(), 0, NOW() -); - -INSERT INTO `t_weight_rounding_info` ( - `RoundingId`, `StartValue`, `EndValue`, `Public`, `IsDeleted`, `CreateUserId`, `CreateTime` -) VALUES ( - 9001, 0, 30, '0.5', 0, 0, NOW() -); - --- 服务渠道 + 买价 -INSERT INTO `t_service_channel` ( - `Id`, `ChannelCode`, `ChannelName`, `IsActive`, - `IsDeleted`, `ConcurrencyStamp`, `CreateUserId`, `CreateTime` -) VALUES ( - 9001, 'E2E-CH-01', 'E2E测试渠道', 1, - 0, UUID(), 0, NOW() -); - -INSERT INTO `t_service_channel_price` ( - `Id`, `ServiceChannelId`, `SerialNumber`, `Status`, `PriceName`, `CostItem`, `CostUnit`, `Currency`, - `IsDeleted`, `CreateUserId`, `CreateTime` -) VALUES ( - 9001, 9001, 1, 1, 'E2E买价', 'freight', 'kg', 'CNY', - 0, 0, NOW() -); - -INSERT INTO `t_service_channel_price_detail` ( - `PriceId`, `FactorValuesJson`, `CalculationFormula`, `CalculatedValue`, - `IsDeleted`, `CreateUserId`, `CreateTime` -) VALUES ( - 9001, - '{"分区":"美西","货物类型":"普货","首重":"1","首重价":"10","续重单位":"0.5","续重价":"4"}', - '续单价', NULL, - 0, 0, NOW() -); - --- 销售产品 + 卖价 + 排货 -INSERT INTO `t_sales_product` ( - `Id`, `ProductCode`, `ProductName`, `ProductGroup`, `PriceAreaId`, `WeightRuleId`, `WeightRoundingId`, - `IsActive`, `Scheme`, `IsDeleted`, `ConcurrencyStamp`, `CreateUserId`, `CreateTime` -) VALUES ( - 9001, 'E2E-SP-01', 'E2E测试产品', '专线', 9001, 9001, 9001, - 1, 'costLowest', 0, UUID(), 0, NOW() -); - -INSERT INTO `t_sales_product_price` ( - `Id`, `SalesProductId`, `SerialNumber`, `Status`, `PriceName`, `CostItem`, `CostUnit`, `Currency`, - `IsDeleted`, `CreateUserId`, `CreateTime` -) VALUES ( - 9001, 9001, 1, 1, 'E2E卖价', 'freight', 'kg', 'CNY', - 0, 0, NOW() -); - -INSERT INTO `t_sales_product_price_detail` ( - `PriceId`, `FactorValuesJson`, `CalculationFormula`, `CalculatedValue`, - `IsDeleted`, `CreateUserId`, `CreateTime` -) VALUES ( - 9001, - '{"分区":"美西","货物类型":"普货","首重":"1","首重价":"18","续重单位":"0.5","续重价":"6"}', - '续单价', NULL, - 0, 0, NOW() -); - -INSERT INTO `t_sales_product_allocation_provider` ( - `SalesProductId`, `SerialNumber`, `ProviderName`, `ServiceChannelId`, `Weight`, - `IsDeleted`, `CreateUserId`, `CreateTime` -) VALUES ( - 9001, 1, 'E2E渠道商', 9001, 100, - 0, 0, NOW() -); - --- 客户(密码明文 e2e123 → MD5) -INSERT INTO `t_customer` ( - `Id`, `UserId`, `CustomerCode`, `CustomerName`, `Email`, `Phone`, `Balance`, - `Status`, `Password`, `IsDeleted`, `ConcurrencyStamp`, `CreateUserId`, `CreateTime` -) VALUES ( - 99001, 1, 'E2E001', 'E2E测试客户', 'e2e99001@test.local', '19900009901', 50000.00, - 1, '5df3e7decfd8323014e399401de7d82f', 0, UUID(), 0, NOW() -); - -SET FOREIGN_KEY_CHECKS = 1; diff --git a/sql/seed_order_lab_rbac_menu.sql b/sql/seed_order_lab_rbac_menu.sql deleted file mode 100644 index a186e5c..0000000 --- a/sql/seed_order_lab_rbac_menu.sql +++ /dev/null @@ -1,54 +0,0 @@ --- 订单批量任务 RBAC 菜单(Fake.Rbac menu 表) --- 执行库:RBAC 库(与 seed_xhs_rbac_menu.sql 相同) --- 幂等:可重复执行 - -SET @ADMIN_USER_ID = ( - SELECT `Id` FROM `user` - WHERE `Account` = 'admin' AND (`IsDeleted` = 0 OR `IsDeleted` IS NULL) - LIMIT 1 -); -SET @ADMIN_USER_ID = IFNULL( - @ADMIN_USER_ID, - '08de4226-3fd4-4a5c-83e5-70e164b15f2f' -); - -SET @ORDER_PID = ( - SELECT `Id` FROM `menu` - WHERE `Route` = '/order' AND `IsDeleted` = 0 - ORDER BY `Order` - LIMIT 1 -); -SET @ORDER_PID = IFNULL(@ORDER_PID, '00000000-0000-0000-0000-000000000000'); - -INSERT INTO `menu` ( - `Id`, `PId`, `Name`, `PermissionCode`, `Type`, `Icon`, `Route`, `Component`, `Order`, - `IsHidden`, `IsCached`, `Description`, `IsDeleted`, - `ConcurrencyStamp`, `CreateUserId`, `CreateTime`, `UpdateUserId`, `UpdateTime` -) VALUES ( - 'b1b2c3d4-e5f6-7890-abcd-ef1234567901', - @ORDER_PID, - '批量任务', - 'Order.BatchJobs', - 1, - NULL, - '/order/batchJobs', - 'views/order/batchJobs/index', - 4, - 0, 1, '订单 RabbitMQ 批量任务治理', 0, - UUID(), @ADMIN_USER_ID, NOW(), @ADMIN_USER_ID, NOW() -) -ON DUPLICATE KEY UPDATE - `Name` = VALUES(`Name`), - `PId` = VALUES(`PId`), - `PermissionCode` = VALUES(`PermissionCode`), - `Route` = VALUES(`Route`), - `Component` = VALUES(`Component`), - `Order` = VALUES(`Order`), - `Description` = VALUES(`Description`), - `CreateUserId` = VALUES(`CreateUserId`), - `UpdateUserId` = VALUES(`UpdateUserId`); - --- 清理已废弃的链路演练菜单 -UPDATE `menu` -SET `IsDeleted` = 1, `UpdateTime` = NOW(), `UpdateUserId` = @ADMIN_USER_ID -WHERE `Route` = '/order/lifecycleLab' AND `IsDeleted` = 0; diff --git a/sql/seed_order_lab_role_permissions.sql b/sql/seed_order_lab_role_permissions.sql deleted file mode 100644 index adef590..0000000 --- a/sql/seed_order_lab_role_permissions.sql +++ /dev/null @@ -1,31 +0,0 @@ --- 为 Admin / Customer 角色追加批量任务权限(幂等) --- RBAC 库执行;执行后登录用户需重新获取 token 或刷新权限缓存 - -SET @ADMIN_USER_ID = ( - SELECT `Id` FROM `user` - WHERE `Account` = 'admin' AND (`IsDeleted` = 0 OR `IsDeleted` IS NULL) - LIMIT 1 -); -SET @ADMIN_USER_ID = IFNULL( - @ADMIN_USER_ID, - '08de4226-3fd4-4a5c-83e5-70e164b15f2f' -); - -INSERT INTO `role_permission` (`Id`, `RoleId`, `PermissionCode`, `CreateUserId`, `CreateTime`) -SELECT UUID(), r.`Id`, p.`Code`, @ADMIN_USER_ID, NOW() -FROM `role` r -CROSS JOIN ( - SELECT 'Order.BatchJobs.Query' AS `Code` UNION ALL - SELECT 'Order.BatchJobs.View' UNION ALL - SELECT 'Order.BatchJobs.Retry' UNION ALL - SELECT 'Order.BatchJobs.Cancel' -) p -WHERE r.`Code` IN ('Admin', 'Customer') - AND NOT EXISTS ( - SELECT 1 FROM `role_permission` rp - WHERE rp.`RoleId` = r.`Id` AND rp.`PermissionCode` = p.`Code` - ); - --- 清理已废弃的链路演练权限 -DELETE FROM `role_permission` -WHERE `PermissionCode` LIKE 'Order.LifecycleLab.%'; diff --git a/sql/seed_order_template_dedicated_small_parcel.sql b/sql/seed_order_template_dedicated_small_parcel.sql deleted file mode 100644 index 93159e5..0000000 --- a/sql/seed_order_template_dedicated_small_parcel.sql +++ /dev/null @@ -1,20 +0,0 @@ --- 标准模板:专线小包模板 -INSERT INTO `t_order_template` ( - `Name`, `Type`, `TemplateKey`, `StandardTemplateKey`, `MappingStatus`, - `CustomerId`, `IsDeleted`, `CreateUserId`, `CreateTime` -) -SELECT - '专线小包模板', - 'standard', - 'dedicated_small_parcel_v1', - 'dedicated_small_parcel_v1', - 'ready', - NULL, - 0, - 0, - NOW() -FROM DUAL -WHERE NOT EXISTS ( - SELECT 1 FROM `t_order_template` - WHERE `Type` = 'standard' AND `TemplateKey` = 'dedicated_small_parcel_v1' AND `IsDeleted` = 0 -); diff --git a/sql/seed_warehouse_module_permissions.sql b/sql/seed_warehouse_module_permissions.sql deleted file mode 100644 index b50bbae..0000000 --- a/sql/seed_warehouse_module_permissions.sql +++ /dev/null @@ -1,45 +0,0 @@ --- ???? + ????/?? RBAC ?????? --- RBAC ????????????????????? - -SET @ADMIN_USER_ID = ( - SELECT `Id` FROM `user` - WHERE `Account` = 'admin' AND (`IsDeleted` = 0 OR `IsDeleted` IS NULL) - LIMIT 1 -); -SET @ADMIN_USER_ID = IFNULL( - @ADMIN_USER_ID, - '08de4226-3fd4-4a5c-83e5-70e164b15f2f' -); - -INSERT INTO `role_permission` (`Id`, `RoleId`, `PermissionCode`, `CreateUserId`, `CreateTime`) -SELECT UUID(), r.`Id`, p.`Code`, @ADMIN_USER_ID, NOW() -FROM `role` r -CROSS JOIN ( - SELECT 'Warehouse.Sku.Query' AS `Code` UNION ALL - SELECT 'Warehouse.Sku.Save' UNION ALL - SELECT 'Warehouse.Sku.Delete' UNION ALL - SELECT 'Warehouse.Inventory.Query' UNION ALL - SELECT 'Warehouse.Inventory.Relocate' UNION ALL - SELECT 'Warehouse.BinLocation.Query' UNION ALL - SELECT 'Warehouse.BinLocation.Save' UNION ALL - SELECT 'Warehouse.Parcel.Query' UNION ALL - SELECT 'Warehouse.Parcel.Save' UNION ALL - SELECT 'Warehouse.Parcel.Delete' UNION ALL - SELECT 'Warehouse.InboundNotice.Query' UNION ALL - SELECT 'Warehouse.InboundNotice.Save' UNION ALL - SELECT 'Warehouse.InboundNotice.ConfirmReceive' UNION ALL - SELECT 'Warehouse.InboundNotice.Delete' UNION ALL - SELECT 'Order.PlatformStore.Query' UNION ALL - SELECT 'Order.PlatformStore.Save' UNION ALL - SELECT 'Order.PlatformStore.Delete' UNION ALL - SELECT 'Order.PlatformStore.Auth' UNION ALL - SELECT 'Order.PlatformStoreOrder.Query' UNION ALL - SELECT 'Order.PlatformStoreOrder.MatchInventory' UNION ALL - SELECT 'Order.PlatformStoreOrder.ToggleSuspend' UNION ALL - SELECT 'Order.PlatformStoreOrder.Delete' -) p -WHERE r.`Code` IN ('Admin', 'Customer') - AND NOT EXISTS ( - SELECT 1 FROM `role_permission` rp - WHERE rp.`RoleId` = r.`Id` AND rp.`PermissionCode` = p.`Code` - ); diff --git a/sql/seed_xhs_ai_providers.sql b/sql/seed_xhs_ai_providers.sql deleted file mode 100644 index 92b4536..0000000 --- a/sql/seed_xhs_ai_providers.sql +++ /dev/null @@ -1,36 +0,0 @@ --- 小红书 AI 提供商模板(CustomerId=0 全局,需填入 ApiKeyEnc / ApiSecretEnc 后启用) --- ApiSecretEnc 字段存模型名,如 glm-4-flash / deepseek-chat / gpt-4o-mini --- --- 若报 1146 Table doesn't exist:请先执行 migrate_t_xhs.sql - -CREATE TABLE IF NOT EXISTS `t_xhs_ai_provider` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', - `CustomerId` INT NOT NULL COMMENT '客户ID;0 表示全局', - `ProviderKey` VARCHAR(32) NOT NULL COMMENT 'ai_chatgpt / ai_zhipu 等', - `ProviderType` VARCHAR(32) NOT NULL COMMENT 'chatgpt/doubao/deepseek/zhipu', - `DisplayName` VARCHAR(64) NOT NULL COMMENT '展示名', - `BaseUrl` VARCHAR(512) NOT NULL COMMENT 'API Base URL', - `ApiKeyEnc` VARCHAR(512) NULL COMMENT 'API Key(暂明文,后续可加密)', - `ApiSecretEnc` VARCHAR(512) NULL COMMENT 'Secret/模型名', - `IsDefault` TINYINT NOT NULL DEFAULT 0 COMMENT '是否默认', - `Enabled` TINYINT NOT NULL DEFAULT 1 COMMENT '是否启用', - `IsDeleted` TINYINT NOT NULL DEFAULT 0, - `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()), - `CreateUserId` INT NOT NULL DEFAULT 0, - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `UpdateUserId` INT NULL, - `UpdateTime` DATETIME NULL, - PRIMARY KEY (`Id`), - UNIQUE KEY `uk_xhs_ai_provider` (`CustomerId`, `ProviderKey`), - KEY `idx_xhs_ai_customer` (`CustomerId`, `Enabled`) -) COMMENT='小红书 AI 提供商配置表'; - -INSERT INTO `t_xhs_ai_provider` ( - `CustomerId`, `ProviderKey`, `ProviderType`, `DisplayName`, `BaseUrl`, - `ApiKeyEnc`, `ApiSecretEnc`, `IsDefault`, `Enabled`, - `IsDeleted`, `CreateUserId`, `CreateTime` -) VALUES -(0, 'ai_zhipu', 'zhipu', '智谱 AI', 'https://open.bigmodel.cn/api/paas/v4', NULL, 'glm-4-flash', 1, 0, 0, 0, NOW()), -(0, 'ai_deepseek', 'deepseek', 'DeepSeek', 'https://api.deepseek.com/v1', NULL, 'deepseek-chat', 0, 0, 0, 0, NOW()), -(0, 'ai_chatgpt', 'chatgpt', 'OpenAI', 'https://api.openai.com/v1', NULL, 'gpt-4o-mini', 0, 0, 0, 0, NOW()) -ON DUPLICATE KEY UPDATE `DisplayName` = VALUES(`DisplayName`), `BaseUrl` = VALUES(`BaseUrl`); diff --git a/sql/seed_xhs_rbac_menu.sql b/sql/seed_xhs_rbac_menu.sql deleted file mode 100644 index 5b59481..0000000 --- a/sql/seed_xhs_rbac_menu.sql +++ /dev/null @@ -1,97 +0,0 @@ --- 小红书模块 RBAC 菜单种子(Fake.Rbac menu 表) --- 设计文档:E:\oms0414\docs\小红书模块设计-063001.md --- --- 注意:本环境 menu.CreateUserId / UpdateUserId 为 CHAR(36) GUID,不可写整数 0 --- 若已误插入导致 get-menu-tree 报错,先执行 fix_xhs_menu_bad_guids.sql - -SET @ADMIN_USER_ID = ( - SELECT `Id` FROM `user` - WHERE `Account` = 'admin' AND (`IsDeleted` = 0 OR `IsDeleted` IS NULL) - LIMIT 1 -); -SET @ADMIN_USER_ID = IFNULL( - @ADMIN_USER_ID, - '08de4226-3fd4-4a5c-83e5-70e164b15f2f' -); -SET @ROOT_PID = '00000000-0000-0000-0000-000000000000'; - --- 一级:小红书(目录节点,PermissionCode 留空字符串;子菜单各自绑权限) -INSERT INTO `menu` ( - `Id`, `PId`, `Name`, `PermissionCode`, `Type`, `Icon`, `Route`, `Component`, `Order`, - `IsHidden`, `IsCached`, `Description`, `IsDeleted`, - `ConcurrencyStamp`, `CreateUserId`, `CreateTime`, `UpdateUserId`, `UpdateTime` -) VALUES ( - 'a1b2c3d4-e5f6-7890-abcd-ef1234567801', - @ROOT_PID, - '小红书', - '', - 1, - 'icon-fire', - '/xhs', - NULL, - 4, - 0, 0, 'LIKE AI 小红书自动化', 0, - UUID(), @ADMIN_USER_ID, NOW(), @ADMIN_USER_ID, NOW() -) ON DUPLICATE KEY UPDATE - `Name` = VALUES(`Name`), - `PId` = VALUES(`PId`), - `PermissionCode` = VALUES(`PermissionCode`), - `Route` = VALUES(`Route`), - `Component` = VALUES(`Component`), - `CreateUserId` = VALUES(`CreateUserId`), - `UpdateUserId` = VALUES(`UpdateUserId`); - -INSERT INTO `menu` ( - `Id`, `PId`, `Name`, `PermissionCode`, `Type`, `Icon`, `Route`, `Component`, `Order`, - `IsHidden`, `IsCached`, `Description`, `IsDeleted`, - `ConcurrencyStamp`, `CreateUserId`, `CreateTime`, `UpdateUserId`, `UpdateTime` -) VALUES -('a1b2c3d4-e5f6-7890-abcd-ef1234567802', 'a1b2c3d4-e5f6-7890-abcd-ef1234567801', '启动服务', 'Xhs.Agent.Query', 1, NULL, '/xhs/startService', 'views/xhs/startService/index', 1, 0, 1, NULL, 0, UUID(), @ADMIN_USER_ID, NOW(), @ADMIN_USER_ID, NOW()), -('a1b2c3d4-e5f6-7890-abcd-ef1234567803', 'a1b2c3d4-e5f6-7890-abcd-ef1234567801', '内容分析', 'Xhs.Analysis.Use', 1, NULL, '/xhs/analysis', 'views/xhs/analysis/index', 2, 0, 1, NULL, 0, UUID(), @ADMIN_USER_ID, NOW(), @ADMIN_USER_ID, NOW()), -('a1b2c3d4-e5f6-7890-abcd-ef1234567804', 'a1b2c3d4-e5f6-7890-abcd-ef1234567801', '爆款创作', 'Xhs.Creation.Use', 1, NULL, '/xhs/creation', 'views/xhs/creation/index', 3, 0, 1, NULL, 0, UUID(), @ADMIN_USER_ID, NOW(), @ADMIN_USER_ID, NOW()), -('a1b2c3d4-e5f6-7890-abcd-ef1234567805', 'a1b2c3d4-e5f6-7890-abcd-ef1234567801', '发布记录', 'Xhs.Publish.Query', 1, NULL, '/xhs/publishHistory', 'views/xhs/publishHistory/index', 4, 0, 1, NULL, 0, UUID(), @ADMIN_USER_ID, NOW(), @ADMIN_USER_ID, NOW()), -('a1b2c3d4-e5f6-7890-abcd-ef1234567806', 'a1b2c3d4-e5f6-7890-abcd-ef1234567801', '技能卡片', 'Xhs.Skills.Query', 1, NULL, '/xhs/skills', 'views/xhs/skills/index', 5, 0, 1, NULL, 0, UUID(), @ADMIN_USER_ID, NOW(), @ADMIN_USER_ID, NOW()), -('a1b2c3d4-e5f6-7890-abcd-ef1234567807', 'a1b2c3d4-e5f6-7890-abcd-ef1234567801', '拟人设置', 'Xhs.HumanSettings.Save', 1, NULL, '/xhs/humanSettings', 'views/xhs/humanSettings/index', 6, 0, 1, NULL, 0, UUID(), @ADMIN_USER_ID, NOW(), @ADMIN_USER_ID, NOW()) -ON DUPLICATE KEY UPDATE - `Name` = VALUES(`Name`), - `PId` = VALUES(`PId`), - `Route` = VALUES(`Route`), - `Component` = VALUES(`Component`), - `Order` = VALUES(`Order`), - `CreateUserId` = VALUES(`CreateUserId`), - `UpdateUserId` = VALUES(`UpdateUserId`); - --- AI 助手:挂在「系统管理」下(Route=/system);若不存在则挂根节点 -SET @SYSTEM_PID = ( - SELECT `Id` FROM `menu` - WHERE `Route` = '/system' AND `IsDeleted` = 0 - ORDER BY `Order` - LIMIT 1 -); -SET @AI_ASSISTANT_PID = IFNULL(@SYSTEM_PID, @ROOT_PID); - -INSERT INTO `menu` ( - `Id`, `PId`, `Name`, `PermissionCode`, `Type`, `Icon`, `Route`, `Component`, `Order`, - `IsHidden`, `IsCached`, `Description`, `IsDeleted`, - `ConcurrencyStamp`, `CreateUserId`, `CreateTime`, `UpdateUserId`, `UpdateTime` -) VALUES ( - 'a1b2c3d4-e5f6-7890-abcd-ef1234567808', - @AI_ASSISTANT_PID, - 'AI 助手', - 'Xhs.Ai.Use', - 1, - NULL, - '/system/xhsAiAssistant', - 'views/system/xhsAiAssistant/index', - 99, - 0, 1, '小红书 AI 助手(系统菜单)', 0, - UUID(), @ADMIN_USER_ID, NOW(), @ADMIN_USER_ID, NOW() -) ON DUPLICATE KEY UPDATE - `Name` = VALUES(`Name`), - `PId` = VALUES(`PId`), - `Route` = VALUES(`Route`), - `Component` = VALUES(`Component`), - `CreateUserId` = VALUES(`CreateUserId`), - `UpdateUserId` = VALUES(`UpdateUserId`); - --- 权限分配见 sql/seed_xhs_role_permissions.sql(或重启 API 由 XhsRolePermissionSeedContributor 自动合并) diff --git a/sql/seed_xhs_role_permissions.sql b/sql/seed_xhs_role_permissions.sql deleted file mode 100644 index 41fd0ce..0000000 --- a/sql/seed_xhs_role_permissions.sql +++ /dev/null @@ -1,61 +0,0 @@ --- 为客户 / Admin 角色批量追加小红书权限(幂等,可重复执行) --- RBAC 库执行 --- ⚠️ 本环境 role_permission.CreateUserId 为 CHAR(36) GUID,不可写整数 0(登录会报 Guid: 0) - -SET @ADMIN_USER_ID = ( - SELECT `Id` FROM `user` - WHERE `Account` = 'admin' AND (`IsDeleted` = 0 OR `IsDeleted` IS NULL) - LIMIT 1 -); -SET @ADMIN_USER_ID = IFNULL( - @ADMIN_USER_ID, - '00000000-0000-0000-0000-000000000001' -); - -INSERT INTO `role_permission` (`Id`, `RoleId`, `PermissionCode`, `CreateUserId`, `CreateTime`) -SELECT UUID(), r.`Id`, p.`Code`, @ADMIN_USER_ID, NOW() -FROM `role` r -CROSS JOIN ( - SELECT 'Xhs.Agent.Query' AS `Code` UNION ALL - SELECT 'Xhs.Agent.Control' UNION ALL - SELECT 'Xhs.Analysis.Use' UNION ALL - SELECT 'Xhs.Creation.Use' UNION ALL - SELECT 'Xhs.Publish.Query' UNION ALL - SELECT 'Xhs.Publish.Cancel' UNION ALL - SELECT 'Xhs.Skills.Query' UNION ALL - SELECT 'Xhs.Skills.Save' UNION ALL - SELECT 'Xhs.Skills.Run' UNION ALL - SELECT 'Xhs.HumanSettings.Save' UNION ALL - SELECT 'Xhs.Ai.Use' UNION ALL - SELECT 'Xhs.Ai.Save' -) p -WHERE r.`Code` = 'Customer' - AND NOT EXISTS ( - SELECT 1 FROM `role_permission` rp - WHERE rp.`RoleId` = r.`Id` AND rp.`PermissionCode` = p.`Code` - ); - -INSERT INTO `role_permission` (`Id`, `RoleId`, `PermissionCode`, `CreateUserId`, `CreateTime`) -SELECT UUID(), r.`Id`, p.`Code`, @ADMIN_USER_ID, NOW() -FROM `role` r -CROSS JOIN ( - SELECT 'Xhs.Agent.Query' AS `Code` UNION ALL - SELECT 'Xhs.Agent.Control' UNION ALL - SELECT 'Xhs.Analysis.Use' UNION ALL - SELECT 'Xhs.Creation.Use' UNION ALL - SELECT 'Xhs.Publish.Query' UNION ALL - SELECT 'Xhs.Publish.Cancel' UNION ALL - SELECT 'Xhs.Skills.Query' UNION ALL - SELECT 'Xhs.Skills.Save' UNION ALL - SELECT 'Xhs.Skills.Run' UNION ALL - SELECT 'Xhs.HumanSettings.Save' UNION ALL - SELECT 'Xhs.Ai.Use' UNION ALL - SELECT 'Xhs.Ai.Save' -) p -WHERE r.`Code` = 'Admin' - AND NOT EXISTS ( - SELECT 1 FROM `role_permission` rp - WHERE rp.`RoleId` = r.`Id` AND rp.`PermissionCode` = p.`Code` - ); - --- 若曾用 CreateUserId=0 插入过,执行 fix_rbac_bad_guids.sql 修复脏行 diff --git a/sql/seed_xhs_skills.sql b/sql/seed_xhs_skills.sql deleted file mode 100644 index 0d29d57..0000000 --- a/sql/seed_xhs_skills.sql +++ /dev/null @@ -1,47 +0,0 @@ --- 小红书系统预置技能卡片(CustomerId=0) --- 来源:LIKE AI .xhs_bridge/skills.json --- --- 若报 1146 Table doesn't exist:请先执行 migrate_t_xhs.sql(建全部 t_xhs_* 表) --- 或仅缺本表时,下方 CREATE TABLE 会自动创建 t_xhs_skill - -CREATE TABLE IF NOT EXISTS `t_xhs_skill` ( - `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', - `CustomerId` INT NOT NULL COMMENT '客户ID;0 表示系统预置', - `ExternalId` VARCHAR(32) NOT NULL COMMENT '对外稳定 ID', - `Title` VARCHAR(256) NOT NULL COMMENT '技能名称', - `SkillType` VARCHAR(32) NOT NULL DEFAULT 'ai_create' COMMENT '技能类型', - `PresetId` VARCHAR(64) NULL COMMENT '内置预设标识', - `RecipeJson` JSON NOT NULL COMMENT '配方 JSON', - `SortOrder` INT NOT NULL DEFAULT 0 COMMENT '排序', - `IsDeleted` TINYINT NOT NULL DEFAULT 0, - `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()), - `CreateUserId` INT NOT NULL DEFAULT 0, - `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `UpdateUserId` INT NULL, - `UpdateTime` DATETIME NULL, - PRIMARY KEY (`Id`), - UNIQUE KEY `uk_xhs_skill_external` (`CustomerId`, `ExternalId`), - KEY `idx_xhs_skill_customer` (`CustomerId`, `SortOrder`) -) COMMENT='小红书技能卡片表'; - -INSERT INTO `t_xhs_skill` ( - `CustomerId`, `ExternalId`, `Title`, `SkillType`, `PresetId`, `RecipeJson`, `SortOrder`, - `IsDeleted`, `CreateUserId`, `CreateTime` -) VALUES -(0, '5a9d3c012d50', '数字型/疑问型 · 物流知识 · 图文', 'ai_create', NULL, - '{"formula":["emotion","utility","visual","social"],"title_types":["number","question"],"body":{"domain":"物流知识","content_type":"干货教程","emotion":"生活场景","social":"知识炫耀"},"image_modes":["cover_impact"],"video_modes":[],"notes":"讲解9610的简易申报和汇总申报,退税,以及申报要求"}', - 1, 0, 0, NOW()), -(0, '7dd58bfe4770', '效率工具 · 干货教程(新号)', 'ai_create', 'efficiency_tutorial', - '{"formula":["emotion","utility","visual","social"],"title_types":["number","question"],"body":{"domain":"效率工具","content_type":"干货教程","emotion":"焦虑共鸣","social":"价值传递"},"image_modes":["cover_impact","step_cards"],"video_modes":[],"notes":"话题示例:笔记工具提升效率"}', - 2, 0, 0, NOW()), -(0, '3f6ed9f62afd', '职场发展 · 经验分享', 'ai_create', 'career_experience', - '{"formula":["emotion","utility","social"],"title_types":["story","compare"],"body":{"domain":"职场发展","content_type":"经验分享","emotion":"理想生活","social":"身份标签"},"image_modes":["cover_impact","lifestyle"],"video_modes":[],"notes":"话题示例:职场人际关系"}', - 3, 0, 0, NOW()), -(0, '61a4d4febada', '情感共鸣 · 真实场景', 'ai_create', 'emotional_relatable', - '{"formula":["emotion","social"],"title_types":["story","question"],"body":{"domain":"情感共鸣","content_type":"经验分享","emotion":"生活场景","social":"情感支持"},"image_modes":["lifestyle"],"video_modes":["vlog_clip"],"notes":"让读者觉得这也太真实了"}', - 4, 0, 0, NOW()), -(0, 'ec62cc03eea9', '避坑指南 · 观点表达', 'ai_create', 'pitfall_opinion', - '{"formula":["emotion","utility","visual","social"],"title_types":["number"],"body":{"domain":"职场发展","content_type":"避坑指南","emotion":"吐槽宣泄","social":"观点表达"},"image_modes":["info_chart"],"video_modes":["talking_head"],"notes":"话题示例:避坑指南"}', - 5, 0, 0, NOW()) -ON DUPLICATE KEY UPDATE `Title` = VALUES(`Title`), `RecipeJson` = VALUES(`RecipeJson`); - \ No newline at end of file diff --git a/sql/wechat_login.sql b/sql/wechat_login.sql deleted file mode 100644 index 6cc0067..0000000 --- a/sql/wechat_login.sql +++ /dev/null @@ -1,5 +0,0 @@ --- 微信登录:客户 openId 唯一索引(允许多个 NULL) --- 执行前请确认索引不存在 - -CREATE UNIQUE INDEX IF NOT EXISTS uk_customer_wechat_openid - ON t_customer (WechatOpenid); diff --git a/src/Oms.Application/Services/Plugin/PluginBrowserService.cs b/src/Oms.Application/Services/Plugin/PluginBrowserService.cs new file mode 100644 index 0000000..6b55a8e --- /dev/null +++ b/src/Oms.Application/Services/Plugin/PluginBrowserService.cs @@ -0,0 +1,125 @@ +using System.Text; +using Fake.Application; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Caching.Distributed; +using Oms.Application.Shared; +using Oms.Domain.CustomersAggregate.Repositories; +using Oms.Domain.SystemAggregate.Repositories; +using Oms.Domain.WarehouseAggregate.Repositories; + +namespace Oms.Application.Services.Plugin; + +/// +/// 浏览器采集插件草稿 / 查重(对齐哪哪发 wepost API)。 +/// +[ApiExplorerSettings(GroupName = "OMS-Plugin")] +public class PluginBrowserService : ApplicationService +{ + private static readonly TimeSpan DraftTtl = TimeSpan.FromSeconds(90); + + private ICustomerRepository CustomerRepository => LazyServiceProvider.GetRequiredService(); + private ICParcelRepository ParcelRepository => LazyServiceProvider.GetRequiredService(); + private IWarehouseAddressRepository WarehouseAddressRepository => + LazyServiceProvider.GetRequiredService(); + private IDistributedCache Cache => LazyServiceProvider.GetRequiredService(); + + /// + /// 缓存采集草稿,返回 key(确认页 getPackage 使用)。 + /// + [HttpPost("/plugin/browser/add")] + [Consumes("application/x-www-form-urlencoded", "multipart/form-data")] + public async Task AddDraftAsync([FromForm] string? item) + { + var customerId = await ResolveRequiredCustomerIdAsync(); + var payload = item; + if (string.IsNullOrWhiteSpace(payload)) + { + throw new BusinessException("草稿内容不能为空"); + } + + var key = $"{customerId}{DateTimeOffset.UtcNow.ToUnixTimeSeconds()}{Random.Shared.Next(100, 999)}"; + await Cache.SetAsync( + CacheKey(key), + Encoding.UTF8.GetBytes(payload!), + new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = DraftTtl }); + + return key; + } + + /// + /// 读取草稿 JSON 字符串。 + /// + [HttpGet("/plugin/browser/getPackage")] + public async Task GetDraftAsync([FromQuery] string key) + { + if (string.IsNullOrWhiteSpace(key)) + { + throw new BusinessException("key 不能为空"); + } + + var bytes = await Cache.GetAsync(CacheKey(key.Trim())); + if (bytes == null || bytes.Length == 0) + { + throw new BusinessException("包裹草稿不存在或已过期"); + } + + return Encoding.UTF8.GetString(bytes); + } + + /// + /// 查重:快递单号是否已存在于当前客户的「我的包裹」。 + /// + [HttpGet("/plugin/browser/selectPackage")] + public async Task SelectPackageAsync([FromQuery] string? expressNum, [FromQuery] string? orderNo) + { + var customerId = await ResolveRequiredCustomerIdAsync(); + var trackingNo = (expressNum ?? string.Empty).Trim(); + var trackExists = false; + if (!string.IsNullOrWhiteSpace(trackingNo)) + { + var hit = await ParcelRepository.FirstOrDefaultAsync(x => + x.CustomerId == customerId && x.TrackingNo == trackingNo); + trackExists = hit != null; + } + + // OMS 包裹表无独立订单号字段;orderNo 仅作兼容保留,默认同 track 不分别标记 + return new + { + trackNo = trackExists, + orderNo = false + }; + } + + /// + /// 插件确认页默认仓库(取第一个可用仓库)。 + /// + [HttpGet("/plugin/browser/getPluginWhseInfo")] + public async Task GetPluginWhseInfoAsync() + { + await ResolveRequiredCustomerIdAsync(); + var list = await WarehouseAddressRepository.GetPagedListAsync( + _ => true, + 1, + 20, + new Dictionary { [nameof(Oms.Domain.SystemAggregate.Entities.WarehouseAddress.Id)] = true }); + var wh = list.FirstOrDefault(); + if (wh == null) + { + return null; + } + + return new + { + id = wh.Id, + name = wh.WarehouseName + }; + } + + private async Task ResolveRequiredCustomerIdAsync() => + await WarehouseCustomerHelper.ResolveRequiredCustomerIdAsync( + CustomerRepository, + CurrentUser, + null); + + private static string CacheKey(string key) => $"oms:plugin:parcel:draft:{key}"; +} diff --git a/src/Oms.E2E.Tests/Oms.E2E.Tests.csproj b/src/Oms.E2E.Tests/Oms.E2E.Tests.csproj index 621c955..86de2fe 100644 --- a/src/Oms.E2E.Tests/Oms.E2E.Tests.csproj +++ b/src/Oms.E2E.Tests/Oms.E2E.Tests.csproj @@ -32,8 +32,4 @@ - - - - diff --git a/src/Oms.E2E.Tests/Support/E2eDatabase.cs b/src/Oms.E2E.Tests/Support/E2eDatabase.cs index c8a1c74..6411e2c 100644 --- a/src/Oms.E2E.Tests/Support/E2eDatabase.cs +++ b/src/Oms.E2E.Tests/Support/E2eDatabase.cs @@ -18,35 +18,12 @@ internal static class E2eDatabase } } - public static async Task ApplySeedScriptAsync(string connectionString, CancellationToken cancellationToken = default) + public static Task ApplySeedScriptAsync(string connectionString, CancellationToken cancellationToken = default) { - var seedPath = Path.Combine(AppContext.BaseDirectory, "sql", "seed_e2e_order_lifecycle.sql"); - if (!File.Exists(seedPath)) - { - throw new FileNotFoundException("E2E seed script not found.", seedPath); - } - - var script = await File.ReadAllTextAsync(seedPath, cancellationToken); - var builder = new MySqlConnectionStringBuilder(connectionString) - { - AllowUserVariables = true - }; - await using var conn = new MySqlConnection(builder.ConnectionString); - await conn.OpenAsync(cancellationToken); - - foreach (var statement in SplitSqlStatements(script)) - { - await using var cmd = new MySqlCommand(statement, conn); - await cmd.ExecuteNonQueryAsync(cancellationToken); - } - } - - private static IEnumerable SplitSqlStatements(string script) - { - return script - .Split(';', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries) - .Select(x => x.Trim()) - .Where(x => x.Length > 0 && !x.StartsWith("--", StringComparison.Ordinal)); + // 仓储库不再维护 E2E 种子脚本;依赖目标库既有测试数据。 + _ = connectionString; + _ = cancellationToken; + return Task.CompletedTask; } public static async Task GetOrderStatusByServiceNoAsync(