@quansitech/antd-admin
v1.3.2
Published
qscmf antd-admin前端组件
Readme
Qs-antd-admin
该项目作为qs-cmf的后台前端组件库,基于ant-design-pro
安装
npm install @quansitech/antd-admin使用参考
Layout组件Props
| 属性 | 替换组件 | 说明 | 类型 | 默认值 | |---------------|---------------|------|-----------|---------------| | headerActions | HeaderActions | 顶部操作 | ReactNode | - | | footer | Footer | 底部内容 | ReactNode | 全思科技 - Github |
可在项目目录 /resources/js/backend/app.tsx 中修改,如:
createInertiaApp({
resolve: async name => {
const pages = import.meta.glob('./Pages/**/*.tsx')
const page: any = await pages[`./Pages/${name}.tsx`]()
page.default.layout = page.default.layout || ((page: ReactNode) => <Layout
headerActions={<HeaderActions/>} //顶部操作
footer={<>这是底部内容</>} // 底部内容
children={page}/>
)
return page
},
//...
})对于单独页面修改Layout组件属性,可在页面中调用对应的 Replacement 组件,如:
import HeaderActions from "@quansitech/antd-admin/dist/components/Layout/Replacement/HeaderActions";
export default function () {
return <>
<HeaderActions>
修改的内容
</HeaderActions>
页面内容
</>
}
valueType列表
自定义组件
对外暴露 container 供外部调用
import container from "@quansitech/antd-admin/lib/container";
container.register('[组件名]', () => import('[组件路径]'));通用
通用Column Schema
- 组件名前缀:
Column. - 用途:表单项组件(非只读模式)、表格列编辑组件、表格搜索项组件
- 示例:
// [组件.tsx]
import {ColumnProps} from "@quansitech/antd-admin/compontents/Column/types";
export default function (props: ColumnProps) {
return <>
组件内容
</>
}
// [app.tsx]
import container from "@quansitech/antd-admin/lib/container";
container.register('Column.组件名', () => import('[组件路径]'));- 若要补充组件库,请把组件放
compontents/Column/目录下
只读Column Schema
- 组件名前缀:
Column.Readonly. - 用途:表单项组件(只读模式)、表格列组件
- 示例:
// [组件.tsx]
import {ColumnProps} from "@quansitech/antd-admin/compontents/Column/Readonly/types";
export default function (props: ColumnProps) {
return <>
组件内容
</>
}
// [app.tsx]
import container from "@quansitech/antd-admin/lib/container";
container.register('Column.Readonly.组件名', () => import('[组件路径]'));- 若要补充组件库,请把组件放
compontents/Column/Readonly/目录下
表格Table
工具栏操作组件
- 组件名前缀:
Table.Column.Action. - 示例:
// [组件.tsx]
import {TableActionProps} from "@quansitech/antd-admin/compontents/Table/Action/types";
export default function (props: TableActionProps) {
return <Button>{props.title}</Button>
}
// [app.tsx]
import container from "@quansitech/antd-admin/lib/container";
container.register('Table.Column.Action.组件名', () => import('[组件路径]'));
- 若要补充组件库,请把组件放
compontents/Table/Action/目录下
行操作组件
- 组件名前缀:
Table.Column.Option - 示例:
// [组件.tsx]
import {TableColumnOptionProps} from "@quansitech/antd-admin/compontents/Column/Readonly/Action/types";
export default function (props: TableColumnOptionProps) {
<a onClick={onClick}>{props.title}</a>
}
// [app.tsx]
import container from "@quansitech/antd-admin/lib/container";
container.register('Column.Readonly.Action.组件名', () => import('[组件路径]'));
- 若要补充组件库,请把组件放
compontents/Column/Readonly/Action/目录下
常用扩展功能
弹窗(Modal)使用
框架提供了 modalShow 函数用于显示弹窗,支持在弹窗中嵌套 Table、Form、Tabs 等组件。
基本用法
import {modalShow} from "@quansitech/antd-admin/lib/helpers";
// 显示弹窗
await modalShow({
title: '弹窗标题',
content: {
type: 'form', // 支持 'form' | 'table' | 'tabs'
props: {
// 传递给组件的 props
},
url: '/api/modal-content' // 可选:从 URL 获取弹窗内容
},
contexts: {
// 传递给弹窗的上下文数据
tableContext,
customData: 'value'
}
})在弹窗中使用上下文
弹窗内的组件通过 ModalContext 访问上下文:
import {ModalContext} from "@quansitech/antd-admin/components/ModalContext";
export default function MyComponent() {
const modalContext = useContext(ModalContext)
// 关闭弹窗
const close = () => {
modalContext.closeModal()
}
// 设置关闭后的回调
modalContext.setAfterClose(() => {
console.log('弹窗已关闭')
})
// 访问传递的上下文数据
const tableContext = modalContext.contexts?.tableContext
return <div>弹窗内容</div>
}支持的弹窗类型
- form: 表单弹窗,组件路径
Modal.Form - table: 表格弹窗,组件路径
Modal.Table - tabs: 标签页弹窗,组件路径
Modal.Tabs
自定义弹窗组件
// 1. 创建弹窗组件
import {ModalContext} from "@quansitech/antd-admin/components/ModalContext";
export default function CustomModal({title, data}: any) {
const modalContext = useContext(ModalContext)
return (
<div>
<h2>{title}</h2>
<p>{data}</p>
<Button onClick={modalContext.closeModal}>关闭</Button>
</div>
)
}
// 2. 注册弹窗组件
import container from "@quansitech/antd-admin/lib/container";
container.register('Modal.Custom', () => import('./components/CustomModal'))
// 3. 使用自定义弹窗
await modalShow({
content: {
type: 'custom',
props: {
title: '自定义弹窗',
data: 'some data'
}
}
})页面跳转
框架提供了 routerNavigateTo 函数用于页面跳转,基于 Inertia.js 实现。
基本用法
import {routerNavigateTo} from "@quansitech/antd-admin/lib/helpers";
// 简单跳转
routerNavigateTo('/admin/user')
// 带配置的跳转
routerNavigateTo('/admin/user', {
onSuccess: () => {
console.log('跳转成功')
},
onError: (errors) => {
console.error('跳转失败', errors)
},
preserveState: true, // 保留页面状态
replace: false // 不替换历史记录
})在组件中使用
// 按钮点击跳转
<Button onClick={() => routerNavigateTo('/admin/create')}>
新建
</Button>
// JavaScript 协议链接(会使用 window.location.href)
routerNavigateTo('javascript:history.back()')消息提示
框架通过 global 对象提供了消息提示功能,包括成功、错误、警告、信息等提示。
使用方式
import global from "@quansitech/antd-admin/lib/global";
// 成功提示
global.notification.success({
message: '操作成功',
description: '数据已保存'
})
// 错误提示
global.notification.error({
message: '操作失败',
description: '请稍后重试'
})
// 警告提示
global.notification.warning({
message: '警告',
description: '请注意检查数据'
})
// 信息提示
global.notification.info({
message: '提示信息'
})
// 简单消息提示
global.message.success('保存成功')
global.message.error('保存失败')
global.message.warning('请检查输入')
global.message.info('提示信息')
global.message.loading('加载中...')HTTP 自动消息处理
HTTP 拦截器会自动处理后端返回的消息:
// 后端返回格式
{
status: 1, // 1=成功, 0=失败
info: '操作成功', // 会自动显示提示
url: '/admin/list' // 可选:自动跳转
}
// 前端请求
await http({url: '/api/save'})
// 会自动显示成功/失败提示
// 如果返回 url,2秒后自动跳转禁用自动消息
await http({
url: '/api/data',
fetchOptions: {
noHandle: true // 不自动处理消息和跳转
}
})确认框(Confirm)
在需要用户确认的操作时使用确认框。
在 Action 组件中使用
// Table Action
{
title: '删除',
request: {
url: '/admin/delete/__id__',
method: 'post',
confirm: '确定要删除这条记录吗?' // 显示确认框
}
}
// Form Action
{
title: '保存',
submit: true,
confirm: '确定要保存吗?' // 提交前确认
}手动使用确认框
import {Modal} from "antd";
Modal.confirm({
title: '确认操作',
content: '确定要执行此操作吗?',
onOk() {
console.log('确认')
},
onCancel() {
console.log('取消')
}
})HTTP 请求
框架封装了 http 实例,基于 Axios,提供了统一的请求处理。
基本用法
import http from "@quansitech/antd-admin/lib/http";
// GET 请求
const res = await http({
method: 'get',
url: '/api/user/list'
})
// POST 请求
const res = await http({
method: 'post',
url: '/api/user/create',
data: {
name: '张三',
email: '[email protected]'
}
})
// 带请求头
const res = await http({
method: 'post',
url: '/api/data',
headers: {
'X-Custom-Header': 'value'
},
data: {}
})参数替换
支持使用 __field__ 格式进行动态参数替换:
// URL 参数替换
const url = replaceUrl('/admin/user/edit/__id__', {id: 123})
// 结果: '/admin/user/edit/123'
// 请求参数替换
const data = replaceParams({
name: '__username__',
age: '__userage__'
}, {username: '张三', userage: 25})
// 结果: {name: '张三', age: 25}错误处理
try {
await http({
method: 'post',
url: '/api/save',
data: {}
})
} catch (error) {
// 错误会自动显示通知
// 这里可以添加额外处理
console.error('保存失败', error)
}树形数据处理
框架提供了多个树形数据处理的工具函数。
treeToList - 树形转列表
import {treeToList} from "@quansitech/antd-admin/lib/helpers";
const tree = [
{
id: 1,
name: '节点1',
children: [
{id: 11, name: '子节点1.1', children: []},
{id: 12, name: '子节点1.2', children: []}
]
},
{
id: 2,
name: '节点2',
children: []
}
]
const list = treeToList(tree, 'children')
// 结果: [{id:1, name:'节点1'}, {id:11, name:'子节点1.1'}, {id:12, name:'子节点1.2'}, {id:2, name:'节点2'}]diffTree - 对比树形差异
import {diffTree} from "@quansitech/antd-admin/lib/helpers";
const oldTree = [{id: 1, name: 'A', children: []}]
const newTree = [{id: 1, name: 'A', children: []}, {id: 2, name: 'B', children: []}]
const added = diffTree(oldTree, newTree, 'children')
// 结果: [{id: 2, name: 'B'}] - 新增的节点findValuePath - 查找值路径
import {findValuePath} from "@quansitech/antd-admin/lib/helpers";
const obj = {
a: {
b: {
c: 'target'
}
}
}
const path = findValuePath(obj, 'target')
// 结果: ['a', 'b', 'c']getValueByPath - 根据路径取值
import {getValueByPath} from "@quansitech/antd-admin/lib/helpers";
const obj = {a: {b: {c: 'value'}}}
const value = getValueByPath(obj, ['a', 'b', 'c'])
// 结果: 'value'条件判断
使用 handleCondition 函数进行条件判断:
import {handleCondition} from "@quansitech/antd-admin/lib/helpers";
// 支持的操作符
const conditions = [
{field: 'age', operator: '>', value: 18}, // gt, gte, lt, lte
{field: 'status', operator: '=', value: 1}, // eq, neq
{field: 'type', operator: 'in', value: [1, 2, 3]}, // in, not in
]
const data = {age: 20, status: 1, type: 2}
conditions.forEach(cond => {
const result = handleCondition(cond, data)
console.log(`条件${cond.field} ${cond.operator} ${cond.value}:`, result)
})Context 使用
框架提供了多个 Context 用于在不同组件间共享数据。
TableContext
表格上下文,提供表格相关的操作:
import {TableContext} from "@quansitech/antd-admin/components/TableContext";
const tableContext = useContext(TableContext)
// 重新加载表格
await tableContext.getActionRef()?.reload()
// 获取选中的行
const selectedRows = tableContext.getSelectedRows()
// 清空选中
tableContext.getActionRef()?.clearSelected()
// 获取编辑的值
const editedValues = tableContext.getEditedValues()
// 获取数据源
const dataSource = tableContext.getDataSource()
// 获取表格配置
const tableProps = tableContext.getTableProps()FormContext
表单上下文,提供表单相关的操作:
import {FormContext} from "@quansitech/antd-admin/components/FormContext";
const formContext = useContext(FormContext)
// 获取表单引用
const formRef = formContext.getFormRef()
// 获取表单值
const values = await formRef?.getFieldsValue()
// 设置表单值
formRef?.setFieldsValue({name: '张三'})
// 重置表单
formRef?.resetFields()
// 提交表单
formRef?.submit()ModalContext
弹窗上下文,提供弹窗相关的操作:
import {ModalContext} from "@quansitech/antd-admin/components/ModalContext";
const modalContext = useContext(ModalContext)
// 是否在弹窗中
const inModal = modalContext.inModal
// 关闭弹窗
modalContext.closeModal()
// 设置关闭后的回调
modalContext.setAfterClose(() => {
console.log('弹窗关闭后执行')
})
// 访问传递的上下文
const contexts = modalContext.contexts完整示例
表格操作按钮
// 后端配置
{
title: '操作',
actions: [
{
type: 'Button', // 使用自定义按钮组件
props: {
type: 'primary',
title: '编辑',
relateSelection: false, // 不关联选中行
link: {
url: '/admin/edit/__id__' // 跳转链接
}
}
},
{
type: 'Button',
props: {
type: 'default',
title: '审核',
request: {
url: '/admin/audit',
method: 'post',
data: {id: '__id__'},
confirm: '确定要审核通过吗?' // 确认框
}
}
},
{
type: 'Button',
props: {
type: 'default',
title: '查看详情',
modal: {
title: '详情',
content: {
type: 'form',
url: '/admin/detail/__id__'
}
}
}
},
{
type: 'Button',
props: {
type: 'primary',
title: '批量删除',
relateSelection: true, // 关联选中行
request: {
url: '/admin/batch-delete',
method: 'post',
confirm: '确定要删除选中的记录吗?'
}
}
}
]
}表单操作按钮
// 后端配置
{
title: '操作',
actions: [
{
type: 'Button',
props: {
title: '保存',
submit: true // 提交表单
}
},
{
type: 'Button',
props: {
title: '保存并新增',
request: {
url: '/admin/save',
method: 'post',
afterAction: ['tableReload', 'closeModal'] // 操作后执行
}
}
},
{
type: 'Button',
props: {
title: '重置',
reset: true // 重置表单
}
},
{
type: 'Button',
props: {
title: '返回',
back: true // 返回上一页
}
},
{
type: 'Button',
props: {
title: '打开子表单',
modal: {
title: '子表单',
content: {
type: 'form',
url: '/admin/subform/__id__'
}
}
}
}
]
}更新日志
1.3.0 (2026-02-11)
新增功能
- Table 组件优化:添加表格默认搜索值初始化和加载状态处理
- 树形数据处理:新增树形数据处理工具函数(
treeToList、diffTree、findValuePath、getValueByPath) - 布局组件优化:优化布局组件的渲染逻辑和用户体验
Bug 修复
- 修复 Cascader 组件值比较逻辑问题
- 修复表格搜索 URL 处理逻辑
- 修复文件上传组件的 multiple 属性判断逻辑
1.2.0 (2025-09-29)
新增功能
- SelectText 组件:新增键值对输入组件,支持灵活的数据输入方式
- Table 组件增强:
- 添加表格描述功能
- 增加日期范围搜索功能
- 优化列处理逻辑和搜索表单初始值处理
- File 组件增强:支持多文件选择上传功能
- 类型支持:添加 scss 模块声明文件支持
组件优化
- 优化 SelectText 组件样式与功能
- 优化 textarea 渲染逻辑
- 优化上传组件的校验逻辑
1.1.0 (2024-11-14)
新增功能
- Composer 包自动注册:支持自动分析并注册 Composer 包中的组件
- Table 组件增强:
- 添加表格树型结构支持
- 增加表格右侧操作的数据字段渲染功能
- 新增 Link 表格组件
- 支持选项设置、隐藏列配置及行宽设置
- Form 组件增强:
- 新增 Dependency 表单项,支持依赖项处理
- 新增 formList 表单列表组件
- 提交失败后自动滚动到第一个错误表单项
- Layout 组件优化:
- 新增 Layout Replacement 组件,支持单独变更属性
- 支持自定义 headerActions 和 footer
- 文件上传增强:增加图片裁剪质量选项
- 主题支持:添加暗黑模式切换功能
组件优化
- 优化级联初始化机制和省市区组件
- 增加注入自定义组件验证
- 优化文件上传请求,统一文件名后缀大小写
- 添加 hidden 字段适配
- 优化布局组件并添加自定义路由映射
- 添加 useWindowResize 自定义钩子处理窗口大小变化
类型支持
- 将 lodash 引入方式改为花括号形式,优化打包体积
- 增加引入部分类型定义
