news 2026/9/12 12:38:57

SSH框架CRM客户关系管理系统课设开发全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SSH框架CRM客户关系管理系统课设开发全解析

简介:本资源是一套基于Java技术栈开发的客户关系管理系统(CRM)完整实现方案,面向高校计算机专业课程设计、毕业设计及Java Web开发初学者,解决企业客户信息管理、销售流程跟踪与服务响应等典型业务场景建模与系统落地问题。压缩包共含全套可运行源码与配套文档,大小为86.92MB,涵盖JSP前端页面、Spring与SSH(Struts2+Spring+Hibernate)三层架构后端代码、MySQL数据库脚本及详细设计说明书、部署说明与测试记录,各模块职责清晰,便于理解MVC分层逻辑与框架整合要点。已有662人学习下载,源码经实测可一键部署运行,附带完整业务流程(客户录入、跟进记录、合同管理、统计报表等)与规范注释,特别适合用于巩固SSH框架集成、掌握传统Java Web开发全流程及撰写课程设计报告。 做Java Web课程设计的人,几乎都会碰到这样一个题目:客户关系管理系统,也就是CRM。市面上的参考项目一抓一大把,但代码质量只能说一言难尽——要么是框架整合层的XML配置乱成一团,要么是JSP页面里塞满了Java脚本片段,要么是数据库表设计干脆就是一锅粥。我前阵子帮一个学弟完整过了一遍基于Spring+Struts+Hibernate(也就是Java Web领域常说的SSH)的CRM客户关系管理系统源码和配套文档,花了两天时间把架构逻辑、核心表、请求流转和部署链路全部捋了一遍,最后发现这个老技术栈的项目其实非常值得拿来当教材:正面是它把分层架构和框架整合讲得很清楚,负面是它把经典SSH项目里很多让人抓狂的坑也全部暴露了出来。这篇就借这个CRM项目,把我梳理过程中的完整思路、关键设计和踩坑记录整理出来,给正在做课设、或者想把这个题目做成毕设的同学一个可直接参考的路线图。

1. 为什么2025年还要拆一个SSH老项目:需求定位与系统全貌

1.1 这个CRM到底管理什么:客户、跟进与商机

CRM字面意思是客户关系管理,但放到课设里,最常见的业务边界其实是围绕三件事:管住客户信息、记录跟进过程、统计销售结果。这三个动作听上去简单,落地到系统里却需要一整套数据结构和页面流支撑。

先说客户信息。一个客户档案不只是公司名称和联系方式,还应该包含客户来源(百度投放、朋友转介绍、展会、电销名单……)、所属行业、客户等级(A/B/C/D)、当前状态(潜在、意向、成交、流失)等维度。这些字段不是摆设,它们直接决定了后续所有统计报表的口径。比如要算"这个月新增了多少A级客户",前提就是客户表和等级字段设计得足够规范。

再说跟进记录。这是CRM和普通通讯录软件最大的区别。一个客户从线索到成交,中间可能要经过三五次甚至十几次的电话、面谈、微信沟通,每一次沟通都应该留下记录,并且下次跟进时间要能被系统提醒。跟进记录表本质上是一个带时间轴的流水表,每次操作都插入一条新记录,而不是覆盖旧记录——这一点很多初学者会搞错,觉得"我更新一下客户的描述不就行了",结果客户沟通历史全丢了。

最后是商机管理。商机可以理解成"可能成交的单子",它挂在客户下面,包含产品名称、预计金额、预计成交日期、销售阶段(初次接触、方案报价、商务谈判、赢单/输单)。商机表和客户表是一对多关系,一个客户名下可以有多个商机,但一个商机只能归属一个客户。这套模型做出来之后,"我手上正在跟进多少金额的商机"就能直接通过SQL聚合算出来,这也是CRM系统最有说服力的功能之一。

1.2 角色与权限:谁在用这套系统

CRM的使用者通常有三类角色。销售专员负责录入客户、记跟进、建商机;销售主管要能看到团队所有成员的数据,做业绩统计和分配;系统管理员负责维护用户账号、配置基础数据字典。

