From 5a2d56986ae9a3d7e0a9848f606df07e04e40417 Mon Sep 17 00:00:00 2001 From: zzh <1368735060@qq.com> Date: Tue, 21 Jul 2026 18:49:59 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=AD=97=E5=85=B8=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=81=A2=E5=A4=8D=E8=BD=AF=E5=88=A0=E9=A1=B9?= =?UTF-8?q?=E5=B9=B6=E5=AE=8C=E5=96=84=E7=B1=BB=E5=9E=8B=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 批量导入时若同类型编码曾被软删,改为恢复并更新而非插入,避免唯一键冲突 500;迁移脚本补全预置类型中文名并支持覆盖 Remark/TypeSort。 --- sql/migrate_t_dict_type.sql | 77 +++++++++++++++++-- .../Services/System/DictService.cs | 24 ++++-- .../Repositories/IDictRepository.cs | 2 + src/Oms.SqlSugarCore/System/DictRepository.cs | 11 +++ 4 files changed, 104 insertions(+), 10 deletions(-) diff --git a/sql/migrate_t_dict_type.sql b/sql/migrate_t_dict_type.sql index c3b2e3e..f0d306b 100644 --- a/sql/migrate_t_dict_type.sql +++ b/sql/migrate_t_dict_type.sql @@ -1,11 +1,12 @@ --- 已有库增量:字典类型元数据 t_dict_type(类型编码 + 备注) --- 可重复执行(IF NOT EXISTS) +-- 已有库增量:字典类型元数据 t_dict_type(类型编码 + 备注 + 排序) +-- 对应功能:系统 → 数据字典,左侧类型列表与类型备注 +-- 可重复执行(IF NOT EXISTS / INSERT IGNORE;预置名称直接覆盖 Remark、TypeSort) CREATE TABLE IF NOT EXISTS `t_dict_type` ( `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键,自增,步长 1', - `DictType` VARCHAR(64) NOT NULL COMMENT '字典类型编码', + `DictType` VARCHAR(64) NOT NULL COMMENT '字典类型编码,与 t_dict.DictType 对应', `Remark` VARCHAR(512) NULL COMMENT '字典类型备注', - `TypeSort` INT NOT NULL DEFAULT 0 COMMENT '左侧菜单排序', + `TypeSort` 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 '创建人', @@ -16,8 +17,74 @@ CREATE TABLE IF NOT EXISTS `t_dict_type` ( UNIQUE KEY `uk_dict_type_code` (`DictType`) ) COMMENT='字典类型元数据表'; --- 从现有字典项回填类型元数据(无备注) +-- 从已有字典项回填类型(无备注) INSERT IGNORE INTO `t_dict_type` (`DictType`, `Remark`, `TypeSort`, `CreateUserId`) SELECT DISTINCT `DictType`, NULL, 0, 0 FROM `t_dict` WHERE `IsDeleted` = 0 AND TRIM(`DictType`) <> ''; + +-- 预置 OMS 字典类型中文名称(与前端 dict-batch-import.ts OMS_DICT_TYPE_REMARKS 对齐) +-- 已存在记录时直接覆盖 Remark、TypeSort +INSERT INTO `t_dict_type` (`DictType`, `TypeSort`, `Remark`, `CreateUserId`) +VALUES + ('area_type', 1, '分区类型', 0), + ('auto_trigger_operation', 2, '自动触发操作', 0), + ('auto_trigger_timing', 3, '自动触发时机', 0), + ('billable_weight', 4, '计重取值', 0), + ('calculation_formula', 5, '计算公式', 0), + ('cargo_attribute', 6, '货物属性', 0), + ('claim_type', 7, '理赔类型', 0), + ('cost_unit', 8, '计费单位', 0), + ('currency', 9, '币种', 0), + ('customer_account_flow_biz_type', 10, '账户流水业务类型', 0), + ('customer_address_type', 11, '客户地址类型', 0), + ('customer_group', 12, '客户组', 0), + ('customer_status', 13, '客户状态', 0), + ('customer_waybill', 14, '客户面单', 0), + ('data_scope', 15, '数据范围', 0), + ('enable_status', 16, '启用状态', 0), + ('es_snapshot_status', 17, '快照生效状态', 0), + ('export_customs_mode', 18, '出口报关方式', 0), + ('fee_item', 19, '费用项', 0), + ('forecast_type', 20, '预报类型', 0), + ('issue_notify_method', 21, '问题通知方式', 0), + ('issue_type', 22, '问题件类型', 0), + ('label_generate_status', 23, '面单生成状态', 0), + ('label_template_type', 24, '面单模板类型', 0), + ('notice_type', 25, '通知类型', 0), + ('number_type', 26, '打印号码类型', 0), + ('operator_type', 27, '发布操作类型', 0), + ('order_batch_job_item_status', 28, '批量任务明细状态', 0), + ('order_batch_job_status', 29, '批量任务状态', 0), + ('order_fee_charging_stage', 30, '费用计费阶段', 0), + ('order_fee_type', 31, '费用类型', 0), + ('order_handle_status', 32, '订单处理子状态', 0), + ('order_source', 33, '订单来源', 0), + ('order_status', 34, '订单状态', 0), + ('order_stock_bind_status', 35, '库存绑定状态', 0), + ('order_stock_bind_type', 36, '库存绑定类型', 0), + ('order_task_status', 37, '订单导入任务状态', 0), + ('order_template_mapping_status', 38, '模板映射状态', 0), + ('order_template_type', 39, '订单模板类型', 0), + ('order_weight_type', 40, '件重尺类型', 0), + ('org_scope', 41, '组织范围', 0), + ('pay_type', 42, '支付方式', 0), + ('pricing_factor', 43, '定价因素', 0), + ('principal_type', 44, '主体类型', 0), + ('publish_record_type', 45, '发布记录类型', 0), + ('receiver_type', 46, '接收方类型', 0), + ('recharge_status', 47, '充值审核状态', 0), + ('sales_product_group', 48, '卖价分组', 0), + ('sales_store_auth_status', 49, '店铺授权状态', 0), + ('sales_store_fulfill_status', 50, '平台店铺履约状态', 0), + ('scheme', 51, '排货方案', 0), + ('secret_level', 52, '密级', 0), + ('warehouse_inbound_type', 53, '入库类型', 0), + ('warehouse_parcel_lifecycle', 54, '包裹生命周期', 0), + ('warehouse_receipt_status', 55, '收货状态', 0), + ('warehouse_type', 56, '仓库类型', 0), + ('weight_rule_condition', 57, '计重条件', 0), + ('yes_no', 58, '通用是否', 0) +ON DUPLICATE KEY UPDATE + `TypeSort` = VALUES(`TypeSort`), + `Remark` = VALUES(`Remark`); diff --git a/src/Oms.Application/Services/System/DictService.cs b/src/Oms.Application/Services/System/DictService.cs index a8f824f..88a23af 100644 --- a/src/Oms.Application/Services/System/DictService.cs +++ b/src/Oms.Application/Services/System/DictService.cs @@ -184,14 +184,28 @@ public class DictService : ApplicationService [HttpPost("/system/dict/create")] public async Task CreateAsync(DictCreateInput input) { - await ValidateDictInputAsync(input.DictType, input.DictCode, input.DictName, null); - await EnsureDictTypeMetaAsync(input.DictType.Trim()); + var dictType = input.DictType.Trim(); + var dictCode = input.DictCode.Trim(); + var dictName = input.DictName.Trim(); + await ValidateDictInputAsync(dictType, dictCode, dictName, null); + await EnsureDictTypeMetaAsync(dictType); + + var deleted = await DictRepository.GetByTypeAndCodeIncludingDeletedAsync(dictType, dictCode); + if (deleted != null && deleted.IsDeleted) + { + deleted.IsDeleted = false; + deleted.DictSort = input.DictSort; + deleted.DictName = dictName; + await DictRepository.UpdateAsync(deleted); + return; + } + await DictRepository.InsertAsync(new Dict { - DictType = input.DictType.Trim(), + DictType = dictType, DictSort = input.DictSort, - DictCode = input.DictCode.Trim(), - DictName = input.DictName.Trim() + DictCode = dictCode, + DictName = dictName }); } diff --git a/src/Oms.Domain/SystemAggregate/Repositories/IDictRepository.cs b/src/Oms.Domain/SystemAggregate/Repositories/IDictRepository.cs index 4f9a6fa..d05a6aa 100644 --- a/src/Oms.Domain/SystemAggregate/Repositories/IDictRepository.cs +++ b/src/Oms.Domain/SystemAggregate/Repositories/IDictRepository.cs @@ -7,5 +7,7 @@ public interface IDictRepository : IRepository { Task GetByTypeAndCodeAsync(string dictType, string dictCode, CancellationToken cancellationToken = default); + Task GetByTypeAndCodeIncludingDeletedAsync(string dictType, string dictCode, CancellationToken cancellationToken = default); + Task> GetItemCountByTypeAsync(CancellationToken cancellationToken = default); } diff --git a/src/Oms.SqlSugarCore/System/DictRepository.cs b/src/Oms.SqlSugarCore/System/DictRepository.cs index 8b0e4ba..caba94a 100644 --- a/src/Oms.SqlSugarCore/System/DictRepository.cs +++ b/src/Oms.SqlSugarCore/System/DictRepository.cs @@ -13,6 +13,17 @@ public class DictRepository : OmsSqlSugarRepository, IDictRepository, ISco return FirstOrDefaultAsync(x => x.DictType == dictType && x.DictCode == dictCode, cancellationToken); } + public async Task GetByTypeAndCodeIncludingDeletedAsync( + string dictType, + string dictCode, + CancellationToken cancellationToken = default) + { + var db = await GetDbContextAsync(cancellationToken); + return await db.Queryable() + .ClearFilter() + .FirstAsync(x => x.DictType == dictType && x.DictCode == dictCode, cancellationToken); + } + public async Task> GetItemCountByTypeAsync(CancellationToken cancellationToken = default) { var db = await GetDbContextAsync(cancellationToken);