$val) { $name = 'PHP_' . strtoupper($key); if (is_array($val)) { foreach ($val as $k => $v) { putenv("{$name}_" . strtoupper($k) . "={$v}"); } } else { putenv("{$name}={$val}"); } } } \think\Config::set(\think\Config::load(APP_PATH . 'config.php')); $dbConfig = [ 'type' => 'mysql', 'hostname' => '127.0.0.1', 'database' => 'henglianshutong', 'username' => 'henglianshutong', 'password' => 'henglianshutong', 'hostport' => '3306', 'prefix' => 'hla_', ]; \think\Config::set('database', $dbConfig); use think\Db; class Verify3COnlineData { private $passed = 0; private $failed = 0; private function assert($condition, $message) { if ($condition) { echo " [PASS] {$message}\n"; $this->passed++; } else { echo " [FAIL] {$message}\n"; $this->failed++; } } public function run() { echo "====================================================\n"; echo "开始验证 3C 商品与分类线上数据及 API 接口...\n"; echo "====================================================\n\n"; // 1. 分类检验 echo "--- 场景 1: 分类层级与权重检验 ---\n"; $topCategory = Db::name('shopro_category') ->where('parent_id', 0) ->where('status', 'normal') ->order('weigh', 'desc') ->order('id', 'desc') ->find(); $this->assert(!empty($topCategory), "获取当前生效一级主分类成功 (ID: {$topCategory['id']}, 名称: {$topCategory['name']})"); $categories = Db::name('shopro_category') ->where('parent_id', $topCategory['id']) ->where('status', 'normal') ->order('weigh', 'desc') ->select(); $catNames = array_column($categories, 'name'); $this->assert(in_array('手机数码', $catNames), "分类列表中包含 '手机数码'"); $this->assert(in_array('智能影音', $catNames), "分类列表中包含 '智能影音'"); $this->assert(in_array('智能穿戴', $catNames), "分类列表中包含 '智能穿戴'"); $this->assert(in_array('电脑办公', $catNames), "分类列表中包含 '电脑办公'"); // 校验权重排在前面 $top4Names = array_slice($catNames, 0, 4); $this->assert( in_array('手机数码', $top4Names) && in_array('智能影音', $top4Names), "前 4 大展示分类全部为 3C 核心品类" ); // 2. 商品检验 echo "\n--- 场景 2: 8 款主流 3C 商品及 SKU 检验 ---\n"; $titles = [ '倍思 65W GaN氮化镓多口快充充电器', '漫步者 LolliPods 真无线立体声蓝牙耳机', '罗马仕 20000mAh 22.5W超级快充移动电源', '华为手环 8 智能运动健康手环 曜石黑', '小米Redmi Watch 3 青春版 智能蓝牙通话手表', '罗技 M330 降噪静音无线鼠标 曜石黑', '绿联 六合一Type-C多功能扩展坞', '品胜 苹果PD 20W快充编织数据线 1.2米' ]; $goodsList = Db::name('shopro_goods') ->whereIn('title', $titles) ->whereNull('deletetime') ->select(); $this->assert(count($goodsList) === 8, "8 款 3C 商品均已完整入库并正常启用 (实际: " . count($goodsList) . ")"); $goodsIds = []; foreach ($goodsList as $goods) { $goodsIds[] = $goods['id']; $this->assert($goods['status'] === 'up', "商品 [{$goods['title']}] 状态为正常上架 (up)"); $this->assert(!empty($goods['image']), "商品 [{$goods['title']}] 配备高清封面图"); $images = json_decode($goods['images'], true); $this->assert(is_array($images) && count($images) >= 3, "商品 [{$goods['title']}] 包含 3 张高清轮播图"); $params = json_decode($goods['params'], true); $this->assert(is_array($params) && count($params) >= 5, "商品 [{$goods['title']}] 包含完整规格参数指标 (≥5项)"); $this->assert(strpos($goods['content'], '正品保障') !== false, "商品 [{$goods['title']}] 详情包含正品与官方售后承诺"); // SKU 价格与库存 $sku = Db::name('shopro_goods_sku_price')->where('goods_id', $goods['id'])->find(); $this->assert(!empty($sku), "商品 [{$goods['title']}] 存在有效 SKU 价格记录"); $this->assert($sku['stock'] >= 1000, "商品 [{$goods['title']}] 库存充足 (当前库存: {$sku['stock']})"); $this->assert($sku['price'] > 0 && $sku['price'] == $goods['price'], "商品 [{$goods['title']}] 售价核验一致 ({$sku['price']}元)"); } // 3. API 模拟测试 echo "\n--- 场景 3: API 模拟测试 (覆盖正常/业务失败/参数异常) ---\n"; // 3.1 正常场景: 查询分类下的商品 $mobileCat = Db::name('shopro_category')->where('parent_id', $topCategory['id'])->where('name', '手机数码')->find(); $mobileGoods = Db::name('shopro_goods') ->whereRaw("find_in_set({$mobileCat['id']}, category_ids)") ->where('status', 'up') ->whereNull('deletetime') ->select(); $this->assert(count($mobileGoods) >= 3, "API 模拟: 查询 [手机数码] 分类成功返回对应商品 (返回: " . count($mobileGoods) . "款)"); // 3.2 正常场景: 商品详情查询 $firstGoodsId = $goodsIds[0]; $detail = Db::name('shopro_goods')->where('id', $firstGoodsId)->where('status', 'up')->find(); $this->assert(!empty($detail) && $detail['id'] == $firstGoodsId, "API 模拟: 获取商品 ID [{$firstGoodsId}] 详情成功"); // 3.3 业务失败场景: 查询下架或不存在的商品 $nonExistDetail = Db::name('shopro_goods')->where('id', 999999)->where('status', 'up')->find(); $this->assert(empty($nonExistDetail), "API 模拟: 查询不存在商品 ID [999999] 正确返回空 (业务预期失败)"); // 3.4 参数异常场景: 空参数或非法分类 ID $invalidCatGoods = Db::name('shopro_goods') ->whereRaw("find_in_set(-1, category_ids)") ->select(); $this->assert(empty($invalidCatGoods), "API 模拟: 传入非法分类 ID [-1] 正确返回空列表"); // 4. 装修模板 5 首页与 Tabbar 配置联动检验 echo "\n--- 场景 4: 装修模板 5 首页与 Tabbar 配置联动检验 ---\n"; $decorPage = Db::name('shopro_decorate_page') ->where('decorate_id', 5) ->where('type', 'home') ->find(); $this->assert(!empty($decorPage), "装修模板 5 (3C数码) home 页面记录存在"); if ($decorPage) { $pageConfig = json_decode($decorPage['page'], true); $found3CSearch = false; $found3CGoods = false; foreach ($pageConfig['data'] as $block) { if ($block['type'] === 'searchBlock') { if (strpos($block['data']['placeholder'], '65W') !== false || in_array('65W快充', $block['data']['keywords'])) { $found3CSearch = true; } } if ($block['type'] === 'goodsCard') { if (isset($block['data']['goodsIds']) && !empty(array_intersect($block['data']['goodsIds'], $goodsIds))) { $found3CGoods = true; } } } $this->assert($found3CSearch, "首页搜索框关键词已更新为 3C 数码热词"); $this->assert($found3CGoods, "首页推荐商品卡片已关联新生成的 3C 数码爆品"); } // 校验 Tabbar 链接已指向当前主分类,杜绝死链 $basicPage = Db::name('shopro_decorate_page')->where('decorate_id', 5)->where('type', 'basic')->find(); if ($basicPage) { $basicConfig = json_decode($basicPage['page'], true); $tabbarCategoryUrl = ''; foreach ($basicConfig['tabbar']['list'] as $tab) { if ($tab['text'] === '分类') { $tabbarCategoryUrl = $tab['url']; } } $this->assert( $tabbarCategoryUrl === "/pages/index/category?id={$topCategory['id']}", "Tabbar 分类链接正确指向当前有效顶级分类 ({$tabbarCategoryUrl})" ); } echo "\n====================================================\n"; echo "测试执行完成: 通过 {$this->passed} 项, 失败 {$this->failed} 项\n"; echo "====================================================\n"; if ($this->failed > 0) { exit(1); } } } $verifier = new Verify3COnlineData(); $verifier->run();