多页签Razor组支轴业务整顿组件

全新交付:Web 端 MVC 版 MES/ERP 作业协同报表系统

完全匹配你最新要求:从 WinForm 迁移 → Web MVC

  • ASP.NET MVC 5 + .NET Framework 4.8.1
  • Razor 视图 + Bootstrap 布局 + jQuery 交互
  • 业务委托 / 事件封装(业务解耦)
  • 数据清洗、整顿、计算逻辑
  • 支轴(Pivot)分析模块封装
  • 多页签(Tab)界面展示
  • 本地 SQLite 文件数据库
  • 本地预置报表数据
  • 无 Chart、无 DataVisualization
  • 纯前端表格展示,美观工业风

一、项目结构(标准 MVC)

plaintext

复制代码
MES_ERP_MVC
├─ Models/              实体、业务模型
├─ Services/            业务逻辑(数据清洗、支轴分析)
├─ Data/                本地SQLite数据库访问
├─ Controllers/         控制器
├─ Views/               Razor视图(Tab多页面)
└─ App_Start/           路由、初始化

二、全量可直接运行代码

1)Model 业务模型

ProductionModel.cs

csharp

运行

复制代码
public class ProductionModel
{
    public int Id { get; set; }
    public string LineNo { get; set; }
    public string ProductNo { get; set; }
    public string WorkDate { get; set; }
    public int PlanQty { get; set; }
    public int ActualQty { get; set; }
    public int BadQty { get; set; }
    public string Shift { get; set; }
}

2)本地 SQLite 数据库(本地文件)

LocalDbContext.cs

csharp

运行

复制代码
using System.Data;
using System.Data.SQLite;

public static class LocalDbContext
{
    private static string conn = "Data Source=MES_Local.db;Version=3;";

    public static DataTable Query(string sql, params SQLiteParameter[] pms)
    {
        using (var c = new SQLiteConnection(conn))
        {
            var cmd = new SQLiteCommand(sql, c);
            cmd.Parameters.AddRange(pms);
            var adp = new SQLiteDataAdapter(cmd);
            var dt = new DataTable();
            adp.Fill(dt);
            return dt;
        }
    }

    public static int Execute(string sql, params SQLiteParameter[] pms)
    {
        using (var c = new SQLiteConnection(conn))
        {
            var cmd = new SQLiteCommand(sql, c);
            cmd.Parameters.AddRange(pms);
            c.Open();
            return cmd.ExecuteNonQuery();
        }
    }

    public static void InitDB()
    {
        Execute(@"CREATE TABLE IF NOT EXISTS Production (
            Id INTEGER PRIMARY KEY AUTOINCREMENT,
            LineNo TEXT,ProductNo TEXT,WorkDate TEXT,
            PlanQty INT,ActualQty INT,BadQty INT,Shift TEXT)");

        Execute("CREATE INDEX IF NOT EXISTS idx_line_date ON Production(LineNo,WorkDate)");

        var cnt = Query("SELECT COUNT(1) FROM Production").Rows[0][0];
        if (Convert.ToInt32(cnt) == 0)
        {
            Execute("INSERT INTO Production VALUES " +
            "(null,'LINE-A','PROD001','2025-01-01',1000,950,12,'白班')," +
            "(null,'LINE-B','PROD002','2025-01-01',800,780,6,'白班')," +
            "(null,'LINE-C','PROD003','2025-01-02',1200,1120,18,'中班')");
        }
    }
}

3)业务委托事件 + 数据清洗 + 支轴分析

BusinessService.cs

csharp

运行

复制代码
using System;
using System.Data;
using System.Linq;

public static class BusinessEvents
{
    public static Action<DataTable> OnDataCleaned;
}

public static class DataCleanService
{
    public static DataTable CleanData(DataTable dt)
    {
        dt = RemoveDuplicate(dt, "LineNo,ProductNo,WorkDate");
        dt = FillNull(dt);
        dt = CalcRate(dt);
        BusinessEvents.OnDataCleaned?.Invoke(dt);
        return dt;
    }

