# Hours.MaterialManagement **Repository Path**: liang-cao/hours-material-management ## Basic Information - **Project Name**: Hours.MaterialManagement - **Description**: 物料管理 - **Primary Language**: C# - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-06-10 - **Last Updated**: 2026-04-23 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Hours.MaterialManagement - 物料管理模块 ## 📋 项目介绍 Hours.MaterialManagement 是一个独立的物料管理模块,专为实验室环境设计,提供完整的物料信息管理、库存跟踪、货架管理等功能。该模块采用现代化的分层架构设计,具有高度的可扩展性和可维护性。 ## 🏗️ 软件架构 ### 分层架构设计 ``` Hours.MaterialManagement/ ├── Hours.MaterialManagement.Core/ # 核心业务层 │ ├── Interfaces/ # 业务接口定义 │ ├── Events/ # 事件定义 │ └── Services/ # 业务服务 ├── Hours.MaterialManagement.Data/ # 数据访问层 │ ├── Models/ # 数据模型 │ ├── Enums/ # 枚举定义 │ ├── Repositories/ # 仓储接口 │ └── UnitOfWork/ # 工作单元 ├── Hours.MaterialManagement.Infrastructure/ # 基础设施层 │ ├── Repositories/ # 仓储实现 │ ├── Providers/ # 数据提供者 │ └── Extensions/ # 扩展方法 └── Hours.MaterialManagement.UI/ # 用户界面层 ├── Views/ # 视图 ├── ViewModels/ # 视图模型 └── Models/ # UI模型 ``` ### 核心特性 - **🎯 独立模块**: 完全自包含,无外部依赖 - **🔧 可配置**: 支持多种数据库和配置选项 - **📊 统计分析**: 内置丰富的统计和分析功能 - **🔍 高级搜索**: 支持多条件组合搜索 - **📱 现代UI**: 基于MaterialDesign的现代化界面 - **⚡ 高性能**: 异步操作和优化的数据访问 - **🏗️ 货架管理**: 动态货架配置和可视化管理 ## 🚀 快速开始 ### 1. 环境要求 - .NET 6.0 或更高版本 - Visual Studio 2022 或 Visual Studio Code - MySQL / SQL Server / PostgreSQL / SQLite (任选其一) ### 2. 项目引用 在您的主项目中添加对物料管理模块的引用: ```xml ``` ### 3. NuGet包安装 ```bash # 核心依赖 Install-Package SqlSugarCore Install-Package Microsoft.Extensions.DependencyInjection Install-Package Prism.Core # UI依赖 (如果使用UI模块) Install-Package MaterialDesignThemes Install-Package Prism.Wpf Install-Package Prism.DryIoc ``` ## 📖 使用说明 ### 1. 应用程序配置 (App.xaml.cs) 基于Prism框架的完整配置示例: ```csharp using System; using System.Windows; using Hours.MaterialManagement.UI.Views; using Hours.MaterialManagement.UI.ViewModels; using Hours.MaterialManagement.Infrastructure.Repositories; using Hours.MaterialManagement.Data.Repositories; using Hours.MaterialManagement.Core.Services; using Hours.MaterialManagement.Infrastructure.Providers; using Hours.MaterialManagement.Data.Models; using SqlSugar; using Prism.Ioc; using Prism.DryIoc; namespace Hours.MaterialManagement.UI { public partial class App : PrismApplication { protected override Window CreateShell() { return Container.Resolve(); } protected override void RegisterTypes(IContainerRegistry containerRegistry) { // 1. 配置数据库连接 var connectionString = "server=127.0.0.1;uid=root;pwd=yourpassword;database=hours;Pooling=True;Min Pool Size=5;Max Pool Size=100"; var databaseType = DatabaseType.MySQL; // 2. 注册数据库连接提供者 containerRegistry.RegisterSingleton(() => new SqlSugarConnectionProvider(connectionString, databaseType)); // 3. 注册 SqlSugar 客户端 containerRegistry.RegisterSingleton(provider => { var connProvider = provider.Resolve(); return connProvider.GetSugarClient(); }); // 4. 注册仓储服务 containerRegistry.RegisterSingleton(); containerRegistry.RegisterSingleton(); containerRegistry.RegisterSingleton(); // 5. 注册业务服务 containerRegistry.RegisterSingleton(); // 6. 注册视图和ViewModel containerRegistry.Register(); containerRegistry.Register(); containerRegistry.Register(); containerRegistry.Register(); containerRegistry.Register(); containerRegistry.Register(); containerRegistry.Register(); // 7. 注册导航 containerRegistry.RegisterForNavigation("ShelfView"); containerRegistry.RegisterForNavigation("ShelfConfigurationView"); } protected override void OnInitialized() { // 在容器初始化完成后进行数据库表初始化 InitializeDatabase(); base.OnInitialized(); } /// /// 自动初始化数据库表 /// private void InitializeDatabase() { try { var db = Container.Resolve(); db.CodeFirst.SetStringDefaultLength(200); // 按依赖关系顺序创建表 var tableTypes = new Type[] { typeof(MaterialInfo), // 物料基础信息表 typeof(MaterialStock), // 物料库存表 typeof(ShelfConfiguration) // 货架配置表 }; foreach (var tableType in tableTypes) { var tableName = db.EntityMaintenance.GetTableName(tableType); if (!db.DbMaintenance.IsAnyTable(tableName)) { db.CodeFirst.InitTables(tableType); System.Diagnostics.Debug.WriteLine($"表 {tableName} 创建成功"); } } } catch (Exception ex) { MessageBox.Show($"数据库初始化失败:{ex.Message}", "数据库初始化警告", MessageBoxButton.OK, MessageBoxImage.Warning); } } } } ``` ### 2. 数据库配置选项 支持多种数据库类型: ```csharp // MySQL var connectionString = "server=localhost;uid=root;pwd=password;database=hours"; var databaseType = DatabaseType.MySQL; // SQL Server var connectionString = "Server=.;Database=Hours;Trusted_Connection=true;"; var databaseType = DatabaseType.SqlServer; // SQLite var connectionString = "Data Source=hours.db"; var databaseType = DatabaseType.Sqlite; // PostgreSQL var connectionString = "Host=localhost;Database=hours;Username=postgres;Password=password"; var databaseType = DatabaseType.PostgreSQL; ``` ### 3. 基本使用示例 #### 物料管理 ```csharp // 注入服务 private readonly IMaterialRepository _materialRepository; private readonly IStockRepository _stockRepository; public async Task MaterialManagementExample() { // 创建新物料 var material = new MaterialInfo { Name = "乙醇", ChineseName = "乙醇", MaterialCode = "ETH001", CASNumber = "64-17-5", MaterialType = MaterialType.RawMaterial, PhysicalState = PhysicalState.Liquid, Unit = "ml", Density = 0.789m }; await _materialRepository.AddAsync(material); // 查询物料 var materials = await _materialRepository.GetAllAsync(); var ethanol = await _materialRepository.GetByIdAsync(material.Id); // 按条件搜索 var results = await _materialRepository.FindAsync(m => m.MaterialType == MaterialType.RawMaterial && m.PhysicalState == PhysicalState.Liquid); } ``` #### 库存管理 ```csharp public async Task StockManagementExample() { // 创建库存记录 var stock = new MaterialStock { MaterialId = "material-id", BatchNumber = "BATCH001", TotalQuantity = 1000m, CurrentQuantity = 800m, SafetyStock = 100m, StorageType = StorageType.Shelf, Position = "A1-01", Row = 1, Column = 1, ShelfLevel = 1, ProductionDate = DateTime.Now.AddDays(-30), ExpiryDate = DateTime.Now.AddYears(2) }; await _stockRepository.AddAsync(stock); // 查询库存 var stocks = await _stockRepository.GetByMaterialIdAsync("material-id"); var totalQuantity = await _stockRepository.GetTotalStockQuantityAsync("material-id"); // 检查低库存 var lowStocks = await _stockRepository.FindAsync(s => s.CurrentQuantity <= s.SafetyStock); } ``` #### 货架管理 ```csharp public async Task ShelfManagementExample() { // 创建货架配置 var shelfConfig = new ShelfSystemConfiguration { ConfigurationName = "实验室货架配置", DeviceId = "LAB001", LayoutMode = LayoutMode.Grid, GridColumns = 2, Shelves = new ObservableCollection { new ShelfConfig { ShelfId = "A", ShelfName = "Shelf_A", DisplayName = "货架A", LayerCount = 3, Layers = new ObservableCollection { new LayerConfig { LayerNumber = 1, LayerName = "第1层", PositionCount = 7, AllowedContainerTypes = new List { ContainerType.StockBottle } } } } } }; // 保存货架配置 var configEntity = new ShelfConfiguration { DeviceId = shelfConfig.DeviceId, ConfigurationName = shelfConfig.ConfigurationName, SystemConfiguration = shelfConfig, IsActive = true }; await _shelfConfigurationRepository.AddAsync(configEntity); } ``` ### 4. UI组件使用 #### 在XAML中使用货架视图 ```xml ``` #### 使用Prism导航 ```csharp // 在ViewModel中导航到货架视图 private readonly IRegionManager _regionManager; public void NavigateToShelfView() { _regionManager.RequestNavigate("MainRegion", "ShelfView"); } public void NavigateToShelfConfiguration() { _regionManager.RequestNavigate("MainRegion", "ShelfConfigurationView"); } ``` ### 5. 高级功能示例 #### 货架位置动态生成 ```csharp public class ShelfService { private readonly ShelfGenerator _shelfGenerator; public Dictionary> GenerateShelfPositions(ShelfSystemConfiguration config) { return _shelfGenerator.GenerateShelfPositions(config); } public ShelfSystemConfiguration CreateCustomConfiguration(string deviceId, int shelfCount, int layersPerShelf, int positionsPerLayer) { return _shelfGenerator.GenerateCustomConfiguration(deviceId, shelfCount, layersPerShelf, positionsPerLayer); } } ``` #### 数据验证和错误处理 ```csharp public async Task ValidateAndSaveConfiguration(ShelfSystemConfiguration config) { try { // 验证配置 var validation = _shelfGenerator.ValidateConfiguration(config); if (!validation.IsValid) { MessageBox.Show($"配置验证失败:{validation.ErrorMessage}", "验证错误"); return false; } // 保存配置 var shelfConfig = new ShelfConfiguration { DeviceId = config.DeviceId, ConfigurationName = config.ConfigurationName, SystemConfiguration = config, IsActive = true }; await _shelfConfigurationRepository.AddAsync(shelfConfig); return true; } catch (Exception ex) { MessageBox.Show($"保存失败:{ex.Message}", "错误"); return false; } } ``` ## 🔧 配置选项 ### 数据库连接池配置 ```csharp var connectionString = "server=127.0.0.1;uid=root;pwd=password;database=hours;" + "Pooling=True;" + // 启用连接池 "Min Pool Size=5;" + // 最小连接数 "Max Pool Size=100;" + // 最大连接数 "Connection Timeout=30;" + // 连接超时 "Command Timeout=60;"; // 命令超时 ``` ### SqlSugar高级配置 ```csharp containerRegistry.RegisterSingleton(provider => { var connProvider = provider.Resolve(); var db = connProvider.GetSugarClient(); // 配置日志 db.Aop.OnLogExecuting = (sql, pars) => { System.Diagnostics.Debug.WriteLine($"SQL: {sql}"); }; // 配置过滤器 db.QueryFilter.Add(new TableFilterItem { FilterValue = filterDb => new SqlFilterResult { Sql = " IsActive = 1 " } }); return db; }); ``` ## 📊 功能特性 ### ✅ 已实现功能 - [x] **物料信息管理** - [x] 物料CRUD操作 - [x] 物料分类和属性管理 - [x] CAS号和编码管理 - [x] 供应商信息管理 - [x] **库存管理** - [x] 库存信息CRUD操作 - [x] 批号和条形码管理 - [x] 安全库存和预警 - [x] 有效期管理 - [x] **货架管理系统** - [x] 动态货架配置 - [x] 多层级货架支持 - [x] 位置编码自动生成 - [x] 容器类型管理 - [x] 货架配置持久化 - [x] 可视化货架界面 - [x] 货架配置验证 - [x] **用户界面** - [x] MaterialDesign现代化界面 - [x] 响应式布局 - [x] 多条件搜索和筛选 - [x] 数据网格和详情视图 - [x] 对话框和向导 - [x] **技术特性** - [x] 异步操作支持 - [x] 多数据库支持 - [x] 依赖注入和IoC - [x] MVVM架构模式 - [x] 数据验证和完整性检查 - [x] 自动数据库表创建 ### 🚧 开发中功能 - [ ] 出入库记录管理 - [ ] 批量操作支持 - [ ] 导入导出功能 - [ ] 高级报表生成 - [ ] 移动端适配 - [ ] 条形码/二维码支持 - [ ] 自动预警系统 - [ ] 工作流引擎 - [ ] API接口 - [ ] 插件系统 ## 🏗️ 数据模型说明 ### 核心数据模型 #### MaterialInfo - 物料基础信息 ```csharp public class MaterialInfo { public string Id { get; set; } // 物料唯一ID public string Name { get; set; } // 物料名称 public string ChineseName { get; set; } // 中文名称 public string MaterialCode { get; set; } // 物料编码 public string CASNumber { get; set; } // CAS号 public MaterialType MaterialType { get; set; } // 物料类型 public PhysicalState PhysicalState { get; set; } // 物理状态 public string Unit { get; set; } // 计量单位 public decimal? Density { get; set; } // 密度 public HazardLevel HazardLevel { get; set; } // 危险等级 // ... 更多属性 } ``` #### MaterialStock - 物料库存信息 ```csharp public class MaterialStock { public string Id { get; set; } // 库存记录ID public string MaterialId { get; set; } // 物料ID public string BatchNumber { get; set; } // 批号 public string Position { get; set; } // 存储位置 public decimal TotalQuantity { get; set; } // 总量 public decimal CurrentQuantity { get; set; } // 当前余量 public decimal SafetyStock { get; set; } // 安全库存 public DateTime? ExpiryDate { get; set; } // 有效期 public StockStatus StockStatus { get; set; } // 库存状态 public int Row { get; set; } // 行位置 public int Column { get; set; } // 列位置 public int ShelfLevel { get; set; } // 货架层级 // ... 更多属性 } ``` #### ShelfConfiguration - 货架配置 ```csharp public class ShelfConfiguration { public string Id { get; set; } // 配置ID public string DeviceId { get; set; } // 设备ID public string ConfigurationName { get; set; } // 配置名称 public string ShelfConfigJson { get; set; } // 配置JSON public bool IsActive { get; set; } // 是否活动 public ShelfSystemConfiguration SystemConfiguration { get; set; } // 系统配置对象 // ... 更多属性 } ``` ### 枚举类型 ```csharp // 物理状态 public enum PhysicalState { Solid = 0, // 固体 Liquid = 1, // 液体 Powder = 2, // 粉末 Gas = 3 // 气体 } // 物料类型 public enum MaterialType { RawMaterial = 0, // 原材料 Consumable = 1, // 耗材 Product = 2, // 产品 Intermediate = 3 // 中间体 } // 容器类型 public enum ContainerType { StockBottle = 0, // 原液瓶 SampleBottle = 1, // 取样瓶 TransferBottle = 2, // 中转瓶 PowderBarrel = 3 // 粉桶 } // 存储类型 public enum StorageType { Shelf = 0, // 货架 Cabinet = 1, // 液柜 Buffer = 2 // 缓存位 } ``` ## 🤝 参与贡献 我们欢迎任何形式的贡献! ### 贡献方式 1. **Fork** 本仓库 2. 创建您的功能分支 (`git checkout -b feature/AmazingFeature`) 3. 提交您的更改 (`git commit -m 'Add some AmazingFeature'`) 4. 推送到分支 (`git push origin feature/AmazingFeature`) 5. 打开一个 **Pull Request** ### 开发规范 - 遵循 C# 编码规范 - 添加适当的单元测试 - 更新相关文档 - 确保代码通过所有测试 ## 📄 许可证 本项目采用 MIT 许可证 - 查看 [LICENSE](LICENSE) 文件了解详情。 ## 🆘 技术支持 ### 常见问题 **Q: 如何切换数据库类型?** A: 在App.xaml.cs的RegisterTypes方法中修改connectionString和databaseType参数。 **Q: 如何自定义UI界面?** A: 可以继承现有的ViewModel类,或者创建自定义的View和ViewModel,然后在RegisterTypes中注册。 **Q: 如何扩展数据模型?** A: 可以通过继承现有模型类或实现相关接口来扩展功能,记得在InitializeDatabase中添加新表的创建。 **Q: 数据库表创建失败怎么办?** A: 检查数据库连接字符串是否正确,确保数据库服务正在运行,并且用户有创建表的权限。 **Q: 如何添加新的货架配置?** A: 使用ShelfConfigurationView界面进行可视化配置,或者通过代码创建ShelfSystemConfiguration对象。 ### 获取帮助 - 📧 邮件支持:通过项目Issues联系 - 📖 文档:查看项目Wiki - 💬 讨论:参与GitHub Discussions ### 版本历史 - **v1.0.0** - 初始版本,基础功能实现 - **v1.1.0** - 添加统计分析功能 - **v1.2.0** - UI界面优化和性能提升 - **v1.3.0** - 货架管理系统完整实现 - **v1.4.0** - 数据库自动初始化和配置优化 --- **⭐ 如果这个项目对您有帮助,请给我们一个Star!** ## 🔗 相关链接 - [SqlSugar ORM](https://www.donet5.com/Home/Doc) - [Prism Library](https://prismlibrary.com/) - [Material Design in XAML](http://materialdesigninxaml.net/) - [.NET 6 文档](https://docs.microsoft.com/zh-cn/dotnet/core/) --- #### 特技 1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md 2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) 3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) 6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)