这套权限逻辑落到项目里,最常见的实现方式是做一个简单的角色字段,在用户表里加一个role属性,然后通过拦截器去判断当前登录用户能访问哪些Action。想再规范一点,就上RBAC(基于角色的访问控制)五张表:用户表、角色表、菜单表、用户角色关联表、角色菜单关联表。课设阶段用简单的角色字段已经足够,但如果你想让答辩更有亮点,把RBAC做进去是一个性价比很高的加分项。

1.3 模块清单与技术选型逻辑

按照上面的业务拆解,一个完整的SSH版CRM系统通常包含以下模块:系统管理(用户、角色、菜单)、客户管理(客户列表、新增、编辑、删除、分配)、联系人管理、跟进记录管理、商机管理、数据统计(按阶段统计客户数量、按月份统计成交金额、销售排行榜)、日程提醒(今日需跟进的客户)。

技术选型方面,本来Spring Boot + SSM现在已经是绝对主流,为什么还要用SSH?最直接原因是很多学校的课程体系还停留在SSH阶段,另一个原因是SSH的三层拆分方式把"表现层、业务层、持久层"的概念呈现得特别清晰,学完再看Spring Boot会更容易理解"约定大于配置"到底省了什么。所以如果你想把这个项目做得既符合课设要求,又能为后面Spring Boot学习打基础,SSH反而是个不错的中间站。

2. SSH三件套的真正分工:Spring容器、Struts2控制层与Hibernate持久层

2.1 请求从JSP到数据库的完整链路

先跟我走一遍完整的请求链路,这是理解SSH项目的钥匙。

用户在JSP页面点击"保存客户",表单以POST方式提交,请求URL是/customer_save。这个URL会先被web.xml里配置的Struts2过滤器拦下,由Struts2框架根据配置文件的映射规则找到对应的Action类,例如com.crm.web.action.CustomerAction。这里是第一层接力。

然后是Spring容器。Struts2的Action本身并不直接new出来,而是通过Spring的插件去容器里获取。为什么要这样?因为Action里要调用Service接口,Service又依赖Dao接口,Dao依赖Hibernate的SessionFactory,这一长串依赖如果全部手动new,代码会耦合得没法看。Spring通过依赖注入把Service实例塞进Action的属性里,Action只认接口,根本不用关心实现类是怎么创建的。

再往下一层是Service调用Dao。Dao层基于HibernateTemplate或者Hibernate的Session完成数据库操作,把结果返回给Service,Service包装成页面需要的数据结构返回给Action,Action再把数据放到值栈(ValueStack)中,最终通过Struts2的结果类型跳转到JSP页面渲染。

这个链路里每一层都有明确的边界:Action只做参数接收、调用和跳转控制;Service只做业务逻辑,比如"保存客户前先校验手机号是否重复";Dao只做增删改查。很多SSH项目写烂了,根本原因是有人把SQL直接写到了Action里面,或者Service里直接操作Session,分层名存实亡。

2.2 Spring为什么是整合的"胶水"

SSH里最关键的配置文件是applicationContext.xml,它是Spring IoC容器的核心。这个文件里通常配置了三类东西:数据源、SessionFactory、Service和Action的Bean定义。

数据源我建议用C3P0连接池,配置方式很简单,指定数据库驱动、URL、用户名、密码,再设置最小连接数和最大连接数。SessionFactory交给Spring管理后,Hibernate的主配置文件hibernate.cfg.xml甚至可以不要,把方言、显示SQL、自动建表这些属性统统丢到applicationContext.xml里用property标签配。

最容易被忽略的是事务配置。在SSH项目里,Service层的方法通常需要使用@Transactional注解或者通过AOP配置声明式事务。不配事务会出现什么情况?"保存客户的时候同时写客户表和跟进记录表,第二步抛异常,但客户表已经提交了"——这就是数据不一致。Spring管理Hibernate事务,本质上是对当前线程的Session做了绑定,只有绑定了事务的Session才能在失败时回滚。这个知识点答辩很喜欢问,一定要能讲清楚。

2.3 Hibernate懒加载与Session关闭顺序的经典拼图

SSH整合时有一个高频报错叫LazyInitializationException,字面意思是懒加载初始化异常。Hibernate的懒加载是"用到的时候才去数据库查",但如果Session已经关了,再去查关联对象就会抛这个异常。

