news 2026/10/20 7:37:17

OA系统请假审批待办列表的SQL查询设计与优化

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OA系统请假审批待办列表的SQL查询设计与优化

我一直觉得,在OA系统这种内部管理系统里,审批功能做得好不好,直接影响整个公司的工作效率。尤其是像请假这种高频业务,几乎每天都有员工在提,审批人也在天天点。这篇继续讲我们的OA系统系列,具体说说【请假审批】这个内嵌界面里的核心逻辑,尤其是底层的待审批数据SQL该怎么写、怎么写才不容易出问题。

很多刚接触OA开发的同事容易把"待审批列表"想简单了,认为无非就是select * from leave_request where status = 审批中。但实际等你理清审批流、数据权限、历史归档之后会发现,一个看起来不起眼的待办清单,背后其实是一个精巧的组合查询。

这一篇主要解决三个问题:审批功能在整个OA系统里的定位、待审批数据的业务定义和权限边界、以及最终落到SQL语句时的具体写法。我会把表结构也一并给出,结合真实的开发场景说明每一步为什么这么设计。

1. 审批功能在OA系统里到底解决了什么问题

1.1 为什么说"待审批列表"是整个审批流的入口

请假审批这个功能,从用户视角来看,其实就三个入口:员工提交请假单、审批人查看待办并处理、申请人回看审批进度。而这其中,审批人的"待办列表"又是使用频率最高、最容易出性能瓶颈的地方。

你站在审批人的角度想一下:每天一打开OA,第一件事就是看一眼"有没有需要我批的"。这个列表如果查询慢、数据不准、权限混乱,审批人第一反应就是系统不行。所以,待审批数据的查询,表面上看只是几个SQL语句的事情,但从系统架构来说,它是审批流的门面。

从流程角度说,一个完整的请假审批流大概分三段:

  1. 申请阶段:员工填写请假类型、起止时间、天数、原因,提交后生成一条请假单。
  2. 流转阶段:系统根据预设的审批规则,把这条单据推给对应节点的审批人。审批人可以是直属上级、部门主管、人事专员等,甚至可能有多级审批。
  3. 归档阶段:所有节点都处理完后,单据变成"已通过"或"已驳回",进入历史存档,不再出现在任何人的待办列表里。

所以,待审批数据在系统层面就是一个"过程态"数据,要查询它,就必须把流转阶段中那些"当前节点轮到我处理"的单据捞出来。

1.2 待办清单、已办清单、我发起的,为什么不能混在一起查

我在给某企业做OA系统梳理时,发现很多开发人员容易把三种列表数据搅在一起,SQL里一个status字段走天下。但其实三种列表的业务语义是完全不同的:

  • 待办清单:我作为审批人,有哪些单子需要我现在处理。条件是:流程没结束、节点轮到我、我还没动作。
  • 已办清单:我处理过的所有历史单据。条件是:我在某个节点做过通过或驳回动作,单据流转进入下一节点或结束。
  • 我发起的:所有我提交的单据,无论当前在哪个节点、什么状态。条件只看申请人和单据状态。

这三种列表如果混在一个逻辑里处理,会导致两个问题:一是SQL里到处是if else分支极难维护;二是查询性能很难优化,因为不同列表侧重的维度和索引都不一样。

我们这次设计的【请假审批】内嵌界面,严格把待办清单独立出来。标题里提到的"待审批请假数据"就是这一部分,它的SQL也会单独隔离出来,不跟已办、我发起的混在一起。这样从根上避免了后续改一处崩三处的问题。

2. 待审批数据的业务定义:别再用"状态字段模糊查询"糊弄自己

2.1 一条数据称得上"待审批",必须同时满足三个硬条件

我们在设计SQL之前,先把业务定义定清楚。所谓"待审批请假数据",就是一条请假单满足下面三个条件:

  1. 单据当前处于"审批中"状态,而不是草稿、已通过、已驳回。这一条对应请假单主表的status字段。
  2. 单据当前流转到的审批节点,恰好包含"当前操作人"这个人。注意,这里不一定是单人,可能有多个审批人并行处理,比如"部门负责人"这个角色下有三个人,那这三个人都应该看到这条待办。
  3. 当前操作人在这个节点上还没有做任何动作。也就是说,在审批记录表里,这条单据针对这个审批人的最新记录是"待审批"状态,而不是"已通过"或"已驳回"。

