返回作品

RuoYi 开发实践项目

创建于 2025 年 7 月 17 日

标签
  • Java
  • Spring Boot 2.5
  • Shiro
  • Thymeleaf
  • MyBatis
  • MySQL 8
  • Druid
  • ECharts
  • Apache POI

项目介绍

本项目是一个以若依 RuoYi 4.8.0 单体版为底座、面向旅行社获客场景二次开发的「抖音客资管理」后台。业务背景是旅游公司通过抖音、视频号等渠道投放获取客户线索(即”客资”),需要一条完整的跟进链路:剪辑(editor)负责把各渠道来的客户资源登记入库 → 系统自动把客资指派给销售(salesman)→ 销售接收后跟进并反馈成交、无效、退款、是否出行等结果 → 经理(manager)跨组查看数据并监控团队转化情况。

项目在 ruoyi-system 模块下新增 com.ruoyi.dy 业务包(domain / mapper / service),在 ruoyi-admin 下新增 com.ruoyi.web.controller.dy 控制器与 templates/dy 页面模板,核心数据表为 t_customer_info(客户资料),配套 sql/cf-25.7.17.sql(Navicat 全库导出,含 QRTZ 定时任务表、sys_* 框架表与 1 万余条客资演示数据)。仓库 README.md 中还保留了完整的需求迭代记录(如”剪辑下拉可以折叠""添加客资过滤掉离职""列表销售下拉离职折叠""成交时间改成可选择的”等),是典型的”真实业务 + 脚手架快速落地”开发实践。

项目架构

项目采用若依经典的单体多模块 Maven 结构(ruoyi-admin / ruoyi-framework / ruoyi-system / ruoyi-common / ruoyi-quartz / ruoyi-generator),前后端由 Thymeleaf 模板 + Shiro 权限标签同源渲染,版本为 RuoYi 4.8.0(Spring Boot 2.5.15、Shiro 1.13.0、MyBatis、Druid、MySQL 8.0.26):

模块技术栈说明
ruoyi-adminSpring Boot 2.5.15、Shiro 1.13.0、Thymeleaf控制器与页面:controller/dy/DyCustomerController(客资 CRUD)、controller/dy/DyStatisticsController(转化率统计),页面模板位于 resources/templates/dy/customerdy/statistics
ruoyi-systemMyBatis、Druid框架系统模块 + com.ruoyi.dy 业务包:Customer / SalesmanStatistics 领域对象、CustomerMapper(XML 手写复杂 SQL)、CustomerService(数据权限注解、导入去重、CVR 计算)
ruoyi-quartzQuartz定时任务模块(QRTZ 表随库导出,支持 job 管理)
sql/MySQL 8cf-25.7.17.sql 全库导出、自定义表.sql 客资表建表脚本、ry_20240601.sql 框架基础库、quartz.sql 调度表

后端分层严格遵循若依规范:控制器负责参数组装与权限判断(@RequiresPermissions + shiro:hasAnyRoles 页面标签),服务层通过 @DataScope(deptAlias = "su1", userAlias = "su1") 注入部门/本人数据过滤 SQL,Mapper XML 手写完成复杂业务逻辑(指派轮询、批量更新、转化率聚合)。页面使用 Thymeleaf + bootstrap-table + bootstrap-select + ECharts,剪辑/销售下拉按”澜途 / 渠道 / 离职”分组渲染并支持折叠与多颜色标识。

核心功能

