完整MES系统实现 (C# 客户端服务器)

制造执行系统(MES)实现,包含客户端和服务器端代码,使用C#开发,支持生产管理、质量管理、设备管理和物料管理等功能。

系统架构

HTTP/JSON
OPC UA
Web API
Web API
客户端
API网关
生产管理服务
质量管理服务
设备管理服务
物料管理服务
SQL Server
PLC设备
ERP系统
WMS系统

服务器端实现

1. 项目结构

复制代码
MES.Server/
├── Controllers/        // API控制器
├── Services/           // 业务逻辑层
├── Models/             // 数据模型
├── Repositories/        // 数据访问层
├── Middleware/         // 中间件
├── appsettings.json    // 配置文件
└── Program.cs          // 入口文件

2. 数据模型 (Models)

csharp 复制代码
// ProductionOrder.cs
public class ProductionOrder
{
    public int Id { get; set; }
    public string OrderNumber { get; set; }
    public string ProductCode { get; set; }
    public int PlannedQuantity { get; set; }
    public int ProducedQuantity { get; set; }
    public string Status { get; set; } // Created, InProgress, Completed, Canceled
    public DateTime StartDate { get; set; }
    public DateTime? EndDate { get; set; }
    public string Workstation { get; set; }
    public List<ProductionStep> Steps { get; set; } = new List<ProductionStep>();
}

// ProductionStep.cs
public class ProductionStep
{
    public int Id { get; set; }
    public int OrderId { get; set; }
    public string StepName { get; set; }
    public int Sequence { get; set; }
    public string Status { get; set; } // Pending, InProgress, Completed
    public DateTime? StartTime { get; set; }
    public DateTime? EndTime { get; set; }
    public string Operator { get; set; }
    public string Equipment { get; set; }
}

// QualityCheck.cs
public class QualityCheck
{
    public int Id { get; set; }
    public int OrderId { get; set; }
    public int StepId { get; set; }
    public string CheckType { get; set; } // Visual, Dimensional, Functional
    public string Result { get; set; } // Pass, Fail, Rework
    public string Inspector { get; set; }
    public DateTime CheckTime { get; set; }
    public string Comments { get; set; }
    public List<Defect> Defects { get; set; } = new List<Defect>();
}

// Defect.cs
public class Defect
{
    public int Id { get; set; }
    public int CheckId { get; set; }
    public string DefectCode { get; set; }
    public string Description { get; set; }
    public int Quantity { get; set; }
}

// Equipment.cs
public class Equipment
{
    public int Id { get; set; }
    public string EquipmentId { get; set; }
    public string Name { get; set; }
    public string Type { get; set; }
    public string Status { get; set; } // Running, Idle, Maintenance, Down
    public DateTime LastMaintenance { get; set; }
    public string Location { get; set; }
    public List<EquipmentParameter> Parameters { get; set; } = new List<EquipmentParameter>();
}

// EquipmentParameter.cs
public class EquipmentParameter
{
    public int Id { get; set; }
    public int EquipmentId { get; set; }
    public string ParameterName { get; set; }
    public string Value { get; set; }
    public DateTime Timestamp { get; set; }
}

// Material.cs
public class Material
{
    public int Id { get; set; }
    public string MaterialCode { get; set; }
    public string Name { get; set; }
    public string Specification { get; set; }
    public string Unit { get; set; }
    public decimal CurrentStock { get; set; }
    public decimal MinStock { get; set; }
    public decimal MaxStock { get; set; }
    public string Supplier { get; set; }
    public string Location { get; set; }
}

// MaterialTransaction.cs
public class MaterialTransaction
{
    public int Id { get; set; }
    public int MaterialId { get; set; }
    public string TransactionType { get; set; } // Receipt, Issue, Transfer, Adjustment
    public decimal Quantity { get; set; }
    public string OrderId { get; set; }
    public string Operator { get; set; }
    public DateTime Timestamp { get; set; }
    public string Comments { get; set; }
}

3. 数据库上下文 (AppDbContext.cs)

csharp 复制代码
using Microsoft.EntityFrameworkCore;

public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }

    public DbSet<ProductionOrder> ProductionOrders { get; set; }
    public DbSet<ProductionStep> ProductionSteps { get; set; }
    public DbSet<QualityCheck> QualityChecks { get; set; }
    public DbSet<Defect> Defects { get; set; }
    public DbSet<Equipment> Equipments { get; set; }
    public DbSet<EquipmentParameter> EquipmentParameters { get; set; }
    public DbSet<Material> Materials { get; set; }
    public DbSet<MaterialTransaction> MaterialTransactions { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // 配置实体关系
        modelBuilder.Entity<ProductionStep>()
            .HasOne(s => s.Order)
            .WithMany(o => o.Steps)
            .HasForeignKey(s => s.OrderId);

        modelBuilder.Entity<QualityCheck>()
            .HasOne(q => q.Order)
            .WithMany()
            .HasForeignKey(q => q.OrderId);

        modelBuilder.Entity<QualityCheck>()
            .HasOne(q => q.Step)
            .WithMany()
            .HasForeignKey(q => q.StepId);

        modelBuilder.Entity<Defect>()
            .HasOne(d => d.Check)
            .WithMany(c => c.Defects)
            .HasForeignKey(d => d.CheckId);

        modelBuilder.Entity<EquipmentParameter>()
            .HasOne(p => p.Equipment)
            .WithMany(e => e.Parameters)
            .HasForeignKey(p => p.EquipmentId);

        modelBuilder.Entity<MaterialTransaction>()
            .HasOne(t => t.Material)
            .WithMany(m => m.Transactions)
            .HasForeignKey(t => t.MaterialId);
    }
}

