推荐位 alias 会修改甚至为 null,而业务代码又依赖 alias 做硬编码查找,这导致数据与代码之间的绑定关系出现混乱,维护成本和出错风险上升
1、– `official-website-management-system`.recommendation_slots definition
CREATE TABLE `recommendation_slots` ( `id` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL, `alias` varchar(200) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `name` varchar(200) COLLATE utf8mb4_unicode_ci DEFAULT '', `cover_image_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '封面图', `more_redirect_url` varchar(300) COLLATE utf8mb4_unicode_ci DEFAULT '', `title` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT '', `keywords` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT '', `description` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT '', `content` text COLLATE utf8mb4_unicode_ci, `usage` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '用法', `status` tinyint unsigned DEFAULT '1' COMMENT '是否显示 1可用 2不可用 4删除', `created_at` datetime DEFAULT NULL, `updated_at` datetime DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `idx-alias` (`alias`), KEY `idx-status` (`status`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- `official-website-management-system`.recommendation_contents definition CREATE TABLE `recommendation_contents` ( `id` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL, `slot_id` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `type` tinyint unsigned DEFAULT '5' COMMENT '类型 1文章 2视频 3音频 4图片 5链接 6小程序 7应用 9其他', `title` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT '', `cover_image_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '封面图', `image_1_id` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `image_2_id` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `image_3_id` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `text_1` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '文本一', `text_2` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '文本二', `text_3` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '文本三', `link_1` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '链接一', `link_2` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '链接二', `link_3` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '链接三', `keywords` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT '', `description` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT '', `content` text COLLATE utf8mb4_unicode_ci, `click_count` int unsigned DEFAULT '0', `status` tinyint unsigned DEFAULT '1' COMMENT '是否显示 1显示 2不显示', `order_number` int unsigned DEFAULT '1' COMMENT '排序,数值越大越靠前', `created_at` datetime DEFAULT NULL, `updated_at` datetime DEFAULT NULL, PRIMARY KEY (`id`), KEY `idx-slot_id` (`slot_id`), KEY `idx-status` (`status`), KEY `idx-order_number` (`order_number`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
现有推荐位与推荐位数据两张表。
还有一个推荐位的初始化脚本,代码实现如下:
<?php namespace console\controllers; use common\models\IdMaker; use common\models\RecommendationSlot; use Yii; use yii\console\Controller; use yii\console\ExitCode; use yii\db\Exception; use yii\helpers\BaseConsole; use yii\helpers\Console; class RecommendationSlotController extends Controller { /** * 推荐位数据初始化 * @return void * @throws Exception */ public function actionInit() { $now = date('Y-m-d H:i:s'); $data = [ [ 'id' => '1001', 'alias' => 'sidebar-contact-1', 'name' => '获取专业会务管理解决方案', 'title' => '获取专业会务管理解决方案', 'description' => '', 'usage' => '', ], [ 'id' => '1002', 'alias' => 'sidebar-features', 'name' => '会务功能', 'title' => '会务功能', 'description' => '', 'usage' => '', ], [ 'id' => '1003', 'alias' => 'sidebar-products', 'name' => '产品服务', 'title' => '产品服务', 'description' => '', 'usage' => '', ], [ 'id' => '1004', 'alias' => 'sidebar-contact-2', 'name' => '我有需求立即联系', 'title' => '我有需求立即联系', 'description' => '', 'usage' => '', ], [ 'id' => '1006', 'alias' => 'setting-tabs', 'name' => '“真”零代码灵活搭建,专属系统灵活配置', 'title' => '“真”零代码灵活搭建,专属系统灵活配置', 'description' => '5分钟上手,1小时上线,个性化需求随时调整', 'usage' => '', ], [ 'id' => '1007', 'alias' => 'cases-with-image-and-content', 'name' => '300万用户在使用***,他们在竞争中脱颖而出', 'title' => '300万用户在使用***,他们在竞争中脱颖而出', 'description' => '一站式会务管理系统助力企业高效办会', 'usage' => '', ], [ 'id' => '1009', 'alias' => 'industry-carousels', 'name' => '行业资讯轮播图', 'title' => '新闻资讯轮播图', 'description' => '', 'usage' => '', ], [ 'id' => '1010', 'alias' => 'setting-tabs-mobile', 'name' => '“真”零代码灵活搭建,专属系统灵活配置(手机端)', 'title' => '', 'description' => '5分钟上手,1小时上线,个性化需求随时调整', 'usage' => '', ], [ 'id' => '1011', 'alias' => 'recommended-cases', 'name' => '领先企业都在用***', 'title' => '', 'description' => '无论是政务型会议、展会、学术会、经销商大会等等,都有您的同行已经加入我们', 'usage' => '首页的精彩案例', ], [ 'id' => '1012', 'alias' => 'industry-news', 'name' => '行业新闻资讯', 'title' => '', 'description' => '最新实时新闻,帮助主办及时了解行业动态', 'usage' => '首页的行业资讯', ], [ 'id' => '1013', 'alias' => 'links-recommended-for-you', 'name' => '猜你喜欢', 'title' => '', 'description' => '', 'usage' => '页面底部', ], [ 'id' => '1014', 'alias' => 'links-solutions', 'name' => ' 解决方案', 'title' => '', 'description' => '', 'usage' => '页面底部', ], [ 'id' => '1015', 'alias' => 'links-support', 'name' => '服务支持', 'title' => '', 'description' => '', 'usage' => '页面底部', ], [ 'id' => '1016', 'alias' => 'contact-image-1', 'name' => '微信公众号', 'title' => '', 'description' => '', 'usage' => '页面底部', ], [ 'id' => '1017', 'alias' => 'contact-image-2', 'name' => '客服微信', 'title' => '', 'description' => '', 'usage' => '页面底部', ], [ 'id' => '1018', 'alias' => 'links-resources', 'name' => '资源支持', 'title' => '', 'description' => '', 'usage' => '页面底部', ], [ 'id' => '1019', 'alias' => 'index-carousels', 'name' => '首页轮播图', 'title' => '首页轮播图', 'description' => '', 'usage' => '', ], [ 'id' => '1020', 'alias' => 'index-features', 'name' => '首页功能列表模块', 'title' => '', 'description' => '包括大会管理系统、活动管理系统、邀请函系统、信息查询系统、展会管理系统', 'usage' => '用于首页的多种功能满足您的日程所需', ], [ 'id' => '1021', 'alias' => 'index-convention-features', 'name' => '首页大会管理系统的功能列表模块', 'title' => '', 'description' => '适用于大型论坛、峰会、学术会议、政府大会、合作伙伴大会、经销商大会、产业大会、行业大会、发布会、招商会、培训会等会议场景。 支持自定义风格,功能模块丰富,注册即可使用!', 'usage' => '用于首页的大会管理系统', ], [ 'id' => '1022', 'alias' => 'convention-image-text', 'name' => '大会管理系统的详情页面的左图右文模块', 'title' => '', 'description' => '无限创建线上线下会议活动', 'usage' => '用于大会管理系统的详情页面', ], [ 'id' => '1023', 'alias' => 'feature-tabs', 'name' => '详情页-多种功能满足你日程所需', 'title' => '详情页-多种功能满足你日程所需', 'description' => '', 'usage' => '', ], [ 'id' => '1024', 'alias' => 'customers-with-logo', 'name' => '案例logo集合', 'title' => '服务千行百业,值得您信赖', 'description' => '', 'usage' => '', ], ]; foreach ($data as $row) { $slot = RecommendationSlot::find()->where(['alias' => $row['alias']])->limit(1)->one(); if (!$slot) { $slot = new RecommendationSlot(); $slot->created_at = $now; echo "➕ 新增:{$row['alias']}\n"; } else { echo "♻️ 更新:{$row['alias']}\n"; } $slot->id = $row['id']; $slot->alias = $row['alias']; $slot->name = $row['name']; $slot->title = $row['title']; $slot->description = $row['description']; $slot->usage = $row['usage']; $slot->status = RecommendationSlot::STATUS_ENABLED; $slot->updated_at = $now; if (!$slot->save()) { echo Console::error("❌ 保存失败:{$row['alias']}"); print_r($slot->getErrors()); } } echo Console::ansiFormat("✅ 初始化完成\n", [BaseConsole::FG_GREEN]); } }
实现了基于 alias 添加或者更新的逻辑,且 alias 与 id 固定了对应关系。
在代码中,硬编码获取推荐位数据时,基本上是基于 alias 获取。
现在存在一个问题,就是可能后台编辑推荐位时,允许 alias 为 null。那么在页面编辑器中,某一个页面元素数据源只能够关联上推荐位的 id,因为 alias 可能为 null 。
后台推荐位的 alias 可能会被修改,比如说 id = 1024 的 alias 为 customers-with-logo。后续可能 在后台需要将 id = 1024 的 alias 修改为 null,然后将 id = 1200 的 alias 修改为 customers-with-logo。此时需要在代码中,硬编码获取 alias 为 customers-with-logo 的数据。
现阶段感觉整体逻辑较为混乱,有无一个整体的清晰的逻辑结构可供参考?
2、最终初始化脚本调整如下
<?php namespace console\controllers; use common\models\IdMaker; use common\models\RecommendationSlot; use Yii; use yii\console\Controller; use yii\console\ExitCode; use yii\db\Exception; use yii\helpers\BaseConsole; use yii\helpers\Console; class RecommendationSlotController extends Controller { /** * 推荐位数据初始化 * @return void * @throws Exception */ public function actionInit() { $now = date('Y-m-d H:i:s'); $data = [ [ 'id' => '1001', 'alias' => 'sidebar-contact-1', 'name' => '获取专业会务管理解决方案', 'title' => '获取专业会务管理解决方案', 'description' => '', 'usage' => '', ], [ 'id' => '1002', 'alias' => 'sidebar-features', 'name' => '会务功能', 'title' => '会务功能', 'description' => '', 'usage' => '', ], [ 'id' => '1003', 'alias' => 'sidebar-products', 'name' => '产品服务', 'title' => '产品服务', 'description' => '', 'usage' => '', ], [ 'id' => '1004', 'alias' => 'sidebar-contact-2', 'name' => '我有需求立即联系', 'title' => '我有需求立即联系', 'description' => '', 'usage' => '', ], [ 'id' => '1006', 'alias' => 'setting-tabs', 'name' => '“真”零代码灵活搭建,专属系统灵活配置', 'title' => '“真”零代码灵活搭建,专属系统灵活配置', 'description' => '5分钟上手,1小时上线,个性化需求随时调整', 'usage' => '', ], [ 'id' => '1007', 'alias' => 'cases-with-image-and-content', 'name' => '300万用户在使用***,他们在竞争中脱颖而出', 'title' => '300万用户在使用***,他们在竞争中脱颖而出', 'description' => '一站式会务管理系统助力企业高效办会', 'usage' => '', ], [ 'id' => '1009', 'alias' => 'industry-carousels', 'name' => '行业资讯轮播图', 'title' => '新闻资讯轮播图', 'description' => '', 'usage' => '', ], [ 'id' => '1010', 'alias' => 'setting-tabs-mobile', 'name' => '“真”零代码灵活搭建,专属系统灵活配置(手机端)', 'title' => '', 'description' => '5分钟上手,1小时上线,个性化需求随时调整', 'usage' => '', ], [ 'id' => '1011', 'alias' => 'recommended-cases', 'name' => '领先企业都在用***', 'title' => '', 'description' => '无论是政务型会议、展会、学术会、经销商大会等等,都有您的同行已经加入我们', 'usage' => '首页的精彩案例', ], [ 'id' => '1012', 'alias' => 'industry-news', 'name' => '行业新闻资讯', 'title' => '', 'description' => '最新实时新闻,帮助主办及时了解行业动态', 'usage' => '首页的行业资讯', ], [ 'id' => '1013', 'alias' => 'links-recommended-for-you', 'name' => '猜你喜欢', 'title' => '', 'description' => '', 'usage' => '页面底部', ], [ 'id' => '1014', 'alias' => 'links-solutions', 'name' => ' 解决方案', 'title' => '', 'description' => '', 'usage' => '页面底部', ], [ 'id' => '1015', 'alias' => 'links-support', 'name' => '服务支持', 'title' => '', 'description' => '', 'usage' => '页面底部', ], [ 'id' => '1016', 'alias' => 'contact-image-1', 'name' => '微信公众号', 'title' => '', 'description' => '', 'usage' => '页面底部', ], [ 'id' => '1017', 'alias' => 'contact-image-2', 'name' => '客服微信', 'title' => '', 'description' => '', 'usage' => '页面底部', ], [ 'id' => '1018', 'alias' => 'links-resources', 'name' => '资源支持', 'title' => '', 'description' => '', 'usage' => '页面底部', ], [ 'id' => '1019', 'alias' => 'index-carousels', 'name' => '首页轮播图', 'title' => '首页轮播图', 'description' => '', 'usage' => '', ], [ 'id' => '1020', 'alias' => 'index-features', 'name' => '首页功能列表模块', 'title' => '', 'description' => '包括大会管理系统、活动管理系统、邀请函系统、信息查询系统、展会管理系统', 'usage' => '用于首页的多种功能满足您的日程所需', ], [ 'id' => '1021', 'alias' => 'index-convention-features', 'name' => '首页大会管理系统的功能列表模块', 'title' => '', 'description' => '适用于大型论坛、峰会、学术会议、政府大会、合作伙伴大会、经销商大会、产业大会、行业大会、发布会、招商会、培训会等会议场景。 支持自定义风格,功能模块丰富,注册即可使用!', 'usage' => '用于首页的大会管理系统', ], [ 'id' => '1022', 'alias' => 'convention-image-text', 'name' => '大会管理系统的详情页面的左图右文模块', 'title' => '', 'description' => '无限创建线上线下会议活动', 'usage' => '用于大会管理系统的详情页面', ], [ 'id' => '1023', 'alias' => 'feature-tabs', 'name' => '详情页-多种功能满足你日程所需', 'title' => '详情页-多种功能满足你日程所需', 'description' => '', 'usage' => '', ], [ 'id' => '1832069240769958', 'alias' => 'customers-with-logo', 'name' => '案例logo集合', 'title' => '服务千行百业,值得您信赖', 'description' => '', 'usage' => '', ], ]; foreach ($data as $row) { $existingSlot = RecommendationSlot::find()->where(['alias' => $row['alias']])->limit(1)->one(); $currentSlot = RecommendationSlot::find()->where(['id' => $row['id']])->limit(1)->one(); $now = date('Y-m-d H:i:s'); // 如果 alias 已存在,但不是当前 id,则需要迁移 if ($existingSlot && $existingSlot->id !== $row['id']) { echo "🔁 alias '{$row['alias']}' 已被 id = {$existingSlot->id} 使用,准备迁移...\n"; // 清空旧 slot 的 alias $existingSlot->alias = null; $existingSlot->updated_at = $now; if (!$existingSlot->save()) { echo Console::error("❌ 清空旧 alias 失败:{$existingSlot->id}\n"); print_r($existingSlot->getErrors()); } // 更新 recommendation_contents 中的 slot_id Yii::$app->db->createCommand()->update( 'recommendation_contents', ['slot_id' => $row['id']], ['slot_id' => $existingSlot->id] )->execute(); echo "✅ 已将 recommendation_contents.slot_id = {$existingSlot->id} 替换为 {$row['id']}\n"; } if (!$currentSlot) { $currentSlot = new RecommendationSlot(); $currentSlot->id = $row['id']; $currentSlot->created_at = $now; echo "➕ 新增:{$row['alias']} (id={$row['id']})\n"; } else { echo "♻️ 更新:{$row['alias']} (id={$row['id']})\n"; } $currentSlot->alias = $row['alias']; $currentSlot->name = $row['name']; $currentSlot->title = $row['title']; $currentSlot->description = $row['description']; $currentSlot->usage = $row['usage']; $currentSlot->status = RecommendationSlot::STATUS_ENABLED; $currentSlot->updated_at = $now; if (!$currentSlot->save()) { echo Console::error("❌ 保存失败:{$row['alias']} (id={$row['id']})\n"); print_r($currentSlot->getErrors()); } } echo Console::ansiFormat("✅ 初始化完成\n", [BaseConsole::FG_GREEN]); } }
近期评论