我见过很多学弟用暴力解法:把Session关闭时间延长到视图渲染完(OpenSessionInView模式)。但生产环境里这种模式会长时间占用数据库连接,并发一上来连接池就炸了。更合理的做法是在Service层就完成所有关联数据的初始化,比如查询客户列表时,如果页面要显示每个客户最近的跟进时间,就在查询客户的同时用HQL join fetch把跟进记录查出来,或者直接用一条子查询计算。这样Action层拿到的已经是一个完整的数据对象,Hibernate的Session闭不关闭都不影响。

我个人的建议是在课设阶段,最省心的是把一个客户的联系人、跟进记录做成查询方法里显式初始化,配合DTO返回。虽然代码会多一点,但逻辑清楚,而且面试的时候你说得出"为什么要这么干",比写一堆OpenSessionInView配置要有说服力得多。

3. 数据库建模:一套可跑通全部业务的表设计

3.1 客户与联系人:一对多还是多对多

客户和联系人的关系,理论上一个客户可以有多个联系人,一个联系人可能需要关联多个客户(比如一个采购人同时对接两家供应商),但课程设计阶段做成一对多就够了,否则中间表的CRUD会把你绕晕。一对多的表设计非常直观:客户主表crm_customer,联系人表crm_contact,联系人表里有个customer_id外键指向客户主键。

客户主表的核心字段我列一下:id(主键自增)、name(客户名称)、level(客户等级)、source(来源渠道)、industry(行业)、status(客户状态)、phone(联系电话)、owner_user_id(归属销售)、create_time(创建时间)、update_time(更新时间)。这里的owner_user_id直接关联用户表,用于区分"这个客户是谁的",列表页就能按当前登录人过滤。

3.2 跟进记录:时间线设计的关键

跟进记录表crm_follow_up是最能体现业务理解的一张表。它的核心字段包括:idcustomer_id(关联客户)、contact_id(本次沟通的联系人)、content(沟通内容)、next_time(下次跟进时间)、create_by(跟进人)、create_time(跟进时间)。

这里有一个很关键的细节:跟进记录表的每条记录都代表一次独立的沟通事件,存储的是event,不是state。所以更新客户状态的时候,应该是客户端状态变化,跟进记录insert一条新数据,而不是update原有的跟进内容。下次跟进时间next_time一定要单独存,因为统计"今日需跟进客户"全靠这个字段,千万不能从跟进内容里去解析。

页面展示时,跟进记录通常是按create_time倒序排列的时间线。对应的HQL写法大概是from FollowUp f where f.customer.id = ? order by f.createTime desc,用HQL而不是SQL,是因为Hibernate可以直接操作对象属性,省去手动映射ResultSet的机械劳动。

3.3 RBAC权限表的落地方式

如果决定做RBAC,表结构是固定的五张核心表。用户表sys_user存储账号密码和基础信息;角色表sys_role存储角色名称和描述;菜单表sys_menu存储系统菜单和按钮权限;用户角色表和角色菜单表分别存关联关系。

菜单表我建议做成父子结构,通过parent_id字段自关联,这样页面导航就可以用一个递归方法渲染出多级菜单。权限控制的思路是:登录成功时查询当前用户的角色,再查出所有关联的菜单权限码,把权限码列表放到Session里。之后每个Action执行前,拦截器检查当前用户是否拥有对应权限码,没有就直接跳转到403页面。

数据库建表脚本可以直接放到项目根目录的sql/文件夹下,并附上初始化的测试数据。答辩时评委基本都会让现场演示,一个有测试数据的系统演示起来远比一个空表系统有说服力。

4. JSP页面层与Struts2协作:渲染、传参与跳转细节

4.1 用S标签和EL表达式替换页面里的Java片段

SSH老项目的JSP页面最容易被批评的问题,就是嵌入了大量<% %>Java脚本片段。一个典型的反面案例是客户列表页里用for循环加out.println去渲染表格。这种写法在课程设计里可能能跑,但代码可读性极差,而且混入的Java代码多了,页面维护成本会直线上升。

正确做法是用Struts2标签库(前缀通常为s)加EL表达式。客户列表页list.jsp的核心部分应该是:

