From 11f40a75e4d75ac98b5a9fef37340ef796cb3287 Mon Sep 17 00:00:00 2001 From: LQ Date: Fri, 14 Aug 2026 23:21:37 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=20=E7=BC=BA?= =?UTF-8?q?=E9=99=B7=EF=BC=9A=E4=B8=BB=E9=A2=98=E9=85=8D=E8=89=B2=E9=9C=80?= =?UTF-8?q?=E8=A6=81=E4=BC=98=E5=8C=96=E6=95=B4=E4=BD=93=E7=9A=84=E5=90=8C?= =?UTF-8?q?=E9=A3=8E=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .cursor/rules/Database-SQL.mdc | 27 ++++++++++ .../2026-08-14/01_cc_carousel_add_status.sql | 15 ++++++ .../sql/2026-08-14/02_nl_wx_app_create.sql | 36 +++++++++++++ .../03_cc_wx_user_template_code.sql | 15 ++++++ database/sql/2026-08-14/04_nl_menu_dealer.sql | 50 +++++++++++++++++++ .../2026-08-14/05_cc_category_add_sort.sql | 23 +++++++++ 6 files changed, 166 insertions(+) create mode 100644 .cursor/rules/Database-SQL.mdc create mode 100644 database/sql/2026-08-14/01_cc_carousel_add_status.sql create mode 100644 database/sql/2026-08-14/02_nl_wx_app_create.sql create mode 100644 database/sql/2026-08-14/03_cc_wx_user_template_code.sql create mode 100644 database/sql/2026-08-14/04_nl_menu_dealer.sql create mode 100644 database/sql/2026-08-14/05_cc_category_add_sort.sql diff --git a/.cursor/rules/Database-SQL.mdc b/.cursor/rules/Database-SQL.mdc new file mode 100644 index 00000000..797b0e19 --- /dev/null +++ b/.cursor/rules/Database-SQL.mdc @@ -0,0 +1,27 @@ +--- +description: 数据库变更一律走按日 SQL 目录,禁止新建 PHP Migration +alwaysApply: true +--- + +# 数据库变更约定(lgp-admin-plus-api) + +## 强制 + +- **禁止**为表结构变更新建 `database/migrations/*.php` +- **一律**落在: + +``` +database/sql//01_简短英文名.sql +database/sql//02_....sql +``` + +- 当天目录不存在则新建;序号从 `01` 递增 +- 脚本尽量幂等(查 `information_schema` + `PREPARE`) +- 系统表(`nl_*`)若影响全新安装:同步改 `public/nl_admin.sql` +- 业务表(`cc_*`):只写 `database/sql/`,**不进** `nl_admin.sql` +- 上线由运维在目标库手工执行对应日期目录下的 SQL + +## 反例 + +- `php artisan make:migration add_xxx_to_yyy` → 不要 +- 把 DDL 塞进 Seeder / 业务代码里临时跑 → 不要 diff --git a/database/sql/2026-08-14/01_cc_carousel_add_status.sql b/database/sql/2026-08-14/01_cc_carousel_add_status.sql new file mode 100644 index 00000000..511d10f3 --- /dev/null +++ b/database/sql/2026-08-14/01_cc_carousel_add_status.sql @@ -0,0 +1,15 @@ +-- ============================================================ +-- cc_carousel 补 status 列(幂等) +-- 新后台 CRUD / 启停开关依赖此列;老表从未有 status +-- ============================================================ + +SET @db := DATABASE(); +SET @exists := ( + SELECT COUNT(*) FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 'cc_carousel' AND COLUMN_NAME = 'status' +); +SET @sql := IF(@exists = 0, + 'ALTER TABLE `cc_carousel` ADD COLUMN `status` tinyint(1) NOT NULL DEFAULT 0 COMMENT ''状态 0显示 1隐藏'' AFTER `sort`', + 'SELECT ''skip cc_carousel.status'' AS msg' +); +PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; diff --git a/database/sql/2026-08-14/02_nl_wx_app_create.sql b/database/sql/2026-08-14/02_nl_wx_app_create.sql new file mode 100644 index 00000000..e5cedb64 --- /dev/null +++ b/database/sql/2026-08-14/02_nl_wx_app_create.sql @@ -0,0 +1,36 @@ +-- ============================================================ +-- nl_wx_app 小程序应用配置表(幂等) +-- 与 public/nl_admin.sql 末尾建表等价;已装库可单独执行本文件补表 +-- AppSecret 等敏感字段由后台加密入库,不要在本文件写明文密钥 +-- ============================================================ + +SET @db := DATABASE(); +SET @exists := ( + SELECT COUNT(*) FROM information_schema.TABLES + WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 'nl_wx_app' +); +SET @sql := IF(@exists = 0, + 'CREATE TABLE `nl_wx_app` ( + `id` int UNSIGNED NOT NULL AUTO_INCREMENT, + `code` varchar(20) NOT NULL DEFAULT '''' COMMENT ''品牌标识 brm/wl'', + `name` varchar(50) NOT NULL DEFAULT '''', + `app_id` varchar(50) NOT NULL DEFAULT '''', + `app_secret` varchar(255) NOT NULL DEFAULT '''' COMMENT ''密文存储'', + `mch_id` varchar(50) NOT NULL DEFAULT '''' COMMENT ''微信支付商户号'', + `mch_key` varchar(255) NOT NULL DEFAULT '''' COMMENT ''APIv3 密钥,密文存储'', + `mch_serial_no` varchar(100) NOT NULL DEFAULT '''' COMMENT ''商户证书序列号'', + `mch_private_key` text NULL COMMENT ''商户私钥,密文存储'', + `platform_public_key` text NULL COMMENT ''微信支付平台证书公钥'', + `notify_url` varchar(255) NOT NULL DEFAULT '''' COMMENT ''支付回调地址'', + `template_code` varchar(50) NOT NULL DEFAULT '''' COMMENT ''默认装修模板 code'', + `status` tinyint NOT NULL DEFAULT 0 COMMENT ''0=启用 1=停用'', + `remark` varchar(255) NOT NULL DEFAULT '''', + `created_at` int NOT NULL DEFAULT 0, + `updated_at` int NOT NULL DEFAULT 0, + `deleted_at` int NOT NULL DEFAULT 0, + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `uk_wx_app_code`(`code` ASC) USING BTREE + ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = ''小程序应用配置'' ROW_FORMAT = DYNAMIC', + 'SELECT ''skip nl_wx_app (already exists)'' AS msg' +); +PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; diff --git a/database/sql/2026-08-14/03_cc_wx_user_template_code.sql b/database/sql/2026-08-14/03_cc_wx_user_template_code.sql new file mode 100644 index 00000000..bb1e2893 --- /dev/null +++ b/database/sql/2026-08-14/03_cc_wx_user_template_code.sql @@ -0,0 +1,15 @@ +-- ============================================================ +-- cc_wx_user 补 template_code:经销商可绑定专属装修模板(幂等) +-- 空字符串 = 跟随品牌默认模板 +-- ============================================================ + +SET @db := DATABASE(); +SET @exists := ( + SELECT COUNT(*) FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 'cc_wx_user' AND COLUMN_NAME = 'template_code' +); +SET @sql := IF(@exists = 0, + 'ALTER TABLE `cc_wx_user` ADD COLUMN `template_code` varchar(50) NOT NULL DEFAULT '''' COMMENT ''经销商专属装修模板 code,空=跟随品牌默认'' AFTER `price_number`', + 'SELECT ''skip cc_wx_user.template_code'' AS msg' +); +PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; diff --git a/database/sql/2026-08-14/04_nl_menu_dealer.sql b/database/sql/2026-08-14/04_nl_menu_dealer.sql new file mode 100644 index 00000000..91ab2cd6 --- /dev/null +++ b/database/sql/2026-08-14/04_nl_menu_dealer.sql @@ -0,0 +1,50 @@ +-- ============================================================ +-- 菜单:客户中心下增加「经销商管理」(幂等) +-- component/path 对齐前端 views/customer/dealer +-- keep_alive:0=开启缓存;affix_tab:0=固定(输出到前端 meta 时取反) +-- 注意:nl_menu 无 type/status 列,勿照搬其它脚手架字段 +-- ============================================================ + +SET @db := DATABASE(); +SET @parent_id := ( + SELECT id FROM nl_menu WHERE name = 'Customer' AND deleted_at = 0 LIMIT 1 +); + +SET @exists := ( + SELECT COUNT(*) FROM nl_menu + WHERE name = 'CustomerDealer' AND deleted_at = 0 +); + +-- 插在「微信用户」后:sort=1;企业管理及之后在 menu-sync / 手工时再调序 +SET @sql := IF(@parent_id IS NOT NULL AND @exists = 0, + CONCAT( + 'INSERT INTO `nl_menu` (`title`,`icon`,`name`,`path`,`component`,`redirect`,`keep_alive`,`hide_in_menu`,`affix_tab`,`badge`,`badge_type`,`badge_variants`,`iframe_src`,`pid`,`sort`,`query`,`created_at`,`updated_at`,`deleted_at`) VALUES (', + '''经销商管理'', ''lucide:handshake'', ''CustomerDealer'', ''/customer/dealer'', ''/customer/dealer/index'', '''', 1, 0, 1, '''', 0, 0, '''', ', + @parent_id, + ', 1, '''', UNIX_TIMESTAMP(), UNIX_TIMESTAMP(), 0)' + ), + 'SELECT ''skip menu CustomerDealer'' AS msg' +); +PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; + +-- 与 lgp_menu 口径一致:企业/清单/订单 sort 后移(仅当经销商菜单刚存在时幂等更新) +UPDATE `nl_menu` SET `sort` = 2, `updated_at` = UNIX_TIMESTAMP() +WHERE `name` = 'CustomerEnterprise' AND `deleted_at` = 0 AND `sort` < 2; +UPDATE `nl_menu` SET `sort` = 3, `updated_at` = UNIX_TIMESTAMP() +WHERE `name` = 'CustomerList' AND `deleted_at` = 0 AND `sort` < 3; +UPDATE `nl_menu` SET `sort` = 4, `updated_at` = UNIX_TIMESTAMP() +WHERE `name` = 'CustomerOrder' AND `deleted_at` = 0 AND `sort` < 4; + +-- 凡已拥有「微信用户」菜单的角色,同步挂上「经销商管理」(幂等) +SET @menu_id := (SELECT id FROM nl_menu WHERE name = 'CustomerDealer' AND deleted_at = 0 LIMIT 1); +SET @wx_user_menu_id := (SELECT id FROM nl_menu WHERE name = 'CustomerWxUser' AND deleted_at = 0 LIMIT 1); +INSERT INTO `nl_role_menu_relations` (`role_id`, `menu_id`, `created_at`) +SELECT r.role_id, @menu_id, UNIX_TIMESTAMP() +FROM `nl_role_menu_relations` r +WHERE @menu_id IS NOT NULL + AND @wx_user_menu_id IS NOT NULL + AND r.menu_id = @wx_user_menu_id + AND NOT EXISTS ( + SELECT 1 FROM `nl_role_menu_relations` x + WHERE x.role_id = r.role_id AND x.menu_id = @menu_id + ); diff --git a/database/sql/2026-08-14/05_cc_category_add_sort.sql b/database/sql/2026-08-14/05_cc_category_add_sort.sql new file mode 100644 index 00000000..b1686a99 --- /dev/null +++ b/database/sql/2026-08-14/05_cc_category_add_sort.sql @@ -0,0 +1,23 @@ +-- ============================================================ +-- cc_category 补 sort:分类排序(幂等) +-- 数字越小越靠前;首次加列后若全为 0,用 id 回填保持原顺序 +-- ============================================================ + +SET @db := DATABASE(); +SET @exists := ( + SELECT COUNT(*) FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 'cc_category' AND COLUMN_NAME = 'sort' +); +SET @sql := IF(@exists = 0, + 'ALTER TABLE `cc_category` ADD COLUMN `sort` int NOT NULL DEFAULT 0 COMMENT ''排序,数字越小越靠前'' AFTER `pid`', + 'SELECT ''skip cc_category.sort'' AS msg' +); +PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; + +-- 仅当尚无任何非 0 排序值时回填(避免重复执行覆盖手工排序) +SET @has_custom := (SELECT COUNT(*) FROM `cc_category` WHERE `sort` <> 0); +SET @sql2 := IF(@has_custom = 0, + 'UPDATE `cc_category` SET `sort` = `id`', + 'SELECT ''skip cc_category.sort backfill'' AS msg' +); +PREPARE stmt2 FROM @sql2; EXECUTE stmt2; DEALLOCATE PREPARE stmt2;