基于若依框架的表单开发实战:从CRUD到动态表单与工作流集成
1. 项目概述为什么选择若依框架来构建表单在后台管理系统的日常开发中表单几乎是每个功能模块的基石。无论是用户注册、数据录入还是复杂的审批流程都离不开表单。但每次从零开始重复编写增删改查、权限控制、数据校验的代码不仅效率低下还容易引入不一致性和安全漏洞。这就是为什么我们需要一个像若依RuoYi这样的开源后台管理系统框架。若依框架提供了一个功能完备、开箱即用的开发平台。它基于经典的技术栈Spring Boot, MyBatis, Vue.js封装了大量后台管理系统的通用功能如用户管理、角色权限、菜单管理、操作日志等。对于“创建一个表单”这个需求若依的价值在于它提供了一套标准化的、从后端接口到前端页面的完整解决方案。你不再需要手动处理表单数据的接收、校验、存储、分页查询和权限拦截框架已经为你搭好了舞台你只需要专注于业务表单本身的字段和逻辑即可。这极大地提升了开发效率降低了维护成本尤其适合需要快速迭代的中小型项目或内部管理系统。2. 核心思路拆解若依框架下的表单开发范式在若依框架中创建一个表单并非简单地画一个前端页面它是一个涉及前后端协同的、有固定模式的开发流程。理解这个范式是高效使用若依的关键。2.1 前后端分离架构下的职责划分若依主流版本如RuoYi-Vue采用前后端分离架构。这意味着后端Java/Spring Boot负责提供纯净的RESTful API接口。核心工作是定义数据模型实体类、编写业务逻辑Service、暴露增删改查接口Controller并确保数据安全和一致性。前端Vue.js/Element UI负责渲染用户界面。核心工作是调用后端API将数据以表单、表格等形式展示给用户并处理用户的交互操作。创建一个表单需要两端同时开工但遵循着“后端驱动前端”的协作模式。通常我们先在后端定义好数据结构和接口前端再根据接口文档或直接查看后端代码来构建页面。2.2 标准CRUD流程与代码生成器若依框架将表单操作抽象为标准的CRUD创建、读取、更新、删除流程。对应到框架的具体实现通常包含以下模块实体类Entity对应数据库表定义表单包含哪些字段。Mapper接口与XML使用MyBatis进行数据库操作。服务层接口与实现Service编写业务逻辑。控制层Controller提供/list查询列表、/add新增、/edit修改、/remove删除等HTTP接口。前端Vue组件包含列表页面通常是表格和表单对话框用于新增和编辑。注意若依内置了强大的代码生成器。这是其核心利器之一。你只需要在数据库中设计好表结构通过代码生成器的可视化界面进行简单配置就能一键生成上述所有后端代码和基础的前端Vue组件。这能将一个简单表单的开发时间从数小时缩短到几分钟。但生成器生成的是通用代码复杂的业务逻辑仍需手动调整。2.3 表单校验的双重保障表单校验是保证数据质量的第一道关卡。若依框架在此提供了双重保障后端校验使用Spring Boot的Validated注解配合JSR-303校验注解如NotBlank,Size,Pattern在Controller层进行校验。这是数据安全的最终防线。前端校验使用Element UI表单组件的rules属性在用户提交前进行即时验证。这提供了更好的用户体验。框架生成的前端代码通常会包含基础的非空、长度等校验规则。对于更复杂的校验逻辑如跨字段校验、异步校验用户名是否存在需要在前后端的业务逻辑中手动实现。3. 从零到一手把手创建一个“产品信息”表单理论说得再多不如动手实操。我们假设要为一个简单的“产品管理系统”创建一个产品信息表单包含产品名称、分类、价格、库存等字段。3.1 第一步数据库设计与实体类映射一切从数据库开始。我们在数据库中创建一张表sys_product。CREATE TABLE sys_product ( product_id bigint(20) NOT NULL AUTO_INCREMENT COMMENT 产品ID, product_name varchar(255) NOT NULL COMMENT 产品名称, category_id bigint(20) DEFAULT NULL COMMENT 产品分类ID, price decimal(10,2) NOT NULL COMMENT 产品价格, stock int(11) NOT NULL DEFAULT 0 COMMENT 库存数量, status char(1) DEFAULT 0 COMMENT 状态0正常 1停用, remark varchar(500) DEFAULT COMMENT 备注, create_by varchar(64) DEFAULT COMMENT 创建者, create_time datetime DEFAULT NULL COMMENT 创建时间, update_by varchar(64) DEFAULT COMMENT 更新者, update_time datetime DEFAULT NULL COMMENT 更新时间, PRIMARY KEY (product_id) ) ENGINEInnoDB AUTO_INCREMENT1 DEFAULT CHARSETutf8mb4 COMMENT产品信息表;注意表名以sys_开头是若依的命名惯例便于区分。字段create_by,create_time,update_by,update_time是若依基础实体类BaseEntity中定义的字段用于自动记录操作审计日志强烈建议保留。接着在若依后端项目的entity包下创建对应的Java实体类SysProduct.java。这里可以直接使用代码生成器来生成但理解其结构很重要。package com.ruoyi.project.system.domain; import com.ruoyi.framework.aspectj.lang.annotation.Excel; import com.ruoyi.framework.web.domain.BaseEntity; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import java.math.BigDecimal; /** * 产品信息对象 sys_product */ public class SysProduct extends BaseEntity { private static final long serialVersionUID 1L; /** 产品ID */ private Long productId; /** 产品名称 */ Excel(name 产品名称) NotBlank(message 产品名称不能为空) Size(min 1, max 255, message 产品名称长度必须在1到255个字符之间) private String productName; /** 产品分类ID */ Excel(name 产品分类ID) private Long categoryId; // 关联的分类名称用于前端显示非数据库字段 private String categoryName; /** 产品价格 */ Excel(name 产品价格) NotNull(message 产品价格不能为空) private BigDecimal price; /** 库存数量 */ Excel(name 库存数量) NotNull(message 库存数量不能为空) private Integer stock; /** 状态0正常 1停用 */ Excel(name 状态, readConverterExp 0正常,1停用) private String status; // 省略 getter/setter 和 toString 方法 }关键点解析继承BaseEntity这自动获得了创建人、时间等审计字段无需在类中重复声明。Excel注解这是若依的特色功能用于配合其提供的“导出Excel”功能。name属性是导出列的标题readConverterExp用于状态等枚举值的转换。JSR-303校验注解如NotBlank,Size。这些注解会在Controller层被Validated触发实现后端校验。categoryName字段这是一个典型的“冗余字段”设计。数据库只存categoryId但前端列表需要显示分类名称。我们可以在查询时通过JOIN语句或后续业务代码将其赋值。这在若依的查询逻辑中很常见。3.2 第二步使用代码生成器快速搭建骨架这是若依框架最高效的环节。登录若依后台进入“系统工具” - “代码生成”。点击“导入表”选择你刚创建的sys_product表。导入后在列表中点击“编辑”进行生成配置。基本信息设置模块名如system、业务名如product、类名SysProduct等。这决定了生成代码的包路径和文件命名。字段信息这里可以调整每个字段在表单中的显示类型输入框、下拉框、日期等。例如将status字段的“HTML类型”设置为“单选按钮”并设置字典类型需先在系统字典中定义sys_normal_disable。生成信息选择模板默认即可勾选需要生成的模块。通常全选Controller, Service, Mapper, 前端Vue。点击“提交”预览生成的代码。确认无误后点击“生成代码”会下载一个ZIP包。解压ZIP包将后端Java代码复制到项目对应源码目录main/java将前端Vue文件复制到前端项目的views目录下例如views/system/product。对于后端还需要手动将生成的SQL菜单文件通常是menu.sql在数据库中执行以在系统菜单中新增“产品管理”的入口。实操心得代码生成器生成的Controller和Vue文件其增删改查接口的URL路径和前端请求路径是自动关联好的。例如列表查询接口路径通常是/system/product/list而前端index.vue中getList方法请求的也正是这个地址。这种一致性避免了手动对接时常见的路径错误。3.3 第三步后端核心逻辑定制与增强生成器提供了骨架但真实业务往往更复杂。我们需要深入定制。3.3.1 处理关联查询与字典翻译在SysProductMapper.xml中我们需要改造列表查询的SQL实现关联查询以获取categoryName并对status字段进行字典翻译。!-- 在 SysProductMapper.xml 中 -- select idselectSysProductList parameterTypeSysProduct resultMapSysProductResult include refidselectSysProductVo/ where if testproductName ! null and productName ! AND p.product_name like concat(%, #{productName}, %) /if if testcategoryId ! null AND p.category_id #{categoryId} /if !-- 其他条件... -- /where /select sql idselectSysProductVo select p.product_id, p.product_name, p.category_id, c.category_name, !-- 关联查询分类名称 -- p.price, p.stock, p.status, p.remark, p.create_by, p.create_time, p.update_by, p.update_time from sys_product p left join sys_category c on p.category_id c.category_id !-- 关联表 -- /sql同时在SysProduct实体类中我们已经定义了categoryName字段及其getter/setter。在Service层我们可能还需要对查询结果进行二次处理比如将状态码0和1转换为“正常”和“停用”。但更优雅的做法是依靠前端的字典翻译功能。3.3.2 实现复杂的业务校验假设我们要求“产品价格不能高于10000且同一分类下产品名称不能重复”。这超出了基础注解的能力范围。首先在SysProductService接口中定义校验方法// SysProductService.java String checkProductUnique(SysProduct product);然后在SysProductServiceImpl中实现Override public String checkProductUnique(SysProduct product) { Long productId product.getProductId() null ? -1L : product.getProductId(); SysProduct info mapper.checkProductNameUnique(product.getProductName(), product.getCategoryId()); if (info ! null !info.getProductId().equals(productId)) { return 已存在同分类下的相同产品名称; } if (product.getPrice().compareTo(new BigDecimal(10000)) 0) { return 产品价格不能超过10000; } return null; }最后在SysProductController的add和edit方法中在调用service.insertProduct或updateProduct之前先调用这个校验PostMapping(/add) public AjaxResult add(Validated RequestBody SysProduct product) { String checkResult productService.checkProductUnique(product); if (checkResult ! null) { return AjaxResult.error(checkResult); } // ... 其他逻辑 return toAjax(productService.insertProduct(product)); }注意事项这种业务校验必须在后端进行。前端校验可以提升体验但绝不能替代后端校验否则极易被绕过造成数据混乱或业务逻辑错误。3.4 第四步前端表单页面的精细化打磨生成器生成的Vue组件是一个功能完备的起点但UI和交互需要根据产品需求调整。3.4.1 表单控件与布局优化打开生成的index.vue找到表单对话框的模板部分通常是一个el-dialog。我们可以优化表单控件el-form refformRef :modelform :rulesrules label-width100px el-row el-col :span12 el-form-item label产品名称 propproductName el-input v-modelform.productName placeholder请输入产品名称 clearable / /el-form-item /el-col el-col :span12 el-form-item label产品分类 propcategoryId !-- 将输入框改为下拉选择框并绑定字典或从接口加载选项 -- el-select v-modelform.categoryId placeholder请选择分类 clearable filterable el-option v-foritem in categoryOptions :keyitem.categoryId :labelitem.categoryName :valueitem.categoryId / /el-select /el-form-item /el-col /el-row el-row el-col :span12 el-form-item label产品价格 propprice el-input-number v-modelform.price :min0 :precision2 :step0.1 controls-positionright stylewidth: 100%;/ /el-form-item /el-col el-col :span12 el-form-item label库存数量 propstock el-input-number v-modelform.stock :min0 :step1 controls-positionright stylewidth: 100%;/ /el-form-item /el-col /el-row el-form-item label状态 propstatus el-radio-group v-modelform.status el-radio v-fordict in statusOptions :keydict.value :labeldict.value{{ dict.label }}/el-radio /el-radio-group /el-form-item el-form-item label备注 propremark el-input v-modelform.remark typetextarea placeholder请输入内容 / /el-form-item /el-form关键调整使用el-row和el-col进行栅格布局让表单更紧凑美观。将分类ID输入框改为下拉选择框(el-select)并通过categoryOptions加载数据这比让用户输入ID友好得多。价格和库存使用el-input-number数字输入组件并设置min、precision精度等属性防止非法输入。状态使用el-radio-group单选框组绑定statusOptions字典数据。3.4.2 数据加载与字典绑定需要在Vue组件的script部分定义categoryOptions和statusOptions并在页面创建时加载数据。export default { name: SysProduct, data() { return { // ... 其他数据 categoryOptions: [], // 分类下拉选项 statusOptions: [], // 状态字典选项 }; }, created() { this.getList(); this.getDicts(sys_normal_disable).then(response { // 获取字典 this.statusOptions response.data; }); this.getCategoryList(); // 加载分类列表 }, methods: { // 加载分类列表的方法 getCategoryList() { listCategory().then(response { // 假设有一个获取分类列表的接口 this.categoryOptions response.rows; }); }, // 表单重置时清空分类选择 resetForm() { this.form { productId: undefined, productName: undefined, categoryId: undefined, price: undefined, stock: 0, status: 0, remark: undefined }; this.resetForm(formRef); }, } };3.4.3 增强前端表单校验规则在data()中定义的rules对象里我们可以添加更丰富的校验规则rules: { productName: [ { required: true, message: 产品名称不能为空, trigger: blur }, { min: 1, max: 255, message: 产品名称长度必须在 1 到 255 个字符之间, trigger: blur } ], categoryId: [ { required: true, message: 请选择产品分类, trigger: change } // trigger 为 change ], price: [ { required: true, message: 产品价格不能为空, trigger: blur }, { type: number, message: 价格必须为数字值}, { validator: (rule, value, callback) { if (value ! null value 10000) { callback(new Error(产品价格不能超过10000)); } else { callback(); } }, trigger: blur } ], stock: [ { required: true, message: 库存数量不能为空, trigger: blur }, { type: integer, message: 库存必须为整数}, { min: 0, message: 库存不能小于0, trigger: blur } ] }实操心得前端rules校验和el-input-number等组件的属性限制如min形成了双重防护但正如前文强调它们只是用户体验的优化。所有关键的业务规则如价格上限、唯一性约束必须在后端接口中不依赖前端地重新校验一遍。4. 进阶探讨动态表单、工作流与常见问题4.1 动态表单的实现思路若依框架本身并未深度集成动态表单设计器但可以通过一些模式来实现“动态”特性。基于数据库配置的渲染在数据库中设计一张表用来存储表单的元数据字段名、类型、标签、校验规则等。前端页面初始化时通过API拉取这个元数据配置然后利用Vue的v-for和动态组件如component :isfield.type动态渲染出整个表单。这需要较强的前后端设计能力。集成第三方表单设计器如搜索热词中提到的ruoyi-vue-plus集成flowable表单设计器或引入form-generator等开源项目。这通常用于需要高度自定义、且与业务流程绑定的场景如OA审批流。集成这类设计器意味着你需要处理表单定义的存储、解析和运行时渲染复杂度较高。对于大多数常规后台系统使用若依代码生成器生成的固定表单在遇到字段变更时重新生成并合并代码可能是更务实和稳定的选择。4.2 表单与工作流的结合若依框架可以与其他工作流引擎如Flowable、Activiti集成实现表单驱动的业务流程。典型场景是请假申请、报销审批等。表单作为流程变量你创建的产品信息表单其数据可以作为流程启动时的变量variables传入工作流引擎。流程状态驱动表单表单的UI或操作如“提交审批”、“撤销申请”按钮会根据当前流程实例的状态如草稿、审批中、已通过来显示或隐藏。若依的角色权限与流程任务结合工作流中的“用户任务”User Task可以指向若依系统中的某个角色或用户。当流程到达该任务时对应的用户登录若依系统后可以在其“待办任务”中看到这个表单并进行审批操作。集成工作流是一个系统工程需要仔细设计流程定义、表单数据模型和权限体系的对接。4.3 常见问题与排查技巧实录在实际使用若依框架创建表单时你一定会遇到下面这些问题。问题现象可能原因排查步骤与解决方案前端列表不显示数据控制台报4041. 后端API路径错误。2. 前端请求的URL与后端RequestMapping不匹配。3. 未登录或Token过期请求被权限拦截器拦截。1. 打开浏览器开发者工具的“网络(Network)”标签查看请求的完整URL和响应状态码。2. 对比前端api文件中定义的URL和后端Controller类上的RequestMapping以及方法上的GetMapping/PostMapping注解。3. 检查请求头是否携带了有效的AuthorizationToken。表单提交成功但数据库没数据1. 后端Service或Mapper层的事务未生效或异常被捕获未抛出。2. 字段名映射错误MyBatis的#{}占位符中的属性名与实体类字段名不一致。3. 前端提交的数据格式不对如日期字符串格式。1. 在后端Controller和Service方法入口和出口打日志确认数据是否传递到Mapper层。2. 检查MyBatis的insert语句中的字段名和#{property}是否与实体类属性名严格一致注意大小写。3. 查看前端提交的payload在开发者工具中确认数据格式。对于日期确保使用yyyy-MM-dd HH:mm:ss格式或时间戳。下拉框Select选项加载不出来1. 加载选项的API接口地址错误或未返回数据。2. 前端v-for循环中:key绑定值或:value绑定值与选项数据结构不匹配。3. 选项数据在created或mounted钩子中没有成功获取。1. 在created或mounted钩子中在调用加载选项的方法前后打console.log或直接在开发者工具“网络”中查看该请求是否发出并成功返回。2. 检查el-option的label和value绑定的属性名是否与API返回的数据结构如{ id: 1, name: ‘分类1’ }对应。3. 使用Vue Devtools检查组件实例的data中选项数组是否已被正确赋值。表单校验规则不生效1.el-form的:rules绑定错误或rules对象未正确定义。2.el-form-item的prop属性值与rules对象中的键名、form对象中的字段名三者不一致。3. 自定义校验函数validator中的callback()未被调用。1. 检查prop的值它必须是一个字符串且与form对象中的字段名、rules对象中的键名完全一致。例如prop“productName”那么rules里必须有productName: [...]form里必须有productName属性。2. 在自定义校验函数中无论校验是否通过必须调用一次callback()。通过时调用callback()失败时调用callback(new Error(‘错误信息’))。编辑表单时数据回显不全或错误1. 编辑时查询详情的API返回的数据字段不全。2. 前端form对象在打开编辑对话框时没有用查询到的数据完整覆盖。3. 某些字段如下拉框绑定的ID与选项列表中的值类型不匹配如字符串 vs 数字。1. 在打开编辑对话框的方法中打印从API获取的详细数据确认是否包含所有需要的字段。2. 确保执行了类似this.form { ...this.form, ...response.data }或Object.assign(this.form, response.data)的操作来合并数据。3. 检查下拉框等组件确保v-model绑定的值类型如数字与选项value的类型一致。必要时使用.number修饰符或进行类型转换。分页查询接口返回的ID精度丢失这是JavaScript处理长整型JavaLong的经典问题。JavaScript的Number类型能安全表示的最大整数是2^53-1约16位而JavaLong可能超过这个值如雪花算法生成的19位ID导致前端接收后最后几位变成0。解决方案在后端将Long类型的ID字段以字符串String的形式返回给前端。可以在实体类的ID字段上添加JsonSerialize(using ToStringSerializer.class)注解Jackson库或者全局配置Jackson序列化规则。这是最一劳永逸的办法。最后再分享一个小技巧若依的代码生成器模板是可以自定义的。如果你团队有特殊的编码规范或者总是需要为实体类添加某些特定的注解、为Service层添加某种通用的缓存逻辑可以修改代码生成器的模板文件位于后端项目的resources/vm目录下。这样每次生成代码都符合团队规范能节省大量后期调整的时间。不过修改前最好备份原模板并充分测试。

相关新闻

113、Zephyr RTOS网络协议栈基础:IPv4与IPv6

113、Zephyr RTOS网络协议栈基础:IPv4与IPv6

Zephyr RTOS网络协议栈基础:IPv4与IPv6 从一次现场调试说起 去年冬天在东北某工厂调试一套基于Zephyr的工业网关,设备上电后能ping通内网服务器,但就是无法通过IPv6访问云端管理平台。抓包一看,路由器RA(Router Advertisement)报文设备收到了,但Zephyr的IPv6栈就是没自…

2026/8/6 8:34:03 阅读更多 →
FortiGate防火墙手动更新IP地理位置数据库:原理、操作与排错指南

FortiGate防火墙手动更新IP地理位置数据库:原理、操作与排错指南

1. 项目概述:为什么需要手动更新IP地理位置数据库?在FortiGate防火墙的日常运维中,IP地理位置数据库(GeoIP Database)是一个看似不起眼,实则至关重要的组件。它就像防火墙的“世界地图”,告诉设…

2026/8/6 8:34:03 阅读更多 →
解决Android构建错误:Could not resolve all files for configuration ‘:app:androidJdkImage‘

解决Android构建错误:Could not resolve all files for configuration ‘:app:androidJdkImage‘

1. 问题现象与初步定位 今天在同步一个老项目的Gradle构建时,遇到了一个挺典型的报错,控制台红字提示: Could not resolve all files for configuration ‘:app:androidJdkImage‘. 。这个错误乍一看有点唬人,特别是对于刚接触A…

2026/8/6 8:34:02 阅读更多 →

最新新闻

Linux性能优化实战:从基础到高级的全面指南

Linux性能优化实战:从基础到高级的全面指南

1. Linux性能优化全景指南:从理论到实践的深度解析作为一位在Linux系统管理领域摸爬滚打十多年的老运维,我见证了无数服务器从卡顿到流畅的蜕变过程。性能优化从来不是简单的参数调整,而是对系统工作原理的深刻理解与精准干预。本文将分享我积…

2026/8/6 10:18:58 阅读更多 →
动态CoVaR模型在金融风险管理中的应用与实现

动态CoVaR模型在金融风险管理中的应用与实现

1. 金融风险测度的前沿方法解析在金融风险管理领域,CoVaR(Conditional Value at Risk)已经成为衡量系统性风险的重要工具。与传统VaR不同,CoVaR能够捕捉金融机构之间的风险传染效应,这对于理解2008年金融危机后金融体系…

2026/8/6 10:18:58 阅读更多 →
ESP32-C3驱动TFT彩屏:RGB565图像转换与显示优化实战

ESP32-C3驱动TFT彩屏:RGB565图像转换与显示优化实战

1. 项目概述:当ESP32-C3遇上TFT彩屏,图像转换是关键桥梁 如果你手头有一块ESP32-C3开发板和一块TFT彩屏,想在上面显示一张漂亮的图片或者自定义的UI界面,你可能会发现第一步就卡住了。直接从电脑里拖一张JPG或PNG图片给单片机&…

2026/8/6 10:18:58 阅读更多 →
Claude Code Skills 实战:把重复任务变成可复用的技能包

Claude Code Skills 实战:把重复任务变成可复用的技能包

你每次让 Claude Code 生成 CRUD,都要重复差不多的 Prompt——“参照 UserController 风格,包含 Entity、Mapper、Service、Controller、DTO,做完跑测试”。这篇文章教你用 Skill 把这套流程固化下来——以后说"为 xx 表生成 CRUD"…

2026/8/6 10:18:58 阅读更多 →
STM32+机智云物联网项目实战:智能风扇系统从电路到云端的全流程开发

STM32+机智云物联网项目实战:智能风扇系统从电路到云端的全流程开发

这类毕业设计项目最值得关注的不是功能列表,而是如何把“智能”、“远程”、“语音”和“物联网”这几个关键词,通过一个具体的硬件平台(STM32)和一个云平台(机智云)真正跑通,并且把电路、程序、…

2026/8/6 10:18:58 阅读更多 →
Linux性能优化:五维观察法实战指南

Linux性能优化:五维观察法实战指南

1. Linux性能优化的核心挑战与破局思路当服务器响应变慢、应用卡顿甚至崩溃时,作为工程师的我们常常陷入"盲人摸象"的困境——CPU飙高就查CPU,内存不足就加内存,这种头痛医头的做法往往治标不治本。我在阿里云处理过的一个典型案例…

2026/8/6 10:17:58 阅读更多 →

日新闻

深入解析LimboAI C++内核:架构设计与性能优化实战

深入解析LimboAI C++内核:架构设计与性能优化实战

1. 项目概述:为什么我们需要深入LimboAI的C内核?如果你是一名使用Godot引擎的游戏开发者,尤其是对AI行为逻辑有较高要求的项目,那么LimboAI这个名字你大概率不会陌生。它作为Godot 4生态中一个备受瞩目的行为树与状态机插件&#…

2026/8/6 0:00:06 阅读更多 →
Unity 2D游戏敌人AI系统:基于PlayMaker状态机与2D Toolkit的实战开发

Unity 2D游戏敌人AI系统:基于PlayMaker状态机与2D Toolkit的实战开发

1. 项目概述与核心思路大家好,我是老张,一个在游戏开发一线摸爬滚打了十多年的老码农。今天咱们接着聊《空洞骑士》风格2D动作游戏的Demo制作。上一期我们搭好了基础框架,处理了角色移动和碰撞,这一期,我们要让游戏世界…

2026/8/6 0:00:06 阅读更多 →
被动防火门市场前景发展趋势

被动防火门市场前景发展趋势

被动防火门依靠材质结构、密闭构造阻隔烟火蔓延,无需电控启动,是建筑被动消防系统核心构件,行业依托新规管控、城市更新、工业安全升级迎来稳定扩容,整体朝着合规化、专项化、低碳化、智能化方向发展。现阶段 GB12955‑2024 新版国…

2026/8/6 0:00:06 阅读更多 →

周新闻

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

1. 从水管网络到最大流:一个核心问题的诞生想象一下,你是一个城市供水系统的总工程师。你的城市有多个水源(水库),需要通过一个复杂的地下管道网络,将水输送到各个居民区。每条管道都有其最大通水能力&…

2026/8/5 15:00:43 阅读更多 →
基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台…

2026/8/5 13:13:56 阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/5 10:20:36 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/5 23:28:39 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/5 21:00:14 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/5 23:46:51 阅读更多 →