← 返回首页系统设计方案使用说明状态与流程OAuth 对接计划未来功能计划

工单中心系统(Work Order Center)

当前版本:1.2.79

景区慢速四轮车现场运维工单的统一接入、分派、跟踪与考核中枢。方案文档见 工单中心系统设计方案.md。

版本记录

版本 内容
1.2.79 .env 新增内置兜底解析:未安装 phpdotenv 时也能读取(系统环境变量优先);CLI 脚本(migrate/诊断)统一使用同一加载器
1.2.78 新增 .env 诊断工具与启动告警(缺少 phpdotenv/文件不可读时提示),README 补充 Linux 部署排查清单
1.2.77 后台退出登录增加二次确认(取消留在当前页,确认后退出)
1.2.76 新建工单所属景点改为必填(前端校验 + 后端 422);建单成功后自动跳转该工单详情页
1.2.75 列表/详情输出所属景点(不再显示位置);待处理/已驳回工单可编辑(含扩展字段,记录编辑时间轴);新建/编辑成功右上角提示;派单按景点匹配
1.2.74 新建工单「所属景点」改为可搜索单选下拉(数据来自景点管理,输入关键字过滤,点击选择,单选替换)
1.2.73 重新应用新建工单景点数据源改动(/api/stations 启用景点全量;修复 /admin/stations 无分页参数只返回 1 条)
1.2.72 修复后台多页面无数据:恢复 v1.2.65 重写派单弹窗时误删的 19 个函数(人员/景点/扩展登录/系统配置/权限节点及分页组件)
1.2.71 (已回滚)新建工单景点数据源调整
1.2.70 详情页操作区显示当前处理人「已派给X ✓」灰色只读按钮;派单/改派成功提示带 ✓,详情自动刷新展示当前处理人
1.2.69 选择接单人弹窗比例调整:宽度 800px、列表最多显示约 3 行(内部滚动),整体更宽扁,接近参考稿比例
1.2.68 「前往派单/改派」选择接单人按设计稿重做:候选人卡片(头像/状态/景点/标签/推荐分)、可派人数与排序说明、底部「取消 / 派给X」;抢单池/转人工指派先输出待实现提示
1.2.67 测试工单种子支持 --append 追加批次;当前已追加一批(测试工单共 66 条)
1.2.66 修复详情页「前往派单/重新派单/改派」无反应:恢复重做弹窗时误删的 assignModal 选人流程
1.2.65 派单/改派二次确认按设计稿重做:人员卡片(头像/状态/景点/推荐分)、技能匹配/在手单/上月 SLA 指标、工单摘要与剩余时限、推荐说明,底部「暂不派单/确认派单」
1.2.64 修复工作台待派工单列表少于统计数:改为服务端按 created+rejected 查询,不再受「最新 50 条」截断
1.2.63 工作台「待派工单」口径与侧栏列表计数一致:待受理 + 已驳回(dispatch_count)
1.2.62 管理员工作台「待处理工单」改为「待派工单」,口径为待受理(尚未派单);列表只展示待派工单
1.2.61 管理员工作台「待处理工单」改为待受理+已派单数量(不再包含处理中/挂起),列表只展示待处理工单
1.2.60 工作台按角色区分:运维人员显示个人指标(待接单/进行中/今日完成/超时临期),隐藏「运维人员工单分布」,卡片标题改为个人视角;管理角色保持全局视图
1.2.59 首页「各类型分布」进度条按工单类型区分颜色(11 种类型各有独立色)
1.2.58 SLA 进度条前增加「响应 / 完成」名称标签,便于区分两条进度含义
1.2.57 工单列表 SLA 改为两条进度条(响应/完成),按已用时长占时限比例填充,超时红色、临期橙色,数值在悬停提示中
1.2.56 工单列表 SLA 列改为「响应 / 完成」:已接单显示响应耗时与已用时间,已完成/已关闭显示响应与完成耗时
1.2.55 侧栏「全部工单」计数改为仅统计待受理+已驳回;各类型入口增加同口径计数(新增 /api/work-orders/nav-counts)
1.2.54 后台「退出」按钮增加退出图标
1.2.53 点击工单消息提示打开详情时,同时将该条消息标记为已读并更新红点/未读数(后台与 H5)
1.2.52 工单类消息的实时提示(右上角 toast / H5 底部提示)支持点击直接打开工单详情
1.2.51 响应时限改为以「接单」计算:派单后仍显示等待,运维接单(开始处理)才记为已响应
1.2.50 工单详情 SLA 显示耗时:响应/完成行显示已用时长与时限,已完成显示总耗时,并展示计时起点
1.2.49 后台接单增加二次确认;新增各类型测试工单种子脚本(33 条,覆盖 8 种状态)
1.2.48 已驳回工单仅管理员可标记完成/关闭(前端按钮与后端接口双重限制);修复 HttpOnly 会话下前端无法建立通知 WebSocket 的问题(改为服务端从握手 Cookie 鉴权)
1.2.47 后台状态操作成功改为右上角弱提示(接单/挂起/恢复/完成/驳回/派单/改派/关闭/取消),不再弹窗打断
1.2.46 顶栏消息入口改为铃铛(红点/未读数在铃铛上,点击弹出消息列表);「刷新权限」从顶栏移至权限节点管理页
1.2.45 新增用户消息中心:新派单/SLA 临期通知,后台与 H5 未读红点与数量、消息列表、实时提示音(系统配置可定制,默认「叮」)
1.2.44 新增 .env 配置:默认配置集中到项目根目录 .env(含 .env.example 模板),引入 phpdotenv 由 webman 启动时加载;景点导入地址改为 SCENIC_IMPORT_URL
1.2.43 类型子入口的折叠箭头按状态显示:收起时向上、展开时向下
1.2.42 「全部工单」下的类型子入口最多显示 5 个,超出可滚动;新增「展开全部(N)/ 收起」按钮,展开状态记忆在本地
1.2.41 侧栏新增「集成」分组:飞书集成、扩展登录从「管理」移入,管理组保留人员/景点/工单类型/权限节点/系统配置
1.2.40 通知 WebSocket 地址改为配置:新增 /api/client-config 下发 notify_ws_url/notify_ws_port,前端不再写死 8789;内部 UDP 地址也可配置(WOC_NOTIFY_*)
1.2.39 远程仓库迁移至 gitee.com/explorer-software/tickethub
1.2.38 移除代码中写死的本机地址:新增 app.url 配置(APP_URL 环境变量,默认按端口推导);OAuth 回调地址与数据初始化改为读取配置,后台自定义值仍优先
1.2.37 调整「API 生成工单」入口位置:从工作台与侧栏移除,改为首页 / 入口卡片(/console/openapi 页面保留可直达);恢复侧栏「派单」组原状
1.2.36 新增「API 请求生成工单」页面(/console/openapi):工作台与侧栏入口,可调试开放接口(创建/查询/更新状态),Bearer Token、JSON 请求体、请求预览、响应回显与 cURL 复制
1.2.35 扩展登录(OAuth2)页面去掉表单区内部滚动条:移除 max-height/overflow,内容按原有长度完整展开
1.2.34 后台列表统一分页(每页 20):人员管理改为服务端分页;权限节点、工单类型、SLA 配置、事件映射接入分页条;超过 20 条才显示翻页
1.2.33 恢复姓名同步:本地姓名随认证中心 nickname 更新(与用户名/手机号/邮箱/角色一同比对,有变化才写库)
1.2.32 OAuth 资料同步不再用昵称(nickname)覆盖本地姓名:仅同步用户名/手机号/邮箱/角色,姓名以工单系统为准(新建账号时昵称仅作初始姓名)
1.2.31 OAuth 资料同步扩展到用户名/手机号/邮箱:登录与刷新权限时比对并更新(有变化才写库),新增 users.email;用户名冲突时保留本地值
1.2.30 权限节点页统计改为一行小字说明(无卡片边框),内容:节点数 · 来源 · 导入方式
1.2.29 权限节点页统计仅保留「本地节点数」,移除顶层/类型/导入方式与 OAuth 状态相关内容
1.2.28 移除对 OAuth 数据库的直连:删除权限同步服务/接口与人员 OAuth 绑定查询;权限节点改由导出 JSON 在 OAuth 后台导入;OAuth 登录按登录名自动关联本地账号
1.2.27 OAuth 登录改为 upsert:本地不存在则新增,存在则按认证中心更新姓名/手机号/角色(不覆盖本地登录名、密码、景点)
1.2.26 修复 OAuth 首次登录自动建档时 users.username 唯一约束冲突(冲突时自动生成唯一登录名)
1.2.25 待派队列增加父级目录 dispatch(派单管理),dispatch:view 挂到其下;同步 OAuth(30 节点)
1.2.24 权限节点支持导出 JSON(嵌套树,可直接导入 OAuth 后台权限导入);权限节点页新增「下载 JSON」
1.2.23 人员列表优化:飞书 open_id 改为「查看 / 复制」(不再整列输出),景点列加宽至可完整展示名称
1.2.22 后台响应式修复:折叠态下窄屏仍两列、顶栏元素溢出被裁;新增 1100/860/560 三档断点与表格横向滚动
1.2.21 修复景点下拉点击无响应:.ts 容器的 overflow 裁剪了绝对定位的下拉列表
1.2.20 景点多选增加下拉按钮(一键展开全部);新增/编辑人员保存后不再弹提示,直接刷新页面
1.2.19 负责景点改为「可搜索标签式多选」:搜索→选中→标签回显,可连续选择、点 × 移除;修复浏览器自动填充污染人员表单
1.2.18 人员管理支持多景点(景点下拉多选、联动景点管理)与登录方式提示修正;新增 user_stations 关联表,派单按多景点匹配
1.2.17 登录支持本地账号(OAuth 改为可选):登录页方式切换、人员管理设置登录名/本地密码、密码哈希隐藏;auto 模式先本地后 OAuth
1.2.16 修复登录页 logo 残留「+」:login.html 引用的 console.css 版本号过期导致命中旧缓存
1.2.15 品牌标识更新:工单纸+勾选新 logo,品牌名「工单中心」,覆盖后台顶栏 / 登录页 / H5 登录页
1.2.14 左侧「工单」类型子菜单补充语义图标(维修=扳手、挪车=箭头、充电=闪电、遇困=警示、采购=购物车等 11 个)
1.2.13 恢复误删的 User::workOrders 关联,修复「前往派单/改派」候选加载失败(withCount 依赖该关联)
1.2.12 代码清理:删除未使用的 import、JS 函数与死常量(如 WorkOrder::STATUSES、User::workOrders 等),消除冗余
1.2.11 新增「未来功能计划」文档(操作审计日志、飞书推送日志与查漏补缺清单、阶段拆解),接入文档导航
1.2.10 首页视觉优化:标题与入口整体居中、入口图标放大(58px)、卡片留白/圆角/阴影更正式
1.2.9 首页仅保留四个入口(文档 / 后台 / 测试 / H5),移除快速建单演示、接口清单、快速上手等页内内容与相关脚本样式
1.2.8 首页改版:文档 / 后台 / 测试 / H5 四个入口卡片;H5 入口以手机外框 + iframe 模拟移动端,可直接操作
1.2.7 修复权限节点页「刷新」与工单类型页「查询/筛选」点击无反应(IIFE 内函数未挂到 window)
1.2.6 权限节点管理页「类型」列改为中文标识(目录 / 菜单 / 按钮)
1.2.5 权限节点层级修正:workorder:list 改为目录(dir),按类型的列表节点挂到其下(workorder:list:{type});权限节点页支持多级缩进
1.2.4 新增后台「权限节点管理」页:查看注册表节点与 OAuth 侧状态(一致/差异/缺失)、一键推送;新增权限码 admin:permissions
1.2.3 H5 动作后返回对应列表(完成→已完成;接单/挂起/恢复/驳回→进行中),不再停留在详情页
1.2.2 H5 动作(接单/挂起/恢复/完成/驳回/取消接单)后立即刷新顶部 Tab 统计,无需手动刷新页面
1.2.1 卡片链接票据有效期改为可配置(飞书集成页新增「卡片链接有效期(小时)」1–168,默认 24)
1.2.0 H5 链接免登:飞书卡片带 24h 一次性票据直达工单详情;票据过期/已用/已转派回落登录并自动跳回;新增权限快照表(OAuth 登录时写入,免登时读取)
1.1.9 工单详情操作按钮按「本人」收敛:接单仅对派单对象显示(后台),H5 底部操作栏仅本人的工单显示
1.1.8 新增 40 条随机演示工单(10 类型 / 6 状态 / 4 来源 / 扩展字段与时间轴完整);修复 SLA 截止时间格式化导致列表出现「NaN」的缺陷
1.1.7 修复详情页返回列表无响应;接单仅限派单对象;派单/改派二次确认与即时提示;飞书推送改异步(WebSocket 右上角结果通知)
1.1.6 飞书工单卡片改版:按优先级配色、展开工单详情与问题描述、字段单行两列排布、分隔线与脚注、接单/查看按钮分组、SLA 文案紧凑化
1.1.5 人员管理列表新增手机号列(便于核对飞书手机号绑定)
1.1.4 飞书集成:后台配置页(凭证/单聊/匹配字段/H5 地址/卡片/通知开关/事件回调)、真实消息发送(tenant_access_token 缓存 + 卡片)、账号按手机号批量绑定 open_id、卡片「接单」事件回调(幂等 + 操作人校验 + AES 解密)
1.1.3 H5 接单端新增「工作台」个人概览页(今日/进行中/待接单/超时临期 KPI、本月 SLA 达成率、近 7 日完单趋势、需关注超时任务、快捷入口)
1.1.2 侧栏图标 + 工单列表条数气泡、状态/处理人下拉筛选、工作台运维工单分布、详情页整页滚动、时长格式 Xh Ym、导航分组空则隐藏、工单类型可配置(独立管理入口 + 按类型列表入口 + 权限节点同步 oauth)、列表类型路径化 /console/work-orders/{type}、类型级权限节点 workorder:list:{type}、OAuth 接口调试页、侧栏收起(仅留图标)
1.1.1 已驳回工单可重新派单/标记完成/关闭、关闭二次确认
1.0.1 H5 接单端、SLA 超时处理等基础能力

