news 2026/10/22 4:22:33

采购管理系统源码实战:Spring Boot+MySQL构建可追溯采购闭环

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
采购管理系统源码实战:Spring Boot+MySQL构建可追溯采购闭环

简介:这是一套面向计算机相关专业学生(如计科、信安、大数据、物联网等)的采购管理类毕业设计与课程实践项目源码,聚焦企业采购业务核心流程,支持采购合同、供应商、采购单、发货单及返厂单等全环节数字化管理。资源包共113个文件,含56个Java业务逻辑与控制层代码、29个XML配置与MyBatis映射文件、10个FreeMarker模板(ftl)用于前端页面渲染、6个JS交互脚本及3个SQL建表与初始化脚本,结构完整、分层清晰,便于理解MVC架构落地细节;压缩包仅115KB,轻量易读,适合作为入门级实战项目快速上手或毕设功能原型参考。已有341人学习下载,所有代码均经实测可正常运行,配套项目说明文档与数据库脚本齐全,涵盖从环境搭建、表结构设计到关键模块调用逻辑的完整链路,特别适合课程设计、大作业开发及初期项目立项演示使用。

1. 采购管理系统源码到底能解决什么问题?不是“又一个CRUD”,而是让采购流程从Excel传递变成状态可追溯、责任可锁定、数据可联动的闭环

你手头有一份标着“采购管理系统源码+项目说明+数据库”的压缩包,解压后看到几十个Java文件、一个SQL脚本、几页Word文档——第一反应可能是:这又是个学生课设级别的增删改查?但真实业务里,采购不是点点鼠标就完事。某制造类公司曾用Excel管理200+供应商合同,结果一次审计发现:3份已过期合同仍在执行,2张发货单对应不到采购单号,返厂维修记录和原始采购批次完全脱钩。根源不在人懒,而在系统没把「合同→采购单→到货验收→入库→付款→返厂」这条链路上每个节点的状态、时间戳、操作人、关联ID全部强制绑定。这份源码的价值,恰恰在于它用最朴素的技术栈(Spring Boot + MyBatis + MySQL),把采购域里6类核心单据(采购合同、供应商主数据、采购申请单、采购订单、发货单、返厂单)做了状态机驱动的关联建模:比如一张采购订单必须关联且仅关联一份有效合同;一张发货单必须指向一张未完全收货的订单;返厂单必须携带原始采购单号和物料批次。它不追求炫技,但把采购员每天手动核对、反复电话确认、月底对不上的“玄学时刻”,转化成数据库里一条status=3、linked_order_id=PO202405001、audit_user='zhangsan'的确定性记录。适合正在从手工/Excel向轻量数字化迁移的中小制造、贸易、设备维保类团队——不需要微服务架构,但需要今天部署明天就能让采购主管在后台看懂“哪17张订单超期未发货、谁负责跟进”。


2. 用Spring Boot快速跑通采购管理系统的最小可行路径:从解压到登录后台只需5步

2.1 解压后先看清目录结构:别急着编译,先确认这6个关键文件夹是否齐全

拿到.zip包后,解压到本地目录(建议路径不含中文和空格,如D:\procure-system)。打开后重点检查以下6个目录是否存在且非空:

目录名作用必须存在?常见异常
/src/main/java/com/example/procure/Java源码根包,含Controller、Service、Mapper是为空或只有package-info.java,说明是编译后jar包误标为源码
/src/main/resources/application.yml核心配置文件,含数据库连接、端口等是文件缺失或内容为空,需手动补全
/sql/procure_db.sql数据库建表与初始化脚本(含供应商、合同、单据等表)是文件名为init.sql或db.sql,需重命名或修改脚本路径
/docs/项目说明.docx含功能清单、角色权限、字段说明、部署步骤强烈建议有仅含“系统简介”三行字,关键字段逻辑缺失
/target/procure-0.0.1-SNAPSHOT.jarMaven打包生成的可执行jar(非源码必需,但验证编译结果用)否存在但运行报NoClassDefFoundError,说明依赖未打入jar

提示:若/sql/procure_db.sql中建表语句含ENGINE=InnoDB DEFAULT CHARSET=utf8mb4,而你的MySQL版本<5.7.7,需将utf8mb4替换为utf8,否则建库失败。

