news 2026/9/7 16:41:34

ERP进销存明细查询管理:Web ERP设计要点与Spring Boot实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ERP进销存明细查询管理:Web ERP设计要点与Spring Boot实现

在实际的 ERP 进销存项目中,明细查询管理往往是业务人员每天使用频率最高的功能之一。它不像基础资料维护那样只做增删改查,也不像报表统计那样直接输出汇总结果,而是承担了“把业务单据变成可追踪、可核对、可下钻的流水记录”这一关键任务。

本文围绕“ERP 进销存-8|明细查询管理|Web ERP 使用教程”这条主线展开,讲解在 Web 版进销存系统中,明细查询管理模块应该怎么设计、怎么实现、怎么验证。整个示例不会绑定某个具体商业 ERP 产品,而是采用 Spring Boot 3 + MyBatis Plus + Vue 3 + Element Plus 这套常见技术栈,搭建一个最小但完整的明细查询功能。读完本文后,你可以独立完成从建表、写查询接口、做前端筛选页面,到排查“日期查不到、分页总数不对、明细和汇总对不上”等典型问题的全过程。

1. 明细查询管理到底在管什么

1.1 从业务角度看明细查询的价值

在进销存系统里,业务人员关心的不只是“这个月进了多少货、出了多少货”,更关心的是“这批货是哪张采购单进来的”“这张销售单对应哪些商品明细”“某个仓库的结存是怎么一步步变成当前数值的”。这些逐行数据就是明细数据。

明细查询管理的核心价值有三个:

  • 可追溯:每一条入库、出库、退货、调拨记录都能找到来源单据和经办人。
  • 可核对:财务、仓库、采购、销售看到同一份明细口径,对账时有依据。
  • 可分析:明细数据是库存报表、销售报表、采购报表的数据底座,明细查不准,汇总必然失真。

如果只做单据保存而不做明细查询,系统就只是一个录入工具,不是管理工具。

1.2 明细查询在 Web ERP 系统中的技术定义

从技术角度说,明细查询管理是一个典型的多条件组合查询模块。它通常包含:

  • 查询条件区:单据编号、商品编码、商品名称、仓库、往来单位、业务类型、日期范围、经办人、审核状态。
  • 数据列表区:按条件查询出的明细行,支持分页、排序、导出。
  • 明细联动区:从明细行跳转到对应单据详情,或显示该商品的库存流水。

它不是单独的数据库表,而是基于“出入库明细表”或“库存流水表”这一层数据模型,向上承接单据,向下支撑报表。

1.3 明细查询和报表查询的边界

很多刚接触进销存项目的人会混淆明细查询和报表统计。

  • 明细查询:查的是流水行,一行对应一次业务动作,结果可下钻到原始单据。
  • 报表查询:查的是汇总后的数值,比如某商品本月销量、某仓库当前结存。

在实际项目中,明细查询是报表统计的数据来源之一,但两者在索引设计、缓存策略、响应要求上并不一样。报表可以接受分钟级延迟,明细查询通常要求秒级返回。

2. 环境准备与项目结构设计

2.1 技术选型与版本说明

本示例采用前后端分离架构。后端负责查询接口和数据权限控制,前端负责筛选条件交互和结果展示。

技术作用示例版本
JDK运行环境17
Spring Boot后端基础框架3.2.x
MyBatis PlusORM 与分页插件3.5.x
MySQL数据库8.0
Vue前端框架3.4.x
Element Plus前端组件库2.x
Vite前端构建工具5.x

版本以实际项目安装为准,不同版本之间部分配置项可能有差异,尤其是 Spring Boot 3 依赖的 Jakarta 命名空间和 MyBatis Plus 的适配方式。

2.2 后端项目结构

erp-stock-api ├── pom.xml ├── src/main/java/com/example/erp │ ├── ErpStockApplication.java │ ├── controller │ │ └── StockDetailController.java │ ├── service │ │ ├── StockDetailService.java │ │ └── impl │ │ └── StockDetailServiceImpl.java │ ├── mapper │ │ ├── StockDetailMapper.java │ │ └── xml │ │ └── StockDetailMapper.xml │ ├── entity │ │ ├── StockDetail.java │ │ └── StockDetailQuery.java │ └── common │ ├── PageResult.java │ └── Result.java └── src/main/resources ├── application.yml └── mapper └── StockDetailMapper.xml

2.3 前端项目结构

