From 1e4761840672132e474c34f4ed75c7a85e4fea9c Mon Sep 17 00:00:00 2001 From: hongawen <83944980@qq.com> Date: Fri, 27 Mar 2026 16:18:21 +0800 Subject: [PATCH] =?UTF-8?q?feat(system):=20=E8=B0=83=E6=95=B4Git=E8=A7=84?= =?UTF-8?q?=E8=8C=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- githooks/commit-msg | 40 ++++++ .../01_permission_v2_stage1_schema.sql | 127 +++++++++++++++++ .../02_permission_v2_stage1_org_backfill.sql | 44 ++++++ .../03_permission_v2_stage1_seed.sql | 69 ++++++++++ .../04_permission_v2_stage1_finalize.sql | 29 ++++ .../sql/permission-v2/system_dept.sql | 5 + scripts/commit.ps1 | 92 +++++++++++++ scripts/commit.sh | 130 ++++++++++++++++++ scripts/install-git-hooks.ps1 | 9 ++ scripts/install-git-hooks.sh | 11 ++ 10 files changed, 556 insertions(+) create mode 100644 githooks/commit-msg create mode 100644 rdms-system/rdms-system-boot/src/main/resources/sql/permission-v2/01_permission_v2_stage1_schema.sql create mode 100644 rdms-system/rdms-system-boot/src/main/resources/sql/permission-v2/02_permission_v2_stage1_org_backfill.sql create mode 100644 rdms-system/rdms-system-boot/src/main/resources/sql/permission-v2/03_permission_v2_stage1_seed.sql create mode 100644 rdms-system/rdms-system-boot/src/main/resources/sql/permission-v2/04_permission_v2_stage1_finalize.sql create mode 100644 scripts/commit.ps1 create mode 100644 scripts/commit.sh create mode 100644 scripts/install-git-hooks.ps1 create mode 100644 scripts/install-git-hooks.sh diff --git a/githooks/commit-msg b/githooks/commit-msg new file mode 100644 index 0000000..075ebc3 --- /dev/null +++ b/githooks/commit-msg @@ -0,0 +1,40 @@ +#!/bin/sh + +set -eu + +MSG_FILE="$1" +FIRST_LINE="$(sed -n '1p' "$MSG_FILE" | tr -d '\r')" + +# Allow Git-generated merge commits and revert commits to pass through. +case "$FIRST_LINE" in + Merge\ *|Revert\ \"*) + exit 0 + ;; +esac + +PATTERN='^(feat|feat-wip|fix|docs|typo|style|refactor|perf|optimize|test|build|ci|chore|revert)\([a-z][a-z0-9-]*\): .+$' + +if printf '%s\n' "$FIRST_LINE" | grep -Eq "$PATTERN"; then + exit 0 +fi + +cat <<'EOF' >&2 +ERROR: commit message must follow Conventional Commits. + +Required format: + type(scope): 描述 + +Examples: + fix(system): 修复组织树查询空指针问题 + refactor(framework): 拆分权限上下文装配逻辑 + docs(other): 补充后端提交规范说明 + +Allowed types: + feat, feat-wip, fix, docs, typo, style, refactor, perf, + optimize, test, build, ci, chore, revert + +Tip: + 优先使用贴近模块的 scope,例如 system、gateway、framework、security、sql、deps、other。 +EOF + +exit 1 diff --git a/rdms-system/rdms-system-boot/src/main/resources/sql/permission-v2/01_permission_v2_stage1_schema.sql b/rdms-system/rdms-system-boot/src/main/resources/sql/permission-v2/01_permission_v2_stage1_schema.sql new file mode 100644 index 0000000..f17961e --- /dev/null +++ b/rdms-system/rdms-system-boot/src/main/resources/sql/permission-v2/01_permission_v2_stage1_schema.sql @@ -0,0 +1,127 @@ +-- permission-v2 stage 1 schema for MySQL 8.0 +-- execution target: existing rdms system schema +-- execution mode: manual +-- +-- purpose: +-- 1. add target-model columns +-- 2. create visibility relation tables +-- 3. keep legacy fields temporarily for subsequent code migration +-- +-- note: +-- 1. run this script before stage 2/3 code changes +-- 2. do not drop leader_user_id / post_ids / data_scope in this stage + +START TRANSACTION; + +ALTER TABLE system_dept + ADD COLUMN org_type VARCHAR(20) NOT NULL DEFAULT 'dept' COMMENT '组织节点类型:company/dept/direction/team' AFTER parent_id, + ADD COLUMN path VARCHAR(1024) CHARACTER SET ascii NOT NULL DEFAULT '/' COMMENT '组织物化路径,格式如 /1/2/3/' AFTER org_type, + ADD COLUMN level INT NOT NULL DEFAULT 1 COMMENT '组织层级,根节点为 1' AFTER path, + ADD COLUMN code VARCHAR(64) NULL COMMENT '组织编码' AFTER level; + +ALTER TABLE system_users + ADD COLUMN position_id BIGINT NULL COMMENT '主岗位ID' AFTER dept_id, + ADD COLUMN resigned_at DATETIME NULL COMMENT '离职时间' AFTER position_id; + +ALTER TABLE system_post + ADD COLUMN post_type VARCHAR(20) NULL COMMENT '岗位类型:management/technical/business' AFTER code, + ADD COLUMN level_rank INT NULL COMMENT '岗位等级排序,越大级别越高' AFTER post_type; + +ALTER TABLE system_dept + ADD KEY idx_system_dept_parent_id (parent_id), + ADD KEY idx_system_dept_org_type (org_type), + ADD KEY idx_system_dept_path (path(191)), + ADD UNIQUE KEY uk_system_dept_code (code); + +ALTER TABLE system_users + ADD KEY idx_system_users_dept_id (dept_id), + ADD KEY idx_system_users_position_id (position_id); + +ALTER TABLE system_post + ADD KEY idx_system_post_type (post_type), + ADD KEY idx_system_post_level_rank (level_rank); + +CREATE TABLE system_org_leader_relation ( + id BIGINT NOT NULL COMMENT '主键ID', + dept_id BIGINT NOT NULL COMMENT '组织节点ID', + user_id BIGINT NOT NULL COMMENT '负责人用户ID', + effective_from DATETIME NULL COMMENT '生效开始时间,空表示立即长期生效', + effective_until DATETIME NULL COMMENT '生效结束时间,空表示长期有效', + remark VARCHAR(500) NULL COMMENT '备注', + creator VARCHAR(64) NULL DEFAULT '' COMMENT '创建者', + create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + updater VARCHAR(64) NULL DEFAULT '' COMMENT '更新者', + update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + deleted BIT(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + PRIMARY KEY (id), + KEY idx_org_leader_user (user_id, deleted, effective_from, effective_until), + KEY idx_org_leader_dept (dept_id, deleted, effective_from, effective_until), + UNIQUE KEY uk_org_leader_once (dept_id, user_id, effective_from) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='组织负责人关系表'; + +CREATE TABLE system_user_management_relation ( + id BIGINT NOT NULL COMMENT '主键ID', + manager_user_id BIGINT NOT NULL COMMENT '管理者用户ID', + subordinate_user_id BIGINT NOT NULL COMMENT '被管理用户ID', + effective_from DATETIME NULL COMMENT '生效开始时间,空表示立即长期生效', + effective_until DATETIME NULL COMMENT '生效结束时间,空表示长期有效', + remark VARCHAR(500) NULL COMMENT '备注', + creator VARCHAR(64) NULL DEFAULT '' COMMENT '创建者', + create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + updater VARCHAR(64) NULL DEFAULT '' COMMENT '更新者', + update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + deleted BIT(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + PRIMARY KEY (id), + KEY idx_mgr_user (manager_user_id, deleted, effective_from, effective_until), + KEY idx_sub_user (subordinate_user_id, deleted, effective_from, effective_until), + UNIQUE KEY uk_mgr_sub_once (manager_user_id, subordinate_user_id, effective_from) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户直接管理关系表'; + +CREATE TABLE system_user_visibility_config ( + id BIGINT NOT NULL COMMENT '主键ID', + user_id BIGINT NOT NULL COMMENT '用户ID', + visibility_type VARCHAR(20) NOT NULL COMMENT '可见范围类型:all/directions/projects', + visible_direction_ids JSON NULL COMMENT '补充可见方向ID集合', + visible_project_ids JSON NULL COMMENT '补充可见项目ID集合', + remark VARCHAR(500) NULL COMMENT '备注', + creator VARCHAR(64) NULL DEFAULT '' COMMENT '创建者', + create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + updater VARCHAR(64) NULL DEFAULT '' COMMENT '更新者', + update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + deleted BIT(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + PRIMARY KEY (id), + UNIQUE KEY uk_visibility_user (user_id), + KEY idx_visibility_type (visibility_type), + CONSTRAINT chk_visibility_type CHECK (visibility_type IN ('all', 'directions', 'projects')) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户补充可见范围配置表'; + +CREATE TABLE system_project_member ( + id BIGINT NOT NULL COMMENT '主键ID', + project_id BIGINT NOT NULL COMMENT '项目ID', + user_id BIGINT NOT NULL COMMENT '用户ID', + project_role VARCHAR(20) NOT NULL COMMENT '项目角色:pm/product/developer/tester/viewer', + member_type VARCHAR(20) NOT NULL DEFAULT 'core' COMMENT '成员类型:core/support', + joined_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '加入时间', + left_at DATETIME NULL COMMENT '退出时间,空表示仍在项目中', + remark VARCHAR(500) NULL COMMENT '备注', + creator VARCHAR(64) NULL DEFAULT '' COMMENT '创建者', + create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + updater VARCHAR(64) NULL DEFAULT '' COMMENT '更新者', + update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + deleted BIT(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + active_user_id BIGINT GENERATED ALWAYS AS ( + CASE WHEN left_at IS NULL THEN user_id ELSE NULL END + ) STORED, + active_pm_project_id BIGINT GENERATED ALWAYS AS ( + CASE WHEN project_role = 'pm' AND left_at IS NULL THEN project_id ELSE NULL END + ) STORED, + PRIMARY KEY (id), + UNIQUE KEY uk_project_active_member (project_id, active_user_id), + UNIQUE KEY uk_project_active_pm (active_pm_project_id), + KEY idx_pm_user_active (user_id, left_at), + KEY idx_pm_project_role_active (project_id, project_role, left_at), + CONSTRAINT chk_project_role CHECK (project_role IN ('pm', 'product', 'developer', 'tester', 'viewer')), + CONSTRAINT chk_member_type CHECK (member_type IN ('core', 'support')) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='项目成员关系表'; + +COMMIT; diff --git a/rdms-system/rdms-system-boot/src/main/resources/sql/permission-v2/02_permission_v2_stage1_org_backfill.sql b/rdms-system/rdms-system-boot/src/main/resources/sql/permission-v2/02_permission_v2_stage1_org_backfill.sql new file mode 100644 index 0000000..bf204f4 --- /dev/null +++ b/rdms-system/rdms-system-boot/src/main/resources/sql/permission-v2/02_permission_v2_stage1_org_backfill.sql @@ -0,0 +1,44 @@ +-- permission-v2 stage 1 organization backfill for MySQL 8.0 +-- purpose: +-- 1. initialize org_type +-- 2. backfill path and level from parent_id +-- +-- assumption: +-- 1. root organization nodes satisfy parent_id = 0 +-- 2. system_dept currently has no parent cycle + +START TRANSACTION; + +UPDATE system_dept +SET org_type = 'dept' +WHERE org_type IS NULL OR org_type = ''; + +WITH RECURSIVE dept_tree AS ( + SELECT + id, + parent_id, + CAST(CONCAT('/', id, '/') AS CHAR(1024)) AS new_path, + 1 AS new_level + FROM system_dept + WHERE parent_id = 0 + + UNION ALL + + SELECT + child.id, + child.parent_id, + CAST(CONCAT(parent.new_path, child.id, '/') AS CHAR(1024)) AS new_path, + parent.new_level + 1 AS new_level + FROM system_dept child + INNER JOIN dept_tree parent ON child.parent_id = parent.id +) +UPDATE system_dept d +INNER JOIN dept_tree t ON d.id = t.id +SET + d.path = t.new_path, + d.level = t.new_level; + +COMMIT; + +-- verification: +-- SELECT id, name, parent_id, org_type, path, level FROM system_dept ORDER BY parent_id, sort, id; diff --git a/rdms-system/rdms-system-boot/src/main/resources/sql/permission-v2/03_permission_v2_stage1_seed.sql b/rdms-system/rdms-system-boot/src/main/resources/sql/permission-v2/03_permission_v2_stage1_seed.sql new file mode 100644 index 0000000..39969ad --- /dev/null +++ b/rdms-system/rdms-system-boot/src/main/resources/sql/permission-v2/03_permission_v2_stage1_seed.sql @@ -0,0 +1,69 @@ +-- permission-v2 stage 1 seed for MySQL 8.0 +-- purpose: +-- 1. ensure there is at least one root organization node for user association +-- 2. ensure there is at least one available post for user association +-- 3. bind admin user to an organization and a primary position +-- +-- note: +-- 1. the reserved ids below are only for cold-start initialization +-- 2. adjust them before execution if your database already uses the same ids + +START TRANSACTION; + +INSERT INTO system_dept ( + id, name, parent_id, sort, org_type, path, level, code, phone, email, status, + creator, create_time, updater, update_time, deleted +) +SELECT + 900000000000000001, '平台根组织', 0, 0, 'company', '/900000000000000001/', 1, 'ROOT', + NULL, NULL, 0, + 'system', NOW(), 'system', NOW(), b'0' +FROM DUAL +WHERE NOT EXISTS ( + SELECT 1 FROM system_dept WHERE parent_id = 0 AND deleted = b'0' +); + +INSERT INTO system_post ( + id, name, code, post_type, level_rank, sort, status, remark, + creator, create_time, updater, update_time, deleted +) +SELECT + 900000000000000101, '系统管理员岗', 'SYS_ADMIN_POST', 'management', 100, 0, 0, 'permission-v2 cold-start seed', + 'system', NOW(), 'system', NOW(), b'0' +FROM DUAL +WHERE NOT EXISTS ( + SELECT 1 FROM system_post WHERE deleted = b'0' +); + +UPDATE system_users +SET + dept_id = COALESCE( + dept_id, + (SELECT root_dept.id + FROM ( + SELECT id + FROM system_dept + WHERE parent_id = 0 AND deleted = b'0' + ORDER BY sort ASC, id ASC + LIMIT 1 + ) root_dept) + ), + position_id = COALESCE( + position_id, + (SELECT chosen_post.id + FROM ( + SELECT id + FROM system_post + WHERE deleted = b'0' + ORDER BY sort ASC, id ASC + LIMIT 1 + ) chosen_post) + ), + update_time = NOW(), + updater = 'system' +WHERE username = 'admin'; + +COMMIT; + +-- verification: +-- SELECT id, username, dept_id, position_id FROM system_users WHERE username = 'admin'; diff --git a/rdms-system/rdms-system-boot/src/main/resources/sql/permission-v2/04_permission_v2_stage1_finalize.sql b/rdms-system/rdms-system-boot/src/main/resources/sql/permission-v2/04_permission_v2_stage1_finalize.sql new file mode 100644 index 0000000..4c5a4ba --- /dev/null +++ b/rdms-system/rdms-system-boot/src/main/resources/sql/permission-v2/04_permission_v2_stage1_finalize.sql @@ -0,0 +1,29 @@ +-- permission-v2 stage 1 finalize for MySQL 8.0 +-- purpose: +-- 1. verify required user-position data is complete +-- 2. convert system_users.position_id to NOT NULL +-- +-- execute this script only after: +-- 1. 01/02/03 have completed successfully +-- 2. every existing user has a valid position_id + +SELECT COUNT(*) AS missing_position_count +FROM system_users +WHERE position_id IS NULL; + +SET @missing_position_count := ( + SELECT COUNT(*) FROM system_users WHERE position_id IS NULL +); + +SET @finalize_sql := IF( + @missing_position_count = 0, + 'ALTER TABLE system_users MODIFY COLUMN position_id BIGINT NOT NULL COMMENT ''主岗位ID''', + 'SELECT ''skip finalize: system_users.position_id still has NULL rows'' AS message' +); + +PREPARE stmt FROM @finalize_sql; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; + +-- verification: +-- SHOW CREATE TABLE system_users; diff --git a/rdms-system/rdms-system-boot/src/main/resources/sql/permission-v2/system_dept.sql b/rdms-system/rdms-system-boot/src/main/resources/sql/permission-v2/system_dept.sql index 4684409..bcdf45a 100644 --- a/rdms-system/rdms-system-boot/src/main/resources/sql/permission-v2/system_dept.sql +++ b/rdms-system/rdms-system-boot/src/main/resources/sql/permission-v2/system_dept.sql @@ -702,4 +702,9 @@ SET `component` = 'view.iframe-page', `route_props_json` = '{\"url\":\"https://cn.vuejs.org/\"}' WHERE `id` = 900016; +INSERT INTO `system_menu` VALUES (1036, '组织负责人查询', 'system:org-leader:query', 3, 5, 103, '', '#', '', NULL, 0, b'1', b'1', b'1', 'admin', '2026-03-25 00:00:00', 'admin', '2026-03-25 00:00:00', b'0'); +INSERT INTO `system_menu` VALUES (1037, '组织负责人新增', 'system:org-leader:create', 3, 6, 103, '', '#', '', NULL, 0, b'1', b'1', b'1', 'admin', '2026-03-25 00:00:00', 'admin', '2026-03-25 00:00:00', b'0'); +INSERT INTO `system_menu` VALUES (1038, '组织负责人修改', 'system:org-leader:update', 3, 7, 103, '', '#', '', NULL, 0, b'1', b'1', b'1', 'admin', '2026-03-25 00:00:00', 'admin', '2026-03-25 00:00:00', b'0'); +INSERT INTO `system_menu` VALUES (1039, '组织负责人删除', 'system:org-leader:delete', 3, 8, 103, '', '#', '', NULL, 0, b'1', b'1', b'1', 'admin', '2026-03-25 00:00:00', 'admin', '2026-03-25 00:00:00', b'0'); + SET FOREIGN_KEY_CHECKS = 1; diff --git a/scripts/commit.ps1 b/scripts/commit.ps1 new file mode 100644 index 0000000..5ff94c6 --- /dev/null +++ b/scripts/commit.ps1 @@ -0,0 +1,92 @@ +$ErrorActionPreference = 'Stop' + +function Select-Option { + param( + [string]$Title, + [string[]]$Options + ) + + while ($true) { + Write-Host "" + Write-Host $Title + for ($i = 0; $i -lt $Options.Length; $i++) { + Write-Host ("{0}. {1}" -f ($i + 1), $Options[$i]) + } + + $inputValue = Read-Host "请输入序号" + $index = 0 + if ([int]::TryParse($inputValue, [ref]$index) -and $index -ge 1 -and $index -le $Options.Length) { + return $Options[$index - 1] + } + + Write-Host "输入无效,请重新选择。" + } +} + +$repoRoot = Resolve-Path (Join-Path $PSScriptRoot '..') + +if (-not (git -C $repoRoot rev-parse --is-inside-work-tree 2>$null)) { + throw "当前目录不是 Git 仓库。" +} + +git -C $repoRoot diff --cached --quiet +if ($LASTEXITCODE -eq 0) { + throw "当前没有已暂存的改动,请先执行 git add。" +} + +$types = @( + 'feat', + 'feat-wip', + 'fix', + 'docs', + 'typo', + 'style', + 'refactor', + 'perf', + 'optimize', + 'test', + 'build', + 'ci', + 'chore', + 'revert' +) + +$scopes = @( + 'system', + 'gateway', + 'framework', + 'common', + 'security', + 'web', + 'mybatis', + 'redis', + 'mq', + 'rpc', + 'sql', + 'deps', + 'other' +) + +$type = Select-Option -Title '请选择提交类型 type' -Options $types +$scope = Select-Option -Title '请选择提交范围 scope' -Options $scopes + +while ($true) { + $description = (Read-Host '请输入提交描述').Trim() + if ($description) { + break + } + Write-Host "描述不能为空,请重新输入。" +} + +$message = "{0}({1}): {2}" -f $type, $scope, $description + +Write-Host "" +Write-Host "提交信息预览:$message" + +$confirm = Read-Host '确认提交请输入 y,取消请输入其他任意内容' +if ($confirm -ne 'y' -and $confirm -ne 'Y') { + Write-Host '已取消提交。' + exit 1 +} + +git -C $repoRoot commit -m $message diff --git a/scripts/commit.sh b/scripts/commit.sh new file mode 100644 index 0000000..d324151 --- /dev/null +++ b/scripts/commit.sh @@ -0,0 +1,130 @@ +#!/bin/sh + +set -eu + +SCRIPT_DIR="$(CDPATH= cd -- "$(dirname "$0")" && pwd)" +REPO_ROOT="$(CDPATH= cd -- "$SCRIPT_DIR/.." && pwd)" + +if ! git -C "$REPO_ROOT" rev-parse --is-inside-work-tree >/dev/null 2>&1; then + printf '%s\n' "当前目录不是 Git 仓库。" >&2 + exit 1 +fi + +if git -C "$REPO_ROOT" diff --cached --quiet; then + printf '%s\n' "当前没有已暂存的改动,请先执行 git add。" >&2 + exit 1 +fi + +choose_type() { + printf '%s\n' "" + printf '%s\n' "请选择提交类型 type" + printf '%s\n' "1. feat" + printf '%s\n' "2. feat-wip" + printf '%s\n' "3. fix" + printf '%s\n' "4. docs" + printf '%s\n' "5. typo" + printf '%s\n' "6. style" + printf '%s\n' "7. refactor" + printf '%s\n' "8. perf" + printf '%s\n' "9. optimize" + printf '%s\n' "10. test" + printf '%s\n' "11. build" + printf '%s\n' "12. ci" + printf '%s\n' "13. chore" + printf '%s\n' "14. revert" + printf '%s' "请输入序号: " + read -r answer + + case "$answer" in + 1) printf '%s' "feat" ;; + 2) printf '%s' "feat-wip" ;; + 3) printf '%s' "fix" ;; + 4) printf '%s' "docs" ;; + 5) printf '%s' "typo" ;; + 6) printf '%s' "style" ;; + 7) printf '%s' "refactor" ;; + 8) printf '%s' "perf" ;; + 9) printf '%s' "optimize" ;; + 10) printf '%s' "test" ;; + 11) printf '%s' "build" ;; + 12) printf '%s' "ci" ;; + 13) printf '%s' "chore" ;; + 14) printf '%s' "revert" ;; + *) return 1 ;; + esac +} + +choose_scope() { + printf '%s\n' "" + printf '%s\n' "请选择提交范围 scope" + printf '%s\n' "1. system" + printf '%s\n' "2. gateway" + printf '%s\n' "3. framework" + printf '%s\n' "4. common" + printf '%s\n' "5. security" + printf '%s\n' "6. web" + printf '%s\n' "7. mybatis" + printf '%s\n' "8. redis" + printf '%s\n' "9. mq" + printf '%s\n' "10. rpc" + printf '%s\n' "11. sql" + printf '%s\n' "12. deps" + printf '%s\n' "13. other" + printf '%s' "请输入序号: " + read -r answer + + case "$answer" in + 1) printf '%s' "system" ;; + 2) printf '%s' "gateway" ;; + 3) printf '%s' "framework" ;; + 4) printf '%s' "common" ;; + 5) printf '%s' "security" ;; + 6) printf '%s' "web" ;; + 7) printf '%s' "mybatis" ;; + 8) printf '%s' "redis" ;; + 9) printf '%s' "mq" ;; + 10) printf '%s' "rpc" ;; + 11) printf '%s' "sql" ;; + 12) printf '%s' "deps" ;; + 13) printf '%s' "other" ;; + *) return 1 ;; + esac +} + +while :; do + if type_value="$(choose_type)"; then + break + fi + printf '%s\n' "输入无效,请重新选择。" +done + +while :; do + if scope_value="$(choose_scope)"; then + break + fi + printf '%s\n' "输入无效,请重新选择。" +done + +while :; do + printf '%s' "请输入提交描述: " + read -r description + description="$(printf '%s' "$description" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')" + if [ -n "$description" ]; then + break + fi + printf '%s\n' "描述不能为空,请重新输入。" +done + +message="$type_value($scope_value): $description" + +printf '%s\n' "" +printf '%s\n' "提交信息预览:$message" +printf '%s' "确认提交请输入 y,取消请输入其他任意内容: " +read -r confirm + +if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then + printf '%s\n' "已取消提交。" + exit 1 +fi + +git -C "$REPO_ROOT" commit -m "$message" diff --git a/scripts/install-git-hooks.ps1 b/scripts/install-git-hooks.ps1 new file mode 100644 index 0000000..353611d --- /dev/null +++ b/scripts/install-git-hooks.ps1 @@ -0,0 +1,9 @@ +$ErrorActionPreference = 'Stop' + +$repoRoot = Resolve-Path (Join-Path $PSScriptRoot '..') +$hooksPath = Join-Path $repoRoot 'githooks' + +git -C $repoRoot config core.hooksPath $hooksPath + +Write-Host "Git hooks installed." +Write-Host "core.hooksPath=$hooksPath" diff --git a/scripts/install-git-hooks.sh b/scripts/install-git-hooks.sh new file mode 100644 index 0000000..313e60c --- /dev/null +++ b/scripts/install-git-hooks.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +set -eu + +SCRIPT_DIR="$(CDPATH= cd -- "$(dirname "$0")" && pwd)" +REPO_ROOT="$(CDPATH= cd -- "$SCRIPT_DIR/.." && pwd)" + +git -C "$REPO_ROOT" config core.hooksPath "$REPO_ROOT/githooks" + +printf '%s\n' "Git hooks installed." +printf '%s\n' "core.hooksPath=$REPO_ROOT/githooks"