# dramacmt 给在线短剧铺机器人评论。一次性运营工具,不进 cron。 ## 为什么不用后台已有的评论导入 `web/api/commentctrl.AddContentExcel` 有三个限制: 1. 只认视频(按 `vidmod.GetVideoInfo` 查对象),短剧的 `objID` 是 `media._id`,走不通 2. 要上传 Excel 3. 它的 `userID` 取自 `static.json` 的 `sysUser`——**那些 uid 在 `user` 表里并不存在** 第 3 点是实际踩到的坑:评论列表填充用户信息时(`app/service/commentser/cmtcoverter.go`) 查不到用户**不会丢弃评论,只是把昵称和头像留空**。线上已经有 5962 条这样的 「无名无头像」评论(抽查 400 个引用 uid,0 命中)。 所以本工具自己建一批机器人用户,评论挂在它们身上。 ## 机器人用户 - uid 从 **1001** 开始往上发,默认 400 个。该区间原本完全空闲(`uid 1~17` 是库里 已有的 17 个机器人,1000 以下整段不碰) - uid 必须 `<= 111999`(`common/constant.RobotUIDLimit`)—— `commentser.getTrackInfo` 靠这个阈值判定 `isRobot`,后台可按机器人筛选和撤回 - uid 池远低于 `auto_id` 的 uid 计数器(当时是 3111989,只增不减), 不会和后续真实注册撞号 - 昵称按「姓 + 名」随机拼,风格对齐库里现有那 17 个机器人(郏哲、溪焱这种) - 头像**从库里现有用户采样**,不写死路径(各站 `static.json` 里是同一批 90 张) `user` 表的唯一索引要当心: | 索引 | 类型 | 处理 | |---|---|---| | `devID` | **非 sparse 唯一** | 必须给唯一非空值,用 `ROBOT%07d` | | `token` / `promotionCode` / `mobile` | 部分唯一(`{$gt: ""}`) | 留空串即豁免 | 已存在的 uid **不覆盖**(昵称头像可能被运营改过),所以可以重复跑。 ## 评论 要能在 App 里显示,必须满足 `models/v/cmtmod.GetParentCmtList` 的全部条件: ``` level = 1 status = 1 isGodComment = false isDelete = false isAdvertiser 非 true createdAt <= now ``` 注意 `status`:App 发评论走的 `getTrackInfo` 写的是 `status: 2`(未审核), 而列表只认 `1`。所以铺数据必须直接写 `1`,否则一条都不显示。 其余字段整体对齐线上真实短剧评论的形状,两个容易写错的地方: - `type` 是 `"VIDEO"`,不是 `"drama"`——`objType` 才是 `"drama"`。 `getTrackInfo` 对所有 objType 都传 `cmtmod.CmtTypeVideo` - `tousername` 落库键名是**小写**的:结构体那个字段只有 `form`/`json` tag, 没写 `bson` tag,driver 默认把字段名小写 - `city` 必须写 `"-"`:发评论路径里 `GetLocationByIP` 的调用是注释掉的 (`app/service/commentser/cmtsend.go:114-116`),线上真实评论**没有一条**带 归属地。`City` 会原样出参给 App(`cmtcoverter.go:46`),给真城市等于在评论区 挂个「我是机器人」的标。第一版写了随机城市,已改掉,线上那 19,697 条也已回刷 **`media.countComment` 必须同步 `$inc`**。App 的「总评论条数」在第一页直接读这个 字段(`app/api/commentctrl`),不补的话前端显示 0 条、但列表里有评论。 ### 点赞数与时间 - `createdAt` 随机铺在该剧 `latestPublishedAt`(没有就退 `createdAt`)到现在之间, 再按时间排序写入 - `likeCount` 走长尾:55% 落 0~5、30% 落 6~30、12% 落 31~120、3% 落 121~400。 热门评论区要求 `likeCount > 0` 且按它倒序,所以不能全给 0 - 再按文案长短压上限:≤4 字的短评最多 30 赞,≤8 字最多 120。 不压的话会出现「可以」两个字拿 164 赞这种明显假的数据 - **不写 `like` 集合的记录**。`likeCount` 是展示值,`isLike` 只反映当前请求用户, 不建 like 文档不影响功能,也省掉几万条垃圾数据 文案池在 `content.go`,179 条互不重复。单剧内文案和用户都不重复, 所以 `--max` 不能超过池子容量。 ## 用法 ```bash go build -o /tmp/dramacmt ./scripts/dramacmt/ # 干跑,看会写多少 /tmp/dramacmt --dst "$DST_TANGGUO" --db tangguo --dry-run # 只给评论数为 0 的剧铺,每部 20~50 条(默认) /tmp/dramacmt --dst "$DST_TANGGUO" --db tangguo # 全部在线短剧都补到 20~50 条 /tmp/dramacmt --dst "$DST_TANGGUO" --db tangguo --only-empty=false # 调试:只跑 3 部,固定种子便于复现 /tmp/dramacmt --dst "$DST_TANGGUO" --db tangguo --limit 3 --seed 42 ``` `--db` 必须显式传:URI 里的 `authSource` 通常是 `admin`,推不出业务库名。 ## 撤回 机器人用户和评论都带标记,撤回是两条命令: ```js // 撤回评论(软删,保守做法) db.comment.updateMany({isRobot: true, objType: "drama", userID: {$gte: 1001, $lte: 1400}}, {$set: {isDelete: true}}) // countComment 要跟着减,按 objID 分组重算 ``` 硬删同理,把 `$set` 换成 `deleteMany`。重算 `countComment` 用 `countDocuments({objID, level:1, status:1, isDelete:false})`。