工序路径主子表单工序组装图表组件

开发一个主页面包含工序路径的主子表单控件GridView表格图表的页面,工序管理页面,工序资源组装带拖拽式控件,相关Tab页签分菜单页面,SQLSugar相关函数预备5,6组工序数据,项目框架主要使用ASP.NET Core Razor Pages 应用,实现本地文件化数据库的Web端界面化实现的代码解决方案实现组件

一、项目整体架构

基于ASP.NET Core Razor Pages + SQLSugar + SQLite(本地文件数据库) + Bootstrap + jQuery + Sortable.js(拖拽) + ECharts(图表)实现,以下是完整的代码解决方案:

二、环境准备

  1. 新建ASP.NET Core Razor Pages 项目(.NET 6/7)

  2. 安装 NuGet 包: plaintext

    复制代码
    Install-Package SQLSugarCore
    Install-Package Microsoft.EntityFrameworkCore.Sqlite
    Install-Package ECharts

三、数据库配置(SQLSugar + SQLite)

1. 数据库上下文配置(SQLSugarSetup.cs)

csharp

运行

复制代码
using SqlSugar;

namespace ProcessManagement
{
    public static class SqlSugarSetup
    {
        public static void AddSqlSugar(this IServiceCollection services, IConfiguration configuration)
        {
            // SQLite本地文件数据库
            var dbPath = Path.Combine(AppContext.BaseDirectory, "ProcessDB.db");
            var connectionString = $"Data Source={dbPath}";

            // 初始化SQLSugar
            var db = new SqlSugarClient(new ConnectionConfig
            {
                ConnectionString = connectionString,
                DbType = DbType.Sqlite,
                IsAutoCloseConnection = true,
                InitKeyType = InitKeyType.Attribute
            });

            // 自动创建表
            db.CodeFirst.InitTables(typeof(Process), typeof(ProcessPath), typeof(ProcessResource));

            // 初始化测试数据
            InitTestData(db);

            services.AddSingleton<ISqlSugarClient>(db);
        }

        // 初始化5-6组工序测试数据
        private static void InitTestData(ISqlSugarClient db)
        {
            if (db.Queryable<Process>().Any()) return;

            var processes = new List<Process>
            {
                new Process { Id = 1, ProcessName = "原材料切割", ProcessCode = "PROC001", CreateTime = DateTime.Now },
                new Process { Id = 2, ProcessName = "零部件打磨", ProcessCode = "PROC002", CreateTime = DateTime.Now },
                new Process { Id = 3, ProcessName = "组装焊接", ProcessCode = "PROC003", CreateTime = DateTime.Now },
                new Process { Id = 4, ProcessName = "表面喷涂", ProcessCode = "PROC004", CreateTime = DateTime.Now },
                new Process { Id = 5, ProcessName = "质量检测", ProcessCode = "PROC005", CreateTime = DateTime.Now },
                new Process { Id = 6, ProcessName = "成品包装", ProcessCode = "PROC006", CreateTime = DateTime.Now }
            };
            db.Insertable(processes).ExecuteCommand();

            // 工序路径数据
            var paths = new List<ProcessPath>
            {
                new ProcessPath { Id = 1, ProcessId = 1, NextProcessId = 2, PathName = "切割-打磨", Sort = 1 },
                new ProcessPath { Id = 2, ProcessId = 2, NextProcessId = 3, PathName = "打磨-焊接", Sort = 2 },
                new ProcessPath { Id = 3, ProcessId = 3, NextProcessId = 4, PathName = "焊接-喷涂", Sort = 3 },
                new ProcessPath { Id = 4, ProcessId = 4, NextProcessId = 5, PathName = "喷涂-检测", Sort = 4 },
                new ProcessPath { Id = 5, ProcessId = 5, NextProcessId = 6, PathName = "检测-包装", Sort = 5 }
            };
            db.Insertable(paths).ExecuteCommand();

            // 工序资源数据
            var resources = new List<ProcessResource>
            {
                new ProcessResource { Id = 1, ProcessId = 1, ResourceName = "切割机", ResourceType = "设备", Sort = 1 },
                new ProcessResource { Id = 2, ProcessId = 1, ResourceName = "切割刀片", ResourceType = "耗材", Sort = 2 },
                new ProcessResource { Id = 3, ProcessId = 2, ResourceName = "打磨机", ResourceType = "设备", Sort = 1 },
                new ProcessResource { Id = 4, ProcessId = 3, ResourceName = "焊接机", ResourceType = "设备", Sort = 1 },
                new ProcessResource { Id = 5, ProcessId = 4, ResourceName = "喷涂枪", ResourceType = "设备", Sort = 1 },
                new ProcessResource { Id = 6, ProcessId = 5, ResourceName = "检测仪器", ResourceType = "设备", Sort = 1 }
            };
            db.Insertable(resources).ExecuteCommand();
        }
    }
}
2. 实体类定义
Process.cs(工序主表)

