diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslDesktopAnonController.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslDesktopAnonController.java index d97484e..fa458a8 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslDesktopAnonController.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslDesktopAnonController.java @@ -43,6 +43,7 @@ import org.jeecg.modules.xslmes.service.MesXslStompNotifyService; import org.jeecg.modules.xslmes.vo.MesXslRawMaterialCardBriefVO; import org.springframework.web.bind.annotation.*; +import java.math.BigDecimal; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -405,12 +406,7 @@ public class MesXslDesktopAnonController { if (oConvertUtils.isEmpty(mesXslWeightRecord.getPlateNumber())) { return Result.error("车牌号不能为空"); } - // 净重自动计算 - if (mesXslWeightRecord.getGrossWeight() != null && mesXslWeightRecord.getTareWeight() != null) { - mesXslWeightRecord.setNetWeight( - mesXslWeightRecord.getGrossWeight().subtract(mesXslWeightRecord.getTareWeight())); - } - applyWeightBillType(mesXslWeightRecord); + applyWeightNetAndBillType(mesXslWeightRecord); applyMaterialTypeDefault(mesXslWeightRecord); weightRecordService.save(mesXslWeightRecord); stompNotify.publishWeightRecordChanged("add", mesXslWeightRecord.getId()); @@ -423,12 +419,7 @@ public class MesXslDesktopAnonController { if (oConvertUtils.isEmpty(mesXslWeightRecord.getId())) { return Result.error("主键不能为空"); } - // 净重自动计算 - if (mesXslWeightRecord.getGrossWeight() != null && mesXslWeightRecord.getTareWeight() != null) { - mesXslWeightRecord.setNetWeight( - mesXslWeightRecord.getGrossWeight().subtract(mesXslWeightRecord.getTareWeight())); - } - applyWeightBillType(mesXslWeightRecord); + applyWeightNetAndBillType(mesXslWeightRecord); applyMaterialTypeDefault(mesXslWeightRecord); boolean ok = weightRecordService.updateById(mesXslWeightRecord); if (!ok) { @@ -839,18 +830,47 @@ public class MesXslDesktopAnonController { // ─────────────────────────── 车辆私有辅助 ──────────────────────────── + private void applyWeightNetAndBillType(MesXslWeightRecord record) { + sanitizeNonPositiveWeightsToNull(record); + if (isEffectiveWeight(record.getGrossWeight()) && isEffectiveWeight(record.getTareWeight())) { + BigDecimal net = record.getGrossWeight().subtract(record.getTareWeight()); + record.setNetWeight(net.compareTo(BigDecimal.ZERO) >= 0 ? net : BigDecimal.ZERO); + } else { + record.setNetWeight(null); + } + applyWeightBillType(record); + } + + /** 将 ≤0 的重量视为未录入,避免 JSON/Numeric 占位 0 被当成已称皮重、误判称重完成 */ + private static void sanitizeNonPositiveWeightsToNull(MesXslWeightRecord record) { + if (record.getGrossWeight() != null && record.getGrossWeight().compareTo(BigDecimal.ZERO) <= 0) { + record.setGrossWeight(null); + } + if (record.getTareWeight() != null && record.getTareWeight().compareTo(BigDecimal.ZERO) <= 0) { + record.setTareWeight(null); + } + } + + private static boolean isEffectiveWeight(BigDecimal w) { + return w != null && w.compareTo(BigDecimal.ZERO) > 0; + } + private void applyWeightBillType(MesXslWeightRecord record) { - if (record.getGrossWeight() != null && record.getTareWeight() != null) { + boolean g = isEffectiveWeight(record.getGrossWeight()); + boolean t = isEffectiveWeight(record.getTareWeight()); + if (g && t) { record.setBillType("2"); return; } - if (record.getGrossWeight() != null) { + if (g) { record.setBillType("1"); return; } - if (record.getTareWeight() != null) { + if (t) { record.setBillType("3"); + return; } + record.setBillType(null); } private void applyMaterialTypeDefault(MesXslWeightRecord record) { diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslWeightRecordController.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslWeightRecordController.java index 9e112f0..08cfd8d 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslWeightRecordController.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslWeightRecordController.java @@ -72,9 +72,9 @@ public class MesXslWeightRecordController extends JeecgController edit(@RequestBody MesXslWeightRecord mesXslWeightRecord) { - computeBillType(mesXslWeightRecord); applyMaterialTypeDefault(mesXslWeightRecord); computeNetWeight(mesXslWeightRecord); + computeBillType(mesXslWeightRecord); mesXslWeightRecordService.updateById(mesXslWeightRecord); stompNotifyService.publishWeightRecordChanged("edit", mesXslWeightRecord.getId()); return Result.OK("编辑成功!"); @@ -137,26 +137,47 @@ public class MesXslWeightRecordController extends JeecgController= 0 ? net : BigDecimal.ZERO); + } else { + record.setNetWeight(null); } } private void computeBillType(MesXslWeightRecord record) { - if (record.getGrossWeight() != null && record.getTareWeight() != null) { + boolean g = isEffectiveWeight(record.getGrossWeight()); + boolean t = isEffectiveWeight(record.getTareWeight()); + if (g && t) { record.setBillType("2"); return; } - if (record.getGrossWeight() != null) { + if (g) { record.setBillType("1"); return; } - if (record.getTareWeight() != null) { + if (t) { record.setBillType("3"); + return; } + record.setBillType(null); + } + + /** 将 ≤0 的重量视为未录入,避免占位 0 误判称重完成 */ + private static void sanitizeNonPositiveWeightsToNull(MesXslWeightRecord record) { + if (record.getGrossWeight() != null && record.getGrossWeight().compareTo(BigDecimal.ZERO) <= 0) { + record.setGrossWeight(null); + } + if (record.getTareWeight() != null && record.getTareWeight().compareTo(BigDecimal.ZERO) <= 0) { + record.setTareWeight(null); + } + } + + private static boolean isEffectiveWeight(BigDecimal w) { + return w != null && w.compareTo(BigDecimal.ZERO) > 0; } private void applyMaterialTypeDefault(MesXslWeightRecord record) { diff --git a/yy-admin-master/YY.Admin.Core/Core/Services/IWarehouseService.cs b/yy-admin-master/YY.Admin.Core/Core/Services/IWarehouseService.cs index a0da84f..d54ba1a 100644 --- a/yy-admin-master/YY.Admin.Core/Core/Services/IWarehouseService.cs +++ b/yy-admin-master/YY.Admin.Core/Core/Services/IWarehouseService.cs @@ -4,6 +4,6 @@ namespace YY.Admin.Core.Services; public interface IWarehouseService { - /// 获取全部仓库列表(在线时拉取远端并刷新缓存,离线时返回本地缓存) + /// 获取全部仓库列表(优先内存/磁盘缓存;仅缓存为空且在线时拉取远端) Task> GetAllAsync(CancellationToken ct = default); } diff --git a/yy-admin-master/YY.Admin.Core/Entity/SysMenu.cs b/yy-admin-master/YY.Admin.Core/Entity/SysMenu.cs index 7abb9af..e275fa0 100644 --- a/yy-admin-master/YY.Admin.Core/Entity/SysMenu.cs +++ b/yy-admin-master/YY.Admin.Core/Entity/SysMenu.cs @@ -103,6 +103,12 @@ public partial class SysMenu : EntityBase [SugarColumn(ColumnDescription = "是否固定")] public bool IsAffix { get; set; } + /// + /// 桌面端登录后默认打开的首页(全库仅一项建议为 true,保存时由服务层互斥) + /// + [SugarColumn(ColumnDescription = "桌面端默认首页")] + public bool IsDefaultDesktopHome { get; set; } + /// /// 排序 /// diff --git a/yy-admin-master/YY.Admin.Core/SeedData/SysMenuSeedData.cs b/yy-admin-master/YY.Admin.Core/SeedData/SysMenuSeedData.cs index 9623ab4..e50cc67 100644 --- a/yy-admin-master/YY.Admin.Core/SeedData/SysMenuSeedData.cs +++ b/yy-admin-master/YY.Admin.Core/SeedData/SysMenuSeedData.cs @@ -16,7 +16,7 @@ public class SysMenuSeedData : ISqlSugarEntitySeedData return new[] { new SysMenu{ Id=1300100000101, Pid=0, Title="工作台", Path="", Name="dashboard", Component="Layout", Icon="", Type=MenuTypeEnum.Dir, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=0 }, - new SysMenu{ Id=1300100010101, Pid=1300100000101, Title="仪表盘", Path="DashboardView", Name="home", Component="/home/index", IsAffix=true, Icon="", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 }, + new SysMenu{ Id=1300100010101, Pid=1300100000101, Title="仪表盘", Path="DashboardView", Name="home", Component="/home/index", IsAffix=true, IsDefaultDesktopHome=true, Icon="", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 }, new SysMenu{ Id=1300100010201, Pid=1300100000101, Title="站内信", Path="/dashboard/notice", Name="notice", Component="/home/notice/index", Icon="", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=101 }, // 建议此处Id范围之间放置具体业务应用菜单 diff --git a/yy-admin-master/YY.Admin.Core/SqlSugar/SqlSugarSetup.cs b/yy-admin-master/YY.Admin.Core/SqlSugar/SqlSugarSetup.cs index 5a9df0c..29111e9 100644 --- a/yy-admin-master/YY.Admin.Core/SqlSugar/SqlSugarSetup.cs +++ b/yy-admin-master/YY.Admin.Core/SqlSugar/SqlSugarSetup.cs @@ -251,6 +251,8 @@ namespace YY.Admin.Core.SqlSugar // 兼容旧库:曾关闭表初始化或升级前库无 Jeecg 盐列时补齐,避免脱网按 Jeecg 规则验密时读列失败 EnsureSysUserJeecgPasswordSaltColumn(dbProvider, config); + // 兼容旧库:菜单表增加「桌面默认首页」标记列 + EnsureSysMenuDefaultDesktopHomeColumn(dbProvider, config); // 兜底:确保 Jeecg 用户同构表存在(登录页“同步 Jeecg 用户”写入此表) EnsureJeecgSysUserMirrorTable(dbProvider, config); // 兜底:确保 Jeecg 数据字典同构表存在(数据字典页面“同步数据字典”写入此表) @@ -352,8 +354,57 @@ namespace YY.Admin.Core.SqlSugar } /// - /// 若 sys_user 缺少 jeecg_password_salt,则执行 ALTER 补列(与实体 SysUser.JeecgPasswordSalt 一致) + /// 若 sys_menu 缺少桌面默认首页标记列,则 ALTER 补齐(与实体 SysMenu.IsDefaultDesktopHome 一致) /// + private static void EnsureSysMenuDefaultDesktopHomeColumn(SqlSugarScopeProvider dbProvider, DbConnectionConfig config) + { + try + { + var entityInfo = dbProvider.EntityMaintenance.GetEntityInfo(typeof(SysMenu)); + var tableName = entityInfo.DbTableName; + if (!dbProvider.DbMaintenance.IsAnyTable(tableName, false)) + { + return; + } + + var col = entityInfo.Columns.FirstOrDefault(c => c.PropertyName == nameof(SysMenu.IsDefaultDesktopHome)); + if (col == null) + { + return; + } + + var columns = dbProvider.DbMaintenance.GetColumnInfosByTableName(tableName, false); + if (columns != null && + columns.Any(c => string.Equals(c.DbColumnName, col.DbColumnName, StringComparison.OrdinalIgnoreCase))) + { + return; + } + + var cName = col.DbColumnName; + var sql = config.DbType switch + { + DbType.Sqlite => $"ALTER TABLE {tableName} ADD COLUMN {cName} INTEGER NOT NULL DEFAULT 0;", + DbType.MySql => $"ALTER TABLE `{tableName}` ADD COLUMN `{cName}` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '桌面端默认首页';", + DbType.PostgreSQL => $"ALTER TABLE \"{tableName}\" ADD COLUMN IF NOT EXISTS {cName} BOOLEAN NOT NULL DEFAULT FALSE;", + DbType.SqlServer => $"ALTER TABLE [{tableName}] ADD [{cName}] BIT NOT NULL DEFAULT 0;", + DbType.Kdbndp => $"ALTER TABLE \"{tableName}\" ADD COLUMN IF NOT EXISTS {cName} BOOLEAN NOT NULL DEFAULT FALSE;", + DbType.Dm => $"ALTER TABLE {tableName} ADD {cName} NUMBER(1) DEFAULT 0 NOT NULL;", + _ => (string?)null + }; + + if (string.IsNullOrEmpty(sql)) + { + return; + } + + Retry(() => dbProvider.Ado.ExecuteCommand(sql), maxRetry: 3, retryIntervalMs: 1000); + } + catch + { + // 无权限、从库只读等场景不阻断启动 + } + } + private static void EnsureSysUserJeecgPasswordSaltColumn(SqlSugarScopeProvider dbProvider, DbConnectionConfig config) { try diff --git a/yy-admin-master/YY.Admin.Services/Service/Menu/Dto/MenuOutput.cs b/yy-admin-master/YY.Admin.Services/Service/Menu/Dto/MenuOutput.cs index 5ea53f0..7c5272a 100644 --- a/yy-admin-master/YY.Admin.Services/Service/Menu/Dto/MenuOutput.cs +++ b/yy-admin-master/YY.Admin.Services/Service/Menu/Dto/MenuOutput.cs @@ -121,6 +121,11 @@ namespace YY.Admin.Services /// 是否固定 /// public bool IsAffix { get; set; } + + /// + /// 桌面端登录后作为默认首页打开的菜单 + /// + public bool IsDefaultDesktopHome { get; set; } #endregion /// /// 菜单子项 diff --git a/yy-admin-master/YY.Admin.Services/Service/Menu/SysMenuService.cs b/yy-admin-master/YY.Admin.Services/Service/Menu/SysMenuService.cs index eb840f9..ee7297c 100644 --- a/yy-admin-master/YY.Admin.Services/Service/Menu/SysMenuService.cs +++ b/yy-admin-master/YY.Admin.Services/Service/Menu/SysMenuService.cs @@ -157,6 +157,9 @@ namespace YY.Admin.Services.Service.Menu if (n <= 0) return (false, "保存失败", 0); + if (input.IsDefaultDesktopHome) + await ClearDefaultDesktopHomeExceptAsync(input.Id); + await TryLinkCurrentTenantMenuAsync(id); return (true, "保存成功", id); } @@ -180,6 +183,9 @@ namespace YY.Admin.Services.Service.Menu if (NewParentIsInsideMenuSubtree(input.Id, input.Pid, all)) return (false, "不能将父级设为当前菜单或其子菜单"); + if (input.IsDefaultDesktopHome) + await ClearDefaultDesktopHomeExceptAsync(input.Id); + existing.Pid = input.Pid; existing.Type = input.Type; existing.Name = input.Name; @@ -194,13 +200,17 @@ namespace YY.Admin.Services.Service.Menu existing.IsHide = input.IsHide; existing.IsKeepAlive = input.IsKeepAlive; existing.IsAffix = input.IsAffix; + existing.IsDefaultDesktopHome = input.IsDefaultDesktopHome; existing.OrderNo = input.OrderNo; existing.Status = input.Status; existing.Remark = input.Remark; existing.UpdateTime = DateTime.Now; var n = await _dbContext.Updateable(existing).ExecuteCommandAsync(); - return n > 0 ? (true, "保存成功") : (false, "更新失败"); + if (n <= 0) + return (false, "更新失败"); + await TryLinkCurrentTenantMenuAsync(input.Id); + return (true, "保存成功"); } /// @@ -219,6 +229,17 @@ namespace YY.Admin.Services.Service.Menu return n > 0 ? (true, "已删除") : (false, "删除失败"); } + /// + /// 保证全表仅一条菜单为桌面默认首页(当前保留项除外全部置 false) + /// + private async Task ClearDefaultDesktopHomeExceptAsync(long keepMenuId) + { + await _dbContext.Updateable() + .SetColumns(m => new SysMenu { IsDefaultDesktopHome = false }) + .Where(m => m.Id != keepMenuId && m.IsDefaultDesktopHome) + .ExecuteCommandAsync(); + } + private async Task TryLinkCurrentTenantMenuAsync(long menuId) { var tenantId = AppSession.CurrentUser?.TenantId; diff --git a/yy-admin-master/YY.Admin.Services/Service/Warehouse/WarehouseService.cs b/yy-admin-master/YY.Admin.Services/Service/Warehouse/WarehouseService.cs index 2f370fd..d4da0fb 100644 --- a/yy-admin-master/YY.Admin.Services/Service/Warehouse/WarehouseService.cs +++ b/yy-admin-master/YY.Admin.Services/Service/Warehouse/WarehouseService.cs @@ -10,8 +10,7 @@ using YY.Admin.Core.Services; namespace YY.Admin.Services.Service.Warehouse; /// -/// 仓库数据只读服务:启动时从后端拉取全量列表并缓存到磁盘,断网时回退本地缓存。 -/// 仅供其他模块的下拉筛选使用,不提供 CRUD。 +/// 仓库数据只读服务:启动与重连时后台刷新远端写入缓存;GetAllAsync 优先读缓存,避免库区等业务每次打开都全量拉仓库。 /// public class WarehouseService : IWarehouseService, ISingletonDependency { @@ -20,6 +19,7 @@ public class WarehouseService : IWarehouseService, ISingletonDependency private readonly INetworkMonitor _networkMonitor; private readonly ILoggerService _logger; private readonly object _cacheLock = new(); + private readonly SemaphoreSlim _emptyLoadGate = new(1, 1); private readonly string _cacheFilePath; private List _localCache = new(); @@ -64,19 +64,44 @@ public class WarehouseService : IWarehouseService, ISingletonDependency public async Task> GetAllAsync(CancellationToken ct = default) { - if (_networkMonitor.IsOnline) + lock (_cacheLock) { + if (_localCache.Count > 0 || !_networkMonitor.IsOnline) + return _localCache.ToList(); + } + + // 缓存为空且在线:仅此时阻塞拉远端(首次安装或清缓存后) + await _emptyLoadGate.WaitAsync(ct).ConfigureAwait(false); + try + { + lock (_cacheLock) + { + if (_localCache.Count > 0) + return _localCache.ToList(); + } + + if (!_networkMonitor.IsOnline) + { + lock (_cacheLock) + return _localCache.ToList(); + } + try { await RefreshFromRemoteAsync(ct).ConfigureAwait(false); } - catch { } + catch + { + /* 登录前拉取失败等场景,仍返回当前缓存(可能仍为空) */ + } + } + finally + { + _emptyLoadGate.Release(); } lock (_cacheLock) - { return _localCache.ToList(); - } } private async Task RefreshFromRemoteAsync(CancellationToken ct) diff --git a/yy-admin-master/YY.Admin.Services/Service/WeightRecord/WeightRecordService.cs b/yy-admin-master/YY.Admin.Services/Service/WeightRecord/WeightRecordService.cs index c8e83f2..b0b409a 100644 --- a/yy-admin-master/YY.Admin.Services/Service/WeightRecord/WeightRecordService.cs +++ b/yy-admin-master/YY.Admin.Services/Service/WeightRecord/WeightRecordService.cs @@ -197,12 +197,12 @@ public class WeightRecordService : IWeightRecordService, ISingletonDependency public async Task AddAsync(MesXslWeightRecord entity, CancellationToken ct = default) { + SanitizeWeightsBeforePersist(entity); if (!entity.TenantId.HasValue || entity.TenantId.Value <= 0) entity.TenantId = DefaultTenantId; if (string.IsNullOrWhiteSpace(entity.BillNo)) entity.BillNo = GenerateBillNo(); - if (string.IsNullOrWhiteSpace(entity.BillType)) - entity.BillType = ResolveBillType(entity); + entity.BillType = ResolveBillType(entity); var local = Clone(entity); if (string.IsNullOrWhiteSpace(local.Id)) @@ -246,21 +246,41 @@ public class WeightRecordService : IWeightRecordService, ISingletonDependency /// /// 根据称重数据推导单据类型:仅毛重=已称毛重;仅皮重=已称皮重;毛重+皮重=称重完成。 + /// 注意:皮重/毛重为 0 时按「未称」处理(避免 NumericUpDown/JSON 占位 0 误判为称重完成)。 /// private static string? ResolveBillType(MesXslWeightRecord entity) { - if (entity.GrossWeight.HasValue && entity.TareWeight.HasValue) return "2"; - if (entity.GrossWeight.HasValue) return "1"; - if (entity.TareWeight.HasValue) return "3"; + var g = HasEffectiveWeighKg(entity.GrossWeight); + var t = HasEffectiveWeighKg(entity.TareWeight); + if (g && t) return "2"; + if (g) return "1"; + if (t) return "3"; return null; } + private static bool HasEffectiveWeighKg(double? kg) => kg.HasValue && kg.Value > 0; + + /// + /// 将 ≤0 的重量视为未录入并清空净重,防止上传 payload 带 0 误判。 + /// + private static void SanitizeWeightsBeforePersist(MesXslWeightRecord entity) + { + if (entity.GrossWeight.HasValue && entity.GrossWeight.Value <= 0) + entity.GrossWeight = null; + if (entity.TareWeight.HasValue && entity.TareWeight.Value <= 0) + entity.TareWeight = null; + if (HasEffectiveWeighKg(entity.GrossWeight) && HasEffectiveWeighKg(entity.TareWeight)) + entity.NetWeight = Math.Round(entity.GrossWeight!.Value - entity.TareWeight!.Value, 2); + else + entity.NetWeight = null; + } + public async Task EditAsync(MesXslWeightRecord entity, CancellationToken ct = default) { + SanitizeWeightsBeforePersist(entity); if (!entity.TenantId.HasValue || entity.TenantId.Value <= 0) entity.TenantId = DefaultTenantId; - if (string.IsNullOrWhiteSpace(entity.BillType)) - entity.BillType = ResolveBillType(entity); + entity.BillType = ResolveBillType(entity); var local = Clone(entity); if (IsLocalTempId(local.Id)) diff --git a/yy-admin-master/YY.Admin/ViewModels/Control/MenuTreeViewModel.cs b/yy-admin-master/YY.Admin/ViewModels/Control/MenuTreeViewModel.cs index 99a4262..dcf315a 100644 --- a/yy-admin-master/YY.Admin/ViewModels/Control/MenuTreeViewModel.cs +++ b/yy-admin-master/YY.Admin/ViewModels/Control/MenuTreeViewModel.cs @@ -19,6 +19,11 @@ namespace YY.Admin.ViewModels.Control public MenuItem? Parent { get; set; } // 父节点引用 public ObservableCollection Children { get; set; } = []; + /// + /// 是否为桌面端配置的默认首页 + /// + public bool IsDefaultDesktopHome { get; set; } + private bool _isExpanded; @@ -300,6 +305,7 @@ namespace YY.Admin.ViewModels.Control target.Icon = ConvertHtmlEntityToUnicode(source?.Icon ?? ""); target.ViewName = ResolveViewName(source); // 将菜单路由映射到已注册的WPF视图 target.Parent = parent; // 设置父节点 + target.IsDefaultDesktopHome = source?.IsDefaultDesktopHome == true; // 添加子菜单(如果有) if (source.Children != null && source.Children.Any()) @@ -389,8 +395,9 @@ namespace YY.Admin.ViewModels.Control { try { - // 默认菜单 - var defaultMenuItem = GetFirstLeaf(MenuItems.FirstOrDefault()); + // 优先使用菜单管理中勾选的「默认首页」,否则取排序后的第一个叶子菜单 + var defaultMenuItem = FindDefaultHomeLeaf(MenuItems) + ?? GetFirstLeaf(MenuItems.FirstOrDefault()); if (defaultMenuItem != null) { // Tab不允许关闭 @@ -419,6 +426,31 @@ namespace YY.Admin.ViewModels.Control return GetFirstLeaf(menu.Children.FirstOrDefault()); } + /// + /// 按先序遍历查找第一个标记为默认首页的叶子节点(与左侧树展示顺序一致) + /// + private static MenuItem? FindDefaultHomeLeaf(IEnumerable? nodes) + { + if (nodes == null) + return null; + + foreach (var m in nodes) + { + if (m.Children is not { Count: > 0 }) + { + if (m.IsDefaultDesktopHome) + return m; + continue; + } + + var sub = FindDefaultHomeLeaf(m.Children); + if (sub != null) + return sub; + } + + return null; + } + public void ToggleParents(MenuItem? item, bool IsExpanded) { if (item == null) diff --git a/yy-admin-master/YY.Admin/ViewModels/MainWindowViewModel.cs b/yy-admin-master/YY.Admin/ViewModels/MainWindowViewModel.cs index f337fba..c7fa391 100644 --- a/yy-admin-master/YY.Admin/ViewModels/MainWindowViewModel.cs +++ b/yy-admin-master/YY.Admin/ViewModels/MainWindowViewModel.cs @@ -306,16 +306,7 @@ namespace YY.Admin.ViewModels ViewName = "MenuTreeView", Command = new DelegateCommand(it => _ = NavigateToViewAsync(CommonConst.MenuRegion, it.ViewName)) }, - new NavItem { - Icon = "GamepadVariantOutline", - Name = "菜单区域", - Command = new DelegateCommand(it => _ = NavigateToViewAsync(CommonConst.MenuRegion, it.ViewName)) - }, - new NavItem { - Icon = "FoodAppleOutline", - Name = "Tab区域", - Command = new DelegateCommand(OnOpenOrActivateTab) - }, + // 已隐藏开发调试用「菜单区域」「Tab区域」,日常仅保留「功能菜单」 (_menuTreeToggleNavItem = new NavItem { Icon = "ChevronDoubleLeft", Name = "折叠菜单", diff --git a/yy-admin-master/YY.Admin/ViewModels/SysManage/MenuManagementViewModel.cs b/yy-admin-master/YY.Admin/ViewModels/SysManage/MenuManagementViewModel.cs index 7eceeaf..716e2a4 100644 --- a/yy-admin-master/YY.Admin/ViewModels/SysManage/MenuManagementViewModel.cs +++ b/yy-admin-master/YY.Admin/ViewModels/SysManage/MenuManagementViewModel.cs @@ -1,5 +1,6 @@ using System.Collections.ObjectModel; using System.Linq; +using System.Windows; using HandyControl.Controls; using Prism.Commands; using Prism.Mvvm; @@ -11,21 +12,28 @@ using YY.Admin.Services.Service.Menu; namespace YY.Admin.ViewModels.SysManage; /// -/// 左侧列表一行(树形扁平展示) +/// 左侧列表一行(树形扁平展示,可见行受折叠状态控制) /// public sealed class MenuFlatRow { public SysMenu Menu { get; } public int Depth { get; } - public string IndentTitle { get; } + /// 是否存在子节点(用于显示展开按钮) + public bool HasChildren { get; } + /// 子节点当前是否展开 + public bool IsExpanded { get; } + public Thickness LeadingMargin => new(Depth * 14, 0, 0, 0); + public string TitleText { get; } - public MenuFlatRow(SysMenu menu, int depth) + public MenuFlatRow(SysMenu menu, int depth, bool hasChildren, bool isExpanded) { Menu = menu; Depth = depth; - var pad = new string(' ', depth); + HasChildren = hasChildren; + IsExpanded = isExpanded; var tag = menu.Type == MenuTypeEnum.Dir ? "[目录] " : menu.Type == MenuTypeEnum.Btn ? "[按钮] " : "[菜单] "; - IndentTitle = pad + tag + menu.Title; + var homeMark = menu.IsDefaultDesktopHome ? "[默认首页] " : ""; + TitleText = tag + homeMark + menu.Title; } } @@ -49,13 +57,25 @@ public class MenuEditorModel : BindableBase private bool _isHide; private bool _isKeepAlive = true; private bool _isAffix; + private bool _isDefaultDesktopHome; private int _orderNo = 100; private StatusEnum _status = StatusEnum.Enable; private string? _remark; public long Id { get => _id; set => SetProperty(ref _id, value); } public long Pid { get => _pid; set => SetProperty(ref _pid, value); } - public MenuTypeEnum Type { get => _type; set => SetProperty(ref _type, value); } + public MenuTypeEnum Type + { + get => _type; + set + { + if (!SetProperty(ref _type, value)) + return; + RaisePropertyChanged(nameof(CanSetDefaultDesktopHome)); + if (value != MenuTypeEnum.Menu) + IsDefaultDesktopHome = false; + } + } public string? Name { get => _name; set => SetProperty(ref _name, value); } public string? Path { get => _path; set => SetProperty(ref _path, value); } public string? Component { get => _component; set => SetProperty(ref _component, value); } @@ -68,12 +88,20 @@ public class MenuEditorModel : BindableBase public bool IsHide { get => _isHide; set => SetProperty(ref _isHide, value); } public bool IsKeepAlive { get => _isKeepAlive; set => SetProperty(ref _isKeepAlive, value); } public bool IsAffix { get => _isAffix; set => SetProperty(ref _isAffix, value); } + public bool IsDefaultDesktopHome + { + get => _isDefaultDesktopHome; + set => SetProperty(ref _isDefaultDesktopHome, value); + } public int OrderNo { get => _orderNo; set => SetProperty(ref _orderNo, value); } public StatusEnum Status { get => _status; set => SetProperty(ref _status, value); } public string? Remark { get => _remark; set => SetProperty(ref _remark, value); } public bool IsNew => Id == 0; + /// 仅「菜单」类型可设为桌面默认首页 + public bool CanSetDefaultDesktopHome => Type == MenuTypeEnum.Menu; + public void LoadFrom(SysMenu m) { Id = m.Id; @@ -91,6 +119,7 @@ public class MenuEditorModel : BindableBase IsHide = m.IsHide; IsKeepAlive = m.IsKeepAlive; IsAffix = m.IsAffix; + IsDefaultDesktopHome = m.Type == MenuTypeEnum.Menu && m.IsDefaultDesktopHome; OrderNo = m.OrderNo; Status = m.Status; Remark = m.Remark; @@ -115,6 +144,7 @@ public class MenuEditorModel : BindableBase IsHide = IsHide, IsKeepAlive = IsKeepAlive, IsAffix = IsAffix, + IsDefaultDesktopHome = Type == MenuTypeEnum.Menu && IsDefaultDesktopHome, OrderNo = OrderNo, Status = Status, Remark = Remark @@ -138,6 +168,7 @@ public class MenuEditorModel : BindableBase IsHide = false; IsKeepAlive = true; IsAffix = false; + IsDefaultDesktopHome = false; OrderNo = 100; Status = StatusEnum.Enable; Remark = null; @@ -147,6 +178,10 @@ public class MenuEditorModel : BindableBase public class MenuManagementViewModel : BaseViewModel { private readonly ISysMenuService _menuService; + /// 最近一次加载的全量菜单(折叠切换时仅重算列表,不重复读库) + private List _allMenusCache = new(); + /// 已折叠节点 Id(其子级不在扁平列表中展示) + private readonly HashSet _collapsedMenuIds = new(); public ObservableCollection FlatRows { get; } = new(); public ObservableCollection> ParentOptions { get; } = new(); @@ -208,6 +243,9 @@ public class MenuManagementViewModel : BaseViewModel public DelegateCommand AddChildCommand { get; } public DelegateCommand SaveCommand { get; } public DelegateCommand DeleteCommand { get; } + public DelegateCommand ToggleExpandCommand { get; } + public DelegateCommand ExpandAllCommand { get; } + public DelegateCommand CollapseAllCommand { get; } public MenuManagementViewModel( ISysMenuService menuService, @@ -224,6 +262,9 @@ public class MenuManagementViewModel : BaseViewModel .ObservesProperty(() => Editor); DeleteCommand = new DelegateCommand(async () => await DeleteAsync(), () => SelectedRow != null && SelectedRow.Menu.Id != 0) .ObservesProperty(() => SelectedRow); + ToggleExpandCommand = new DelegateCommand(OnToggleExpand); + ExpandAllCommand = new DelegateCommand(OnExpandAll); + CollapseAllCommand = new DelegateCommand(OnCollapseAll); _ = RefreshAsync(); } @@ -234,8 +275,11 @@ public class MenuManagementViewModel : BaseViewModel { IsLoading = true; var all = await _menuService.GetAllMenusForManageAsync(); + PruneCollapsedState(all); + _allMenusCache = all; RebuildFlat(all); RebuildParentOptions(all); + ResyncSelectionAfterRebuild(); } catch (Exception ex) { @@ -250,18 +294,90 @@ public class MenuManagementViewModel : BaseViewModel private void RebuildFlat(List all) { FlatRows.Clear(); + bool HasChild(long id) => all.Any(x => x.Pid == id); + void Walk(long pid, int depth) { foreach (var m in all.Where(x => x.Pid == pid).OrderBy(x => x.OrderNo).ThenBy(x => x.Id)) { - FlatRows.Add(new MenuFlatRow(m, depth)); - Walk(m.Id, depth + 1); + var hasCh = HasChild(m.Id); + var expanded = !_collapsedMenuIds.Contains(m.Id); + FlatRows.Add(new MenuFlatRow(m, depth, hasCh, expanded)); + if (hasCh && expanded) + Walk(m.Id, depth + 1); } } Walk(0, 0); } + /// 删除已不存在的菜单 Id,并去掉已无子级的折叠记录 + private void PruneCollapsedState(List all) + { + var validIds = new HashSet(all.Select(m => m.Id)); + foreach (var id in _collapsedMenuIds.ToList()) + { + if (!validIds.Contains(id) || !all.Any(x => x.Pid == id)) + _collapsedMenuIds.Remove(id); + } + } + + private void OnToggleExpand(MenuFlatRow? row) + { + if (row?.HasChildren != true) + return; + + var id = row.Menu.Id; + if (_collapsedMenuIds.Contains(id)) + _collapsedMenuIds.Remove(id); + else + _collapsedMenuIds.Add(id); + + RebuildFlat(_allMenusCache); + ResyncSelectionAfterRebuild(); + } + + private void OnExpandAll() + { + _collapsedMenuIds.Clear(); + RebuildFlat(_allMenusCache); + ResyncSelectionAfterRebuild(); + } + + private void OnCollapseAll() + { + _collapsedMenuIds.Clear(); + foreach (var m in _allMenusCache.Where(m => _allMenusCache.Any(c => c.Pid == m.Id))) + _collapsedMenuIds.Add(m.Id); + + RebuildFlat(_allMenusCache); + ResyncSelectionAfterRebuild(); + } + + /// 重建列表后,按 Id 恢复选中;若当前项被折叠隐藏则选中其可见祖先 + private void ResyncSelectionAfterRebuild() + { + if (_selectedRow == null) + return; + + var id = _selectedRow.Menu.Id; + MenuFlatRow? row = FlatRows.FirstOrDefault(r => r.Menu.Id == id); + var curId = id; + while (row == null && curId != 0) + { + var m = _allMenusCache.FirstOrDefault(x => x.Id == curId); + if (m == null) + break; + curId = m.Pid; + if (curId == 0) + break; + row = FlatRows.FirstOrDefault(r => r.Menu.Id == curId); + } + + if (row != null) + SelectedRow = row; + } + private void RebuildParentOptions(List all) { ParentOptions.Clear(); diff --git a/yy-admin-master/YY.Admin/ViewModels/WeightRecord/WeightRecordEditDialogViewModel.cs b/yy-admin-master/YY.Admin/ViewModels/WeightRecord/WeightRecordEditDialogViewModel.cs index 5398819..f0fdd15 100644 --- a/yy-admin-master/YY.Admin/ViewModels/WeightRecord/WeightRecordEditDialogViewModel.cs +++ b/yy-admin-master/YY.Admin/ViewModels/WeightRecord/WeightRecordEditDialogViewModel.cs @@ -168,9 +168,12 @@ public class WeightRecordEditDialogViewModel : BaseViewModel, IDialogResultable< return; } - // 净重自动计算 - if (Record.GrossWeight.HasValue && Record.TareWeight.HasValue) + // 净重自动计算(0 视为未称,不计算净重) + if (Record.GrossWeight.HasValue && Record.GrossWeight.Value > 0 + && Record.TareWeight.HasValue && Record.TareWeight.Value > 0) Record.NetWeight = Math.Round(Record.GrossWeight.Value - Record.TareWeight.Value, 2); + else + Record.NetWeight = null; // 写入密炼物料 Record.MixerMaterialIds = _mixerMaterialIds; diff --git a/yy-admin-master/YY.Admin/ViewModels/WeightRecord/WeightRecordOperationViewModel.cs b/yy-admin-master/YY.Admin/ViewModels/WeightRecord/WeightRecordOperationViewModel.cs index 86c4254..04aad77 100644 --- a/yy-admin-master/YY.Admin/ViewModels/WeightRecord/WeightRecordOperationViewModel.cs +++ b/yy-admin-master/YY.Admin/ViewModels/WeightRecord/WeightRecordOperationViewModel.cs @@ -98,6 +98,21 @@ public class WeightRecordOperationViewModel : BaseViewModel private bool _tareWeightCaptured; public bool TareWeightCaptured { get => _tareWeightCaptured; set => SetProperty(ref _tareWeightCaptured, value); } + /// + /// 手动输入毛重/皮重(仅用于测试联调,正式过磅请关闭)。 + /// + private bool _isManualWeightEntry; + public bool IsManualWeightEntry + { + get => _isManualWeightEntry; + set + { + if (!SetProperty(ref _isManualWeightEntry, value)) return; + CaptureGrossWeightCommand.RaiseCanExecuteChanged(); + CaptureTareWeightCommand.RaiseCanExecuteChanged(); + } + } + // ─── 表单绑定属性 ─── private DateTime _weighDate = DateTime.Today; @@ -234,14 +249,27 @@ public class WeightRecordOperationViewModel : BaseViewModel public double? GrossWeight { get => _grossWeight; - set { SetProperty(ref _grossWeight, value); RecalcNetWeight(); } + set + { + if (!SetProperty(ref _grossWeight, value)) return; + // 测试用手动录入:有有效数值即视为已填写(用于「已采集」提示与保存) + if (IsManualWeightEntry) + GrossWeightCaptured = value.HasValue && value.Value > 0; + RecalcNetWeight(); + } } private double? _tareWeight; public double? TareWeight { get => _tareWeight; - set { SetProperty(ref _tareWeight, value); RecalcNetWeight(); } + set + { + if (!SetProperty(ref _tareWeight, value)) return; + if (IsManualWeightEntry) + TareWeightCaptured = value.HasValue && value.Value > 0; + RecalcNetWeight(); + } } private double? _netWeight; @@ -312,10 +340,12 @@ public class WeightRecordOperationViewModel : BaseViewModel CaptureGrossWeightCommand = new DelegateCommand(CaptureGrossWeight, CanCaptureGrossWeight) .ObservesProperty(() => IsWeightStable) + .ObservesProperty(() => IsManualWeightEntry) .ObservesProperty(() => GrossWeightCaptured) .ObservesProperty(() => TareWeightCaptured); CaptureTareWeightCommand = new DelegateCommand(CaptureTareWeight, CanCaptureTareWeight) .ObservesProperty(() => IsWeightStable) + .ObservesProperty(() => IsManualWeightEntry) .ObservesProperty(() => GrossWeightCaptured) .ObservesProperty(() => TareWeightCaptured); SaveCommand = new DelegateCommand(async () => await SaveAsync()); @@ -386,7 +416,8 @@ public class WeightRecordOperationViewModel : BaseViewModel { _vehiclePresent = true; _stableCountdown = 0; - _baseWeight = _rnd.Next(18000, 65000); // 18~65吨随机 + // 同一张单第二次上磅:模拟重量与已采值协调(先毛后皮 → 皮重小于毛重;先皮后毛 → 毛重大于皮重) + PickBaseWeightForCurrentWeighingScenario(); AddLog("检测到车辆入场"); // 模拟摄像头识别车牌(2秒后回传) @@ -411,6 +442,40 @@ public class WeightRecordOperationViewModel : BaseViewModel leaveTimer.Start(); } + /// + /// 按当前单据已填毛重/皮重生成模拟磅台基准重量,保证净重合理。 + /// + private void PickBaseWeightForCurrentWeighingScenario() + { + if (HasEffectiveWeighValue(GrossWeight) && !HasEffectiveWeighValue(TareWeight)) + { + var g = GrossWeight!.Value; + // 皮重需明显小于毛重,留出净重空间 + var maxTare = Math.Max(0, g - 30); + var minTare = Math.Min(maxTare * 0.22, maxTare - 80); + minTare = Math.Max(0, minTare); + if (maxTare - minTare < 25) + minTare = Math.Max(0, maxTare * 0.45); + if (maxTare - minTare < 1) + maxTare = Math.Max(minTare + 1, g - 5); + _baseWeight = minTare + _rnd.NextDouble() * Math.Max(1e-6, maxTare - minTare); + } + else if (HasEffectiveWeighValue(TareWeight) && !HasEffectiveWeighValue(GrossWeight)) + { + var t = TareWeight!.Value; + var lower = t + Math.Max(100, t * 0.05); + var span = 8000 + _rnd.NextDouble() * 12000; + var upper = Math.Min(65000, lower + span); + if (upper - lower < 500) + upper = lower + 500; + _baseWeight = lower + _rnd.NextDouble() * (upper - lower); + } + else + { + _baseWeight = _rnd.Next(18000, 65000); // 18~65 吨随机(首次过磅或两称已齐) + } + } + private void SimulateVehicleLeave() { _vehiclePresent = false; @@ -446,19 +511,25 @@ public class WeightRecordOperationViewModel : BaseViewModel private bool CanCaptureGrossWeight() { - return IsWeightStable && !GrossWeightCaptured; + if (GrossWeightCaptured) return false; + // 手动测试模式:无需等稳定即可点采集 + if (IsManualWeightEntry) return true; + return IsWeightStable; } private bool CanCaptureTareWeight() { - return IsWeightStable && !TareWeightCaptured; + if (TareWeightCaptured) return false; + if (IsManualWeightEntry) return true; + return IsWeightStable; } private void RecalcNetWeight() { - if (GrossWeight.HasValue && TareWeight.HasValue) + // 与后端一致:0 或占位视为“未称”,避免仅毛重时 net=tare(0) 即毛重、单据误判完成 + if (HasEffectiveWeighValue(GrossWeight) && HasEffectiveWeighValue(TareWeight)) { - NetWeight = Math.Round(GrossWeight.Value - TareWeight.Value, 2); + NetWeight = Math.Round(GrossWeight!.Value - TareWeight!.Value, 2); RaisePropertyChanged(nameof(NetWeightDisplay)); } else @@ -468,6 +539,8 @@ public class WeightRecordOperationViewModel : BaseViewModel } } + private static bool HasEffectiveWeighValue(double? kg) => kg.HasValue && kg.Value > 0; + private async Task SaveAsync() { if (string.IsNullOrWhiteSpace(PlateNumber)) @@ -481,12 +554,12 @@ public class WeightRecordOperationViewModel : BaseViewModel var isOutbound = string.Equals(InoutDirection, "2", StringComparison.Ordinal); if (!isCompleteSelectedRecord) { - if (isOutbound && !TareWeight.HasValue) + if (isOutbound && !HasEffectiveWeighValue(TareWeight)) { HandyControl.Controls.MessageBox.Warning("出厂流程请先采集皮重!"); return; } - if (!isOutbound && !GrossWeight.HasValue) + if (!isOutbound && !HasEffectiveWeighValue(GrossWeight)) { HandyControl.Controls.MessageBox.Warning("进厂流程请先采集毛重!"); return; @@ -494,7 +567,7 @@ public class WeightRecordOperationViewModel : BaseViewModel } else { - var needSecondWeightCaptured = isOutbound ? GrossWeight.HasValue : TareWeight.HasValue; + var needSecondWeightCaptured = isOutbound ? HasEffectiveWeighValue(GrossWeight) : HasEffectiveWeighValue(TareWeight); if (!needSecondWeightCaptured) { HandyControl.Controls.MessageBox.Warning(isOutbound @@ -558,6 +631,7 @@ public class WeightRecordOperationViewModel : BaseViewModel ClearCustomerSelection(); ClearMixerMaterialSelection(); ClearVehicleMatch(); + IsManualWeightEntry = false; // 保存后立即按当前方向回填缓存,避免必须重进页面才显示 TryApplyCachedUnitByDirection(InoutDirection); RaisePropertyChanged(nameof(NetWeightDisplay)); @@ -592,8 +666,9 @@ public class WeightRecordOperationViewModel : BaseViewModel IsPlateNumberLocked = false; ClearSupplierSelection(); ClearCustomerSelection(); - ClearMixerMaterialSelection(); + ClearMixerMaterialSelection(); ClearVehicleMatch(); + IsManualWeightEntry = false; RaisePropertyChanged(nameof(NetWeightDisplay)); AddLog("表单已清空"); } @@ -845,15 +920,16 @@ public class WeightRecordOperationViewModel : BaseViewModel // 按进出方向查询当天待补称单据:进厂=已称毛重,出厂=已称皮重。 var page = await _weightRecordService.PageAsync(1, 100, filterPlateNumber: plate); var today = DateTime.Today; - var isOutbound = string.Equals(InoutDirection, "2", StringComparison.Ordinal); - var candidates = page.Records - .Where(r => - string.Equals((r.PlateNumber ?? string.Empty).Trim(), plate, StringComparison.OrdinalIgnoreCase) && - r.WeighDate.HasValue && - r.WeighDate.Value.Date == today && - (isOutbound - ? (r.TareWeight.HasValue && !r.GrossWeight.HasValue) - : (r.GrossWeight.HasValue && !r.TareWeight.HasValue))) + var isOutbound = string.Equals(InoutDirection, "2", StringComparison.Ordinal); + bool effT(double? w) => w.HasValue && w.Value > 0; + var candidates = page.Records + .Where(r => + string.Equals((r.PlateNumber ?? string.Empty).Trim(), plate, StringComparison.OrdinalIgnoreCase) && + r.WeighDate.HasValue && + r.WeighDate.Value.Date == today && + (isOutbound + ? (effT(r.TareWeight) && !effT(r.GrossWeight)) + : (effT(r.GrossWeight) && !effT(r.TareWeight)))) .OrderByDescending(r => r.CreateTime ?? DateTime.MinValue) .ToList(); @@ -865,8 +941,8 @@ public class WeightRecordOperationViewModel : BaseViewModel BillNo = record.BillNo ?? "-", PlateNumber = record.PlateNumber ?? "-", FirstWeightDisplay = isOutbound - ? (record.TareWeight.HasValue ? $"{record.TareWeight.Value:N2}" : "-") - : (record.GrossWeight.HasValue ? $"{record.GrossWeight.Value:N2}" : "-") + ? (HasEffectiveWeighValue(record.TareWeight) ? $"{record.TareWeight!.Value:N2}" : "-") + : (HasEffectiveWeighValue(record.GrossWeight) ? $"{record.GrossWeight!.Value:N2}" : "-") }); } @@ -914,14 +990,14 @@ public class WeightRecordOperationViewModel : BaseViewModel if (isOutbound) { TareWeight = selected.Source.TareWeight; - TareWeightCaptured = TareWeight.HasValue; + TareWeightCaptured = HasEffectiveWeighValue(TareWeight); GrossWeight = null; GrossWeightCaptured = false; } else { GrossWeight = selected.Source.GrossWeight; - GrossWeightCaptured = GrossWeight.HasValue; + GrossWeightCaptured = HasEffectiveWeighValue(GrossWeight); TareWeight = null; TareWeightCaptured = false; } @@ -953,6 +1029,7 @@ public class WeightRecordOperationViewModel : BaseViewModel ClearCustomerSelection(); ClearMixerMaterialSelection(); ClearVehicleMatch(); + IsManualWeightEntry = false; RaisePropertyChanged(nameof(NetWeightDisplay)); AddLog("已切换进出方向,当前表单数据已清空"); } diff --git a/yy-admin-master/YY.Admin/Views/LoginWindow.xaml b/yy-admin-master/YY.Admin/Views/LoginWindow.xaml index 1ee32e6..94343e2 100644 --- a/yy-admin-master/YY.Admin/Views/LoginWindow.xaml +++ b/yy-admin-master/YY.Admin/Views/LoginWindow.xaml @@ -6,6 +6,7 @@ xmlns:md="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:consts="clr-namespace:YY.Admin.Core.Const;assembly=YY.Admin.Core" xmlns:ctls="clr-namespace:YY.Admin.Core.Controls;assembly=YY.Admin.Core" + xmlns:shell="clr-namespace:System.Windows.Shell;assembly=PresentationFramework" prism:ViewModelLocator.AutoWireViewModel="True" Icon="/Resources/Icon/logo.ico" Title="{Binding Title}" @@ -17,6 +18,28 @@ KeyDown="Window_KeyDown" FontSize="{StaticResource FontSize }"> + + + + + + + @@ -38,16 +61,6 @@ - diff --git a/yy-admin-master/YY.Admin/Views/SysManage/MenuManagementView.xaml b/yy-admin-master/YY.Admin/Views/SysManage/MenuManagementView.xaml index 6566816..d991d18 100644 --- a/yy-admin-master/YY.Admin/Views/SysManage/MenuManagementView.xaml +++ b/yy-admin-master/YY.Admin/Views/SysManage/MenuManagementView.xaml @@ -61,11 +61,53 @@ - + + + + + + + + + @@ -199,6 +241,12 @@ + + + diff --git a/yy-admin-master/YY.Admin/Views/WeightRecord/WeightRecordOperationView.xaml b/yy-admin-master/YY.Admin/Views/WeightRecord/WeightRecordOperationView.xaml index e191333..8f02609 100644 --- a/yy-admin-master/YY.Admin/Views/WeightRecord/WeightRecordOperationView.xaml +++ b/yy-admin-master/YY.Admin/Views/WeightRecord/WeightRecordOperationView.xaml @@ -540,9 +540,14 @@ - + + + @@ -568,20 +573,44 @@ - - - - - + + + + + + + + + + + + + + + @@ -632,12 +661,44 @@ - - - - - + + + + + + + + + + + + + + +