<s:iterator value="pageResult.list" var="customer" status="st"> <tr> <td><s:property value="#customer.name"/></td> <td><s:property value="#customer.level"/></td> <td><s:property value="#customer.phone"/></td> <td> <a href="${pageContext.request.contextPath}/customer_edit.action?id=${customer.id}">编辑</a> <a href="${pageContext.request.contextPath}/customer_delete.action?id=${customer.id}" onclick="return confirm('确认删除?')">删除</a> </td> </tr> </s:iterator>

这样页面里没有一行Java代码,标签的语义也清楚。如果项目里用了JSTL,还可以配合c标签做分页条。注意:使用s:property输出属性时,value里必须是OGNL表达式;使用EL表达式的地方则不需要前缀。两种表达式混着用经常把人绕晕,我建议统一用OGNL,学习成本虽然高一点,但是和Struts2集成得最自然。

4.2 Action参数接收的三种方式与注意事项

Struts2接收页面参数有好几种方式,最常用的是Action中定义同名属性。比如表单里有一个customer.name输入框,Action里就定义一个Customer customer属性,并提供getter和setter,Struts2会自动把页面参数填充进对象的name字段。

另一种方式是实现ModelDriven<Customer>接口,getModel()返回一个Customer实例,Struts2会把所有同名参数直接注入这个model对象。这种方式的访问最省事,页面里直接写namephone,不需要customer.name前缀。但它的缺点也很明显:一个Action只能有一个model,当一个页面同时提交"客户"和"联系人"两类数据时就会很别扭。

还有一种更灵活的方式是使用@Param注解的方式,或者在Action里直接操作ActionContext.getContext().getParameters(),但普通业务场景用到的机会不多。

这里有一个常见的坑:页面提交的日期字符串形如"2025-05-20",而实体属性是java.util.Date类型,Struts2默认不能自动完成转换,必须提供类型转换器,或者在实体属性上配合Struts2的日期格式化注解。课设阶段最简单的做法是日期属性都用String接,Service层保存时再转成Date,虽然丑,但绝对不报错。

4.3 登录拦截器和权限过滤的通用写法

登录校验是每个web项目都绕不开的。Struts2实现登录拦截的标准方式是写一个拦截器类,继承AbstractInterceptor,在intercept()方法里判断Session中是否存在登录用户。

public class LoginInterceptor extends AbstractInterceptor { @Override public String intercept(ActionInvocation invocation) throws Exception { Map<String, Object> session = invocation.getInvocationContext().getSession(); User user = (User) session.get("loginUser"); if (user == null) { return "login"; } return invocation.invoke(); } }

然后在struts.xml里配置拦截器栈,把LoginInterceptor加到默认栈中,并且用excludeMethodsloginAction的执行方法排除掉,比如user_login不能拦截。如果不排除,登录功能本身也会被拦截,形成一个死循环。

权限过滤的思路类似:先判断登录用户是否为空,再判断当前用户角色是否具备访问当前Action的权限码。可以把权限码集合放在Session里,用Map结构缓存,登录后只查一次,避免每次请求都查数据库。

5. 部署与排错:从导入源码到跑通全流程

5.1 Eclipse/IDEA导入老项目的正确姿势

SSH项目大多是用Eclipse建立的,目录结构通常是src、WebContent、config等。如果你用的是IDEA,导入时要注意几个点。

第一,不要把整个zip直接解压后用IDEA打开,正确流程是:File -> New -> Project from Existing Sources,然后选择项目目录,IDEA会自动识别Web项目结构。第二,SSH项目依赖的jar包通常会放在WebContent/WEB-INF/lib目录下,导入后要确认这些jar已经被识别到,否则编译会报大量红色错误。第三,检查Project Structure里的Artifacts设置,确保Web应用名称正确,Facet里识别到了Web模块,否则部署到Tomcat时会404。

如果你在设置JSP页面高亮和代码提示时发现没有语法提示,多半是IDEA的Facet里没有正确绑定Web根目录。在Project Structure -> Facets -> Web里,把Web Resource Directory指向WebContent目录,再把Web.xml路径指定一下,JSP的语法高亮、EL表达式提示就全出来了。

5.2 数据库初始化与连接参数的坑

数据库初始化基本是照葫芦画瓢:先用Navicat或命令行创建数据库,然后执行项目里的sql脚本。需要特别注意的是字符集。如果你的表结构里大量使用varchar,建议建库语句用CREATE DATABASE crm DEFAULT CHARACTER SET utf8,否则中文会保存成问号。

