webman+vue3搭建erp系统需解决后端常驻内存与前端动态路由的契约问题:路由须显式注册(如/api/auth/login),禁用点号分隔;控制器必须return json()并手动校验token;后端/menu/routes返回菜单json,前端用router.addroute()动态生成路由;所有io操作需协程安全,长事务应拆分为异步任务。

Webman + Vue3 搭建企业级 ERP 系统,不是简单拼凑两个技术名词,而是要解决「后端常驻内存模型」和「前端路由/权限动态加载」之间的契约断裂问题。直接套用 ThinkPHP 或 Laravel 的开发习惯,90% 的人会在登录后卡在白屏、404 或 token 失效循环里。
Webman 路由必须显式注册,不能依赖点号分隔
常见错误现象:/admin/user.list 或 /api.v1/user/index 返回 404 —— 这是把 Webman 当成 ThinkPHP 6 多应用模式用了。
Webman 没有自动解析控制器的机制,所有接口路径必须在 app/route.php 中手动声明:
Route::group('/api', function () {
Route::post('/auth/login', [AuthController::class, 'login']);
Route::get('/user/list', [UserController::class, 'list']);
Route::get('/menu/routes', [MenuController::class, 'routes']); // 供前端动态生成路由
});
- 前缀统一用
/api(而非/admin),避免与 Vue Router 的 base 冲突 - 不要在控制器方法里写
echo json_encode(...),必须用return json([...]) - 所有敏感接口(如
/user/list)不带鉴权逻辑就等于裸奔,下一步必须补上 token 校验
Vue3 前端必须自己解析后端返回的菜单结构
ERP 系统菜单层级深、权限粒度细,vue-router 不会自动读取后端 JSON 并生成路由表,必须手动做映射。
后端 MenuController::routes() 应返回标准格式(示例):
[{
"path": "/dashboard",
"name": "Dashboard",
"component": "layout/BasicLayout",
"meta": { "title": "仪表盘", "icon": "home" },
"children": [{
"path": "/dashboard/workbench",
"name": "Workbench",
"component": "views/dashboard/Workbench",
"meta": { "title": "工作台" }
}]
}]
- 前端需在 Pinia store 中调用该接口,并用
router.addRoute()动态注册 -
component字段值必须与src/views/下真实文件路径一致,且需配合defineAsyncComponent懒加载 - 若后端返回的是字符串路径(如
"dashboard/Workbench"),前端必须拼接为() => import('@/views/dashboard/Workbench.vue')
Token 鉴权不能靠中间件“挂载 user”,得每次手动校验
Webman 的 Request 是不可变对象,试图在中间件里写 $request->user = $user 会静默失败。
正确做法是封装一个可复用的校验函数,在每个受保护接口开头调用:
public function list(Request $request)
{
$user = AuthHelper::verify($request);
if (!$user) {
return json(['code' => 401, 'msg' => 'Unauthorized']);
}
// 后续业务逻辑...
}
-
AuthHelper::verify()应从Authorizationheader 提取 JWT,并验证签名、过期时间、角色字段(如role: 'erp-admin') - 不要把用户信息塞进 session 或全局静态变量——Webman 常驻内存,静态变量跨请求污染风险极高
- 前端 Axios 请求拦截器需统一加
Authorization: Bearer xxx,且登录成功后立刻存入localStorage
代码生成器输出需人工适配容器绑定和协程安全
php webman sai:generate 生成的控制器默认按 ThinkORM 风格写,直接运行大概率报错。
- 构造函数注入的 Service 类,必须确认已通过
container()->bind()绑定,否则会提示类未找到 - 涉及 DB 查询、Redis、HTTP 调用的操作,不能直接用同步阻塞方式(如
file_get_contents),应改用Swoole\Coroutine\Http\Client或co::sleep()兼容协程 - 生成的 Model 若含
protected $connection,需检查是否与当前配置的数据库连接名一致(如mysql而非default)
最易被忽略的一点:ERP 系统常有长事务(如库存扣减+财务记账+通知推送),这类逻辑不能放在协程内直接跑完,必须拆成异步任务或消息队列,否则会拖垮整个 Worker 进程。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