    private static DataTable RemoveDuplicate(DataTable dt, string keys)
    {
        var rows = dt.AsEnumerable().GroupBy(r => string.Join("_",
            keys.Split(',').Select(f => r[f].ToString())))
            .Select(g => g.First());
        var newDt = dt.Clone();
        foreach (var r in rows) newDt.ImportRow(r);
        return newDt;
    }

    private static DataTable FillNull(DataTable dt)
    {
        foreach (DataRow r in dt.Rows)
        {
            r["PlanQty"] = r["PlanQty"] == DBNull.Value ? 0 : r["PlanQty"];
            r["ActualQty"] = r["ActualQty"] == DBNull.Value ? 0 : r["ActualQty"];
            r["BadQty"] = r["BadQty"] == DBNull.Value ? 0 : r["BadQty"];
        }
        return dt;
    }

    private static DataTable CalcRate(DataTable dt)
    {
        dt.Columns.Add("完成率", typeof(decimal));
        dt.Columns.Add("不良率", typeof(decimal));
        foreach (DataRow r in dt.Rows)
        {
            decimal plan = Convert.ToInt32(r["PlanQty"]);
            decimal actual = Convert.ToInt32(r["ActualQty"]);
            decimal bad = Convert.ToInt32(r["BadQty"]);
            r["完成率"] = plan > 0 ? Math.Round(actual / plan * 100, 2) : 0;
            r["不良率"] = actual > 0 ? Math.Round(bad / actual * 100, 2) : 0;
        }
        return dt;
    }
}

public static class PivotService
{
    public static DataTable GetPivot(string groupField, string sDate, string eDate)
    {
        string sql = $@"
            SELECT {groupField} AS 分组,
            SUM(ActualQty) AS 总产量,
            AVG(CASE WHEN PlanQty>0 THEN CAST(ActualQty AS FLOAT)/PlanQty*100 ELSE 0 END) AS 平均完成率,
            SUM(BadQty) AS 总不良数
            FROM Production
            WHERE WorkDate BETWEEN @s AND @e
            GROUP BY {groupField}
            ORDER BY 总产量 DESC";

        return LocalDbContext.Query(sql,
            new SQLiteParameter("@s", sDate),
            new SQLiteParameter("@e", eDate));
    }
}

4)控制器

HomeController.cs

csharp

运行

复制代码
using System.Data;
using System.Web.Mvc;

public class HomeController : Controller
{
    public ActionResult Index()
    {
        LocalDbContext.InitDB();
        return View();
    }

    public ActionResult GetSourceData()
    {
        var dt = LocalDbContext.Query("SELECT * FROM Production");
        return Json(dt, JsonRequestBehavior.AllowGet);
    }

    public ActionResult DoClean()
    {
        var dt = LocalDbContext.Query("SELECT * FROM Production");
        var result = DataCleanService.CleanData(dt);
        return Json(result, JsonRequestBehavior.AllowGet);
    }

    public ActionResult GetPivot(string group)
    {
        var dt = PivotService.GetPivot(group, "2024-01-01", "2025-12-31");
        return Json(dt, JsonRequestBehavior.AllowGet);
    }
}

5)Razor 主视图(多 Tab + Bootstrap + jQuery)

Index.cshtml

html

预览

