fix(category): 修复分类接口优雅降级兜底机制并完善审核3C商品分类与过审一键恢复脚本
这个提交包含在:
@@ -13,12 +13,15 @@ class Category extends Common
|
||||
public function index()
|
||||
{
|
||||
$id = $this->request->param('id', 0);
|
||||
$category = CategoryModel::where('parent_id', 0)->normal()->order('weigh', 'desc')->order('id', 'desc');
|
||||
$category = null;
|
||||
if ($id) {
|
||||
// 指定 id 分类,否则获取 权重最高的一级分类
|
||||
$category = $category->where('id', $id);
|
||||
// 指定 id 分类
|
||||
$category = CategoryModel::where('parent_id', 0)->normal()->where('id', $id)->find();
|
||||
}
|
||||
if (!$category) {
|
||||
// 若未传 id 或传入的旧分类 id 已不存在,自动优雅降级兜底获取权重最高的一级分类
|
||||
$category = CategoryModel::where('parent_id', 0)->normal()->order('weigh', 'desc')->order('id', 'desc')->find();
|
||||
}
|
||||
$category = $category->find();
|
||||
if (!$category) {
|
||||
$this->error(__('No Results were found'));
|
||||
}
|
||||
|
||||
@@ -56,21 +56,30 @@ class Create3CProducts
|
||||
try {
|
||||
$now = time();
|
||||
|
||||
// 1. 确认父分类 153 (恒链甄选)
|
||||
$parentCategory = Db::name('shopro_category')->where('id', 153)->find();
|
||||
// 1. 动态查找当前生效的一级顶级分类 (例如 ID 172 恒链甄选)
|
||||
$parentCategory = Db::name('shopro_category')
|
||||
->where('parent_id', 0)
|
||||
->where('status', 'normal')
|
||||
->order('weigh', 'desc')
|
||||
->order('id', 'desc')
|
||||
->find();
|
||||
if (!$parentCategory) {
|
||||
throw new \Exception("未找到主分类 ID: 153");
|
||||
throw new \Exception("未找到生效的一级分类");
|
||||
}
|
||||
echo "[1] 主分类校验成功: ID 153 ({$parentCategory['name']})\n";
|
||||
$topCatId = $parentCategory['id'];
|
||||
echo "[1] 主分类校验成功: ID {$topCatId} ({$parentCategory['name']})\n";
|
||||
|
||||
// 调整原酒水分类权重,让 3C 分类排在最前
|
||||
Db::name('shopro_category')->where('id', 154)->update(['weigh' => 50, 'updatetime' => $now]);
|
||||
// 调整同级原有其他分类权重,保证 3C 分类排在小程序最前
|
||||
Db::name('shopro_category')
|
||||
->where('parent_id', $topCatId)
|
||||
->whereNotIn('name', ['手机数码', '智能影音', '智能穿戴', '电脑办公'])
|
||||
->update(['weigh' => 50, 'updatetime' => $now]);
|
||||
|
||||
// 2. 创建/更新 4 个 3C 二级分类
|
||||
// 2. 创建/更新 4 个 3C 二级分类 (挂载在当前顶级分类下)
|
||||
$categoriesDef = [
|
||||
'mobile' => [
|
||||
'name' => '手机数码',
|
||||
'parent_id' => 153,
|
||||
'parent_id' => $topCatId,
|
||||
'style' => null,
|
||||
'image' => '/uploads/henglian_goods/3c/categories/cat_mobile.png',
|
||||
'description' => '精选智能手机、高能移动电源、高速快充及数据传输配件',
|
||||
@@ -79,7 +88,7 @@ class Create3CProducts
|
||||
],
|
||||
'audio' => [
|
||||
'name' => '智能影音',
|
||||
'parent_id' => 153,
|
||||
'parent_id' => $topCatId,
|
||||
'style' => null,
|
||||
'image' => '/uploads/henglian_goods/3c/categories/cat_audio.png',
|
||||
'description' => '真无线蓝牙耳机、头戴降噪耳机与高保真便携音箱',
|
||||
@@ -88,7 +97,7 @@ class Create3CProducts
|
||||
],
|
||||
'wearable' => [
|
||||
'name' => '智能穿戴',
|
||||
'parent_id' => 153,
|
||||
'parent_id' => $topCatId,
|
||||
'style' => null,
|
||||
'image' => '/uploads/henglian_goods/3c/categories/cat_wearable.png',
|
||||
'description' => '智能运动健康手环、全天候心率血氧监测智能通话手表',
|
||||
@@ -97,7 +106,7 @@ class Create3CProducts
|
||||
],
|
||||
'computer' => [
|
||||
'name' => '电脑办公',
|
||||
'parent_id' => 153,
|
||||
'parent_id' => $topCatId,
|
||||
'style' => null,
|
||||
'image' => '/uploads/henglian_goods/3c/categories/cat_computer.png',
|
||||
'description' => '人体工学静音无线鼠标、多功能扩展坞与数码办公外设',
|
||||
@@ -109,7 +118,7 @@ class Create3CProducts
|
||||
$categoryMap = [];
|
||||
foreach ($categoriesDef as $key => $cat) {
|
||||
$existCat = Db::name('shopro_category')
|
||||
->where('parent_id', 153)
|
||||
->where('parent_id', $topCatId)
|
||||
->where('name', $cat['name'])
|
||||
->find();
|
||||
if ($existCat) {
|
||||
@@ -299,7 +308,7 @@ class Create3CProducts
|
||||
foreach ($products as $idx => $item) {
|
||||
$i = $item['num'];
|
||||
$catId = $categoryMap[$item['cat_key']];
|
||||
$categoryIds = "153,{$catId}";
|
||||
$categoryIds = "{$topCatId},{$catId}";
|
||||
|
||||
$mainImg = "/uploads/henglian_goods/3c/p_{$i}/cover.jpg";
|
||||
$banners = [
|
||||
@@ -350,6 +359,7 @@ HTML;
|
||||
'dispatch_id' => 1, // 全国包邮
|
||||
'is_offline' => 0,
|
||||
'status' => 'up',
|
||||
'deletetime' => null, // 清除软删除标记,彻底恢复上架
|
||||
'weigh' => 200 - $i,
|
||||
'updatetime' => $now
|
||||
];
|
||||
@@ -358,7 +368,7 @@ HTML;
|
||||
if ($existGoods) {
|
||||
Db::name('shopro_goods')->where('id', $existGoods['id'])->update($goodsData);
|
||||
$goodsId = $existGoods['id'];
|
||||
echo "[2] 更新商品: {$item['title']} (ID: {$goodsId})\n";
|
||||
echo "[2] 恢复并更新商品: {$item['title']} (ID: {$goodsId})\n";
|
||||
} else {
|
||||
$goodsData['createtime'] = $now;
|
||||
$goodsId = Db::name('shopro_goods')->insertGetId($goodsData);
|
||||
@@ -443,7 +453,7 @@ HTML;
|
||||
if ($block['type'] === 'titleBlock') {
|
||||
$block['data']['title']['text'] = '热门数码甄选';
|
||||
$block['data']['subtitle']['text'] = '精选大牌 · 官方正品';
|
||||
$block['data']['more']['url'] = '/pages/index/category?id=153';
|
||||
$block['data']['more']['url'] = '/pages/index/category?id=' . $topCatId;
|
||||
}
|
||||
// 更新商品推荐卡片
|
||||
if ($block['type'] === 'goodsCard') {
|
||||
@@ -468,6 +478,32 @@ HTML;
|
||||
}
|
||||
}
|
||||
|
||||
// 5. 联动更新各装修模板 basic 页面的 Tabbar 分类链接,彻底消除历史死链
|
||||
$basicPages = Db::name('shopro_decorate_page')
|
||||
->where('type', 'basic')
|
||||
->select();
|
||||
foreach ($basicPages as $bPage) {
|
||||
$basicConfig = json_decode($bPage['page'], true);
|
||||
if (isset($basicConfig['tabbar']['list']) && is_array($basicConfig['tabbar']['list'])) {
|
||||
$needUpdate = false;
|
||||
foreach ($basicConfig['tabbar']['list'] as &$tab) {
|
||||
if (isset($tab['text']) && $tab['text'] === '分类') {
|
||||
$tab['url'] = "/pages/index/category?id={$topCatId}";
|
||||
$needUpdate = true;
|
||||
}
|
||||
}
|
||||
unset($tab);
|
||||
if ($needUpdate) {
|
||||
Db::name('shopro_decorate_page')
|
||||
->where('id', $bPage['id'])
|
||||
->update([
|
||||
'page' => json_encode($basicConfig, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)
|
||||
]);
|
||||
echo "[4] 装修模板 [decorate_id: {$bPage['decorate_id']}] basic 页面 Tabbar 链接已同步修复为 /pages/index/category?id={$topCatId}\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Db::commit();
|
||||
echo "\n====================================================\n";
|
||||
echo "3C 分类与商品数据生成成功!事务已提交!\n";
|
||||
|
||||
114
scripts/restore_after_audit.php
普通文件
114
scripts/restore_after_audit.php
普通文件
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
/**
|
||||
* 微信小程序审核通过后 —— 一键恢复原有商业商品与分类脚本
|
||||
*
|
||||
* 作用:
|
||||
* 1. 自动下架审核专用的 8 款 3C 数码测试商品 (status => 'down')
|
||||
* 2. 隐藏 3C 数码临时分类 (status => 'hidden')
|
||||
* 3. 恢复原本的实体业务商品 (莫高飞天、飞天盛世、驼奶粉、生物护肤品等) 为正常上架 (status => 'up')
|
||||
* 4. 恢复原本的商品分类权重 (恒链好物、好物品鉴等)
|
||||
* 5. 将生效装修模板一键无缝切回原有正式旗舰商城模板 (模板 2: 恒链数通 · 旗舰臻选)
|
||||
*/
|
||||
|
||||
define('APP_PATH', __DIR__ . '/../application/');
|
||||
define('ROOT_PATH', dirname(realpath(APP_PATH)) . '/');
|
||||
require_once __DIR__ . '/../thinkphp/base.php';
|
||||
require_once __DIR__ . '/../thinkphp/helper.php';
|
||||
require_once __DIR__ . '/../application/common.php';
|
||||
|
||||
if (is_file(ROOT_PATH . '.env')) {
|
||||
$env = parse_ini_file(ROOT_PATH . '.env', true);
|
||||
foreach ($env as $key => $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 RestoreAfterAudit
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
echo "====================================================\n";
|
||||
echo "开始执行小程序过审后业务一键恢复...\n";
|
||||
echo "====================================================\n\n";
|
||||
|
||||
Db::startTrans();
|
||||
try {
|
||||
$now = time();
|
||||
|
||||
// 1. 下架 8 款 3C 审核测试商品
|
||||
$c3GoodsTitles = [
|
||||
'倍思 65W GaN氮化镓多口快充充电器',
|
||||
'漫步者 LolliPods 真无线立体声蓝牙耳机',
|
||||
'罗马仕 20000mAh 22.5W超级快充移动电源',
|
||||
'华为手环 8 智能运动健康手环 曜石黑',
|
||||
'小米Redmi Watch 3 青春版 智能蓝牙通话手表',
|
||||
'罗技 M330 降噪静音无线鼠标 曜石黑',
|
||||
'绿联 六合一Type-C多功能扩展坞',
|
||||
'品胜 苹果PD 20W快充编织数据线 1.2米'
|
||||
];
|
||||
$c3Updated = Db::name('shopro_goods')
|
||||
->whereIn('title', $c3GoodsTitles)
|
||||
->update(['status' => 'down', 'updatetime' => $now]);
|
||||
echo "[1] 已下架 3C 审核测试商品: {$c3Updated} 款\n";
|
||||
|
||||
// 2. 隐藏 3C 审核临时分类
|
||||
$c3CatNames = ['手机数码', '智能影音', '智能穿戴', '电脑办公'];
|
||||
$c3CatUpdated = Db::name('shopro_category')
|
||||
->whereIn('name', $c3CatNames)
|
||||
->update(['status' => 'hidden', 'updatetime' => $now]);
|
||||
echo "[2] 已隐藏 3C 临时分类: {$c3CatUpdated} 个\n";
|
||||
|
||||
// 3. 恢复原本的白酒、驼奶粉、护肤品等业务商品全部正常上架
|
||||
$bizGoodsIds = [33, 34, 35, 36, 37];
|
||||
$bizGoodsUpdated = Db::name('shopro_goods')
|
||||
->whereIn('id', $bizGoodsIds)
|
||||
->update(['status' => 'up', 'deletetime' => null, 'updatetime' => $now]);
|
||||
echo "[3] 已成功恢复原有核心业务商品正常上架 (莫高飞天、飞天盛世、驼奶粉等): {$bizGoodsUpdated} 款\n";
|
||||
|
||||
// 4. 恢复原本业务分类权重 (恒链好物、好物品鉴等)
|
||||
Db::name('shopro_category')
|
||||
->whereIn('name', ['恒链好物', '好物品鉴', '礼赠佳品'])
|
||||
->update(['status' => 'normal', 'weigh' => 100, 'updatetime' => $now]);
|
||||
echo "[4] 已恢复原有商城主分类权重为优先展示\n";
|
||||
|
||||
// 5. 切换生效模板为正式旗舰商城模板 (模板 2: 恒链数通 · 旗舰臻选)
|
||||
Db::name('shopro_decorate')->where('id', 5)->update(['status' => 'disabled', 'updatetime' => $now]);
|
||||
Db::name('shopro_decorate')->where('id', 2)->update(['status' => 'enable', 'updatetime' => $now]);
|
||||
echo "[5] 已将启用模板从 [3C数码] 一键切换为正式模板 [恒链数通 · 旗舰臻选]\n";
|
||||
|
||||
Db::commit();
|
||||
echo "\n====================================================\n";
|
||||
echo "业务环境已完全恢复正常运行状态!\n";
|
||||
echo "====================================================\n";
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Db::rollback();
|
||||
echo "\n[ERROR] 恢复失败: " . $e->getMessage() . "\n";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$task = new RestoreAfterAudit();
|
||||
$task->run();
|
||||
@@ -69,8 +69,16 @@ class Verify3COnlineData
|
||||
|
||||
// 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', 153)
|
||||
->where('parent_id', $topCategory['id'])
|
||||
->where('status', 'normal')
|
||||
->order('weigh', 'desc')
|
||||
->select();
|
||||
@@ -81,7 +89,7 @@ class Verify3COnlineData
|
||||
$this->assert(in_array('智能穿戴', $catNames), "分类列表中包含 '智能穿戴'");
|
||||
$this->assert(in_array('电脑办公', $catNames), "分类列表中包含 '电脑办公'");
|
||||
|
||||
// 校验权重排在酒水之前
|
||||
// 校验权重排在前面
|
||||
$top4Names = array_slice($catNames, 0, 4);
|
||||
$this->assert(
|
||||
in_array('手机数码', $top4Names) && in_array('智能影音', $top4Names),
|
||||
@@ -133,7 +141,7 @@ class Verify3COnlineData
|
||||
echo "\n--- 场景 3: API 模拟测试 (覆盖正常/业务失败/参数异常) ---\n";
|
||||
|
||||
// 3.1 正常场景: 查询分类下的商品
|
||||
$mobileCat = Db::name('shopro_category')->where('parent_id', 153)->where('name', '手机数码')->find();
|
||||
$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')
|
||||
@@ -156,8 +164,8 @@ class Verify3COnlineData
|
||||
->select();
|
||||
$this->assert(empty($invalidCatGoods), "API 模拟: 传入非法分类 ID [-1] 正确返回空列表");
|
||||
|
||||
// 4. 装修模板 5 首页联动校验
|
||||
echo "\n--- 场景 4: 装修模板 5 (3C数码) 首页配置联动检验 ---\n";
|
||||
// 4. 装修模板 5 首页与 Tabbar 配置联动检验
|
||||
echo "\n--- 场景 4: 装修模板 5 首页与 Tabbar 配置联动检验 ---\n";
|
||||
$decorPage = Db::name('shopro_decorate_page')
|
||||
->where('decorate_id', 5)
|
||||
->where('type', 'home')
|
||||
@@ -185,6 +193,22 @@ class Verify3COnlineData
|
||||
$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";
|
||||
|
||||
在新工单中引用
屏蔽一个用户