erp-web ├── package.json ├── vite.config.js ├── src │ ├── api │ │ └── stockDetail.js │ ├── views │ │ └── stock │ │ └── StockDetailQuery.vue │ └── router │ └── index.js

前端只保留与明细查询相关的页面,其余菜单和权限逻辑可以根据项目后续需要补齐。

2.4 环境准备清单

开始编码前,先确认以下项都就绪:

  • 本地 MySQL 服务已经启动,root 账号可以登录。
  • JDK 17 已安装,终端执行java -version能看到版本信息。
  • Node.js 已安装,建议使用 18 或 20 LTS 版本。
  • 后端开发工具使用 IDEA 或 Eclipse 均可,前端使用 VS Code。

注意:不要只验证工具能启动,还要验证数据库连接、端口占用、Maven 依赖下载和 npm 源是否可用。很多明细查询报错并不是代码问题,而是环境没对齐。

3. 数据库设计与查询接口实现

3.1 明细表结构设计

明细查询的基础是一张可靠的流水表。以出入库明细表为例,核心字段如下:

CREATE TABLE stock_detail ( id BIGINT PRIMARY KEY AUTO_INCREMENT, bill_no VARCHAR(32) NOT NULL COMMENT '单据编号', bill_type VARCHAR(20) NOT NULL COMMENT '业务类型:PURCHASE_IN/SELL_OUT/STOCK_TRANSFER', warehouse_id BIGINT NOT NULL COMMENT '仓库ID', product_id BIGINT NOT NULL COMMENT '商品ID', product_code VARCHAR(64) COMMENT '商品编码冗余', product_name VARCHAR(128) COMMENT '商品名称冗余', unit_name VARCHAR(20) COMMENT '单位名称', quantity DECIMAL(18, 4) NOT NULL COMMENT '数量', price DECIMAL(18, 4) COMMENT '单价', amount DECIMAL(18, 4) COMMENT '金额', direction TINYINT NOT NULL COMMENT '方向:1 入库,-1 出库', remark VARCHAR(255) COMMENT '备注', create_time DATETIME NOT NULL COMMENT '业务时间', create_by VARCHAR(32) COMMENT '经办人', audit_status TINYINT DEFAULT 0 COMMENT '审核状态:0 未审核,1 已审核' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='出入库明细表';

商品编码、名称、单位这些字段属于冗余字段。正常设计商品主表后,明细表并不需要重复保存这些信息,但实际项目里为了方便查询、避免每次 join 商品表,通常会冗余保存。

设计时要注意:quantityamount必须使用DECIMAL,不要使用FLOATDOUBLE,否则金额会出现精度误差。

3.2 查询条件的 DTO 设计

查询条件单独封装成一个对象,比直接用Map传参更规范,也方便后续扩展排序规则。

public class StockDetailQuery { private String billNo; private String billType; private Long warehouseId; private String productCode; private String productName; private Integer direction; private Integer auditStatus; private String startTime; private String endTime; private Integer pageNum; private Integer pageSize; }

页码和每页条数也放在查询对象里,前端统一传参,后端统一接收。

3.3 Mapper XML 中的多条件查询 SQL

使用 MyBatis Plus 提供的分页插件,SQL 里只需要写普通查询,分页拦截器会自动生成 limit 语句和 count 语句。

<select id="selectDetailPage" resultType="com.example.erp.entity.StockDetail"> SELECT d.id, d.bill_no, d.bill_type, d.bill_type_name, w.warehouse_name, d.product_code, d.product_name, d.unit_name, d.quantity, d.price, d.amount, d.direction, d.create_time, d.create_by, d.audit_status FROM stock_detail d LEFT JOIN warehouse w ON w.id = d.warehouse_id <where> <if test="query.billNo != null and query.billNo != ''"> AND d.bill_no LIKE CONCAT('%', #{query.billNo}, '%') </if> <if test="query.billType != null and query.billType != ''"> AND d.bill_type = #{query.billType} </if> <if test="query.warehouseId != null"> AND d.warehouse_id = #{query.warehouseId} </if> <if test="query.productCode != null and query.productCode != ''"> AND d.product_code LIKE CONCAT('%', #{query.productCode}, '%') </if> <if test="query.productName != null and query.productName != ''"> AND d.product_name LIKE CONCAT('%', #{query.productName}, '%') </if> <if test="query.direction != null"> AND d.direction = #{query.direction} </if> <if test="query.auditStatus != null"> AND d.audit_status = #{query.auditStatus} </if> <if test="query.startTime != null and query.startTime != ''"> AND d.create_time &gt;= #{query.startTime} </if> <if test="query.endTime != null and query.endTime != ''"> AND d.create_time &lt;= CONCAT(#{query.endTime}, ' 23:59:59') </if> </where> ORDER BY d.create_time DESC, d.id DESC </select>

这里的两个时间条件值得展开说明。前端日期范围选择器通常只会传2025-01-01这样的日期字符串,如果直接用AND create_time <= '2025-01-01',当天的数据都会被过滤掉,因为create_timeDATETIME类型,比较时会把2025-01-01当作2025-01-01 00:00:00。正确做法是在结束日期后面拼接23:59:59,或者直接用< create_time < 结束日期 + 1天,后者性能更好。

3.4 Service 层的分页处理

@Service public class StockDetailServiceImpl implements StockDetailService { private final StockDetailMapper stockDetailMapper; public StockDetailServiceImpl(StockDetailMapper stockDetailMapper) { this.stockDetailMapper = stockDetailMapper; } @Override public PageResult<StockDetail> queryPage(StockDetailQuery query) { Page<StockDetail> page = new Page<>(query.getPageNum(), query.getPageSize()); Page<StockDetail> result = stockDetailMapper.selectDetailPage(page, query); return PageResult.of(result); } }

分页插件需要配置拦截器:

@Configuration public class MybatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } }

