夜雨聆风学习资料网

ARTICLE · 1017678

源码专题-java0183-基于Spring Boot在线网络学习平台

源码专题-java0183-基于Spring Boot在线网络学习平台

寻亲信息管理与服务平台:技术栈、角色功能与工程亮点拆解

   一套面向走失人员家属、志愿者与平台运营方的寻亲信息枢纽。信息发布、地理标记、实时私聊、论坛互助与内容治理,在同一套工程里闭环完成。
>
> 后端 134 个 Java 源文件,14 张业务数据表,三个独立工程(后端 8080 / 后台 8081 / 门户 8082)。

一、系统定位与工程结构

平台要解决的其实是寻亲场景里最耗时间的三件事:信息发不出去、线索对不上人、沟通转不出去。对应到工程上,就是一套带地理坐标的寻亲档案、一条点对点的实时沟通链路,以及一个可治理的互助社区。
三个工程各自独立启动,共享同一套后端接口和同一份 MySQL 库:
  • 后端 springboot6n98hw4l:Spring Boot 服务,端口 8080,context-path /springboot6n98hw4l,提供全部 REST 接口与 WebSocket 端点。
  • 后台 springboot6n98hw4l-admin:管理员工作台,端口 8081,Element UI + ECharts,负责审核、统计与系统配置。
  • 门户 springboot6n98hw4l-front:家属与志愿者使用的前端,端口 8082,承载发布、检索、收藏、私聊与论坛。
  • 接口代理:两个前端各自通过 devServer.proxy 把 /springboot6n98hw4l 前缀转发到 8080,跨域与鉴权全部由后端拦截器统一处理。

二、技术栈

**后端基础**:Spring Boot 2.2.2.RELEASE + JDK 8,内嵌 Tomcat;统一 REST 风格,所有接口返回封装类 `R`(code / msg / data)。依赖包括 spring-boot-starter-web、spring-boot-starter-jdbc、javax.validation、commons-lang3、commons-io。
**持久层**:MyBatis-Plus 2.3,配 mybatisplus-spring-boot-starter 1.0.5。单表操作走 `EntityWrapper` 条件构造器,复杂统计写在 `mapper/*.xml` 中。自建工具 `MPUtil` 负责 likeOrEq / between / sort / allEQMapPre 四类动态条件拼装,`PageUtils` 统一分页封装,`SQLFilter` 做注入关键字过滤。数据库 MySQL 5.7,字符集 utf8mb4。
**实时通信**:spring-boot-starter-websocket,`@ServerEndpoint("/ws")` 端点配合 `WebSocketConfig`(ServerEndpointExporter)注册,在线会话存放在静态 `ConcurrentHashMap` 中。
**安全与脱敏**:自定义 `AuthorizationInterceptor` 做 Token 校验与跨域预检放行;`EncryptUtil` 负责 MD5;`DeSensUtil` 基于反射做字段级动态脱敏;`SQLFilter` 过滤注入关键字。
**后台前端**:Vue 2.6 + Vue Router 3 + Vuex 3 + Element UI 2.13,看板使用 ECharts 5.4 与 vue-echarts 6,另配 echarts-wordcloud、vue-json-excel 导出、print-js 打印、svg-sprite-loader 图标、js-md5。
**门户前端**:Vue 2.6 + Element UI 2.15,地图同时接入 `vue-baidu-map 0.21` 与 `vue-amap 0.5.10`(高德,含 Geocoder / CitySearch 插件),富文本用 vue-quill-editor(Quill 1.3.7),另有 swiper 5、emoji-mart-vue、animate.css、watermark-dom。
**第三方能力**:百度 AI Java SDK 4.4.1,封装在 `BaiduUtil` 中,可直接调用 OCR、人脸比对、图像分类、语音识别与翻译,并包含基于经纬度的逆地理编码。
**工具与集成**:Fastjson 1.2.8 序列化,Hutool 4.0.12 常用工具,Apache POI 3.11 处理表格导入导出,HttpClient 4.5.2 与 unirest 负责外部 HTTP 调用。

三、角色与核心功能

