我把 20 个页面的权限控制从"硬编码"改成"配置驱动",AI 帮我生成了 80% 的迁移代码

项目里 20+ 个页面有按钮级权限控制,每个都是 if (hasPermission('xxx')) 硬编码在 JSX 里。新增一个按钮要改代码,调整权限要发版。

我让 AI 帮我设计了一个配置驱动的权限方案,把权限逻辑从组件中抽离。然后让 AI 批量生成迁移代码------20 个页面,半天搞定。

改造前的痛点

typescript 复制代码
// 到处都是这种代码
const StoreList = () => {
  const { hasPermission } = useAuth()
  
  return (
    <div>
      {hasPermission('store:create') && <Button>新增门店</Button>}
      {hasPermission('store:edit') && <Button>编辑</Button>}
      {hasPermission('store:delete') && <Button>删除</Button>}
      {hasPermission('store:export') && <Button>导出</Button>}
      {(hasPermission('store:online') || hasPermission('store:admin')) && (
        <Button>上线</Button>
      )}
    </div>
  )
}

问题:

vbnet 复制代码
├── 权限 key 散落在 20+ 个文件里,没人知道一共有多少
├── 运营说"给角色 A 加个按钮权限" → 要改代码发版
├── 同一个权限 key 有人写 'store:create',有人写 'store_create'
├── 无法一眼看出某个角色能看到哪些按钮
└── 新人不知道该用哪个权限 key(没有统一的权限清单)

AI 设计的配置驱动方案

typescript 复制代码
// permissions/store.ts --- 集中配置
export const storePermissions = {
  page: 'store:view',
  actions: {
    create: {
      key: 'store:create',
      label: '新增门店',
    },
    edit: {
      key: 'store:edit',
      label: '编辑',
    },
    delete: {
      key: 'store:delete',
      label: '删除',
      danger: true,  // 危险操作标记
    },
    export: {
      key: 'store:export',
      label: '导出',
    },
    online: {
      key: ['store:online', 'store:admin'],  // 多权限 OR 关系
      label: '上线',
    },
  },
}
typescript 复制代码
// hooks/usePagePermissions.ts --- 通用 Hook
const usePagePermissions = (config: PermissionConfig) => {
  const { hasPermission } = useAuth()

  const actions = useMemo(() => {
    return Object.entries(config.actions).reduce((acc, [name, action]) => {
      const keys = Array.isArray(action.key) ? action.key : [action.key]
      acc[name] = {
        ...action,
        visible: keys.some(k => hasPermission(k)),
      }
      return acc
    }, {} as Record<string, ActionPermission>)
  }, [config, hasPermission])

  return { actions, pageVisible: hasPermission(config.page) }
}
typescript 复制代码
// 组件中使用 --- 干净很多
const StoreList = () => {
  const { actions } = usePagePermissions(storePermissions)

  return (
    <div>
      {actions.create.visible && <Button>{actions.create.label}</Button>}
      {actions.edit.visible && <Button>{actions.edit.label}</Button>}
      {actions.delete.visible && <Button danger>{actions.delete.label}</Button>}
      {actions.export.visible && <Button>{actions.export.label}</Button>}
      {actions.online.visible && <Button>{actions.online.label}</Button>}
    </div>
  )
}

进阶:AuthButton 组件

更进一步,封装一个权限按钮:

typescript 复制代码
// components/AuthButton.tsx
const AuthButton = ({ actionConfig, ...buttonProps }: AuthButtonProps) => {
  if (!actionConfig.visible) return null
  return (
    <Button danger={actionConfig.danger} {...buttonProps}>
      {actionConfig.label}
    </Button>
  )
}

// 使用时
<AuthButton actionConfig={actions.create} onClick={handleCreate} />
<AuthButton actionConfig={actions.delete} onClick={handleDelete} />

AI 批量迁移的过程

我给 AI 的 Prompt:

markdown 复制代码
这是我的权限配置方案(附上面的代码)。

