外运长江营销综合服务平台是一个集物流产品展示、物流资源管理、物流通道可视化和后台数据维护于一体的 Web 应用系统,涵盖 46 个线路产品(按线路级划分,分 5 大类)和 70 个物流资源点。
平台采用线路级产品划分:同一产品面向不同目的地港口(如外高桥港区、洋山港区)拆分为独立线路展示,便于用户按实际业务需求筛选和查看。
平台采用前后台分离设计:
导航栏:页面顶部导航栏包含以下入口:
| 入口 | 功能 |
|---|---|
| 首页 | 平台介绍、数据统计概览 |
| 物流产品 | 浏览全部 46 个线路产品(默认显示星标产品,可按分类筛选),点击卡片查看详情 |
| 物流资源 | 浏览 70 个资源点,支持按类型筛选 |
| 物流通道 | 进入物流通道可视化地图页面(独立页面) |
| 关于我们 | 平台简介、核心服务、联系方式 |
| 帮助 | 跳转到独立帮助页面 |
| 后台管理 | 弹出钉钉扫码登录二维码 |
产品详情:点击任意产品卡片,弹窗展示产品完整信息,包括通道示意图(动态展示该产品的港口、城市、目的地节点及通道连线)、产品简介、运营时刻表、覆盖站点、海运航线时效、销售团队、支持船司、客户案例等。
产品分类筛选:物流产品页顶部提供分类 Tab 切换按钮,共 7 个:「星标产品」(默认选中,金色星标)、「全部」、「全程物流」、「海铁联运」、「陆改水」、「港口直拖」、「水水联运」,每个按钮显示该分类数量(兼统计功能)。默认显示「星标产品」分类,每个分类中标注的「星标产品」以金色边框和右上角金色星标圆形徽章突出显示,并自动排在分类列表首位。
资源筛选:在物流资源页面,顶部筛选按钮(全部 / 码头 / 仓库 / 铁路站点 / 堆场)兼作分类统计,按钮内显示该类型数量,点击即过滤列表与地图标记,与物流产品页的筛选统计方式保持一致。筛选按钮下方另以辅助信息行展示「覆盖城市数 / 服务省份数」。
资源详情:点击任意资源卡片,弹窗按结构化分组展示资源完整信息,包括基本信息、权属信息、业务简介、能力规格(按"规格/作业能力/安全设施/管理信息"等分组)、地理位置、联系方式。
资源地图视图:物流资源页面支持切换"列表视图"和"地图视图",地图视图在地图上展示所有资源标记,可点击标记查看详情。
首页产品展示:首页产品区采用「1 大图 + 4 小卡片」布局,5 大产品分类各占一席,保证首页能一览全部产品线:
首页快捷入口:首页 Hero 区提供三个快捷按钮:
页面入口:点击导航栏「物流通道」或首页「选择物流通道」按钮,进入独立的物流通道可视化地图页面(基于 Leaflet + 高德地图)。
地图元素:
| 元素 | 说明 |
|---|---|
| 港口/站点标记 | 地图上的圆点标记,鼠标悬停显示名称 |
| 海运航线 | 蓝色曲线,连接沿海港口与海外目的地 |
| 铁路通道 | 橙黄色线条,沿真实铁路走廊绘制 |
| 水路通道 | 青色线条,沿长江干线绘制 |
| 公路通道 | 灰色虚线,调用高德驾车路径规划 API 绘制 |
查看通道详情:点击任意通道线,弹出气泡显示通道名称、类型和时效信息,同时该通道高亮显示(加粗、置顶)。
按产品分类筛选:左侧「产品筛选」面板顶部提供分类筛选 chips(「全部」+ 5 大产品分类),每个 chip 显示该分类下产品数量。两种视图模式:
线路模式切换:地图右上角筛选面板提供两种线路绘制模式:
筛选通道:筛选面板可按通道类型(海运/铁路/水路/公路)显示或隐藏对应通道。
登录方式:钉钉扫码登录。
点击导航栏"后台管理"按钮,在弹出的二维码框中使用钉钉 App 扫码即可进入后台。登录态由服务端 HttpOnly Cookie 维持,7 天内免重复扫码。建议使用钉钉 App 主账号扫码,退出登录后需重新扫码。
后台登录基于钉钉 OAuth 2.0 扫码授权 + Cloudflare Pages Functions 无服务器后端实现,整套流程无需独立服务器,随站点一同部署。架构与流程概括如下:
| 环节 | 实现说明 |
|---|---|
| 登录配置下发 | 前端请求 /api/dingtalk-login-url,由 Pages Function 读取 Cloudflare 环境变量中的 DINGTALK_APP_KEY、APP_BASE_URL,生成随机 state 并写入 HttpOnly Cookie(CSRF 防护),返回 clientId、redirectUri、state 给前端 |
| 二维码渲染 | 前端加载钉钉官方 h5-dingtalk-login SDK,用返回的 clientId/redirectUri/state 在弹窗内嵌二维码 |
| 扫码授权 | 用户用钉钉 App 扫码确认后,钉钉将 authCode 回调到 redirectUri(即站点根路径 /),前端捕获 code 后请求 /api/dingtalk/callback |
| 换取用户身份 | callback 函数用 DINGTALK_APP_SECRET 获取 access_token,再调用钉钉 OpenAPI 用 authCode 换取用户 unionId |
| 白名单校验 | 校验 unionId 是否在 ADMIN_UNION_IDS 环境变量白名单内;当前为内部系统演示期,配置为 placeholder 时放行任意钉钉账号(可在 Cloudflare 环境变量收紧为指定账号) |
| 签发会话 | 校验通过后用 SESSION_SECRET 以 HMAC-SHA256 签名生成会话 token,写入名为 session 的 HttpOnly Cookie(7 天有效期),返回登录成功 |
| 登录态维持 | 前端后续请求自带 Cookie,/api/me 校验签名恢复登录态;/api/logout 清除 Cookie 登出 |
所需 Cloudflare 环境变量(在 Cloudflare Dashboard → 项目 → Settings → Environment variables 配置):
DINGTALK_APP_KEY:钉钉应用 AppKey(明文)DINGTALK_APP_SECRET:钉钉应用 AppSecret(Secret,加密存储)APP_BASE_URL:站点访问地址,如 https://yxzhfwpt.pages.dev(用于拼接回调地址)SESSION_SECRET:会话签名密钥,任意长随机串(Secret,加密存储)ADMIN_UNION_IDS:允许登录的钉钉 unionId 白名单,逗号分隔;填 placeholder 为旁路模式(放行任意账号)安全机制:state 随机值 + HttpOnly Cookie 防 CSRF;会话 token 用 HMAC-SHA256 签名防伪造;Cookie 设置 HttpOnly 与 SameSite=Lax 防 XSS 窃取;AppSecret 与 SessionSecret 通过 Cloudflare Secret 加密存储,不进入代码仓库。
后台功能模块:
新增产品:点击"新增产品"按钮,在弹出的表单中填写产品信息(带 * 号为必填项),点击"保存"完成添加。
新增资源:点击"新增资源"按钮,在弹出的表单中填写资源信息(带 * 号为必填项),点击"保存"完成添加。
编辑数据:在数据列表中点击对应行的"编辑"按钮,在弹出的表单中修改信息后保存。
删除数据:在数据列表中点击对应行的"删除"按钮,确认后即可删除。删除操作不可撤销。
后台管理第三个 Tab「系统设置」用于配置物流通道地图页所需的两个全局参数。设置保存在浏览器的 localStorage 中,前后台与地图页共享同一份数据。
高德地图 API Key:
检测 API Key 有效性:在 API Key 输入框下方点击「检测」按钮,系统会用一对固定测试坐标(上海→苏州)调用高德 API:
| 检测结果 | 含义 |
|---|---|
| Key 有效(测试路径约 XX km) | Key 可用,显示测试路径距离 |
| Key 无效:<错误信息>(code: XXXX) | Key 不可用,显示高德返回的错误码和说明 |
| 检测失败:网络错误 | 无法访问高德 API,请检查网络 |
线路模式:设置物流通道地图页的默认线路绘制方式(卡片式单选):
保存设置:点击「保存设置」按钮,配置立即生效。地图页刷新后会读取最新设置。
数据存储:所有数据保存在浏览器的 localStorage 中,关闭浏览器后数据不会丢失。但清除浏览器缓存会导致数据重置为初始状态。
数据字段说明:
产品数据字段:
| 字段 | 说明 | 必填 |
|---|---|---|
| 产品名称 | 产品的唯一标识名称 | 是 |
| 产品分类 | 全程物流/海铁联运/陆改水/港口直拖/水水联运(5 大类) | 是 |
| 星标产品 | 是否标注为星标产品(featured: true 时以金色边框+星标突出) | 否 |
| 产品标语 | 产品的一句话描述 | 否 |
| 产品描述 | 产品的详细介绍 | 否 |
| 运营主体 | 负责运营的公司名称 | 否 |
| 服务范围 | 提供的服务类型 | 否 |
| 联系人/电话 | 业务联系人姓名及电话 | 否 |
| 覆盖区域 | 用逗号分隔的服务区域 | 否 |
| 服务特色 | 用逗号分隔的特色标签 | 否 |
资源数据字段:
| 字段 | 说明 | 必填 |
|---|---|---|
| 资源名称 | 资源的唯一标识名称 | 是 |
| 资源类型 | 码头/仓库/铁路站点/堆场 | 是 |
| 所在城市 | 资源所在的城市 | 是 |
| 所在省份 | 资源所在的省份 | 是 |
| 经纬度坐标 | lng(经度)/ lat(纬度),存于 details 内,用于地图视图定位与导出 | 否 |
| 业务权属 | 自有/租赁/合资/公共 | 否 |
| 业务单位 | 负责运营的单位名称 | 否 |
| 地址 | 资源的详细地址 | 否 |
| 联系人 | 业务联系人姓名 | 否 |
| 联系电话 | 业务联系人电话 | 否 |
导出数据:在后台管理的产品管理或资源管理页面,点击"导出"按钮展开下拉菜单,可选择导出格式与范围:
导出文件命名:物流产品_全部.json、物流资源_码头.csv 等,格式与范围一目了然。
行业解决方案是平台的专题板块,针对不同行业的货物特性、合规门槛与交付场景,提供定制化、专业化的物流供应链方案。点击导航栏「行业解决方案」即可进入方案总览页。
三大行业方案:
页面导航:每个方案详情页顶部设有方案切换标签栏,可在三大方案间快速跳转。导航栏与页脚均提供返回平台首页及其他模块的链接。
设计风格:行业解决方案页面采用独立的「蓝金编辑风」设计系统(深海军蓝 + 金色发丝线),与平台主体风格协调统一,同时呈现行业专题的专业质感。
Q:无法扫码登录后台怎么办?
A:登录服务依赖 Cloudflare Pages Functions 后端,必须通过 https://yxzhfwpt.pages.dev 访问才可使用,本地直接打开 HTML 文件无法扫码登录。如二维码不显示或扫码后报错,请检查 Cloudflare 环境变量是否齐全(见第 4 节)。当前系统为内部演示期,ADMIN_UNION_IDS 配置为 placeholder 旁路模式,任意钉钉账号均可扫码登录;如需收紧为指定账号,请将 unionId 写入该环境变量。
Q:数据会丢失吗?
A:数据保存在浏览器 localStorage 中,正常关闭浏览器不会丢失。但清除浏览器缓存或使用无痕模式会导致数据重置。
Q:新增的数据前台看不到怎么办?
A:新增或修改数据后,前台页面会自动刷新。如未显示,请手动刷新浏览器页面。
Q:如何恢复初始数据?
A:在浏览器控制台中执行 localStorage.clear() 然后刷新页面,即可恢复为初始预置数据。
Q:支持手机端访问吗?
A:支持。平台采用响应式设计,可在手机、平板、电脑等设备上正常浏览和使用。
Q:如何关闭弹窗?
A:点击弹窗右上角的关闭按钮,或点击弹窗外的半透明遮罩区域,或按键盘 Esc 键。
Q:物流通道地图页的公路线显示为虚线怎么办?
A:说明未配置有效的高德 API Key,或当前为「模拟线路」模式。请进入后台「系统设置」配置并检测 API Key,并将线路模式切换为「精确匹配线路」。
Q:点击导航栏「物流通道」后弹出系统提示框怎么办?
A:这是 Trae 预览环境的限制(自定义协议无法在 Windows 打开)。代码本身正确,部署到正式服务器后可正常跳转。在 Trae 中可通过「浏览器」工具访问本地预览服务器(参见 start-preview.sh)。