文件
fenleixinxi/application/admin/command/FcSeedPosts.php

478 行
30 KiB
PHP

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

<?php
namespace app\admin\command;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\Db;
/**
* 信息测试数据重建命令
*
* 用法:
* php think fc:seed-posts 清空接口验证/残缺信息,按 8 个分类重建规范化演示数据
*
* 说明:
* - 只处理内容类业务表:fc_post / fc_comment / fc_favorite / fc_pay_view / fc_draft / fc_report
* 以及重复的「接口验证区」区域,不动用户、订单、佣金、配置等数据。
* - 命令可重复执行,每次都会重建同一套 ID 段的数据。
*/
class FcSeedPosts extends Command
{
/** 演示账号:user_id => [昵称, 手机号] */
const USERS = [
1001 => ['同城小助手', '13800001111'],
1002 => ['小王同学', '15033443344'],
1003 => ['洁净到家·陈姐', '13156785678'],
2001 => ['顺捷物流·杨经理', '13988888888'],
2002 => ['安家房产·周主管', '13566666666'],
2003 => ['骑行爱好者·小周', '13712341234'],
2004 => ['车行天下·张总', '13800000000'],
2005 => ['洁净到家·王师傅', '13156785678'],
2006 => ['数码达人·阿豪', '15033443344'],
2007 => ['优选二手车·赵经理', '13700000000'],
];
/** 区域中心坐标(gcj02 近似值,用于首页「附近」排序演示) */
const AREA_COORD = [
'云岩区' => [26.605, 106.710],
'南明区' => [26.568, 106.716],
'观山湖区' => [26.625, 106.625],
'花溪区' => [26.430, 106.670],
];
protected function configure()
{
$this->setName('fc:seed-posts')
->setDescription('清理不规范测试数据,按分类重建信息演示数据');
}
protected function execute(Input $input, Output $output)
{
$now = time();
$prefix = \think\Config::get('database.prefix');
$output->writeln('==> 清理不规范测试数据');
$this->clean();
$data = $this->posts();
$owners = $this->owners();
Db::startTrans();
try {
$id = 101;
$seq = 0;
$stat = [];
foreach ($data as $categoryId => $rows) {
$stat[$categoryId] = 0;
foreach ($rows as $i => $row) {
$uid = $owners[$categoryId][$i];
$user = self::USERS[$uid];
$audit = $this->auditStatus($categoryId, $i);
$paid = $audit === 1 && $categoryId !== 8 && $i % 4 === 1;
$views = 160 + (($categoryId * 977 + $i * 613) % 3200);
$likes = max(2, (int)($views / 48));
$areas = $this->coord($row[4], $i);
$created = $now - (int)((0.15 + $i * 0.41 + $categoryId * 0.13) * 86400);
$media = $this->mediaPaths($categoryId, $i);
$areaId = $this->areaId($row[5]);
Db::name('fc_post')->insert([
'id' => $id,
'user_id' => $uid,
'category_id' => $categoryId,
'identity_type' => in_array($uid, [1003, 2001, 2002, 2004, 2005, 2007, 2011], true) ? 2 : 1,
'title' => $row[1],
'content' => $row[2],
'cover' => $media[0],
'media' => json_encode($media, JSON_UNESCAPED_UNICODE),
'price' => $row[3],
'price_unit' => $row[4],
'area' => $row[5],
'district_id' => $areaId,
'address' => $row[6],
'lat' => $areas[0],
'lng' => $areas[1],
'contact' => $row[0],
'phone' => $user[1],
'wechat' => 'gyfc' . $id,
'tags' => $row[7],
'is_paid' => $paid ? 1 : 0,
'amount' => $paid ? 5 : 0,
'pay_type' => $paid ? ($i % 2 === 1 ? 'wxpay' : 'balance') : '',
'audit_status' => $audit,
'audit_reason' => $audit === 2 ? '信息涉嫌重复发布' : '',
'views' => $audit === 1 ? $views : 0,
'likes' => $audit === 1 ? $likes : 0,
'comment_count' => 0,
'status' => 1,
'is_top' => $this->isTop($categoryId, $i) ? 1 : 0,
'distance' => 0,
'createtime' => $created,
'updatetime' => $created,
]);
$id++;
$seq++;
if ($audit === 1) {
$stat[$categoryId]++;
}
}
}
$output->writeln(' - 信息 ' . $seq . ' 条(已更新 ID 101-' . ($id - 1) . ')');
$this->seedComments($now);
$this->seedDrafts($now);
$this->seedReports($now);
$this->syncCounts();
Db::commit();
} catch (\Exception $e) {
Db::rollback();
$output->writeln(' [x] 重建失败:' . $e->getMessage());
return;
}
Db::execute('ALTER TABLE `' . $prefix . 'fc_post` AUTO_INCREMENT = 165');
foreach ($stat as $categoryId => $count) {
$name = Db::name('fc_category')->where('id', $categoryId)->value('name');
$output->writeln(' - ' . $name . ':' . $count . ' 条已发布');
}
$output->writeln('==> 完成');
}
/** 清理内容类测试数据(保留用户、订单、佣金、配置) */
protected function clean()
{
Db::name('fc_comment')->where('id', '>', 0)->delete();
Db::name('fc_favorite')->where('id', '>', 0)->delete();
Db::name('fc_pay_view')->where('id', '>', 0)->delete();
Db::name('fc_draft')->where('id', '>', 0)->delete();
Db::name('fc_report')->where('id', '>', 0)->delete();
Db::name('fc_post')->where('id', '>', 0)->delete();
Db::name('fc_area')->where('district', '接口验证区')->delete();
Db::name('fc_message')->where('title', 'like', '%接口验证%')->whereOr('content', 'like', '%接口验证%')->delete();
$this->cleanMockUsers();
}
/** 清理历史自动化脚本遗留的临时用户及其关联数据 */
protected function cleanMockUsers()
{
$ids = Db::name('user')
->where('username', 'like', 'test\\_dist\\_%')
->whereOr('username', 'like', 'mock\\_test\\_dist\\_%')
->column('id');
if (!$ids) {
return;
}
Db::name('fc_user_ext')->where('user_id', 'in', $ids)->delete();
Db::name('fc_dist_relation')->where('user_id', 'in', $ids)->whereOr('parent_id', 'in', $ids)->delete();
Db::name('fc_order')->where('user_id', 'in', $ids)->delete();
Db::name('fc_commission')->where('user_id', 'in', $ids)->whereOr('from_user_id', 'in', $ids)->delete();
Db::name('fc_withdraw')->where('user_id', 'in', $ids)->delete();
Db::name('fc_message')->where('user_id', 'in', $ids)->delete();
Db::name('user')->where('id', 'in', $ids)->delete();
}
/** 每个分类下的发布账号,按信息顺序一一对应 */
protected function owners()
{
return [
1 => [2001, 1002, 2002, 2005, 1002, 2001, 1003, 2004],
2 => [2002, 2002, 2002, 2002, 1001, 2002, 2002, 1001],
3 => [2003, 2006, 1002, 2005, 1003, 1001, 2003, 2006],
4 => [2004, 2007, 2004, 2007, 2004, 2007, 2003, 2007],
5 => [2005, 1003, 1001, 1003, 2005, 1003, 1002, 1001],
6 => [1002, 1003, 1001, 1002, 1003, 1001, 1002, 1003],
7 => [1003, 2005, 1003, 2005, 1003, 2005, 1003, 2005],
8 => [1002, 2003, 1001, 1002, 2003, 1001, 1002, 2003],
];
}
/** 审核状态:默认通过;少量待审/驳回用于验证后台流程 */
protected function auditStatus($categoryId, $index)
{
$pending = [[4, 6], [8, 7]];
$rejected = [[3, 5]];
if (in_array([$categoryId, $index], $pending, true)) {
return 0;
}
if (in_array([$categoryId, $index], $rejected, true)) {
return 2;
}
return 1;
}
/** 置顶:每个分类最多一条,制造首页头部内容 */
protected function isTop($categoryId, $index)
{
$tops = [[1, 0], [3, 1], [5, 0], [7, 1]];
return in_array([$categoryId, $index], $tops, true);
}
/** 区县名称 → 服务区域ID(fc_area.id) */
protected function areaId($area)
{
static $cache = [];
if (isset($cache[$area])) {
return $cache[$area];
}
$row = Db::name('fc_area')->where('district', $area)->find();
return $cache[$area] = $row ? (int)$row['id'] : 0;
}
/** 区域中心 + 稳定偏移,避免所有信息坐标完全重合 */
protected function coord($area, $index)
{
$base = isset(self::AREA_COORD[$area]) ? self::AREA_COORD[$area] : self::AREA_COORD['云岩区'];
$lat = $base[0] + (($index % 5) - 2) * 0.0055;
$lng = $base[1] + ((int)($index / 2) - 2) * 0.0065;
return [round($lat, 6), round($lng, 6)];
}
/**
* 信息配图:每条信息使用 1 张与内容匹配的真实照片作为封面和详情图。
* 图片存放在 public/static/posts/,随代码仓库部署,不依赖第三方外链。
*/
protected function mediaPaths($categoryId, $index)
{
$primary = $this->primaries()[$categoryId][$index];
return ['/static/posts/' . $primary . '.jpg'];
}
/** 每条信息的首图(与 posts() 的顺序一一对应) */
protected function primaries()
{
return [
1 => ['job-warehouse', 'job-cafe', 'job-office', 'job-cleaning', 'job-warehouse', 'job-delivery', 'job-classroom', 'job-handshake'],
2 => ['house-living1', 'house-living3', 'house-office', 'house-model', 'house-living2', 'house-living4', 'house-exterior', 'job-cafe'],
3 => ['goods-bike', 'goods-ipad', 'goods-dining', 'goods-fridge', 'goods-stroller', 'goods-laptop', 'goods-treadmill', 'goods-desk'],
4 => ['car-sedan-white', 'car-compact-blue', 'car-moto', 'car-hatch-red', 'car-coupe-blue', 'car-suv-white', 'goods-bike', 'car-sedan-dark'],
5 => ['svc-spray', 'svc-keys', 'svc-code', 'svc-wrench', 'svc-moving', 'svc-drill', 'svc-camera', 'svc-night'],
6 => ['edu-art', 'edu-books', 'edu-shelf', 'edu-guitar', 'edu-laptop', 'edu-class', 'car-sedan-white', 'edu-shelf'],
7 => ['clean-window', 'clean-bath', 'clean-baby', 'clean-kitchen', 'clean-kitchen', 'clean-window', 'clean-elder', 'clean-vacuum'],
8 => ['friend-hike', 'friend-badminton', 'friend-books', 'friend-run', 'friend-camera', 'friend-bike', 'friend-board', 'friend-group'],
];
}
/** 信息数据集:联系人 / 标题 / 内容 / 价格 / 单位 / 区域 / 地址 / 标签 */
protected function posts()
{
return [
// 招聘求职
1 => [
['杨经理', '急招快递分拣员(日结)', '站点直招,日结 180-220 元,包工作餐,当天结算。能吃苦、手脚麻利即可,年龄 18-50 岁。', 0, '面议', '云岩区', '贵阳北站物流园', '日结,包吃'],
['李店长', '奶茶店店员(包住)', '花果园商圈奶茶店招店员,负责点单和出杯。早班 10 点到 18 点,月休 4 天,包住,有提成。', 3800, '元/月', '南明区', '花果园购物中心', '包住,有提成'],
['周主管', '行政文员(双休)', '负责合同整理、客户接待和日常表格。会基本办公软件,做事细心,转正后买五险。', 4200, '元/月', '观山湖区', '金融城', '双休,五险'],
['王师傅', '招保洁员 5 名', '承接小区和写字楼保洁,公司派单,不用自己找客户。多劳多得,工资月结。', 3000, '元/月', '云岩区', '喷水池', '多劳多得,月结'],
['张店长', '超市理货员(兼职)', '每天下午 4 点到 9 点,负责补货和整理货架。适合学生和宝妈,工资周结。', 18, '元/小时', '南明区', '花果园', '兼职,周结'],
['刘站长', '外卖骑手(可日结)', '自带电动车优先,站点提供充电和休息区。跑单时间自由,多跑多得。', 6000, '元/月', '观山湖区', '世纪城', '日结,时间自由'],
['陈老师', '幼儿园保育员', '负责班级卫生和孩子日常照料,有保育员证优先。周末双休,包午餐。', 3200, '元/月', '花溪区', '贵州大学附近', '双休,包午餐'],
['吴经理', '汽车销售顾问', '负责到店客户接待和车型介绍,有销售经验优先。底薪加提成,上不封顶。', 5000, '元/月', '观山湖区', '金阳客车站旁', '底薪加提成,五险'],
],
// 房产租售
2 => [
['刘经理', '整租·未来方舟精装一室一厅', '家电齐全,拎包入住,近地铁 2 号线,押一付一,可短租。', 1800, '元/月', '南明区', '未来方舟 B 区', '精装,近地铁'],
['王女士', '花果园两室一厅 南北通透', '中间楼层,采光好,家具家电全带,随时看房。', 2200, '元/月', '南明区', '花果园', '采光好,随时看房'],
['周先生', '观山湖金融城写字楼出租', '80 平,独立办公室,带中央空调和前台,适合小团队。', 45, '元/㎡/月', '观山湖区', '金融城', '写字楼,带空调'],
['李女士', '云岩区学区房出售 满五唯一', '两室一厅 78 平,划片实验小学,业主置换急售。', 98, '万元', '云岩区', '喷水池', '学区房,满五唯一'],
['小杨', '花溪大学城单间合租', '独立卫生间,室友都是上班族,环境安静,押一付三。', 650, '元/月', '花溪区', '贵州大学北门', '合租,独卫'],
['刘经理', '世纪城三室两厅 拎包入住', '130 平,电梯房,家电齐全,适合一家人住。', 2600, '元/月', '观山湖区', '世纪城', '电梯房,家电齐全'],
['陈先生', '甲秀楼旁两室出售', '65 平,位置方便,出门就是菜场和公交站,价格可谈。', 62, '万元', '南明区', '甲秀楼', '位置好,可议价'],
['小杨', '观山湖门面转让(可空转)', '临街 40 平,带基础装修,适合小吃和便利店,接手就能营业。', 3500, '元/月', '观山湖区', '奥体中心', '临街,可空转'],
],
// 二手闲置
3 => [
['小周', '九成新山地自行车 转让', '骑行不到 300 公里,27 速,原价 1599,现 680 出,可小刀,同城自提。', 680, '元', '观山湖区', '世纪城', '自提,9成新'],
['小王', 'iPad 2021 64G 深空灰', '学生自用,无磕碰,配件齐全,支持当面验机。', 1450, '元', '观山湖区', '贵阳奥体中心', '验机,无磕碰'],
['小林', '实木餐桌椅 四人位', '搬家带不走,桌面无划痕,椅子结实,自提价。', 420, '元', '南明区', '花果园', '自提,实木'],
['王姐', '美的双门冰箱 260L', '用了两年,制冷正常,因为换大冰箱所以出,可上门看货。', 550, '元', '云岩区', '喷水池', '可看货,制冷正常'],
['小陈', '好孩子婴儿推车', '宝宝大了用不上,可坐可躺,折叠方便,清洗干净。', 180, '元', '花溪区', '花溪公园', '可折叠,已清洗'],
['小杨', '联想拯救者游戏本', '16G 内存,512G 固态,打游戏不卡,电池健康,带原装充电器。', 3200, '元', '南明区', '花果园', '游戏本,带充电器'],
['小周', '家用跑步机 九成新', '买来跑了不到十次,可折叠收纳,同城自提。', 800, '元', '观山湖区', '观山湖公园', '自提,可折叠'],
['小王', '书架加办公桌一套', '租房换地方,便宜出,书桌 1.2 米,书架五层。', 200, '元', '观山湖区', '世纪城', '一套,便宜出'],
],
// 车辆买卖
4 => [
['吴经理', '2019 款奥迪 A4L 一手车', '白色车身,车况好,无事故无泡水,4S 店保养记录齐全,支持第三方检测。', 12.8, '万元', '云岩区', '金阳客车站旁', '无事故,可检测'],
['优选二手车', '城市代步小车 2022 款', '车身小巧好停车,续航够日常通勤,跑了 1.2 万公里,手续齐全。', 2.6, '万元', '观山湖区', '世纪城', '代步,手续齐全'],
['吴经理', '雅马哈踏板摩托车', '125 排量,车况好,油耗低,带牌照一起出,可试车。', 4500, '元', '南明区', '花果园', '可试车,带牌'],
['老李', '二手代步小车 省油好开', '个人一手车,1.5 排量,市区代步省油,保养刚做,可试车。', 1.8, '万元', '云岩区', '贵阳北站', '省油,可试车'],
['吴经理', '宝马 4 系 2018 款', '蓝色车身,车况好,无事故,支持第三方检测,可分期。', 15.8, '万元', '观山湖区', '金融城', '无事故,可分期'],
['优选二手车', '家用七座 SUV 车况好', '七座大空间,适合一家人出行,无事故,保养记录齐全,可检测。', 8.8, '万元', '南明区', '龙洞堡', '7座,可检测'],
['小周', '电助力山地车', '36V 电池,助力续航 50 公里,上下班代步很省力。', 1600, '元', '观山湖区', '奥体中心', '助力,省力'],
['老李', '宝马 3 系 2019 款', '车况好,内饰干净,无事故,支持第三方检测,可分期。', 12.8, '万元', '花溪区', '石板物流园', '无事故,可分期'],
],
// 本地服务
5 => [
['王师傅', '专业空调清洗加氟上门', '10 年老师傅,清洗 60 元一台,加氟 80 元起,不满意不收费。', 60, '元/台', '南明区', '花果园', '上门,不满意不收费'],
['陈师傅', '开锁换锁 24 小时上门', '防盗门、汽车锁都能开,换锁芯明码标价,半夜也能来。', 80, '元起', '云岩区', '喷水池', '24小时,明码标价'],
['小杨', '电脑维修 重装系统', '蓝屏、开不了机、清灰换硅脂都能修,先检测后报价。', 50, '元起', '南明区', '花果园', '先检测,上门'],
['陈师傅', '管道疏通 高压清洗', '厨房下水、马桶、地漏疏通,不通不收费,节假日不休。', 100, '元起', '云岩区', '黔灵山公园', '不通不收费,节假日不休'],
['王师傅', '搬家拉货 小面包车', '市区内 120 元起,可帮忙搬下楼,费用提前说清楚。', 120, '元起', '观山湖区', '世纪城', '搬家,价格透明'],
['陈师傅', '防水补漏 免费上门检测', '屋顶、卫生间、外墙漏水都能做,先看现场再报价,质保两年。', 0, '面议', '花溪区', '花溪公园', '免费检测,质保两年'],
['小林', '摄影跟拍 婚礼活动', '婚礼、生日、毕业照都能拍,当天出精修图,可约周末。', 800, '元/场', '观山湖区', '观山湖公园', '跟拍,当天出图'],
['小杨', '酒后代驾 市区内', '晚上 8 点到凌晨 2 点接单,市区 39 元起,安全送到家。', 39, '元起', '南明区', '甲秀楼', '夜间,安全送达'],
],
// 教育培训
6 => [
['李老师', '少儿美术体验课 9.9 元', '4 到 12 岁都能来,画材全包,先体验再决定,周末可约。', 9.9, '元', '观山湖区', '世纪城', '体验课,画材全包'],
['张老师', '初三数学一对一辅导', '在职老师,带过三届毕业班,先测水平再定计划,可上门。', 150, '元/课时', '南明区', '花果园', '一对一,可上门'],
['招生办', '成人高考报名咨询', '大专本科都能报,流程有人指导,考前有资料,不收中介费。', 0, '面议', '云岩区', '喷水池', '学历提升,免费咨询'],
['阿杰老师', '吉他尤克里里 零基础班', '小班教学,一人一把琴,学会三首歌再续课,晚上和周末上课。', 80, '元/课时', '观山湖区', '奥体中心', '零基础,小班'],
['李老师', '少儿编程体验课', '图形化编程入门,边玩边学,适合 7 到 12 岁,电脑教室上课。', 19.9, '元', '花溪区', '花溪公园', '体验课,边玩边学'],
['招生办', '普通话考级培训', '针对二乙二甲考试,小班纠音,考前模拟测试,不过可重听。', 680, '元', '云岩区', '黔灵山公园', '考级,可重听'],
['王教练', '驾校 C1 报名', '本地练车,随到随学,科目一到科目四全程带,费用一次交清。', 2680, '元', '南明区', '龙洞堡', '一费制,随到随学'],
['张老师', '英语四六级冲刺班', '每周三次晚课,讲真题和作文模板,适合基础一般的大学生。', 499, '元', '花溪区', '贵州大学', '冲刺班,真题讲解'],
],
// 家政保洁
7 => [
['陈姐', '日常保洁 3 小时', '扫地拖地、擦灰、厨房卫生间清洁,自带工具,满意再付款。', 120, '元/次', '南明区', '花果园', '自带工具,满意付款'],
['王师傅', '新房开荒保洁', '装修后除尘除胶,玻璃和柜子里外都擦,按面积算,量大优惠。', 5, '元/㎡', '观山湖区', '世纪城', '开荒,按面积'],
['陈姐', '月嫂育儿嫂 可预约', '带过 30 多个宝宝,会做月子餐,有健康证,可先面试。', 8000, '元/月', '云岩区', '喷水池', '有健康证,可面试'],
['王师傅', '油烟机洗衣机深度清洗', '拆洗不伤机器,清洗完当场试机,两台一起更划算。', 199, '元', '南明区', '花果园', '拆洗,当场试机'],
['陈姐', '钟点工 做饭打扫', '每天两小时,做饭加简单收拾,口味可以按家里习惯来。', 35, '元/小时', '观山湖区', '金融城', '做饭,按小时'],
['王师傅', '高层玻璃清洗', '内外都能擦,带安全绳,雨天不接单,提前一天预约。', 150, '元起', '观山湖区', '奥体中心', '高层,带安全绳'],
['陈姐', '老人陪护 住家', '照顾能自理的老人,做饭陪着说话,有护理经验,可长期。', 4500, '元/月', '花溪区', '花溪公园', '住家,有护理经验'],
['王师傅', '地毯清洗 上门', '公司办公室和家庭地毯都能洗,洗完当天能干,按平方计价。', 8, '元/㎡', '云岩区', '贵阳北站', '上门,当天干'],
],
// 同城交友
8 => [
['小林', '周末爬山搭子 黔灵山', '周六早上 8 点黔灵山门口集合,走慢线,新手也能来,自带水。', 0, '面议', '云岩区', '黔灵山公园', '爬山,新手友好'],
['小周', '羽毛球约球 每周三晚', '观山湖体育馆,水平一般,主要活动身体,场地费 AA。', 0, '面议', '观山湖区', '奥体中心', '羽毛球,AA'],
['小杨', '贵阳本地读书会 招募', '每月一本书,线下聊两小时,不限年龄职业,安静参与就好。', 0, '面议', '南明区', '甲秀楼', '读书会,每月一次'],
['小林', '90 后女生 找运动搭子', '平时跑步、骑车都可以,周末有空,希望住得近一点,互相监督。', 0, '面议', '观山湖区', '观山湖公园', '运动,住得近'],
['小周', '摄影爱好者 周末扫街', '喜欢拍老街和人文,器材不限,手机也能一起玩,拍完一起吃饭。', 0, '面议', '云岩区', '喷水池', '摄影,手机也行'],
['小杨', '骑行群招募 周末环湖', '休闲骑,速度不快,观山湖集合,骑完喝茶,安全第一。', 0, '面议', '观山湖区', '观山湖公园', '骑行,休闲'],
['小林', '桌游局 缺 2 人', '周六下午玩狼人杀和剧本,新手有人带,场地在花果园,费用 AA。', 0, '面议', '南明区', '花果园', '桌游,新手可来'],
['小周', '单身青年联谊活动 报名', '25 到 35 岁,工作稳定,活动有游戏和自由聊天,提前报名。', 0, '面议', '南明区', '花果园', '联谊,提前报名'],
],
];
}
/** 评价:post_id => [用户ID, 评分, 内容, 商家回复] */
protected function seedComments($now)
{
$comments = [
101 => [[1002, 5, '联系很及时,当天就上岗了。', ''], [2003, 5, '工资日结是真的,站长人也不错。', '']],
102 => [[1003, 5, '店里氛围挺好,排班也合理。', '']],
109 => [[1003, 4, '房子不错,房东好说话。', '感谢支持,欢迎续租~']],
110 => [[1002, 5, '采光确实好,看房很方便。', '']],
117 => [[2006, 5, '车况和描述一致,交易很顺利。', ''], [1001, 4, '卖家很爽快,还送了车锁。', '']],
118 => [[2003, 5, '当面验过机,没有问题。', '']],
125 => [[2003, 5, '检测报告齐全,买得放心。', '']],
126 => [[1002, 4, '代步够用,充电也方便。', '']],
133 => [[1001, 5, '师傅上门很准时,清洗得很干净。', '感谢认可,有需要随时联系。']],
134 => [[2006, 5, '半夜叫的开锁,十分钟就到了。', '']],
141 => [[1003, 5, '孩子很喜欢,老师也有耐心。', '']],
142 => [[2003, 4, '讲得清楚,孩子愿意学。', '']],
149 => [[1001, 5, '打扫得仔细,下次还约。', '']],
150 => [[1003, 5, '开荒做得很干净,柜子里面都擦了。', '']],
157 => [[1003, 5, '上周去过,路线轻松,人也很好。', '']],
158 => [[1001, 5, '水平差不多,打得很尽兴。', '']],
];
$id = 5001;
$i = 0;
foreach ($comments as $postId => $rows) {
foreach ($rows as $row) {
$t = $now - (int)((0.4 + $i * 0.23) * 86400);
Db::name('fc_comment')->insert([
'id' => $id,
'post_id' => $postId,
'user_id' => $row[0],
'score' => $row[1],
'content' => $row[2],
'images' => json_encode([], JSON_UNESCAPED_UNICODE),
'reply' => $row[3],
'replytime' => $row[3] !== '' ? $t + 3600 : null,
'top' => 0,
'status' => 1,
'createtime' => $t,
'updatetime' => $t,
]);
$id++;
$i++;
}
}
}
/** 草稿:保留两条未完成信息,用于验证草稿箱 */
protected function seedDrafts($now)
{
$rows = [
[1001, 2, '转租单间(草稿)', '房子还在收拾,晚点补照片。'],
[1003, 7, '保洁套餐(草稿)', '想做一个三次卡的套餐,价格还没定。'],
];
$t = $now - 7200;
foreach ($rows as $row) {
Db::name('fc_draft')->insert([
'user_id' => $row[0],
'category_id' => $row[1],
'title' => $row[2],
'content' => $row[3],
'media' => json_encode([], JSON_UNESCAPED_UNICODE),
'contact' => '',
'phone' => '',
'address' => '',
'savedat' => $t,
'createtime' => $t,
'updatetime' => $t,
]);
$t -= 1800;
}
}
/** 举报:两条不同状态,便于后台处理演示 */
protected function seedReports($now)
{
$rows = [
['post', 117, '价格与描述不一致', 1002, 'pending', '', 0.6],
['comment', 5002, '评论里留了外部联系方式', 2006, 'handled', '已删除违规评论', 3],
];
foreach ($rows as $row) {
$t = $now - (int)($row[6] * 86400);
Db::name('fc_report')->insert([
'target_type' => $row[0],
'target_id' => $row[1],
'reason' => $row[2],
'reporter_id' => $row[3],
'status' => $row[4],
'remark' => $row[5],
'createtime' => $t,
'updatetime' => $t,
]);
}
}
/** 回写分类信息量 / 评价数,保证列表计数与真实数据一致 */
protected function syncCounts()
{
Db::execute('UPDATE `' . \think\Config::get('database.prefix') . 'fc_post` p SET p.`comment_count` = (SELECT COUNT(*) FROM `' . \think\Config::get('database.prefix') . 'fc_comment` c WHERE c.`post_id` = p.`id` AND c.`status` = 1)');
foreach ([1, 2, 3, 4, 5, 6, 7, 8] as $categoryId) {
$count = Db::name('fc_post')
->where('category_id', $categoryId)
->where('audit_status', 1)
->where('status', 1)
->whereNull('deletetime')
->count();
Db::name('fc_category')->where('id', $categoryId)->update(['post_count' => $count]);
}
// 同步商家有效发帖数
$merchants = Db::name('fc_merchant')->field('id,user_id')->select();
foreach ($merchants as $m) {
$mCount = Db::name('fc_post')
->where('user_id', $m['user_id'])
->where('audit_status', 1)
->where('status', 1)
->whereNull('deletetime')
->count();
Db::name('fc_merchant')->where('id', $m['id'])->update(['post_count' => $mCount]);
}
}
}