现在请帮我迁移以下页面:
1. 读取 src/view/selfCatering/storeSetup/index.tsx
2. 找出所有 hasPermission 调用
3. 生成对应的 permissions 配置文件
4. 改写组件使用新方案

保持组件的其他逻辑不变,只替换权限相关代码。

AI 的工作流:

vbnet 复制代码
Step 1: 扫描文件,提取所有 hasPermission('xxx') 调用
         → 找到 5 个权限 key

Step 2: 生成 permissions/selfCatering/storeSetup.ts
         → 结构化的权限配置

Step 3: 在组件中替换
         → 引入 usePagePermissions
         → 用 actions.xxx.visible 替换 hasPermission('xxx')
         → 删除 useAuth 导入(如果不再需要)

Step 4: 验证
         → 确保 import 路径正确
         → 确保没有遗漏的 hasPermission

20 个页面,每个页面 AI 处理 2-3 分钟,总共半天完成。

迁移后的收益

vbnet 复制代码
改造前                              改造后
──────                              ──────
权限散落 20+ 文件                   集中在 permissions/ 目录
无法枚举所有权限                    一目了然
改权限要发版                        理论上可以做成后台配置
新人不知道用啥 key                  看配置文件就行
权限 key 拼写不一致                 TypeScript 类型约束

全局权限清单(自动生成)

配置集中后,可以自动生成权限清单:

typescript 复制代码
// scripts/generatePermissionList.ts
import * as configs from '@/permissions'

const allPermissions = Object.entries(configs).flatMap(([module, config]) =>
  Object.values(config.actions).map(action => ({
    module,
    key: action.key,
    label: action.label,
  }))
)

// 输出:
// [
//   { module: 'store', key: 'store:create', label: '新增门店' },
//   { module: 'store', key: 'store:edit', label: '编辑' },
//   ...
// ]

这个清单可以给后端做权限管理界面的数据源。

AI 在这类"批量迁移"中的价值

matlab 复制代码
人工做:
├── 理解新方案:30min
├── 每个页面迁移:20min × 20 = 400min
├── 检查遗漏:60min
├── 总计:约 8h(1 整天)

AI 辅助:
├── 设计方案(AI + 人):1h
├── 每个页面迁移(AI 执行、人审查):5min × 20 = 100min
├── 修正 AI 的少量错误:30min
├── 总计:约 3.5h(半天)

节省:~55% 时间

核心原因:这类迁移是模式固定、重复度高的工作,正好是 AI 擅长的。


💬 你们项目的权限控制是什么方案?有没有遇到"权限散落各处"的问题?


🔗 完整 Skills 源码已开源github.com/sleepyccat/...,欢迎 Star ⭐ 和 PR。

相关推荐
是立不是利44 分钟前
第二篇:CSS 与用户体验——看不见的设计
前端·css·ux
志尊宝1 小时前
Vue3 零基础每日笔记(005):ref 响应式基础——为什么 script 里要 .value
前端·javascript·vue.js·笔记
海鸥两三1 小时前
Mac电脑使用 Tabby 部署前端项目到阿里云服务器完整教程
前端·macos·阿里云
console.log('npc')1 小时前
2026 实测:Grok 4.5 与 Grok 4.6 怎么选?前端开发、教程写作、Figma 还原选型指南
前端·大模型·ai编程·figma·grok
yyt3630458411 小时前
一次鼠标交互触发两次 Vue flushJobs:把高频交互从 VDOM 里拆出来
前端·vue.js·计算机外设
YUJIANYUE2 小时前
查立得万用查分安卓版(web环境+查询系统免安装单文件一键运行包)
android·前端
超级架构师2 小时前
连接企业系统,不等于把接口直接交给 Agent:LIMENORA 的集成边界
网络·人工智能·架构·ai编程
慧都小项2 小时前
从 Figma 到 Qt:Qtitan 能减少哪些界面还原工作?
前端·qt·嵌入式·figma·图形界面·工业界面·qtitan
YWL2 小时前
OpenLayers导出功能:地图截图+GeoJSON导出完整方案,从Canvas合并到PDF生成
前端·vue·openlayers