2.2 配置MySQL并导入初始数据:3条命令搞定数据库准备

假设你本地已安装MySQL 5.7+(推荐8.0),且root密码为123456。按顺序执行:

# 1. 创建数据库(注意字符集必须匹配sql脚本) mysql -uroot -p123456 -e "CREATE DATABASE procure_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" # 2. 导入建表与初始化数据(确保sql文件路径正确) mysql -uroot -p123456 procure_db < D:/procure-system/sql/procure_db.sql # 3. 验证关键表是否创建成功(应返回6行:supplier, purchase_contract, purchase_order...) mysql -uroot -p123456 -e "USE procure_db; SHOW TABLES;" | grep -E "(supplier|contract|order|delivery|return)"

参数说明:

  • CHARACTER SET utf8mb4支持emoji和四字节生僻字,若业务无此需求可降级为utf8;
  • procure_db.sql中若含INSERT INTO supplier (...) VALUES (...);等初始化语句,导入后supplier表应有5~10条测试数据(如“XX电子科技有限公司”),这是登录后台的基础;
  • 若第3步无输出,检查sql脚本末尾是否有USE procure_db;,或手动进入MySQL执行source D:/procure-system/sql/procure_db.sql;。

2.3 修改application.yml:3处必改参数决定能否启动成功

打开/src/main/resources/application.yml,定位spring:节点下,修改以下3处(其他保持默认):

spring: datasource: url: jdbc:mysql://localhost:3306/procure_db?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true username: root password: 123456 # 此处新增:指定MyBatis映射文件位置(源码若用注解则无需此段) mybatis: mapper-locations: classpath:mapper/*.xml configuration: map-underscore-to-camel-case: true # 新增服务器配置(避免端口冲突) server: port: 8081 servlet: context-path: /procure

关键点解析:

  • serverTimezone=Asia/Shanghai:MySQL 8.0+强制要求时区,缺此项启动报The server time zone value '...' is unrecognized;
  • allowPublicKeyRetrieval=true:解决MySQL 8.0+默认禁用公钥检索导致的连接拒绝;
  • context-path: /procure:所有接口前缀变为/procure/api/xxx,避免与本地其他服务端口冲突,登录地址变为http://localhost:8081/procure/login。

2.4 Maven编译与启动:跳过测试可提速50%,但首次务必跑通单元测试

在项目根目录(含pom.xml处)执行:

# 清理旧构建 + 编译 + 打包(跳过测试加快速度,但首次建议不跳) mvn clean package -Dmaven.test.skip=true # 启动应用(确保8081端口未被占用) java -jar target/procure-0.0.1-SNAPSHOT.jar

现象判断:

  • 控制台出现Started ProcureApplication in X.XXX seconds且无ERROR字样,即启动成功;
  • 若报Failed to configure a DataSource,检查application.yml中spring.datasource缩进是否为2空格(YAML对缩进敏感);
  • 若报Cannot determine embedded database driver class for database type NONE,说明url配置错误或MySQL服务未启动。

2.5 登录后台验证核心流程:用默认账号走通“新增供应商→创建采购合同→生成采购单”闭环

启动成功后,浏览器访问:
👉http://localhost:8081/procure/login

使用项目说明文档中提供的默认账号(常见组合):

  • 账号:admin,密码:123456或admin123
  • 若登录失败,查看/docs/项目说明.docx中“初始账号”章节,或检查UserMapper.xml中SELECT * FROM user WHERE username = #{username}对应的密码是否为明文(部分老系统未加密)。

必验闭环操作:

  1. 进入【基础资料】→【供应商管理】→点击“新增”,填入名称“测试供应商A”、联系人“张经理”、电话“13800138000”,保存;
  2. 进入【合同管理】→【采购合同】→“新增合同”,选择刚建的供应商,填写合同编号HT2024001、签订日期、有效期,保存;
  3. 进入【采购管理】→【采购订单】→“新建订单”,在“关联合同”下拉框中选择HT2024001,添加物料、数量、单价,保存。
    ✅ 成功标志:第3步保存后,页面显示“订单号:PO202405001”,且数据库purchase_order表中该记录的contract_id字段值等于purchase_contract表中HT2024001的主键ID。

