你是否还在为繁琐的库存管理而头疼?每天面对枯燥的CRUD操作,重复输入商品信息,手动查询库存状态?
今天,我将带你用C#和Semantic Kernel打造一个革命性的智能库存管理系统。想象一下,只需要说"帮我添加一个iPad Pro,价格8999元,库存20台",系统就能自动完成所有操作!
这不是科幻,而是我们今天要实现的真实项目。通过WPF界面+AI对话,让传统的管理系统焕发新生命力。无论你是C#新手还是资深开发者,这套解决方案都将为你的项目带来质的飞跃!
传统系统需要逐个字段填写,步骤冗长,容易出错。一个简单的添加商品操作可能需要点击7-8次才能完成。
想要了解库存状况,需要在多个界面间切换,数据缺乏关联性分析,决策效率低。
新员工需要培训才能熟练操作系统,界面复杂,功能分散。

C#public class Product : INotifyPropertyChanged
{
private int _stockQuantity;
private string _name;
public int Id { get; set; }
public string Name
{
get => _name;
set { _name = value; OnPropertyChanged(); }
}
public int StockQuantity
{
get => _stockQuantity;
set {
_stockQuantity = value;
OnPropertyChanged();
OnPropertyChanged(nameof(StockStatus));
}
}
// 🔥 智能状态判断
public string StockStatus
{
get
{
if (StockQuantity <= 0) return "缺货";
if (StockQuantity <= MinStockLevel) return "预警";
return "充足";
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
C#public class AIInventoryService
{
private readonly Kernel _kernel;
private readonly InventoryService _inventoryService;
public AIInventoryService(InventoryService inventoryService)
{
_inventoryService = inventoryService;
_kernel = InitializeKernel();
RegisterInventoryPlugins();
}
private Kernel InitializeKernel()
{
var kernelBuilder = Kernel.CreateBuilder();
// 🌟 配置DeepSeek API
kernelBuilder.AddOpenAIChatCompletion(
modelId: "deepseek-chat",
apiKey: Environment.GetEnvironmentVariable("DEEPSEEK_API_KEY"),
endpoint: new Uri("https://api.deepseek.com/v1")
);
return kernelBuilder.Build();
}
private void RegisterInventoryPlugins()
{
// 🔧 添加商品插件
var addProductFunction = _kernel.CreateFunctionFromMethod(
method: ([Description("商品名称")] string name,
[Description("商品类别")] string category,
[Description("商品价格")] decimal price,
[Description("库存数量")] int stockQuantity,
[Description("最低库存水平")] int minStockLevel) =>
{
try
{
var product = new Product
{
Name = name,
Category = category,
Price = price,
StockQuantity = stockQuantity,
MinStockLevel = minStockLevel
};
_inventoryService.AddProduct(product);
return JsonSerializer.Serialize(new
{
success = true,
message = $"✅ 成功添加商品:{name}",
productId = product.Id
});
}
catch (Exception ex)
{
return JsonSerializer.Serialize(new
{
success = false,
message = $"❌ 添加失败:{ex.Message}"
});
}
},
functionName: "AddProduct",
description: "添加新商品到库存系统"
);
_kernel.ImportPluginFromFunctions("DataPlugin", [addProductFunction]);
}
}
在WPF应用中,AI服务运行在后台线程,直接修改UI绑定的集合会导致异常。解决方案:
C#using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
namespace AppInventoryManagement
{
public class InventoryService
{
private ObservableCollection<Product> _products;
private ObservableCollection<Supplier> _suppliers;
private readonly Dispatcher _dispatcher;
public InventoryService()
{
// 获取UI线程的Dispatcher
_dispatcher = Application.Current?.Dispatcher ?? Dispatcher.CurrentDispatcher;
InitializeSampleData();
}
public ObservableCollection<Product> GetAllProducts()
{
return _products;
}
public ObservableCollection<Supplier> GetAllSuppliers()
{
return _suppliers;
}
public void AddProduct(Product product)
{
if (_dispatcher.CheckAccess())
{
// 已在UI线程上
AddProductInternal(product);
}
else
{
// 不在UI线程上,需要调度到UI线程
_dispatcher.Invoke(() => AddProductInternal(product));
}
}
private void AddProductInternal(Product product)
{
product.Id = _products.Count > 0 ? _products.Max(p => p.Id) + 1 : 1;
product.LastUpdated = DateTime.Now;
_products.Add(product);
}
public void UpdateProduct(Product product)
{
if (_dispatcher.CheckAccess())
{
UpdateProductInternal(product);
}
else
{
_dispatcher.Invoke(() => UpdateProductInternal(product));
}
}
private void UpdateProductInternal(Product product)
{
var existing = _products.FirstOrDefault(p => p.Id == product.Id);
if (existing != null)
{
var index = _products.IndexOf(existing);
product.LastUpdated = DateTime.Now;
_products[index] = product;
}
}
public void DeleteProduct(int productId)
{
if (_dispatcher.CheckAccess())
{
DeleteProductInternal(productId);
}
else
{
_dispatcher.Invoke(() => DeleteProductInternal(productId));
}
}
private void DeleteProductInternal(int productId)
{
var product = _products.FirstOrDefault(p => p.Id == productId);
if (product != null)
{
_products.Remove(product);
}
}
public void AddSupplier(Supplier supplier)
{
if (_dispatcher.CheckAccess())
{
AddSupplierInternal(supplier);
}
else
{
_dispatcher.Invoke(() => AddSupplierInternal(supplier));
}
}
private void AddSupplierInternal(Supplier supplier)
{
supplier.Id = Guid.NewGuid().ToString("N")[..8];
_suppliers.Add(supplier);
}
public InventoryAnalysisReport GenerateAnalysisReport()
{
// 创建副本以避免线程问题
List<Product> productsCopy;
if (_dispatcher.CheckAccess())
{
productsCopy = _products.ToList();
}
else
{
productsCopy = _dispatcher.Invoke(() => _products.ToList());
}
var report = new InventoryAnalysisReport
{
TotalProducts = productsCopy.Count,
LowStockProducts = productsCopy.Count(p => p.StockQuantity <= p.MinStockLevel && p.StockQuantity > 0),
OutOfStockProducts = productsCopy.Count(p => p.StockQuantity <= 0),
TotalValue = productsCopy.Sum(p => p.Price * p.StockQuantity)
};
// 找出最多的商品类别
var categoryGroups = productsCopy.GroupBy(p => p.Category);
if (categoryGroups.Any())
{
report.TopCategory = categoryGroups.OrderByDescending(g => g.Count()).First().Key;
}
// 找出最有价值的商品
var mostValuable = productsCopy.OrderByDescending(p => p.Price * p.StockQuantity).FirstOrDefault();
if (mostValuable != null)
{
report.MostValuableProduct = mostValuable.Name;
}
// 生成建议
if (report.OutOfStockProducts > 0)
{
report.Recommendations.Add($"有 {report.OutOfStockProducts} 种商品缺货,需要紧急补货");
}
if (report.LowStockProducts > 0)
{
report.Recommendations.Add($"有 {report.LowStockProducts} 种商品库存不足,建议及时补货");
}
return report;
}
// 添加线程安全的查询方法
public List<Product> GetProductsCopy()
{
if (_dispatcher.CheckAccess())
{
return _products.ToList();
}
else
{
return _dispatcher.Invoke(() => _products.ToList());
}
}
public List<Supplier> GetSuppliersCopy()
{
if (_dispatcher.CheckAccess())
{
return _suppliers.ToList();
}
else
{
return _dispatcher.Invoke(() => _suppliers.ToList());
}
}
private void InitializeSampleData()
{
// 初始化供应商数据
_suppliers = new ObservableCollection<Supplier>
{
new Supplier { Id = "SUP001", Name = "科技产品供应商", Contact = "张经理", Phone = "138-0000-0001", Email = "zhang@tech.com", Address = "北京市朝阳区" },
new Supplier { Id = "SUP002", Name = "办公用品供应商", Contact = "李经理", Phone = "138-0000-0002", Email = "li@office.com", Address = "上海市浦东区" },
new Supplier { Id = "SUP003", Name = "电子配件供应商", Contact = "王经理", Phone = "138-0000-0003", Email = "wang@electronic.com", Address = "深圳市南山区" }
};
// 初始化商品数据
_products = new ObservableCollection<Product>
{
new Product { Id = 1, Name = "联想ThinkPad笔记本", Category = "电子产品", Price = 6999m, StockQuantity = 15, MinStockLevel = 5, SupplierId = "SUP001", LastUpdated = DateTime.Now.AddDays(-2) },
new Product { Id = 2, Name = "iPhone 15", Category = "电子产品", Price = 7999m, StockQuantity = 2, MinStockLevel = 5, SupplierId = "SUP001", LastUpdated = DateTime.Now.AddDays(-1) },
new Product { Id = 3, Name = "办公椅", Category = "办公用品", Price = 899m, StockQuantity = 0, MinStockLevel = 3, SupplierId = "SUP002", LastUpdated = DateTime.Now.AddDays(-3) },
new Product { Id = 4, Name = "激光打印机", Category = "办公设备", Price = 1299m, StockQuantity = 8, MinStockLevel = 2, SupplierId = "SUP002", LastUpdated = DateTime.Now },
new Product { Id = 5, Name = "无线鼠标", Category = "电子配件", Price = 129m, StockQuantity = 25, MinStockLevel = 10, SupplierId = "SUP003", LastUpdated = DateTime.Now.AddHours(-5) }
};
}
}
}
XML<!-- 智能状态显示 -->
<DataGridTemplateColumn Header="状态" Width="80">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Border Background="{Binding StockStatus, Converter={StaticResource StockStatusConverter}}"
CornerRadius="3" Padding="5,2">
<TextBlock Text="{Binding StockStatus}"
Foreground="White"
HorizontalAlignment="Center"
FontWeight="Bold"/>
</Border>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<!-- AI对话区域 -->
<ScrollViewer Grid.Row="0" VerticalScrollBarVisibility="Auto"
Background="#F8F9FA">
<ItemsControl ItemsSource="{Binding ChatHistory}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Margin="5" Padding="10" CornerRadius="5"
Background="{Binding ., Converter={x:Static local:ChatMessageConverter.Instance}}">
<TextBlock Text="{Binding}" TextWrapping="Wrap"/>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>

C#public async Task<string> ChatAsync(string userMessage)
{
// 🚀 使用ConfigureAwait(false)避免死锁
var response = await chatCompletionService.GetChatMessageContentAsync(
history, executionSettings, _kernel).ConfigureAwait(false);
return response.Content;
}
C#// 🎯 使用副本避免线程问题
public List<Product> GetProductsCopy()
{
return _dispatcher.CheckAccess()
? _products.ToList()
: _dispatcher.Invoke(() => _products.ToList());
}
| 传统方式 | AI智能方式 |
|---|---|
| 填写7个字段 | 一句话描述 |
| 点击8次操作 | 发送1条消息 |
| 需要培训30分钟 | 即学即用 |
| 查询需要3步骤 | 自然语言询问 |
通过本文的实战演示,我们成功打造了一个革命性的AI驱动库存管理系统。这套解决方案的三大核心价值:
这不仅仅是一个技术demo,更是未来软件交互模式的预演。想象一下,当所有的企业系统都能通过对话来操作时,我们的工作效率将发生怎样的变革?
💡 技术金句收藏:
🤔 讨论话题:
如果这篇文章对你有启发,请转发给更多的C#同行!让我们一起推动技术创新,用AI让编程变得更美好!
关注我,持续分享C#前沿技术和实战经验! 🚀
相关信息
通过网盘分享的文件:AppInventoryManagement.zip 链接: https://pan.baidu.com/s/1F9hoF_LdX1Oj232I8ztQWQ?pwd=fa4a 提取码: fa4a --来自百度网盘超级会员v9的分享
本文作者:技术老小子
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!