客资录入与自动指派。 剪辑在”新增客资”页填写客资(客户手机号/微信号)、渠道(抖音、视频号自热等)、地区、上传客资图片,保存时后端自动完成指派逻辑(DyCustomerController.addSave):若当前登录人是销售角色,客资直接分配给自己并同时写入指派时间与接收时间;否则调用 CustomerMapper.selectDesignate——一条基于 MySQL 8 窗口函数的 SQL,按部门(含子部门 FIND_IN_SET(#{deptId}, ancestors))过滤在岗销售(status='0'、角色 100),用 first_value(designate_time) over (partition by su.user_id order by designate_time desc) 取出每人最近一次指派时间后 order by ... limit 1,实现”最近指派最少的人优先”的轮询分发。

接收、改派与成交状态机。 销售通过”接收客资”接口(/dy/customer/receive)写入 receive_time;经理改派销售时 Mapper 用 if(salesman_id != #{customer.salesmanId}, current_timestamp, designate_time) 保证换人才刷新指派时间;成交状态用整型状态机管理:deal 0 初始 / 1 未成交 / 2 成交 / 3 退款,complete 0 初始 / 1 未走完 / 2 走完,effective 0 初始 / 1 无效 / 2 有效,并配套 invalid_type(无效类型)、feedback_img_path(销售反馈图片)、sales_remark(销售备注)、is_travel / travel_time(是否出行及出行时间)、estimated_amount / receipt_amount(预计与实际回款金额)等完整跟进字段。成交时 deal_time 由 SQL 自动记录首次成交时间(if(deal is NULL OR deal != 2, SYSDATE(), IFNULL(deal_time, SYSDATE()))),且允许在编辑页手动修改成交时间。

角色化数据权限。 客资列表按角色过滤:经理(manager)可看部门内全部客资,销售只能看指派给自己的(customer.setSalesmanId(userId)),剪辑只能看自己录入的(customer.setEditorId(userId));服务层再叠加 @DataScope 注解按部门数据权限二次过滤,导出接口同样复刻该过滤逻辑,避免越权导出。新增客资的剪辑下拉会自动排除离职人员(status='0'),销售/剪辑下拉均按部门分组并带”离职”折叠组。

Excel 批量导入导出。 基于若依 ExcelUtil 实现:支持下载导入模板(/importTemplate)、/importData 批量导入,导入时先查”同一剪辑最近三个月已录入过的客资”(selectExistCustomer),用 Collectors.groupingBy 将数据流拆分为新增/更新两组,新增走批量 insertCustomers,更新走 MySQL with upd as (...) update 的 CTE 批量更新;列表页支持按客资、渠道、地区、成交状态、上传/成交时间区间等多条件组合筛选并导出 Excel(/export)。

销售转化率统计看板。 统计页(templates/dy/statistics/statistics.html + DyStatisticsController.getStatisticsData)按销售聚合生成 CVR 数据:findCusDataCOUNT(c.effective = 2 OR NULL)COUNT(c.deal = 3 OR NULL) 等条件计数技巧统计客资总数、有效数、退款数、成交数、未成交数与未反馈数,成交率与有效成交率保留两位小数,后端按成交数倒序排序后以 9 组序列返回给 ECharts(macarons 主题)渲染分组柱状图;支持按剪辑(多选)、销售(多选)、渠道、地区、录入时间区间等条件钻取统计。

功能截图

暂无运行截图。

快速上手

  1. 准备数据库:在 MySQL 8 中依次执行 sql/ry_20240601.sql(框架基础库)与 sql/cf-25.7.17.sql(业务库,含 QRTZ 表、框架表及 1 万余条客资数据),库中预置了 admin / manager / editor / salesman 四类角色账号与部门数据。

  2. 启动后端:修改 ruoyi-admin/src/main/resources/application-druid.ymlapplication.yml 中的数据源地址、账号、密码后执行:

mvn clean package -DskipTests
java -jar ruoyi-admin/target/ruoyi-admin.jar
  1. 访问后台:浏览器打开 http://localhost:8080,使用管理员账号登录,在系统管理→菜单中确认 dy:customer:view 等权限已分配给对应角色。

  2. 体验流程:以剪辑账号进入”客资管理”新增一条客资(系统自动指派销售)→ 切换销售账号接收客资并填写跟进反馈(是否有效、是否成交、是否出行、回款金额)→ 切换经理账号进入”数据统计”查看各销售的成交率与有效成交率柱状图。

总结

这个项目展示了在若依框架上把一个真实业务需求打磨成可用系统的完整过程:业务侧以”客资”为核心对象,把剪辑、销售、经理三个角色的分工固化进代码——剪辑只管录入,销售只管跟进反馈,经理只看统计与改派;技术侧则充分利用了若依的既有能力(Shiro 权限、@DataScope 数据权限、ExcelUtil、操作日志),并把难点集中在 Mapper XML 的复杂 SQL 上:窗口函数实现”最少指派优先”的轮询分配、if() 表达式实现指派/成交时间的自动落库、COUNT(expr OR NULL) 实现条件聚合、with upd as (...) 实现批量更新,这些都是单体后台开发中非常实用的 SQL 技巧。对于想在若依/Spring Boot 脚手架上快速实现客户线索管理、工单分发、销售业绩统计类系统的开发者,本项目的角色权限设计与 SQL 写法是很有参考价值的实践样本。