bump version: 6.0.0

This commit is contained in:
baorong
2026-03-14 14:20:35 +08:00
parent 8f7dd82e40
commit ccaf67076e
34 changed files with 2027 additions and 101 deletions
+77 -51
View File
@@ -1,83 +1,109 @@
<p align="center">
<a href="http://github.com/zuiidea/antd-admin">
<img alt="antd-admin" height="64" src="./public/logo.svg">
</a>
<a href="http://github.com/zuiidea/antd-admin" target="_blank">
<img alt="antd-admin-logo" height="80" src="./public/logo.svg">
</a>
</p>
<h1 align="center">AntD Admin</h1>
<div align="center">
一个简洁的基于 antd、umi 的 admin 模板.
[![antd](https://img.shields.io/badge/antd-^6.0.0-blue.svg?style=flat-square)](https://github.com/ant-design/ant-design) [![umi](https://img.shields.io/badge/umi-^4.0.0-orange.svg?style=flat-square)](https://github.com/umijs/umi) [![GitHub issues](https://img.shields.io/github/issues/zuiidea/antd-admin.svg?style=flat-square)](https://github.com/zuiidea/antd-admin/issues) [![MIT](https://img.shields.io/dub/l/vibe-d.svg?style=flat-square)](http://opensource.org/licenses/MIT) [![欢迎 PR](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://github.com/zuiidea/antd-admin/pulls) [![Gitter](https://img.shields.io/gitter/room/antd-admin/antd-admin.svg)](https://gitter.im/antd-admin/antd-admin)
基于 Ant Design 6、Umi 4 与 TypeScript 构建的企业级前端解决方案。
</div>
<!-- - Preview - [https://antd-admin.zuiidea.com](https://antd-admin.zuiidea.com)
- Documentation - [https://superlbr.gitee.io/antd-admin](https://superlbr.gitee.io/antd-admin)
- FAQ - [https://doc.antd-admin.zuiidea.com/#/faq](https://doc.antd-admin.zuiidea.com/#/faq)
- ChangeLog - [https://doc.antd-admin.zuiidea.com/#/change-log](https://doc.antd-admin.zuiidea.com/#/change-log) -->
---
English | [简体中文](./README-zh_CN.md)
## 📖 项目简介
## 主要特性
**AntD Admin** 是一个轻量、高性能的管理后台模板,旨在为构建企业级应用提供干净、可扩展的起点。项目使用 **Ant Design 6**、**Umi 4** 与 **TypeScript** 的最新特性,减轻样板代码,提升开发体验。
- 基于 Ant Design 6 + Umi 框架
- TypeScript 支持
- 本地 mock(`mock/index.js`)用于开发阶段模拟接口
- 轻量状态管理:`zustand`
- 常用页面示例:Dashboard、菜单管理、AI Chat 示例等
无论您要构建仪表盘、管理系统,还是集成 AI 功能的工具,本项目都能提供必要的基础。
## 快速开始
## ✨ 主要特性
推荐使用 pnpm:
- 🚀 **现代栈**:基于 **Ant Design 6** + **Umi 4** + **TypeScript**。
- 🎨 **清晰架构**:使用 `zustand` 进行轻量状态管理。
- 🛠 **良好的开发体验**:内置本地 mock 服务器(`mock/index.js`),无需后端即可开发前端功能。
- 📦 **丰富示例页面**:包含可直接使用的页面示例:
- 📊 **仪表盘**:数据可视化概览。
- 👥 **用户管理**:CRUD 操作示例。
- 🧩 **菜单管理**:动态路由配置示例。
- 🤖 **AI 聊天示例**:大模型(LLM)接口集成示例。
- ✅ **CI/CD 支持**:预配置的 GitHub Actions 工作流,用于 lint 和构建。
## 🚀 快速开始
建议使用 **pnpm** 进行包管理。
```bash
# 安装依赖
# 1. 克隆仓库
git clone https://github.com/zuiidea/antd-admin.git -b master --depth=1
cd antd-admin
# 2. 安装依赖
pnpm install
# 本地开发
pnpm run dev
# 3. 启动本地开发(含 mock 数据)
npm run dev
# 打包构建
pnpm run build
# 4. 构建生产包
npm run build
# 代码检查与格式化
pnpm run lint
pnpm run format
# 5. 代码质量检查
npm run lint
npm run format
```
(本项目 `package.json` 中的脚本)
🔌 开发说明
## 项目结构(简要)
#### Mock 服务
- `src/`
- `layouts/` 全局布局
- `pages/` 页面路由与视图
- `components/` 公用组件
- `services/` 接口封装
- `store/` 全局状态管理
- `utils/` 工具与配置
项目包含位于 `mock/index.js` 的内置 mock 服务,方便在没有后端的情况下独立开发前端功能。
## 配置与开发说明
如需关闭 mock 或切换到真实 API,请修改项目的代理配置(例如 Umi 项目可能的配置文件 `config/proxy.ts`、`.umirc.ts` 或 `config/config.ts`),以匹配您的实际项目结构。
- 本地 mock: `mock/index.js`,开发时可直接使用 mock 接口。
- 路由示例:
- `/` 或 `/dashboard` — 仪表盘
- `/users` — 用户管理
- `/sys/menu` — 菜单管理
- `/ai/chat` — AI Chat 示例
#### 常用路由
## 自定义与扩展
| 路由 | 说明 |
| --- | --- |
| `/` 或 `/dashboard` | 主仪表盘 |
| `/users` | 用户列表与管理 |
| `/sys/menu` | 系统菜单配置 |
| `/ai/chat` | AI 聊天示例界面 |
- 接口封装位于 `src/services`,按需修改或替换为真实后端。
- 公共组件位于 `src/components`,例如 `DropOption` 可复用于表格操作列。
#### 定制化
## 贡献
- **API 集成:** 在 `src/services` 中更新 API 接口以对接真实后端。
- **组件扩展:** 在 `src/components` 中复用或扩展现有组件(例如 `DropOption`、`StandardTable`)。
- **主题:** 在主题配置中自定义 Ant Design 变量以匹配品牌视觉。
欢迎提交 issue 或 PR:
#### GitHub Actions(CI)
仓库包含预配置的 GitHub Actions 工作流(见 `.github/workflows/ci.yml`),用于保证代码质量:
- 使用 `pnpm` 安装依赖。
- 运行 lint 检查。
- 构建生产包。
- **工作流位置:** `.github/workflows/ci.yml`
- **提示:** 若要在 CI 中加入自动化测试,请在 `package.json` 中添加测试脚本并更新 workflow YAML。
## 🤝 贡献
欢迎各类贡献:修复 bug、添加新示例页面或组件、完善类型定义与 lint 规则、改进国际化等。
常见贡献流程:
1. Fork 仓库。
2. 新建分支:`git checkout -b feature/AmazingFeature`。
3. 提交变更:`git commit -m 'Add some AmazingFeature'`。
4. 推送分支:`git push origin feature/AmazingFeature`。
5. 提交 Pull Request。
## 📄 许可证
本项目采用 MIT 许可证。
由 zuiidea 与贡献者共同维护,Made with ❤️。
- 修复 bug
- 补充示例页面或组件
- 优化类型定义或代码风格
+80 -50
View File
@@ -1,6 +1,6 @@
<p align="center">
<a href="http://github.com/zuiidea/antd-admin">
<img alt="antd-admin" height="64" src="./public/logo.svg">
<a href="http://github.com/zuiidea/antd-admin" target="_blank">
<img alt="antd-admin-logo" height="80" src="./public/logo.svg">
</a>
</p>
@@ -8,77 +8,107 @@
<div align="center">
An excellent front-end solution for enterprise applications.
An excellent enterprise-grade front-end solution built with Ant Design 6, Umi 4, and TypeScript.
[![antd](https://img.shields.io/badge/antd-^6.0.0-blue.svg?style=flat-square)](https://github.com/ant-design/ant-design) [![umi](https://img.shields.io/badge/umi-^4.0.0-orange.svg?style=flat-square)](https://github.com/umijs/umi) [![GitHub issues](https://img.shields.io/github/issues/zuiidea/antd-admin.svg?style=flat-square)](https://github.com/zuiidea/antd-admin/issues) [![MIT](https://img.shields.io/dub/l/vibe-d.svg?style=flat-square)](http://opensource.org/licenses/MIT) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://github.com/zuiidea/antd-admin/pulls) [![Gitter](https://img.shields.io/gitter/room/antd-admin/antd-admin.svg)](https://gitter.im/antd-admin/antd-admin)
[![antd](https://img.shields.io/badge/AntD-^6.0.0-1890ff?style=flat-square&logo=ant-design)](https://github.com/ant-design/ant-design)
[![umi](https://img.shields.io/badge/Umi-^4.0.0-ff9900?style=flat-square&logo=umijs)](https://github.com/umijs/umi)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-3178c6?style=flat-square&logo=typescript)](https://www.typescriptlang.org/)
[![GitHub issues](https://img.shields.io/github/issues/zuiidea/antd-admin?style=flat-square)](https://github.com/zuiidea/antd-admin/issues)
[![GitHub stars](https://img.shields.io/github/stars/zuiidea/antd-admin?style=flat-square)](https://github.com/zuiidea/antd-admin/stargazers)
[![License](https://img.shields.io/badge/License-MIT-blue?style=flat-square)](http://opensource.org/licenses/MIT)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen?style=flat-square)](https://github.com/zuiidea/antd-admin/pulls)
# antd-admin_next
</div>
Lightweight admin template built with Ant Design, Umi and TypeScript. This project aims to provide a clean, extensible starting point for building admin panels. It includes common pages, sample components, and a local mock server for development.
---
## Key Features
## 📖 Introduction
- Ant Design 6 + Umi
- TypeScript-first codebase
- Local mock server (`mock/index.js`) for development
- Lightweight state with `zustand`
- Example pages: Dashboard, Users, Menu management, AI Chat demo
**AntD Admin** is a lightweight, high-performance admin template designed to provide a clean and extensible starting point for building enterprise applications. It leverages the latest features of **Ant Design 6**, **Umi 4**, and **TypeScript**, offering a modern development experience with minimal boilerplate.
## Quick Start
Whether you are building a dashboard, a management system, or an AI-powered tool, this project provides the essential foundation you need.
Recommended: use pnpm.
## ✨ Key Features
- 🚀 **Modern Stack**: Built on **Ant Design 6** + **Umi 4** + **TypeScript**.
- 🎨 **Clean Architecture**: Lightweight state management using `zustand`.
- 🛠 **Dev Experience**: Integrated local mock server (`mock/index.js`) for seamless frontend development without backend dependency.
- 📦 **Rich Examples**: Includes ready-to-use pages:
- 📊 **Dashboard**: Data visualization overview.
- 👥 **User Management**: CRUD operations example.
- 🧩 **Menu Management**: Dynamic routing configuration.
- 🤖 **AI Chat Demo**: Integration example for LLM interfaces.
- ✅ **CI/CD Ready**: Pre-configured GitHub Actions for linting and building.
## 🚀 Quick Start
We recommend using **pnpm** for package management.
```bash
# install dependencies
# 1. Clone the repository
git clone https://github.com/zuiidea/antd-admin.git -b master --depth=1
cd antd-admin
# 2. Install dependencies
pnpm install
# local development
pnpm run dev
# 3. Start local development server (with mock data)
npm run dev
# build for production
pnpm run build
# 4. Build for production
npm run build
# lint and format
pnpm run lint
pnpm run format
# 5. Code quality checks
npm run lint
npm run format
```
Scripts are defined in `package.json`.
🔌 **Development Notes**
## Project Structure (summary)
#### Mock Server
- `src/`
- `layouts/` global layout components
- `pages/` routes and views
- `components/` shared components
- `services/` API wrappers
- `store/` global state (zustand)
- `utils/` helpers and configuration
The project includes a built-in mock server defined in `mock/index.js`. This allows you to develop frontend features independently of the backend.
## Development notes
To disable mocks or switch to a real API, modify the proxy settings in your configuration file (for example, `config/proxy.ts` or `.umirc.ts`).
- Local mock: `mock/index.js` provides mocked API endpoints during development.
- Common routes:
- `/` or `/dashboard` — Dashboard
- `/users` — Users list
- `/sys/menu` — Menu management
- `/ai/chat` — AI Chat demo
#### Common Routes
## Customization
| Route | Description |
| --- | --- |
| `/` or `/dashboard` | Main Dashboard |
| `/users` | User List & Management |
| `/sys/menu` | System Menu Configuration |
| `/ai/chat` | AI Chat Interface Demo |
- Update API calls in `src/services` to point to real backends.
- Reuse or extend components in `src/components` (for example `DropOption`).
#### Customization
## GitHub Actions CI
- **API Integration:** Update API endpoints in `src/services` to connect to your real backend.
- **Component Extension:** Reuse or extend existing components in `src/components` (for example, `DropOption`, `StandardTable`).
- **Theme:** Customize Ant Design tokens in the theme configuration to match your brand identity.
This repository includes a GitHub Actions workflow that installs dependencies with `pnpm`, runs lint and builds the project. The workflow is at `.github/workflows/ci.yml`.
#### GitHub Actions CI
If you want tests added to CI, add a test script to `package.json` and update the workflow accordingly.
This repository includes a pre-configured GitHub Actions workflow to ensure code quality:
## Contributing
- Installs dependencies using `pnpm`.
- Runs linting checks.
- Builds the project for production.
Contributions welcome via issues and pull requests. Typical contributions:
- Bug fixes
- Example pages or components
- Type and lint improvements
- **Workflow location:** `.github/workflows/ci.yml`
- **Tip:** To add automated tests to the CI pipeline, add a test script to `package.json` and update the workflow YAML accordingly.
🤝 Contributing
Contributions are always welcome! Whether it's fixing a bug, adding a new feature, or improving documentation, please feel free to submit an Issue or a Pull Request.
Typical contributions include:
🐛 Bug fixes
🧩 New example pages or components
📝 Type definitions and linting improvements
🌍 Internationalization (i18n) updates
How to contribute:
Fork the repository.
Create your feature branch (git checkout -b feature/AmazingFeature).
Commit your changes (git commit -m 'Add some AmazingFeature').
Push to the branch (git push origin feature/AmazingFeature).
Open a Pull Request.
📄 License
This project is licensed under the MIT License.
Made with ❤️ by zuiidea and contributors.
View File
+36
View File
@@ -0,0 +1,36 @@
# API configuration
This project uses explicit per-feature service modules (TypeScript) under `src/services/` that call a shared HTTP helper `src/utils/request.ts` (exported as the default `api` function).
Why this pattern?
- Clear function boundaries per domain (users, admin, menu, dashboard).
- Type-safe signatures in TypeScript for inputs/outputs (`src/types`).
- Centralized request handling (query params, JSON body, auth header, unified response format) in `src/utils/request.ts`.
Example service (from `src/services/user.ts`):
```ts
import type { PagedResponse, User } from '@/types/user';
import api from '../utils/request';
export async function listUsers(
params?: Record<string, string | number | boolean>,
): Promise<PagedResponse<User>> {
return api<PagedResponse<User>>('/users', { method: 'GET', params });
}
export async function createUser(values: Record<string, unknown>): Promise<User> {
return api('/user', { method: 'POST', body: values });
}
```
Usage:
- Import named functions from the service module: `import { listUsers } from '@/services/user'`.
- The helper `api(path, options)` returns the parsed `data` payload from responses that follow the `{ success, message, data }` convention.
Notes about `src/utils/request.ts`:
- Combines `config.apiPrefix` with the provided `path`.
- Supports `params` (query), `body` (JSON or FormData), and sets `Authorization` header from local storage when available.
- Throws errors and shows UI messages for non-success responses.
If you are migrating older code that used an API mapping, prefer creating small service modules with clear function names and types as shown above.
+57
View File
@@ -0,0 +1,57 @@
<p align="center">
<a href="http://github.com/zuiidea/antd-admin">
<img alt="antd-admin" height="64" src="./_media/logo.svg">
</a>
</p>
<h1 align="center">AntD Admin</h1>
<div align="center">
An enterprise-grade front-end starter built with Ant Design 6, Umi 4 and TypeScript.
[![antd](https://img.shields.io/badge/AntD-^6.0.0-1890ff?style=flat-square&logo=ant-design)](https://github.com/ant-design/ant-design)
[![umi](https://img.shields.io/badge/Umi-^4.0.0-ff9900?style=flat-square&logo=umijs)](https://github.com/umijs/umi)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-3178c6?style=flat-square&logo=typescript)](https://www.typescriptlang.org/)
[![License](https://img.shields.io/badge/License-MIT-blue?style=flat-square)](http://opensource.org/licenses/MIT)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen?style=flat-square)](https://github.com/zuiidea/antd-admin/pulls)
</div>
- Documentation source for this project is under `docs/`.
## Quick start
This repository uses `pnpm` in examples and CI; `npm` or `yarn` also work but `pnpm` is recommended.
```bash
# clone
git clone https://github.com/zuiidea/antd-admin.git
cd antd-admin
# install
pnpm install
# start dev server (includes local mock server)
npm run dev
# build
npm run build
# lint & format
npm run lint
npm run format
```
Notes:
- Mock data live in `mock/index.js` and the project can run without a backend during development.
- CI workflow is available at `.github/workflows/ci.yml` (uses pnpm, lint, build).
- Update API endpoints under `src/services` to integrate a real backend.
For detailed documentation see the other pages in this `docs/` folder.
## Contributing
Contributions welcome — file issues or open a PR as usual on GitHub.
Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

+24
View File
@@ -0,0 +1,24 @@
<svg width="169px" height="141px" viewBox="0 0 169 141" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 51.3 (57544) - http://www.bohemiancoding.com/sketch -->
<desc>Created with Sketch.</desc>
<defs>
<linearGradient x1="54.0428975%" y1="4.39752391%" x2="54.0428975%" y2="108.456714%" id="linearGradient-1">
<stop stop-color="#29CDFF" offset="0%"></stop>
<stop stop-color="#148EFF" offset="62.3089445%"></stop>
<stop stop-color="#0A60FF" offset="100%"></stop>
</linearGradient>
<linearGradient x1="50%" y1="14.2201464%" x2="50%" y2="113.263844%" id="linearGradient-2">
<stop stop-color="#FA816E" offset="0%"></stop>
<stop stop-color="#F74A5C" offset="65.9092442%"></stop>
<stop stop-color="#F51D2C" offset="100%"></stop>
</linearGradient>
</defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Group" transform="translate(0.000000, -5.000000)">
<rect id="Rectangle" fill="url(#linearGradient-1)" transform="translate(83.718923, 75.312358) rotate(-24.000000) translate(-83.718923, -75.312358) " x="68.7189234" y="0.312357954" width="30" height="150" rx="15"></rect>
<rect id="Rectangle" fill="url(#linearGradient-1)" transform="translate(129.009910, 75.580213) rotate(-24.000000) translate(-129.009910, -75.580213) " x="114.00991" y="0.580212739" width="30" height="150" rx="15"></rect>
<circle id="Oval" fill="url(#linearGradient-2)" cx="25" cy="120" r="25"></circle>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 194 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 118 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 199 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 124 KiB

+12
View File
@@ -0,0 +1,12 @@
- Getting started
- [Quick Start](getting-started.md)
- Customization
- [Configuration](configuration.md)
- [API Configuration](API-configuration.md)
- [I18n](i18n.md)
- [Layout](layout.md)
- [Request](request.md)
- Guide
- [Deploy](deploy.md)
- [Change Log](change-log.md)
- [FAQ](faq.md)
+26
View File
@@ -0,0 +1,26 @@
## 6.0.0
This project was modernized and migrated to a modern front-end stack. Key highlights of the current version:
### Modern stack
- Upgraded to Ant Design 6, Umi 4 and TypeScript 5.
- React has been updated to the current major line used in the repo (see `package.json`).
### Architecture & DX
- Services are implemented as TypeScript modules under `src/services/` and use a centralized HTTP helper `src/utils/request.ts`.
- Lightweight local state management using `zustand` replacing older `dva` patterns.
- Local mock server using `mock/index.js` with `mockjs` for frontend development without backend dependency.
### Tooling & CI
- Dev workflows use `pnpm` by default; scripts are defined in `package.json` (e.g. `pnpm run dev`, `pnpm run build`).
- Tests use `jest` and related tooling; CI is implemented with GitHub Actions (`.github/workflows/ci.yml`) which installs via `pnpm`, lints and builds the project.
### Quality and types
- TypeScript types are added/expanded under `src/types/` for safer APIs and components.
- Prettier / ESLint configuration added to enforce code style.
### Other
- Documentation is maintained under `docs/` (this site) and updated to reflect the new stack and commands.
- Removed old custom components that duplicate Ant Design functionality and simplified the codebase accordingly.
If you want a more detailed, commit-level changelog for each migration step, I can generate one from git history or help draft a migration guide.
+33
View File
@@ -0,0 +1,33 @@
# Configuration
You can do some custom configuration in `/src/utils/config.js`:
## siteName
- Type `String`
Configure the site name, apply it to the login box, and display the title text at the top of the sidebar.
## copyright
- Type: `String`
Configure the copyright notice to apply to the login page, at the bottom of the `Primary` layout.
## logoPath
- Type: `String`
Configure the site logo to apply to the login box and the Logo display at the top of the sidebar.
## apiPrefix
- Type: `String`
Configure the prefix of the interface in the project. The interface related documents can be viewed [API configuration](API-configuration.md)
## fixedHeader
- Type: `String`
Under the `Primary` layout, whether the top of the page is fixed when scrolling。
+113
View File
@@ -0,0 +1,113 @@
# Deploy
After the development is completed and verified in the development environment, it needs to be deployed to our users.
![i18n](./_media/term_build.svg)
## Build
First execute the following command,
```bash
npm run build
```
After a few seconds, the output should look like this:
```bash
> antd-admin@5.0.0-beta build /Users/zuiidea/web/antd-admin
> umi build
[21:13:17] webpack compiled in 43s 868ms
DONE Compiled successfully in 43877ms 21:13:17
File sizes after gzip:
1.3 MB dist/vendors.async.js
308.21 KB dist/umi.js
45.49 KB dist/vendors.chunk.css
36.08 KB dist/p__chart__highCharts__index.async.js
33.53 KB dist/p__user__index.async.js
22.36 KB dist/p__chart__ECharts__index.async.js
4.21 KB dist/p__dashboard__index.async.js
4.06 KB dist/umi.css
...
```
The `build` command will package all resources, including JavaScript, CSS, web fonts, images, html, and more. You can find these files in the `dist/` directory.
> If you have requirements for using HashHistory , deploying html to non-root directories, statics, etc., check out [Umi Deployment] (https://umijs.org/en/guide/deploy.html).
## Local verification
Local verification can be done via `serve` before publishing.
```
$ yarn global add serve
$ serve ./dist
Serving!
- Local: http://localhost:5000
- On Your Network: http://{Your IP}:5000
Copied local address to clipboard!
```
Access [http://localhost:5000](http://localhost:5000), under normal circumstances, it should be consistent with `npm start` (The API may not get the correct data).
## Deploy
Next, we can upload the static file to the server. If you use Nginx as the Web server, you can configure it in `ngnix.conf`:
```
server
{
listen 80;
# Specify an accessible domain name
server_name antd-admin.zuiidea.com;
# The directory where the compiled files are stored
root /home/www/antd-admin/dist;
# Proxy server interface to avoid cross-domain
location /api {
proxy_pass http://localhost:7000/api;
}
Because the front end uses BrowserHistory, it will route backback to index.html
location / {
index index.html;
try_files $uri $uri/ /index.html;
}
}
```
Restart the web server and access [http://antd-admin.zuiidea.com](http://antd-admin.zuiidea.com) , You will see the correct page.
```bash
nginx -s reload
```
Similarly, if you use Caddy as a web server, you can do this in `Caddyfile`:
```
antd-admin.zuiidea.com {
gzip
root /home/www/antd-admin/dist
proxy /api http://localhost:7000
rewrite {
if {path} not_match ^/api
to {path} {path}/ /
}
}
antd-admin.zuiidea.com/public {
gzip
root /home/www/antd-admin/dist/static/public
}
```
+9
View File
@@ -0,0 +1,9 @@
# FAQ
Most asked
## create new page
1. just copy a page in /src/pages (route here auto generated by [umi](https://umijs.org/guide/router.html#basic-routing))
2. modify namespace/pathToRegexp in model.js
3. modify mock route.js to add a route
+75
View File
@@ -0,0 +1,75 @@
# Quick Start
> Before delving into Ant Design React, a good knowledge base of [React](http://facebook.github.io/react/) 、 [ES2015+](http://es6.ruanyifeng.com/) 、 [Antd Design](https://ant.design/docs/react/introduce-cn). Learn about [UmiJS](https://umijs.org/). Ensure you have [Node.js](https://nodejs.org/) (v18+ recommended) and [Git](https://git-scm.com/) installed.
## Installation
```bash
git clone https://github.com/zuiidea/antd-admin.git my-project
cd my-project
```
## Scaffolding
The project layout is as follows:
```bash
├── dist/ # Default build output directory
├── mock/ # Mock files
├── public/ # Static resource
├── src/ # Source code
│ ├── components/ # Components
│ ├── e2e/ # Integrated Test Case
│ ├── layouts/ # Common Layouts
│ ├── locales/ # i18n resources
│ ├── models/ # Global dva Model
│ ├── pages/ # Sub-pages and templates
│ ├── services/ # Backend Services
│ │ ├── api.js # API configuration
│ │ └── index.js # API export
│ ├── themes/ # Themes
│ │ ├── default.less # Less variable
│ │ ├── index.less # Global style
│ │ ├── mixin.less # Less mixin
│ │ └── vars.less # Less variable and mixin
│ ├── utils/ # Utility
│ │ ├── config.js # Application configuration
│ │ ├── constant.js # Static constant
│ │ ├── index.js # Utility methods
│ │ ├── request.js # Request function(axios)
│ │ └── theme.js # Style variables used in js
├── .editorconfig
├── .env
├── .eslintrc
├── .gitignore
├── .prettierignore
├── .prettierrc
├── .stylelintrc.json
├── .travis.yml
└── .umirc.js
└── package.json
```
## Development
1. Install dependencies (recommended: `pnpm`).
```bash
pnpm install
```
Or with other package managers:
```bash
npm install
# or
yarn install
```
2. Start local development server.
```bash
npm run dev
```
3. After startup, open the app in a browser (see dev server output for the actual URL/port).
+121
View File
@@ -0,0 +1,121 @@
# Internationalization (i18n) Guide
This project uses Umi's `plugin-locale` (based on `react-intl`) to manage localization. Translation resources live in `src/locales` (for example `en-US.json`, `zh-CN.json`). Below are instructions for: adding a language, adding a translation entry, switching languages, and disabling i18n. Examples use Japanese `ja-JP`.
## 1. Add a new language (persistent)
1. Create a new translation file under `src/locales/` with the language id as the file name, for example: `src/locales/ja-JP.json`.
2. The file should contain a JSON object of translation keys and values (nesting allowed):
```json
{
"welcome": "ようこそ",
"login": {
"username": "ユーザー名",
"password": "パスワード",
"submit": "ログイン"
}
}
```
3. If you want Ant Design components to use the same locale (dates, component text), add the AntD locale import and mapping in `src/app.tsx`'s `pick` function, e.g.:
```ts
import jaJP from 'antd/locale/ja_JP';
// ...
if (l === 'ja-JP') return jaJP;
```
4. Add the language to the language selector (for example in `src/components/TopbarControls.tsx`):
```ts
{ key: 'ja-JP', label: '日本語' }
```
5. Restart the dev server:
```bash
pnpm run dev
```
Umi collects files in `src/locales` into `localeInfo` at build/dev time so the new language becomes available. If you prefer not to restart, see the runtime registration option below.
## 2. Add a translation entry
1. Add the same key to each language JSON (keep `en-US.json` and `zh-CN.json` up to date alongside the new language):
`src/locales/en-US.json`
```json
"my.feature.greeting": "Hello from feature"
```
`src/locales/zh-CN.json`
```json
"my.feature.greeting": "来自功能的问候"
```
2. In a component use `useIntl()` and `formatMessage`:
```ts
import { useIntl } from 'umi';
const intl = useIntl();
const text = intl.formatMessage({ id: 'my.feature.greeting', defaultMessage: 'Hello' });
```
Use `useIntl()` (or `injectIntl`) so the component updates automatically when the locale changes.
## 3. Runtime switching and registering
- Switch locale (writes `umi_locale` to localStorage and either reloads or triggers an update):
```ts
import { setLocale } from 'umi';
// switch and reload
setLocale('ja-JP', true);
// switch without reload (emit update event)
setLocale('zh-CN', false);
```
- Register a locale at runtime (no server restart required):
```ts
import { addLocale, setLocale } from 'umi';
import jaMessages from '@/locales/ja-JP.json';
import jaAntd from 'antd/locale/ja_JP';
addLocale('ja-JP', jaMessages, { antd: jaAntd, momentLocale: 'ja' });
setLocale('ja-JP', false);
```
`addLocale` merges messages into the internal `localeInfo`. You can pass extra data (like AntD locale and moment locale) so components using AntD/moment behave correctly.
## 4. Disable i18n (turn off multi-language)
To permanently disable multi-language support:
1. In `src/app.tsx`'s `LocaleWrapper`, return a fixed AntD locale (ignore `localStorage` `umi_locale`):
```ts
const pick = (l: string | null) => {
return zhCN; // force Chinese
};
```
2. Remove or hide the language switcher (for example, remove language menu items in `src/components/TopbarControls.tsx`).
3. Optionally remove other JSON files in `src/locales` except the single target language to reduce build size.
If you only want to temporarily prevent user switching, hide the switcher (step 2) and keep files intact for easy re-enable.
## 5. Debugging & common issues
- New language not appearing: restart dev server or use `addLocale`; ensure AntD locale mapping exists in `app.tsx`.
- Missing translations: check all `src/locales/*.json` contain the key, and the `formatMessage` id is correct.
- Want automated extraction of message ids: this repo does not include extraction scripts; consider integrating `lingui`, `babel-plugin-react-intl`, or other tooling and adding scripts to `package.json`.
If you want, I can:
- create an initial `src/locales/ja-JP.json` and update `TopbarControls`/`app.tsx` mappings; or
- add a small example component that demonstrates runtime registration using `addLocale`. Tell me which one you prefer.
+55
View File
@@ -0,0 +1,55 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>antd-admin - An admin dashboard application demo built upon Ant Design and UmiJS</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="description" content="An admin dashboard application demo built upon Ant Design and UmiJS">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/vue.css">
<link rel="icon" href="/_media/favicon.ico" />
</head>
<body>
<nav data-cloak class="app-nav">
<a href="/">En</a>
<a href="#/zh-cn/">中文</a>
</nav>
<div id="app">Loading...</div>
<script>
window.$docsify = {
name: 'AntD Admin',
loadSidebar: true,
maxLevel: 3,
subMaxLevel: 3,
auto2top: true,
autoHeader: true,
repo: 'zuiidea/antd-admin',
themeColor: '#1890ff',
search: {
paths: 'auto',
placeholder: {
'/zh-cn/': '搜索',
'/': 'Type to search'
},
noData: {
'/zh-cn/': '找不到结果',
'/': 'No Results'
}
}
}
// if (typeof navigator.serviceWorker !== 'undefined') {
// navigator.serviceWorker.register('sw.js')
// }
</script>
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
<script src="//unpkg.com/docsify/lib/plugins/search.min.js"></script>
<script src="//unpkg.com/docsify/lib/plugins/emoji.min.js"></script>
<script src="//unpkg.com/docsify/lib/plugins/zoom-image.min.js"></script>
<script src="//unpkg.com/docsify-copy-code"></script>
</body>
</html>
+60
View File
@@ -0,0 +1,60 @@
# Layout
## Add a new layout
Take a new layout named `secondary` as an example to make the route starting with `secondary` use this layout.
1. Add related configuration in `src/utils/config.js`. For details, please refer to [layouts](/configuration?id=layouts).
```javascript
   layouts: [
           {
               name: 'primary',
               include: [/.*/],
               exclude: [/(\/(en|zh))*\/login/, /(\/(en|zh))*\/secondary\/(.*)/],
           },
           {
               name: 'secondary',
               include: [/(\/(en|zh))*\/secondary\/(.*)/],
           },
   ],
```
2. Add the `secondary` layout component to the `src/layouts/BaseLayout.js` file.
```javascript
   import SecondaryLayout from './SecondaryLayout'
   const LayoutMap = {
     primary: PrimaryLayout,
     public: PublicLayout,
     secondary: SecondaryLayout,
   }
```
3. Add the `SecondaryLayout.js` file to the `src/layouts/` directory.
```javascript
   import React from 'react'
   export default ({ children }) => {
     return (
       <div>
         <h1>Secondary</h1>
         {children}
       </div>
     )
   }
```
4. Add a `secondary/index.js` file to the `src/pages/` directory.
```javascript
   import React from 'react'
   export default ({ children }) => {
     Return <div>Secondary page Content</div>
   }
```
5. Finally, start the development mode with `npm run dev`, then open the layout page in your browser (see dev server output for the actual URL), e.g. `/secondary/`.
+33
View File
@@ -0,0 +1,33 @@
# HTTP requests
This project uses a small fetch-based HTTP helper implemented at `src/utils/request.ts` (export default `api`). The helper centralizes:
- Prefixing paths with `config.apiPrefix`.
- Handling `params` (query string) and `body` (JSON or FormData).
- Injecting an `Authorization` header from local storage when available.
- Unified response parsing and error handling (expects backend responses in the form `{ success, message, data }`).
Key behaviors
- `api(path, options)` merges `config.apiPrefix` + `path` to build the URL.
- If `options.params` is provided it's serialized and appended as query string.
- `options.body` handling:
- FormData is sent as-is (do not set Content-Type manually).
- Strings and Blobs are sent directly.
- Plain objects are JSON.stringified and Content-Type defaults to `application/json`.
- If a token exists in local storage (key `app-auth-token`), the helper injects an `Authorization: Bearer <token>` header unless one is already provided.
- Responses are expected to be JSON with `{ success: boolean, message?: string, data: T }`. Non-success responses throw an Error and show a UI message (uses `antd`'s `message`).
Usage (TypeScript-friendly):
```ts
import api from '@/utils/request';
// GET with query params
const page = await api('/users', { method: 'GET', params: { page: 1, pageSize: 10 } });
// POST with JSON body
const created = await api('/user', { method: 'POST', body: { name: 'Alice' } });
```
The helper returns the `data` field from successful responses. Check `src/utils/request.ts` for exact typings and behavior.
+83
View File
@@ -0,0 +1,83 @@
/* ===========================================================
* docsify sw.js
* ===========================================================
* Copyright 2016 @huxpro
* Licensed under Apache 2.0
* Register service worker.
* ========================================================== */
const RUNTIME = 'docsify'
const HOSTNAME_WHITELIST = [
self.location.hostname,
'fonts.gstatic.com',
'fonts.googleapis.com',
'unpkg.com'
]
// The Util Function to hack URLs of intercepted requests
const getFixedUrl = (req) => {
var now = Date.now()
var url = new URL(req.url)
// 1. fixed http URL
// Just keep syncing with location.protocol
// fetch(httpURL) belongs to active mixed content.
// And fetch(httpRequest) is not supported yet.
url.protocol = self.location.protocol
// 2. add query for caching-busting.
// Github Pages served with Cache-Control: max-age=600
// max-age on mutable content is error-prone, with SW life of bugs can even extend.
// Until cache mode of Fetch API landed, we have to workaround cache-busting with query string.
// Cache-Control-Bug: https://bugs.chromium.org/p/chromium/issues/detail?id=453190
if (url.hostname === self.location.hostname) {
url.search += (url.search ? '&' : '?') + 'cache-bust=' + now
}
return url.href
}
/**
* @Lifecycle Activate
* New one activated when old isnt being used.
*
* waitUntil(): activating ====> activated
*/
self.addEventListener('activate', event => {
event.waitUntil(self.clients.claim())
})
/**
* @Functional Fetch
* All network requests are being intercepted here.
*
* void respondWith(Promise<Response> r)
*/
self.addEventListener('fetch', event => {
// Skip some of cross-origin requests, like those for Google Analytics.
if (HOSTNAME_WHITELIST.indexOf(new URL(event.request.url).hostname) > -1) {
// Stale-while-revalidate
// similar to HTTP's stale-while-revalidate: https://www.mnot.net/blog/2007/12/12/stale
// Upgrade from Jake's to Surma's: https://gist.github.com/surma/eb441223daaedf880801ad80006389f1
const cached = caches.match(event.request)
const fixedUrl = getFixedUrl(event.request)
const fetched = fetch(fixedUrl, { cache: 'no-store' })
const fetchedCopy = fetched.then(resp => resp.clone())
// Call respondWith() with whatever we get first.
// If the fetch fails (e.g disconnected), wait for the cache.
// If there’s nothing in cache, wait for the fetch.
// If neither yields a response, return offline pages.
event.respondWith(
Promise.race([fetched.catch(_ => cached), cached])
.then(resp => resp || fetched)
.catch(_ => { /* eat any errors */ })
)
// Update the cache with the version we fetched (only for ok status)
event.waitUntil(
Promise.all([fetchedCopy, caches.open(RUNTIME)])
.then(([response, cache]) => response.ok && cache.put(event.request, response))
.catch(_ => { /* eat any errors */ })
)
}
})
+35
View File
@@ -0,0 +1,35 @@
# 接口配置
本项目使用基于 TypeScript 的按功能分割服务模块,位于 `src/services/`,所有服务通过共享的 HTTP 封装 `src/utils/request.ts`(默认导出为 `api` 函数)发起请求。
为什么采用此模式?
- 每个领域(user/admin/menu/dashboard)有独立函数,职责清晰。
- 使用 TypeScript 提供输入/输出类型定义,便于维护(参见 `src/types`)。
- 请求处理集中化(查询参数、JSON body、鉴权 header、统一响应格式等)在 `src/utils/request.ts`。
示例(来自 `src/services/user.ts`):
```ts
import type { PagedResponse, User } from '@/types/user';
import api from '../utils/request';
export async function listUsers(
params?: Record<string, string | number | boolean>,
): Promise<PagedResponse<User>> {
return api<PagedResponse<User>>('/users', { method: 'GET', params });
}
export async function createUser(values: Record<string, unknown>): Promise<User> {
return api('/user', { method: 'POST', body: values });
}
```
使用方式:
- 通过 `import { listUsers } from '@/services/user'` 导入命名函数。
- `api(path, options)` 返回后端约定格式 `{ success, message, data }` 中的 `data` 字段。
关于 `src/utils/request.ts`:
- 会将 `config.apiPrefix` 与 `path` 拼接;支持 `params`(查询)、`body`(JSON 或 FormData);若存在本地 token 则自动注入 `Authorization`。
- 对非成功响应会抛出异常并在界面上显示消息(使用 `antd` 的 `message`)。
如果你在迁移旧的 API 映射实现,建议按当前结构将功能拆分为小型服务模块并补充类型定义。
+53
View File
@@ -0,0 +1,53 @@
<p align="center">
<a href="http://github.com/zuiidea/antd-admin">
<img alt="antd-admin" height="64" src="../_media/logo.svg">
</a>
</p>
<h1 align="center">AntD Admin</h1>
<div align="center">
基于 Ant Design 6、Umi 4 与 TypeScript 的企业级前端起手模版。
[![antd](https://img.shields.io/badge/AntD-^6.0.0-1890ff?style=flat-square&logo=ant-design)](https://github.com/ant-design/ant-design)
[![umi](https://img.shields.io/badge/Umi-^4.0.0-ff9900?style=flat-square&logo=umijs)](https://github.com/umijs/umi)
</div>
- 文档源文件位于 `docs/` 目录。
## 快速开始
本仓库示例与 CI 使用 `pnpm`,你也可以使用 `npm` 或 `yarn`,但推荐 `pnpm`。
```bash
# 克隆
git clone https://github.com/zuiidea/antd-admin.git
cd antd-admin
# 安装依赖
pnpm install
# 启动开发(含本地 mock)
npm run dev
# 构建
npm run build
# lint 与格式化
npm run lint
npm run format
```
说明:
- 本地 mock 实现在 `mock/index.js`,便于在无后端时开发。
- CI 工作流位于 `.github/workflows/ci.yml`(使用 pnpm、lint、build)。
- 若需对接真实后端,请修改 `src/services` 下的 API。
更多详细文档请查看 `docs/` 目录下的其他页面。
## 参与贡献
欢迎提交 Issue 或 PR 改进项目文档或代码。
+11
View File
@@ -0,0 +1,11 @@
- 入门
- [快速上手](zh-cn/getting-started.md)
- 定制化
- [配置项](zh-cn/configuration.md)
- [接口配置](zh-cn/API-configuration.md)
- [国际化](zh-cn/i18n.md)
- [布局](zh-cn/layout.md)
- [http 请求](zh-cn/request.md)
- 指南
- [部署](zh-cn/deploy.md)
- [更新日志](zh-cn/change-log.md)
+52
View File
@@ -0,0 +1,52 @@
## 5.0.0
#### 优化
- 尽量使用修饰器,简化代码编写,提高代码可读性。
- API 配置化,简化获取数据方式。
- `utils` 内文件拆分,各司其职。
- 简化`utils/request`文件,不做特殊处理。
#### 规范
- 函数添加描述、参数、返回值等注释,含糊不清的代码增加注释,规范参考 [Google JavaScript Style Guide](https://google.github.io/styleguide/jsguide.html#appendices-jsdoc-tag-reference)。
- 语义化版本号,规范参加 [语义化版本 2.0.0](https://semver.org/lang/zh-CN/)。
- 静态代码检查,统一代码风格,代码提交前将会使用 `prettier`、`stylelint`、`eslint` 规范代码。
- Git 提交信息规范化,[git-commit-emoji-cn](https://github.com/liuchengxu/git-commit-emoji-cn)。
- 基于 `Umi` 的约定式路由,无需再写路由配置文件。
- 使用 `React 16` 新特性,如 `Fragment`、`Context`、 `PureComponent`等。
#### 功能
- 支持国际化,源码中抽离翻译字段,按需加载语言包,自动在线翻译。
- 支持按需引入 `lodash` 函数。
- 支持多布局,可根据规则规定哪些路由使用哪种布局。
- 支持 Antd Admin 在 Travis 上自动编译和部署。
- 使用 `Docsify` 生成文档网站。
#### 样式
- 新增 Antd Admin 独立 Logo。
- 重写整体布局组件,优化菜单、面包屑导航自动高亮,菜单自动展开等逻辑。
- 移动端菜单更改为抽屉式。
#### 其他
- 废弃 `IconFont`、 `Search`、`DataTable`等组件,因为在 `Antd` 中有很好的支持和可替代的。
+33
View File
@@ -0,0 +1,33 @@
# 配置项
你可以在 `/src/utils/config.js` 里做一些自定义配置:
## siteName
- 类型: `String`
配置站点名称,应用到登录框,侧边栏顶部的标题文字显示。
## copyright
- 类型: `String`
配置版权声明,应用到登录页、`Primay`布局底部。
## logoPath
- 类型: `String`
配置站点 Logo,应用到登录框,侧边栏顶部的 Logo 显示。
## apiPrefix
- 类型: `String`
配置项目中接口的前缀,接口相关文档可查看 [接口配置](API-configuration.md)
## fixedHeader
- 类型: `String`
在`Primary`布局下,页面滚动时是否固定顶部。
+114
View File
@@ -0,0 +1,114 @@
# 部署
完成开发并且在开发环境验证之后,就需要部署给我们的用户了。
![i18n](../_media/term_build.svg)
## 构建
先执行下面的命令,
```bash
npm run build
```
几秒后,输出应该如下:
```bash
> antd-admin@5.0.0-beta build /Users/zuiidea/web/antd-admin
> umi build
[21:13:17] webpack compiled in 43s 868ms
DONE Compiled successfully in 43877ms 21:13:17
File sizes after gzip:
1.3 MB dist/vendors.async.js
308.21 KB dist/umi.js
45.49 KB dist/vendors.chunk.css
36.08 KB dist/p__chart__highCharts__index.async.js
33.53 KB dist/p__user__index.async.js
22.36 KB dist/p__chart__ECharts__index.async.js
4.21 KB dist/p__dashboard__index.async.js
4.06 KB dist/umi.css
...
```
`build` 命令会打包所有的资源,包含 JavaScript, CSS, web fonts, images, html 等。你可以在 `dist/` 目录下找到这些文件。
> 如果有使用 HashHistory 、 部署 html 到非根目录、静态化等需求,请查看[Umi 部署](https://umijs.org/zh/guide/deploy.html)。
## 本地验证
发布之前,可以通过 `serve` 做本地验证,
```
$ yarn global add serve
$ serve ./dist
Serving!
- Local: http://localhost:5000
- On Your Network: http://{Your IP}:5000
Copied local address to clipboard!
```
访问 [http://localhost:5000](http://localhost:5000),正常情况下法应该是和 `npm start` 一致的(接口可能无法获取到正确数据)。
## 部署
接下来,我们可以把静态文件上传到服务器,如果使用 Nginx 作为 Web server,你可以在 `ngnix.conf` 中这样配置:
```
server
{
listen 80;
# 指定可访问的域名
server_name antd-admin.zuiidea.com;
# 编译后的文件存放的目录
root /home/www/antd-admin/dist;
# 代理服务端接口,避免跨域
location /api {
proxy_pass http://localhost:7000/api;
}
# 因为前端使用了BrowserHistory,所以将路由 fallback 到 index.html
location / {
index index.html;
try_files $uri $uri/ /index.html;
}
}
```
重启 Web server,访问 [http://antd-admin.zuiidea.com](http://antd-admin.zuiidea.com) ,你将看到正确的页面。
```bash
nginx -s reload
```
类似的,如果你使用 Caddy 作为 Web server,你可以在 `Caddyfile` 中这样配置:
```
antd-admin.zuiidea.com {
gzip
root /home/www/antd-admin/dist
proxy /api http://localhost:7000
rewrite {
if {path} not_match ^/api
to {path} {path}/ /
}
}
antd-admin.zuiidea.com/public {
gzip
root /home/www/antd-admin/dist/static/public
}
```
+7
View File
@@ -0,0 +1,7 @@
# 问题集锦
## 新建页面
1. 直接从/src/pages复制一个page (会自动创建路由[umi](https://umijs.org/zh/guide/router.html#%E7%BA%A6%E5%AE%9A%E5%BC%8F%E8%B7%AF%E7%94%B1))
2. 修改 namespace/pathToRegexp 在 model.js
3. 修改 mock中route.js增加一条route
+69
View File
@@ -0,0 +1,69 @@
# 快速上手
> 在开始之前,推荐先学习 [React](http://facebook.github.io/react/) 、 [ES2015+](http://es6.ruanyifeng.com/) 、 [Antd Design](https://ant.design/docs/react/introduce-cn) , 了解 [UmiJS](https://umijs.org/) 、[Dva](http://github.com/dvajs/dva) ,并正确安装和配置了 [Node.js](https://nodejs.org/) v8 或以上 、[Git](https://git-scm.com/)。提前了解和学习这些知识会非常有帮助。
## 安装
```bash
git clone https://github.com/zuiidea/antd-admin.git my-project
cd my-project
```
1. 克隆项目并安装依赖(推荐使用 `pnpm`)。
```bash
git clone https://github.com/zuiidea/antd-admin.git my-project
cd my-project
pnpm install
```
或使用其它包管理器:
```bash
npm install
# 或
yarn install
```
2. 启动开发模式:
```bash
npm run dev
```
3. 启动完成后在浏览器打开项目(查看开发服务器输出以获取实际 URL/端口)。
│ │ ├── index.js # 工具函数
│ │ ├── request.js # 异步请求函数(axios)
│ │ └── theme.js # 项目需要在js中使用到样式变量
├── .editorconfig # 编辑器配置
├── .env # 环境变量
├── .eslintrc # ESlint配置
├── .gitignore # Git忽略文件配置
├── .prettierignore # Prettier忽略文件配置
├── .prettierrc # Prettier配置
├── .stylelintrc.json # Stylelint配置
├── .travis.yml # Travis配置
└── .umirc.js # Umi配置
└── package.json # 项目信息
```
## 本地开发
项目推荐使用 `pnpm` 进行依赖管理:
```bash
pnpm install
npm run dev
```
也可以使用 `npm` 或 `yarn`:
```bash
npm install
# 或
yarn install
# 然后使用对应的启动命令,例如 `npm run dev` 或 `yarn dev`(若 package.json 中配置了),
# 本仓库默认开发脚本为 `npm run dev`。
```
启动后在浏览器打开项目(查看开发服务器输出以获取实际 URL/端口)。
+123
View File
@@ -0,0 +1,123 @@
# 国际化(i18n)使用说明
本项目通过 Umi 的 `plugin-locale`(基于 `react-intl`)管理多语言,翻译资源位于 `src/locales`(例如 `en-US.json`、`zh-CN.json`)。下面说明如何:新增语言、增加翻译条目、切换语言与关闭多语言。示例以新增日语 `ja-JP` 为例。
## 1. 新增一种语言(长期支持)
1. 在 `src/locales/` 下创建新的翻译文件,文件名为语言标识,例如:`src/locales/ja-JP.json`。
2. 文件内容为 JSON 格式的翻译对象(可嵌套):
```json
{
"welcome": "ようこそ",
"login": {
"username": "ユーザー名",
"password": "パスワード",
"submit": "ログイン"
}
}
```
3. 若希望 Ant Design 组件也使用对应的本地化(日期/组件文案),在 `src/app.tsx` 的 `pick` 函数中添加对应的 AntD locale 引入与映射,例如:
```ts
import jaJP from 'antd/locale/ja_JP';
// ...
if (l === 'ja-JP') return jaJP;
```
4. 在语言选择列表(例如 `src/components/TopbarControls.tsx` 的 `localeMenuItems`)中加入新语言项:
```ts
{ key: 'ja-JP', label: '日本語' }
```
5. 重启开发服务器:
```bash
pnpm run dev
```
Umi 会在构建时将 `src/locales` 下的文件编入 `localeInfo`,页面即可使用新语言。
提示:如不想重启或想动态注册翻译,可使用运行时 API `addLocale(name, messages, extraLocales)`(见下一节)。
## 2. 增加一条多语言文本(翻译条目)
1. 在所有语言的 JSON 文件中添加相同的 id(推荐同时维护 `en-US.json` 与 `zh-CN.json`,新语言也应添加):
`src/locales/en-US.json`
```json
"my.feature.greeting": "Hello from feature"
```
`src/locales/zh-CN.json`
```json
"my.feature.greeting": "来自功能的问候"
```
2. 在组件中使用 `useIntl()` 获取 `intl`,并调用 `formatMessage`:
```ts
import { useIntl } from 'umi';
const intl = useIntl();
const text = intl.formatMessage({ id: 'my.feature.greeting', defaultMessage: 'Hello' });
```
建议使用 `useIntl()`(或 `injectIntl`)以保证语言切换时组件可自动刷新并显示新文本。
## 3. 运行时切换或注册语言
- 切换语言(会写入 `localStorage` 并触发刷新或事件):
```ts
import { setLocale } from 'umi';
// 切换并刷新页面
setLocale('ja-JP', true);
// 切换但不刷新(触发事件更新)
setLocale('zh-CN', false);
```
- 运行时注册(无需重启):
```ts
import { addLocale, setLocale } from 'umi';
import jaMessages from '@/locales/ja-JP.json';
import jaAntd from 'antd/locale/ja_JP';
addLocale('ja-JP', jaMessages, { antd: jaAntd, momentLocale: 'ja' });
setLocale('ja-JP', false);
```
`addLocale` 会把翻译合并到内部 `localeInfo`,并可同时提供 AntD 与(可选的)moment 本地化配置。
## 4. 关闭多语言(禁用 i18n)
若想永久关闭多语言功能:
1. 在 `src/app.tsx` 的 `LocaleWrapper` 中,直接返回固定的 AntD locale(忽略 `localStorage` 中的 `umi_locale`):
```ts
const pick = (l: string | null) => {
return zhCN; // 强制使用中文
};
```
2. 移除或隐藏语言切换控件(例如删除 `src/components/TopbarControls.tsx` 中的语言菜单项或 Dropdown)。
3. 可选:删除 `src/locales` 中其它语言文件,仅保留目标语言文件以减少构建体积。
如果只是临时禁止用户切换,建议仅执行第 2 步(隐藏切换),以便未来快速恢复多语言支持。
## 5. 调试与常见问题
- 新增语言后无显示:确认已重启 dev server(或使用 `addLocale` 动态注册),并在 `app.tsx` 中为该语言提供 AntD locale。
- 翻译未生效或缺失:检查 `src/locales/*.json` 是否包含对应 id,且 `formatMessage` 中的 id 拼写正确。
- 想自动抽取翻译 id:仓库未内置抽取脚本,建议按需集成 `lingui`、`babel-plugin-react-intl` 或其他工具并在 `package.json` 中添加相应脚本。
如果你需要,我可以:
- 为你创建一个 `src/locales/ja-JP.json` 的初始翻译并更新 `TopbarControls` 与 `app.tsx` 映射;或
- 添加一个示例组件,演示如何在运行时通过 `addLocale` 注册新语言。请告诉我你更希望我执行哪项。
+60
View File
@@ -0,0 +1,60 @@
# 布局
## 新增布局
以新增名为 `secondary` 的布局为例,使以 `secondary` 开头的路由都使用该布局。
1. 在 `src/utils/config.js` 新增相关配置,参数详细请查看 [layouts](/zh-cn/configuration?id=layouts)。
```javascript
layouts: [
{
name: 'primary',
include: [/.*/],
exclude: [/(\/(en|zh))*\/login/, /(\/(en|zh))*\/secondary\/(.*)/],
},
{
name: 'secondary',
include: [/(\/(en|zh))*\/secondary\/(.*)/],
},
],
```
2. 在`src/layouts/BaseLayout.js` 文件中新增 `secondary` 布局组件。
```javascript
import SecondaryLayout from './SecondaryLayout'
const LayoutMap = {
primary: PrimaryLayout,
public: PublicLayout,
secondary: SecondaryLayout,
}
```
3. 在`src/layouts/` 目录中新增 `SecondaryLayout.js` 文件。
```javascript
import React from 'react'
export default ({ children }) => {
return (
<div>
<h1>Secondary</h1>
{children}
</div>
)
}
```
4. 在`src/pages/` 目录中新增 `secondary/index.js` 文件。
```javascript
import React from 'react'
export default ({ children }) => {
return <div>Secondary page Content</div>
}
```
5. 最后,使用 `npm run dev` 启动开发模式,然后在浏览器中打开该布局页面(查看开发服务器输出以获取实际 URL),例如 `/secondary/`。
+33
View File
@@ -0,0 +1,33 @@
# HTTP 请求
本项目使用位于 `src/utils/request.ts` 的轻量封装(基于 `fetch`),默认导出为 `api`。该封装负责:
- 将 `config.apiPrefix` 与请求 `path` 拼接为最终 URL。
- 处理 `params`(查询字符串)与 `body`(JSON 或 FormData)。
- 在本地有 token 时自动注入 `Authorization` 头(本项目使用 localStorage 键 `app-auth-token`)。
- 统一解析后端返回(后端需遵循 `{ success, message, data }` 约定)并在非成功时抛出错误并显示 UI 提示(使用 `antd` 的 `message`)。
主要行为说明
- `api(path, options)` 会把 `config.apiPrefix` 与 `path` 拼接。
- 当传入 `options.params` 时,会序列化为查询字符串并追加到 URL。
- `options.body` 的处理策略:
- 若为 FormData,直接发送(不要手动设置 Content-Type)。
- 若为字符串或 Blob,直接发送。
- 其余对象会被 `JSON.stringify`,默认设置 `Content-Type: application/json`(除非已在 headers 中指定)。
- 若 localStorage 中有 token 且未在 headers 中显式提供 Authorization,将自动设置 `Authorization: Bearer <token>`。
- 成功响应返回后端 `data` 字段;响应格式不符合约定或后端返回失败时会抛出异常。
使用示例(TypeScript):
```ts
import api from '@/utils/request';
// 带查询参数的 GET
const page = await api('/users', { method: 'GET', params: { page: 1, pageSize: 10 } });
// 发送 JSON 请求体的 POST
const created = await api('/user', { method: 'POST', body: { name: 'Alice' } });
```
详细实现请参阅 `src/utils/request.ts`,文档中仅列出使用建议与约定。
+5
View File
@@ -0,0 +1,5 @@
# 路由
本项目中采用约定式路由
参考[umi 路由](https://umijs.org/zh/guide/router.html)