
简介这份供应链系统页面原型资源面向产品经理、UI设计师、前端开发者及供应链业务人员用于在开发前期快速理解系统界面布局与交互流程降低沟通成本。压缩包共299个文件约661KB以87个html页面为主体辅以126个gif与43个png图片素材、14张jpg、5个css与6个js脚本另有15个scc及3个xlsx表格覆盖登录、菜单、表单等界面元素。内容围绕采购管理、库存管理、生产计划与调度、物流配送、销售分销、财务管理及报表分析等核心模块展开每个页面均呈现按钮、表单、图表与导航菜单的协同方式。已有1175人学习下载适合作为供应链系统设计阶段的参考模板帮助读者把握需求实现方式提升项目落地效率。1. 供应链系统页面原型一套能直接跑起来的 HTML 静态原型如果你接过供应链相关的后台项目大概率遇到过这种局面需求方说“先出个页面看看”后端接口还没影设计稿只给了几张模糊的截图前端却要在一周内拿出能点击、能跳转、能演示的原型。这时候最省事的做法不是从零画页面而是找一套结构完整、模块齐全的 HTML 原型把菜单、表格、表单、弹窗这些高频组件先搭起来。这份「供应链系统页面原型」就是干这个的——它用纯 HTML 加 CSS 加少量 JavaScript把供应商管理、采购订单、库存查询、物流跟踪这几个核心业务场景的页面骨架全部铺好下载解压后用浏览器直接打开就能点。适合谁适合需要快速交付演示版本的前端、需要给客户看流程的产品以及想拿一套现成后台模板做二次开发的人。2. 技术选型与目录结构为什么用纯静态 HTML 而不是框架2.1 静态原型的取舍逻辑拿到一份原型资源第一件事是判断它的技术底座。这套原型没有用 Vue、React 或者任何构建工具全部是原生 HTML 文件加外链 CSS 和 JavaScript。这个选择在原型阶段其实很合理供应链系统的页面原型核心诉求是“能看、能点、能改”而不是“能扛住生产流量”。用框架反而会引入 node_modules、构建配置、路由定义这些额外负担改一个字段名要重新编译演示时还得起本地服务。原生方案的好处是双击index.html就能跑发给不懂技术的业务方也能直接打开。代价是页面之间的状态共享要靠 URL 参数或者 localStorage 手动处理组件复用靠复制粘贴。对于原型来说这个代价可以接受。我一般会在原型阶段刻意保持这种“低技术密度”把精力留给信息架构和交互流程等需求确认后再决定要不要迁移到框架。2.2 目录结构拆解一份组织良好的静态原型目录结构本身就是文档。这套原型的典型布局如下supply-chain-prototype/ ├── index.html # 登录页 / 入口 ├── dashboard.html # 数据概览首页 ├── supplier/ │ ├── list.html # 供应商列表 │ ├── detail.html # 供应商详情 │ └── edit.html # 供应商新增/编辑 ├── purchase/ │ ├── order-list.html # 采购订单列表 │ ├── order-detail.html # 订单详情 │ └── order-create.html # 创建采购单 ├── inventory/ │ ├── stock-list.html # 库存查询 │ └── stock-alert.html # 库存预警 ├── logistics/ │ └── track.html # 物流跟踪 ├── css/ │ ├── reset.css # 样式重置 │ ├── layout.css # 布局框架侧边栏 顶栏 内容区 │ └── components.css # 表格、表单、按钮、弹窗 ├── js/ │ ├── common.js # 公共函数菜单高亮、弹窗控制 │ └── mock-data.js # 模拟数据 └── assets/ └── icons/ # 图标资源这个结构按业务域分目录而不是按文件类型分。好处是找一个模块的页面时不用在几十个 HTML 文件里翻。css拆成三层也是常见做法reset 抹平浏览器差异layout 管整体骨架components 管可复用控件。改样式时能快速定位到该改哪个文件。2.3 布局框架的实现方式后台系统原型的视觉一致性八成靠布局框架撑着。这套原型用的是经典的「左侧固定侧边栏 顶部导航 右侧内容区」结构。核心 CSS 逻辑如下/* layout.css —— 三区布局骨架 */ .app-wrapper { display: flex; min-height: 100vh; } .sidebar { width: 220px; flex-shrink: 0; /* 侧边栏不参与压缩 */ background: #1f2d3d; overflow-y: auto; /* 菜单过多时内部滚动 */ } .main-container { flex: 1; /* 占满剩余宽度 */ display: flex; flex-direction: column; } .topbar { height: 56px; flex-shrink: 0; border-bottom: 1px solid #e8e8e8; } .content { flex: 1; padding: 20px; overflow-y: auto; /* 内容区独立滚动 */ background: #f5f7fa; }这里的关键点是flex-shrink: 0和overflow-y: auto的配合。侧边栏固定宽度不压缩内容区自适应剩余空间侧边栏和内容区各自独立滚动互不影响。很多新手写后台布局时用position: fixed定位侧边栏结果内容区要么被遮挡要么滚动错位用 flex 能避开这个坑。提示如果你的原型需要适配小屏演示可以在.sidebar上加一个media查询窄屏时把宽度压到 60px 只显示图标鼠标悬停再展开。2.4 页面间的导航与状态传递静态原型没有路由页面跳转就是a href...。但后台系统有个刚需当前在哪个菜单侧边栏对应项要高亮。纯静态页面里这个状态没法自动感知常见做法是在每个页面的body上打一个标记然后用 JavaScript 统一处理// common.js —— 根据 body 标记高亮当前菜单 document.addEventListener(DOMContentLoaded, function () { // 每个页面在 body 上写>!-- supplier/list.html —— 数据表格骨架 -- div classtable-wrapper table classdata-table thead tr thinput typecheckbox idcheck-all/th th供应商编码/th th供应商名称/th th联系人/th th合作状态/th th操作/th /tr /thead tbody idsupplier-tbody !-- 数据由 mock-data.js 渲染原型阶段先写死几行 -- /tbody /table div classpagination span classpage-info共 128 条/span button classpage-btn disabled上一页/button button classpage-btn active1/button button classpage-btn2/button button classpage-btn下一页/button /div /div表格用原生table而不是 div 模拟是因为原型阶段要快速调整列宽和表头对齐table的colspan、rowspan和自动列宽计算比 flex 模拟省事得多。check-all复选框控制全选对应的 JavaScript 逻辑在common.js里统一处理所有列表页共用。3.2 模拟数据的组织方式原型要看起来“像真的”就得有像样的假数据。这套原型把数据集中放在mock-data.js里按业务模块分组// mock-data.js —— 供应商模拟数据 var MOCK_SUPPLIERS [ { code: SUP-2024-001, name: 华东电子元件供应商, contact: 张经理, phone: 138****0001, status: active, // active | pending | disabled statusText: 合作中 }, { code: SUP-2024-002, name: 南方物流服务商, contact: 李主管, phone: 139****0002, status: pending, statusText: 待审核 } // ... 更多数据 ]; // 渲染函数把数据填充到表格 function renderSupplierTable(data) { var tbody document.getElementById(supplier-tbody); if (!tbody) return; var html ; data.forEach(function (item) { html tr; html tdinput typecheckbox/td; html td item.code /td; html td item.name /td; html td item.contact /td; html tdspan classstatus-tag status- item.status item.statusText /span/td; html tda hrefdetail.html?code item.code 查看/a/td; html /tr; }); tbody.innerHTML html; }数据字段的设计要和真实接口对齐。status用英文枚举值statusText用中文展示文案这样后续接真实接口时前端渲染逻辑不用改只需要把MOCK_SUPPLIERS换成接口返回的数据。状态标签的样式通过status-active、status-pending这类 class 控制颜色在components.css里定义。3.3 采购订单创建页的表单联动采购订单创建页比列表页复杂涉及表单校验和行项目动态增删。这套原型里订单创建页包含供应商选择、收货信息、商品明细表格三块。商品明细支持「添加一行」「删除一行」核心逻辑如下// purchase/order-create.js —— 动态添加商品行 function addOrderItemRow() { var tbody document.getElementById(order-items); var rowCount tbody.querySelectorAll(tr).length; var tr document.createElement(tr); tr.innerHTML tdinput typetext nameproductCode placeholder商品编码/td tdinput typetext nameproductName placeholder商品名称/td tdinput typenumber nameqty value1 min1/td tdinput typenumber nameprice value0.00 step0.01/td tdspan classrow-total0.00/span/td tdbutton typebutton onclickremoveOrderItemRow(this)删除/button/td; tbody.appendChild(tr); bindRowCalculation(tr); // 绑定数量/单价变化时自动算小计 } // 行内小计计算 function bindRowCalculation(tr) { var qtyInput tr.querySelector(input[nameqty]); var priceInput tr.querySelector(input[nameprice]); var totalSpan tr.querySelector(.row-total); function calc() { var qty parseFloat(qtyInput.value) || 0; var price parseFloat(priceInput.value) || 0; totalSpan.textContent (qty * price).toFixed(2); calcGrandTotal(); // 重算合计金额 } qtyInput.addEventListener(input, calc); priceInput.addEventListener(input, calc); }这里有两个容易忽略的细节一是parseFloat后面要跟|| 0防止用户清空输入框时得到NaN二是每次行小计变化都要触发合计重算否则底部总金额对不上。原型阶段这些计算逻辑虽然不接后端但演示时业务方一定会盯着数字看算错了很尴尬。3.4 库存预警页的状态可视化库存预警页是供应链系统里视觉反馈最重的页面。这套原型用颜色标签和进度条来区分库存状态正常绿色、低于安全库存橙色、缺货红色。核心渲染逻辑// inventory/stock-alert.js —— 库存状态判定与渲染 function getStockLevel(current, safety) { if (current 0) return { level: danger, text: 缺货 }; if (current safety) return { level: warning, text: 低于安全库存 }; return { level: normal, text: 正常 }; } function renderStockRow(item) { var status getStockLevel(item.currentQty, item.safetyQty); var percent Math.min(100, (item.currentQty / item.safetyQty) * 100); return tr td item.productName /td td item.currentQty /td td item.safetyQty /td tdspan classstatus-tag status- status.level status.text /span/td tddiv classprogress-bar div classprogress-fill progress- status.level stylewidth: percent %/div /div/td /tr; }进度条宽度用Math.min(100, ...)限制防止库存远超安全值时进度条溢出容器。状态标签和进度条共用同一套status-*和progress-*类名样式在components.css里集中定义改配色时只改一处。4. 避坑与常见问题静态原型最容易翻车的几个地方4.1 路径问题导致样式和脚本加载失败现象本地双击打开页面正常发给同事后对方打开是白板样式全丢。原因CSS 和 JS 用了绝对路径如/css/layout.css或者用了file://协议下不支持的写法。静态原型没有服务器根目录的概念绝对路径会指向磁盘根目录。解决所有资源引用统一用相对路径。同级目录用./上级目录用../。比如supplier/list.html引用 CSS 要写../css/layout.css。如果原型要发给别人建议在项目根目录放一个start.bat或说明文档提示用浏览器直接打开index.html。4.2 中文编码不一致导致乱码现象页面上的中文显示成问号或方块。原因HTML 文件保存时用了 GBK 编码但meta charsetUTF-8声明的是 UTF-8或者反过来。解决所有 HTML 文件统一用 UTF-8 保存并在head第一行写meta charsetUTF-8。VS Code 右下角可以切换编码切换后记得重新保存。如果已经乱码用编辑器「以编码重新打开」功能修正后再另存。4.3 表格列过多时横向溢出现象采购订单明细列数多页面出现横向滚动条侧边栏被挤走。原因表格没有设置最小宽度或者外层容器没有overflow-x: auto。解决给表格外层包一个.table-wrapper设置overflow-x: auto表格本身设min-width比如min-width: 900px。这样列多时表格内部横向滚动不影响整体布局。4.4 弹窗层级被遮挡现象点击「新增供应商」弹出模态框但模态框被侧边栏或顶栏盖住。原因模态框的z-index低于侧边栏或者模态框放在了有overflow: hidden的容器里。解决模态框的 HTML 直接放在body末尾不要嵌套在内容区里z-index设一个足够大的值如 9999并确保侧边栏和顶栏的z-index低于它。同时给模态框遮罩层设position: fixed; top: 0; left: 0; width: 100%; height: 100%。4.5 演示时浏览器缓存旧样式现象改了 CSS 后刷新页面没变化以为改错了文件。原因浏览器缓存了旧的 CSS 文件。解决开发阶段用Ctrl F5强制刷新或者在引用 CSS 时加版本参数如layout.css?v2。原型交付前记得把版本参数去掉或统一避免混乱。5. 二次开发与改造把这套原型变成你自己的项目5.1 替换品牌色和基础样式这套原型的配色集中在css/components.css顶部的变量区如果用了 CSS 变量或者散落在各处的十六进制色值。改造第一步是把主色换掉。常见做法是在:root里定义变量:root { --primary-color: #1f2d3d; /* 侧边栏深色 */ --accent-color: #1890ff; /* 按钮、链接主色 */ --success-color: #52c41a; --warning-color: #faad14; --danger-color: #f5222d; --border-color: #e8e8e8; --bg-color: #f5f7fa; }然后把所有硬编码的颜色替换成var(--accent-color)这样的引用。改一处全站生效。如果原型的 CSS 没有用变量可以自己加一层工作量不大但后续维护省心。5.2 接入真实接口的改造路径原型转真实项目核心是把mock-data.js里的静态数组换成fetch请求。改造时建议保留 mock 数据作为降级方案// 改造后的数据获取函数 async function fetchSuppliers(params) { // 开发阶段如果配置了 USE_MOCK走本地数据 if (window.APP_CONFIG window.APP_CONFIG.useMock) { return Promise.resolve(MOCK_SUPPLIERS); } var query new URLSearchParams(params).toString(); var res await fetch(/api/supplier/list? query); if (!res.ok) throw new Error(请求失败: res.status); var json await res.json(); return json.data; // 约定接口返回 { code, data, message } }这样在接口没通之前把useMock设为true就能继续演示接口通了改成false即可。参数用URLSearchParams拼接避免手动拼字符串时漏掉encodeURIComponent导致中文参数出错。5.3 从静态原型迁移到框架的时机判断什么时候该把这套静态原型迁移到 Vue 或 React我的经验是看三个信号页面数量超过 20 个、多个页面需要共享复杂状态比如购物车式的采购单草稿、团队超过两人同时改前端。如果只是演示和确认需求静态原型足够了。迁移时不用重写把每个 HTML 页面拆成组件CSS 直接复用JavaScript 里的渲染逻辑改成框架的数据绑定即可。5.4 一个具体的改造技巧用 URL 参数驱动页面状态静态原型里详情页经常需要根据列表页点击的行来显示不同数据。没有路由的情况下用 URL 参数是最简单的方案// supplier/detail.html 里读取 URL 参数 function getQueryParam(name) { var params new URLSearchParams(window.location.search); return params.get(name); } var supplierCode getQueryParam(code); if (supplierCode) { // 从 mock 数据里找到对应供应商 var supplier MOCK_SUPPLIERS.find(function (s) { return s.code supplierCode; }); if (supplier) { document.getElementById(supplier-name).textContent supplier.name; // ... 填充其他字段 } }这个技巧在原型阶段特别实用演示时从列表点进详情数据能对上看起来就像真系统。改造时把这个逻辑换成接口请求即可URL 参数的结构不用变。从那以后我每次拿到静态原型都强制先跑一遍「路径检查 编码检查 弹窗层级检查」这三步再开始改样式。很多看起来是「样式写错了」的问题其实是资源没加载进来。希望这套原型的拆解能帮你少走点弯路拿到手就能跑起来、改起来。本文还有配套的精品资源点击获取