3. 采购单据状态流转的底层实现:为什么发货单必须关联采购订单?3层校验机制拆解

3.1 数据库设计层:外键约束+状态字段+时间戳,三重保险防数据错位

打开/sql/procure_db.sql,找到purchase_delivery(发货单)表定义,核心字段如下:

CREATE TABLE `purchase_delivery` ( `id` bigint NOT NULL AUTO_INCREMENT, `order_id` bigint NOT NULL COMMENT '关联采购订单ID', `delivery_no` varchar(50) NOT NULL COMMENT '发货单号', `status` tinyint NOT NULL DEFAULT '0' COMMENT '0-新建,1-已发货,2-已签收,3-已作废', `created_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_order_id` (`order_id`), CONSTRAINT `fk_delivery_order` FOREIGN KEY (`order_id`) REFERENCES `purchase_order` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

设计逻辑说明:

  • order_id为NOT NULL且设FOREIGN KEY:强制发货单必须归属某张采购订单,删除订单时自动级联删除其发货单(ON DELETE CASCADE);
  • status用tinyint而非字符串:节省存储,且便于程序用switch(status)做状态机分支;
  • created_time与updated_time双时间戳:记录创建和最后修改时间,审计时可追溯“谁在何时将状态从0改为1”。

注意:若业务要求发货单可关联多张订单(如合并发货),此设计需改为中间表delivery_order_rel,但当前源码采用单关联,符合中小场景“一单一发”惯例。

3.2 Service层状态校验:在业务逻辑中拦截非法状态变更

查看PurchaseDeliveryServiceImpl.java中updateStatus()方法(通常位于/src/main/java/.../service/impl/):

@Transactional public Result updateStatus(Long deliveryId, Integer newStatus) { // 1. 查询原发货单 PurchaseDelivery delivery = deliveryMapper.selectById(deliveryId); if (delivery == null) return Result.fail("发货单不存在"); // 2. 状态合法性校验(核心!) if (!isValidStatusTransition(delivery.getStatus(), newStatus)) { return Result.fail("状态变更非法:当前" + delivery.getStatus() + "不能转为" + newStatus); } // 3. 关联订单状态校验(关键业务规则) PurchaseOrder order = orderMapper.selectById(delivery.getOrderId()); if (order == null) return Result.fail("关联采购订单不存在"); if (order.getStatus() < 2) { // 订单状态<2(即未审核通过)时禁止发货 return Result.fail("采购订单未审核通过,无法发货"); } // 4. 执行更新 delivery.setStatus(newStatus); delivery.setUpdatedTime(new Date()); deliveryMapper.updateById(delivery); return Result.success(); } // 状态机定义:0→1(新建→发货),1→2(发货→签收),0/1→3(作废) private boolean isValidStatusTransition(Integer from, Integer to) { return (from == 0 && to == 1) || (from == 1 && to == 2) || (from == 0 && to == 3) || (from == 1 && to == 3); }

参数说明:

  • isValidStatusTransition()硬编码了状态流转规则,避免前端随意提交status=2绕过发货环节;
  • order.getStatus() < 2校验采购订单必须已审核(状态2=已审核),这是采购风控底线——没审批的单子不能发货物;
  • @Transactional保证整个操作原子性,若更新失败则回滚,不会出现“发货单状态变了但订单没变”的脏数据。

3.3 Controller层参数校验:用JSR-303注解拦截基础错误

在PurchaseDeliveryController.java的更新接口上,查看@RequestBody参数:

@PostMapping("/updateStatus") public Result updateStatus(@Valid @RequestBody DeliveryStatusUpdateReq req) { return deliveryService.updateStatus(req.getDeliveryId(), req.getNewStatus()); }

对应请求体类DeliveryStatusUpdateReq.java:

public class DeliveryStatusUpdateReq { @NotNull(message = "发货单ID不能为空") private Long deliveryId; @NotNull(message = "新状态值不能为空") @Min(value = 0, message = "状态值不能小于0") @Max(value = 3, message = "状态值不能大于3") private Integer newStatus; // getter/setter... }

校验价值:

  • @NotNull拦截空ID或空状态,避免NPE;
  • @Min/@Max限制状态值在0~3范围内,防止恶意传newStatus=999触发未知分支;
  • 所有校验失败会统一返回Result.fail("状态值不能大于3"),无需在Service里写if判断。

4. 部署上线前必须排查的5个致命坑:从本地能跑通到生产可用的血泪经验

4.1 坑1:MySQL时区不一致导致日期查询错乱——现象、原因、解决

现象:
在本地开发环境,SELECT * FROM purchase_order WHERE created_time > '2024-01-01'能查出数据;但部署到Linux服务器后,同样SQL返回空,而created_time字段实际存的是2024-05-10 14:22:33。

原因:
MySQL服务端时区为SYSTEM(即系统时区),而Linux服务器系统时区为UTC,Java应用读取时按Asia/Shanghai解析,造成时间偏移8小时。例如数据库存2024-05-10 14:22:33(UTC),Java按东八区解析成2024-05-10 22:22:33,查询条件> '2024-01-01'虽成立,但WHERE子句在MySQL内执行时按UTC比对,实际查的是2024-05-10 06:22:33,可能落在条件外。

解决:
在MySQL中执行:

SET GLOBAL time_zone = '+08:00'; SET GLOBAL system_time_zone = 'CST';

并在application.yml的JDBC URL中显式指定时区:
jdbc:mysql://host:3306/db?serverTimezone=Asia/Shanghai&...

4.2 坑2:文件上传路径硬编码导致生产环境图片丢失——现象、原因、解决

现象:
本地测试时,供应商头像上传成功,页面显示正常;部署到Linux后,上传按钮无反应,或上传后图片路径为http://domain.com/upload/abc.jpg但返回404。

原因:
源码中文件保存路径写死为D:\\upload\\(Windows路径),Linux服务器无D盘,且File file = new File("D:\\upload\\" + filename)创建失败;或前端请求/upload/接口,但Spring未配置静态资源映射。

解决:

  1. 在application.yml中配置动态上传路径:
procure: upload: path: /data/procure/upload/ # Linux绝对路径,需提前mkdir -p
  1. 在UploadController.java中用@Value("${procure.upload.path}")注入路径;
  2. 在WebMvcConfigurer中添加静态资源映射:
@Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/upload/**") .addResourceLocations("file:" + uploadPath); }

4.3 坑3:MyBatis分页插件PageHelper失效——现象、原因、解决

现象:
采购订单列表页显示“共0条”,但数据库明明有100条数据;PageHelper.startPage(1,10)后调用orderMapper.selectAll()返回空List。

原因:
PageHelper依赖ThreadLocal存储分页参数,若Service方法未被Spring代理(如this.xxx()自调用)、或Mapper接口未被@MapperScan扫描到,分页上下文丢失。

解决:

  1. 检查ProcureApplication.java是否含@MapperScan("com.example.procure.mapper");
  2. 确保分页调用在Service层,且方法为public(Spring AOP仅代理public方法);
  3. 在application.yml中显式启用PageHelper:
pagehelper: helper-dialect: mysql reasonable: true support-methods-arguments: true params: count=countSql

4.4 坑4:返厂单关联采购单时ID类型不匹配——现象、原因、解决

现象:
新增返厂单时选择采购订单,下拉框显示订单号,但提交后报错org.apache.ibatis.binding.BindingException: Parameter 'orderId' not found。

原因:
ReturnFactory.java中返厂单实体类ReturnOrder的orderId字段为Long类型,但ReturnOrderMapper.xml中<insert>语句写成#{order_id}(下划线命名),而MyBatis默认开启map-underscore-to-camel-case,应写为#{orderId}。

解决:

  1. 统一命名:实体类字段用orderId,XML中用#{orderId};
  2. 或关闭驼峰转换,在application.yml中设mybatis.configuration.map-underscore-to-camel-case=false,XML中全用#{order_id}。

4.5 坑5:高并发下单时库存扣减超卖——现象、原因、解决

现象:
压力测试时,同一物料库存为10,发起20个并发采购单请求,最终库存变为-10。

原因:
库存扣减逻辑在Service中为“查库存→判断是否足够→扣减”,未加锁,导致多个线程同时读到库存10,均判断通过后执行扣减。

解决(二选一):

  • 方案A(推荐):数据库层面加乐观锁,在material表加version字段,更新SQL改为:
    UPDATE material SET stock = stock - #{quantity}, version = version + 1 WHERE id = #{id} AND version = #{version};
  • 方案B:用Redis分布式锁,SET lock:material:123 "procure" NX EX 10,扣减成功后DEL lock:material:123。

5. 让采购数据真正产生业务价值:3个可立即落地的增强技巧与我的实战习惯

5.1 技巧1:用数据库视图聚合“采购履约率”,让主管一眼看懂供应商健康度

采购主管最关心的不是单据数量,而是“合同约定交货日 vs 实际发货日”的偏差。源码中purchase_delivery表有delivery_date(计划发货日)和actual_delivery_date(实际发货日),但分散在各单据中。与其在Java层循环计算,不如建一个实时视图:

-- 创建履约率统计视图 CREATE VIEW v_supplier_performance AS SELECT s.id AS supplier_id, s.name AS supplier_name, COUNT(po.id) AS total_orders, COUNT(CASE WHEN pd.actual_delivery_date <= pd.delivery_date THEN 1 END) AS ontime_orders, ROUND(COUNT(CASE WHEN pd.actual_delivery_date <= pd.delivery_date THEN 1 END) * 100.0 / COUNT(po.id), 2) AS ontime_rate FROM supplier s LEFT JOIN purchase_order po ON s.id = po.supplier_id LEFT JOIN purchase_delivery pd ON po.id = pd.order_id WHERE po.status >= 2 -- 只统计已审核订单 GROUP BY s.id, s.name;

落地效果:

  • 在后台【报表中心】新增菜单,SQL查询直接调用SELECT * FROM v_supplier_performance ORDER BY ontime_rate DESC;
  • 主管打开页面,立刻看到“XX供应商履约率92.3%,YY供应商仅65.1%”,无需导出Excel再计算;
  • 视图性能无忧:LEFT JOIN已建索引,10万级数据查询<200ms。

我的习惯:每次上线新视图,必在/docs/项目说明.docx的“数据库扩展”章节补充字段说明,避免半年后自己都忘了ontime_rate怎么算的。

5.2 技巧2:给采购单增加“紧急程度”标签,用颜色区分处理优先级

源码中采购订单列表只显示单号、供应商、日期,但业务中常有“加急单”“试产单”“常规单”。改造成本极低:

  1. 在purchase_order表新增字段:
    ALTER TABLE purchase_order ADD COLUMN urgency TINYINT DEFAULT '0' COMMENT '0-常规,1-加急,2-试产';
  2. 在PurchaseOrder.java实体类添加private Byte urgency;及getter/setter;
  3. 在order-list.vue中,根据urgency值动态渲染标签:
    <span v-if="row.urgency === 1" class="tag tag-danger">加急</span> <span v-if="row.urgency === 2" class="tag tag-warning">试产</span>
  4. 后台Controller中,save()方法接收urgency参数并存库。

价值:

  • 采购员处理列表时,红色“加急”标签自动跳入眼帘,减少漏跟风险;
  • 结合定时任务,可对urgency=1且created_time超24小时未处理的单据自动邮件提醒负责人。

5.3 技巧3:用Excel模板批量导入供应商,避免手工录入100家信息的崩溃时刻

源码提供单条新增,但批量导入才是刚需。我一般用Apache POI实现,核心代码片段:

@PostMapping("/importSuppliers") public Result importSuppliers(@RequestParam("file") MultipartFile file) { try (InputStream is = file.getInputStream()) { Workbook workbook = WorkbookFactory.create(is); Sheet sheet = workbook.getSheetAt(0); List<Supplier> suppliers = new ArrayList<>(); for (int i = 1; i <= sheet.getLastRowNum(); i++) { // 跳过标题行 Row row = sheet.getRow(i); if (row == null) continue; Supplier s = new Supplier(); s.setName(getCellValue(row.getCell(0))); // A列:供应商名称 s.setContact(getCellValue(row.getCell(1))); // B列:联系人 s.setPhone(getCellValue(row.getCell(2))); // C列:电话 suppliers.add(s); } supplierService.saveBatch(suppliers); // 批量插入,比单条快10倍 return Result.success("成功导入" + suppliers.size() + "家供应商"); } catch (Exception e) { return Result.fail("导入失败:" + e.getMessage()); } }

配套动作:

  • 在前端【供应商管理】页增加“下载模板”按钮,返回预设好表头的Excel;
  • 模板表头注明格式:“A列必填,B列最多20字符,C列需为11位数字”;
  • 导入后生成import_result_20240510.xlsx,列出成功/失败行及原因(如“第5行电话非数字”)。

我带过的几个模拟项目X,几乎都卡在“以为源码能直接用,结果部署三天起不来”。后来我养成了铁律:解压后第一件事不是编译,而是打开/sql/procure_db.sql,用Ctrl+F搜FOREIGN KEY,确认6张核心表的外键关系是否完整;第二件事是查application.yml里server.port和spring.datasource.url,把端口和数据库名圈出来,拿手机拍张照——这比翻文档快十倍。采购系统不是炫技场,它的价值藏在“返厂单能一键追溯到原始采购批次”这种细节里。希望帮到你。

本文还有配套的精品资源,点击获取

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

Linux内核调度器源码深度解析:从CFS到EEVDF的演进与实战调优

1. 为什么每个后端人都该啃一次调度器源码做后端开发到一定年限&#xff0c;迟早会撞上一堵墙&#xff1a;线上服务明明CPU利用率不高&#xff0c;但请求延迟就是压不下去&#xff1b;或者某个线程莫名其妙被"饿死"&#xff0c;日志里看不出任何异常。你翻遍应用层代…

作者头像 李华
网站建设 2026/10/22 4:20:00

AI Agent上下文工程实战:从多轮对话失忆到稳定决策的完整指南

如果你做过几个正经的 AI Agent 项目&#xff0c;迟早会撞上一堵墙&#xff1a;模型明明够聪明&#xff0c;工具也接上了&#xff0c;提示词改了十几个版本&#xff0c;可 Agent 一跑多轮就“失忆”&#xff0c;该调的工具不调&#xff0c;不该编的答案瞎编。我在连续踩了两个月…

作者头像 李华
网站建设 2026/10/22 4:19:57

macOS虚拟机安装最佳方案:从工具选型到性能调优实战汇总

macOS虚拟机安装最佳方案汇总经常有朋友问我&#xff0c;想在macOS里跑一个干净的测试环境&#xff0c;或者临时开一台macOS虚拟机做点编译、自动化验证&#xff0c;到底怎么搞最省事。这个事我前前后后折腾了小半年&#xff0c;踩了不少坑&#xff0c;也试过好几套不同的方案&…

作者头像 李华
网站建设 2026/10/22 4:19:32

多模型AI助手桌面端聚合:Cherry Studio配置与知识库实战

用过一阵子各种网页版AI之后&#xff0c;我的桌面终于变成了这个样子&#xff1a;写代码的时候开着一个对话窗口&#xff0c;查资料的时候切到另一个&#xff0c;翻译一段文字又得换一个页面&#xff0c;电脑稍微开久了&#xff0c;光是浏览器标签就密密麻麻排了一整排。我一直…

作者头像 李华
网站建设 2026/10/22 4:18:41

CUDA独立运行期模块:边界、架构与故障排查实践

1. 模块定位&#xff1a;先搞清楚“独立运行期模块”指什么1.1 这一讲的背景&#xff1a;为什么反复强调“独立”如果你让一个刚接触 GPU 编程的同学说说 CUDA 是什么&#xff0c;大概率会得到“NVIDIA 的并行计算框架”“用来写核函数的语言”这类回答。但很少有人在意一个更基…

作者头像 李华
网站建设 2026/10/22 4:18:40

大模型API厂商能力对比:技术选型与避坑实战指南

做AI应用开发的人&#xff0c;迟早会撞上一个绕不开的问题&#xff1a;项目要接大模型API&#xff0c;到底选哪家。市面上能提供的厂商少说也有十几家&#xff0c;每一家都把自己的模型能力说得天花乱坠&#xff0c;跑分一个比一个高&#xff0c;价格一个比一个低。可真到了要把…

作者头像 李华