csharp

运行

复制代码
using SqlSugar;

namespace ProcessManagement
{
    [SugarTable("Process")]
    public class Process
    {
        [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
        public int Id { get; set; }
        [SugarColumn(ColumnName = "ProcessName", Length = 50, IsNullable = false)]
        public string ProcessName { get; set; }
        [SugarColumn(ColumnName = "ProcessCode", Length = 20, IsNullable = false)]
        public string ProcessCode { get; set; }
        [SugarColumn(ColumnName = "CreateTime")]
        public DateTime CreateTime { get; set; }
    }
}
ProcessPath.cs(工序路径表)

csharp

运行

复制代码
using SqlSugar;

namespace ProcessManagement
{
    [SugarTable("ProcessPath")]
    public class ProcessPath
    {
        [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
        public int Id { get; set; }
        [SugarColumn(ColumnName = "ProcessId")]
        public int ProcessId { get; set; }
        [SugarColumn(ColumnName = "NextProcessId")]
        public int NextProcessId { get; set; }
        [SugarColumn(ColumnName = "PathName", Length = 50)]
        public string PathName { get; set; }
        [SugarColumn(ColumnName = "Sort")]
        public int Sort { get; set; }

        // 导航属性
        [SugarColumn(IsIgnore = true)]
        public Process CurrentProcess { get; set; }
        [SugarColumn(IsIgnore = true)]
        public Process NextProcess { get; set; }
    }
}
ProcessResource.cs(工序资源表)

csharp

运行

复制代码
using SqlSugar;

namespace ProcessManagement
{
    [SugarTable("ProcessResource")]
    public class ProcessResource
    {
        [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
        public int Id { get; set; }
        [SugarColumn(ColumnName = "ProcessId")]
        public int ProcessId { get; set; }
        [SugarColumn(ColumnName = "ResourceName", Length = 50)]
        public string ResourceName { get; set; }
        [SugarColumn(ColumnName = "ResourceType", Length = 20)]
        public string ResourceType { get; set; }
        [SugarColumn(ColumnName = "Sort")]
        public int Sort { get; set; }

        // 导航属性
        [SugarColumn(IsIgnore = true)]
        public Process Process { get; set; }
    }
}

四、页面实现

1. Program.cs 配置

csharp

运行

复制代码
using ProcessManagement;

var builder = WebApplication.CreateBuilder(args);

// 添加Razor Pages支持
builder.Services.AddRazorPages();

// 添加SQLSugar配置
builder.Services.AddSqlSugar(builder.Configuration);

var app = builder.Build();

// 中间件配置
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();

// 配置Razor Pages路由
app.MapRazorPages();

app.Run();
2. 主页面(Index.cshtml + Index.cshtml.cs)
Index.cshtml.cs(后台逻辑)

csharp

运行

复制代码
using Microsoft.AspNetCore.Mvc.RazorPages;
using SqlSugar;

namespace ProcessManagement.Pages
{
    public class IndexModel : PageModel
    {
        private readonly ISqlSugarClient _db;

        public IndexModel(ISqlSugarClient db)
        {
            _db = db;
        }

        // 工序列表
        public List<Process> ProcessList { get; set; }
        // 工序路径列表
        public List<ProcessPath> ProcessPathList { get; set; }
        // 图表数据(工序-资源数量)
        public List<object> ChartData { get; set; }

