牛牛算账机器人 用 .NET 8 + uni-app 做一套多租户畜牧 SaaS:秦巴牧云踩过的 6 个实战坑
秦巴牧云是一套面向富硒畜牧养殖场的多租户SaaS系统,整体采用「ASP.NET Core 8 + EF Core 8 后
端 + Blazor .NET 8 Web后台 + uni-app Vue3 微信小程序」的典型产业互联网技术栈,重后台管控、
轻微信端触达,落地过程中我们实打实踩过6个高价值密度的核心坑,每一个都对应从架构到细节的可
落地避坑方案。
坑1:多租户隔离差点翻车,绝不能让客户端自选租户
早期差点踩进最危险的写法:直接让前端传租户ID,后端不加校验就直接使用,一旦上线任意客户端都能
越权读取其他农场的牲畜数据。
正确的落地规则是租户身份只从认证上下文取:仅平台级Admin角色允许通过请求头X-Tenant-Id切换租
户,普通用户的租户ID必须100%从JWT令牌里的tid声明读取,完全不接受前端传入的租户参数。同时全
局配置EF Core查询过滤器,把租户隔离和软删除逻辑合并成统一规则,所有业务查询自动带上TenantId
== 当前租户ID的约束,从底层杜绝越权访问的可能。角色层级明确划分:平台Admin权限高于单租户
Owner,所有授权逻辑统一封装成User.IsInRole("Owner") || User.IsInRole("Admin")的通用判断,前端
同步对应IsOwnerOrAdmin标识,彻底避免散落的魔法字符串。
坑2:前后端序列化契约错位,枚举数字比对藏暗坑
后端.NET 8全局配置CamelCase命名策略 + JsonStringEnumConverter,所有枚举默认以字符串形式输出
(比如OnFarm/Cattle),Blazor Web后台直接项目引用后端DTO和枚举定义,字段一致性由C#编译器保证,
天然不会出现错位问题。
但uni-app小程序是JS宽松类型环境,很容易出现“后端改了枚举顺序、前端用数字比对”的隐性Bug,这类
问题不会直接报错,只会悄悄返回错误结果,排查成本极高。我们直接把三条红线写进项目AGENTS.md,让
AI生成代码时也严格遵守:禁止用数字/中文比对枚举,必须用=== 'OnFarm'这类字符串全匹配;禁止私自
修改字段别名,严格对齐后端DTO定义的字段名;decimal类型的金额字段后端以字符串返回,前端必须手动
执行parseFloat转换,避免浮点精度丢失。
坑3:record位置参数DTO序列化后字段名“缩水”
最阴间的一个线上Bug:健康看板的体温点DTO定义为public record TemperaturePointDto(DateTime T,
double TempC),开启CamelCase序列化后,字段名直接变成了t和tempC,完全不是预期的
recordedAtUtc和temperatureC。前端照着业务实体的属性名去读取,拿到的全是undefined,直接导致
体温图高度计算成NaN%、日期标签显示NaN/NaN。
修复方案很简单,但教训要记进流程:所有用于图表、曲线这类单点传输的位置参数record,必须显式给每
个参数加上[JsonPropertyName]特性指定序列化字段名,绝对不能依赖位置参数的默认命名规则,同时要
求前端取数必须严格对照DTO定义的参数名,禁止按业务实体属性名臆测字段。
坑4:uni-app多端兼容,混用平台判断逻辑导致体验分裂
小程序、H5、APP三端差异场景下,早期我们混用了自定义的平台判断代码,结果出现“小程序端正常、
APP端样式错乱”的问题。后续直接定死规则:所有多端差异场景,100%使用uni官方的条件编译#ifdef H5/
#ifdef MP-WEIXIN,完全弃用自定义的平台判断逻辑。
同时配套三条基础兼容铁律:全局统一使用uni-app专属的rpx响应式单位,禁止混用px、rem,避免不同设
备分辨率下布局错乱;通过uni.getSystemInfo()动态获取状态栏高度,适配刘海屏、挖孔屏的顶部导航间距,
避免内容被系统UI遮挡;长列表绝对禁止用原生scroll-view渲染上千条数据,统一使用uni-app内置的uni-list虚
拟列表,只渲染可视区域DOM,彻底解决列表滑动卡顿问题。
坑5:跨端请求封装散落,重复逻辑藏大量隐性Bug
早期页面各自写uni.request请求逻辑,导致token过期处理、网络异常兜底、全局加载状态的逻辑散落各处,
经常出现“请求失败后页面一直卡在loading状态”“token过期后没有自动跳转登录”的问题。
后续统一封装全局uni.request拦截器,统一实现三个核心能力:自动在请求头里携带当前用户的token,全局
统一处理401状态码,token过期时自动跳转登录页;所有请求默认开启全局loading状态,请求结束后自动关
闭,避免重复写加载逻辑;统一封装错误兜底提示,网络异常、服务端报错时自动弹出友好提示,不用每个页
面单独处理。
坑6:.NET EF Core 多租户批量写入触发FullGC雪崩
畜牧场景下经常出现批量导入牲畜数据的高并发写入场景,早期EF Core批量新增时没有做租户级别的上下文隔
离,大量实体对象被跟踪后,内存占用快速飙升,频繁触发FullGC导致接口响应雪崩。
优化方案直接适配你之前关注的.NET FullGC优化经验:多租户场景下每个租户的DbContext独立生命周期,批
量写入前临时关闭实体变更跟踪,用ExecuteUpdate/ExecuteDelete替代全量实体加载操作;批量导入时按每
200条数据做一次批次切分,避免一次性加载上千个实体对象到内存,从根源上降低托管堆的内存压力,彻底解决
高并发写入时的FullGC卡顿问题。
需要我为你补充这套多租户SaaS的uni-app全局请求封装可直接落地的完整代码,复制到项目里就能直接运行吗?
牛牛机器人 / 牛牛算账机器人版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!