4. 仓储层 (Repository Pattern)

csharp 复制代码
// IRepository.cs
public interface IRepository<T> where T : class
{
    Task<IEnumerable<T>> GetAllAsync();
    Task<T> GetByIdAsync(int id);
    Task AddAsync(T entity);
    Task UpdateAsync(T entity);
    Task DeleteAsync(int id);
    Task SaveChangesAsync();
}

// Repository.cs
public class Repository<T> : IRepository<T> where T : class
{
    protected readonly AppDbContext _context;
    protected readonly DbSet<T> _dbSet;

    public Repository(AppDbContext context)
    {
        _context = context;
        _dbSet = context.Set<T>();
    }

    public async Task<IEnumerable<T>> GetAllAsync()
    {
        return await _dbSet.ToListAsync();
    }

    public async Task<T> GetByIdAsync(int id)
    {
        return await _dbSet.FindAsync(id);
    }

    public async Task AddAsync(T entity)
    {
        await _dbSet.AddAsync(entity);
    }

    public Task UpdateAsync(T entity)
    {
        _context.Entry(entity).State = EntityState.Modified;
        return Task.CompletedTask;
    }

    public async Task DeleteAsync(int id)
    {
        var entity = await _dbSet.FindAsync(id);
        if (entity != null)
        {
            _dbSet.Remove(entity);
        }
    }

    public async Task SaveChangesAsync()
    {
        await _context.SaveChangesAsync();
    }
}

5. 服务层 (Business Logic)

csharp 复制代码
// IProductionService.cs
public interface IProductionService
{
    Task<IEnumerable<ProductionOrder>> GetAllOrdersAsync();
    Task<ProductionOrder> GetOrderByIdAsync(int id);
    Task<ProductionOrder> CreateOrderAsync(ProductionOrder order);
    Task UpdateOrderAsync(ProductionOrder order);
    Task StartOrderAsync(int id);
    Task CompleteOrderAsync(int id);
    Task CancelOrderAsync(int id);
    Task AddStepAsync(int orderId, ProductionStep step);
    Task UpdateStepAsync(int stepId, ProductionStep step);
    Task StartStepAsync(int stepId);
    Task CompleteStepAsync(int stepId);
}

// ProductionService.cs
public class ProductionService : IProductionService
{
    private readonly IRepository<ProductionOrder> _orderRepository;
    private readonly IRepository<ProductionStep> _stepRepository;

    public ProductionService(IRepository<ProductionOrder> orderRepository, 
                            IRepository<ProductionStep> stepRepository)
    {
        _orderRepository = orderRepository;
        _stepRepository = stepRepository;
    }

    public async Task<ProductionOrder> CreateOrderAsync(ProductionOrder order)
    {
        order.Status = "Created";
        order.StartDate = DateTime.Now;
        await _orderRepository.AddAsync(order);
        await _orderRepository.SaveChangesAsync();
        return order;
    }

    public async Task StartOrderAsync(int id)
    {
        var order = await _orderRepository.GetByIdAsync(id);
        if (order == null) throw new KeyNotFoundException("Order not found");
        
        order.Status = "InProgress";
        await _orderRepository.UpdateAsync(order);
        await _orderRepository.SaveChangesAsync();
    }

