LikeShop 种草社区模块二开:笔记发布、话题广场与商品挂载实现

一、原生资讯模块数据表拆解

1.1 文章主表(ls_articie)

LikeShop 的资讯模块以 ls_article 表为核心,存储平台发布的文章内容;核心字段包括:

字段名类型说明
idint文章ID
cidint文章分类ID
titlevarchar文章标题
synopsisvarchar文字简介
imagevarchar文章图片/封面图
is_noticetinyint是否公告:1-是,0-否
contenttext文章内容
visitint浏览人数
is_showtinyint是否显示:0-隐藏,1-显示
sortint排序
create_timeint创建时间

文章分类通过 ls_article_category 表管理,支持分类名称、分类简介、分类图片、父级ID、排序等字段,后台可维护文章分类,方便文章分类整理;文章列表接口返回字段包括 id,cid,title,image,click_virtual,click_actual,create_time 等。

1.2 原生资讯模块的四个核心局限

局限一:内容生产模式单一。ls_article 表定位为平台官方资讯发布,内容由后台管理员创建,不支持用户(C端消费者)发布内容;表结构中没有 user_id 字段,无法追踪内容创作者。

局限二:无社交互动能力。资讯模块是单向传播——平台发布、用户阅读、不具备点赞、评论、收藏、分享等互动能力;ls_article 表仅有 visit (浏览人数)字段,没有点赞数、评论数、收藏数的统计字段。

局限三:无商品关联能力。资讯内容与商品体系完全割裂;ls_article 表没有任何与 ls_goods 关联的字段或关联表,无法实现“内容种草 → 商品转化”的链路。

局限四:无话题/社区运营能力。资讯以分类(cid)组织,分类结构是树形的一级/二级分类,而种草社区需要的是话题广场模式——一个用户可以自由创建、参与和关注的话题体系,话题具有动态性和社交性。

1.3 二开策略定位

参考 LikeShop 的二开规范,核心原则是“新增能力 > 修改原逻辑,组合扩展 > 覆盖替换”;资讯模块的二开策略应当遵循:

  1. 不修改 ls_article 表结构,保持原生资讯功能不变,避免影响平台官方资讯发布
  2. 新建独立的笔记体系,与资讯模块并行运行,通过统一的内容聚合层对外提供数据
  3. 复用原生的文件上传、用户体系、商品体系,通过关联表实现笔记与商品、话题的绑定
  4. 扩展逻辑封装在独立的 Service 中,不修改核心的 ArticleLogic、UserLogic 等文件
二、数据库扩展设计

2.1 笔记主表(ls_note)