权限设计不是简单的菜单开关,而是从拦截器、会话变量一路下沉到 SQL 条件与字段输出:不同角色看到的数据范围和字段完整度都不一样。
管理员(users 表,role = 管理员,后台 8081)
  • 用户管理:账号 CRUD、按账号 / 姓名检索、用户人数统计、直接发起私聊。
  • 寻亲信息管理:全量审核与增删改查,查看评论、年龄分段统计、失踪者人数统计、首页统计口径维护。
  • 走失人员管理:维护走失人员档案,与寻亲信息形成两侧对照。
  • 交流论坛治理:主题帖与回帖的查看 / 删除,论坛分类维护(寻人启事、寻亲故事、志愿者交流、政策咨询、经验分享、寻亲成功、失散求助、爱心传递)。
  • 举报处理:查看举报记录、填写处理建议,推动状态从「处理中」流转到「已处理」。
  • 系统管理:公告信息、公告分类、首页轮播图(config 表 picture1~picture3)。
  • 数据看板:ECharts 渲染分组统计、时间趋势与词云。
用户 / 家属(yonghu 表,门户 8082,需登录)
  • 账号体系:注册(账号唯一索引去重)、登录(MD5 比对后签发 Token)、退出、忘记密码重置为初始密码。
  • 发布寻亲信息:寻亲人编号自动生成并带唯一索引,支持多张头像、性别年龄、失踪时间与地点、经纬度、富文本详细说明。
  • 检索与浏览:按编号 / 姓名 / 地点组合查询,点击量一键排序,热度 TOP 由 autoSort 接口按 clicknum 倒序返回。
  • 互动:收藏(storeup)、评论与回复(discussxunqinxinxi,含赞 / 踩 / 置顶)。
  • 实时沟通:详情页「联系 TA」直接拉起 WebSocket 私聊,支持文字与图片消息。
  • 社区:论坛发帖、回帖、匿名发布、举报违规内容。
  • 个人中心:资料维护、头像更换、密码修改、我的发布与收藏。
游客(未登录,@IgnoreAuth 放行)
  • 免登录浏览:寻亲信息列表、详情页、论坛、公告均通过 @IgnoreAuth 放行,降低线索获取门槛。
  • 热度排序:/autoSort 无需鉴权即可按点击量取热门内容。
  • 点击计数:每次进入详情自动 clicknum + 1 并刷新 clicktime,作为排序与统计的数据源。
  • 脱敏输出:游客视角下姓名、手机号、邮箱按规则打码,联系方式不直接暴露。

四、业务模块与数据模型

**寻亲信息 `xunqinxinxi`** —— 平台主数据,一条记录就是一个完整的寻人档案。
关键字段:xunqinrenbianhao(唯一索引)、qinrenxingming、touxiang(多图)、xingbie、nianling、shizongshijian、shizongdidian、jingdu / weidu、xiangxishuoming(富文本)、clicknum / discussnum / storeupnum。
**走失人员 `zoushirenyuan`** —— 以走失人视角组织的展示与维护入口,字段复用寻亲档案,按编号、姓名、地点检索。
关键字段:zoushirenbianhao、zoushirenxingming、zoushididian、clicknum 排序。
**交流论坛 `forum` / `forumtype`** —— parentid 构成树形回帖结构,支持匿名发布、置顶与置顶时间、封面图与分类名称。
关键字段:title、content、parentid、isdone 状态、istop / toptime、typename、cover、isanon、delflag。
**举报记录 `forumreport`** —— 完整的举报工单:谁举报了谁、原因、图片举证、处理建议与状态流转。
关键字段:forumid、reporteduserid、reason、picture、handleadvise、status(处理中 / 已处理)、reporttype。
**寻亲信息评论 `discussxunqinxinxi`** —— 挂在 refid 上的评论流,含回复内容、赞踩计数与用户 id 集合、置顶标记。
关键字段:refid、userid、content、reply、thumbsupnum / crazilynum、istop、tuserids / cuserids。
**消息与好友 `chatmessage` / `friend`** —— 私聊内容落库,format 区分文字(1)与图片(2),isread 标记已读;friend 表维护会话关系与申请状态。
关键字段:uid、fid、content、format、isread、type(0 申请 / 1 好友 / 2 消息)。
**公告资讯 `news` / `newstype`** —— 平台公告与寻亲资讯,分类覆盖政策解读、成功案例、防拐防骗、志愿动态、爱心公益、行业观察等。
关键字段:title、introduction、typename、picture、content、clicknum / thumbsupnum / storeupnum。
**收藏 `storeup`** —— 通用收藏表,用 tablename + refid 指向任意业务对象,type / inteltype 区分收藏场景与推荐类型。
**账号与鉴权 `yonghu` / `users` / `token`** —— 用户与管理员分表,token 表保存 userid、角色、表名与过期时间,是拦截器识别身份的唯一依据。