    public async Task CompleteOrderAsync(int id)
    {
        var order = await _orderRepository.GetByIdAsync(id);
        if (order == null) throw new KeyNotFoundException("Order not found");
        
        order.Status = "Completed";
        order.EndDate = DateTime.Now;
        order.ProducedQuantity = order.PlannedQuantity; // 简化处理
        await _orderRepository.UpdateAsync(order);
        await _orderRepository.SaveChangesAsync();
    }

    public async Task AddStepAsync(int orderId, ProductionStep step)
    {
        var order = await _orderRepository.GetByIdAsync(orderId);
        if (order == null) throw new KeyNotFoundException("Order not found");
        
        step.OrderId = orderId;
        step.Status = "Pending";
        await _stepRepository.AddAsync(step);
        await _stepRepository.SaveChangesAsync();
    }

    // 其他方法实现...
}

6. API控制器

csharp 复制代码
// ProductionController.cs
[ApiController]
[Route("api/production")]
public class ProductionController : ControllerBase
{
    private readonly IProductionService _productionService;

    public ProductionController(IProductionService productionService)
    {
        _productionService = productionService;
    }

    [HttpGet("orders")]
    public async Task<ActionResult<IEnumerable<ProductionOrder>>> GetOrders()
    {
        var orders = await _productionService.GetAllOrdersAsync();
        return Ok(orders);
    }

    [HttpGet("orders/{id}")]
    public async Task<ActionResult<ProductionOrder>> GetOrder(int id)
    {
        var order = await _productionService.GetOrderByIdAsync(id);
        if (order == null) return NotFound();
        return Ok(order);
    }

    [HttpPost("orders")]
    public async Task<ActionResult<ProductionOrder>> CreateOrder(ProductionOrder order)
    {
        var createdOrder = await _productionService.CreateOrderAsync(order);
        return CreatedAtAction(nameof(GetOrder), new { id = createdOrder.Id }, createdOrder);
    }

    [HttpPut("orders/{id}/start")]
    public async Task<IActionResult> StartOrder(int id)
    {
        await _productionService.StartOrderAsync(id);
        return NoContent();
    }

    [HttpPut("orders/{id}/complete")]
    public async Task<IActionResult> CompleteOrder(int id)
    {
        await _productionService.CompleteOrderAsync(id);
        return NoContent();
    }

    [HttpPost("orders/{orderId}/steps")]
    public async Task<ActionResult<ProductionStep>> AddStep(int orderId, ProductionStep step)
    {
        step.OrderId = orderId;
        await _productionService.AddStepAsync(orderId, step);
        return CreatedAtAction(nameof(GetStep), new { stepId = step.Id }, step);
    }

    [HttpGet("steps/{stepId}")]
    public async Task<ActionResult<ProductionStep>> GetStep(int stepId)
    {
        // 实现获取步骤详情
        return Ok();
    }
}

7. 主程序 (Program.cs)

csharp 复制代码
using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

// 添加数据库上下文
builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

// 添加仓储
builder.Services.AddScoped(typeof(IRepository<>), typeof(Repository<>));

// 添加服务
builder.Services.AddScoped<IProductionService, ProductionService>();
builder.Services.AddScoped<IQualityService, QualityService>();
builder.Services.AddScoped<IEquipmentService, EquipmentService>();
builder.Services.AddScoped<IMaterialService, MaterialService>();

// 添加控制器
builder.Services.AddControllers();

// 添加Swagger
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// 配置中间件
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();

// 初始化数据库
using (var scope = app.Services.CreateScope())
{
    var services = scope.ServiceProvider;
    try
    {
        var context = services.GetRequiredService<AppDbContext>();
        context.Database.Migrate();
    }
    catch (Exception ex)
    {
        var logger = services.GetRequiredService<ILogger<Program>>();
        logger.LogError(ex, "An error occurred while migrating the database.");
    }
}

app.Run();

参考代码 完整MES代码(含客户端和server端) www.youwenfan.com/contentcsu/45435.html

客户端实现 (WPF)

1. 项目结构

复制代码
MES.Client/
├── Views/            // 视图
├── ViewModels/       // 视图模型 (MVVM)
├── Services/         // 服务
├── Models/           // 数据模型
├── Converters/        // 值转换器
└── App.xaml          // 应用入口

2. 主窗口 (MainWindow.xaml)