提交约定:每次改动完成后提交一个 git 版本;提交说明以当次需求原文为参考,整理为规范描述(一行摘要 + 要点列表,说明改了什么、影响范围),并同步更新上方「当前版本」与「版本记录」;版本号按补丁位递增(1.2.79 → 1.2.80 → …)。提交后推送到远端仓库 origin(git@gitee.com:explorer-software/tickethub.git,main 分支)。

首页入口

/ 为系统入口页,仅保留四个入口卡片(无其他内容):

入口 说明
文档 /docs/plan(方案 / 状态与流程 / OAuth 对接 / 使用说明)
后台 /console(客服工作台、工单列表、派单、管理与配置,需登录)
测试 /console/oauth/debug(OAuth 接口调试;同页可继续进入飞书测试、权限节点等,需登录)
H5 接单端 打开手机样式模拟器:390×800 手机外框内嵌 /m,同源可直接登录与操作;支持刷新、关闭(Esc / 点遮罩)

响应式

技术栈

快速启动

# 1. 安装依赖(需 PHP 8.1+)
composer install

# 2. 环境配置(首次)
cp .env.example .env
# 按实际环境修改 .env(端口 / 数据库 / OAuth / 通知 WebSocket 等)

# 3. 建表 + 默认数据(站点/示例用户/SLA配置/事件映射)
php tools/migrate.php