然后就是修改数据库连接参数,位置在applicationContext.xml里的dataSource配置:

<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/crm?useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=false&amp;serverTimezone=Asia/Shanghai"/> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="user" value="root"/> <property name="password" value="123456"/>

如果你是MySQL 8.x版本,驱动类名要改成com.mysql.cj.jdbc.Driver,并且URL里必须带serverTimezone参数,否则会报时区错误。如果项目里的jar包还是旧的5.x驱动,建议直接去Maven仓库下最新的5.1.49版替换掉最老的版本,useSSL=false也要加上,避免SSL握手警告打扰你排查其他问题。

5.3 常见报错清单与解决方案

我梳理一下这类SSH项目最容易出现的几个典型报错:

  • 404页面:先看URL有没有拼对,再看struts.xml里action的namespace是否正确,最后确认Artifacts里是否已经包含struts.xml和所有的class文件。很多404是部署目录里没更新,clean一下Tomcat再重新发布就能解决。
  • 500错误显示ClassNotFound:通常是jar包没有进入WEB-INF/lib目录,也就是没有被构建到Artifacts里。在IDEA的Artifacts界面的Available Elements里把jar包右键选择Put into WEB-INF/lib。
  • Hibernate的MappingException:说的是某个实体映射文件找不到,检查hbm.xml文件位置是否在classpath下,以及实体类的配置里类的完整限定名是否对。
  • 中文乱码:在web.xml里配置CharacterEncodingFilter,强制请求和响应都用UTF-8,数据库连接URL加characterEncoding=utf8,JSP页面里保证pageEncoding="UTF-8"。这三个位置缺一不可。
  • com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:距离上一次通信时间超过连接池的空闲时间,连接被数据库关闭,但连接池还拿着这个死连接。解决办法是给C3P0配置testConnectionOnCheckout或者定期用testPeriod检测连接存活。

6. 拿到这套源码之后:代码复盘与升级路线

6.1 源码结构里最容易忽略的问题

很多源码包下载下来,里面文档和代码好像很完整,但真正导入开发工具后总会少这少那。我复盘这个项目时,重点看了三个地方。

第一是配置文件之间的引用路径。SSH项目的配置文件分布在src和config目录下,Spring配置文件用classpath加载,Struts的配置用package里的namespace做路由,路径一错,框架启动就会失败。第二是实体类与数据表的字段映射,注意看hbm.xml里每个字段的column属性和数据库表是否一致,有任何一个字段对不上,查询就会报SQL异常。第三是文档的版本描述,看文档里写的环境是JDK 1.7还是1.8,Tomcat是7还是8,MySQL是5.6还是8.0。老项目文档和实际环境不一致太常见了,按文档操作报错之后,要优先怀疑版本问题。

如果你拿到源码后想快速跑起来,我建议的顺序是:先建库执行SQL脚本,再改数据库连接配置,然后导入项目到IDE,最后启动Tomcat。不要先启动项目再改配置,那样报错信息会很多,不好定位。

6.2 从SSH到SSM再到Spring Boot的演进思路

这个CRM项目如果作为毕业设计,答辩时老师大概率会问一句"你觉得这套架构有哪些不足,怎么改进"。你要能接住这个问题。

SSH最明显的问题是配置繁杂,Struts2的拦截器机制和Servlet规范差异较大,Hibernate在复杂查询上的灵活性和MyBatis相比有差距。演进路线很清晰:用Spring MVC替代Struts2、用MyBatis替代Hibernate,组成SSM;再进一步就是用Spring Boot的自动配置把XML配置全部干掉,整合成Spring Boot + MyBatis Plus + Vue的前后端分离架构。

我建议在文档里专门写一节"未来改进方向",把业务层面和技术层面分开说。业务层面可以提数据看板、移动端适配、客户公海池自动分配;技术层面可以提代码生成器、Redis缓存热点客户、RabbitMQ处理消息通知。这样既展示了思考深度,也给答辩留了充足的提问空间。

6.3 文档应该怎么写才能加分

课程设计或毕业设计的文档,我见过太多流水账:第一章项目背景,第二章需求分析,第三章数据库设计,第四章代码实现,第五章测试——格式挑不出毛病,但内容全是空话。