xml 复制代码
<Window x:Class="MES.Client.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MES系统" Height="768" Width="1024">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="200"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        
        <!-- 导航菜单 -->
        <StackPanel Grid.Column="0" Background="#FF2D2D30">
            <Image Source="/Assets/logo.png" Height="50" Margin="10"/>
            <Button Content="生产管理" Command="{Binding NavigateCommand}" CommandParameter="ProductionView" Style="{StaticResource NavButton}"/>
            <Button Content="质量管理" Command="{Binding NavigateCommand}" CommandParameter="QualityView" Style="{StaticResource NavButton}"/>
            <Button Content="设备管理" Command="{Binding NavigateCommand}" CommandParameter="EquipmentView" Style="{StaticResource NavButton}"/>
            <Button Content="物料管理" Command="{Binding NavigateCommand}" CommandParameter="MaterialView" Style="{StaticResource NavButton}"/>
            <Button Content="报表中心" Command="{Binding NavigateCommand}" CommandParameter="ReportView" Style="{StaticResource NavButton}"/>
        </StackPanel>
        
        <!-- 内容区域 -->
        <ContentControl Grid.Column="1" Content="{Binding CurrentView}"/>
    </Grid>
</Window>

3. 主窗口视图模型 (MainWindowViewModel.cs)

csharp 复制代码
public class MainWindowViewModel : INotifyPropertyChanged
{
    private object _currentView;
    private readonly INavigationService _navigationService;

    public event PropertyChangedEventHandler PropertyChanged;

    public object CurrentView
    {
        get => _currentView;
        set
        {
            _currentView = value;
            OnPropertyChanged();
        }
    }

    public ICommand NavigateCommand { get; }

    public MainWindowViewModel(INavigationService navigationService)
    {
        _navigationService = navigationService;
        NavigateCommand = new RelayCommand(Navigate);
        
        // 默认视图
        Navigate("ProductionView");
    }

    private void Navigate(object parameter)
    {
        var viewName = parameter as string;
        CurrentView = _navigationService.GetView(viewName);
    }

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

4. 生产订单视图 (ProductionView.xaml)

xml 复制代码
<UserControl x:Class="MES.Client.Views.ProductionView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        
        <!-- 工具栏 -->
        <ToolBar Grid.Row="0">
            <Button Content="新建订单" Command="{Binding NewOrderCommand}"/>
            <Button Content="开始订单" Command="{Binding StartOrderCommand}"/>
            <Button Content="完成订单" Command="{Binding CompleteOrderCommand}"/>
            <Button Content="取消订单" Command="{Binding CancelOrderCommand}"/>
            <TextBox Width="200" Text="{Binding SearchText}" PlaceholderText="搜索订单..."/>
            <Button Content="搜索"/>
        </ToolBar>
        
        <!-- 订单列表 -->
        <DataGrid Grid.Row="1" ItemsSource="{Binding Orders}" SelectedItem="{Binding SelectedOrder}"
                  AutoGenerateColumns="False" IsReadOnly="True">
            <DataGrid.Columns>
                <DataGridTextColumn Header="订单号" Binding="{Binding OrderNumber}"/>
                <DataGridTextColumn Header="产品代码" Binding="{Binding ProductCode}"/>
                <DataGridTextColumn Header="计划数量" Binding="{Binding PlannedQuantity}"/>
                <DataGridTextColumn Header="已产数量" Binding="{Binding ProducedQuantity}"/>
                <DataGridTextColumn Header="状态" Binding="{Binding Status}"/>
                <DataGridTextColumn Header="开始日期" Binding="{Binding StartDate, StringFormat=yyyy-MM-dd}"/>
                <DataGridTextColumn Header="结束日期" Binding="{Binding EndDate, StringFormat=yyyy-MM-dd}"/>
            </DataGrid.Columns>
        </DataGrid>
        
        <!-- 状态栏 -->
        <StatusBar Grid.Row="2">
            <StatusBarItem>
                <TextBlock Text="{Binding StatusMessage}"/>
            </StatusBarItem>
        </StatusBar>
    </Grid>
</UserControl>

5. 生产订单视图模型 (ProductionViewModel.cs)

csharp 复制代码
public class ProductionViewModel : INotifyPropertyChanged
{
    private readonly IProductionService _productionService;
    private ObservableCollection<ProductionOrder> _orders = new ObservableCollection<ProductionOrder>();
    private ProductionOrder _selectedOrder;
    private string _searchText;
    private string _statusMessage;

    public event PropertyChangedEventHandler PropertyChanged;

    public ObservableCollection<ProductionOrder> Orders
    {
        get => _orders;
        set
        {
            _orders = value;
            OnPropertyChanged();
        }
    }

    public ProductionOrder SelectedOrder
    {
        get => _selectedOrder;
        set
        {
            _selectedOrder = value;
            OnPropertyChanged();
        }
    }

    public string SearchText
    {
        get => _searchText;
        set
        {
            _searchText = value;
            OnPropertyChanged();
            LoadOrders();
        }
    }