3.5 Controller 接口设计

@RestController @RequestMapping("/api/stock/detail") public class StockDetailController { private final StockDetailService stockDetailService; public StockDetailController(StockDetailService stockDetailService) { this.stockDetailService = stockDetailService; } @PostMapping("/page") public Result<PageResult<StockDetail>> page(@RequestBody StockDetailQuery query) { if (query.getPageNum() == null) { query.setPageNum(1); } if (query.getPageSize() == null || query.getPageSize() > 200) { query.setPageSize(20); } return Result.success(stockDetailService.queryPage(query)); } }

接口使用 POST 而不是 GET,主要原因是查询条件较多,JSON 比 query string 更清晰,也方便后续扩展排序字段和权限参数。

4. 前端查询页面的实现

4.1 前端 API 封装

import request from '@/utils/request' export function queryStockDetailPage(data) { return request({ url: '/api/stock/detail/page', method: 'post', data }) }

实际项目中request是基于 axios 封装的实例,统一处理 token、错误码和加载状态。

4.2 页面布局与筛选条件

<template> <div class="stock-detail-query"> <el-form :model="queryForm" inline> <el-form-item label="单据编号"> <el-input v-model="queryForm.billNo" placeholder="模糊查询" clearable /> </el-form-item> <el-form-item label="业务类型"> <el-select v-model="queryForm.billType" clearable> <el-option label="采购入库" value="PURCHASE_IN" /> <el-option label="销售出库" value="SELL_OUT" /> <el-option label="库存调拨" value="STOCK_TRANSFER" /> </el-select> </el-form-item> <el-form-item label="商品编码"> <el-input v-model="queryForm.productCode" placeholder="模糊查询" clearable /> </el-form-item> <el-form-item label="商品名称"> <el-input v-model="queryForm.productName" placeholder="模糊查询" clearable /> </el-form-item> <el-form-item label="业务日期"> <el-date-picker v-model="dateRange" type="daterange" value-format="YYYY-MM-DD" start-placeholder="开始日期" end-placeholder="结束日期" /> </el-form-item> <el-form-item> <el-button type="primary" @click="handleQuery">查询</el-button> <el-button @click="handleReset">重置</el-button> <el-button @click="handleExport">导出</el-button> </el-form-item> </el-form> <el-table :data="tableData" v-loading="loading" border stripe> <el-table-column prop="billNo" label="单据编号" width="160" /> <el-table-column prop="billTypeName" label="业务类型" width="110" /> <el-table-column prop="productCode" label="商品编码" width="120" /> <el-table-column prop="productName" label="商品名称" min-width="160" /> <el-table-column prop="warehouseName" label="仓库" width="120" /> <el-table-column prop="direction" label="方向" width="80"> <template #default="{ row }"> <el-tag :type="row.direction === 1 ? 'success' : 'warning'"> {{ row.direction === 1 ? '入库' : '出库' }} </el-tag> </template> </el-table-column> <el-table-column prop="quantity" label="数量" width="100" align="right" /> <el-table-column prop="amount" label="金额" width="120" align="right" /> <el-table-column prop="createTime" label="业务时间" width="160" /> <el-table-column prop="auditStatus" label="审核状态" width="90"> <template #default="{ row }"> {{ row.auditStatus === 1 ? '已审核' : '未审核' }} </template> </el-table-column> </el-table> <el-pagination background layout="total, sizes, prev, pager, next" :total="total" v-model:current-page="queryForm.pageNum" v-model:page-size="queryForm.pageSize" :page-sizes="[10, 20, 50, 100]" @size-change="handleQuery" @current-change="handleQuery" /> </div> </template> <script setup> import { ref, reactive } from 'vue' import { queryStockDetailPage } from '@/api/stockDetail' import { ElMessage } from 'element-plus' const queryForm = reactive({ billNo: '', billType: '', productCode: '', productName: '', direction: null, auditStatus: null, pageNum: 1, pageSize: 20 }) const dateRange = ref([]) const tableData = ref([]) const total = ref(0) const loading = ref(false) async function handleQuery() { loading.value = true try { const params = { ...queryForm } if (dateRange.value && dateRange.value.length === 2) { params.startTime = dateRange.value[0] params.endTime = dateRange.value[1] } const res = await queryStockDetailPage(params) if (res.code === 0) { tableData.value = res.data.records total.value = res.data.total } else { ElMessage.error(res.msg || '查询失败') } } finally { loading.value = false } } function handleReset() { queryForm.billNo = '' queryForm.billType = '' queryForm.productCode = '' queryForm.productName = '' queryForm.direction = null queryForm.auditStatus = null dateRange.value = [] queryForm.pageNum = 1 handleQuery() } </script>

