面向校招/社招,开源社区系统 Echo,基于目前主流 Java Web 技术栈,并提供详细的开发文档和配套教程 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
smallbeef1998

面向校招/社招,开源社区系统 Echo,基于目前主流 Java Web 技术栈,并提供详细的开发文档和配套教程

  •  4
     
  •   smallbeef1998 2021 年 2 月 12 日 4715 次点击
    这是一个创建于 1896 天前的主题,其中的信息可能已经有所发展或是发生改变。

    博主目前东南大学研究生在读,近一个月开发了一款社区系统,为接下来的校招做准备,同时开源出来和各位小伙伴一起交流学习。项目仍然存在很多不完善的地方,大家多多指教~

    • 仓库地址https://github.com/Veal98/Echo

    • 在线体验:项目已经部署到腾讯云服务器,各位小伙伴们可直接线上体验:http://1.15.127.74/

      已内置三种不同身份的用户:

      username password 特殊权限
      管理员 admin admin 数据统计、删除帖子
      版主 master master 置顶帖子、加精帖子
      普通用户 user user
    • 文档地址:文档通过 Docsify + Gitee Pages 生成,在线访问地址: https://veal98.gitee.io/echo

    核心技术栈

    后端:

    • Spring
    • Spring Boot 2.1.5 RELEASE
    • Spring MVC
    • ORM:MyBatis
    • 数据库:MySQL 5.7
    • 分布式缓存:Redis
    • 本地缓存:Caffeine
    • 消息队列:Kafka 2.13-2.7.0
    • 搜索引擎:Elasticsearch 6.4.3
    • 安全:Spring Security
    • 邮件任务:Spring Mail
    • 分布式定时任务:Spring Quartz
    • 日志:SLF4J (日志接口) + Logback (日志实现)

    前端:

    • Thymeleaf
    • Bootstrap 4.x
    • Jquery
    • Ajax

    界面展示

    首页:

    登录页:

    帖子详情页:

    个人主页:

    朋友私信页:

    私信详情页:

    系统通知页:

    通知详情页:

    账号设置页:

    数据统计页:

    搜索详情页:

    功能列表

    • 注册

      • 用户注册成功,将用户信息存入 MySQL,但此时该用户状态为未激活
      • 向用户发送激活邮件,用户点击链接则激活账号( Spring Mail )
    • 登录 | 登出

      • 进入登录界面,动态生成验证码,并将验证码短暂存入 Redis ( 60 秒)
      • 用户登录成功(验证用户名、密码、验证码),生成登录凭证且设置状态为有效,并将登录凭证存入 Redis 注意:登录凭证存在有效期,在所有的请求执行之前,都会检查凭证是否有效和是否过期,只要该用户的凭证有效并在有效期时间内,本次请求就会一直持有该用户信息(使用 ThreadLocal 持有用户信息)
      • 勾选记住我,则延长登录凭证有效时间
      • 用户登录成功,将用户信息短暂存入 Redis ( 1 小时)
      • 用户登出,将凭证状态设为无效,并更新 Redis 中该用户的登录凭证信息
    • 账号设置

      • 修改头像
        • 将用户选择的头像图片文件上传至七牛云服务器
      • 修改密码
    • 帖子模块

      • 发布帖子(过滤敏感词),将其存入 MySQL
      • 分页显示所有的帖子
        • 支持按照 “发帖时间” 显示
        • 支持按照 “热度排行” 显示( Spring Quartz )
      • 查看帖子详情
      • 权限管理( Spring Security + Thymeleaf Security )
        • 未登录用户无法发帖
        • “版主” 可以看到帖子的置顶和加精按钮并执行相应操作
        • “管理员” 可以看到帖子的删除按钮并执行相应操作
        • “普通用户” 无法看到帖子的置顶、加精、删除按钮,也无法执行相应操作
    • 评论模块

      • 发布对帖子的评论(过滤敏感词),将其存入 MySQL
      • 分页显示评论
      • 发布对评论的回复(过滤敏感词)
      • 权限管理( Spring Security )
        • 未登录用户无法使用评论功能
    • 私信模块

      • 发送私信(过滤敏感词)
      • 私信列表
        • 查询当前用户的会话列表
        • 每个会话只显示一条最新的私信
        • 支持分页显示
      • 私信详情
        • 查询某个会话所包含的所有私信
        • 访问私信详情时,将显示的私信设为已读状态
        • 支持分页显示
      • 权限管理( Spring Security )
        • 未登录用户无法使用私信功能
    • 统一处理 404 / 500 异常

      • 普通请求异常
      • 异步请求异常
    • 统一记录日志

    • 点赞模块

      • 支持对帖子、评论 /回复点赞
      • 第 1 次点赞,第 2 次取消点赞
      • 首页统计帖子的点赞数量
      • 详情页统计帖子和评论 /回复的点赞数量
      • 详情页显示当前登录用户的点赞状态(赞过了则显示已赞)
      • 统计我的获赞数量
      • 权限管理( Spring Security )
        • 未登录用户无法使用点赞相关功能
    • 关注模块

      • 关注功能
      • 取消关注功能
      • 统计用户的关注数和粉丝数
      • 我的关注列表(查询某个用户关注的人),支持分页
      • 我的粉丝列表(查询某个用户的粉丝),支持分页
      • 权限管理( Spring Security )
        • 未登录用户无法使用关注相关功能
    • 系统通知模块

      • 通知列表
        • 显示评论、点赞、关注三种类型的通知
      • 通知详情
        • 分页显示某一类主题所包含的通知
        • 进入某种类型的系统通知详情,则将该页的所有未读的系统通知状态设置为已读
      • 未读数量
        • 分别显示每种类型的系统通知的未读数量
        • 显示所有系统通知的未读数量
      • 导航栏显示所有消息的未读数量(未读私信 + 未读系统通知)
      • 权限管理( Spring Security )
        • 未登录用户无法使用系统通知功能
    • 搜索模块

      • 发布事件
        • 发布帖子时,通过消息队列将帖子异步地提交到 Elasticsearch 服务器
        • 为帖子增加评论时,通过消息队列将帖子异步地提交到 Elasticsearch 服务器
      • 搜索服务
        • 从 Elasticsearch 服务器搜索帖子
        • 从 Elasticsearch 服务器删除帖子(当帖子从数据库中被删除时)
      • 显示搜索结果
    • 网站数据统计(管理员专属)

      • 独立访客 UV
        • 存入 Redis 的 HyperLogLog
        • 支持单日查询和区间日期查询
      • 日活跃用户 DAU
        • 存入 Redis 的 Bitmap
        • 支持单日查询和区间日期查询
      • 权限管理( Spring Security )
        • 只有管理员可以查看网站数据统计
    • 优化网站性能

      • 使用本地缓存 Caffeine 缓存热帖列表以及所有用户帖子的总数

    待实现及优化

    以下是我个人发现的本项目存在的问题,但是暂时没有头绪无法解决,集思广益,欢迎各位小伙伴提 PR 解决:

    • 注册模块无法正常跳转到操作提示界面(本地运行没有问题)
    • 评论功能的前端显示部分存在 Bug
    • 查询我的评论(未完善)

    以下是我觉得本项目还可以添加的功能,同样欢迎各位小伙伴提 issue 指出还可以增加哪些功能,或者直接提 PR 实现该功能:

    • 忘记密码(发送邮件找回密码)
    • 查询我的点赞
    • 管理员对帖子的二次点击取消置顶功能
    • 管理员对已删除帖子的恢复功能(本项目中的删除帖子并未将其从数据库中删除,只是将其状态设置为了拉黑)

    本地运行

    各位如果需要将项目部署在本地进行测试,以下环境请提前备好:

    • Java 8
    • MySQL 5.7
    • Redis
    • Kafka 2.13-2.7.0
    • Elasticsearch 6.4.3

    然后修改配置文件中的信息为你自己的本地环境,直接运行是运行不了的,而且相关私密信息我全部用 xxxxxxx 代替了。

    本地运行需要修改的配置文件信息如下:

    1 )application-develop.properties

    • MySQL
    • Spring Mail (邮箱需要开启 SMTP 服务)
    • Kafka:consumer.group-id (该字段见 Kafka 安装包中的 consumer.proerties,可自行修改, 修改完毕后需要重启 Kafka )
    • Elasticsearch:cluster-name (该字段见 Elasticsearch 安装包中的 elasticsearch.yml ,可自行修改)
    • 七牛云(需要新建一个七牛云的对象存储空间,用来存放上传的头像图片)

    2 )logback-spring-develop.xml

    • LOG_PATH:日志存放的位置

    每次运行需要打开:

    • MySQL
    • Redis
    • Elasticsearch
    • Kafka

    另外,还需要事件建好数据库表,详细见下文。

    数据库设计

    用户 user

    DROP TABLE IF EXISTS `user`; SET character_set_client = utf8mb4 ; CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(50) DEFAULT NULL, `password` varchar(50) DEFAULT NULL, `salt` varchar(50) DEFAULT NULL, `email` varchar(100) DEFAULT NULL, `type` int(11) DEFAULT NULL COMMENT '0-普通用户; 1-超级管理员; 2-版主;', `status` int(11) DEFAULT NULL COMMENT '0-未激活; 1-已激活;', `activation_code` varchar(100) DEFAULT NULL, `header_url` varchar(200) DEFAULT NULL, `create_time` timestamp NULL DEFAULT NULL, PRIMARY KEY (`id`), KEY `index_username` (`username`(20)), KEY `index_email` (`email`(20)) ) ENGINE=InnoDB AUTO_INCREMENT=101 DEFAULT CHARSET=utf8; 

    讨论帖 discuss_post

    DROP TABLE IF EXISTS `discuss_post`; SET character_set_client = utf8mb4 ; CREATE TABLE `discuss_post` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) DEFAULT NULL, `title` varchar(100) DEFAULT NULL, `content` text, `type` int(11) DEFAULT NULL COMMENT '0-普通; 1-置顶;', `status` int(11) DEFAULT NULL COMMENT '0-正常; 1-精华; 2-拉黑;', `create_time` timestamp NULL DEFAULT NULL, `comment_count` int(11) DEFAULT NULL, `score` double DEFAULT NULL, PRIMARY KEY (`id`), KEY `index_user_id` (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

    评论(回复)comment

    CREATE TABLE `comment` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) DEFAULT NULL, `entity_type` int(11) DEFAULT NULL COMMENT '评论目标的类别:1 帖子; 2 评论 ', `entity_id` int(11) DEFAULT NULL COMMENT '评论目标的 id', `target_id` int(11) DEFAULT NULL COMMENT '指明对谁进行评论', `content` text, `status` int(11) DEFAULT NULL COMMENT '状态:0 正常; 1 禁用', `create_time` timestamp NULL DEFAULT NULL, PRIMARY KEY (`id`), KEY `index_user_id` (`user_id`), KEY `index_entity_id` (`entity_id`) ) ENGINE=InnoDB AUTO_INCREMENT=247 DEFAULT CHARSET=utf8; 

    私信 message

    DROP TABLE IF EXISTS `message`; SET character_set_client = utf8mb4 ; CREATE TABLE `message` ( `id` int(11) NOT NULL AUTO_INCREMENT, `from_id` int(11) DEFAULT NULL, `to_id` int(11) DEFAULT NULL, `conversation_id` varchar(45) NOT NULL, `content` text, `status` int(11) DEFAULT NULL COMMENT '0-未读;1-已读;2-删除;', `create_time` timestamp NULL DEFAULT NULL, PRIMARY KEY (`id`), KEY `index_from_id` (`from_id`), KEY `index_to_id` (`to_id`), KEY `index_conversation_id` (`conversation_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

    理想的部署架构

    我每个都只部署了一台,以下是理想的部署架构:

    功能逻辑图

    画了一些不是那么严谨的图帮助各位小伙伴理清思绪。

    单向绿色箭头:

    • 前端模板 -> Controller:表示这个前端模板中有一个超链接是由这个 Controller 处理的
    • Controller -> 前端模板:表示这个 Controller 会像该前端模板传递数据或者跳转

    双向绿色箭头:表示 Controller 和前端模板之间进行参数的相互传递或使用

    单向蓝色箭头:A -> B,表示 A 方法调用了 B 方法

    单向红色箭头:数据库或缓存操作

    注册

    • 用户注册成功,将用户信息存入 MySQL,但此时该用户状态为未激活
    • 向用户发送激活邮件,用户点击链接则激活账号( Spring Mail )

    登录 | 登出

    • 进入登录界面,动态生成验证码,并将验证码短暂存入 Redis ( 60 秒)

    • 用户登录成功(验证用户名、密码、验证码),生成登录凭证且设置状态为有效,并将登录凭证存入 Redis

      注意:登录凭证存在有效期,在所有的请求执行之前,都会检查凭证是否有效和是否过期,只要该用户的凭证有效并在有效期时间内,本次请求就会一直持有该用户信息(使用 ThreadLocal 持有用户信息)

    • 勾选记住我,则延长登录凭证有效时间

    • 用户登录成功,将用户信息短暂存入 Redis ( 1 小时)

    • 用户登出,将凭证状态设为无效,并更新 Redis 中该用户的登录凭证信息

    下图是登录模块的功能逻辑图,并没有使用 Spring Security 提供的认证逻辑(我觉得这个模块是最复杂的,这张图其实很多细节还没有画全)

    分页显示所有的帖子

    • 支持按照 “发帖时间” 显示
    • 支持按照 “热度排行” 显示( Spring Quartz )
    • 将热帖列表和所有帖子的总数存入本地缓存 Caffeine (利用分布式定时任务 Spring Quartz 每隔一段时间就刷新计算帖子的热度 /分数 见下文,而 Caffeine 里的数据更新不用我们操心,它天生就会自动的更新它拥有的数据,给它一个初始化方法就完事儿)

    账号设置

    • 修改头像(异步请求)
      • 将用户选择的头像图片文件上传至七牛云服务器
    • 修改密码

    此处只画出修改头像:

    发布帖子(异步请求)

    显示评论及相关信息

    评论部分前端的名称显示有些缺陷,有兴趣的小伙伴欢迎提 PR 解决~

    关于评论模块需要注意的就是评论表的设计,把握其中字段的含义,才能透彻了解这个功能的逻辑。

    评论 Comment 的目标类型(帖子,评论) entityType 和 entityId 以及对哪个用户进行评论 /回复 targetId 是由前端传递给 DiscussPostController 的

    一个帖子的详情页需要封装的信息大概如下:

    添加评论(事务管理)

    私信列表和详情页

    发送私信(异步请求)

    点赞(异步请求)

    将点赞相关信息存入 Redis 的数据结构 set 中。其中,key 命名为 like:entity:entityType:entityId,value 即点赞用户的 id 。比如 key = like:entity:2:246 value = 11 表示用户 11 对实体类型 2 即评论进行了点赞,该评论的 id 是 246

    某个用户的获赞数量对应的存储在 Redis 中的 key 是 like:user:userId,value 就是这个用户的获赞数量

    我的获赞数量

    关注(异步请求)

    • 若 A 关注了 B,则 A 是 B 的粉丝 Follower,B 是 A 的目标 Followee
    • 关注的目标可以是用户、帖子、题目等,在实现时将这些目标抽象为实体(目前只做了关注用户)

    将某个用户关注的实体相关信息存储在 Redis 的数据结构 zset 中:key 是 followee:userId:entityType ,对应的 value 是 zset(entityId, now) ,以关注的时间进行排序。比如说 followee:111:3 对应的 value (20, 2020-02-03-xxxx),表明用户 111 关注了实体类型为 3 即人(用户),该帖子的 id 是 20,关注该帖子的时间是 2020-02-03-xxxx

    同样的,将某个实体拥有的粉丝相关信息也存储在 Redis 的数据结构 zset 中:key 是 follower:entityType:entityId,对应的 value 是 zset(userId, now),以关注的时间进行排序

    关注列表

    发送系统通知

    显示系统通知

    搜索

    类似的,置顶、加精也会触发发帖事件,就不再图里面画出来了。

    置顶加精删除(异步请求)

    网站数据统计

    帖子热度计算

    每次发生点赞(给帖子点赞)、评论(给帖子评论)、加精的时候,就将这些帖子信息存入缓存 Redis 中,然后通过分布式的定时任务 Spring Quartz,每隔一段时间就从缓存中取出这些帖子进行计算分数。

    帖子分数 /热度计算公式:分数(热度) = 权重 + 发帖距离天数

    // 计算权重 double w = (wonderful ? 75 : 0) + commentCount * 10 + likeCount * 2; // 分数 = 权重 + 发帖距离天数 double score = Math.log10(Math.max(w, 1)) + (post.getCreateTime().getTime() - epoch.getTime()) / (1000 * 3600 * 24); 

    配套教程

    想要自己从零开始实现这个项目或者深入理解的小伙伴,可以扫描下方二维码关注公众号『飞天小牛肉』,第一时间获取配套教程, 不仅会详细解释本项目涉及的各大技术点,还会汇总相关的常见面试题,目前尚在更新中。

    并推荐我的开源教程类项目 『 CS-Wiki ,Gitee 推荐项目,目前已 0.9k star: 致力打造完善的 Java 后端知识体系,不仅仅帮助各位小伙伴快速且系统的准备面试(秋招 /社招),更指引学习的方向

    联系我

    有什么问题也可以添加我的微信,记得备注来意:格式 <u>(学校或公司 - 姓名或昵称 - 来意)</u>

    鸣谢

    本项目参考牛客网 Java 高级工程师课程,感谢老师和平台

    47 条回复    2021-05-24 14:13:42 +08:00
    stabc
        1
    stabc  
       2021 年 2 月 12 日
    你这是招聘贴么?
    coolyan
        2
    coolyan  
       2021 年 2 月 12 日
    请问你的图是用什么软件画的?
    smallbeef1998
        3
    smallbeef1998  
    OP
       2021 年 2 月 12 日
    @stabc 不是 哈哈哈哈,标题好像有歧义,是我自己准备秋招做的项目
    smallbeef1998
        4
    smallbeef1998  
    OP
       2021 年 2 月 12 日
    @coolyan draw.io 在线画图网站
    smallbeef1998
        5
    smallbeef1998  
    OP
       2021 年 2 月 12 日
    @smallbeef1998 改成 备战秋招 /校招,哈哈哈哈
    NIYIKI
        6
    NIYIKI  
       2021 年 2 月 12 日
    不错,已 star
    smallbeef1998
        7
    smallbeef1998  
    OP
       2021 年 2 月 12 日
    @NIYIKI 感谢,后续会不断完善
    selendipity
        8
    selendipity  
       2021 年 2 月 13 日
    做成这样一个项目可以进什么公司?
    smallbeef1998
        9
    smallbeef1998  
    OP
       2021 年 2 月 13 日 via iPhone
    @selendipity 结果并不重要吧 重要的是弄懂项目包含的技术点
    alexkuang
        10
    alexkuang  
       2021 年 2 月 13 日
    谢谢大佬,功能逻辑图很详细,正好最近学校做个项目包含社区系统,参考一下
    NVDA
        11
    NVDA  
       2021 年 2 月 13 日 via iPhone
    Why Kafka?
    smallbeef1998
        12
    smallbeef1998  
    OP
       2021 年 2 月 13 日 via iPhone
    @alexkuang 不是大佬啦,点个 star 就是最大的支持
    smallbeef1998
        13
    smallbeef1998  
    OP
       2021 年 2 月 13 日 via iPhone
    @Mirage09 高吞吐量、分布式架构、发布订阅模型
    learningman
        14
    learningman  
       2021 年 2 月 13 日 via Android   1
    就挺离谱的,都写了这么多页面了,在多写一个 install 也没多麻烦啊。。。
    每次看到这种要手动导入 SQL 的玩意儿就觉得一股业余的味
    smallbeef1998
        15
    smallbeef1998  
    OP
       2021 年 2 月 13 日 via iPhone
    @learningman 大佬 我确实经验不足
    smallbeef1998
        16
    smallbeef1998  
    OP
       2021 年 2 月 13 日 via iPhone
    @learningman 不知道您说的 install 是个啥意思
    JustSong
        17
    JustSong  
       2021 年 2 月 13 日 via Android
    @smallbeef1998 应该就是一个安装配置页面,类似 WordPress 的初始配置页面
    smallbeef1998
        18
    smallbeef1998  
    OP
       2021 年 2 月 13 日
    @JustSong 这不太好整吧,毕竟大家本地环境不一样
    JustSong
        19
    JustSong  
       2021 年 2 月 13 日 via Android
    @smallbeef1998 配置下数据库而已呀,本地环境有啥影响
    Cbdy
        20
    Cbdy  
       2021 年 2 月 13 日 via Android
    蛮怪的
    smallbeef1998
        21
    smallbeef1998  
    OP
       2021 年 2 月 13 日
    @Cbdy 大佬,怎么说
    smallbeef1998
        22
    smallbeef1998  
    OP
       2021 年 2 月 13 日 via iPhone
    为什么大家都在收藏却不愿意给个 star
    wbd31
        23
    wbd31  
       2021 年 2 月 13 日
    项目的 kafka 是用在了什么地方
    smallbeef1998
        24
    smallbeef1998  
    OP
       2021 年 2 月 13 日 via iPhone
    @wbd31 关注、点赞、评论的系统通知,以及相应的触发 Elasticsearch 数据的更新。可以看看逻辑图
    anrgct
        25
    anrgct  
       2021 年 2 月 13 日 via iPhone
    冲这么多字支持一下
    smallbeef1998
        26
    smallbeef1998  
    OP
       2021 年 2 月 13 日 via iPhone
    Austin2035
        27
    Austin2035  
       2021 年 2 月 13 日
    这种项目适合学习与教学,能说明轮子玩的够熟。
    Austin2035
        28
    Austin2035  
       2021 年 2 月 13 日
    我的建议是:
    1. console 提的报错与警告修改一下
    ```Javascript
    Uncaught SyntaxError: Unexpected token 'export'
    DevTools failed to load SourceMap: Could not load content for http://1.15.127.74/js/bootstrap.min.js.map: HTTP error: status code 404, net::ERR_HTTP_RESPONSE_CODE_FAILURE
    ```
    2.如果有余力,可以把网站修改为,首屏 SSR,其余的使用 restful API.
    好处在于,1. 增加了前后端分离的模式 2.提升了用户体验 3.减轻了服务器后端的压力(尤其高并发场景,能节约带宽与算力)
    smallbeef1998
        29
    smallbeef1998  
    OP
       2021 年 2 月 13 日 via iPhone
    @lookcos 感谢大佬建议啊 不过对我这样的初学者来说,前后端不分离相对来说比较友好,强行前后端分离容易把我搞懵
    lasfresas
        30
    lasfresas  
       2021 年 2 月 13 日
    感觉做的挺好
    smallbeef1998
        31
    smallbeef1998  
    OP
       2021 年 2 月 13 日 via iPhone
    @lasfresas 感谢
    wolfan
        32
    wolfan  
       2021 年 2 月 13 日 via Android
    移动端适配不成。
    chenlee9876
        33
    chenlee9876  
       2021 年 2 月 14 日 via iPhone
    老哥你直接把 IP 暴露出来真的大丈夫嘛?不考虑整个域名之类的嘛?
    smallbeef1998
        34
    smallbeef1998  
    OP
       2021 年 2 月 14 日 via iPhone
    @chenlee9876 不考虑 练手项目 没必要吧
    tousfun
        35
    tousfun  
       2021 年 2 月 14 日 via iPhone
    up 研一已经学了这么多东西了吗 本科也是 cs ?
    smallbeef1998
        36
    smallbeef1998  
    OP
       2021 年 2 月 14 日
    @919615766 对的
    Adaocean
        37
    Adaocean  
       2021 年 2 月 14 日 via Android
    @smallbeef1998 前辈的作品完整度也太高了。
    smallbeef1998
        38
    smallbeef1998  
    OP
       2021 年 2 月 14 日 via iPhone
    @Adaocean 哈哈哈哈 不然怎么在疯狂的内卷里活下来
    smallbeef1998
        39
    smallbeef1998  
    OP
       2021 年 2 月 14 日 via iPhone
    @wolfan 是这样的 我一个人精力实在有限 开源出来也是期待诸位大佬们帮助完善 让我跟在后面学习学习
    Adaocean
        40
    Adaocean  
       2021 年 2 月 14 日 via Android
    @smallbeef1998 很棒 赞赞赞
    hello2060
        41
    hello2060  
       2021 年 2 月 14 日 via iPhone
    4 系老校友只能帮顶了
    smallbeef1998
        42
    smallbeef1998  
    OP
       2021 年 2 月 14 日 via iPhone
    @hello2060 哈哈哈哈哈 多谢学长
    wssy
        43
    wssy  
       2021 年 2 月 16 日 via Android
    图画的蛮好
    smallbeef1998
        44
    smallbeef1998  
    OP
       2021 年 2 月 16 日 via iPhone
    @wssy 多谢
    golangLover
        45
    golangLover  
       2021 年 2 月 16 日
    大神厉害了
    smallbeef1998
        46
    smallbeef1998  
    OP
       2021 年 2 月 17 日 via iPhone
    @golangLover 不是大神 共同进步
    lycbug666
        47
    lycbug666  
       2021 年 5 月 24 日
    4 系老校友只能帮顶了
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5433 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 126ms UTC 07:08 PVG 15:08 LAX 00:08 JFK 03:08
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86