快速回顾
| 项目 | 内容 |
|---|---|
| 业务模块 | 农机资产、作业任务、维保管理、成本管理、经营分析 |
| 租户模型 | 组织作为租户,单数据库共享业务表,通过组织字段和应用层权限隔离 |
| 认证与授权 | Spring Security、JWT 建立身份;业务层检查成员关系、角色、数据范围和状态 |
| 权限判断 | 身份有效 + 成员有效 + 操作权限 + 数据范围 + 业务状态允许 |
| 查询与写入 | 同时限定资源 ID 和组织范围,按需附加成员范围及状态条件 |
| 异步与 Agent | 恢复发起人上下文,实际执行前重新校验,通过业务 Service 执行 |
面试主回答
我参与了资产、作业、维保、成本和经营分析等后端模块,使用 Spring Boot、MyBatis 和 MySQL 实现接口、状态流转及统计查询。这些能力也通过业务 Service 提供给智能体工具,确保 Agent 与普通接口遵循相同规则。
多租户以组织为单位,采用共享表和应用层组织隔离。Spring Security 与 JWT 负责登录认证,业务层结合有效成员关系、角色、数据范围和资源状态完成授权。角色决定能做什么,数据范围决定能操作哪些记录。
查询和更新都限定组织范围,详情、导出、下载和批量操作同样校验。后台任务和 Agent 执行时恢复发起人上下文,并在实际操作前重新检查权限,避免任务创建后撤权或资源变化造成越权执行。
业务划分
面试回答
我围绕农机运营流程划分资产、作业、维保、成本和经营分析模块。资产模块维护机型与具体设备,作业模块管理任务和资源安排,维保模块处理维修保养流转,成本模块管理单据与审核,经营分析按统一时间和组织口径汇总数据。
接口层由 Controller 接收请求,Service 组织业务和校验,MyBatis 完成持久化。跨模块通过公开 Service 协作,比如调度时检查设备状态、已有任务和维保占用,不直接改其他模块的表。这样普通接口和 Agent 都能复用同一套权限、状态流转和资源规则,模型提出方案后仍由后端判断能否执行。
实现细节
模块职责与主要规则见表。资产档案与标准机型区分,统计按有效业务记录和时间口径汇总;跨模块调用不能绕过对方业务状态与数据范围检查。
| 模块 | 主要职责 | 需要处理的规则 |
|---|---|---|
| 农机资产 | 维护机型、具体设备档案及关联信息 | 资产归属、生命周期、可调度状态 |
| 作业任务 | 创建任务、安排设备与执行人、记录执行情况 | 资源可用性、时间冲突、任务状态 |
| 维保管理 | 保养计划、维修工单、检查与复机验收 | 工单流转、维修期间的设备使用限制 |
| 成本管理 | 成本单据、明细、提交与审核 | 单据状态、审核权限、统计口径 |
| 经营分析 | 汇总作业、维保和成本数据 | 组织范围、有效记录和时间口径 |
租户与权限设计
面试回答
我们以组织作为租户,采用单数据库共享业务表,通过组织字段和应用层授权隔离数据。每个组织有自己的成员、设备、作业、维保和成本记录,用户在当前有效组织内查询和操作,知道其他组织的资源 ID 也不能访问。
同时区分平台公共资料和组织私有数据。标准机型、公共知识按规则共享,组织资产和私有知识只在授权范围内开放。服务端会核对当前成员关系与数据范围,不能直接相信请求里填写的组织 ID。平台管理员承担平台治理,也不会因为拥有平台角色就自动获得所有组织的业务明细。
实现细节
组织隔离只是第一层,同一组织内部还可能存在成员或任务分配范围。公共标准机型与组织具体资产分别建模,避免把公共读取能力扩大成组织业务访问权。
面试回答
JWT 用来携带可验证的登录身份,Spring Security 校验签名和有效期、建立认证上下文并控制请求入口。进入业务层后,还要检查账号和当前组织成员关系、角色操作权限、资源数据范围以及业务状态。
所以令牌有效只能证明登录凭据仍有效,不能代表用户当前仍有全部业务权限。比如用户登录后被移出组织,后续操作会按当前成员关系拒绝;用户在请求中切换组织,也要由服务端重新确认成员资格。查询和写入最终都基于经过验证的上下文限定范围,避免只在登录时检查一次权限。
实现细节
检查次序为身份、账号及有效成员关系、操作权限、资源归属与数据范围、业务状态,最后执行。令牌内容和客户端传入的 organizationId 均不能独立替代当前业务授权。
| 环节 | 职责 | 不能替代的检查 |
|---|---|---|
| Spring Security / JWT | 校验签名、有效期并建立请求身份 | 不能仅凭令牌有效就认定业务授权 |
| 成员与角色 | 检查当前组织成员关系及操作权限 | 仍需检查具体资源范围 |
| 资源与状态 | 核对归属、数据范围和当前业务状态 | 写入时按需附加预期状态并检查影响行数 |
面试回答
角色权限决定用户能进行哪类操作,数据范围决定这次操作能作用于哪些记录。比如农机手具备执行任务的权限,但只能处理分配给自己的任务;维保员可以处理工单,也只能访问授权范围内的工单。
之后还要检查业务状态。即使用户有权限、资源也属于本组织,已经结束且不允许修改的工单仍然不能更新。因此一次操作要同时满足身份与成员关系有效、具有操作权限、记录处于数据范围内、当前状态允许,不能只凭一个角色名称就放行。
实现细节
操作权限、记录范围、状态规则和当前成员关系的区别见表。组织成员身份不意味着可以读取本组织全部记录,平台角色也不自动授予组织私有数据访问权。
| 检查层次 | 回答的问题 | 例子 |
|---|---|---|
| 角色权限 | 能做什么操作 | 能否处理维保工单 |
| 数据范围 | 能对哪些记录操作 | 仅授权或分配给自己的工单 |
| 业务状态 | 这条记录现在是否允许操作 | 已结束且不允许修改的工单拒绝更新 |
| 组织成员关系 | 当前是否仍属于该组织 | 被移出组织后旧 JWT 不授予原权限 |
面试回答
资源状态校验放在业务 Service 中,与权限检查分别执行。比如修改维保工单,先确认用户有权操作且工单在授权范围内,再判断它当前是否处于允许修改的状态,已经结束的工单不能因为用户有权限就继续改。
对于检查后可能发生并发变化的操作,实际更新时还会带上预期状态,并检查影响行数。如果其他请求已经推进状态,当前更新就不能继续当作成功,需要返回状态已变化的结果。这样避免只在写入前查一次状态,随后被其他请求修改,却仍然按旧判断执行。
实现细节
状态条件与资源 ID、组织范围共同进入需要保护的更新语句。更新影响零行时,不能直接返回成功,需要结合资源与状态检查说明原因;权限和状态各自负责不同约束。
查询、写入与执行边界
面试回答
我把服务端验证过的组织和数据范围带进实际查询与更新条件。查详情时同时限定资源 ID、组织和有效状态,必要时再限定任务分配或成员范围;写入时同样带组织范围和所需的预期状态,并检查影响行数,避免查询有校验、更新却只按主键。
这套限制也覆盖导出、附件下载、统计和批量操作,不能只保护列表接口。批量请求逐项确认资源是否属于当前范围,请求里填写其他组织 ID 不能扩大权限。Agent 和异步任务调用业务 Service 时也复用这些规则,确保入口变了,资源边界仍然一致。
实现细节
下面的 SQL 展示资源、组织与状态条件如何进入实际读写。organizationId 来自服务端验证的上下文,不能由模型或客户端自报决定;批量请求不能只验证其中一个 ID。
SELECT ...
FROM machinery_assets
WHERE id = #{assetId}
AND organization_id = #{organizationId}
AND deleted = 0;
UPDATE ...
SET ...
WHERE id = #{resourceId}
AND organization_id = #{organizationId}
AND status = #{expectedStatus};
面试回答
创建任务时会保存发起人、组织和资源标识。HTTP 请求结束后,原线程的登录上下文不能长期代表后台执行权限,所以 Worker 真正执行时会重新加载有效身份与成员关系,建立本次执行上下文,再调用业务 Service。
Agent 也是模型先提出工具和参数,工具执行器校验用户范围,Service 再检查权限和业务状态。任务创建后如果用户被撤权、成员停用,或者设备状态发生变化,就按执行时的当前事实处理。人工确认只表示接受某份方案,不能替代权限校验,模型填写其他组织 ID 也不能越权。
实现细节
模型调用、后台任务和普通 HTTP 请求最终进入相同业务边界。任务记录保存执行主体,恢复时重新验证;执行前同时检查草案确认、设备状态和资源冲突。
易混点与回答检查
易混点:JWT 有效不等于业务授权有效;人工确认不替代权限与审批;平台身份不自动获得组织私有数据。
回答检查
补充记录
简历表述:负责农机资产、作业任务、维保、成本及经营分析等后端模块;基于 Spring Security、JWT 和组织/角色/成员范围实现隔离与访问控制。
事实 / 代码依据:待补充。