4.3 日期区间组件的处理细节

Element Plus 的date-picker类型设为daterange时,value-format="YYYY-MM-DD"会得到数组形式的日期字符串。这里不要直接绑定到查询对象里,因为后端接口接收的是扁平字段startTimeendTime,页面里单独维护一个dateRange变量,查询时再拆开,逻辑更清晰。

5. 运行验证与典型查询场景

5.1 准备测试数据

假设已经录入了几张业务单据,明细表里有如下数据:

bill_nobill_typeproduct_codeproduct_namequantitydirectioncreate_timeaudit_status
CG20250101001PURCHASE_INSP001无线鼠标10012025-01-05 09:30:001
CG20250110002PURCHASE_INSP002机械键盘5012025-01-10 14:20:001
XS20250112001SELL_OUTSP001无线鼠标30-12025-01-12 16:40:001
DB20250115001STOCK_TRANSFERSP001无线鼠标2012025-01-15 10:10:000

这些数据可以覆盖模糊查询、入库出库方向筛选、时间范围和状态筛选四类场景。

5.2 启动与验证步骤

  1. 启动 MySQL,确认stock_detail表已经建立并写了测试数据。
  2. 启动后端服务,执行mvn spring-boot:run
  3. 启动前端,执行npm installnpm run dev
  4. 浏览器访问前端页面,不填写任何条件直接点击查询。
  5. 确认表格返回第一页数据,总条数大于 0。

预期结果:

  • 不填条件时返回全部明细,按时间倒序。
  • 输入商品编码SP001,结果只剩该商品的 3 条流水。
  • 选择业务日期范围为2025-01-052025-01-10,结果只包含两条采购入库记录,且 1 月 10 日当天的记录不会丢失。
  • 选择审核状态为“未审核”,只显示调拨单记录。

5.3 明细到报表的核对测试

明细查询是否准确,不能只看“能查出数据”。要用一组已知的测试数据手动计算核对:

  • 商品 SP001 入库合计:100 + 20 = 120。
  • 商品 SP001 出库合计:30。
  • 理论结存:120 - 30 = 90。

然后到系统的库存汇总查询里看 SP001 的结存是否为 90。如果不一致,优先检查方向字段是否存错,业务类型是否混用。

6. 常见问题与排查路径

6.1 日期范围查不到数据

现象:选择了业务日期后,查询结果为空。

可能原因:

  • 前端没有把dateRange拆成startTimeendTime,后端收到的两个字段为空。
  • 结束日期没有拼接到当天23:59:59,导致当天记录被过滤。
  • 数据库里的create_time不是业务时间,而是数据创建时间,创建当晚与业务日报不一致。