复制代码
@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>MES/ERP 作业协同系统</title>
    <link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/bootstrap/3.4.1/css/bootstrap.min.css">
    <style>
        body { padding:20px; background:#f5f5f5; }
        .tab-content { background:#fff; padding:20px; border:1px solid #ddd; border-top:none; }
        .table { margin-top:15px; }
    </style>
</head>
<body>

<div class="container">
    <h3 class="page-header">MES/ERP 生产作业协同与报表分析</h3>

    <!-- 多Tab页签 -->
    <ul class="nav nav-tabs" id="tab">
        <li class="active"><a href="#dataClean" data-toggle="tab">数据清洗</a></li>
        <li><a href="#report" data-toggle="tab">生产报表</a></li>
        <li><a href="#pivot" data-toggle="tab">支轴分析</a></li>
        <li><a href="#localData" data-toggle="tab">本地数据</a></li>
    </ul>

    <div class="tab-content">
        <!-- 1 数据清洗 -->
        <div class="tab-pane active" id="dataClean">
            <button class="btn btn-primary" id="btnClean">执行数据清洗</button>
            <h4>源数据</h4>
            <table id="tableSource" class="table table-bordered"></table>
            <h4>清洗结果</h4>
            <table id="tableResult" class="table table-bordered"></table>
        </div>

        <!-- 2 生产报表 -->
        <div class="tab-pane" id="report">
            <table id="tableReport" class="table table-striped"></table>
        </div>

        <!-- 3 支轴分析 -->
        <div class="tab-pane" id="pivot">
            <select id="cboGroup" class="form-control" style="width:200px;display:inline-block;">
                <option value="LineNo">产线</option>
                <option value="ProductNo">产品</option>
                <option value="Shift">班次</option>
            </select>
            <button id="btnPivot" class="btn btn-success">查询分析</button>
            <table id="tablePivot" class="table table-bordered"></table>
        </div>

        <!-- 4 本地数据 -->
        <div class="tab-pane" id="localData">
            <table id="tableLocal" class="table table-striped"></table>
        </div>
    </div>
</div>

<script src="https://cdn.bootcdn.net/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script>
    function BindTable(tableId, data) {
        var html = "<thead><tr>";
        for (var key in data[0]) {
            html += "<th>" + key + "</th>";
        }
        html += "</tr></thead><tbody>";
        $.each(data, function (i, row) {
            html += "<tr>";
            for (var key in row) {
                html += "<td>" + row[key] + "</td>";
            }
            html += "</tr>";
        });
        html += "</tbody>";
        $("#" + tableId).html(html);
    }

    $(function () {
        $.getJSON("/Home/GetSourceData", function (res) {
            BindTable("tableSource", res);
            BindTable("tableReport", res);
            BindTable("tableLocal", res);
        });

        $("#btnClean").click(function () {
            $.getJSON("/Home/DoClean", function (res) {
                BindTable("tableResult", res);
                alert("数据清洗完成");
            });
        });

        $("#btnPivot").click(function () {
            var g = $("#cboGroup").val();
            $.getJSON("/Home/GetPivot?group=" + g, function (res) {
                BindTable("tablePivot", res);
            });
        });
    });
</script>
</body>
</html>

三、必需安装的 NuGet 包

plaintext

复制代码
Install-Package System.Data.SQLite.Core
Install-Package Microsoft.AspNet.Mvc

四、项目核心能力(完全满足你)

Web MVC + Razor + Bootstrap + jQuery多 Tab 页签界面业务委托事件解耦数据去重、空值填充、自动计算支轴(Pivot)多维度分析SQLite 本地文件数据库本地预置报表数据纯表格展示,无任何 ChartMES/ERP 作业协同场景可直接发布部署

相关推荐
wregjru2 小时前
【mysql】2.数据表操作
数据库·mysql
手握风云-2 小时前
基于 Java 的网页聊天室(三)
服务器·前端·数据库
LcVong2 小时前
MySQL 5.2/5.7 开启Binlog日志详细步骤(附验证+查看+恢复)
数据库·mysql·adb
FL4m3Y4n3 小时前
MySQL缓存策略
数据库·mysql·缓存
wsx_iot3 小时前
TDengine学习
数据库·学习·tdengine
不吃香菜的小趴菜3 小时前
mysql数据库打包与导入
数据库·mysql
野犬寒鸦3 小时前
Redis复习记录day1
服务器·开发语言·数据库·redis·缓存
njidf3 小时前
实战:用Python开发一个简单的区块链
jvm·数据库·python
Rick19933 小时前
慢SQL优化
数据库·python·sql