# 可选:生成各类型测试工单(11 种类型 × 3 条,覆盖待受理/待接单/处理中/挂起/已完成/已关闭/驳回/取消)
php tools/seed_test_orders.php
# 已有测试数据时再追加一批
php tools/seed_test_orders.php --append

# 4. 启动服务(默认 8787 端口)
php start.php start

配置集中在项目根目录 .env(webman 启动时自动加载;系统环境变量优先,.env 不会覆盖已存在的变量):

变量 默认值 说明
WOC_LISTEN_PORT 8787 HTTP 监听端口
APP_URL http://127.0.0.1:8787 系统对外地址(OAuth 回调、对外链接)
DB_DRIVER sqlite sqlite / mysql
DB_HOST / DB_PORT / DB_DATABASE / DB_USERNAME / DB_PASSWORD — MySQL 连接(DB_DRIVER=mysql 时生效)
OAUTH_BASE_URL http://127.0.0.1:8788 认证中心地址
OAUTH_CLIENT_ID / OAUTH_CLIENT_SECRET woc / — OAuth 客户端凭据
WOC_NOTIFY_WS_URL 空 前端通知 WS 地址(完整 ws:///wss:// 或路径,留空自动推导)
WOC_NOTIFY_WS_PORT 8789 通知 WS 端口
WOC_NOTIFY_UDP_HOST / WOC_NOTIFY_UDP_PORT 127.0.0.1 / 8790 内部通知投递地址
SCENIC_IMPORT_URL 内置地址 景点导入接口
SLA_WARN_MINUTES 30 SLA 临期提醒阈值(分钟),剩余不足时通知处理人一次

.env 已被 .gitignore 忽略,不会提交;仓库内提供 .env.example 作为模板。

生产环境切 MySQL:编辑 .env 设置 DB_DRIVER=mysql 及连接信息后执行迁移与启动。

Linux 服务器 .env 不生效排查

webman 仅在 已安装 phpdotenv 且 .env 存在 时加载配置,否则静默使用默认值。按顺序检查:

php tools/check_env.php    # 一键诊断:文件/权限/编码/依赖/解析结果

常见原因:

  1. .env 没上传:.env 在 .gitignore 中,git pull 不会包含,需单独 scp 或复制 .env.example 后修改。
  2. 没执行 composer install:缺少 vlucas/phpdotenv。现已内置兜底解析,.env 仍会生效(建议仍执行 composer install 以获得完整语法支持)。
  3. 文件权限/所有者:运行 PHP 的用户(www-data/nginx 等)需可读 .env(建议 chown 后 chmod 640)。
  4. 系统环境变量优先:webman 使用 immutable 模式,.env 不会覆盖已存在的系统环境变量(systemd Environment=、docker env_file、export)。排查:ps eww <worker-pid> 或查看 systemd/docker 配置。
  5. 未重启:环境文件在进程启动时读取,修改后必须 php start.php restart -d。
  6. BOM / CRLF:Windows 编辑保存可能带 BOM 导致第一行失效,另存为 UTF-8(无 BOM)+ LF。
  7. 路径不对:.env 必须与 start.php 同目录(webman run_path())。

工单状态机

完整状态与流程说明见 docs/状态与流程.md。核心:

created → assigned → processing → pending → completed → closed
created → cancelled
assigned/processing/pending → rejected → assigned(重新派单)/ completed(标记完成)/ closed(关闭)
assigned/processing/pending → created(取消接单,退回待受理)

登录与权限(本地账号 + OAuth 可选)

登录支持两种方式,OAuth 为可选:

方式 说明
本地账号(默认) 人员管理中创建的账号(登录名 + 本地密码,bcrypt 存储);权限来自权限快照,缺省按角色兜底(DefaultPermissions)
OAuth 统一认证 公司认证中心账号(默认 http://127.0.0.1:8788);登录时拉取 RBAC 权限码与角色
注意:本地密码错误时不会回落 OAuth(避免掩盖错误);本地账号未设密码时 mode=local 会明确提示,「auto」则回落 OAuth。

OAuth 登录细节

权限码清单(woc client,oauth 后台可调整):

权限码 覆盖
dashboard 工作台
workorder:list 列表/详情/搜索
workorder:create 新建工单
workorder:assign 分派/转派/分派建议
workorder:process 接单/挂起/恢复/完成/驳回/评论/附件
workorder:close 关闭工单
workorder:cancel 取消工单
dispatch:view 待派单队列
admin:sla / admin:users / admin:stations / admin:events / admin:stats 系统配置各模块

内置角色:admin(全部)、cs_leader(客服主管)、cs(客服)、ops(现场运维);在 oauth 后台为 woc 应用维护权限树/角色/用户分配。

后台控制台(需登录)

浏览器打开 http://<host>:8787/console(默认端口 8787,基于 TicketHub 原型设计系统改造)。

景点管理(独立页)

扩展登录(OAuth2 对接配置,独立页)

「扩展登录」为独立菜单页(/console/oauth,需 admin),参考常见管理后台的扩展登录设计,全部参数后台可配置(存 oauth_settings 表,替代硬编码):

字段 说明
启用 OAuth2 登录 开关;关闭后登录接口返回 403
Callback URL 工单中心回调地址(授权码模式备用)
入口文字提示 登录页副标题文案
Client ID / Client Secret 应用凭据(密钥展示脱敏,留空保存不修改)
协议 / OAuth 服务器 http/https + host:port
Authorize / AccessToken / Resource / Userinfo 路径 各端点路径(默认 /authorize、/token、/token、/userinfo)
权限节点路径(RBAC) 默认 /user-permissions,登录时据此拉取角色与权限节点
登出回调地址 / Scope 登录后 scope 声明

移动接单端(H5)

现场运维使用,浏览器打开 http://<host>:8787/m(手机访问同一地址)。与后台同一套 OAuth2 登录与权限(ops 角色:dashboard / workorder:list / workorder:process)。

超时工单改派(改派后重新计时)

权限节点同步(每次登录 / 进入后台自动更新)

工单中心不缓存过期权限,每次登录都会重新拉取 oauth 权限节点,并在以下时机自动同步:

时机 行为
登录成功 调 /user-permissions 拉取角色 + 权限码 + 权限节点树,写入会话
每次进入后台页面(/console*)或前端初始化(/api/me) 再次拉取,权限变更无需重新登录
令牌临期自动刷新 刷新令牌同时重拉权限
令牌已失效(被撤销/过期未续) 拉取权限失败时自动用 refresh_token 续期并重试一次;refresh_token 也失效则登出回登录页
手动刷新 POST /api/refresh-permissions(后台顶栏「刷新权限」按钮),无需重登

数据可见范围(现场运维隔离)

ops(现场运维)登录后台时仅可见指派给自己的工单:

类型级可见范围(与角色无关,按权限码判定,见「工单列表的类型级权限节点」):无 workorder:list 时,列表、详情、工作台统计一律收敛到已授权的 workorder:list:{type} 类型并集;两者叠加时以更严格者为准(如现场运维 + 仅维修类型权限 → 只看自己的维修工单)。

首次登录自动建档(免手工绑定)

oauth 认证通过但本地 users 表无对应记录时,自动创建本地人员档案(无需管理员预绑定):

飞书内打开的前置条件

  1. 可访问地址:飞书 WebView 需能访问该服务,127.0.0.1 仅本机可用;需以内网 IP 或域名暴露(如 http://192.168.x.x:8787/m),或经网关/nginx 转发
  2. 链接形式:飞书群/机器人消息中发送 http(s)://<可访问地址>/m
  3. 登录:飞书 WebView 无历史会话,首次打开即显示登录页,运维人员输入账号密码后进入任务列表
  4. 免登(可选,需飞书应用):若后续需要飞书免登,需在飞书开放平台创建自建应用 → 获取 app_id/app_secret → H5 内走飞书 JSAPI 取 code → 后端换取 open_id → 与 users.feishu_user_id 匹配后签发会话(当前版本未实现,users.feishu_user_id 字段已就绪)

工单类型管理(后台可配置)

类型不再硬编码,存于 work_order_types 表(后台「工单类型」页维护):

字段 说明
code 类型编码,工单 type 存该值;创建后不可修改(新建时校验 ^[a-z][a-z0-9_]{1,49}$)
name 类型名称(侧栏入口 / 类型卡片 / 列表标签均取此值)
sort 排序(升序,决定侧栏与类型卡片顺序)
enabled 启用 / 停用(停用后不再出现在侧栏入口与新建表单;历史工单不受影响)
fields 扩展字段模板(JSON 数组,见下方 Schema 说明)

列表分页约定

后台所有列表统一每页 20 条:

权限节点管理(/console/permissions,权限 admin:permissions)

独立页面查看与维护权限节点:

oauth 角色层级(认证中心)

认证中心 oauth_roles.parent_id 构成角色树,本系统复用的 woc 接入方当前为:

角色 code 父角色
运营管理员 admin —
客服主管 cs_leader —
客服 cs 客服主管
现场运维 ops 运营管理员

OAuth 接口调试(/console/oauth/debug,权限 admin:sla)

对接认证中心时的排查页(从「扩展登录」页顶部「接口调试」进入),回显原始 HTTP 状态 + 原始响应体 + 耗时(不经过客户端异常封装,失败时也能看到服务端返回内容):

工单类型字段模板(差异化录入)

不同工单类型录入格式不同,由后端 Schema 驱动(app/service/WorkOrderSchema.php):

一键自动派单

POST /api/work-orders/auto-assign(需 workorder:assign):对全部(或指定 ids)待受理工单按「同景点 + 在单负荷」自动派给首位候选,返回成功/失败明细。

接口一览

客服工作台 /api

方法 路径 说明
POST /api/work-orders 建单(type/priority/title 必填)
GET /api/work-orders 列表(status/type/priority/station_id/assignee_id 筛选,分页)
GET /api/work-orders/{id} 详情(含状态日志/评论/扩展字段/SLA)
POST /api/work-orders/{id}/assign 分派(assignee_id, cs_id)
POST /api/work-orders/{id}/status 运维端流转:start/pending/resume/complete/reject/reassign
POST /api/work-orders/{id}/close 客服关闭
POST /api/work-orders/{id}/cancel 取消(创建人可取消;已分派需主管 is_supervisor=1)
POST /api/work-orders/{id}/comment 评论(飞书通知触达)
GET /api/assign-suggestions 分派建议(站点+负荷排序)

车辆平台事件接入 /internal/v1(M2)

方法 路径 说明
POST /internal/v1/events 事件推送自动建单;event_id 幂等;事件→工单映射见 event_configs

外部系统开放 API /open/v1(M3)

方法 路径 说明
POST /open/v1/work-orders 外部建单(type=procurement/after_sales;external_order_no+source_system 幂等)
GET /open/v1/work-orders/{no} 查询工单(Bearer token 鉴权,仅本系统工单)
PATCH /open/v1/work-orders/{no}/status 外部更新状态/进度

认证:Authorization: Bearer <token>,生产环境应复用公司 OAuth2 认证中心校验并映射 external_systems.code(当前为演示映射:factory_ 前缀 → vehicle_factory)。

管理后台 /admin

SLA 配置、人员(含 feishu_user_id)、站点、事件映射、基础报表、工单类型配置(/admin/work-order-types*)、权限节点导出(/admin/permissions/export)。

数据表

work_orders / work_order_status_log / work_order_ext(JSON) / work_order_attachments / work_order_comments / work_order_types / sla_config / event_configs / users / stations / external_systems

后台进程

飞书集成(单聊通知 + 卡片接单)

后台「飞书集成」页(/console/feishu,权限 admin:feishu)维护全部配置,保存即生效:

配置组 内容
凭证 启用开关、App ID、App Secret(密文存储、回显脱敏)、开放平台地址(默认 https://open.feishu.cn,可指向 mock 联调)
接收 通知方式(单聊 open_id / 群 chat_id)、默认群 chat_id、账号匹配字段(手机号)
H5 对外地址(配置后卡片带「查看并处理」按钮,链接形如 {h5_base_url}?order={id};留空则卡片不带跳转)
卡片 按钮文案;通知开关:新单分派 / 转派 / SLA 超时 / 评论
事件 接收卡片回调开关、Verification Token、Encrypt Key(配置后 AES 解密)、回调路径

发送链路

用户消息中心

后台实时通知(WebSocket)

  1. notify_ws_url:完整地址(ws:// / wss://,可含路径)或路径(如 /notify)→ 直接使用/同域拼接
  2. HTTPS 页面:wss://<当前域名>/notify
  3. HTTP 页面:ws://<当前主机>:<notify_ws_port>
location /notify {
    proxy_pass http://127.0.0.1:8789;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
}

H5 链接免登(飞书卡片直达,POST /api/link/login)

卡片上的「查看并处理」按钮不是裸链接,而是带一次性票据的深链:

{h5_base_url}?order=117&t=<ticket>

权限来源(免登没有 OAuth 令牌,无法实时拉权限):

  1. 权限快照(优先):OAuth 登录 / 手动刷新权限时写入 user_permission_cache(权限码 + 角色 + 同步时间)
  2. 角色兜底:无快照时按本地角色给最小可用权限(DefaultPermissions),并记录 [LinkAuth] 无权限快照 警告,提示尽快用浏览器登录一次刷新

安全:票据只对「本人被派单的工单」有效;不自动创建账号;未匹配到用户直接拒绝。

账号绑定

事件回调(卡片内接单)

开放平台需要开通

项 说明
机器人能力 应用 → 添加应用能力 → 机器人
im:message:send_as_bot 以机器人身份发消息
contact:user.id:readonly 按手机号/邮箱反查 open_id(批量绑定)
网页应用能力 + 安全域名 H5 在飞书内打开(可先只打通消息推送,此步与免登一并配置)
事件订阅 card.action.trigger 卡片内接单/操作回调
应用发布 + 可用范围 未发布或成员不在范围时接口成功但收不到消息

自测

后台「发送测试消息」支持填 open_id / 手机号 / 本地用户 ID,结果(时间 / 成功失败 / 原因)显示在「当前状态」卡片;api_base 指向本地 mock 即可在无真实凭证时验证完整链路。

验证记录

完整冒烟测试已通过:建单→分派→接单→挂起→恢复→完成(回填扩展字段)→关闭;驳回→重新分派→转派;取消权限控制;事件自动建单+幂等;外部单创建/查询/状态回传+幂等+401;SLA 超时升级飞书通知。