    public string StatusMessage
    {
        get => _statusMessage;
        set
        {
            _statusMessage = value;
            OnPropertyChanged();
        }
    }

    public ICommand NewOrderCommand { get; }
    public ICommand StartOrderCommand { get; }
    public ICommand CompleteOrderCommand { get; }
    public ICommand CancelOrderCommand { get; }

    public ProductionViewModel(IProductionService productionService)
    {
        _productionService = productionService;
        
        NewOrderCommand = new RelayCommand(NewOrder);
        StartOrderCommand = new RelayCommand(StartOrder, CanStartOrder);
        CompleteOrderCommand = new RelayCommand(CompleteOrder, CanCompleteOrder);
        CancelOrderCommand = new RelayCommand(CancelOrder, CanCancelOrder);
        
        LoadOrders();
    }

    private async void LoadOrders()
    {
        try
        {
            var orders = await _productionService.GetAllOrdersAsync();
            Orders = new ObservableCollection<ProductionOrder>(orders.Where(o => 
                string.IsNullOrEmpty(SearchText) || o.OrderNumber.Contains(SearchText)));
            StatusMessage = $"加载了 {Orders.Count} 个订单";
        }
        catch (Exception ex)
        {
            StatusMessage = $"加载订单失败: {ex.Message}";
        }
    }

    private void NewOrder()
    {
        // 打开新建订单对话框
    }

    private async void StartOrder()
    {
        if (SelectedOrder == null) return;
        
        try
        {
            await _productionService.StartOrderAsync(SelectedOrder.Id);
            StatusMessage = $"订单 {SelectedOrder.OrderNumber} 已开始";
            LoadOrders();
        }
        catch (Exception ex)
        {
            StatusMessage = $"开始订单失败: {ex.Message}";
        }
    }

    private bool CanStartOrder()
    {
        return SelectedOrder != null && SelectedOrder.Status == "Created";
    }

    private async void CompleteOrder()
    {
        if (SelectedOrder == null) return;
        
        try
        {
            await _productionService.CompleteOrderAsync(SelectedOrder.Id);
            StatusMessage = $"订单 {SelectedOrder.OrderNumber} 已完成";
            LoadOrders();
        }
        catch (Exception ex)
        {
            StatusMessage = $"完成订单失败: {ex.Message}";
        }
    }

    private bool CanCompleteOrder()
    {
        return SelectedOrder != null && SelectedOrder.Status == "InProgress";
    }

    private async void CancelOrder()
    {
        if (SelectedOrder == null) return;
        
        try
        {
            await _productionService.CancelOrderAsync(SelectedOrder.Id);
            StatusMessage = $"订单 {SelectedOrder.OrderNumber} 已取消";
            LoadOrders();
        }
        catch (Exception ex)
        {
            StatusMessage = $"取消订单失败: {ex.Message}";
        }
    }

    private bool CanCancelOrder()
    {
        return SelectedOrder != null && 
               (SelectedOrder.Status == "Created" || SelectedOrder.Status == "InProgress");
    }

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

6. API服务 (ApiService.cs)

csharp 复制代码
public class ApiService
{
    private readonly HttpClient _httpClient;
    private readonly string _baseUrl = "https://localhost:5001/api";

    public ApiService()
    {
        _httpClient = new HttpClient();
        _httpClient.DefaultRequestHeaders.Accept.Clear();
        _httpClient.DefaultRequestHeaders.Accept.Add(
            new MediaTypeWithQualityHeaderValue("application/json"));
    }