        public void OnGet()
        {
            // 获取工序列表
            ProcessList = _db.Queryable<Process>().OrderBy(p => p.Id).ToList();

            // 获取工序路径(关联工序名称)
            ProcessPathList = _db.Queryable<ProcessPath>()
                .LeftJoin<Process>((pp, p) => pp.ProcessId == p.Id)
                .LeftJoin<Process>((pp, p1, p2) => pp.NextProcessId == p2.Id)
                .Select((pp, p1, p2) => new ProcessPath
                {
                    Id = pp.Id,
                    ProcessId = pp.ProcessId,
                    NextProcessId = pp.NextProcessId,
                    PathName = pp.PathName,
                    Sort = pp.Sort,
                    CurrentProcess = p1,
                    NextProcess = p2
                })
                .OrderBy(pp => pp.Sort)
                .ToList();

            // 构建图表数据:工序名称 + 对应资源数量
            var resourceCount = _db.Queryable<ProcessResource>()
                .GroupBy(p => p.ProcessId)
                .Select(p => new { ProcessId = p.ProcessId, Count = p.Count() })
                .ToList();

            ChartData = ProcessList.Join(resourceCount, 
                p => p.Id, 
                rc => rc.ProcessId, 
                (p, rc) => new { Name = p.ProcessName, Value = rc.Count })
                .Select(item => new object[] { item.Name, item.Value })
                .ToList();
        }
    }
}
Index.cshtml(前端页面)

html

预览

复制代码
@page
@model ProcessManagement.Pages.IndexModel
@{
    ViewData["Title"] = "工序管理主页面";
}

<!-- 引入依赖 -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.4/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sortablejs@1.15.0/Sortable.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>

<!-- 页签导航 -->
<ul class="nav nav-tabs mt-3" id="mainTab" role="tablist">
    <li class="nav-item" role="presentation">
        <button class="nav-link active" id="process-tab" data-bs-toggle="tab" data-bs-target="#process" type="button" role="tab">工序列表</button>
    </li>
    <li class="nav-item" role="presentation">
        <button class="nav-link" id="path-tab" data-bs-toggle="tab" data-bs-target="#path" type="button" role="tab">工序路径</button>
    </li>
    <li class="nav-item" role="presentation">
        <button class="nav-link" id="resource-tab" data-bs-toggle="tab" data-bs-target="#resource" type="button" role="tab">工序资源(拖拽排序)</button>
    </li>
    <li class="nav-item" role="presentation">
        <button class="nav-link" id="chart-tab" data-bs-toggle="tab" data-bs-target="#chart" type="button" role="tab">数据图表</button>
    </li>
</ul>

<!-- 页签内容 -->
<div class="tab-content mt-3" id="mainTabContent">
    <!-- 1. 工序列表 -->
    <div class="tab-pane fade show active" id="process" role="tabpanel">
        <div class="card">
            <div class="card-header">
                <h5>工序列表</h5>
            </div>
            <div class="card-body">
                <table class="table table-bordered table-striped">
                    <thead>
                        <tr>
                            <th>ID</th>
                            <th>工序编码</th>
                            <th>工序名称</th>
                            <th>创建时间</th>
                            <th>操作</th>
                        </tr>
                    </thead>
                    <tbody>
                        @foreach (var process in Model.ProcessList)
                        {
                            <tr>
                                <td>@process.Id</td>
                                <td>@process.ProcessCode</td>
                                <td>@process.ProcessName</td>
                                <td>@process.CreateTime.ToString("yyyy-MM-dd HH:mm")</td>
                                <td>
                                    <a asp-page="/ProcessDetail" asp-route-id="@process.Id" class="btn btn-sm btn-primary">详情</a>
                                </td>
                            </tr>
                        }
                    </tbody>
                </table>
            </div>
        </div>
    </div>

    <!-- 2. 工序路径 -->
    <div class="tab-pane fade" id="path" role="tabpanel">
        <div class="card">
            <div class="card-header">
                <h5>工序路径</h5>
            </div>
            <div class="card-body">
                <table class="table table-bordered table-striped">
                    <thead>
                        <tr>
                            <th>排序</th>
                            <th>路径名称</th>
                            <th>当前工序</th>
                            <th>下一道工序</th>
                        </tr>
                    </thead>
                    <tbody>
                        @foreach (var path in Model.ProcessPathList)
                        {
                            <tr>
                                <td>@path.Sort</td>
                                <td>@path.PathName</td>
                                <td>@path.CurrentProcess.ProcessName</td>
                                <td>@path.NextProcess.ProcessName</td>
                            </tr>
                        }
                    </tbody>
                </table>
            </div>
        </div>
    </div>

