信息管理小程序开发平台:配置驱动CRUD快速开发实战

发布时间:2026/10/15 4:31:24
信息管理小程序开发平台:配置驱动CRUD快速开发实战 信息管理类小程序大概是所有小程序需求里最“看起来简单、做起来啰嗦”的一类。客户名单、商品目录、库存台账、拜访记录、预约排班……业务名词换了一茬又一茬底层要的东西翻来覆去就是那么几样一个能分页搜索的列表、一个能增改删的表单、一个能看详情的页面。我见过太多人为了这几个页面加班到深夜也下载过不少标着“含源码”的Demo解压之后发现业务是写死的换个字段就要动七八个文件。这篇要聊的“信息管理小程序开发平台含源码”走的恰恰是另一条路把增删改查沉淀成通用能力新增一个信息模块只需要配置数据模型页面和后端接口都会自动出现。换句话说它给你的不是一只已经炖好的鸡而是一套能持续出菜的厨房。接下来我从平台设计、源码结构、跑通步骤、核心代码和实测踩坑这几个角度把这份源码真正讲透。1. 重复造轮子的信息管理小程序缺的不是代码而是建模能力1.1 信息管理类小程序的“万变不离其宗”只要做过几个小程序项目你一定会发现一个规律所谓信息管理拆开看就是“一堆字段 一个列表 一个表单 一个详情”。客户管理是客户名称、联系人、电话、跟进状态商品管理是商品名称、分类、价格、库存预约管理是客户、项目、时间、备注。字段不一样交互模型几乎一模一样。我把常见场景拉了一张表你对照看看是不是这个道理业务场景常见模块划分共同点客户关系管理客户档案、联系记录、跟进计划列表 搜索 详情 编辑进销存商品目录、供应商、入库单、出库单主从表、单据状态预约服务项目、排班、预约单时间字段 状态流转物业巡检楼栋、设备、巡检任务现场拍照、记录上报这些模块单独看都不难难的是每个都要从零写一遍列表页的加载态、空态、搜索防抖、分页参数、表单校验、删除确认。更难受的是下个需求只是把“客户名称”换成“设备名称”你就得复制一个页面改字段名再处理一遍几乎一样的逻辑。这种重复劳动不是技术问题而是建模问题——你一直在用“写代码”的方式表达“数据结构”却没有把数据结构本身当成可以配置的东西。1.2 为什么说“开发平台”比“业务Demo”更有价值市面上带“含源码”的项目很多但大部分是业务Demo登录怎么做、订单怎么提交、商品怎么展示全是写死的。你拿来学习可以拿来复用就痛苦因为改一个字段牵扯到的文件太多改着改着发现和重写差不多。这份“信息管理小程序开发平台”的价值在于它把信息管理场景里最通用的部分做成了骨架数据模型配置、通用列表页、通用表单页、通用详情页、通用CRUD接口。你要做的新模块只要在配置里告诉它“有哪些字段、字段叫什么、哪些要展示、哪些要搜索”页面和接口就自动有了。我理解它的目标用户有三类一是需要快速交付多个信息管理小程序的人靠配置就能攒出模块二是想把团队开发流程标准化的人新成员不需要理解全部业务也能维护简单模块三是正在学前后端分离开发的学生或转行者这套代码比一堆业务Demo更能帮你理解“元数据驱动”到底是怎么回事。1.3 这个平台的边界能做什么、不能做什么拿到源码先别急着扩展先给平台框个边界。它擅长的是结构化数据的管理单表为主、字段相对固定、交互以增删改查为核心。它不擅长的也很明显复杂审批流、多级联动、实时协同编辑、复杂报表分析。如果你要做一个“进销存”这种带主从表和库存扣减逻辑的系统通用配置层能帮你解决录入界面但库存计算和单据状态流转仍要单独写业务逻辑。我的建议是能用配置解决的模块优先用配置配置撑不住的模块再通过扩展接口或自定义页面补齐。平台的意义不是代替你思考业务而是把你从“写腻了的增删改查”里解放出来让你把时间花在真正有业务价值的地方。2. 平台的样子前后端分离 数据模型配置驱动的整体架构2.1 技术选型小程序端原生服务端 Node.js Express数据库 MySQL拿到源码第一件事先弄明白它为什么选这套技术栈。我根据源码常见的实现方式把这套平台的选型逻辑拆开看端技术选型理由小程序端原生 WXML / WXSS / JavaScript无额外依赖、真机兼容性最好、上手门槛低服务端Node.js 16 Express 4前后端语言统一生态成熟部署简单数据库MySQL 5.7 / 8.0结构化数据强约束事务可靠资料最多可能有人会问为什么不用 uni-app 跨端为什么不用 Java Spring Boot。我的看法是uni-app 确实能一套代码跑多端但调试链路更长插件兼容性问题更多对“信息管理”这种重表单、重交互的场景原生小程序反而更稳Spring Boot 在企业级没问题但对个人开发者和小团队来说太重了一个 CRUD 平台用 Express 这种轻量框架启动快、内存占用低、心智负担小改起来也快。技术选型没有绝对正确关键是匹配场景。这套平台面向的是中小企业信息化、个人工具类小程序、内部管理系统Node.js MySQL 的组合足够覆盖而且前端开发者不用切换语言服务端代码看起来也不费劲。2.2 数据模型配置是如何“长出”业务功能的平台的核心不是路由不是页面而是“数据模型配置”。这个概念也叫元数据驱动或者低代码/零代码的底层思路。简单说它把“表结构”从代码里抽出来变成数据库里的一行行配置记录。整个链路是这样的在 sys_entity 表里注册一个实体比如 customer客户管理在 sys_field 表里配置这个实体的字段比如 customer_name、phone、status小程序端列表页加载这些配置自动渲染表头和搜索栏表单页加载这些配置自动渲染输入控件服务端 CRUD 接口也读取这些配置生成对应的增删改查逻辑。所以新增一个“信息模块”在平台里本质上等于“插入一条实体配置 若干字段配置”剩下的列表、表单、接口、权限都是围绕配置动态生成的。我第一次看明白这个设计时最大的感受是原来“写代码”和“描述数据”是可以解耦的后端接口不再是针对某一张表写死而是针对“任意一张配置过的表”统一处理。2.3 这样设计的得与失配置驱动不是银弹它有自己的成本和边界。先说得的部分新增模块快。客户管理做完再做供应商管理就是复制一套字段配置的事。页面风格统一。所有模块共用同一套列表页和表单页视觉和交互天然一致。Bug 面小。通用逻辑只维护一份修一次全体生效。后续可以长出可视化后台。既然配置都存数据库那做一个 Web 管理界面去操作这些配置只是时间问题。再说代价通用层必须做得足够保守。字段类型、校验规则、搜索逻辑都要抽象成统一模型一旦某个需求超出模型就得给平台开“后门”。复杂关联查询很吃力。涉及多表 join、聚合统计、动态条件组合时通用 CRUD 的 SQL 拼接逻辑会变得很复杂性能也不好控制。配置本身需要设计。字段的 label、type、必填、可搜索、可编辑这些配置项也需要有人去规划不是随意填的。所以成熟的做法是平台提供扩展点。比如注册自定义接口、自定义页面、字段级的事件钩子。通用层做 80% 的场景剩下 20% 用扩展解决这样平台才不会变成新的瓶颈。3. 源码目录里最重要的三张表和三个入口文件3.1 先看目录别一上来就 npm install很多朋友下载源码后第一件事就是 npm install结果报错一堆心情全无。我的习惯是先把目录结构通读一遍搞清楚每个文件是干什么的再动手跑。以下是这套平台常见的目录结构不同版本可能有细微出入以你下载到的源码为准mini-info-platform/ ├── miniprogram/ │ ├── pages/ │ │ ├── index/ # 工作台模块入口列表 │ │ ├── list/ # 通用列表页根据配置渲染搜索/列表 │ │ ├── detail/ # 通用详情页 │ │ ├── form/ # 通用表单页新增/编辑共用 │ │ ├── login/ # 登录页 │ │ └── mine/ # 我的个人信息/退出 │ ├── utils/ │ │ ├── request.js # 请求封装baseURL、token、错误提示 │ │ └── util.js # 格式化、防抖等工具 │ ├── config.js # 接口地址、全局配置 │ ├── app.js │ └── app.json ├── server/ │ ├── routes/ │ │ ├── auth.js # 登录注册 │ │ ├── entity.js # 实体配置读取 │ │ ├── crud.js # 通用增删改查 │ │ └── user.js # 用户信息 │ ├── middlewares/ │ │ └── auth.js # JWT 校验 │ ├── utils/ │ │ └── db.js # mysql2 连接池 │ ├── app.js # Express 入口 │ └── config.js # 数据库/密钥/端口 └── sql/ └── init.sql # 系统表 示例业务表看懂这个结构之后你会发现小程序端的工作量其实很少真正的页面只有 index、list、detail、form、login、mine 六个业务模块都靠配置驱动不需要为每个模块新开页面。服务端的关键是 routes/crud.js 和 routes/entity.js前者是通用增删改查后者是配置读取。3.2 三张系统表sys_user、sys_entity、sys_field 的作用数据库初始化时会建好几张表核心是下面这三张系统表表名作用关键字段sys_user用户表id, username, password_hash, nickname, rolesys_entity业务实体配置id, entity_name, table_name, title, owner_field, statussys_field字段配置id, entity_id, name, label, type, listable, searchable, editable, required, options_json, sort_ordersys_user 不用多说做登录和权限控制。sys_entity 一行代表一个业务模块比如 customer、goods、appointment。sys_field 是这个业务模块的字段定义它决定了列表页显示哪些列、搜索框搜哪些字段、表单页有哪些输入项、哪些字段必填、哪些字段可选。特别注意 options_json 这个字段它用来存 select/radio 类型的候选项比如“跟进状态待跟进、跟进中、已成交”在配置里是一段 JSON 字符串前端解析后渲染成下拉选项。字段类型不一样表单页渲染出来的控件也不一样text 渲染输入框textarea 渲染多行文本date 渲染日期选择器number 渲染数字输入框image 渲染图片上传。3.3 三个入口文件config.js、app.js、request.js跑通项目之前先找到三个入口文件它们是你改动最多的地方。第一个是 server/config.js里面是数据库连接信息、JWT 密钥、服务端口。拿到源码后第一件事就是把数据库账号密码改成你自己的把 JWT_SECRET 从默认值换掉。JWT 密钥是登录态签名的关键用默认值等于把后门开着。第二个是 server/app.jsExpress 的入口文件。它会挂载 body 解析中间件、路由、静态资源、404 兜底。在这里你能看清整个服务端暴露了哪些接口中间件的加载顺序是什么样的排查报错时第一个看它。第三个是 miniprogram/utils/request.js小程序端的请求封装。它统一管理 baseURL、token 注入、响应拦截、错误提示。你本地联调时改的就是这个文件的 baseURL改成 http://127.0.0.1:3000 还是局域网 IP决定了你能不能调通。4. 跑通全流程从空目录到手机里能用的信息模块4.1 环境准备清单跑这套平台之前先把环境准备好避免中途来回折腾组件建议版本作用Node.js16 LTS不低于 14运行服务端MySQL5.7 或 8.0存储数据小程序开发者工具最新稳定版开发/预览小程序Git可选建议装拉取/管理源码Node.js 版本太老会报语法错误Express 4 不太挑版本但 mysql2 连接库对老版本 Node 的兼容性一般所以推荐 16 LTS。数据库安装时字符集选 utf8mb4如果建库时用了默认的 latin1后面存中文会发现乱码排查半天最后才发现是字符集问题太亏了。4.2 初始化数据库init.sql 里到底做了什么数据库初始化很简单两行命令mysql -u root -p -e CREATE DATABASE IF NOT EXISTS mini_info_dev DEFAULT CHARACTER SET utf8mb4; mysql -u root -p mini_info_dev sql/init.sql第一行创建数据库指定 utf8mb4 字符集第二行导入初始化脚本。init.sql 做的事有三件建系统表 sys_user、sys_entity、sys_field插入一个示例实体 customer 及其字段配置插入一个初始管理员账号密码是哈希值源码包里一般会写明初始密码登录后务必改掉。导入完成后可以用下面命令确认表建好了mysql -u root -p mini_info_dev -e SHOW TABLES;你会看到系统表之外还有一张 customer 业务表这张表示例用的。如果后面你通过注册实体新增模块服务端会自动创建对应的业务表前提是 MySQL 账号有 CREATE 权限这个坑后面专门说。4.3 启动服务端完整步骤和第一屏日志服务端启动命令很简单cd server npm install node app.jsnpm install 可能因为网络原因比较慢如果卡住可以换镜像源。启动成功后会看到类似这样的日志Server running at http://0.0.0.0:3000 MySQL connected看到这两行就说明服务端起来了。最常见的两个报错一是 3306 端口连不上检查 MySQL 服务是否启动、config.js 里的账号密码是否正确二是端口冲突3000 被别的进程占了改 config.js 里的 PORT 即可。生产环境我建议用 pm2 管理进程pm2 start app.js --name mini-info-server这样崩溃了会自动拉起重启服务器也能开机自启。4.4 小程序端联调从开发者工具到真机预览服务端跑起来后用小程序开发者工具导入 miniprogram 目录修改 utils/request.js 里的 baseURL就能开始联调。不同阶段 baseURL 的配置完全不一样运行场景baseURL 示例合法域名备注开发者工具调试http://127.0.0.1:3000不需要可勾选“不校验合法域名”最快验证真机预览http://192.168.x.x:3000不需要预览版可用开发环境手机和电脑须同一局域网线上发布https://api.example.com必须配置并校验必须 HTTPS这里有个很容易踩的坑开发者工具里用 http://127.0.0.1:3000 调通了真机预览却白屏。因为在手机上127.0.0.1 指向的是手机自己不是你的电脑。真机预览必须把 baseURL 改成电脑的局域网 IP比如 http://192.168.1.100:3000同时手机和电脑连同一个 Wi-Fi。如果不在同一网段要么内网穿透要么直接把服务端部署到有公网 IP 的服务器上然后走合法域名那条路。5. 通用增删改查的核心代码把CRUD变成配置项5.1 列表接口分页、搜索、用户数据隔离的一次成型平台最核心的文件是 server/routes/crud.js。它不是针对某张表写的而是通用的“任意实体 CRUD”。我们看列表接口的实现思路我把关键代码简化了一下const express require(express); const router express.Router(); const auth require(../middlewares/auth); const db require(../utils/db); // 根据实体名读取配置 async function getEntity(entityName) { const [rows] await db.query(SELECT * FROM sys_entity WHERE entity_name ? AND status 1, [entityName]); if (!rows.length) return null; const entity rows[0]; const [fields] await db.query(SELECT * FROM sys_field WHERE entity_id ? ORDER BY sort_order, [entity.id]); entity.fields fields; return entity; } // GET /api/crud/:entityName?page1pageSize10keywordxx router.get(/:entityName, auth, async (req, res) { const entity await getEntity(req.params.entityName); if (!entity) return res.status(404).json({ message: 实体不存在 }); const { page 1, pageSize 10, keyword } req.query; const where []; const params []; // 数据隔离配置了 owner_field 的实体非管理员只能看自己创建的数据 if (entity.owner_field req.user.role ! admin) { where.push(\${entity.owner_field}\ ?); params.push(req.user.id); } // 模糊搜索只搜配置里 searchable 的字段 if (keyword) { const likeFields entity.fields.filter(f f.searchable); if (likeFields.length) { const likeClause likeFields.map(f \${f.name}\ LIKE ?).join( OR ); where.push((${likeClause})); likeFields.forEach(() params.push(%${keyword}%)); } } const whereSql where.length ? WHERE ${where.join( AND )} : ; const [count] await db.query(SELECT COUNT(*) AS total FROM \${entity.table_name}\ ${whereSql}, params); const [rows] await db.query( SELECT * FROM \${entity.table_name}\ ${whereSql} ORDER BY id DESC LIMIT ? OFFSET ?, [...params, Number(pageSize), (Number(page) - 1) * Number(pageSize)] ); res.json({ code: 0, data: { list: rows, total: count[0].total } }); }); module.exports router;这段代码看起来很普通但有几个关键点值得注意表名和字段名都用了反引号包裹防止保留字和注入问题。值全部走参数化查询不要直接拼 SQL 字符串。搜索只作用于配置里 searchable 的字段而不是把所有字段都 LIKE 一遍否则数据量一大性能就会出问题。owner_field 的自动拼接实现了“用户只能看到自己的数据”这个逻辑对所有实体通用新增实体时只要配置 owner_field 字段就自动获得数据隔离能力。5.2 创建与更新字段白名单与防注入新增接口的精髓是“字段白名单”。前端传什么不是重点重点是这个实体配置里允许写哪些字段。简化代码如下router.post(/:entityName, auth, async (req, res) { const entity await getEntity(req.params.entityName); if (!entity) return res.status(404).json({ message: 实体不存在 }); const payload {}; for (const field of entity.fields) { if (!field.editable) continue; // 必填校验 if (field.required req.body[field.name] undefined) { return res.status(400).json({ message: 缺少必填字段: ${field.label} }); } if (req.body[field.name] ! undefined) { payload[field.name] req.body[field.name]; } } // 自动注入创建人 if (entity.owner_field) { payload[entity.owner_field] req.user.id; } const [result] await db.query(INSERT INTO \${entity.table_name}\ SET ?, payload); res.json({ code: 0, data: { id: result.insertId } }); });这段代码的用意很明显即使有人恶意 POST 一个不存在的字段也会被配置过滤掉。更新接口同理但必须带上 ID 条件并且要校验这条记录的 owner_field 是不是当前用户防止越权修改别人的数据。我用白名单 参数化查询基本堵住了最常见的注入和越权漏洞。5.3 前端列表页和表单页的动态渲染原理前端之所以能做到“新增模块不需要新开页面”核心是页面不关心具体字段只关心配置。列表页的 WXML 里没有写死任何列名而是通过 wx:for 遍历一个columns数组view classlist-header view wx:for{{columns}} wx:keyname classcol-{{index}} {{item.label}} /view /view view classlist-row wx:for{{list}} wx:keyid view wx:for{{columns}} wx:keyname classcol-{{index}} {{item.type select ? formatSelect(row[item.name], item.options) : row[item.name]}} /view /viewcolumns 的数据来自/api/entity/:entityName接口它读取 sys_field 配置后返回 name、label、type、options 等信息。页面加载配置后再去请求列表数据然后渲染。新增或编辑时表单页根据 field.type 决定渲染什么控件text 是输入框textarea 是文本域date 是日期选择器select 是下拉选择image 是上传组件。这样做的好处是以后新增模块你只需要配数据不需要碰页面代码。代价是动态渲染一个表单字段时要记得给 dataForm 里每个字段初始化默认值如果字段很多setData 的数据量会偏大建议对 columns 做裁剪列表只取 listable 的字段表单一次只渲染当前分组的字段。5.4 用配置实现一个“客户管理”模块要改哪几处假设现在要新增一个“客户管理”模块在配置驱动下你只需要做两件事第一往 sys_entity 插入一行配置entity_nametable_nametitleowner_fieldcustomercustomer客户管理create_by第二往 sys_field 插入字段配置namelabeltypelistablesearchableeditablerequiredoptions_jsoncustomer_name客户名称text1111nullcontact联系人text1010nullphone联系电话text1010nullstatus跟进状态select1111[待跟进,跟进中,已成交]remark备注textarea0010null插入完成后如果 customer 业务表不存在服务端注册实体时会自动建表。小程序端重新进入工作台就会出现“客户管理”入口点进去就是完整的列表、搜索、新增、编辑、详情、删除功能。整个过程不需要写一行业务代码这就是配置驱动的直观体验。6. 同一份源码不同的坑我的实测踩坑记录6.1 开发者工具正常、真机白屏域名白名单问题这个坑我几乎每次联调都会遇到新手最容易卡住。现象是开发者工具里页面正常加载数据也能请求到但手机扫码预览后白屏或者接口全部报错。排查思路先看控制台报错如果提示 “request:fail”基本就是网络请求没到达服务器。确认 baseURL 是不是写的 127.0.0.1 或 localhost在手机里这两个地址指向手机自己。把 baseURL 改成电脑局域网 IP确认手机和电脑在同一 Wi-Fi 下。如果手机还是连不通检查电脑防火墙有没有放行 3000 端口Windows 经常会拦截。另外正式发布时要求 HTTPS 和合法域名本地“不校验合法域名”这个选项只能在开发者工具里用真机预览不一定生效。最稳妥的方案是本地开发用开发者工具 127.0.0.1真机体验用内网穿透或局域网 IP正式上线走配置好的 HTTPS 域名。6.2 数据库的 DDL 权限与连接池这个坑藏得很深。平台的核心是“注册实体时自动建表”这在本地开发没问题但部署到某些虚拟主机或云数据库时业务账号可能只有 DML 权限没有 CREATE/ALTER 权限。结果就是配置实体的时候接口报CREATE command denied数据库里查不到业务表。解决办法有两类一是给数据库账号补上 DDL 权限适合自建服务器二是把建表动作从应用里拆出来把平台要用的业务表提前在 init.sql 里建好应用运行时只做 DML。生产环境我推荐后者更可控也符合最小权限原则。再说连接池。默认配置里 mysql2 连接池的 max 可能写得比较大比如 50。想象一个场景小程序端每个页面加载都要请求配置接口和 CRUD 接口如果连接池瞬间把 MySQL 的连接数拉满数据库会直接报Too many connections。我实际测试下来的经验是中小型项目连接池 max 设置在 10 到 20 之间足够了连接池是复用连接不是并发线程池开太多反而浪费数据库资源。6.3 日期时间字段的格式陷阱信息管理模块里几乎都离不开日期预约时间、生日、创建时间、到期时间。这里有两个坑第一个是 MySQL 的 TIMESTAMP 和 DATETIME 选择。TIMESTAMP 的范围是 1970 年到 2038 年如果你做的是会员生日、历史档案这类要存过去日期的功能建议统一用 DATETIME。DATETIME 没有时区转换逻辑存什么就是什么对大多数单机部署的应用来说更省心。第二个是前端日期组件的兼容性。小程序原生的 picker 组件date 模式要求 value 格式必须是YYYY-MM-DD但在部分 Android 机型上如果你用new Date()去构造日期得到的结果可能是Invalid Date。我踩过的坑是后端存的日期是2024-05-01 10:30:00前端直接用这个字符串去初始化 pickeriOS 正常Android 白屏。解决方式很简单前端做一次格式化只取年月日部分拼成YYYY-MM-DD再传给 picker。6.4 并发编辑导致数据被覆盖平台自带的更新接口是“读出来改完再保存”没有版本控制。两个人同时打开同一条客户记录A 改了电话先保存B 改完备注再保存B 保存时会把 A 的修改覆盖掉。这在团队协作场景里是致命的。解决办法是加乐观锁。业务表加一个version字段默认值是 1。更新时 SQL 写成UPDATE customer SET phone ?, version version 1 WHERE id ? AND version ?;如果更新影响的行数为 0说明这条记录已经被别人改过了接口返回“数据已被他人修改请刷新后重试”。前端拿到这个提示后刷新列表或详情让用户重新编辑。这个改造不复杂但能避免绝大多数“数据莫名其妙消失”的投诉。7. 如果让我继续改造这个平台我会从这三件事开始7.1 可视化配置后台让运营同事自己建模块平台目前的配置入口是数据库表只有懂 SQL 的人能操作。要让它真正成为一个“平台”下一步应该做一个 Web 管理后台左边列出所有实体右边展示字段配置支持新增实体、拖拽调整字段顺序、配置必填和搜索项。后端接口其实早就准备好了操作 sys_entity 和 sys_field 就是普通的增删改查。前端用 Vue 或 React 写一个简单的表格页 表单页就能搞定。这个后台做完之后业务人员自己就能建模块开发者的工作只剩“查缺补漏”。7.2 补上导出与基础报表信息管理系统的用户有个共性数据录进去之后一定要导出来。Excel 是他们最熟悉的消费方式。目前平台的列表接口是分页的不适合直接导出需要加一个导出接口GET /api/crud/:entityName/export?typecsvkeywordxx服务端用流式输出 CSV前端列表页加一个“导出当前筛选结果”按钮把当前搜索条件传给导出接口下载文件。数据量不大可以直接一次性导出数据量大就做成异步任务生成文件后通知用户下载。报表可以做能力扩展在实体配置里加一个统计字段的配置前端配合图表组件画柱状图、饼图对信息管理类系统来说“每周新增客户数”“各状态订单占比”这类统计很常见也很有价值。7.3 多租户隔离从 owner_field 到 tenant_idowner_field 解决的是“用户只能看自己的数据”但对 B 端场景还不够一个企业有 10 个员工他们需要共享企业内的客户数据同时不同企业之间的数据要隔离。这时候就要引入租户维度。具体改造思路给 sys_entity、sys_user、所有业务表都加一个tenant_id字段服务端在写入数据时自动注入当前用户的 tenant_id查询时自动拼接tenant_id ?条件。索引也要加上tenant_id 和 create_by 的联合索引基本能覆盖绝大多数查询。这个改造不复杂但要注意所有接口的 SQL 都要统一走这个约束漏掉一个就是数据越权。如果你只有几个内部团队使用可以做简化版把 tenant_id 的配置做成可选不填就退化成现在的 owner_field 模式填了就启用多租户隔离。最后说点务虚的体会这套“含源码”的信息管理小程序开发平台能跑通只算入门真正考验人的是理解它的设计边界。我拿它改造时最大的收获不是省下的那几天开发时间而是养成一个习惯接到一个新需求先想“这个模块能不能用配置描述出来”而不是直接动手建表写接口。把数据结构定义清楚把字段清单列明白剩下的增删改查其实是水到渠成的事。你手上的源码可能跟我在文中描述的有细节出入但思路是通的——通用的骨架加上配置化的扩展点足够你应对大部分信息管理类的小程序需求。下载源码之后先把架构和配置表吃透再动手加模块你会少踩很多坑。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询