    public async Task<IEnumerable<ProductionOrder>> GetProductionOrdersAsync()
    {
        var response = await _httpClient.GetAsync($"{_baseUrl}/production/orders");
        response.EnsureSuccessStatusCode();
        var content = await response.Content.ReadAsStringAsync();
        return JsonSerializer.Deserialize<IEnumerable<ProductionOrder>>(content, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
    }

    public async Task<ProductionOrder> GetProductionOrderAsync(int id)
    {
        var response = await _httpClient.GetAsync($"{_baseUrl}/production/orders/{id}");
        response.EnsureSuccessStatusCode();
        var content = await response.Content.ReadAsStringAsync();
        return JsonSerializer.Deserialize<ProductionOrder>(content, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
    }

    public async Task<ProductionOrder> CreateProductionOrderAsync(ProductionOrder order)
    {
        var json = JsonSerializer.Serialize(order);
        var content = new StringContent(json, Encoding.UTF8, "application/json");
        var response = await _httpClient.PostAsync($"{_baseUrl}/production/orders", content);
        response.EnsureSuccessStatusCode();
        var responseContent = await response.Content.ReadAsStringAsync();
        return JsonSerializer.Deserialize<ProductionOrder>(responseContent, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
    }

    public async Task StartProductionOrderAsync(int id)
    {
        var response = await _httpClient.PutAsync($"{_baseUrl}/production/orders/{id}/start", null);
        response.EnsureSuccessStatusCode();
    }

    // 其他API方法...
}

系统功能说明

1. 生产管理

  • 生产订单创建、修改、删除
  • 生产订单状态管理(创建、进行中、完成、取消)
  • 生产步骤管理
  • 生产进度跟踪
  • 在制品(WIP)管理

2. 质量管理

  • 质量检验计划管理
  • 首件检验、巡检、终检管理
  • 缺陷记录与分析
  • SPC统计分析
  • 质量报告生成

3. 设备管理

  • 设备台账管理
  • 设备状态监控
  • 设备维护计划
  • 设备参数采集
  • OEE计算与分析

4. 物料管理

  • 物料主数据管理
  • 库存管理(入库、出库、调拨)
  • 物料追溯
  • 物料需求计划(MRP)
  • 供应商管理

5. 报表中心

  • 生产日报/周报/月报
  • 质量分析报告
  • 设备效率报告
  • 物料消耗报告
  • 自定义报表

部署方案

1. 服务器部署

bash 复制代码
# 安装.NET Core运行时
wget https://dot.net/v1/dotnet-install.sh -O dotnet-install.sh
chmod +x dotnet-install.sh
./dotnet-install.sh --runtime aspnetcore --version 6.0.0

# 部署应用程序
scp -r MES.Server user@server:/opt/mes
ssh user@server "cd /opt/mes && dotnet MES.Server.dll"

# 使用systemd管理
sudo nano /etc/systemd/system/mes.service
ini 复制代码
[Unit]
Description=MES Server

[Service]
WorkingDirectory=/opt/mes
ExecStart=/usr/bin/dotnet /opt/mes/MES.Server.dll
Restart=always
RestartSec=10
SyslogIdentifier=mes-server
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false

[Install]
WantedBy=multi-user.target

2. 客户端部署

  • 使用ClickOnce发布WPF应用程序
  • 打包为MSI安装包
  • 使用Azure DevOps实现CI/CD

3. 数据库部署

sql 复制代码
-- 创建数据库
CREATE DATABASE MesDatabase;
GO

USE MesDatabase;
GO

-- 创建表结构 (使用Entity Framework迁移)
-- 或者执行SQL脚本

系统扩展

1. 添加OPC UA设备集成

csharp 复制代码
// OpcUaClient.cs
public class OpcUaClient
{
    private Opc.Ua.Client.Session _session;
    private readonly string _endpointUrl;

    public OpcUaClient(string endpointUrl)
    {
        _endpointUrl = endpointUrl;
    }

    public async Task ConnectAsync()
    {
        var config = new Opc.Ua.ApplicationConfiguration
        {
            ApplicationName = "MES OPC UA Client",
            ApplicationType = Opc.Ua.ApplicationType.Client,
            SecurityConfiguration = new Opc.Ua.SecurityConfiguration
            {
                ApplicationCertificate = new Opc.Ua.CertificateIdentifier
                {
                    StoreType = "X509Store",
                    StorePath = "CurrentUser\\My",
                    SubjectName = "CN=MES Client"
                },
                TrustedIssuerCertificates = new Opc.Ua.CertificateTrustList
                {
                    StoreType = "Directory",
                    StorePath = "Directory"
                },
                TrustedPeerCertificates = new Opc.Ua.CertificateTrustList
                {
                    StoreType = "Directory",
                    StorePath = "Directory"
                },
                RejectedCertificateStore = new Opc.Ua.CertificateTrustList
                {
                    StoreType = "Directory",
                    StorePath = "Rejected"
                },
                AutoAcceptUntrustedCertificates = true
            },
            TransportQuotas = new Opc.Ua.TransportQuotas
            {
                OperationTimeout = 15000
            },
            ClientConfiguration = new Opc.Ua.ClientConfiguration
            {
                DefaultSessionTimeout = 60000
            }
        };

        await config.Validate(ApplicationType.Client);

        var endpoint = CoreClientUtils.SelectEndpoint(_endpointUrl, useSecurity: false);
        var endpointConfiguration = EndpointConfiguration.Create(config);
        var endpointDescription = new EndpointDescription(_endpointUrl);

        var session = Session.Create(
            config,
            endpointDescription,
            false,
            "MES Client Session",
            60000,
            new Opc.Ua.UserIdentity(new Opc.Ua.AnonymousIdentityToken()),
            null);

        _session = session.Result;
    }

    public async Task<object> ReadNodeValueAsync(string nodeId)
    {
        var node = new NodeId(nodeId);
        var value = await _session.ReadValueAsync(node);
        return value.Value;
    }

    public async Task WriteNodeValueAsync(string nodeId, object value)
    {
        var node = new NodeId(nodeId);
        var variant = new Variant(value);
        await _session.WriteValueAsync(node, variant);
    }
}

2. 添加BI集成

csharp 复制代码
// PowerBiService.cs
public class PowerBiService
{
    private readonly string _workspaceId;
    private readonly string _reportId;
    private readonly string _accessToken;

    public PowerBiService(string workspaceId, string reportId, string accessToken)
    {
        _workspaceId = workspaceId;
        _reportId = reportId;
        _accessToken = accessToken;
    }

    public async Task<byte[]> ExportReportToPdfAsync()
    {
        using (var client = new HttpClient())
        {
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _accessToken);
            var url = $"https://api.powerbi.com/v1.0/myorg/groups/{_workspaceId}/reports/{_reportId}/ExportTo";
            var response = await client.PostAsync(url, null);
            response.EnsureSuccessStatusCode();
            
            var exportId = await response.Content.ReadAsStringAsync();
            // 轮询导出状态...
            
            // 下载PDF
            url = $"https://api.powerbi.com/v1.0/myorg/groups/{_workspaceId}/reports/{_reportId}/exports/{exportId}/file";
            var pdfResponse = await client.GetAsync(url);
            return await pdfResponse.Content.ReadAsByteArrayAsync();
        }
    }
}

3. 添加移动端支持

csharp 复制代码
// Xamarin.Forms 移动端实现
public class MobileProductionPage : ContentPage
{
    public MobileProductionPage()
    {
        Title = "生产订单";
        
        var listView = new ListView
        {
            ItemTemplate = new DataTemplate(() =>
            {
                var viewCell = new ViewCell();
                var stackLayout = new StackLayout { Padding = new Thickness(10) };
                
                var orderNumber = new Label { FontAttributes = FontAttributes.Bold };
                orderNumber.SetBinding(Label.TextProperty, "OrderNumber");
                
                var productCode = new Label();
                productCode.SetBinding(Label.TextProperty, "ProductCode");
                
                var status = new Label();
                status.SetBinding(Label.TextProperty, "Status");
                
                stackLayout.Children.Add(orderNumber);
                stackLayout.Children.Add(productCode);
                stackLayout.Children.Add(status);
                
                viewCell.View = stackLayout;
                return viewCell;
            })
        };
        
        Content = listView;
        
        // 加载数据
        LoadData(listView);
    }
    
    private async void LoadData(ListView listView)
    {
        var apiService = new ApiService();
        var orders = await apiService.GetProductionOrdersAsync();
        listView.ItemsSource = orders;
    }
}

系统安全

1. 认证与授权

csharp 复制代码
// JWT认证服务
public class JwtService
{
    private readonly string _secretKey;
    private readonly string _issuer;
    private readonly string _audience;

    public JwtService(IConfiguration configuration)
    {
        _secretKey = configuration["Jwt:SecretKey"];
        _issuer = configuration["Jwt:Issuer"];
        _audience = configuration["Jwt:Audience"];
    }

    public string GenerateToken(User user)
    {
        var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_secretKey));
        var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);