这三条缺一不可。我见过不少项目只判断了第一条和第三条,忽略了第二条,结果就是审批人A可以看到B的单据,或者某单据从第二个节点退回到第一个节点后,第一个节点的人看不到这条单。

这里我把三个条件再拆细一点,后面写SQL的时候会对应上:

条件对应字段/表说明
单据处于审批中请假单主表status只有审批中状态的单子才需要被处理
当前节点包含操作人审批记录表approver_id候选审批人才能看到这条待办
操作人还没有审批动作审批记录表action = 待审批动作是0或1由具体设计决定,但要有这个区分

2.2 权限边界:A部门主管看不到B部门的请假单

待审批数据还有一个躲不开的问题,就是数据权限。同样是"审批人"角色,A部门主管和B部门主管能看到的待办范围完全不同。如果OA系统是集团级别的,还涉及多公司、多组织层级的数据范围。

我们把权限边界分成了三种级别:

  1. 本人级:只能看到自己提交的单据。申请人查询自己的单子时用。
  2. 部门级:能看到本部门所有员工的单据。部门主管审批时,范围限定在自己部门内。
  3. 角色级:比如人事专员、总经理,可以看到全公司所有相关单据。

在待审批SQL里,权限过滤通常不是叠加在approver_id上,而是叠加在"申请人所属部门"上。比如部门主管要看到本部门的请假单,SQL里就需要额外加一个部门过滤条件:lr.dept_id = 当前用户的部门ID。如果不加这个条件,一个主管就能看到全公司所有人的待办,这绝对是事故级别的权限漏洞。

另外,这里我建议不要直接在SQL里用dept_id做硬编码,最好从用户上下文里取。一般来说系统都会把当前登录人、所属部门、角色列表放到一个上下文对象里,SQL参数直接传进去就行。

2.3 为什么不能只用status字段做过滤

有些开发人员会把待办逻辑简化成:WHERE status = '审批中'。这样做的隐患我在实际项目里见过不止一次。原因很简单:status描述的是"单据整体的生命周期状态",但它不包含"当前流转到哪个节点"和"谁应该处理"这两个关键信息。

举个例子,一张请假单是三级审批,当前已经过了第一级部门主管,正在等第二级总监审批。此时单据的status是审批中没错,但对部门主管来说,这张单已经处理过了,不应该再出现在他的待办里。如果只查status,部门主管会一直看到这张单,直到流程完全结束。

所以,要精确判断"我是否需要处理这张单",必须把单据状态和审批记录结合起来,通过审批记录定位到"当前节点是否有我的记录、我的记录是不是待审批状态"。

这个理解是整个待审批SQL的核心,也是标题里说的"显示【待审批请假数据】的SQL语句"之所以要单独拎出来讲的原因。它不是一个简单的主表查询,而是一个涉及业务主表、审批记录表的联合条件查询。

3. 支撑待办查询的三张表与字段设计

3.1 请假单主表:业务数据的唯一载体

写待办SQL之前,表结构是绕不开的。我们这边用的是三张核心表:请假单主表、审批记录表、审批流程配置表。先看请假单主表,字段大致如下:

