ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Java+SSM+Flask混合架构家政服务平台设计与实战解析

Java+SSM+Flask混合架构家政服务平台设计与实战解析 接手这个家政服务平台项目的时候我其实有点意外——市面上同类毕设/私活项目大多是纯Java或者纯Python单线作战这个标题里直接写了“JavaSSMFlask”两套框架并行说明它是典型的混合架构SSM管后台管理端Flask管前端接口或爬虫/推荐服务。这种组合在真实的企业外包项目里不常见但在毕业设计和课程综合实践里很“吃得开”因为能同时展示Java和Python两方面的能力答辩时技术点也好铺开。这篇博文我就结合自己调试这类双框架项目的经验把家政服务平台从数据建模、双框架分工、接口联调、部署踩坑这四个维度完整拆一遍。源码、LW即论文/说明文档、调试文档这些交付物怎么组织才像样我也会一并讲清楚。如果你正打算做或者正在做类似的“JavaPython混合架构”项目这篇应该能帮你省下不少试错时间。1. 家政服务平台的业务边界与核心功能梳理先别急着写代码。家政公司服务平台这种题目业务边界其实比你想的要宽得多如果不先圈定范围很容易做成“四不像”。做这类系统第一步一定是把“平台到底服务谁、管哪些事、要什么数据”理清楚。我在拆这个题目时第一反应是家政公司服务平台的核心用户有两类——前台/管理端家政公司内部用和客户/用户端下单、预约、评价。有些参考项目还会加一个“阿姨端”或“家政服务人员端”但实际上毕设和外包项目里做到三端的很少两端的居多。管理端用SSMSpring SpringMVC MyBatis很顺手用户端如果是Web页面可以考虑用Flask写一套轻量的服务配合前端模板渲染或前后端分离的接口返回JSON。核心业务模块建议圈定为这几块服务项目管理保洁服务、家务服务、家庭保洁、清洁服务等具体服务类型的增删改查。服务名称、服务内容、价格元/小时或元/次、服务时长、适用面积、预约规则、是否支持加急等。订单管理核心中的核心。客户下单、后台接单、调派家政人员、订单状态流转待接单/待服务/服务中/已完成/已取消/待评价、订单报价、订单评价。家政人员管理人员档案、工种标签保洁、育儿、月嫂、家电清洗等、可约时段、服务区域、累计单量、星级评价。客户管理客户档案、历史订单、地址本、偏好标注比如常约哪个阿姨、是否接受新阿姨。评价管理订单完成后的评分与文字评价直接影响家政人员的星级展示。系统管理管理员账号、角色权限、操作日志。另外家政平台的营销属性很重可以考虑加上优惠券模块但不是必须。如果你的答辩周期有限优惠券可以先砍掉把订单状态机做精细比多做一堆花哨页面更有说服力。还有一点容易被忽略——数据统计看板。保洁公司的运营者对订单量、营收、人员完工率的统计需求非常刚需。这一块我强烈建议在管理端加一个简单的ECharts图表页统计近7天/30天的订单数、营收金额、各服务类型占比工作量不大但展示效果和答辩亮点直接上一个档次。范围定完之后你才能在表和接口设计上做到“心中有数”。否则做到一半发现用户端要加一个“服务人员车辆轨迹”之类的需求表结构推到重来就亏大了。2. SSM管理端与Flask用户端为什么这样分工“JavaSSMFlask”这个组合很多同学一上来就问能不能只用SSM能不能只用Flask答案是都能但题目的价值就在于“两套框架各管一段”。我一直认为这类混合架构最有讲究的不是框架本身而是边界的划分。划得好两套系统像两个独立团队协作互不拖后腿划得不好就是给自己挖个无底洞。我在这个项目里建议的分工方式是这样的端框架职责管理端SSM家政公司内部系统的全部功能人员管理、订单调度、财务对账、数据看板用户端Flask客户自助服务服务浏览、在线下单、预约时间选择、订单状态查询、评价提交共享基础MySQL两份框架指向同一个数据库通过表前缀和状态字段区分数据归属为什么要这样分我给你们几个实际的理由第一SSM的后台管理系统成熟度高。SpringMVC做页面跳转、权限控制过滤器、MyBatis写复杂多表查询简直是“教师爷”级别的方案。家政管理端的订单查询经常要联表查客户名、服务人员名、服务项目名MyBatis的SQL可控性很强写起来很清楚。第二Flask写用户端接口非常轻量。用户端基本都是“单表查询简单逻辑”用FastAPI也可以但Flask的资源更多、生态更成熟。下单这个动作涉及事务插入订单表、扣减服务人员可约时段、更新订单号序列Flask里用db.session.commit()一把梭也很直观。而且Flask配合模板直接渲染页面或返回JSON都行非常灵活。第三答辩和文档的匹配度高。论文里可以写“系统采用异构框架架构管理端采用Java EE企业级解决方案用户端采用Python轻量级框架体现不同技术栈在各自场景下的优势”——这句话放论文里很加分。如果你只用一个框架技术路线就显得单薄也不好凑篇幅LW主要是文档。再强调一点两端不要共享代码只共享数据库。有的同学喜欢把管理端和用户端嵌在同一个Web容器里认为能省部署麻烦但你会发现Session、拦截器、模板目录全部互相干扰调试起来极其痛苦。分两个端口比如SSM跑8080Flask跑5000是最省心的跨域配置做好就行。3. 数据库设计家政业务的关键表和状态流转家政平台的表结构和电商订单表结构很像但它特殊在“服务人员调度”和“预约时间”这两个维度。表设计得好不好直接决定你后面写SQL和调业务逻辑是躺着写还是爬着写。我按核心程度把表拆成三组来设计。第一组是用户与人员第二组是订单与调度第三组是辅助与配置。下面这一版是我在实际调试中验证过的结构你可以直接用3.1 用户和家政人员表customer——客户表存手机号、姓名、常用地址、备注。employee——家政服务人员表除基本档案外一定要有service_type服务工种标签比如保洁/月嫂/育儿/家电清洗、status空闲/忙碌/休息、service_area服务区域、rating综合评分、total_orders累计单量。这里我踩过一个坑如果把服务人员擅长类型设计成单个字段service_type下单的时候就非常难查“找一位能做保洁家电清洗的阿姨”。虽然毕设不需要做到很复杂的标签检索但至少你应该考虑用多对多关系——即employee和service_item之间通过employee_service_type关联表存储可服务类型。admin_user——后台登录管理员表字段不多但要加role区分超级管理员和普通客服。3.2 订单表和调度逻辑orders——主订单表字段至少包括order_no业务订单号便于人工沟通、customer_id下单客户、emp_id被指派的服务人员、service_item_id选择的服务项目、order_status状态、service_time预约服务时间、address服务地址、price订单金额、remark备注如自带工具/有宠物、create_time、pay_status、complete_time。这里最核心的是order_status。状态机在代码里一定要写死不要用魔法数字散落各处。我推荐的流转是0待接单用户下单后客服在后台可见1已接单客服接单并由管理员派发给服务人员2服务中服务人员点击开始服务或客服标记3已完成服务结束后触发结算和评价入口4已取消用户或客服取消5售后中完成后有纠纷可选代码层一定要把状态流转的合法性校验写清楚比如“已完成状态不能直接变成已接单”“已取消订单不能再进入派单列表”。这些细节面试官或答辩老师非常喜欢问也是代码质量高低的分水岭。order_schedule——预约时段表或者是orders表里冗余一个schedule_slot字段。家政预约最大的痛点是“某个阿姨周六下午2点到4点已经被约了但还在订单列表里被搜到”解决思路是查询空闲阿姨时用子查询排除掉orders表中status ! 4且service_time落在目标时段内的记录。具体SQL在第六章会给你先记住表结构要支撑这个查询。3.3 服务项目和评价表service_item——服务项目表存项目名、描述、类型标签、默认价格、市场价、单位次/小时、图片URL。这里要注意“价格单位”字段家政服务里既有按小时的也有按次的如果没有统一单位后面做订单总额计算很容易翻车。evaluation——评价表字段order_id唯一约束防止重复评价、customer_id、emp_id、rating1-5星、content、create_time。评价表回写employee.rating时要用平均数不要在两张表里同时存可推导的冗余数据除非你需要做看板统计。除了核心表别忘了配套表service_area区域表如果公司做多区域、coupon卡券表可选、operation_log日志表。日志表我单独强调一下——写一个简单的LogAnnotation切面或Flask里的装饰器记录所有管理端操作即可工作量不大但调试文档里有这个表能佐证你的系统“可审计”。4. SSM管理端的核心功能实现订单调度与人员排班管理端是SSM的主场。很多同学的SpringMVCMyBatis代码写得很“教科书”——Controller大而全Service薄如纸SQL全写在Mapper XML里。如果只是应付页面展示无所谓但家政平台的订单调度逻辑很容易出错Controller里堆业务代码会让你越debug越头大。4.1 使用MyBatis的复杂查询空闲服务人员查询我们来看最核心的“匹配阿姨”场景。用户提交预约时间后客服需要在后台看到这个时间段内哪些服务人员空闲且可提供指定服务。用MyBatis怎么优雅地写如果employee和service_item是多对多关系一条SQL同时过滤服务类型、状态、时间冲突select idselectAvailableEmployees resultTypecom.example.entity.EmployeeVO SELECT e.*, (SELECT AVG(rating) FROM evaluation ev WHERE ev.emp_id e.id) AS avg_rating FROM employee e WHERE e.status 1 AND e.id IN ( SELECT est.emp_id FROM employee_service_type est WHERE est.service_item_id #{serviceItemId} ) AND e.id NOT IN ( SELECT o.emp_id FROM orders o WHERE o.emp_id IS NOT NULL AND o.order_status NOT IN (4, 5) AND o.service_time lt; #{endTime} AND DATE_ADD(o.service_time, INTERVAL o.duration_minute MINUTE) gt; #{startTime} ) ORDER BY avg_rating DESC /select这段SQL的关键点在于时间区间冲突的判断不是简单service_time 某个点而是“已有的服务时间区间”与“新预约的时间区间”是否存在交集。如果订单表存了duration_minute服务时长分钟这个交集条件就是用区间重叠判断逻辑非常严谨。这条SQL跑通之后你后台的派单页面才算真正可用。4.2 订单调度事务处理派单操作涉及三步更新订单的emp_id、更新订单状态为“已接单”、给该服务人员加一个不可重复的调度记录防止同一时段被重复派单。这三步必须处于同一个事务里。Spring里推荐用Transactional注解注意schema别配错。我在调试时遇到过一个经典问题XML配置了一个事务管理器但Transactional没有指定rollbackFor Exception.class导致SQLException被检查异常捕获时事务不回滚订单被重复派给了两个阿姨。这个错误在答辩时很可能会被问到你自己测试时记得故意制造一次超时看看事务到底有没有回滚。Service层我建议这样组织OrderService订单的增删改查、状态流转、单据号生成。DispatchService调度逻辑方法签名大概长这样——DispatchResult dispatch(Integer orderId, Integer empId, String adminName)。EmployeeService人员档案、空闲查询、工时排班。把派单独立成Service有一个好处用户端Flask不需要直接操作派单逻辑它只需要调HTTP接口让SSM后端完成调度。这个边界清晰了两端联调就顺畅很多。4.3 管理端页面与权限控制SpringMVC的管理页面我用的是JSPJSTL没有引入前端框架。如果你有精力可以换成VueElementUI做前后端分离但工作量会膨胀我得提醒你别高估自己的工期。JSP配合Bootstrap足以应付“管理看板订单表格人员卡片”这三类主要页面。权限控制用SpringMVC的HandlerInterceptor即可。写一个LoginInterceptor校验Session里是否存在admin_user再配合一个简单的角色判断。不需要引入Shiro或Spring Security——对于这个量级的项目那两个框架的配置成本比你手写拦截器高得多而且答辩老师更想看到你对基础机制的理解。5. Flask用户端的三个重点下单流程、查询接口、跨域配置再来看用户端。Flask这一侧的定位是轻、快、独立。它能跑在单独的端口上所以开发和部署都不影响SSM端。但轻归轻三条核心链路必须做完整服务项目浏览、下单预约提交、订单进度与评价。5.1 服务项目浏览与详情接口Flask蓝图的组织方式我建议按功能拆main.py做应用入口和数据库连接views/里放蓝本models.py放简单的SQLAlchemy模型。路由设计很简单bp.route(/api/service_items) def list_service_items(): kw request.args.get(kw, ) page request.args.get(page, 1, typeint) per_page request.args.get(per_page, 10, typeint) query ServiceItem.query if kw: query query.filter(ServiceItem.name.like(f%{kw}%)) pagination query.paginate(pagepage, per_pageper_page, error_outFalse) items [item.to_json() for item in pagination.items] return jsonify({code: 0, data: items, total: pagination.total})注意一个坑SQLAlchemy的paginate依赖Flask-SQLAlchemy如果你用的是原生SQLAlchemy 2.0版本query.paginate方法已经移除了需要手写limit/offset。我一直建议这个项目直接用Flask-SQLAlchemy省心得多。to_json()方法建议在每个模型里单独定义不要每次返回时手动拼字典因为下单确认页和订单列表页要用到的字段不一样模型方法可以带个expand参数控制返回层级。5.2 下单预约提交的事务用户端下单是个典型事务插入订单记录、锁定服务人员的时间段、扣减库存/时段。我的建议是不要直接在Flask里手工写多条INSERT然后commit而是把“创建订单”这个操作封装成一个Service函数。即使Flask端不用Java那样严格的Service层函数级别的封装对复用和测试都友好。核心代码逻辑我建议长这样def create_order(customer_id, service_item_id, emp_id, service_time, address, remark): # 状态校验服务人员在该时段是否空闲 conflict Order.query.filter( Order.emp_id emp_id, Order.order_status.notin_([4, 5]), Order.service_time service_time duration, Order.service_time timedelta(minutesduration) service_time ).first() if conflict: raise BusinessException(该服务人员在该时段已被预约) # 锁定生成订单完成提交 order Order( order_nogenerate_order_no(), customer_idcustomer_id, emp_idemp_id, service_item_idservice_item_id, order_status0, service_timeservice_time, addressaddress, remarkremark ) db.session.add(order) db.session.commit() return order事务冲突检验必须放在数据库层面体现不能只靠前端“这个时段不可选”的提示拦截。真实环境里两个人几乎同时抢同一个时段的概率不低——你可以在orders表针对(emp_id, service_time)建唯一索引来兜底但因为有duration的存在唯一索引效果有限最稳的还是业务查询数据库行锁配合。作为毕设项目做到“代码里查重校验提交后状态回查”就已经超过大多数实现了。5.3 CORS和Session跨域问题SSM在8080端口Flask在5000端口用户端页面调用接口肯定涉及跨域。两个方案方案一用户端直接用Flask渲染Jinja2模板在服务端内部调用SSM的API或直连MySQL不经过浏览器跨域。这种方式最稳但等于用户端页面也只是个“展示壳”逻辑上绕了一圈。方案二前后端分离。用户端页面静态部署或由Flask提供静态文件页面用Ajax调Flask接口Flask再调SSM接口或直连数据库。页面跨域的根源在于浏览器的同源策略所以需要在Flask里配置CORSfrom flask_cors import CORS CORS(app, resources{r/api/*: {origins: http://localhost:8080}})这里有个关键细节CORS的origins要精确匹配不要用*。*表示所有源都放行答辩老师一眼就能看出你安全意识不到位。家用平台涉及用户手机号、家庭住址这种隐私数据跨域的Origin校验是基本线。还有一个坑用户端和管理端如果共用一套Session会因为Cookie的Domain和Path隔离问题互相踢下线。我建议干脆让用户端使用Token机制Flask端在登录成功后签发一个简单的itsdangerous签名Token后续请求携带在Authorization头里。SSM端维持Java原生的Session两端认证互不相干这个设计在我实测中是最省心的。6. 双框架联调与调试那些让人抓狂的典型问题到了联调阶段项目才算真正开始“上强度”。我调试这个项目时遇到的几个问题几乎每个做混合架构的人都会碰到我一个个说清楚。6.1 时间字段的Jackson反序列化格式Java端接收Flask传来的订单service_time时最容易报JSON parse error: Cannot deserialize value of type java.util.Date from String 2025-01-18 14:00:00。原因很简单Jackson默认的日期格式是ISO8601的2025-01-18T14:00:00而Flask端JSON序列化默认会带空格。解决方案是在全局配置里指定日期格式或者干脆统一使用时间戳。我建议全局采用字符串格式JsonFormat(pattern yyyy-MM-dd HH:mm:ss, timezone GMT8) private Date serviceTime;如果你是前后端分离建议在后端返回值里统一格式化后再返回。这个坑很基础但调试日志里反复出现的频率极高。6.2 MyBatis时间区间比较的参数转换前面提到DATE_ADD(o.service_time, INTERVAL o.duration_minute MINUTE) #{startTime}这个写法在MySQL里没问题但如果你把数据库迁移到Oracle或PostgreSQL函数就不兼容了。要做好SQL方言隔离。在MyBatis的Mapper XML里建议用databaseId功能指定多套SQL虽然这项目用不到但文档里提一句能体现你对兼容性的考虑。另外巨坑一个MyBatis往XML传java.time.LocalDateTime类型时如果你用的MySQL驱动是5.x驱动太老的话会抛Unsupported conversion type。解决方法是把驱动换成8.0以上并且JDBC URL加上serverTimezoneAsia/Shanghai。这个不做的话时区问题会在部署到你服务器的机器时随机爆发机上测试明明好好的一部署就快8个小时原因就是服务器时区不是东八区。血泪教训。6.3 Flask的SQLAlchemy连接池被耗尽如果你SSM和Flask共用同一个MySQL库两边同时开启事务后长时间不提交容易把连接池打满报MySQLConnectionPool: Too many connections。原因通常是Flask端调试模式开关debugTrue每次代码修改会reload但旧进程的数据库连接没有被完全释放。解决方案一是调试时把连接池调大二是养成随手db.session.close()的习惯三是如果Flask端并发不大直接把pool_size和max_overflow设一个合理值。这个我实测下来最有效的是app.config[SQLALCHEMY_ENGINE_OPTIONS] { pool_size: 10, pool_recycle: 3600, max_overflow: 5, }6.4 端口占用与服务启动顺序你有两个Web应用启动时要讲究顺序先启动MySQL再启动SSMTomcat默认8080最后启动Flask默认5000。如果SSM端Tomcat启动期间连不上数据库或Redis如果有它默认会启动失败退出但Flask端不会——Flask很宽容启动时不会强检验数据库连接要到第一个请求才炸。这就导致一个怪现象Flask服务看起来是起来了但一访问接口就是500日志却什么都不打。我强烈建议每个接口里加一个启动自检app.before_request def before_request(): try: db.session.execute(text(SELECT 1)) except Exception: return jsonify({code: 500, msg: database connection error}), 500这个简单的健康检查在你演示现场能救大命。7. 接口联调与前端演示页面的互补关系有个理解上的误区我得澄清用户端用Flask不一定非要这是个独立的前端项目。家政平台的客户没有那么多所谓用户端完全可以就是一套用Jinja2模板渲染的多页面站点下单流程从“浏览服务→选阿姨→选时间→提交订单→查看进度→评价”一共5个页面。这样就不需要单独部署Vue项目答辩演示时浏览器打开5000端口整个客户流程就闭环了。这5个页面我做下来感受是工作量其实集中在“选时间”这一步。因为你需要把某个阿姨未来7天可约/不可约的时段展示出来这背后就是一个时间段查询接口前端用表格或时间轴渲染。不可约时段用灰色禁用可约时段用高亮用户在手机上划起来也直观。我的实现方法Flask提供/api/employee/{emp_id}/slots?date2025-01-18内部查询该员工当天已有订单的占用时间段计算空余时间窗口返回一个可用时间段数组。前端用简单的JavaScript生成按钮。页面不需要复杂但要干净利落地把“空闲查询”这个核心业务演示给答辩老师看。管理端这边我反而建议把“订单调度看板”做得比普通CRUD好看一点——左边是待接单列表右边是全部服务人员及其今日任务时间线。用现成的Bootstrap表格一个时间线插件就能实现不需要写复杂的甘特图。但运营者看起来直观答辩演示时也拿得出手。另外Flask侧要加一个Swagger文档吗我的建议是不要加。Swagger对这份作业类项目不是刚需而且Flask生成Swagger文档容易和接口参数校验混在一起增加调试负担。手写一个简单的API清单文档Markdown格式放在README里即可。文档写清楚每个接口的URL、请求参数、返回结构这比你部署一堆美观但无用的调试页面实在得多。8. 源码、LW与调试文档的整理让项目一出手就很“职业”这节很重要因为很多人的代码功能没问题但交付物乱成一团导师或评阅人观感就很差答辩时也容易被追问“你的项目结构为什么这么乱”。千万记得平台项目的交付物不只是能跑的代码还包括结构规整的源码、说明文档LW和调试过程记录。8.1 源码结构规范我理想的源码目录长这样HousekeepingServicePlatform/ ├── backend-ssm/ # Java SSM 管理端 │ ├── src/main/java/com/example/... │ ├── src/main/resources/mapper/... │ ├── src/main/webapp/ # JSP页面 │ ├── pom.xml │ └── sql/init.sql # 建库建表脚本 ├── frontend-flask/ # Flask 用户端 │ ├── app.py │ ├── views/ │ ├── models.py │ └── requirements.txt ├── docs/ │ ├── 需求分析.md │ ├── 数据库设计.md │ ├── 接口文档.md │ └── 调试记录.md └── README.md后端SSM采用Maven标准结构Mapper XML放resources下的mapper目录。前端Flask用蓝图。一定要有requirements.txtFlask项目缺失这个文件到手基本跑不起来。数据库脚本单独放在schema.sql里并且要包含初始化数据服务项目、管理员账号示例等。你想想如果你交付后别人连上数据库发现一张空表还得自己造数据才能看到效果这体验就很差。初始化数据别偷懒服务项目起码8条家政人员8-10条订单10条以上分布在不同状态这样所有页面一打开就有数据。8.2 LW论文/设计文档的写作框架LW建议按这个顺序写摘要→绪论背景、现状、意义→需求分析用例图、功能需求、非功能需求→系统设计架构图、技术选型、数据库设计→系统实现模块截图核心代码说思路→系统测试功能测试表性能简单测试→总结。其中我特别想提醒的是需求分析部分不要抄百度。家政公司的真实痛点是服务人员空档时间管理复杂、客户预约爽约率高、结算时核算繁琐。你能在文档里写清楚这三个痛点并用系统设计回应它们论文的整体逻辑就立住了。8.3 调试文档的写法调试文档不是日志粘贴本。一个合格的调试文档要记录的是问题现象、排查链路、根因分析、解决动作、验证结果。我提供一个模板问题编号问题现象排查链路根因解决方案验证结果BUG-001用户端提交订单后后台订单列表偶尔出现订单时间与预约时间不一致查日志→确认是时区问题→检查JDBC URL和服务器时区JDBC连接串未设置serverTimezone在JDBC URL增加serverTimezoneAsia/Shanghai连续测试20单时间一致BUG-002后台派单页面重复显示同一时段的阿姨检查SQL→发现区间判断用了相等而不是重叠判断时间区间交集判断逻辑错误修改MyBatis SQL使用DATE_ADD区间重叠判断手动构造重叠场景查询正确调试文档的一个隐藏价值是答辩时如果你的项目被问到“有没有遇到比较复杂的问题”你直接把调试记录里的案例拿出来讲解决过程比临时想一个“我解决了什么”要有说服力得多。8.4 演示数据与演示脚本最后再补一个很多人忽视的点准备一份“演示脚本”。类似这样——用客服账号登录管理端看到看板统计→打开待接单列表→选一条新订单→点“派单”→弹出空闲阿姨列表→选人→切换用户端查看订单状态变成了“已接单”。你按这条线走一遍每一步都有数据支撑不露怯这比临时翻到哪个页面讲哪个页面强太多。9. 部署与运行从本地到服务器的最后一步这是很多项目“在家里跑得好好的一到服务器就崩”的重灾区。我接下来说的这几点你在本地开发时就要提前注意别等到要部署了再回头改。9.1 Linux服务器上的两个Java/Python进程管理如果你部署在一台CentOS或Ubuntu服务器上SSM端用Tomcat跑Flask端用gunicorn或uwsgi跑。关键点是别用nohup java -jar xxx.jar 这种土办法因为你关掉SSH客户端后进程经常就丢了。更稳妥的方式是使用systemd管理进程。这里我不展开systemd的全部配置只提两个容易出错的地方确保JVM和Python路径写对不要相对路径。服务启动顺序用systemd的Aftermysql.service来限定。我用systemd管理Flask时习惯用gunicorngunicorn -w 2 -b 0.0.0.0:5000 app:app两个worker就够了不用贪多。如果你的服务器内存只有2GB撑不住几个worker。9.2 数据库初始化与数据导入部署时用schema.sql导入数据库注意字符集CREATE DATABASE housekeeping_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE housekeeping_db; SOURCE /path/to/schema.sql;utf8mb4是必须的因为家政评价里用户可能输入emoji如果用utf8插入时直接报错。这个问题我遇到过不止一次。导入数据前把init_data.sql也一并执行保证页面不是空的。如果业务数据想更真实可以写一个简单的Python脚本批量生成模拟订单和评价数据但要控制生成逻辑——订单服务时间是过去7天能被统计图正确展示人群评分在3.5到5之间分布不要全打5星不然看板图表长得很假。9.3 JDK版本与Tomcat版本兼容性之前忘说SSM这边用JDK 8还是JDK 11会直接影响Tomcat版本选择。如果你们机房统一装了JDK 8Tomcat就用Tomcat 8.5或Tomcat 9如果本地已经装了JDK 17那就用Spring Boot 3.x实现而不是传统SSM。传统的SSMSpring 5.x SpringMVC 5.x MyBatis在JDK 17下需要额外处理模块访问限制比较折腾。这个兼容性矩阵写进调试文档里至少能让拿到你项目的人少走三天弯路。兼容版本搭配供参考组件推荐版本JDK1.8Tomcat8.5.xSpring5.2.xMyBatis3.5.xMySQL5.7 或 8.0Flask2.2.xFlask-SQLAlchemy3.0.x这套组合在我本机和服务器上跑了十几遍稳定性很好没出现过诡异的版本兼容问题。10. 测试用例设计家政业务容易翻车的三个场景测试章节是LW文档里的必备同时也是你实际保证质量的手段。很多人的项目就写了“增删改查都测试过”这太单薄。家政平台至少要设计如下几类测试用例。10.1 核心业务场景测试用例编号用例名称前置条件操作步骤预期结果TC-01正常下单全流程客户已登录服务人员空闲浏览服务→选择人员→选时段→提交订单→客服接单→派单→服务完成→评价订单状态依次流转评价后员工评分更新TC-02抢占同一时段同一员工两个客户同时请求同一日期时段两个会话同时提交预约仅一个成功另一个返回“该时段已被预约”TC-03订单取消订单处于待接单状态取消订单状态变为已取消该时段释放可被重新预约TC-04非空闲时段过滤员工某时段已有订单客户端查询该员工可用时段该时段不再出现在可用列表中TC-05重复评价拦截已完成订单已评价过再次提交评价系统提示“已评价”数据不重复其中TC-02是重点揉进了事务控制和并发检查TC-04是SQL时间重叠查询的验证。这两个用例能在测试文档里把核心难度体现出来。10.2 接口幂等性与异常处理接口幂等是容易被忽视的点客户在用户端点了两次“提交订单”如果接口没有做幂等控制就会出现两条相同订单。我的解决方案是给下单请求加一个前端生成的client_token每次进入下单页随机生成服务端收到后判断该Token是否已存在存在则直接返回原订单不再创建。这里有个小的实现建议Flask端可以单独建一张order_token表主键是client_token字段带order_id利用主键唯一约束避免并发下重复插入。虽然只是在毕设项目里但这个设计思路放在简历上很加分。10.3 页面与接口的异常场景还有一类测试不能省用户输入异常数据。包括手机号格式错误、服务时间为过去时间、地址为空、金额负数不开放改价则不存在、评价内容超长超过数据库varchar长度。每个接口都要写参数校验别指望前端校验兜底。# Flask端简单示例 from flask import request, jsonify def validate_create_order_params(): errors [] if not request.json.get(customer_id): errors.append(客户ID不能为空) if not request.json.get(service_time): errors.append(服务时间不能为空) # ... 更多校验 return errors前端校验是体验问题后端校验是安全问题。所有校验规则我建议集中在validate.py或Java的ValidationUtils里不要在Controller里散落一堆if。这样维护起来非常清爽答辩老师问“你是怎么保证数据安全性的”你直接展示这个模块就是答案。11. 个人体会这类混合架构项目的三个“值不值”项目做到后面我自己复盘了一下觉得这类JavaPython混合架构的家政平台项目有三个很值得复盘的地方第一个是异构系统协作能力的提升。你一个人得同时处理Java的强类型编译期约束和Python的运行时灵活性两边心智模型不一样联调时思维要来回切换。虽然过程有些痛苦但这类经验在真实工作中非常有用——很多中大型项目的内部系统确实就是多语言多框架共存的能在一方主导一方配合的架构里把业务跑通本身就是一种加分能力。第二个是对部署和运维的敬畏。你在本地IDE按一下运行就行但部署到服务器后Tomcat、Gunicorn、MySQL三者的开机启动顺序、日志清理、进程防杀、端口放开都有了新的要求。这些不亲自部署一次光看文档是学不会的。我强烈建议这个项目一定要走完“本地开发→打包→服务器部署→浏览器访问”全流程哪怕服务器是自己的虚拟机走一遍你获得的实战经验价值是翻倍的。第三个是信息检索和版本测评的耐心。这项目里最容易卡住你的不是业务逻辑而是中间件兼容问题的排查。你需要反复检查Spring版本、MyBatis版本、MySQL驱动版本、JDK版本的对应关系遇到一次数据库连接超时就Google很久。每天处理两三个这类问题你的排查链路思维就会比同龄人成熟很多。如果你时间充裕做完基础版本后我建议加三个扩展方向把评价数据做成情感倾向分析用Python的SnowNLP对评价文本算正负倾向、在管理端加一个订单量的日历热力图、给用户端加一个“常用地址一键下单”。这三个点都能自然利用上Flask的Python生态也能让论文的“创新点”章节有货可写。最后再分享一个我从这个项目里带走至今有用的习惯项目里所有需要人工录入的重复性操作哪怕看起来只有两三次也要想一遍“要不要写个脚本”。家政项目的初始化模拟数据、订单状态批量回放、报表统计样例都用脚本批量生成这个习惯帮我省了很多重复劳动也让调试文档的数据一直保持“可复现”的状态。如果你还在犹豫这个题目怎么做我建议先照着这篇的顺序把数据库构建好再动手写代码前后台联调起来会顺很多。
返回列表