        var claims = new[]
        {
            new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
            new Claim(ClaimTypes.Name, user.Username),
            new Claim(ClaimTypes.Role, user.Role)
        };

        var token = new JwtSecurityToken(
            issuer: _issuer,
            audience: _audience,
            claims: claims,
            expires: DateTime.Now.AddHours(3),
            signingCredentials: credentials
        );

        return new JwtSecurityTokenHandler().WriteToken(token);
    }

    public ClaimsPrincipal ValidateToken(string token)
    {
        var tokenHandler = new JwtSecurityTokenHandler();
        var key = Encoding.ASCII.GetBytes(_secretKey);

        try
        {
            var validationParameters = new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(key),
                ValidateIssuer = true,
                ValidIssuer = _issuer,
                ValidateAudience = true,
                ValidAudience = _audience,
                ValidateLifetime = true,
                ClockSkew = TimeSpan.Zero
            };

            var principal = tokenHandler.ValidateToken(token, validationParameters, out _);
            return principal;
        }
        catch
        {
            return null;
        }
    }
}

2. 数据加密

csharp 复制代码
// 数据加密服务
public class EncryptionService
{
    public static string Encrypt(string plainText, string key)
    {
        using (var aes = Aes.Create())
        {
            aes.Key = Encoding.UTF8.GetBytes(key.PadRight(32).Substring(0, 32));
            aes.IV = new byte[16];
            
            var encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
            using (var ms = new MemoryStream())
            using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
            {
                using (var sw = new StreamWriter(cs))
                {
                    sw.Write(plainText);
                }
                return Convert.ToBase64String(ms.ToArray());
            }
        }
    }