排查方式:

  1. 在浏览器开发者工具 Network 面板查看请求 payload,确认startTimeendTime是否传到后端。
  2. 在数据库里手动执行 SQL,用同一时间段查看结果。
  3. 打印后端接收到的 SQL 和参数,确认CONCAT拼接后的结束时间是否符合预期。

处理建议:

  • 前端统一日期选择器格式为YYYY-MM-DD
  • 后端在时间条件里使用create_time < DATE_ADD(结束日期, INTERVAL 1 DAY)代替字符串拼接。
  • 明细表的create_time字段语义要在设计评审时统一,建议名称改为bill_time表意更明确。

6.2 分页总数不对或重复

现象:翻到第二页时数据与第一页重复,或者总条数和实际查询结果不一致。

可能原因:

  • 多表LEFT JOIN时,明细表与关联表不是一对一关系,导致明细行被放大。
  • ORDER BY share_time DESC, id DESC缺少唯一排序字段,当create_time相同时分页顺序不稳定。
  • count 查询没走正确的统计口径。

排查方式:

  1. 单独执行不带分页的查询,查看productCode相同的一行是否出现多次。
  2. 去掉 JOIN 后数一下明细表行数,对比 JOIN 后结果条数。
  3. 查看 MyBatis Plus 自动生成的 count SQL,确认是否包含多余的 JOIN。

处理建议:

  • 仓库名称、单位名称这类冗余字段尽量不要在明细查询 SQL 里 JOIN,可以改成查询时冗余在表中,或者先查明细再批量查关联名称。
  • 如果必须 JOIN,确保关联字段建了唯一索引。
  • 排序条件至少加一个唯一字段id

6.3 导出数据与页面数据不一致

现象:页面显示 20 条,导出却只有几百条;或者导出的是全部生效明细,页面查询只有部分数据。

可能原因:

  • 导出接口没有加和页面相同的权限过滤条件。
  • 导出时直接查全表,没有将查询条件传入导出方法。
  • 分页只限制在页面里,导出接口单独走了一条 SQL。

处理建议:

  • 导出接口复用同一个查询方法,只改变“是否分页”的标志。
  • 在查询对象里增加exportFlag字段,让同一个 SQL 支持分页查询和全量导出的两种场景。
  • 导出前先记录查询条件,生成导出任务后再校验一次条件是否一致。

6.4 慢查询

现象:明细表数据量到几十万行以后,点击查询需要几秒甚至更慢。

排查方式:

  1. 使用EXPLAIN查看 SQL 执行计划。
  2. 检查product_code的 LIKE 查询是否走了全表扫描。
  3. 检查时间下推范围是否过宽。

处理建议:

  • 建立组合索引(create_time, direction, audit_status),优先过滤时间范围。
  • 商品编码查询使用右模糊匹配时,无法利用索引;如果业务允许,改为编码前缀精确匹配,或者引入全文索引。
  • 控制单次查询返回量,页面最多返回 100 行,导出走异步任务。

7. 生产环境最佳实践与扩展方向

7.1 索引设计建议

明细表的索引设计需要根据真实查询条件来定,而不是建一堆单列索引。常见的组合索引优先级如下:

  • (create_time):因为几乎每个明细查询都会带时间范围。
  • (product_id, create_time):商品维度查询频率高。
  • (bill_no):按单据精确查流水时必须命中。

索引不是越多越好。明细表经常有写入,过多索引会拖慢插入性能。先用慢日志找出最耗时的查询语句,再针对性建索引。

7.2 数量、金额精度问题

明细查询模块最容易出现的数据事故就是金额对不上。生产环境要遵循以下约定:

  • 数据库数量字段使用DECIMAL(18, 4)
  • 金额字段使用DECIMAL(18, 4)DECIMAL(18, 2),由财务精度决定。
  • Java 实体使用BigDecimal,不要用double
  • 前端展示金额时也不要使用Number类型做精度转换,直接回显字符串或格式化保留两位小数。

7.3 权限与数据范围

明细数据通常绑定了仓库、部门、业务员等多个维度,生产环境必须做数据权限过滤。最简单的方式是在查询 SQL 里拼接仓库范围:

AND d.warehouse_id IN <foreach collection="query.warehouseIds" item="wid" open="(" separator="," close=")"> #{wid} </foreach>

