统一 OMS DDL 到 db.sql,并新增采集插件草稿 API。
清理 sql/ 增量与种子脚本;E2E 不再依赖种子;PluginBrowserService 对接哪哪发「我的包裹」采集。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
7e90112cbf
commit
600ab37594
644
db.sql
644
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;
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
7
sql/README.md
Normal file
7
sql/README.md
Normal file
@ -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` 末尾对应段落
|
||||
@ -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-%';
|
||||
@ -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';
|
||||
@ -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');
|
||||
@ -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}$');
|
||||
@ -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}$');
|
||||
@ -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;
|
||||
@ -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 确认无脏行
|
||||
@ -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}$');
|
||||
@ -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`;
|
||||
@ -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`);
|
||||
@ -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`);
|
||||
@ -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`;
|
||||
@ -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;
|
||||
@ -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`);
|
||||
@ -1,18 +0,0 @@
|
||||
-- t_auto_trigger 规则名与优先级(可重复执行)
|
||||
-- 在 OMS 业务库执行:mysql -h<host> -u<user> -p<db> < 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;
|
||||
@ -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='客户账户资金流水';
|
||||
@ -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` = '';
|
||||
@ -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='渠道-问题模板';
|
||||
@ -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` = '';
|
||||
@ -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 '更新时间';
|
||||
@ -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`;
|
||||
@ -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` = '';
|
||||
@ -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`;
|
||||
@ -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='订单异常事件表';
|
||||
@ -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`;
|
||||
@ -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');
|
||||
@ -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;
|
||||
@ -1,44 +0,0 @@
|
||||
-- t_order / t_order_fee 小包预报计费字段补齐(可重复执行)
|
||||
-- 在 OMS 业务库执行,例如:mysql -h<host> -u<user> -p<db> < 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;
|
||||
@ -1,11 +0,0 @@
|
||||
-- t_order 预报失败原因(可重复执行)
|
||||
-- 在 OMS 业务库执行:mysql -h<host> -u<user> -p<db> < 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;
|
||||
@ -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` = '');
|
||||
@ -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`);
|
||||
@ -1,4 +0,0 @@
|
||||
-- 销售产品表增加对客说明 Markdown 字段
|
||||
|
||||
ALTER TABLE `t_sales_product`
|
||||
ADD COLUMN `CustomerGuideMarkdown` MEDIUMTEXT NULL COMMENT '对客说明 Markdown' AFTER `PreStorageScript`;
|
||||
@ -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='批量发送邮件记录';
|
||||
@ -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='系统其他配置表';
|
||||
@ -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`;
|
||||
@ -1,6 +0,0 @@
|
||||
-- 仓库地址表移除客服电话、客服微信及二维码字段
|
||||
|
||||
ALTER TABLE `t_warehouse_address`
|
||||
DROP COLUMN `ServicePhone`,
|
||||
DROP COLUMN `ServiceWechat`,
|
||||
DROP COLUMN `ServiceWechatFiles`;
|
||||
@ -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='小红书创作上传媒体表';
|
||||
@ -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='销售店铺订单明细';
|
||||
@ -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` = '';
|
||||
@ -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
|
||||
);
|
||||
@ -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;
|
||||
@ -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`
|
||||
);
|
||||
@ -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;
|
||||
@ -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;
|
||||
@ -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.%';
|
||||
@ -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
|
||||
);
|
||||
@ -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`
|
||||
);
|
||||
@ -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`);
|
||||
@ -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 自动合并)
|
||||
@ -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 修复脏行
|
||||
@ -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`);
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
-- 微信登录:客户 openId 唯一索引(允许多个 NULL)
|
||||
-- 执行前请确认索引不存在
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_customer_wechat_openid
|
||||
ON t_customer (WechatOpenid);
|
||||
125
src/Oms.Application/Services/Plugin/PluginBrowserService.cs
Normal file
125
src/Oms.Application/Services/Plugin/PluginBrowserService.cs
Normal file
@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 浏览器采集插件草稿 / 查重(对齐哪哪发 wepost API)。
|
||||
/// </summary>
|
||||
[ApiExplorerSettings(GroupName = "OMS-Plugin")]
|
||||
public class PluginBrowserService : ApplicationService
|
||||
{
|
||||
private static readonly TimeSpan DraftTtl = TimeSpan.FromSeconds(90);
|
||||
|
||||
private ICustomerRepository CustomerRepository => LazyServiceProvider.GetRequiredService<ICustomerRepository>();
|
||||
private ICParcelRepository ParcelRepository => LazyServiceProvider.GetRequiredService<ICParcelRepository>();
|
||||
private IWarehouseAddressRepository WarehouseAddressRepository =>
|
||||
LazyServiceProvider.GetRequiredService<IWarehouseAddressRepository>();
|
||||
private IDistributedCache Cache => LazyServiceProvider.GetRequiredService<IDistributedCache>();
|
||||
|
||||
/// <summary>
|
||||
/// 缓存采集草稿,返回 key(确认页 getPackage 使用)。
|
||||
/// </summary>
|
||||
[HttpPost("/plugin/browser/add")]
|
||||
[Consumes("application/x-www-form-urlencoded", "multipart/form-data")]
|
||||
public async Task<object> 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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取草稿 JSON 字符串。
|
||||
/// </summary>
|
||||
[HttpGet("/plugin/browser/getPackage")]
|
||||
public async Task<object> 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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查重:快递单号是否已存在于当前客户的「我的包裹」。
|
||||
/// </summary>
|
||||
[HttpGet("/plugin/browser/selectPackage")]
|
||||
public async Task<object> 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
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 插件确认页默认仓库(取第一个可用仓库)。
|
||||
/// </summary>
|
||||
[HttpGet("/plugin/browser/getPluginWhseInfo")]
|
||||
public async Task<object?> GetPluginWhseInfoAsync()
|
||||
{
|
||||
await ResolveRequiredCustomerIdAsync();
|
||||
var list = await WarehouseAddressRepository.GetPagedListAsync(
|
||||
_ => true,
|
||||
1,
|
||||
20,
|
||||
new Dictionary<string, bool> { [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<int> ResolveRequiredCustomerIdAsync() =>
|
||||
await WarehouseCustomerHelper.ResolveRequiredCustomerIdAsync(
|
||||
CustomerRepository,
|
||||
CurrentUser,
|
||||
null);
|
||||
|
||||
private static string CacheKey(string key) => $"oms:plugin:parcel:draft:{key}";
|
||||
}
|
||||
@ -32,8 +32,4 @@
|
||||
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\..\sql\seed_e2e_order_lifecycle.sql" Link="sql\seed_e2e_order_lifecycle.sql" CopyToOutputDirectory="PreserveNewest" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@ -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<string> 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<string?> GetOrderStatusByServiceNoAsync(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user