    <!-- 3. 工序资源(拖拽排序) -->
    <div class="tab-pane fade" id="resource" role="tabpanel">
        <div class="card">
            <div class="card-header">
                <h5>工序资源(拖拽调整排序)</h5>
            </div>
            <div class="card-body">
                <div class="row">
                    @foreach (var process in Model.ProcessList)
                    {
                        var resources = Model._db.Queryable<ProcessResource>().Where(r => r.ProcessId == process.Id).OrderBy(r => r.Sort).ToList();
                        <div class="col-md-4 mb-4">
                            <div class="card">
                                <div class="card-header">@process.ProcessName</div>
                                <div id="resourceList_@process.Id" class="list-group list-group-flush">
                                    @foreach (var res in resources)
                                    {
                                        <div class="list-group-item" data-id="@res.Id">
                                            @res.ResourceName (@res.ResourceType)
                                            <span class="badge bg-secondary float-end">排序:@res.Sort</span>
                                        </div>
                                    }
                                </div>
                            </div>
                        </div>
                    }
                </div>
            </div>
        </div>
    </div>

    <!-- 4. 数据图表 -->
    <div class="tab-pane fade" id="chart" role="tabpanel">
        <div class="card">
            <div class="card-header">
                <h5>工序-资源数量统计</h5>
            </div>
            <div class="card-body">
                <div id="processChart" style="width: 100%; height: 400px;"></div>
            </div>
        </div>
    </div>
</div>

<script>
    // 1. 拖拽排序初始化
    $(function () {
        @foreach (var process in Model.ProcessList)
        {
            <text>
                var el_@(process.Id) = document.getElementById('resourceList_@(process.Id)');
                var sortable_@(process.Id) = new Sortable(el_@(process.Id), {
                    animation: 150,
                    onEnd: function (evt) {
                        // 拖拽完成后更新排序(可对接后台接口)
                        var resourceId = evt.item.getAttribute('data-id');
                        var newSort = evt.newIndex + 1;
                        console.log(`资源ID: ${resourceId}, 新排序: ${newSort}, 工序ID: @process.Id`);
                        // 此处可添加AJAX请求更新数据库排序
                        /*
                        $.post('/Process/UpdateResourceSort', {
                            resourceId: resourceId,
                            newSort: newSort
                        }, function (res) {
                            if (res.success) {
                                alert('排序更新成功');
                            }
                        });
                        */
                    }
                });
            </text>
        }

        // 2. ECharts初始化
        var chartDom = document.getElementById('processChart');
        var myChart = echarts.init(chartDom);
        var option = {
            title: { text: '工序资源数量统计' },
            xAxis: { type: 'category' },
            yAxis: { type: 'value' },
            series: [{
                name: '资源数量',
                type: 'bar',
                data: @Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model.ChartData))
            }]
        };
        myChart.setOption(option);
    });
</script>
3. 工序详情页(ProcessDetail.cshtml + ProcessDetail.cshtml.cs)
ProcessDetail.cshtml.cs

csharp

运行

复制代码
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using SqlSugar;

namespace ProcessManagement.Pages
{
    public class ProcessDetailModel : PageModel
    {
        private readonly ISqlSugarClient _db;

        public ProcessDetailModel(ISqlSugarClient db)
        {
            _db = db;
        }

        public Process Process { get; set; }
        public List<ProcessResource> ProcessResources { get; set; }

        public IActionResult OnGet(int id)
        {
            // 获取工序详情
            Process = _db.Queryable<Process>().FirstOrDefault(p => p.Id == id);
            if (Process == null)
            {
                return NotFound();
            }

            // 获取工序关联资源
            ProcessResources = _db.Queryable<ProcessResource>().Where(r => r.ProcessId == id).OrderBy(r => r.Sort).ToList();

            return Page();
        }
    }
}
ProcessDetail.cshtml

html

预览

复制代码
@page
@model ProcessManagement.Pages.ProcessDetailModel
@{
    ViewData["Title"] = "工序详情";
}

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet">

<div class="container mt-5">
    <a asp-page="/Index" class="btn btn-secondary mb-3">返回首页</a>