数据权限不要只在前端控制。前端隐藏按钮只能改善体验,不能保证安全。后端要根据登录用户所属角色动态计算可访问的仓库列表。

7.4 异步导出与大数据量处理

当明细量达到百万行,同步导出会导致接口超时。建议改成“创建导出任务”模式:

  1. 前端选择查询条件,点击导出。
  2. 后端生成一条导出任务记录,状态为“处理中”。
  3. 后端异步线程执行查询,每查出一批就写入临时文件。
  4. 前端通过轮询或 WebSocket 获取导出进度。
  5. 结果生成后提供下载链接,链接设置过期时间。

这种方式能避免大查询拖垮 Web 服务,也方便用户在不阻塞页面的情况下继续操作。

7.5 从明细查询到库存分析的扩展方向

明细查询管理做完以后,可以在此基础上扩展三个方向:

  • 库存流水跟踪:把每一次库存变动都记录下来,展示“期初 + 入 - 出 = 结存”的完整性。
  • 多维汇总分析:按商品、仓库、日期、业务类型分组统计数量与金额。
  • 预警提醒:根据明细计算低库存、超储量、滞销商品,主动推送给采购或销售。

这三个方向都建立在“明细准确”这一前置条件上。先保证明细查询模块的数据一致性,再谈报表和预警才有意义。

7.6 新手落地建议

第一次在 Web ERP 项目里实现明细查询,不要一开始就追求完整权限、异步导出、复杂索引。建议按这个顺序练习:

  • 第一步:建好明细表,准备 50 行测试数据。
  • 第二步:用显式 SQL 手工查通所有条件组合。
  • 第三步:接入 MyBatis Plus 分页,跑通接口。
  • 第四步:写 Vue 查询页面,验证日期、关键字、下拉框联动。
  • 第五步:核对明细加总与库存结存是否一致。
  • 第六步:再增加数据权限、异步导出、性能优化。

每一步都有明确验证点,做到哪一步出问题,就能把问题范围缩小到数据库、接口还是前端交互。

明细查询管理在 ERP 进销存系统中属于“看起来简单、做起来需要谨慎”的模块。它的代码量不大,但对数据精度、查询性能、权限边界和业务口径的要求都很高。实现时要抓住一条原则:所有页面展示的数据,都必须能从底层明细行追溯到原始单据。守住这条原则,后续的报表、对账、分析和预警才有可靠的数据基础。

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

Gradle Wrapper下载卡死?从distributionUrl到国内镜像的彻底解决指南

最近在一个老项目上又碰见了这个折腾人的问题&#xff1a;Build 窗口卡在 Downloading https://services.gradle.org/distributions/gradle-7.6-all.zip &#xff0c;几十分钟过去进度纹丝不动&#xff0c;偶尔还会直接抛一个 SocketTimeoutException 。可能很多人一看到 …

作者头像 李华
网站建设 2026/9/7 16:40:49

非科班转AI第3周,特征工程的坑逼着我重刷人工智能入门,精度从0.62跳到0.83

非科班转AI第3周,特征工程的坑逼着我重刷人工智能入门,精度从0.62跳到0.83 转行学人工智能的第22天,我坐在电脑前盯着 accuracy: 0.62 的结果发愣。这套房价预测项目我已经调了三次模型,从线性回归换到随机森林,超参调优也试过网格搜索,可验证集上的表现就是上不去。我翻回自己…

作者头像 李华
网站建设 2026/9/7 16:40:41

NSGA-II求解风光火储P2G需求响应多目标优化调度问题

做电力系统调度这些年&#xff0c;我最大的感受是&#xff1a;单一能源的“最优”&#xff0c;放到系统里往往就不是最优了。风电光伏出力一高&#xff0c;火电就得往低压&#xff0c;压完可能又面临爬坡跟不上&#xff1b;储能能搬电量&#xff0c;但容量有限&#xff0c;也不…

作者头像 李华
网站建设 2026/9/7 16:40:29

Buzz 离线转文字完全指南:本地 Whisper 语音识别新手教程

Buzz 离线转文字完全指南&#xff1a;本地 Whisper 语音识别新手教程 【免费下载链接】buzz Buzz transcribes and translates audio offline on your personal computer. Powered by OpenAIs Whisper. 项目地址: https://gitcode.com/GitHub_Trending/buz/buzz 对着半小…

作者头像 李华
网站建设 2026/9/7 16:39:07

AI上下文测量:从文本到群体效应的多层次模型实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华