    public static string Decrypt(string cipherText, string key)
    {
        using (var aes = Aes.Create())
        {
            aes.Key = Encoding.UTF8.GetBytes(key.PadRight(32).Substring(0, 32));
            aes.IV = new byte[16];
            
            var decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
            using (var ms = new MemoryStream(Convert.FromBase64String(cipherText)))
            using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
            using (var sr = new StreamReader(cs))
            {
                return sr.ReadToEnd();
            }
        }
    }
}

系统监控

1. 健康检查

csharp 复制代码
// 健康检查端点
[ApiController]
[Route("health")]
public class HealthController : ControllerBase
{
    private readonly AppDbContext _context;
    private readonly ILogger<HealthController> _logger;

    public HealthController(AppDbContext context, ILogger<HealthController> logger)
    {
        _context = context;
        _logger = logger;
    }

    [HttpGet]
    public async Task<IActionResult> Get()
    {
        try
        {
            // 检查数据库连接
            await _context.Database.CanConnectAsync();
            
            // 检查关键服务
            // ...
            
            return Ok(new
            {
                Status = "Healthy",
                Timestamp = DateTime.UtcNow,
                Version = Assembly.GetEntryAssembly().GetName().Version.ToString()
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Health check failed");
            return StatusCode(503, new
            {
                Status = "Unhealthy",
                Error = ex.Message,
                Timestamp = DateTime.UtcNow
            });
        }
    }
}

2. 日志管理

csharp 复制代码
// 日志配置
public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureLogging(logging =>
        {
            logging.ClearProviders();
            logging.AddConsole();
            logging.AddDebug();
            logging.AddEventSourceLogger();
            
            // 添加文件日志
            logging.AddFile("Logs/mes-{Date}.txt");
        })
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

总结

这个完整的MES系统实现提供了以下核心功能:

  1. 生产管理

    • 生产订单全生命周期管理
    • 生产步骤跟踪与控制
    • 在制品管理
    • 生产进度监控
  2. 质量管理

    • 质量检验计划与执行
    • 缺陷记录与分析
    • SPC统计分析
    • 质量报告
  3. 设备管理

    • 设备台账管理
    • 设备状态监控
    • 设备维护管理
    • OEE计算与分析
  4. 物料管理

    • 物料主数据管理
    • 库存管理
    • 物料追溯
    • 物料需求计划
  5. 系统集成

    • OPC UA设备集成
    • ERP/WMS系统集成
    • BI系统对接
    • 移动端支持

系统采用现代化的技术栈:

  • 后端:ASP.NET Core Web API
  • 前端:WPF客户端
  • 数据库:SQL Server
  • 架构:微服务架构(可扩展)
  • 安全:JWT认证、数据加密
  • 部署:Docker容器化部署
相关推荐
她说彩礼65万2 小时前
C语言 文件
linux·服务器·c语言
月昤昽2 小时前
autocad二次开发 2.旋转
c#·autocad·autocad二次开发
rockey6272 小时前
基于AScript的python3脚本语言发布啦!
python·c#·.net·script·python3·eval·expression·function·动态脚本
工程师0072 小时前
C# 字符串不可变性 + 字符串驻留池原理
c#·字符串拘留池
_codemonster2 小时前
系统分析师刷题系列--操作系统(二)
服务器·系统架构
嵌入式×边缘AI:打怪升级日志2 小时前
TinaSDK Linux Kernel 基本使用(全志T113开发板)
linux·运维·服务器
嵌入式×边缘AI:打怪升级日志3 小时前
Linux内核基础完全入门指南(理论篇)
linux·运维·服务器
Hello_Embed3 小时前
Windows 安装 Claude Code 并接入 模型
windows·笔记·ai编程
Muyuan19983 小时前
28.Paper RAG Agent 开发记录:修复 LLM Rerank 的解析、Fallback 与可验证性
linux·人工智能·windows·python·django·fastapi