    <div class="card">
        <div class="card-header">
            <h4>工序详情:@Model.Process.ProcessName</h4>
        </div>
        <div class="card-body">
            <div class="row mb-3">
                <div class="col-md-2 fw-bold">工序编码:</div>
                <div class="col-md-10">@Model.Process.ProcessCode</div>
            </div>
            <div class="row mb-3">
                <div class="col-md-2 fw-bold">创建时间:</div>
                <div class="col-md-10">@Model.Process.CreateTime.ToString("yyyy-MM-dd HH:mm")</div>
            </div>

            <h5 class="mt-4">关联资源</h5>
            <table class="table table-bordered table-striped">
                <thead>
                    <tr>
                        <th>排序</th>
                        <th>资源名称</th>
                        <th>资源类型</th>
                    </tr>
                </thead>
                <tbody>
                    @foreach (var res in Model.ProcessResources)
                    {
                        <tr>
                            <td>@res.Sort</td>
                            <td>@res.ResourceName</td>
                            <td>@res.ResourceType</td>
                        </tr>
                    }
                </tbody>
            </table>
        </div>
    </div>
</div>

五、核心功能说明

  1. 本地文件数据库 :使用 SQLite 作为本地文件数据库,数据库文件存储在项目运行目录下的ProcessDB.db,无需额外数据库服务。
  2. SQLSugar 操作:通过 SQLSugar 实现数据库 CRUD、关联查询、分组统计等操作,初始化时自动创建表并填充 5-6 组测试数据。
  3. 主子表单 & GridView:主页面通过表格展示工序(主表)、工序路径(子表)、工序资源(子表),实现主子表联动展示。
  4. 拖拽控件:基于 Sortable.js 实现工序资源的拖拽排序,拖拽后可通过 AJAX 更新数据库排序(示例中仅打印日志,可扩展接口)。
  5. Tab 页签:基于 Bootstrap Tab 实现工序列表、路径、资源、图表的分页面展示。
  6. 图表展示:基于 ECharts 实现工序 - 资源数量的柱状图统计。
  7. Razor Pages 架构 :遵循ASP.NET Core Razor Pages 的页面模型分离设计,逻辑与视图解耦。

六、扩展建议

  1. 增加资源排序更新接口:实现拖拽后同步更新数据库ProcessResource表的Sort字段。
  2. 增加工序 CRUD 操作:添加新增、编辑、删除工序的功能页面。
  3. 增加表单验证:对工序名称、编码等字段添加前端 / 后端验证。
  4. 优化图表展示:支持多维度图表(如饼图、折线图),增加数据筛选功能。
  5. 增加权限控制:基于ASP.NET Core Identity 实现用户权限管理。
  6. 美化 UI:结合 AdminLTE 等模板优化页面样式。

七、运行说明

  1. 将代码放入ASP.NET Core Razor Pages 项目中,确保 NuGet 包安装完成。
  2. 运行项目,自动创建 SQLite 数据库并初始化测试数据。
  3. 访问首页(/Index)即可查看所有功能:工序列表、路径、拖拽资源、图表统计。
  4. 点击工序列表的 "详情" 按钮可进入工序详情页查看关联资源。
相关推荐
我叫张小白。1 小时前
基于Redis与FastAPI的分布式共享会话体系
数据库·redis·分布式·缓存·中间件·fastapi·依赖注入
java_cj1 小时前
MySQL 8.0新特性详解:从隐藏索引到窗口函数全面解析
数据库·mysql·架构·开源
数据库安全1 小时前
业务可用、数据可控:美创“动态脱敏+数据库透明加密“合规方案
数据库
Wonderful U1 小时前
AI智能日志异常检测告警平台:告别人工排查,秒级定位线上故障
数据库·人工智能·python·django
天河归来1 小时前
国产数据库安全可靠测评产品观察:从集中式、分布式到 HTAP 的发展趋势
数据库·分布式
linlinlove22 小时前
前端uniapp、后端thinkphp股票系统开发功能展示、代码披露、HQChart
前端·uni-app·echarts·thinkphp·hqchart·配资·deepseek选股票
万少2 小时前
Claude Code 任务结束会自己喊你:一个 Stop Hook 搞定提示音
前端·后端·代码规范
rising start2 小时前
Redis 哨兵模式(Sentinel)
数据库·redis·sentinel
light blue bird2 小时前
Razor Pages工序管理Web端界面化实现方案
jvm·windows·web端