CREATE TABLE `leave_request` ( `id` bigint NOT NULL COMMENT '请假单ID', `request_no` varchar(32) NOT NULL COMMENT '申请编号,如QJ20250101001', `user_id` bigint NOT NULL COMMENT '申请人ID', `dept_id` bigint NOT NULL COMMENT '申请人所属部门ID', `leave_type` tinyint NOT NULL COMMENT '请假类型:1事假 2病假 3年假 4调休', `start_time` datetime NOT NULL COMMENT '请假开始时间', `end_time` datetime NOT NULL COMMENT '请假结束时间', `total_days` decimal(5,1) NOT NULL COMMENT '请假总天数', `reason` varchar(500) DEFAULT NULL COMMENT '请假原因', `status` tinyint NOT NULL DEFAULT '1' COMMENT '状态:1草稿 2审批中 3已通过 4已驳回', `create_time` datetime NOT NULL COMMENT '提交时间', `update_time` datetime NOT NULL COMMENT '更新时间', PRIMARY KEY (`id`), KEY `idx_user` (`user_id`), KEY `idx_dept` (`dept_id`), KEY `idx_status` (`status`), KEY `idx_create_time` (`create_time`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='请假单主表';

这张表的主键是id,唯一业务编号是request_no,但查询待办列表时一般用不上request_no,更多是用dept_id和status过滤。索引方面,status和dept_id是待办列表最常用的过滤字段,必须建索引。

3.2 审批记录表:当前节点的关键在于is_current标记

审批记录表是待办查询的核心。我们给它起名叫approval_record,每次审批节点的创建、通过、驳回都会写一条记录。字段如下:

CREATE TABLE `approval_record` ( `id` bigint NOT NULL COMMENT '记录ID', `business_id` bigint NOT NULL COMMENT '业务单据ID,这里指请假单ID', `step` int NOT NULL COMMENT '审批步骤序号,从1开始', `approver_id` bigint NOT NULL COMMENT '审批人ID', `action` tinyint NOT NULL DEFAULT '0' COMMENT '动作:0待审批 1通过 2驳回', `opinion` varchar(500) DEFAULT NULL COMMENT '审批意见', `operate_time` datetime DEFAULT NULL COMMENT '操作时间,待审批时为空', `is_current` tinyint NOT NULL DEFAULT '1' COMMENT '是否当前有效节点:1是 0否', `create_time` datetime NOT NULL COMMENT '记录创建时间', PRIMARY KEY (`id`), KEY `idx_business` (`business_id`), KEY `idx_approver` (`approver_id`), KEY `idx_current_action` (`is_current`, `action`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='审批记录表';

这里有一个很关键的设计:is_current字段。很多系统的审批记录表没有这个字段,查询当前节点时只能通过step = (select max(step) ...)这种方式来定位,性能和SQL复杂度都很高。加一个is_current标记之后,每次审批动作发生时,我们把当前节点的所有记录is_current置为0,再把新节点的记录插入并标记为1。这样,查询待办时只需要过滤is_current = 1即可,SQL简单、索引命中率高。

另外,每张单据的每个节点可以有多条审批人记录。比如节点2是"人事专员审批",人事部门有两个人,那这个节点就会插入两条approval_record,这两条的step相同、is_current都为1,但approver_id不同。这样一张请假单就会出现在两个候选审批人的待办列表里,谁先处理,另一条记录就变成历史。

3.3 审批流程配置表:节点与审批人的映射

审批流程配置表用来定义不同请假类型、不同条件走哪个审批路径。它不直接参与待办SQL的查询,但决定了审批记录表里节点的生成逻辑。表结构如下:

CREATE TABLE `approval_flow` ( `id` bigint NOT NULL COMMENT '配置ID', `business_type` tinyint NOT NULL COMMENT '业务类型:1请假 2加班 3报销', `leave_type` tinyint DEFAULT NULL COMMENT '请假类型,为空表示适用所有类型', `step` int NOT NULL COMMENT '审批步骤序号', `approver_type` tinyint NOT NULL COMMENT '审批人类型:1指定角色 2指定部门 3指定人', `approver_value` varchar(255) NOT NULL COMMENT '审批人标识,角色ID/部门ID/用户ID', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='审批流程配置表';

这张表的具体使用方式,是在提交请假单时根据business_type和leave_type匹配出所有节点,然后依次生成approval_record记录。待审批SQL不需要直接关联它,但了解这张表能帮你理解审批记录从哪来。尤其是调试"审批人为什么不对"这种问题时,翻配置表通常能快速找到原因。

4. 待审批请假数据的SQL语句设计:从能跑到跑得快

4.1 基础版SQL:一次性关联搞定待办清单

条件理顺了,表也设计好了,接下来就是重头戏:待审批请假数据的SQL写法。我先给出基础版,这个版本能跑、语义也正确,适合刚上手的项目。

SELECT lr.id, lr.request_no, lr.leave_type, lr.start_time, lr.end_time, lr.total_days, lr.reason, lr.create_time, u.real_name AS applicant_name, d.dept_name AS applicant_dept, ar.step AS current_step, ar.approver_id FROM leave_request lr INNER JOIN approval_record ar ON ar.business_id = lr.id INNER JOIN sys_user u ON u.id = lr.user_id LEFT JOIN sys_dept d ON d.id = lr.dept_id WHERE ar.approver_id = #{currentUserId} AND ar.is_current = 1 AND ar.action = 0 AND lr.status = 2 ORDER BY lr.create_time DESC

这个SQL看起来简单,但每一行都有它存在的意义。核心过滤条件就四个:

  • ar.approver_id = #{currentUserId}:限定当前登录人。
  • ar.is_current = 1:只查当前有效节点。
  • ar.action = 0:当前节点下我还没有动作的。
  • lr.status = 2:单据确实处于审批中。

注意,我用了INNER JOIN approval_record而不是LEFT JOIN,这也是有讲究的。因为一个过滤条件全部命中才会返回数据,用LEFT JOIN没有意义,反而可能因为多个审批记录产生重复数据。

4.2 用EXISTS改写的待办查询:更贴近语义的另一种写法

基础版SQL用JOIN实现,优点是直观,缺点是如果审批记录表数据量很大,JOIN可能比EXISTS慢。我提供第二种写法,也更贴合"是否存在一条记录"这种业务语义:

SELECT lr.id, lr.request_no, lr.leave_type, lr.start_time, lr.end_time, lr.total_days, lr.reason, lr.create_time, u.real_name AS applicant_name, d.dept_name AS applicant_dept FROM leave_request lr INNER JOIN sys_user u ON u.id = lr.user_id LEFT JOIN sys_dept d ON d.id = lr.dept_id WHERE lr.status = 2 AND EXISTS ( SELECT 1 FROM approval_record ar WHERE ar.business_id = lr.id AND ar.approver_id = #{currentUserId} AND ar.is_current = 1 AND ar.action = 0 ) ORDER BY lr.create_time DESC

这种写法在逻辑上更容易扩展。比如如果后续要增加"审批人所在部门与申请人部门一致"这样的条件,你只需要在EXISTS子查询里加一个关联,不会影响主查询的结构。

4.3 加上部门数据权限:A部门主管只能看A部门

接下来是权限版本。如果当前登录人是部门主管,他只应该看到自己部门的请假单。这时在基础版SQL里追加一个条件:

SELECT lr.id, lr.request_no, lr.leave_type, lr.start_time, lr.end_time, lr.total_days, lr.reason, lr.create_time, u.real_name AS applicant_name, d.dept_name AS applicant_dept, ar.step AS current_step FROM leave_request lr INNER JOIN approval_record ar ON ar.business_id = lr.id INNER JOIN sys_user u ON u.id = lr.user_id LEFT JOIN sys_dept d ON d.id = lr.dept_id WHERE ar.approver_id = #{currentUserId} AND ar.is_current = 1 AND ar.action = 0 AND lr.status = 2 AND lr.dept_id = #{currentUserDeptId} ORDER BY lr.create_time DESC

这条SQL比基础版多了lr.dept_id = #{currentUserDeptId},这是部门级数据权限。如果系统还支持"本部门及下级部门",那这里就要换成lr.dept_id IN (自己部门 + 子部门集合),子部门集合可以一次性从部门表里查出来放到内存里。

这里我顺便提一个容易踩的坑:部门权限过滤不要加到approval_record表的approver_id上,因为审批人可能是跨部门指定的。比如A部门的员工请假,审批人却是B部门的总监,如果按审批人部门过滤,这条单就被错误过滤掉了。正确做法是始终用"申请人所属部门"作为数据权限的过滤维度。

4.4 待办数量的统计SQL:首页红点不能慢

很多OA首页会显示一个待办数量的小红点,比如"审批(5)"。这个数字如果每次打开都重新统计,性能压力不小。我们的做法是提供一个独立统计SQL:

SELECT COUNT(*) FROM leave_request lr WHERE lr.status = 2 AND EXISTS ( SELECT 1 FROM approval_record ar WHERE ar.business_id = lr.id AND ar.approver_id = #{currentUserId} AND ar.is_current = 1 AND ar.action = 0 )

这个SQL只返回一个整数,逻辑跟列表查询保持一致,不会出现"列表显示6条,红点显示8条"这种尴尬。后面我再补充索引优化时,这个COUNT查询也要一起考虑。

4.5 列表展示字段的补充查询

待办列表里除了请假单本身,通常还要展示申请人的姓名、部门名称、请假类型的中文含义等。这些字段要么在SQL里直接JOIN关联表,要么在Java代码里用批量ID查询后再装配。我建议优先SQL里JOIN,减少查询次数。像sys_user、sys_dept这种基础表都有索引,JOIN成本很低。

另外,请假类型这种枚举字段,我一般不会在SQL里做CASE WHEN转换,原因是枚举逻辑可能会变,放在代码里维护更灵活。SQL只返回leave_type的原始值,界面层再根据字典翻译成"事假、病假"等。

5. 实测中踩过的坑:索引、事务与状态一致性

5.1is_current标记的维护与并发问题

在写审批记录表时加is_current字段确实带来了查询上的便利,但代价是更新逻辑一定要做对。每次审批动作发生时,需要把当前节点的所有is_current = 1记录置为0,再插入新记录。这两个操作必须放在同一个数据库事务里,否则一旦中间出现异常,就会出现"两个节点同时是当前节点"的数据错误。

我们的审批操作核心逻辑大致是:

@Transactional public void approve(Long recordId, Integer action, String opinion) { // 1. 查询当前记录,校验是否待审批状态 ApprovalRecord record = approvalRecordMapper.selectById(recordId); // 2. 更新当前记录的动作、意见、操作时间 record.setAction(action); record.setOpinion(opinion); record.setOperateTime(new Date()); approvalRecordMapper.updateById(record); // 3. 将当前节点所有is_current=1的记录置为0 approvalRecordMapper.disableCurrentByBusinessId(record.getBusinessId()); // 4. 如果流程未结束,插入下一个节点的审批记录 if (hasNextStep(record.getBusinessId(), record.getStep())) { approvalRecordMapper.insertNextStepRecords(...); } else { // 5. 流程结束,更新主表单状态 leaveRequestMapper.updateStatus(record.getBusinessId(), 3); } }

这里有个隐蔽问题:如果recordId是当前节点多条记录中的一条,而当前节点有多个审批人,那么某个审批人操作后,其他审批人的关联记录也会被一起置为is_current = 0。数据逻辑上这样设计是对的,因为节点只要被其中一人处理,该节点就不再是当前节点了。但对"并行审批"这种业务规则(比如要求所有审批人都必须同意),就不能用这个方案了。我们这边请假审批采用"任一审批人处理即通过"的规则,所以is_current维护方式没有问题。

5.2 索引设计:哪些字段必须进组合索引

待办查询的性能瓶颈主要在审批记录表上。我们线上数据量在百万级之后,单表查询还能保持在几十毫秒内,靠的就是组合索引。审批记录表建议建一个联合索引,最核心的是下面这两个:

ALTER TABLE approval_record ADD INDEX idx_business_current_action (business_id, is_current, action), ADD INDEX idx_approver_current_action (approver_id, is_current, action);

第一个索引(business_id, is_current, action)用于根据单据查当前节点记录;第二个索引(approver_id, is_current, action)用于待办查询,因为我们的SQL就是按approver_id + is_current + action三个条件过滤的。如果没有这个联合索引,数据库会先按approver_id筛出一堆历史记录,再过滤is_current,速度会慢很多。

请假单主表方面,status、dept_id、create_time单独建索引即可。有些项目还会遇到"按时间范围统计数据"的需求,比如最近七天的请假人数,这时候可以考虑(dept_id, create_time)联合索引。

5.3 大偏移量分页的优化方案

待办查询列表一定会做分页,LIMIT 10 OFFSET 50000这种写法在数据量大了以后会越来越慢。原因在于数据库需要扫描前面50000行再丢弃,效率极低。我们这边的优化方案是改成"基于游标的分页",或者叫"键集分页"。

简单说,就是排序字段不要用create_time之余还用OFFSET,而是记住上一页最后一条记录的时间,下一页直接从那个时间点往后再取:

SELECT lr.id, lr.request_no, lr.create_time FROM leave_request lr INNER JOIN approval_record ar ON ar.business_id = lr.id WHERE ar.approver_id = #{currentUserId} AND ar.is_current = 1 AND ar.action = 0 AND lr.status = 2 AND lr.create_time < #{lastCreateTime} ORDER BY lr.create_time DESC LIMIT 10

第一次查询时lastCreateTime传当前时间即可,之后每次把上一页最后一条的create_time传进去。这种方式在表数据量很大的情况下性能非常稳。它唯一的限制是要求排序字段没有重复值或重复值少,create_time在极端情况下可能重复,但配合id就可以避免:

AND (lr.create_time < #{lastCreateTime} OR (lr.create_time = #{lastCreateTime} AND lr.id < #{lastId})) ORDER BY lr.create_time DESC, lr.id DESC

这样两列一起排序,既保证数据不重不漏,又彻底告别了OFFSET。

5.4 审批记录与主表单的状态一致性

再强调一个非常容易被忽略的问题:审批记录表更新和请假单主表状态更新必须保证一致性。比如流程最后一步审批通过后,需要把主表的status从2(审批中)改成3(已通过)。如果这两个操作不在同一个事务里,可能出现审批记录已经显示"通过",但主表状态还是"审批中"的脏数据。

这种脏数据一旦出现,最典型的表现就是待办列表里那条单永远消不掉,而且审批人已经找不到处理入口了。修复起来虽然不难,但要排查却非常浪费时间。所以我在项目里一直坚持,凡是涉及审批动作的业务方法,必须加上@Transactional,并在代码注释里写明事务边界。这不是多此一举,而是为了在三个月后或者换人维护时,还能一眼看明白哪些操作是一个整体。

最后说一句,审批功能看起来只是OA系统里的一个小模块,但做深了你会发现,它其实涉及流程引擎、权限模型、数据一致性、查询性能等多个方面的设计取舍。这一篇我们先把【请假审批】界面的待审批数据SQL讲清楚,下一篇再展开审批通过、驳回后的状态流转处理,以及审批历史的展示逻辑。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/20 7:37:16

NTC热敏电阻测温不求人:adafruit库+B值模型实战解析

做嵌入式或物联网原型的朋友&#xff0c;应该都遇到过读NTC热敏电阻温度这件事。接线其实很简单&#xff0c;一个电阻加一个ADC引脚就能测&#xff0c;真正烦人的是把电压换算成温度的数学过程&#xff0c;尤其是当你想用B值公式快速估算&#xff0c;又不想自己写指数和对数运算…

作者头像 李华
网站建设 2026/10/20 7:36:30

喂参考库:让AI网页生成告别‘AI味’的关键工程实践

1. 为什么“喂参考库”是网页生成从“AI味”到“人味”的分水岭“给 AI 喂了一个参考库&#xff0c;它做的网页终于不像 AI 了”——这句话在最近两周的前端圈和产品设计群被反复截图转发。不是因为它多新颖&#xff0c;而是因为它精准戳中了所有用过 AI 网页生成工具的人心里那…

作者头像 李华
网站建设 2026/10/20 7:35:30

微博评论情感分析实战:LSTM+CNN+GloVe构建二分类模型

做微博评论的情感分析&#xff0c;我最早是被一句"这个模型能不能判断用户骂没骂我们"给带进坑的。当时某公司想做舆情监控&#xff0c;人工看评论看得脑袋大&#xff0c;就想着能不能用深度学习自动把评论分成正面和负面两类。于是就有了这个项目&#xff1a;用LSTM…

作者头像 李华
网站建设 2026/10/20 7:35:26

C++继承中默认成员函数的行为详解:从内存布局到对象切片与析构坑

做C开发这些年&#xff0c;我见过太多在继承上栽跟头的项目&#xff1a;有人把继承当成复制粘贴的升级版&#xff0c;不管三七二十一让所有类都继承同一个基类&#xff1b;也有人写了好几年的派生类代码&#xff0c;却连基类构造函数什么时候被调用都说不清楚。继承是C面向对象…

作者头像 李华
网站建设 2026/10/20 7:35:19

分支语句深度解析:if与switch的原理、选型与避坑指南

1. 分支是程序的岔路口&#xff1a;if和switch各自解决什么问题1.1 一个真实场景&#xff1a;格式化工具莫名错位&#xff0c;引出分支配平问题前阵子给一个模拟项目X写配置解析器&#xff0c;功能很简单——读入一段设备状态描述&#xff0c;根据状态码决定后续动作。状态码有…

作者头像 李华
网站建设 2026/10/20 7:35:10

ChatGPT录音上传实战指南:从会议纪要到AI高效转写

ChatGPT 终于能直接上传录音了。这句话我发了不止一条消息给同行&#xff0c;因为它是真的能省掉一大截工作的功能。过去我想把一段两小时的访谈变成会议纪要&#xff0c;必须先把音频导进转写工具&#xff0c;生成文字稿&#xff0c;检查错别字&#xff0c;再把文字稿复制到对…

作者头像 李华