admin-scaffold
v1.0.2
Published
通用后台管理系统脚手架 - 组件、请求、工具、架构、权限、
Maintainers
Readme
admin-scaffold
通用后台管理系统脚手架 —— 组件、请求、工具、架构、权限、布局一站式解决方案。
特性
| 特性 | 说明 | |------|------| | Monorepo 架构 | pnpm workspace 管理多包 | | TypeScript 支持 | 完整类型定义,IDE 智能提示 | | ESM + CJS | 同时支持两种模块格式 | | Tree Shaking | 按需加载,不增加额外体积 | | React 18/19 | 支持 React >= 18.0.0 | | Ant Design 5/6 | 支持 antd >= 5.0.0 | | 版本管理 | changesets 自动化版本发布 | | 零业务耦合 | 不包含任何业务逻辑,一切由配置注入 |
安装
pnpm add admin-scaffold
# 或
npm install admin-scaffoldpeerDependencies
脚手架不打包以下库,由消费项目自行安装:
pnpm add react react-dom react-router-dom antd @ant-design/icons axios dayjs zustand快速开始
1. 初始化配置
在应用入口(如 src/main.tsx)进行全局配置:
import { configure, registerServices, setNavigateCallback } from 'admin-scaffold';
import { useNavigate } from 'react-router-dom';
// 注册 API 键名映射
registerServices({
'user.login': '/api/auth/user/login',
'user.list': 'GET /api/user/list',
'user.detail': '/api/user/detail',
// ... 更多接口
});
// 全局配置
configure({
// —— 请求配置 ——
request: {
baseURL: import.meta.env.VITE_API_BASE_URL,
timeout: 20000,
headers: { 'x-channel': 'my-app' },
getToken: () => localStorage.getItem('my_token'),
clearAuth: () => { localStorage.removeItem('my_token'); },
loginPath: '/login',
// 注入公共参数(如品牌编码)
injectParams: (config) => ({ brandCode: getBrandCode() }),
},
// —— 权限配置 ——
auth: {
hasPermission: (key) => authStore.getState().hasPermission(key),
getUserInfo: () => authStore.getState().userInfo,
fetchPermissionKeys: async () => {
const res = await request('user.permissions');
return { menuKeyList: res.data.menuKeys, permissionKeyList: res.data.authKeys };
},
},
// —— 路由配置 ——
router: {
homePath: '/dashboard',
loginPath: '/login',
},
// —— 常量覆盖 ——
constants: {
DEFAULT_PAGE_SIZE: 20,
PAGE_SIZE_OPTIONS: [20, 50, 100],
STORAGE_KEYS: {
TOKEN: 'my_app_token',
USER_INFO: 'my_app_user_info',
},
},
});2. 设置导航回调
import { setNavigateCallback } from 'admin-scaffold';
import { useNavigate } from 'react-router-dom';
function App() {
const navigate = useNavigate();
useEffect(() => {
setNavigateCallback(navigate);
}, [navigate]);
return <YourRoutes />;
}3. 使用组件
完整组件文档(Props 表格 / 使用示例 / Ref 方法)见 COMPONENTS.md。
TablePage - 列表页
import { TablePage, registerServices } from 'admin-scaffold';
registerServices({ 'order.list': 'GET /api/order/list' });
function OrderList() {
return (
<TablePage
apiKey="order.list"
searchFields={[
{ name: 'orderNo', label: '订单号', type: 'input' },
{ name: 'status', label: '状态', type: 'select', options: [
{ label: '待支付', value: 0 },
{ label: '已完成', value: 1 },
]},
]}
columns={[
{ title: '订单号', dataIndex: 'orderNo' },
{ title: '金额', dataIndex: 'amount' },
{ title: '状态', dataIndex: 'status' },
{ title: '操作', render: (_, record) => <a onClick={() => navigate(`/order/${record.id}`)}>详情</a> },
]}
/>
);
}FormPage - 表单页
import { FormPage, FormPageRef } from 'admin-scaffold';
function OrderEdit() {
const formRef = useRef<FormPageRef>(null);
return (
<FormPage
title="编辑订单"
formItems={[
{ name: 'orderNo', label: '订单号', type: 'input', rules: [{ required: true }] },
{ name: 'amount', label: '金额', type: 'number', rules: [{ required: true }] },
{ name: 'remark', label: '备注', type: 'textarea' },
]}
onSubmit={(values) => console.log('提交:', values)}
showSaveButton
/>
);
}FormModal - 弹窗表单
import { FormModal, FormModalRef } from 'admin-scaffold';
function CreateModal({ visible, onOk, onCancel }) {
const modalRef = useRef<FormModalRef>(null);
return (
<FormModal
ref={modalRef}
visible={visible}
title="新增"
formItems={[
{ name: 'name', label: '名称', type: 'input', rules: [{ required: true }] },
{ name: 'type', label: '类型', type: 'select', options: [...] },
]}
onOk={(values) => onOk(values)}
onCancel={onCancel}
/>
);
}SearchBar - 搜索栏
import { SearchBar } from 'admin-scaffold';
<SearchBar
items={[
{ name: 'keyword', label: '关键词', type: 'input', span: 1 },
{ name: 'status', label: '状态', type: 'select', options: [...], span: 1 },
{ name: 'dateRange', label: '日期', type: 'daterange', span: 2 },
]}
onSearch={(values) => console.log(values)}
onReset={() => console.log('reset')}
/>ApiSelect - 远程数据选择器
import { ApiSelect } from 'admin-scaffold';
// 注册预设类型
ApiSelect.registerTypes({
shop: {
apiKey: 'common.shop.list',
valueField: 'shopCode',
labelField: 'shopName',
placeholder: '请选择门店',
},
});
// 使用
<ApiSelect type="shop" />
// 或直接使用
<ApiSelect apiKey="common.shop.list" valueField="id" labelField="name" />权限控制
import { AuthButton, AuthPage } from 'admin-scaffold';
// 按钮级权限
<AuthButton authKey="order.delete">
<Button danger>删除</Button>
</AuthButton>
// 页面级权限
const OrderPage = AuthPage(OrderComponent, {
add: 'order.add',
edit: 'order.edit',
default: 'order.view',
});布局
布局类组件(
MainLayout/Sidebar/Header/TabBar/Breadcrumb)尚在规划中,暂未随包导出。 消费方可基于 antdLayout自行封装,应用名称等可通过configure({ constants: { APP_NAME } })注入。
完整 API
配置
| 函数 | 说明 |
|------|------|
| configure(config) | 全局配置(应用启动时调用一次) |
| getConfig() | 获取完整配置 |
| getRequestConfig() | 获取请求配置 |
| getAuthConfig() | 获取权限配置 |
| getRouterConfig() | 获取路由配置 |
| getConstants() | 获取常量配置 |
| getHomePath() / getLoginPath() | 获取首页 / 登录页路径 |
服务注册(API 键名系统)
| 函数 | 说明 |
|------|------|
| registerServices(map) | 注册 API 键名映射(可多次调用,自动合并) |
| setServices(map) | 覆盖全部 API 映射 |
| getApiUrl(key) | 根据键名获取接口地址 |
| getAllApiKeys() / getAllServices() | 获取全部键名 / 映射表 |
请求
| 函数 | 说明 |
|------|------|
| request(urlOrKey, data?, config?) | POST 请求 |
| request.get(urlOrKey, params?, config?) | GET 请求 |
| request.post(...) | POST |
| request.put(...) | PUT |
| request.delete(...) | DELETE |
| request.download(urlOrKey, data?, filename?) | 下载文件 |
| get(urlOrKey, params?) / post(...) / put(...) / del(...) | 命名导出的便捷方法 |
| recreateRequestInstance() | 配置变更后重建 axios 实例 |
导航
| 函数 | 说明 |
|------|------|
| navigate(path, options?) | 编程式导航 |
| navigateTo(path, query?) | 带查询参数导航 |
| goBack() | 返回上一页 |
| goForward() | 前进 |
| setNavigateCallback(fn) | 设置导航回调 |
认证
| 函数 | 说明 |
|------|------|
| getToken() / setToken(t) / removeToken() | Token 管理 |
| getUserInfo() / setUserInfo(info) / removeUserInfo() | 用户信息 |
| clearAuth() | 清除认证 |
| saveRedirectUrl(url) / getAndClearRedirectUrl() | 重定向管理 |
状态管理
脚手架不内置任何 Store。认证、标签页、面包屑等状态由消费方自行管理, 通过
configure({ auth })注入回调接入,例如hasPermission/getUserInfo/fetchPermissionKeys。
Hooks
| Hook | 说明 |
|------|------|
| usePermission() | 权限检查(返回 { checkPermission, isSuperAdmin }) |
| useWindowSize() | 窗口尺寸 |
| useRequest(apiFn, deps) | 异步请求(返回 { data, loading, run }) |
| useQueryParams() | URL 查询参数 |
组件
各组件完整 Props 与示例见 COMPONENTS.md。
| 组件 | 说明 |
|------|------|
| TablePage | 列表页(搜索 + 表格 + 分页 + Tab + 列设置) |
| FormPage | 表单页(多分区 + 提交 + 重置) |
| FormModal | 弹窗表单 |
| FormTemplate | 表单项渲染引擎 |
| SearchBar | 搜索栏(可折叠) |
| ApiSelect | 远程数据选择器 |
| ApiCascader | 远程级联选择 |
| ApiTreeSelect | 远程树选择 |
| EditTable | 可编辑表格 |
| ModalTableSelect | 弹窗表格选择器 |
| ModalTreeSelector | 弹窗树选择器 |
| FileUpload | 文件上传(图片/文件) |
| FilePreview | 文件预览 |
| CopyText | 复制文本 |
| Empty | 空状态 |
| QuestionTip | 帮助提示 |
| PlaceholderPage | 占位页 |
| AuthButton | 按钮权限 |
| AuthPage | 页面权限 HOC |
| renderActions(actions) | 表格操作列渲染 |
工具函数
| 函数 | 说明 |
|------|------|
| sleep(ms) | 延时 |
| debounce(fn, delay) | 防抖 |
| throttle(fn, delay) | 节流 |
| deepClone(obj) | 深拷贝 |
| mul(a, b) / add(a, b) / sub(a, b) / div(a, b) | 精确计算 |
| round(num, decimals) | 精确四舍五入 |
| formatMoney(num, decimals) | 格式化金额 |
开发
# 安装依赖
pnpm install
# 开发模式(监听文件变化)
pnpm dev
# 构建
pnpm build
# 类型检查
pnpm type-check
# 发布版本
pnpm changeset
pnpm version
pnpm releaseLicense
MIT
