# 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/)