五、技术亮点

1. 地理坐标贯穿业务,双地图引擎 + 逆地理编码

寻亲记录除了文字地址,还单独存了 jingdu / weidu 经纬度字段。这是寻亲场景里最关键的检索维度:走失地点决定了谁能看到线索。前端同时引入 vue-baidu-map 与 vue-amap(高德,含 Geocoder、CitySearch 插件),后端 `BaiduUtil.getCityByLonLat` 调用百度 reverse_geocoding v3 接口(wgs84ll 坐标系)把坐标反解成省 / 市 / 区 / 街道,用于归档与区域统计。

2. WebSocket 会话池,点对点私聊与广播一套代码

端点用 `@ServerEndpoint("/ws?user_id=&to_id=")`,连接建立时在 onOpen 里解析 query 参数,把 userId 作为 key 放进静态 ConcurrentHashMap 会话池。静态方法 `sendMessage` 用 toUserId 是否为空区分单播与广播——不传就遍历推送给除自己外的所有在线端。收到 "ping" 直接回 "pong",维持长连接活性。消息本身走 chatmessage 表落库(format 区分文字与图片,isread 标记已读),刷新页面历史不丢。

3. 反射驱动的动态脱敏,按角色输出不同精度的字段

`DeSensUtil` 通过反射遍历对象及其父类字段,命中规则字典就原地改写值:姓名保留首字、手机号中间四位、身份证 7-16 位、银行卡保留前 6 后 4、邮箱保留首字符与域名。控制器只需声明 `deSens.put("xingming","名")`,page / list / info / detail 四个出口统一调用,家属联系方式不会在公开列表里裸奔。

4. 一套多维统计引擎,覆盖值统计、时间趋势与分段统计

后端把统计抽象成四组接口:
  • selectValue —— 按 x / y 列分组求和;
  • selectTimeStatValue —— 按 DATE_FORMAT 切日 / 月 / 年;
  • selectGroup —— 分组计数;
  • nianlingSectionStat —— 年龄分段。
年龄分段用 CASE WHEN 配合 UNION ALL 把一行多列拆成多行结果,二十岁以下到八十岁以上共五档,null 补 0,前端直接喂给 ECharts。列名进入 SQL 前先过 `SQLFilter.sqlInject` 关键字黑名单。

5. 数据权限下沉到 SQL:会话变量决定查询边界

拦截器校验 Token 后,把 userId、role、tableName、username 写进 session。控制器里 `if(tableName.equals("yonghu"))` 就自动给 EntityWrapper 追加 `eq("zhanghao", username)`,用户只能看到自己发布的寻亲信息;管理员不受限。同一份 page 代码服务两种角色,不需要各写一套。

6. 热度机制:点击即计数,热门内容自动前置

`info/{id}` 与 `detail/{id}` 在返回前先 selectById、clicknum + 1、写入 clicktime 再 updateById,然后才 selectView 返回视图对象。前台另有 `/autoSort` 强制按 clicknum 倒序,配合评论数、收藏数三个计数列,热门寻亲信息自然浮到前面,不需要额外的排行榜定时任务。

7. 内容治理闭环:从发帖到举报到处理建议

论坛用 parentid 组织树形回帖,isanon 支持匿名求助(寻亲场景里很多人不愿意实名),istop + toptime 控制置顶,delflag 做软删除避免回帖断链。举报侧记录举报人、被举报人、原因、截图举证与处理建议,状态从「处理中」流转到「已处理」,处理结果可追溯。