CREATE TABLE `ls_note` (
`id` int UNSIGNED NOT NULL AUTO_INCREMENT,
 `user_id` int UNSIGNED NOT NULL COMMENT '发布用户ID',
 `title` varchar(100) NOT NULL DEFAULT '' COMMENT '笔记标题',
 `content` text COMMENT '笔记内容,最多1000字',
 `note_type` tinyint NOT NULL DEFAULT 1 COMMENT '笔记类型:1-图片笔记,2-视频笔记',
 `images` text COMMENT '图片列表,JSON数组,最多9张',
 `video_url` varchar(500) NOT NULL DEFAULT '' COMMENT '视频地址',
 `video_cover` varchar(500) NOT NULL DEFAULT '' COMMENT '视频封面图(前三秒截取)',
 `topic_id` int UNSIGNED NOT NULL DEFAULT 0 COMMENT '所属话题ID',
 `category_id` int UNSIGNED NOT NULL DEFAULT 0 COMMENT '所属分类ID',
 `is_top` tinyint NOT NULL DEFAULT 0 COMMENT '是否置顶:0-否,1-是',
 `audit_status` tinyint NOT NULL DEFAULT 0 COMMENT '审核状态:0-待审核,1-已通过,2-已驳回',
 `audit_remark` varchar(255) NOT NULL DEFAULT '' COMMENT '审核备注',
 `status` tinyint NOT NULL DEFAULT 1 COMMENT '状态:0-隐藏,1-显示',
 `like_count` int UNSIGNED NOT NULL DEFAULT 0 COMMENT '点赞数',
 `comment_count` int UNSIGNED NOT NULL DEFAULT 0 COMMENT '评论数',
 `collect_count` int UNSIGNED NOT NULL DEFAULT 0 COMMENT '收藏数',
 `view_count` int UNSIGNED NOT NULL DEFAULT 0 COMMENT '浏览量',
 `virtual_like` int UNSIGNED NOT NULL DEFAULT 0 COMMENT '虚拟点赞数',
 `create_time` int UNSIGNED NOT NULL DEFAULT 0,
 `update_time` int UNSIGNED NOT NULL DEFAULT 0,
 `del` tinyint NOT NULL DEFAULT 0 COMMENT '是否删除:0-否,非0为删除时间',
PRIMARY KEY (`id`),
KEY `idx_user_id` (`user_id`),
KEY `idx_topic_id` (`topic_id`),
KEY `idx_category_id` (`category_id`),
KEY `idx_audit_status` (`audit_status`),
KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='种草笔记表';

笔记支持图片笔记(最多9张图片)和视频笔记(上传一个视频,截取前三秒作为封面),笔记下方支持文字说明(1000字内),可以选择关联商品和所属话题。

2.2 话题表(ls_note_topic)

话题是社区内容组织的基本单元;笔记属于话题,话题属于分类,形成“分类 → 话题 → 笔记”的三级结构:

CREATE TABLE `ls_note_topic` (
`id` int UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL COMMENT '话题名称',
`description` varchar(255) NOT NULL DEFAULT '' COMMENT '话题简介',
`image` varchar(500) NOT NULL DEFAULT '' COMMENT '话题封面图',
`category_id` int UNSIGNED NOT NULL DEFAULT 0 COMMENT '所属分类ID',
`topic_type` tinyint NOT NULL DEFAULT 1 COMMENT '话题类型:1-日常话题,2-有奖征集,3-PK活动',
`note_count` int UNSIGNED NOT NULL DEFAULT 0 COMMENT '笔记数量',
`follow_count` int UNSIGNED NOT NULL DEFAULT 0 COMMENT '关注人数',
`view_count` int UNSIGNED NOT NULL DEFAULT 0 COMMENT '浏览量',
`is_recommend` tinyint NOT NULL DEFAULT 0 COMMENT '是否推荐:0-否,1-是',
`sort` int NOT NULL DEFAULT 0 COMMENT '排序',
`status` tinyint NOT NULL DEFAULT 1 COMMENT '状态:0-禁用,1-启用',
`start_time` int UNSIGNED NOT NULL DEFAULT 0 COMMENT '活动开始时间(有奖活动使用)',
`end_time` int UNSIGNED NOT NULL DEFAULT 0 COMMENT '活动结束时间',
`create_time` int UNSIGNED NOT NULL DEFAULT 0,
`update_time` int UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
KEY `idx_category_id` (`category_id`),
KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='话题表';

话题分类表 ls_note_category 结构参考文章分类表,包含分类名称、简介、图片、父级ID、排序等字段。

2.3 笔记-商品关联表(ls_note_goods)

实现内容到转化的核心表,支持一条笔记关联多个商品:

CREATE TABLE `ls_note_goods` (
`id` int UNSIGNED NOT NULL AUTO_INCREMENT,
`note_id` int UNSIGNED NOT NULL COMMENT '笔记ID',
`goods_id` int UNSIGNED NOT NULL COMMENT '商品ID',
`item_id` int UNSIGNED NOT NULL DEFAULT 0 COMMENT '规格ID',
`sort` int NOT NULL DEFAULT 0 COMMENT '排序',
`create_time` int UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_note_goods` (`note_id`, `goods_id`),
KEY `idx_goods_id` (`goods_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='笔记商品关联表';

2.4 点赞记录表(ls_note_like)

CREATE TABLE `ls_note_like` (
  `id` int UNSIGNED NOT NULL AUTO_INCREMENT,
  `note_id` int UNSIGNED NOT NULL COMMENT '笔记ID',
  `user_id` int UNSIGNED NOT NULL COMMENT '用户ID',
  `create_time` int UNSIGNED NOT NULL DEFAULT 0,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_note_user` (`note_id`, `user_id`),
  KEY `idx_user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='笔记点赞记录表';

2.5 评论表(ls_note_comment)

CREATE TABLE `ls_note_comment` (
 `id` int UNSIGNED NOT NULL AUTO_INCREMENT,
 `note_id` int UNSIGNED NOT NULL COMMENT '笔记ID',
 `user_id` int UNSIGNED NOT NULL COMMENT '评论用户ID',
 `parent_id` int UNSIGNED NOT NULL DEFAULT 0 COMMENT '父评论ID,0为一级评论',
 `reply_user_id` int UNSIGNED NOT NULL DEFAULT 0 COMMENT '被回复用户ID',
 `content` varchar(500) NOT NULL DEFAULT '' COMMENT '评论内容',
 `like_count` int UNSIGNED NOT NULL DEFAULT 0 COMMENT '点赞数',
 `audit_status` tinyint NOT NULL DEFAULT 0 COMMENT '审核状态:0-待审核,1-已通过,2-已驳回',
 `status` tinyint NOT NULL DEFAULT 1 COMMENT '状态:0-隐藏,1-显示',
 `create_time` int UNSIGNED NOT NULL DEFAULT 0,
 `del` tinyint NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
KEY `idx_note_id` (`note_id`),
KEY `idx_user_id` (`user_id`),
KEY `idx_parent_id` (`parent_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='笔记评论表';

2.6 收藏记录表(ls_note_collect)

CREATE TABLE `ls_note_collect` (
 `id` int UNSIGNED NOT NULL AUTO_INCREMENT,
 `note_id` int UNSIGNED NOT NULL COMMENT '笔记ID',
 `user_id` int UNSIGNED NOT NULL COMMENT '用户ID',
 `create_time` int UNSIGNED NOT NULL DEFAULT 0,
 PRIMARY KEY (`id`),
 UNIQUE KEY `uk_note_user` (`note_id`, `user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='笔记收藏记录表';

2.7 话题关注表(ls_note_topic_follow)

CREATE TABLE `ls_note_topic_follow` (
 `id` int UNSIGNED NOT NULL AUTO_INCREMENT,
 `topic_id` int UNSIGNED NOT NULL COMMENT '话题ID',
 `user_id` int UNSIGNED NOT NULL COMMENT '用户ID',
 `create_time` int UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_topic_user` (`topic_id`, `user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='话题关注表';
三、笔记发布功能实现

3.1 发布接口设计

笔记发布是 UGC 社区的核心入口;发布接口 /api/note/publish 的请求参数:

{
"note_type": 1,
"title": "秋季穿搭分享",
"content": "今天入手了一件超好看的外套...",
"images": ["url1", "url2"],
"video_url": "",
"topic_id": 3,
"goods_ids": [15, 28]

}

3.2 核心发布逻辑

class NoteService
{
/**
 * 发布笔记
 */
public function publish($userId, $data)
{
    // 1. 校验用户是否被拉黑
    if ($this->isUserBlacklisted($userId)) {
        throw new Exception('您已被禁止发布笔记');
    }

    // 2. 内容校验
    $this->validateContent($data);

    // 3. 敏感词检测
    if (SensitiveWordService::check($data['content'])) {
        throw new Exception('笔记内容包含敏感词,请修改后提交');
    }

    // 4. 图片/视频格式校验
    if ($data['note_type'] == 1) {
        if (empty($data['images']) || count($data['images']) > 9) {
            throw new Exception('图片笔记需上传1-9张图片');
        }
    } elseif ($data['note_type'] == 2) {
        if (empty($data['video_url'])) {
            throw new Exception('视频笔记需上传视频');
        }
    }

    // 5. 话题校验
    if (!empty($data['topic_id'])) {
        $topic = NoteTopicModel::where('id', $data['topic_id'])
            ->where('status', 1)->find();
        if (!$topic) {
            throw new Exception('话题不存在或已禁用');
        }
    }

    // 6. 写入笔记
    Db::startTrans();
    try {
        $needAudit = ConfigModel::get('note_audit_enable', 1);
        $noteId = NoteModel::create([
            'user_id'     => $userId,
            'title'       => $data['title'],
            'content'     => $data['content'],
            'note_type'   => $data['note_type'],
            'images'      => json_encode($data['images'] ?? [], JSON_UNESCAPED_UNICODE),
            'video_url'   => $data['video_url'] ?? '',
            'video_cover' => $this->extractVideoCover($data['video_url'] ?? ''),
            'topic_id'    => $data['topic_id'] ?? 0,
            'category_id' => $topic['category_id'] ?? 0,
            'audit_status'=> $needAudit ? 0 : 1,
            'create_time' => time(),
        ])->id;

        // 7. 关联商品
        if (!empty($data['goods_ids'])) {
            $this->bindGoods($noteId, $data['goods_ids']);
        }

        // 8. 更新话题笔记数
        if (!empty($data['topic_id'])) {
            NoteTopicModel::where('id', $data['topic_id'])
                ->inc('note_count', 1)->update();
        }

        Db::commit();

        // 9. 触发审核检测
        if ($needAudit) {
            event('NoteSubmitAudit', ['note_id' => $noteId]);
        }

        return ['note_id' => $noteId, 'need_audit' => $needAudit];
    } catch (\Exception $e) {
        Db::rollback();
        throw $e;
    }
}

/**
 * 关联商品到笔记
 */
private function bindGoods($noteId, $goodsIds)
{
    $goodsIds = array_unique(array_filter($goodsIds));
    if (count($goodsIds) > 10) {
        throw new Exception('一条笔记最多关联10个商品');
    }

    foreach ($goodsIds as $sort => $goodsId) {
        // 校验商品是否存在且上架
        $goods = GoodsModel::where('id', $goodsId)
            ->where('status', 1)->where('del', 0)->find();
        if (!$goods) continue;

        NoteGoodsModel::create([
            'note_id'  => $noteId,
            'goods_id' => $goodsId,
            'sort'     => $sort,
            'create_time' => time(),
        ]);
    }
}

/**
 * 视频封面提取(截取前三秒)
 */
private function extractVideoCover($videoUrl)
{
    if (empty($videoUrl)) return '';
    // 调用 FFmpeg 截取视频前三秒作为封面
    // 实际实现中通过队列异步处理
    return $videoUrl . '?vframe/jpg/offset/3';
  }
}

3.3 内容审核机制

笔记发布后进入审核流程;审核支持两种模式:

模式一:人工审核。笔记写入后 audit_status = 0 (待审核),后台“笔记管理”页面展示待审核列表,管理员逐条审核;审核通过后笔记对外可见,驳回时需填写驳回原因。

模式二:AI 自动审核。可接入百度智能鉴定等第三方内容安全服务,笔记上传后自动触发鉴定,鉴定结果为不合规时自动驳回并记录在案;审核通过的笔记直接对外展示,无需人工介入。

3.4 后台配置

在“应用中心 → 种草社区 → 基础设置”中增加:

配置项类型默认值说明
笔记审核开关开关开启笔记是否需审核后展示
AI 自动审核开关关闭是否开启第三方内容安全鉴定
笔记最大图片数数字输入9单条笔记图片上限
笔记最大字数数字输入1000笔记正文字数上限
每日发布上限数字输入5用户每日发布笔记上限,0为不限
四、话题广场功能实现

4.1 话题广场首页

话题广场是社区内容的流量入口,展示热门话题和最新话题;话题列表接口返回数据包含话题名称、封面图、笔记数量、关注人数,并支持按“推荐”“最新”“最热”排序:

 class NoteTopicService
 {
public function getTopicList($sortBy = 'recommend', $categoryId = 0, $page = 1, $size = 20)
{
    $query = NoteTopicModel::where('status', 1);

    if ($categoryId > 0) {
        $query->where('category_id', $categoryId);
    }

    switch ($sortBy) {
        case 'recommend':
            $query->where('is_recommend', 1)
                  ->order('sort', 'desc');
            break;
        case 'newest':
            $query->order('create_time', 'desc');
            break;
        case 'hottest':
            $query->order('note_count', 'desc');
            break;
    }

    $list = $query->page($page, $size)->select();

    // 批量查询当前用户是否已关注
    $userId = request()->userId ?? 0;
    if ($userId > 0) {
        $topicIds = array_column($list->toArray(), 'id');
        $followedIds = NoteTopicFollowModel::where('user_id', $userId)
            ->whereIn('topic_id', $topicIds)
            ->column('topic_id');
        foreach ($list as &$item) {
            $item['is_followed'] = in_array($item['id'], $followedIds) ? 1 : 0;
        }
    }

    return $list;
  }

}

4.2 话题关注与取消

public function followTopic($userId, $topicId)
{
$topic = NoteTopicModel::where('id', $topicId)
    ->where('status', 1)->find();
if (!$topic) {
    throw new Exception('话题不存在');
}

// 幂等:已关注则忽略
$exists = NoteTopicFollowModel::where('user_id', $userId)
    ->where('topic_id', $topicId)->find();
if ($exists) {
    throw new Exception('您已关注该话题');
}

Db::startTrans();
try {
    NoteTopicFollowModel::create([
        'topic_id' => $topicId,
        'user_id'  => $userId,
        'create_time' => time(),
    ]);
    NoteTopicModel::where('id', $topicId)->inc('follow_count', 1)->update();
    Db::commit();
} catch (\Exception $e) {
    Db::rollback();
    throw $e;
  }
}

4.3 话题下的笔记流

话题详情页展示该话题下的笔记列表,支持按“最新”和“最热”排序;列表采用瀑布流布局,根据第一张图片的长度比例实现瀑布流效果:

public function getTopicNotes($topicId, $sortBy = 'newest', $page = 1, $size = 10)
{
$query = NoteModel::where('topic_id', $topicId)
    ->where('audit_status', 1)
    ->where('status', 1)
    ->where('del', 0);

if ($sortBy == 'hottest') {
    $query->order('like_count', 'desc')->order('create_time', 'desc');
} else {
    $query->order('is_top', 'desc')->order('create_time', 'desc');
}

$list = $query->page($page, $size)->select();

// 批量补齐用户信息和商品信息
$this->fillUserInfo($list);
$this->fillGoodsInfo($list);

return $list;
}

4.4 后台配置

在“应用中心 → 种草社区 → 话题管理”中增加话题管理页面,支持话题的增删改查、置顶、推荐、启用/禁用;话题分类在“类目管理”中维护,形成“分类 → 话题 → 笔记”的三级结构。

五、商品挂载与转化链路实现

5.1 笔记详情页的商品展示

笔记详情接口在返回笔记内容的同时,关联查询挂载的商品信息;商品以卡片形式展示在笔记内容下方:

public function getNoteDetail($noteId, $userId = 0)
{
$note = NoteModel::where('id', $noteId)
    ->where('audit_status', 1)
    ->where('status', 1)
    ->where('del', 0)
    ->find();
if (!$note) {
    throw new Exception('笔记不存在或已下架');
}

// 浏览量递增(Redis 原子递增,定时同步到数据库)
Redis::incr("note:view:{$noteId}");

// 查询关联商品
$goodsList = NoteGoodsModel::alias('ng')
    ->join('goods g', 'ng.goods_id = g.id')
    ->where('ng.note_id', $noteId)
    ->where('g.status', 1)
    ->where('g.del', 0)
    ->field('g.id, g.name, g.image, g.price, g.market_price, ng.sort')
    ->order('ng.sort', 'asc')
    ->select();

// 查询发布者信息
$user = UserModel::field('id, nickname, avatar')->find($note['user_id']);

// 查询当前用户互动状态
$isLiked = 0;
$isCollected = 0;
if ($userId > 0) {
    $isLiked = NoteLikeModel::where('note_id', $noteId)
        ->where('user_id', $userId)->count();
    $isCollected = NoteCollectModel::where('note_id', $noteId)
        ->where('user_id', $userId)->count();
}

return [
    'note'         => $note,
    'goods_list'   => $goodsList,
    'user'         => $user,
    'is_liked'     => $isLiked ? 1 : 0,
    'is_collected' => $isCollected ? 1 : 0,
    'like_count'   => $note['like_count'] + $note['virtual_like'],
   ];
}

5.2 商品点击的转化追踪

用户在笔记中点击商品卡片跳转到商品详情页时,记录转化来源:

public function trackGoodsClick($noteId, $goodsId, $userId)
{
// 写入转化追踪记录(可异步写入日志表)
NoteConversionLogModel::create([
    'note_id'   => $noteId,
    'goods_id'  => $goodsId,
    'user_id'   => $userId,
    'action'    => 'click',
    'create_time' => time(),
]);

// 商品浏览量递增
Redis::incr("goods:view:{$goodsId}");
}

5.3 商品挂载的展示规则

  • 笔记详情页展示挂载商品时,仅展示状态为上架且未删除的商品
  • 商品按 sort 字段排序,运营可在后台调整排序
  • 如果挂载的商品已下架,该商品在笔记详情中自动隐藏,不影响笔记本身的展示
  • 每条笔记最多关联 10 个商品,后台可配置上限
六、点赞与评论功能实现

6.1 点赞逻辑

点赞采用“记录表 + 计数字段”的双重机制;ls_note_like 表记录每条点赞明细,ls_note 表的 like_count 字段做计数缓存,避免每次查询都去 count 记录表:

public function toggleLike($userId, $noteId)
{
$note = NoteModel::where('id', $noteId)
    ->where('audit_status', 1)
    ->where('status', 1)
    ->find();
if (!$note) {
    throw new Exception('笔记不存在');
}

$exists = NoteLikeModel::where('note_id', $noteId)
    ->where('user_id', $userId)->find();

Db::startTrans();
try {
    if ($exists) {
        // 取消点赞
        NoteLikeModel::where('id', $exists['id'])->delete();
        NoteModel::where('id', $noteId)->dec('like_count', 1)->update();
        $isLiked = 0;
    } else {
        // 点赞
        NoteLikeModel::create([
            'note_id' => $noteId,
            'user_id' => $userId,
            'create_time' => time(),
        ]);
        NoteModel::where('id', $noteId)->inc('like_count', 1)->update();
        $isLiked = 1;
    }
    Db::commit();
} catch (\Exception $e) {
    Db::rollback();
    throw $e;
}

return ['is_liked' => $isLiked];
}

点赞数展示时,前端看到的点赞数是实际点赞数加上虚拟点赞数(like_count + virtual_like),后台可修改虚拟点赞数。

6.2 评论逻辑

评论支持一级评论和二级回复(楼中楼),通过 parent_id 和 reply_user_id 实现:

 public function addComment($userId, $noteId, $content, $parentId = 0, $replyUserId = 0)
{
if (empty(trim($content))) {
    throw new Exception('评论内容不能为空');
}
if (mb_strlen($content) > 500) {
    throw new Exception('评论内容不能超过500字');
}
if (SensitiveWordService::check($content)) {
    throw new Exception('评论内容包含敏感词');
}

// 校验父评论
if ($parentId > 0) {
    $parent = NoteCommentModel::where('id', $parentId)
        ->where('note_id', $noteId)->find();
    if (!$parent) {
        throw new Exception('回复的评论不存在');
    }
}

$commentId = NoteCommentModel::create([
    'note_id'      => $noteId,
    'user_id'      => $userId,
    'parent_id'    => $parentId,
    'reply_user_id'=> $replyUserId,
    'content'      => $content,
    'audit_status' => ConfigModel::get('comment_audit_enable', 0) ? 0 : 1,
    'create_time'  => time(),
])->id;

// 更新笔记评论数
NoteModel::where('id', $noteId)->inc('comment_count', 1)->update();

// 通知笔记作者和被回复用户
if ($note = NoteModel::find($noteId)) {
    if ($note['user_id'] != $userId) {
        MessageService::send($note['user_id'], '笔记收到新评论', $content);
    }
}
if ($replyUserId > 0 && $replyUserId != $userId) {
    MessageService::send($replyUserId, '有人回复了你的评论', $content);
}

return ['comment_id' => $commentId];
}

6.3 举报与拉黑机制

后台支持处理用户举报的笔记或评论,可以隐藏对应的笔记和评论;作者拉黑后无法发布笔记和下单:

CREATE TABLE `ls_note_report` (
  `id` int UNSIGNED NOT NULL AUTO_INCREMENT,
  `target_type` tinyint NOT NULL DEFAULT 1 COMMENT '举报对象:1-笔记,2-评论',
  `target_id` int UNSIGNED NOT NULL COMMENT '举报对象ID',
  `reporter_id` int UNSIGNED NOT NULL COMMENT '举报人ID',
  `reason` varchar(255) NOT NULL DEFAULT '' COMMENT '举报原因',
  `status` tinyint NOT NULL DEFAULT 0 COMMENT '处理状态:0-待处理,1-已处理',
  `handle_remark` varchar(255) NOT NULL DEFAULT '' COMMENT '处理备 注',
 `create_time` int UNSIGNED NOT NULL DEFAULT 0,
 PRIMARY KEY (`id`),
 KEY `idx_target` (`target_type`, `target_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='举报记录表';
七、完整开发步骤总结

7.1 数据库变更清单

操作表名说明
CREATEls_note笔记主表
CREATEls_note_topic话题表
CREATEls_note_category话题分类表
CREATEls_note_goods笔记-商品关联表
CREATEls_note_like点赞记录表
CREATEls_note_comment评论表
CREATEls_note_collect收藏记录表
CREATEls_note_topic_follow话题关注表
CREATEls_note_report举报记录表
CREATEls_note_conversion_log转化追踪日志表

7.2 后端开发清单

模块文件/类工作内容
数据层NoteModel笔记主表 Model
数据层NoteTopicModel话题 Model
数据层NoteGoodsModel商品关联 Model
数据层NoteLikeModel / NoteCommentModel / NoteCollectModel互动记录 Model
业务层NoteService笔记发布、编辑、删除、列表查询
业务层NoteTopicService话题创建、关注、列表、笔记流
业务层NoteInteractionService点赞、评论、收藏的统一处理
业务层NoteConversionService商品点击追踪和转化统计
业务层NoteAuditService笔记和评论的审核流程
接口层NoteController前台笔记相关接口
接口层NoteTopicController前台话题相关接口
后台接口NoteManageController后台笔记管理、话题管理、举报处理
事件NoteSubmitAuditEvent笔记提交后触发审核
定时任务NoteViewSync笔记浏览量从 Redis 同步到数据库

7.3 后台前端开发清单

页面工作内容
种草社区 → 笔记管理笔记列表(含审核状态筛选)、审核通过/驳回、置顶/隐藏/删除
种草社区 → 话题管理话题增删改查、推荐设置、活动配置
种草社区 → 类目管理话题分类的增删改查
种草社区 → 作者管理查看作者信息、投稿数、评论数,设置拉黑
种草社区 → 举报管理举报记录列表、隐藏笔记/评论、标记已处理
种草社区 → 基础设置审核开关、AI审核开关、发布上限等配置

7.4 开发注意事项

二开规范方面:遵循“稳定内核原则”,不修改 ls_article 表结构和原生资讯模块的代码;种草社区作为独立模块开发,通过统一的 Controlle 层对外提供接口,通过 Model 层与用户表、商品表做关联;新增能力集中在独立的 Service 中,核心 Logic 文件保持只读。

数据一致性方面:点赞、评论、收藏的计数采用“记录表 + 计数字段”模式,写操作在同一事务中完成;浏览量等高频写操作先走 Redis 原子递增,定时任务批量同步到数据库。

审核性能方面:笔记审核支持批量操作,待审核数量在后台菜单以角标展示;AI 自动审核通过队列异步处理,不阻塞用户发布流程。

内容安全方面:笔记标题、正文、评论均需经过敏感词过滤;图片和视频建议接入第三方内容安全鉴定服务,对不合规内容自动驳回。

性能优化方面:笔记列表的瀑布流查询使用覆盖索引,避免回表;话题笔记数、关注数等统计字段通过 Redis 计数器维护,定时同步;笔记详情页的关联商品查询使用 whereIn 批量查询,避免 N+1 问题。

0
0
0
0
评论
未登录
暂无评论