真正能加分的文档写法是:写清"为什么这么设计"而不是只写"设计了什么"。比如数据库设计章节,除了贴表结构,要补充一段"客户和联系人为什么是一对多而不是多对多""跟进记录为什么采用追加式而不是覆盖式"。技术选型章节,要写一下"为什么选择SSH而不是SSM,这个项目里SSH的哪些特性被用到了、哪些坑是怎么避开的"。我在补文档的时候,把测试章节从"系统功能测试"细化成了功能测试、权限测试、并发场景测试三块,并且给每块配了具体的测试用例和预期结果,整个文档的含金量立刻不一样。

如果时间充裕,还可以在文档里加部署说明,把环境要求、数据库初始化步骤、Tomcat配置、常见问题一一列清楚。很多评分老师会照着文档尝试部署,如果你的文档能让他们一次性跑通,第一印象分就稳了——我最开始拿到这个项目时,文档里没有写MySQL 8的驱动替换说明,自己折腾了半小时才跑通,后来补文档时把这块写进去了,这就是实用文档和凑字数文档的区别。

最后再分享一点个人体会。虽然SSH这套技术栈在真实开发中已经逐渐被Spring Boot生态取代,但作为理解Java Web分层架构的"教科书",它依然有不可替代的价值。我在帮人梳理这个CRM项目时最大的感受是:框架选型只是表面,真正决定项目质量的永远是分层的清晰度、表设计的合理性和异常处理的完备性。如果你能把这个SSH版CRM做到"每一个请求到数据库的链路都能讲清楚、每一张表的功能边界都说得明白",那么过渡到Spring Boot和微服务只是时间问题;反之,即使换成了最新的技术栈,写出来的代码也还是那锅粥。按照上面这条路线去复盘和改造,一定比直接下个Spring Boot版本的代码改成自己名字要扎实得多。

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

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

基于Hadoop的房价数据分析系统:从爬虫到可视化的完整毕设指南

每年毕业季&#xff0c;计算机专业的同学都会面对同一个问题&#xff1a;毕业设计到底选什么题目。选得太简单&#xff0c;答辩时容易被老师追问到无话可说&#xff1b;选得太复杂&#xff0c;又可能做到一半发现时间根本不够。如果你正在为这个问题发愁&#xff0c;同时希望毕…

作者头像 李华
网站建设 2026/9/12 19:27:41

浙江研究生自主招生学校盘点:报考细节梳理,浙江万里学院报考要点解析

摘要在浙江研究生自主招生报考阶段&#xff0c;不少考生会把目光投向具备相关招生资质的民办院校&#xff0c;浙江万里学院是其中关注度较高的一所。研究生自主招生区别于全国统考&#xff0c;报考条件、考核形式、录取规则都有着自身特点。本文梳理浙江地区开展研究生自主招生…

作者头像 李华
网站建设 2026/9/12 13:36:21

postgresql数据库中~和like和ilike的区别

~&#xff08;暂且叫他波浪号吧&#xff09; 和 LIKE 和 ILIKE 操作符可以模糊匹配字符串&#xff0c;LIKE是一般用法&#xff0c;ILIKE匹配时则不区分字符串的大小写&#xff0c;~ 波浪号则可以使用正则匹配。LIKE和 ILIKE它们需要结合通配符使用&#xff0c;下面介绍两种常用…

作者头像 李华
网站建设 2026/9/12 16:15:01

企业级Agent记忆系统设计:从Context管理到LangGraph长期记忆

当你的 Agent 在生产环境跑了一个月&#xff0c;用户开始问出这样的问题&#xff1a;“你上次不是说帮我处理过工单吗&#xff1f;”“我不记得你是老客户了&#xff1f;”这时候你才会意识到&#xff0c;Agent 不是模型不够聪明&#xff0c;而是没有记忆。很多团队把 Agent 做…

作者头像 李华
网站建设 2026/9/2 18:35:15

基于YOLO的社交距离检测实战解析

简介&#xff1a;这是一份面向计算机视觉初学者与深度学习实践者的社交距离检测项目资源&#xff0c;基于YOLOv3目标检测模型实现人群间距实时分析&#xff0c;适用于疫情防控、智慧安防等实际场景。资源包共13个文件&#xff0c;包含3个核心Python脚本&#xff08;含主检测逻辑…

作者头像 李华