8. 百度 AI 能力预埋:从图片线索到人像比对

`BaiduUtil` 已封装通用高精度 OCR(basicAccurateGeneral,支持中英文、方向检测与语言检测)、AipFace 人脸比对(MatchRequest)、图像分类、人体分析、语音识别与文本 / 图片翻译。对寻亲平台来说,这些接口对应的正是真实业务动作:把寻人启事上的文字扫成结构化数据,把家属上传的老照片与线索照做相似度比对。

六、关键实现片段

WebSocket 会话池与单播 / 广播

```java
private static ConcurrentHashMap webSocketMap = new ConcurrentHashMap<>();
public static void sendMessage(String message, String fromUserId, String toUserId) {
if (toUserId == null || toUserId.isEmpty()) { // 广播
for (Map.Entry entry : webSocketMap.entrySet()) {
if (!entry.getKey().equals(fromUserId))
entry.getValue().session.getBasicRemote().sendText(message);
}
} else { // 点对点
WebSocket webSocket = webSocketMap.get(toUserId);
if (webSocket != null) webSocket.session.getBasicRemote().sendText(message);
}
}
public void onMessage(String message) {
if ("ping".equals(message)) sendMessage("pong", fromUserId, toUserId);
else sendMessage(message, fromUserId, toUserId);
}
```

拦截器:跨域预检放行 + Token 校验 + 会话注入

```java
if (request.getMethod().equals(RequestMethod.OPTIONS.name())) {
response.setStatus(HttpStatus.OK.value());
return false;
}
if (annotation != null) return true; // @IgnoreAuth 放行
TokenEntity tokenEntity = null;
if (StringUtils.isNotBlank(token)) tokenEntity = tokenService.getTokenEntity(token);
if (tokenEntity != null) {
request.getSession().setAttribute("userId", tokenEntity.getUserid());
request.getSession().setAttribute("role", tokenEntity.getRole());
request.getSession().setAttribute("tableName", tokenEntity.getTablename());
request.getSession().setAttribute("username", tokenEntity.getUsername());
return true;
}
writer.print(JSONObject.toJSONString(R.error(401, "请先登录")));

年龄分段统计:CASE WHEN + UNION ALL

```sql
SELECT '二十岁以下' as nianling,
case when t.二十岁以下 is null then 0 else t.二十岁以下 end total
from (
select sum(case when nianling <= 19 then 1 else 0 end) as 二十岁以下,
sum(case when nianling between 20 and 40 then 1 else 0 end) as 二十至四十岁,
...
from xunqinxinxi 1=1 ${ew.sqlSegment}
) t
union all ...
```

脱敏规则:反射改字段值

```java
Map deSens = new HashMap<>();
deSens.put("xingming", "名"); // 李华 → 李*
deSens.put("shouji", "手"); // 138****8881
deSens.put("youxiang", "邮"); // l*****@qq.com
DeSensUtil.desensitize(page, deSens);
```

七、运行与部署

  • 环境:JDK 1.8、Maven、MySQL 5.7(字符集 utf8mb4)、Node + pnpm。
  • 建库:导入 db/springboot6n98hw4l.sql,库名 springboot6n98hw4l,共 14 张表并带初始化演示数据。
  • 配置:application.yml 中修改数据源账号密码;上传目录为 static/upload,单文件大小上限 300MB。
  • 启动顺序:先起后端 8080,再分别启动后台 8081 与门户 8082;两个前端已配置 devServer 代理转发后端前缀。
  • 构建:前端 npm run build 产出 dist,后端通过 spring-boot-maven-plugin 打成可执行 jar。

代码获取

系统非商用,非开源,非无偿!,非无偿!,非无偿!

由本人开发,如需源码,请后台直接联系我并发项目编号,非无偿。

项目有很多,并未全部上传,如果未找到想要的,可直接咨询。源码非无偿!

软件定制及其他业务

文章有帮助的话,在看,转发吧。

谢谢支持哟 (*^__^*)

相关学习资料

返回首页浏览学习资料