阅读和用户资产补齐之后,小程序还缺最后一层“有理由再回来”的内容氛围。很多项目做到这一步就停了,社区 Tab 还是空的,树洞只是个想法,举报入口没有,友链导航关于也只是以后再说,结果小程序看起来像个内容壳,没有社区感,也没有站点感。
Sourcelin 这轮把“社区扩展”单独收口,就是为了把说说、树洞、举报、友链、导航、关于这些看似分散的能力,真正变成一组能被用户感知到的轻社区入口。
本次阶段推文基于产品文档、仓库现状和本地可提取开发记录生成,未完整依赖远端会话历史。
这个阶段为什么不能只做一个社区列表
产品文档 5.1 第 6 周把这一阶段定义为:
- 说说基础互动
- 树洞
- 举报入口
- 友链
- 导航
- 关于
这几个点如果分开看,像是零散补功能;但从移动端体验看,它们其实都在回答一个问题:用户除了读文章,还能不能感知到这个站点在“活着”。
当前对应的页面和能力已经补齐
- 社区页:sourcelin-ui/sourcelin-ui-uniapp/src/pages/community/community.vue
- 说说发布:sourcelin-ui/sourcelin-ui-uniapp/src/pages-publish/say/say.vue
- 树洞投递:sourcelin-ui/sourcelin-ui-uniapp/src/pages-publish/treehole/treehole.vue
- 关于页:sourcelin-ui/sourcelin-ui-uniapp/src/pages-about/index/index.vue
- 友情链接:sourcelin-ui/sourcelin-ui-uniapp/src/pages-about/links/links.vue
- 网站导航:sourcelin-ui/sourcelin-ui-uniapp/src/pages-about/navigation/navigation.vue
- 社区 API:src/modules/community/api/community.api.ts
- 举报 API:src/modules/report/api/report.api.ts
- 埋点 API:src/modules/analytics/api/analytics.api.ts
- 后端补充:sourcelin-modules/sourcelin-blog/src/main/java/com/sourcelin/blog/controller/front/FrontReportController.java、FrontAnalyticsController.java
到这里已经能看出,这一阶段不是只写前端页面,而是把前端动作和后端接口一起补上了。
社区页已经不是占位,而是说说和树洞双列表
社区页现在直接承接两类内容:
const result = activeTab.value === 'says'
? await fetchSayPage(targetPage, 10)
: await fetchTreeholePage(targetPage, 10);
这个结构的好处很直接:
- 说说和树洞都能在一个一级 Tab 里承接
- 每个列表都有分页、互动和空态
- 发布入口会根据当前 Tab 自动切到“发说说”或“写树洞”
更重要的是,社区页里的点赞、收藏、评论抽屉和举报都已经接入真实动作,不再是浏览壳。
树洞投递这次真正补到了产品要求的细节
产品文档对树洞要求里有一个很容易被忽略的点:失败或中断后,草稿要本地暂存 1 小时。
这次树洞页正好把这个细节做进去了:
const DRAFT_KEY = 'publish.treehole.draft';
setStorage(DRAFT_KEY, {
nickname: nickname.value.trim(),
avatar: avatar.value.trim(),
content: value
}, 3600);
这段代码的价值,比单纯“能发树洞”更大。因为它说明小程序已经开始按真实用户操作来做体验,而不是只顾着把接口调通。
举报、导航、关于、友链都已经从占位变成真实入口
社区扩展最容易被拖延的,往往就是举报和站点信息,因为这些功能不够炫,但缺了以后体验很假。
现在举报链路已经接到后端:
export function createContentReport(payload: ContentReportPayload): Promise<void> {
return http.post<void>('/front/reports', payload);
}
后端也补了对外 Controller:
@RestController
@RequestMapping("/front/reports")
public class FrontReportController extends BaseController
{
@PostMapping
public Void create(@Valid @RequestBody FrontContentReportDTO body)
友情链接、导航和关于页也都不再是“建设中”,而是已经能拉数据、筛选、复制链接和提交申请。尤其导航页,已经补了分类切换和关键词筛选,这比只展示一页静态列表更像真实站点入口。
为什么我现在确认“社区扩展”可以勾选完成
之前这一阶段不能勾,原因非常明确:
- 树洞投递还没闭环
- 导航、关于等页面还有占位
- 社区页还不足以形成访问理由
这次复核后,这几个阻断点都已经不在了:
- 社区 Tab 已具备说说/树洞双列表
- 树洞匿名投递支持 1 小时草稿暂存
- 举报入口已经接入前后端
- 友链、导航、关于全部有真实内容与交互
按产品文档第 7 章“只有核心页面、核心交互、占位替换和验收项全部闭合才算完成”的口径,这一阶段已经满足勾选条件,所以我会把它转为已完成,并补上这篇统一长文。
社区扩展完成状态图
以下是社区扩展各模块的完成状态可视化,展示了从"占位"到"真实功能"的转变:
#mermaid-svg-QHL8KTlpyjN6OV4Y{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-QHL8KTlpyjN6OV4Y .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-QHL8KTlpyjN6OV4Y .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-QHL8KTlpyjN6OV4Y .error-icon{fill:#552222;}#mermaid-svg-QHL8KTlpyjN6OV4Y .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-QHL8KTlpyjN6OV4Y .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-QHL8KTlpyjN6OV4Y .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-QHL8KTlpyjN6OV4Y .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-QHL8KTlpyjN6OV4Y .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-QHL8KTlpyjN6OV4Y .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-QHL8KTlpyjN6OV4Y .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-QHL8KTlpyjN6OV4Y .marker{fill:#333333;stroke:#333333;}#mermaid-svg-QHL8KTlpyjN6OV4Y .marker.cross{stroke:#333333;}#mermaid-svg-QHL8KTlpyjN6OV4Y svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-QHL8KTlpyjN6OV4Y p{margin:0;}#mermaid-svg-QHL8KTlpyjN6OV4Y .pieCircle{stroke:#000000;stroke-width:2px;opacity:0.7;}#mermaid-svg-QHL8KTlpyjN6OV4Y .pieOuterCircle{stroke:#000000;stroke-width:1px;fill:none;}#mermaid-svg-QHL8KTlpyjN6OV4Y .pieTitleText{text-anchor:middle;font-size:25px;fill:#000000;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}#mermaid-svg-QHL8KTlpyjN6OV4Y .slice{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;fill:#000000;font-size:17px;}#mermaid-svg-QHL8KTlpyjN6OV4Y .legend text{fill:#000000;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:17px;}#mermaid-svg-QHL8KTlpyjN6OV4Y :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
40%
25%
20%
15%
社区扩展模块完成状态
说说系统
树洞功能
举报机制
站点信息
#mermaid-svg-au4eKWNb1jyTLe5Y{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-au4eKWNb1jyTLe5Y .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-au4eKWNb1jyTLe5Y .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-au4eKWNb1jyTLe5Y .error-icon{fill:#552222;}#mermaid-svg-au4eKWNb1jyTLe5Y .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-au4eKWNb1jyTLe5Y .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-au4eKWNb1jyTLe5Y .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-au4eKWNb1jyTLe5Y .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-au4eKWNb1jyTLe5Y .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-au4eKWNb1jyTLe5Y .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-au4eKWNb1jyTLe5Y .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-au4eKWNb1jyTLe5Y .marker{fill:#333333;stroke:#333333;}#mermaid-svg-au4eKWNb1jyTLe5Y .marker.cross{stroke:#333333;}#mermaid-svg-au4eKWNb1jyTLe5Y svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-au4eKWNb1jyTLe5Y p{margin:0;}#mermaid-svg-au4eKWNb1jyTLe5Y .mermaid-main-font{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}#mermaid-svg-au4eKWNb1jyTLe5Y .exclude-range{fill:#eeeeee;}#mermaid-svg-au4eKWNb1jyTLe5Y .section{stroke:none;opacity:0.2;}#mermaid-svg-au4eKWNb1jyTLe5Y .section0{fill:rgba(102, 102, 255, 0.49);}#mermaid-svg-au4eKWNb1jyTLe5Y .section2{fill:#fff400;}#mermaid-svg-au4eKWNb1jyTLe5Y .section1,#mermaid-svg-au4eKWNb1jyTLe5Y .section3{fill:white;opacity:0.2;}#mermaid-svg-au4eKWNb1jyTLe5Y .sectionTitle0{fill:#333;}#mermaid-svg-au4eKWNb1jyTLe5Y .sectionTitle1{fill:#333;}#mermaid-svg-au4eKWNb1jyTLe5Y .sectionTitle2{fill:#333;}#mermaid-svg-au4eKWNb1jyTLe5Y .sectionTitle3{fill:#333;}#mermaid-svg-au4eKWNb1jyTLe5Y .sectionTitle{text-anchor:start;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}#mermaid-svg-au4eKWNb1jyTLe5Y .grid .tick{stroke:lightgrey;opacity:0.8;shape-rendering:crispEdges;}#mermaid-svg-au4eKWNb1jyTLe5Y .grid .tick text{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;fill:#333;}#mermaid-svg-au4eKWNb1jyTLe5Y .grid path{stroke-width:0;}#mermaid-svg-au4eKWNb1jyTLe5Y .today{fill:none;stroke:red;stroke-width:2px;}#mermaid-svg-au4eKWNb1jyTLe5Y .task{stroke-width:2;}#mermaid-svg-au4eKWNb1jyTLe5Y .taskText{text-anchor:middle;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}#mermaid-svg-au4eKWNb1jyTLe5Y .taskTextOutsideRight{fill:black;text-anchor:start;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}#mermaid-svg-au4eKWNb1jyTLe5Y .taskTextOutsideLeft{fill:black;text-anchor:end;}#mermaid-svg-au4eKWNb1jyTLe5Y .task.clickable{cursor:pointer;}#mermaid-svg-au4eKWNb1jyTLe5Y .taskText.clickable{cursor:pointer;fill:#003163!important;font-weight:bold;}#mermaid-svg-au4eKWNb1jyTLe5Y .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163!important;font-weight:bold;}#mermaid-svg-au4eKWNb1jyTLe5Y .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163!important;font-weight:bold;}#mermaid-svg-au4eKWNb1jyTLe5Y .taskText0,#mermaid-svg-au4eKWNb1jyTLe5Y .taskText1,#mermaid-svg-au4eKWNb1jyTLe5Y .taskText2,#mermaid-svg-au4eKWNb1jyTLe5Y .taskText3{fill:white;}#mermaid-svg-au4eKWNb1jyTLe5Y .task0,#mermaid-svg-au4eKWNb1jyTLe5Y .task1,#mermaid-svg-au4eKWNb1jyTLe5Y .task2,#mermaid-svg-au4eKWNb1jyTLe5Y .task3{fill:#8a90dd;stroke:#534fbc;}#mermaid-svg-au4eKWNb1jyTLe5Y .taskTextOutside0,#mermaid-svg-au4eKWNb1jyTLe5Y .taskTextOutside2{fill:black;}#mermaid-svg-au4eKWNb1jyTLe5Y .taskTextOutside1,#mermaid-svg-au4eKWNb1jyTLe5Y .taskTextOutside3{fill:black;}#mermaid-svg-au4eKWNb1jyTLe5Y .active0,#mermaid-svg-au4eKWNb1jyTLe5Y .active1,#mermaid-svg-au4eKWNb1jyTLe5Y .active2,#mermaid-svg-au4eKWNb1jyTLe5Y .active3{fill:#bfc7ff;stroke:#534fbc;}#mermaid-svg-au4eKWNb1jyTLe5Y .activeText0,#mermaid-svg-au4eKWNb1jyTLe5Y .activeText1,#mermaid-svg-au4eKWNb1jyTLe5Y .activeText2,#mermaid-svg-au4eKWNb1jyTLe5Y .activeText3{fill:black!important;}#mermaid-svg-au4eKWNb1jyTLe5Y .done0,#mermaid-svg-au4eKWNb1jyTLe5Y .done1,#mermaid-svg-au4eKWNb1jyTLe5Y .done2,#mermaid-svg-au4eKWNb1jyTLe5Y .done3{stroke:grey;fill:lightgrey;stroke-width:2;}#mermaid-svg-au4eKWNb1jyTLe5Y .doneText0,#mermaid-svg-au4eKWNb1jyTLe5Y .doneText1,#mermaid-svg-au4eKWNb1jyTLe5Y .doneText2,#mermaid-svg-au4eKWNb1jyTLe5Y .doneText3{fill:black!important;}#mermaid-svg-au4eKWNb1jyTLe5Y .doneText0.taskTextOutsideLeft,#mermaid-svg-au4eKWNb1jyTLe5Y .doneText0.taskTextOutsideRight,#mermaid-svg-au4eKWNb1jyTLe5Y .doneText1.taskTextOutsideLeft,#mermaid-svg-au4eKWNb1jyTLe5Y .doneText1.taskTextOutsideRight,#mermaid-svg-au4eKWNb1jyTLe5Y .doneText2.taskTextOutsideLeft,#mermaid-svg-au4eKWNb1jyTLe5Y .doneText2.taskTextOutsideRight,#mermaid-svg-au4eKWNb1jyTLe5Y .doneText3.taskTextOutsideLeft,#mermaid-svg-au4eKWNb1jyTLe5Y .doneText3.taskTextOutsideRight{fill:black!important;}#mermaid-svg-au4eKWNb1jyTLe5Y .crit0,#mermaid-svg-au4eKWNb1jyTLe5Y .crit1,#mermaid-svg-au4eKWNb1jyTLe5Y .crit2,#mermaid-svg-au4eKWNb1jyTLe5Y .crit3{stroke:#ff8888;fill:red;stroke-width:2;}#mermaid-svg-au4eKWNb1jyTLe5Y .activeCrit0,#mermaid-svg-au4eKWNb1jyTLe5Y .activeCrit1,#mermaid-svg-au4eKWNb1jyTLe5Y .activeCrit2,#mermaid-svg-au4eKWNb1jyTLe5Y .activeCrit3{stroke:#ff8888;fill:#bfc7ff;stroke-width:2;}#mermaid-svg-au4eKWNb1jyTLe5Y .doneCrit0,#mermaid-svg-au4eKWNb1jyTLe5Y .doneCrit1,#mermaid-svg-au4eKWNb1jyTLe5Y .doneCrit2,#mermaid-svg-au4eKWNb1jyTLe5Y .doneCrit3{stroke:#ff8888;fill:lightgrey;stroke-width:2;cursor:pointer;shape-rendering:crispEdges;}#mermaid-svg-au4eKWNb1jyTLe5Y .milestone{transform:rotate(45deg) scale(0.8,0.8);}#mermaid-svg-au4eKWNb1jyTLe5Y .milestoneText{font-style:italic;}#mermaid-svg-au4eKWNb1jyTLe5Y .doneCritText0,#mermaid-svg-au4eKWNb1jyTLe5Y .doneCritText1,#mermaid-svg-au4eKWNb1jyTLe5Y .doneCritText2,#mermaid-svg-au4eKWNb1jyTLe5Y .doneCritText3{fill:black!important;}#mermaid-svg-au4eKWNb1jyTLe5Y .doneCritText0.taskTextOutsideLeft,#mermaid-svg-au4eKWNb1jyTLe5Y .doneCritText0.taskTextOutsideRight,#mermaid-svg-au4eKWNb1jyTLe5Y .doneCritText1.taskTextOutsideLeft,#mermaid-svg-au4eKWNb1jyTLe5Y .doneCritText1.taskTextOutsideRight,#mermaid-svg-au4eKWNb1jyTLe5Y .doneCritText2.taskTextOutsideLeft,#mermaid-svg-au4eKWNb1jyTLe5Y .doneCritText2.taskTextOutsideRight,#mermaid-svg-au4eKWNb1jyTLe5Y .doneCritText3.taskTextOutsideLeft,#mermaid-svg-au4eKWNb1jyTLe5Y .doneCritText3.taskTextOutsideRight{fill:black!important;}#mermaid-svg-au4eKWNb1jyTLe5Y .vert{stroke:navy;}#mermaid-svg-au4eKWNb1jyTLe5Y .vertText{font-size:15px;text-anchor:middle;fill:navy!important;}#mermaid-svg-au4eKWNb1jyTLe5Y .activeCritText0,#mermaid-svg-au4eKWNb1jyTLe5Y .activeCritText1,#mermaid-svg-au4eKWNb1jyTLe5Y .activeCritText2,#mermaid-svg-au4eKWNb1jyTLe5Y .activeCritText3{fill:black!important;}#mermaid-svg-au4eKWNb1jyTLe5Y .titleText{text-anchor:middle;font-size:18px;fill:#333;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}#mermaid-svg-au4eKWNb1jyTLe5Y :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
2024-01-01
2024-01-03
2024-01-05
2024-01-07
2024-01-09
2024-01-11
2024-01-13
2024-01-15
2024-01-17
2024-01-19
2024-01-21
2024-01-23
2024-01-25
2024-01-27
社区页双列表
社区API开发
说说发布页面
举报API开发
树洞投递页面
埋点API开发
草稿暂存实现
站点信息页面
举报链路打通
占位替换完成
前端页面
后端接口
功能闭环
社区扩展开发进度
效果图

开发过程提示词(优化版)
请先读取 AGENTS.md、rules/frontend-uniapp.md、rules/api-contract.md,
以及 docs/product/UNIAPP_MINI_PROGRAM_PRODUCT_DESIGN.md 第 5.1 节“社区扩展”阶段要求。
本次只处理社区扩展,不扩展到兼容与性能、联调验收或后台管理能力。
请重点补齐:
1. 社区页说说/树洞双列表与基础互动
2. 树洞匿名投递与 1 小时草稿暂存
3. 举报入口及前后端接口
4. 友链、导航、关于真实页面与内容入口
输出时必须说明:
1. 页面目录与 API 归属
2. 哪些占位已被替换
3. 哪些后端接口是新补的
4. 当前还缺哪些上线前验证
这类任务里 AI 最容易跑偏的点
- 只把社区页做成列表展示,不补发布、评论和举报。
- 树洞能提交,但没有草稿暂存和审核提示,用户一中断内容就丢。
- 导航、友链、关于仍然保留“建设中”文案,却误判阶段完成。
- 前端举报入口做了,后端没有对应接口,最后整条链路还是假的。
项目入口
- 在线演示:https://sourcelin.cn
- Gitee:https://gitee.com/my_lyq/sourcelin-cloud-blog
- GitHub:https://github.com/SourceLin/sourcelin-cloud-blog





