├── .env
├── public
├── CNAME
├── favicon.ico
├── images
│ ├── cat.jpeg
│ └── loading.gif
├── icons
│ ├── icon-128x128.png
│ ├── icon-192x192.png
│ └── icon-512x512.png
├── pro_icon.svg
└── logo.svg
├── .eslintignore
├── src
├── pages
│ ├── form
│ │ ├── detail
│ │ │ ├── index.less
│ │ │ └── index.tsx
│ │ ├── debounce
│ │ │ └── index.tsx
│ │ ├── detail2
│ │ │ └── index.tsx
│ │ └── upload
│ │ │ └── index.tsx
│ ├── Welcome.less
│ ├── project
│ │ ├── components
│ │ │ ├── seconed.tsx
│ │ │ ├── three.tsx
│ │ │ └── four.tsx
│ │ └── index.tsx
│ ├── 404.tsx
│ ├── dataManage
│ │ ├── useModel
│ │ │ ├── componenets
│ │ │ │ ├── page3.tsx
│ │ │ │ ├── page2.tsx
│ │ │ │ └── page1.tsx
│ │ │ └── index.tsx
│ │ ├── initialstate
│ │ │ ├── index.tsx
│ │ │ └── componenets
│ │ │ │ ├── page3.tsx
│ │ │ │ ├── page2.tsx
│ │ │ │ └── page1.tsx
│ │ └── project
│ │ │ ├── components
│ │ │ ├── seconed.tsx
│ │ │ ├── three.tsx
│ │ │ └── four.tsx
│ │ │ └── index.tsx
│ ├── product
│ │ ├── list
│ │ │ └── components
│ │ │ │ └── productModal.tsx
│ │ └── addProduct
│ │ │ └── index.tsx
│ ├── Admin.tsx
│ ├── editor
│ │ ├── add
│ │ │ └── index.tsx
│ │ └── list
│ │ │ └── index.tsx
│ ├── Welcome.tsx
│ └── user
│ │ └── Login
│ │ └── index.less
├── locales
│ ├── zh-CN
│ │ ├── component.ts
│ │ ├── pwa.ts
│ │ ├── globalHeader.ts
│ │ ├── settingDrawer.ts
│ │ ├── menu.ts
│ │ ├── settings.ts
│ │ └── pages.ts
│ ├── zh-TW
│ │ ├── component.ts
│ │ ├── pwa.ts
│ │ ├── globalHeader.ts
│ │ ├── settingDrawer.ts
│ │ ├── menu.ts
│ │ └── settings.ts
│ ├── fa-IR
│ │ ├── component.ts
│ │ ├── pwa.ts
│ │ ├── globalHeader.ts
│ │ ├── settingDrawer.ts
│ │ ├── menu.ts
│ │ ├── settings.ts
│ │ └── pages.ts
│ ├── ja-JP
│ │ ├── component.ts
│ │ ├── pwa.ts
│ │ ├── globalHeader.ts
│ │ ├── settingDrawer.ts
│ │ ├── menu.ts
│ │ ├── settings.ts
│ │ └── pages.ts
│ ├── en-US
│ │ ├── component.ts
│ │ ├── pwa.ts
│ │ ├── globalHeader.ts
│ │ ├── settingDrawer.ts
│ │ ├── menu.ts
│ │ └── settings.ts
│ ├── id-ID
│ │ ├── component.ts
│ │ ├── pwa.ts
│ │ ├── globalHeader.ts
│ │ ├── settingDrawer.ts
│ │ ├── menu.ts
│ │ ├── settings.ts
│ │ └── pages.ts
│ ├── pt-BR
│ │ ├── component.ts
│ │ ├── pwa.ts
│ │ ├── globalHeader.ts
│ │ ├── settingDrawer.ts
│ │ ├── menu.ts
│ │ └── settings.ts
│ ├── zh-TW.ts
│ ├── pt-BR.ts
│ ├── ja-JP.ts
│ ├── zh-CN.ts
│ ├── fa-IR.ts
│ ├── id-ID.ts
│ └── en-US.ts
├── services
│ ├── ant-design-pro
│ │ ├── index.ts
│ │ ├── article.ts
│ │ ├── login.ts
│ │ ├── api.ts
│ │ └── typings.d.ts
│ └── swagger
│ │ ├── index.ts
│ │ ├── typings.d.ts
│ │ ├── store.ts
│ │ └── user.ts
├── access.ts
├── components
│ ├── HeaderDropdown
│ │ ├── index.less
│ │ └── index.tsx
│ ├── HeaderSearch
│ │ ├── index.less
│ │ └── index.tsx
│ ├── NoticeIcon
│ │ ├── index.less
│ │ ├── NoticeList.less
│ │ └── NoticeList.tsx
│ ├── Footer
│ │ └── index.tsx
│ ├── RightContent
│ │ ├── index.less
│ │ ├── index.tsx
│ │ └── AvatarDropdown.tsx
│ ├── debounce
│ │ └── index.tsx
│ ├── ComUpload
│ │ └── index.tsx
│ └── ProductInfo
│ │ └── index.tsx
├── models
│ ├── user.ts
│ └── product.ts
├── manifest.json
├── typings.d.ts
├── global.less
├── e2e
│ └── baseLayout.e2e.js
├── service-worker.js
└── global.tsx
├── .prettierrc.js
├── .stylelintrc.js
├── .gitpod.yml
├── mock
├── route.ts
├── form.ts
├── editor.ts
└── notices.ts
├── jsconfig.json
├── tests
├── setupTests.js
├── PuppeteerEnvironment.js
├── getBrowser.js
├── beforeTest.js
└── run-tests.js
├── Dockerfile
├── README.md
├── Dockerfile.dev
├── .eslintrc.js
├── .editorconfig
├── jest.config.js
├── .prettierignore
├── .github
├── workflows
│ ├── emoji-helper.yml
│ ├── rebase.yml
│ ├── preview-start.yml
│ ├── deploy.yml
│ ├── ci.yml
│ ├── preview-build.yml
│ ├── issue-open-check.yml
│ └── preview-deploy.yml
├── ISSUE_TEMPLATE
│ ├── question.md
│ ├── feature_request.md
│ └── bug_report.md
└── FUNDING.yml
├── docker
├── docker-compose.dev.yml
├── docker-compose.yml
└── nginx.conf
├── config
├── config.dev.ts
├── defaultSettings.ts
├── proxy.ts
└── config.ts
├── Dockerfile.hub
├── .dockerignore
├── .gitignore
├── LICENSE
├── tsconfig.json
└── CODE_OF_CONDUCT.md
/.env:
--------------------------------------------------------------------------------
1 | PORT=8091
--------------------------------------------------------------------------------
/public/CNAME:
--------------------------------------------------------------------------------
1 | preview.pro.ant.design
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shengbid/antpro-child/main/public/favicon.ico
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | /lambda/
2 | /scripts
3 | /config
4 | .history
5 | public
6 | dist
7 | .umi
8 | mock
--------------------------------------------------------------------------------
/public/images/cat.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shengbid/antpro-child/main/public/images/cat.jpeg
--------------------------------------------------------------------------------
/public/images/loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shengbid/antpro-child/main/public/images/loading.gif
--------------------------------------------------------------------------------
/public/icons/icon-128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shengbid/antpro-child/main/public/icons/icon-128x128.png
--------------------------------------------------------------------------------
/public/icons/icon-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shengbid/antpro-child/main/public/icons/icon-192x192.png
--------------------------------------------------------------------------------
/public/icons/icon-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shengbid/antpro-child/main/public/icons/icon-512x512.png
--------------------------------------------------------------------------------
/src/pages/form/detail/index.less:
--------------------------------------------------------------------------------
1 | .back {
2 | height: 100px;
3 | background-color: var(--chid-primary-color);
4 | }
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | const fabric = require('@umijs/fabric');
2 |
3 | module.exports = {
4 | ...fabric.prettier,
5 | };
6 |
--------------------------------------------------------------------------------
/.stylelintrc.js:
--------------------------------------------------------------------------------
1 | const fabric = require('@umijs/fabric');
2 |
3 | module.exports = {
4 | ...fabric.stylelint,
5 | };
6 |
--------------------------------------------------------------------------------
/.gitpod.yml:
--------------------------------------------------------------------------------
1 | ports:
2 | - port: 8000
3 | onOpen: open-preview
4 | tasks:
5 | - init: npm install
6 | command: npm start
7 |
--------------------------------------------------------------------------------
/mock/route.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | '/api/auth_routes': {
3 | '/form/advanced-form': { authority: ['admin', 'user'] },
4 | },
5 | };
6 |
--------------------------------------------------------------------------------
/src/locales/zh-CN/component.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'component.tagSelect.expand': '展开',
3 | 'component.tagSelect.collapse': '收起',
4 | 'component.tagSelect.all': '全部',
5 | };
6 |
--------------------------------------------------------------------------------
/src/locales/zh-TW/component.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'component.tagSelect.expand': '展開',
3 | 'component.tagSelect.collapse': '收起',
4 | 'component.tagSelect.all': '全部',
5 | };
6 |
--------------------------------------------------------------------------------
/src/locales/fa-IR/component.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'component.tagSelect.expand': 'باز',
3 | 'component.tagSelect.collapse': 'بسته ',
4 | 'component.tagSelect.all': 'همه',
5 | };
6 |
--------------------------------------------------------------------------------
/src/locales/ja-JP/component.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'component.tagSelect.expand': '展開',
3 | 'component.tagSelect.collapse': '折りたたむ',
4 | 'component.tagSelect.all': 'すべて',
5 | };
6 |
--------------------------------------------------------------------------------
/src/locales/en-US/component.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'component.tagSelect.expand': 'Expand',
3 | 'component.tagSelect.collapse': 'Collapse',
4 | 'component.tagSelect.all': 'All',
5 | };
6 |
--------------------------------------------------------------------------------
/src/locales/id-ID/component.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'component.tagSelect.expand': 'Perluas',
3 | 'component.tagSelect.collapse': 'Lipat',
4 | 'component.tagSelect.all': 'Semua',
5 | };
6 |
--------------------------------------------------------------------------------
/src/locales/pt-BR/component.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'component.tagSelect.expand': 'Expandir',
3 | 'component.tagSelect.collapse': 'Diminuir',
4 | 'component.tagSelect.all': 'Todas',
5 | };
6 |
--------------------------------------------------------------------------------
/src/pages/Welcome.less:
--------------------------------------------------------------------------------
1 | @import '~antd/lib/style/themes/default.less';
2 |
3 | .pre {
4 | margin: 12px 0;
5 | padding: 12px 20px;
6 | background: @input-bg;
7 | box-shadow: @card-shadow;
8 | }
9 |
--------------------------------------------------------------------------------
/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "emitDecoratorMetadata": true,
4 | "experimentalDecorators": true,
5 | "baseUrl": ".",
6 | "paths": {
7 | "@/*": ["./src/*"]
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/locales/zh-CN/pwa.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'app.pwa.offline': '当前处于离线状态',
3 | 'app.pwa.serviceworker.updated': '有新内容',
4 | 'app.pwa.serviceworker.updated.hint': '请点击“刷新”按钮或者手动刷新页面',
5 | 'app.pwa.serviceworker.updated.ok': '刷新',
6 | };
7 |
--------------------------------------------------------------------------------
/src/locales/zh-TW/pwa.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'app.pwa.offline': '當前處於離線狀態',
3 | 'app.pwa.serviceworker.updated': '有新內容',
4 | 'app.pwa.serviceworker.updated.hint': '請點擊“刷新”按鈕或者手動刷新頁面',
5 | 'app.pwa.serviceworker.updated.ok': '刷新',
6 | };
7 |
--------------------------------------------------------------------------------
/tests/setupTests.js:
--------------------------------------------------------------------------------
1 | // do some test init
2 |
3 | const localStorageMock = {
4 | getItem: jest.fn(),
5 | setItem: jest.fn(),
6 | removeItem: jest.fn(),
7 | clear: jest.fn(),
8 | };
9 |
10 | global.localStorage = localStorageMock;
11 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM circleci/node:latest-browsers
2 |
3 | WORKDIR /usr/src/app/
4 | USER root
5 | COPY package.json ./
6 | RUN yarn
7 |
8 | COPY ./ ./
9 |
10 | RUN npm run test:all
11 |
12 | RUN npm run fetch:blocks
13 |
14 | CMD ["npm", "run", "build"]
15 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## qiankun微服务ant-pro项目主应用
2 |
3 | 项目是下载的ant-design-pro
4 | 需要同时下载主应用运行https://github.com/shengbid/antpro-parent
5 |
6 | 使用方法参考博客https://www.cnblogs.com/steamed-twisted-roll/p/15697081.html
7 |
8 |
9 | ## 运行
10 | 1. yarn
11 |
12 | 2. yarn start
--------------------------------------------------------------------------------
/Dockerfile.dev:
--------------------------------------------------------------------------------
1 | FROM node:latest
2 |
3 | WORKDIR /usr/src/app/
4 |
5 | COPY package.json ./
6 | RUN npm install --silent --no-cache --registry=https://registry.npm.taobao.org
7 |
8 | COPY ./ ./
9 |
10 | RUN npm run fetch:blocks
11 |
12 | CMD ["npm", "run", "start"]
13 |
--------------------------------------------------------------------------------
/src/services/ant-design-pro/index.ts:
--------------------------------------------------------------------------------
1 | // @ts-ignore
2 | /* eslint-disable */
3 | // API 更新时间:
4 | // API 唯一标识:
5 | import * as api from './api';
6 | import * as login from './login';
7 | export * from './article';
8 | export default {
9 | api,
10 | login,
11 | };
12 |
--------------------------------------------------------------------------------
/src/locales/ja-JP/pwa.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'app.pwa.offline': 'あなたは今オフラインです',
3 | 'app.pwa.serviceworker.updated': '新しいコンテンツが利用可能です',
4 | 'app.pwa.serviceworker.updated.hint':
5 | '現在のページをリロードするには、「更新」ボタンを押してください',
6 | 'app.pwa.serviceworker.updated.ok': 'リフレッシュ',
7 | };
8 |
--------------------------------------------------------------------------------
/src/services/swagger/index.ts:
--------------------------------------------------------------------------------
1 | // @ts-ignore
2 | /* eslint-disable */
3 | // API 更新时间:
4 | // API 唯一标识:
5 | import * as pet from './pet';
6 | import * as store from './store';
7 | import * as user from './user';
8 | export default {
9 | pet,
10 | store,
11 | user,
12 | };
13 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: [require.resolve('@umijs/fabric/dist/eslint')],
3 | globals: {
4 | ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION: true,
5 | page: true,
6 | REACT_APP_ENV: true,
7 | },
8 | rules: {
9 | 'no-console': 'off'
10 | }
11 | };
12 |
--------------------------------------------------------------------------------
/src/locales/en-US/pwa.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'app.pwa.offline': 'You are offline now',
3 | 'app.pwa.serviceworker.updated': 'New content is available',
4 | 'app.pwa.serviceworker.updated.hint': 'Please press the "Refresh" button to reload current page',
5 | 'app.pwa.serviceworker.updated.ok': 'Refresh',
6 | };
7 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
12 | [*.md]
13 | trim_trailing_whitespace = false
14 |
15 | [Makefile]
16 | indent_style = tab
17 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | testURL: 'http://localhost:8000',
3 | testEnvironment: './tests/PuppeteerEnvironment',
4 | verbose: false,
5 | extraSetupFiles: ['./tests/setupTests.js'],
6 | globals: {
7 | ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION: false,
8 | localStorage: null,
9 | },
10 | };
11 |
--------------------------------------------------------------------------------
/src/access.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @see https://umijs.org/zh-CN/plugins/plugin-access
3 | * */
4 | export default function access(initialState: { currentUser?: API.CurrentUser | undefined }) {
5 | const { currentUser } = initialState || {};
6 | return {
7 | canAdmin: currentUser && currentUser.access === 'admin',
8 | };
9 | }
10 |
--------------------------------------------------------------------------------
/src/locales/fa-IR/pwa.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'app.pwa.offline': 'شما اکنون آفلاین هستید',
3 | 'app.pwa.serviceworker.updated': 'مطالب جدید در دسترس است',
4 | 'app.pwa.serviceworker.updated.hint':
5 | 'لطفاً برای بارگیری مجدد صفحه فعلی ، دکمه "تازه سازی" را فشار دهید',
6 | 'app.pwa.serviceworker.updated.ok': 'تازه سازی',
7 | };
8 |
--------------------------------------------------------------------------------
/src/locales/id-ID/pwa.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'app.pwa.offline': 'Koneksi anda terputus',
3 | 'app.pwa.serviceworker.updated': 'Konten baru sudah tersedia',
4 | 'app.pwa.serviceworker.updated.hint':
5 | 'Silahkan klik tombol "Refresh" untuk memuat ulang halaman ini',
6 | 'app.pwa.serviceworker.updated.ok': 'Memuat ulang',
7 | };
8 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | **/*.svg
2 | package.json
3 | .umi
4 | .umi-production
5 | /dist
6 | .dockerignore
7 | .DS_Store
8 | .eslintignore
9 | *.png
10 | *.toml
11 | docker
12 | .editorconfig
13 | Dockerfile*
14 | .gitignore
15 | .prettierignore
16 | LICENSE
17 | .eslintcache
18 | *.lock
19 | yarn-error.log
20 | .history
21 | CNAME
22 | /build
23 | /public
--------------------------------------------------------------------------------
/src/locales/pt-BR/pwa.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'app.pwa.offline': 'Você está offline agora',
3 | 'app.pwa.serviceworker.updated': 'Novo conteúdo está disponível',
4 | 'app.pwa.serviceworker.updated.hint':
5 | 'Por favor, pressione o botão "Atualizar" para recarregar a página atual',
6 | 'app.pwa.serviceworker.updated.ok': 'Atualizar',
7 | };
8 |
--------------------------------------------------------------------------------
/.github/workflows/emoji-helper.yml:
--------------------------------------------------------------------------------
1 | name: Emoji Helper
2 |
3 | on:
4 | release:
5 | types: [published]
6 |
7 | jobs:
8 | emoji:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions-cool/emoji-helper@v1.0.0
12 | with:
13 | type: 'release'
14 | emoji: '+1, laugh, heart, hooray, rocket, eyes'
15 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/question.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: '疑问或需要帮助 ❓'
3 | about: 对 Ant Design Pro 使用的疑问或需要帮助
4 | title: '🧐[问题]'
5 | labels: '🧐question'
6 | assignees: ''
7 | ---
8 |
9 | ### 🧐 问题描述
10 |
11 |
14 |
15 | ### 💻 示例代码
16 |
17 |
20 |
21 | ### 🚑 其他信息
22 |
23 |
26 |
--------------------------------------------------------------------------------
/src/pages/project/components/seconed.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import Project3 from './three'
3 |
4 | const Project2: React.Fc = (props) => {
5 |
6 | return
7 | 项目第二层组件
8 |
{
9 | // console.log(2,name)
10 | props.onSuccess(name)
11 | }}>
12 |
13 | }
14 |
15 | export default Project2
--------------------------------------------------------------------------------
/src/pages/project/components/three.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import Project4 from './four'
3 |
4 | const Project3: React.Fc = (props: {onSuccess: (name: string) => void}) => {
5 |
6 | return
7 | 项目第三层组件
8 |
{
9 | props.onSuccess(name)
10 | }}>
11 |
12 | }
13 |
14 | export default Project3
--------------------------------------------------------------------------------
/docker/docker-compose.dev.yml:
--------------------------------------------------------------------------------
1 | version: '3.5'
2 |
3 | services:
4 | ant-design-pro_dev:
5 | ports:
6 | - 8000:8000
7 | build:
8 | context: ../
9 | dockerfile: Dockerfile.dev
10 | container_name: 'ant-design-pro_dev'
11 | volumes:
12 | - ../src:/usr/src/app/src
13 | - ../config:/usr/src/app/config
14 | - ../mock:/usr/src/app/mock
15 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: '功能需求 ✨'
3 | about: 对 Ant Design Pro 的需求或建议
4 | title: '👑 [需求]'
5 | labels: '👑Feature Request'
6 | assignees: ''
7 | ---
8 |
9 | ### 🥰 需求描述
10 |
11 |
14 |
15 | ### 🧐 解决方案
16 |
17 |
20 |
21 | ### 🚑 其他信息
22 |
23 |
26 |
--------------------------------------------------------------------------------
/src/components/HeaderDropdown/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .container > * {
4 | background-color: @popover-bg;
5 | border-radius: 4px;
6 | box-shadow: @shadow-1-down;
7 | }
8 |
9 | @media screen and (max-width: @screen-xs) {
10 | .container {
11 | width: 100% !important;
12 | }
13 | .container > * {
14 | border-radius: 0 !important;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/pages/form/debounce/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import DebounceSelect from '@/components/debounce';
3 | import { Card } from 'antd'
4 |
5 | const Demo: React.FC = () => {
6 |
7 | return (
8 |
9 |
延迟搜索select
10 |
11 |
13 |
14 |
15 | );
16 | };
17 |
18 | export default Demo
--------------------------------------------------------------------------------
/src/services/ant-design-pro/article.ts:
--------------------------------------------------------------------------------
1 | import { request } from 'umi';
2 | import type { articleProps } from 'mock/editor'
3 |
4 | /** 获取文章列表 */
5 | export async function getArticleList() {
6 | return request('/api/article/list', {
7 | method: 'POST',
8 | });
9 | }
10 | /** 新增文章列表 */
11 | export async function addArticle(data: articleProps) {
12 | return request('/api/article/add', {
13 | method: 'POST',
14 | data
15 | });
16 | }
--------------------------------------------------------------------------------
/src/models/user.ts:
--------------------------------------------------------------------------------
1 | export interface stateProp {
2 | userName: string
3 | }
4 |
5 | const userModel = {
6 | namespace: 'user',
7 | state: {
8 | useInfo: {
9 | userName: '李明',
10 | age: 18
11 | }
12 | },
13 | reducers: {
14 | changeState: (state: stateProp, { payload: values }: {payload: any}) => {
15 | return {
16 | useInfo: values
17 | }
18 | },
19 | },
20 | }
21 |
22 | export default userModel
--------------------------------------------------------------------------------
/config/config.dev.ts:
--------------------------------------------------------------------------------
1 | // https://umijs.org/config/
2 | import { defineConfig } from 'umi';
3 |
4 | export default defineConfig({
5 | plugins: [
6 | // https://github.com/zthxxx/react-dev-inspector
7 | 'react-dev-inspector/plugins/umi/react-inspector',
8 | ],
9 | // https://github.com/zthxxx/react-dev-inspector#inspector-loader-props
10 | inspectorConfig: {
11 | exclude: [],
12 | babelPlugins: [],
13 | babelOptions: {},
14 | },
15 | });
16 |
--------------------------------------------------------------------------------
/src/pages/404.tsx:
--------------------------------------------------------------------------------
1 | import { Button, Result } from 'antd';
2 | import React from 'react';
3 | import { history } from 'umi';
4 |
5 | const NoFoundPage: React.FC = () => (
6 | history.push('/')}>
12 | Back Home
13 |
14 | }
15 | />
16 | );
17 |
18 | export default NoFoundPage;
19 |
--------------------------------------------------------------------------------
/mock/form.ts:
--------------------------------------------------------------------------------
1 | import { Request, Response } from 'express';
2 | import Mock from 'mockjs'
3 | const Random = Mock.Random
4 |
5 | const uploadData = (req: Request, res: Response) => {
6 | const color = Random.color()
7 | const text = Random.word(4, 10)
8 |
9 | res.send({
10 | data: {
11 | fileUrl: Random.image('400x300', color, '#FFF', text)
12 | },
13 | success: true
14 | })
15 | }
16 |
17 | export default {
18 | 'POST /api/upload/file': uploadData,
19 | };
20 |
--------------------------------------------------------------------------------
/docker/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.5'
2 |
3 | services:
4 | ant-design-pro_build:
5 | build: ../
6 | container_name: 'ant-design-pro_build'
7 | volumes:
8 | - dist:/usr/src/app/dist
9 |
10 | ant-design-pro_web:
11 | image: nginx
12 | ports:
13 | - 80:80
14 | container_name: 'ant-design-pro_web'
15 | restart: unless-stopped
16 | volumes:
17 | - dist:/usr/share/nginx/html:ro
18 | - ./nginx.conf:/etc/nginx/conf.d/default.conf
19 |
20 | volumes:
21 | dist:
22 |
--------------------------------------------------------------------------------
/src/models/product.ts:
--------------------------------------------------------------------------------
1 | import { useState, useCallback } from 'react'
2 |
3 | export default () => {
4 | const [count, setCount] = useState(0)
5 |
6 | // 增加数量
7 | const addCount = useCallback((val: number = 1) => {
8 | setCount((pre) => { return pre + val })
9 | }, [])
10 |
11 | // 减少数量
12 | const substractCount = useCallback((val: number = 1) => {
13 | setCount((pre) => { return pre - val })
14 | }, [])
15 |
16 | return {
17 | count,
18 | addCount,
19 | substractCount
20 | }
21 | }
--------------------------------------------------------------------------------
/src/services/ant-design-pro/login.ts:
--------------------------------------------------------------------------------
1 | // @ts-ignore
2 | /* eslint-disable */
3 | import { request } from 'umi';
4 |
5 | /** 发送验证码 POST /api/login/captcha */
6 | export async function getFakeCaptcha(
7 | params: {
8 | // query
9 | /** 手机号 */
10 | phone?: string;
11 | },
12 | options?: { [key: string]: any },
13 | ) {
14 | return request('/api/login/captcha', {
15 | method: 'POST',
16 | params: {
17 | ...params,
18 | },
19 | ...(options || {}),
20 | });
21 | }
22 |
--------------------------------------------------------------------------------
/Dockerfile.hub:
--------------------------------------------------------------------------------
1 | FROM circleci/node:latest-browsers as builder
2 |
3 | WORKDIR /usr/src/app/
4 | USER root
5 | COPY package.json ./
6 | RUN yarn
7 |
8 | COPY ./ ./
9 |
10 | RUN npm run test:all
11 |
12 | RUN npm run fetch:blocks
13 |
14 | RUN npm run build
15 |
16 |
17 | FROM nginx
18 |
19 | WORKDIR /usr/share/nginx/html/
20 |
21 | COPY ./docker/nginx.conf /etc/nginx/conf.d/default.conf
22 |
23 | COPY --from=builder /usr/src/app/dist /usr/share/nginx/html/
24 |
25 | EXPOSE 80
26 |
27 | CMD ["nginx", "-g", "daemon off;"]
--------------------------------------------------------------------------------
/.github/workflows/rebase.yml:
--------------------------------------------------------------------------------
1 | on:
2 | issue_comment:
3 | types: [created]
4 | name: Automatic Rebase
5 | jobs:
6 | rebase:
7 | name: Rebase
8 | if: github.event.issue.pull_request != '' && contains(github.event.comment.body, '/rebase')
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@master
12 | with:
13 | fetch-depth: 0
14 | - name: Automatic Rebase
15 | uses: cirrus-actions/rebase@1.3
16 | env:
17 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
18 |
--------------------------------------------------------------------------------
/src/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Ant Design Pro",
3 | "short_name": "Ant Design Pro",
4 | "display": "standalone",
5 | "start_url": "./?utm_source=homescreen",
6 | "theme_color": "#002140",
7 | "background_color": "#001529",
8 | "icons": [
9 | {
10 | "src": "icons/icon-192x192.png",
11 | "sizes": "192x192"
12 | },
13 | {
14 | "src": "icons/icon-128x128.png",
15 | "sizes": "128x128"
16 | },
17 | {
18 | "src": "icons/icon-512x512.png",
19 | "sizes": "512x512"
20 | }
21 | ]
22 | }
23 |
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | **/node_modules
5 | /src/utils/request-temp.js
6 |
7 | # production
8 | /.vscode
9 |
10 | # misc
11 | .DS_Store
12 | npm-debug.log*
13 | yarn-error.log
14 |
15 | /coverage
16 | .idea
17 | yarn.lock
18 | package-lock.json
19 | *bak
20 | .vscode
21 |
22 | # visual studio code
23 | .history
24 | *.log
25 |
26 | functions/mock
27 | .temp/**
28 |
29 | # umi
30 | .umi
31 | .umi-production
32 |
33 | # screenshot
34 | screenshot
35 | .firebase
--------------------------------------------------------------------------------
/src/pages/dataManage/useModel/componenets/page3.tsx:
--------------------------------------------------------------------------------
1 | import { useModel } from 'umi';
2 | import { Descriptions } from 'antd';
3 |
4 | export default () => {
5 | const { count } = useModel('product', model => (
6 | {
7 | count: model.count
8 | }
9 | ))
10 |
11 | return <>
12 | 页面三
13 |
14 | T-shirt
15 | 799
16 | {count}
17 |
18 | >
19 | };
--------------------------------------------------------------------------------
/src/components/HeaderSearch/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .headerSearch {
4 | display: inline-flex;
5 | align-items: center;
6 | .input {
7 | width: 0;
8 | min-width: 0;
9 | overflow: hidden;
10 | background: transparent;
11 | border-radius: 0;
12 | transition: width 0.3s, margin-left 0.3s;
13 | :global(.ant-select-selection) {
14 | background: transparent;
15 | }
16 | input {
17 | box-shadow: none !important;
18 | }
19 |
20 | &.show {
21 | width: 210px;
22 | margin-left: 8px;
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: '报告Bug 🐛'
3 | about: 报告 Ant Design Pro 的 bug
4 | title: '🐛[BUG]'
5 | labels: '🐛bug'
6 | assignees: ''
7 | ---
8 |
9 | ### 🐛 bug 描述
10 |
11 |
14 |
15 | ### 📷 复现步骤
16 |
17 |
20 |
21 | ### 🏞 期望结果
22 |
23 |
26 |
27 | ### 💻 复现代码
28 |
29 |
32 |
33 | ### © 版本信息
34 |
35 | - Ant Design Pro 版本: [e.g. 4.0.0]
36 | - umi 版本
37 | - 浏览器环境
38 | - 开发环境 [e.g. mac OS]
39 |
40 | ### 🚑 其他信息
41 |
42 |
45 |
--------------------------------------------------------------------------------
/src/locales/zh-TW.ts:
--------------------------------------------------------------------------------
1 | import component from './zh-TW/component';
2 | import globalHeader from './zh-TW/globalHeader';
3 | import menu from './zh-TW/menu';
4 | import pwa from './zh-TW/pwa';
5 | import settingDrawer from './zh-TW/settingDrawer';
6 | import settings from './zh-TW/settings';
7 |
8 | export default {
9 | 'navBar.lang': '語言',
10 | 'layout.user.link.help': '幫助',
11 | 'layout.user.link.privacy': '隱私',
12 | 'layout.user.link.terms': '條款',
13 | 'app.preview.down.block': '下載此頁面到本地項目',
14 | ...globalHeader,
15 | ...menu,
16 | ...settingDrawer,
17 | ...settings,
18 | ...pwa,
19 | ...component,
20 | };
21 |
--------------------------------------------------------------------------------
/src/components/NoticeIcon/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .popover {
4 | position: relative;
5 | width: 336px;
6 | }
7 |
8 | .noticeButton {
9 | display: inline-block;
10 | cursor: pointer;
11 | transition: all 0.3s;
12 | }
13 | .icon {
14 | padding: 4px;
15 | vertical-align: middle;
16 | }
17 |
18 | .badge {
19 | font-size: 16px;
20 | }
21 |
22 | .tabs {
23 | :global {
24 | .ant-tabs-nav-list {
25 | margin: auto;
26 | }
27 |
28 | .ant-tabs-nav-scroll {
29 | text-align: center;
30 | }
31 | .ant-tabs-bar {
32 | margin-bottom: 0;
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/pages/dataManage/initialstate/index.tsx:
--------------------------------------------------------------------------------
1 | // import React from 'react'
2 | import Page1 from './componenets/page1'
3 | import Page2 from './componenets/page2'
4 | import Page3 from './componenets/page3'
5 |
6 | export default () => {
7 | return <>
8 | 全局初始数据
9 |
12 |
15 |
18 | >
19 | };
--------------------------------------------------------------------------------
/.github/workflows/preview-start.yml:
--------------------------------------------------------------------------------
1 | name: Preview Start
2 |
3 | on: pull_request_target
4 |
5 | jobs:
6 | preview:
7 | runs-on: ubuntu-latest
8 | steps:
9 | - name: create
10 | uses: actions-cool/maintain-one-comment@v1.2.1
11 | with:
12 | token: ${{ secrets.GITHUB_TOKEN }}
13 | body: |
14 | ⚡️ Deploying PR Preview...
15 |
16 |
17 |
18 | body-include: ''
19 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | **/node_modules
5 | # roadhog-api-doc ignore
6 | /src/utils/request-temp.js
7 | _roadhog-api-doc
8 |
9 | # production
10 | /dist
11 | /.vscode
12 |
13 | # misc
14 | .DS_Store
15 | npm-debug.log*
16 | yarn-error.log
17 |
18 | /coverage
19 | .idea
20 | yarn.lock
21 | package-lock.json
22 | *bak
23 | .vscode
24 |
25 | # visual studio code
26 | .history
27 | *.log
28 | functions/*
29 | .temp/**
30 |
31 | # umi
32 | .umi
33 | .umi-production
34 |
35 | # screenshot
36 | screenshot
37 | .firebase
38 | .eslintcache
39 |
40 | build
41 |
--------------------------------------------------------------------------------
/src/pages/dataManage/useModel/index.tsx:
--------------------------------------------------------------------------------
1 | // import React from 'react'
2 | import Page1 from './componenets/page1'
3 | import Page2 from './componenets/page2'
4 | import Page3 from './componenets/page3'
5 |
6 | export default () => {
7 |
8 | return <>
9 | useModel数据管理
10 |
13 |
16 |
19 | >
20 | };
--------------------------------------------------------------------------------
/src/pages/project/index.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react'
2 | import Project2 from './components/seconed'
3 | import { connect } from 'dva'
4 |
5 | const Project: React.Fc = (props) => {
6 | const [name, setName] = useState('小李')
7 | console.log(props.update)
8 |
9 | return
10 | 项目顶层组件
11 |
12 | 姓名: {name}
13 |
14 |
15 | dva姓名: {props.update}
16 |
17 |
{
18 | setName(name)
19 | console.log(999)
20 | }}>
21 |
22 | }
23 |
24 | export default connect(({ project }) => ({
25 | update: project.update,
26 | }))(Project)
--------------------------------------------------------------------------------
/config/defaultSettings.ts:
--------------------------------------------------------------------------------
1 | import { Settings as LayoutSettings } from '@ant-design/pro-layout';
2 |
3 | const Settings: LayoutSettings & {
4 | pwa?: boolean;
5 | logo?: string;
6 | } = {
7 | menu: {
8 | locale: false, //关闭国际化
9 | },
10 | navTheme: 'light',
11 | // 拂晓蓝
12 | // primaryColor: '#1890ff',
13 | primaryColor: '#f26',
14 | layout: 'mix',
15 | contentWidth: 'Fluid',
16 | fixedHeader: false,
17 | fixSiderbar: true,
18 | colorWeak: false,
19 | title: 'Ant Design Pro',
20 | pwa: false,
21 | logo: 'https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg',
22 | iconfontUrl: '',
23 | };
24 |
25 | export default Settings;
26 |
--------------------------------------------------------------------------------
/src/pages/dataManage/project/components/seconed.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import Project3 from './three'
3 | import { Descriptions } from 'antd'
4 | import { connect } from 'dva'
5 |
6 | const Project2: React.Fc = (props:any) => {
7 | const { useInfo } = props
8 |
9 | return
10 |
11 | {useInfo.userName}
12 | {useInfo.age}
13 |
14 |
15 |
16 | }
17 |
18 | export default connect(({ user }) => ({
19 | useInfo: user.useInfo,
20 | }))(Project2)
--------------------------------------------------------------------------------
/src/pages/dataManage/project/components/three.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import Project4 from './four'
3 | import { Descriptions } from 'antd'
4 | import { connect } from 'dva'
5 |
6 | const Project3: React.Fc = (props:any) => {
7 | const { useInfo } = props
8 |
9 | return
10 |
11 |
12 | {useInfo.userName}
13 | {useInfo.age}
14 |
15 |
16 |
17 | }
18 |
19 | export default connect(({ user }) => ({
20 | useInfo: user.useInfo,
21 | }))(Project3)
--------------------------------------------------------------------------------
/public/pro_icon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docker/nginx.conf:
--------------------------------------------------------------------------------
1 | server {
2 | listen 80;
3 | # gzip config
4 | gzip on;
5 | gzip_min_length 1k;
6 | gzip_comp_level 9;
7 | gzip_types text/plain text/css text/javascript application/json application/javascript application/x-javascript application/xml;
8 | gzip_vary on;
9 | gzip_disable "MSIE [1-6]\.";
10 |
11 | root /usr/share/nginx/html;
12 | include /etc/nginx/mime.types;
13 | location / {
14 | try_files $uri $uri/ /index.html;
15 | }
16 | location /api {
17 | proxy_pass https://proapi.azurewebsites.net;
18 | proxy_set_header X-Forwarded-Proto $scheme;
19 | proxy_set_header X-Real-IP $remote_addr;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: ant-design
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
13 |
--------------------------------------------------------------------------------
/src/pages/dataManage/project/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import Project2 from './components/seconed'
3 | import { connect } from 'dva'
4 | import { Descriptions } from 'antd'
5 |
6 | const Project: React.Fc = (props) => {
7 | const { useInfo } = props
8 |
9 | return
10 |
11 |
嵌套组件
12 |
13 | {useInfo.userName}
14 | {useInfo.age}
15 |
16 |
17 |
18 |
19 | }
20 |
21 | export default connect(({ user }) => ({
22 | useInfo: user.useInfo,
23 | }))(Project)
--------------------------------------------------------------------------------
/src/locales/pt-BR.ts:
--------------------------------------------------------------------------------
1 | import component from './pt-BR/component';
2 | import globalHeader from './pt-BR/globalHeader';
3 | import menu from './pt-BR/menu';
4 | import pwa from './pt-BR/pwa';
5 | import settingDrawer from './pt-BR/settingDrawer';
6 | import settings from './pt-BR/settings';
7 | import pages from './pt-BR/pages';
8 |
9 | export default {
10 | 'navBar.lang': 'Idiomas',
11 | 'layout.user.link.help': 'ajuda',
12 | 'layout.user.link.privacy': 'política de privacidade',
13 | 'layout.user.link.terms': 'termos de serviços',
14 | 'app.preview.down.block': 'Download this page to your local project',
15 | ...globalHeader,
16 | ...menu,
17 | ...settingDrawer,
18 | ...settings,
19 | ...pwa,
20 | ...component,
21 | ...pages,
22 | };
23 |
--------------------------------------------------------------------------------
/src/pages/project/components/four.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from 'antd'
2 | import React, { useState } from 'react'
3 | import { connect } from 'dva'
4 |
5 | const Project4: React.Fc = (props: {onSuccess: (name: string) => void, dispatch: any}) => {
6 | const [name, setName] = useState('')
7 |
8 | const clickName = () => {
9 | setName(`小明${Math.floor(Math.random()*10)}`)
10 | props.onSuccess(name)
11 | props.dispatch({
12 | type: 'project/changeState',
13 | payload: name,
14 | })
15 | }
16 |
17 | return
18 | 项目第四层组件
19 |
姓名: {name}
20 |
21 |
22 | }
23 |
24 | export default connect(({ project }) => ({
25 | project,
26 | }))(Project4)
--------------------------------------------------------------------------------
/src/components/HeaderDropdown/index.tsx:
--------------------------------------------------------------------------------
1 | import type { DropDownProps } from 'antd/es/dropdown';
2 | import { Dropdown } from 'antd';
3 | import React from 'react';
4 | import classNames from 'classnames';
5 | import styles from './index.less';
6 |
7 | export type HeaderDropdownProps = {
8 | overlayClassName?: string;
9 | overlay: React.ReactNode | (() => React.ReactNode) | any;
10 | placement?: 'bottomLeft' | 'bottomRight' | 'topLeft' | 'topCenter' | 'topRight' | 'bottomCenter';
11 | } & Omit;
12 |
13 | const HeaderDropdown: React.FC = ({ overlayClassName: cls, ...restProps }) => (
14 |
15 | );
16 |
17 | export default HeaderDropdown;
18 |
--------------------------------------------------------------------------------
/src/locales/ja-JP.ts:
--------------------------------------------------------------------------------
1 | import globalHeader from './ja-JP/globalHeader';
2 | import menu from './ja-JP/menu';
3 | import settingDrawer from './ja-JP/settingDrawer';
4 | import settings from './ja-JP/settings';
5 | import pwa from './ja-JP/pwa';
6 | import component from './ja-JP/component';
7 | import pages from './ja-JP/pages';
8 |
9 | export default {
10 | 'navBar.lang': '言語',
11 | 'layout.user.link.help': 'ヘルプ',
12 | 'layout.user.link.privacy': 'プライバシー',
13 | 'layout.user.link.terms': '利用規約',
14 | 'app.preview.down.block': 'このページをローカルプロジェクトにダウンロードしてください',
15 | 'app.welcome.link.fetch-blocks': '',
16 | 'app.welcome.link.block-list': '',
17 | ...globalHeader,
18 | ...menu,
19 | ...settingDrawer,
20 | ...settings,
21 | ...pwa,
22 | ...component,
23 | ...pages,
24 | };
25 |
--------------------------------------------------------------------------------
/.github/workflows/deploy.yml:
--------------------------------------------------------------------------------
1 | name: Deploy CI
2 | on:
3 | push:
4 | branches:
5 | - master
6 |
7 | jobs:
8 | build-and-deploy:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: checkout
12 | uses: actions/checkout@master
13 |
14 | - name: install
15 | run: yarn
16 |
17 | - name: plugins
18 | run: yarn add umi-plugin-antd-theme umi-plugin-pro umi-plugin-setting-drawer
19 |
20 | - name: fetch-blocks
21 | run: yarn run pro fetch-blocks
22 |
23 | - name: site
24 | run: npm run build
25 |
26 | - name: Deploy
27 | uses: peaceiris/actions-gh-pages@v3
28 | with:
29 | deploy_key: ${{ secrets.ACTIONS_DEPLOY_KEY }}
30 | publish_dir: ./dist
31 | force_orphan: true
32 |
--------------------------------------------------------------------------------
/src/locales/zh-CN/globalHeader.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'component.globalHeader.search': '站内搜索',
3 | 'component.globalHeader.search.example1': '搜索提示一',
4 | 'component.globalHeader.search.example2': '搜索提示二',
5 | 'component.globalHeader.search.example3': '搜索提示三',
6 | 'component.globalHeader.help': '使用文档',
7 | 'component.globalHeader.notification': '通知',
8 | 'component.globalHeader.notification.empty': '你已查看所有通知',
9 | 'component.globalHeader.message': '消息',
10 | 'component.globalHeader.message.empty': '您已读完所有消息',
11 | 'component.globalHeader.event': '待办',
12 | 'component.globalHeader.event.empty': '你已完成所有待办',
13 | 'component.noticeIcon.clear': '清空',
14 | 'component.noticeIcon.cleared': '清空了',
15 | 'component.noticeIcon.empty': '暂无数据',
16 | 'component.noticeIcon.view-more': '查看更多',
17 | };
18 |
--------------------------------------------------------------------------------
/src/locales/zh-TW/globalHeader.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'component.globalHeader.search': '站內搜索',
3 | 'component.globalHeader.search.example1': '搜索提示壹',
4 | 'component.globalHeader.search.example2': '搜索提示二',
5 | 'component.globalHeader.search.example3': '搜索提示三',
6 | 'component.globalHeader.help': '使用手冊',
7 | 'component.globalHeader.notification': '通知',
8 | 'component.globalHeader.notification.empty': '妳已查看所有通知',
9 | 'component.globalHeader.message': '消息',
10 | 'component.globalHeader.message.empty': '您已讀完所有消息',
11 | 'component.globalHeader.event': '待辦',
12 | 'component.globalHeader.event.empty': '妳已完成所有待辦',
13 | 'component.noticeIcon.clear': '清空',
14 | 'component.noticeIcon.cleared': '清空了',
15 | 'component.noticeIcon.empty': '暫無資料',
16 | 'component.noticeIcon.view-more': '查看更多',
17 | };
18 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: Node CI
2 |
3 | on: [push, pull_request]
4 |
5 | jobs:
6 | build:
7 | runs-on: ${{ matrix.os }}
8 | strategy:
9 | matrix:
10 | node_version: [12.x, 14.x]
11 | os: [ubuntu-latest, windows-latest, macOS-latest]
12 | steps:
13 | - uses: actions/checkout@v1
14 | - name: Use Node.js ${{ matrix.node_version }}
15 | uses: actions/setup-node@v1
16 | with:
17 | node-version: ${{ matrix.node_version }}
18 | - run: echo ${{github.ref}}
19 | - run: yarn
20 | - run: yarn run lint
21 | - run: yarn run tsc
22 | - run: yarn run build
23 | - run: yarn run test:all
24 | env:
25 | CI: true
26 | PROGRESS: none
27 | NODE_ENV: test
28 | NODE_OPTIONS: --max_old_space_size=4096
29 |
--------------------------------------------------------------------------------
/src/locales/ja-JP/globalHeader.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'component.globalHeader.search': '検索',
3 | 'component.globalHeader.search.example1': '検索例1',
4 | 'component.globalHeader.search.example2': '検索例2',
5 | 'component.globalHeader.search.example3': '検索例3',
6 | 'component.globalHeader.help': 'ヘルプ',
7 | 'component.globalHeader.notification': '通知',
8 | 'component.globalHeader.notification.empty': 'すべての通知を表示しました。',
9 | 'component.globalHeader.message': 'メッセージ',
10 | 'component.globalHeader.message.empty': 'すべてのメッセージを表示しました。',
11 | 'component.globalHeader.event': 'イベント',
12 | 'component.globalHeader.event.empty': 'すべてのイベントを表示しました。',
13 | 'component.noticeIcon.clear': 'クリア',
14 | 'component.noticeIcon.cleared': 'クリア済み',
15 | 'component.noticeIcon.empty': '通知なし',
16 | 'component.noticeIcon.view-more': 'もっと見る',
17 | };
18 |
--------------------------------------------------------------------------------
/src/locales/zh-CN.ts:
--------------------------------------------------------------------------------
1 | import component from './zh-CN/component';
2 | import globalHeader from './zh-CN/globalHeader';
3 | import menu from './zh-CN/menu';
4 | import pwa from './zh-CN/pwa';
5 | import settingDrawer from './zh-CN/settingDrawer';
6 | import settings from './zh-CN/settings';
7 | import pages from './zh-CN/pages';
8 |
9 | export default {
10 | 'navBar.lang': '语言',
11 | 'layout.user.link.help': '帮助',
12 | 'layout.user.link.privacy': '隐私',
13 | 'layout.user.link.terms': '条款',
14 | 'app.copyright.produced': '蚂蚁集团体验技术部出品',
15 | 'app.preview.down.block': '下载此页面到本地项目',
16 | 'app.welcome.link.fetch-blocks': '获取全部区块',
17 | 'app.welcome.link.block-list': '基于 block 开发,快速构建标准页面',
18 | ...pages,
19 | ...globalHeader,
20 | ...menu,
21 | ...settingDrawer,
22 | ...settings,
23 | ...pwa,
24 | ...component,
25 | };
26 |
--------------------------------------------------------------------------------
/config/proxy.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * 在生产环境 代理是无法生效的,所以这里没有生产环境的配置
3 | * -------------------------------
4 | * The agent cannot take effect in the production environment
5 | * so there is no configuration of the production environment
6 | * For details, please see
7 | * https://pro.ant.design/docs/deploy
8 | */
9 | export default {
10 | dev: {
11 | '/childapi/api/': {
12 | target: 'http://localhost:8091',
13 | changeOrigin: true,
14 | pathRewrite: { '^/childapi': '' },
15 | },
16 | },
17 | test: {
18 | '/api/': {
19 | target: 'https://preview.pro.ant.design',
20 | changeOrigin: true,
21 | pathRewrite: { '^': '' },
22 | },
23 | },
24 | pre: {
25 | '/api/': {
26 | target: 'your pre url',
27 | changeOrigin: true,
28 | pathRewrite: { '^': '' },
29 | },
30 | },
31 | };
32 |
--------------------------------------------------------------------------------
/src/pages/form/detail2/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Descriptions, Card } from 'antd'
3 |
4 | const Detail: React.FC = () => {
5 | return (
6 |
7 |
8 | 这是子应用详情页2
9 |
10 | Zhou Maomao
11 | 1810000000
12 | Hangzhou, Zhejiang
13 | empty
14 |
15 | No. 18, Wantang Road, Xihu District, Hangzhou, Zhejiang, China
16 |
17 |
18 |
19 |
20 | )
21 | }
22 |
23 | export default Detail
--------------------------------------------------------------------------------
/src/pages/dataManage/initialstate/componenets/page3.tsx:
--------------------------------------------------------------------------------
1 | import { useModel } from 'umi';
2 | import { Descriptions } from 'antd'
3 |
4 | export default () => {
5 | const { initialState, loading, error, refresh, setInitialState } = useModel('@@initialState');
6 |
7 | const { currentUser } = initialState
8 |
9 | return <>
10 | 页面三
11 |
12 | {currentUser.name}
13 | {currentUser.phone}
14 | {currentUser.group}
15 | {currentUser.signature}
16 |
17 | {currentUser.address}
18 |
19 |
20 | >
21 | };
--------------------------------------------------------------------------------
/src/pages/dataManage/initialstate/componenets/page2.tsx:
--------------------------------------------------------------------------------
1 | import { useModel } from 'umi';
2 | import { Descriptions } from 'antd'
3 |
4 | export default () => {
5 | const { initialState, loading, error, refresh, setInitialState } = useModel('@@initialState');
6 |
7 | const { currentUser } = initialState
8 |
9 | return <>
10 | 页面二
11 |
12 | {currentUser.name}
13 | {currentUser.phone}
14 | {currentUser.group}
15 | {currentUser.signature}
16 |
17 | {currentUser.address}
18 |
19 |
20 | >
21 | };
--------------------------------------------------------------------------------
/src/locales/fa-IR.ts:
--------------------------------------------------------------------------------
1 | import component from './fa-IR/component';
2 | import globalHeader from './fa-IR/globalHeader';
3 | import menu from './fa-IR/menu';
4 | import pwa from './fa-IR/pwa';
5 | import settingDrawer from './fa-IR/settingDrawer';
6 | import settings from './fa-IR/settings';
7 | import pages from './fa-IR/pages';
8 |
9 | export default {
10 | 'navBar.lang': 'زبان ها ',
11 | 'layout.user.link.help': 'کمک',
12 | 'layout.user.link.privacy': 'حریم خصوصی',
13 | 'layout.user.link.terms': 'مقررات',
14 | 'app.preview.down.block': 'این صفحه را در پروژه محلی خود بارگیری کنید',
15 | 'app.welcome.link.fetch-blocks': 'دریافت تمام بلوک',
16 | 'app.welcome.link.block-list': 'به سرعت صفحات استاندارد مبتنی بر توسعه "بلوک" را بسازید',
17 | ...globalHeader,
18 | ...menu,
19 | ...settingDrawer,
20 | ...settings,
21 | ...pwa,
22 | ...component,
23 | ...pages,
24 | };
25 |
--------------------------------------------------------------------------------
/src/typings.d.ts:
--------------------------------------------------------------------------------
1 | declare module 'slash2';
2 | declare module '*.css';
3 | declare module '*.less';
4 | declare module '*.scss';
5 | declare module '*.sass';
6 | declare module '*.svg';
7 | declare module '*.png';
8 | declare module '*.jpg';
9 | declare module '*.jpeg';
10 | declare module '*.gif';
11 | declare module '*.bmp';
12 | declare module '*.tiff';
13 | declare module 'omit.js';
14 | declare module 'numeral';
15 | declare module '@antv/data-set';
16 | declare module 'mockjs';
17 | declare module 'react-fittext';
18 | declare module 'bizcharts-plugin-slider';
19 |
20 | // preview.pro.ant.design only do not use in your production ;
21 | // preview.pro.ant.design Dedicated environment variable, please do not use it in your project.
22 | declare let ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION: 'site' | undefined;
23 |
24 | declare const REACT_APP_ENV: 'test' | 'dev' | 'pre' | false;
25 |
--------------------------------------------------------------------------------
/src/locales/id-ID.ts:
--------------------------------------------------------------------------------
1 | import component from './id-ID/component';
2 | import globalHeader from './id-ID/globalHeader';
3 | import menu from './id-ID/menu';
4 | import pwa from './id-ID/pwa';
5 | import settingDrawer from './id-ID/settingDrawer';
6 | import settings from './id-ID/settings';
7 | import pages from './id-ID/pages';
8 |
9 | export default {
10 | 'navbar.lang': 'Bahasa',
11 | 'layout.user.link.help': 'Bantuan',
12 | 'layout.user.link.privacy': 'Privasi',
13 | 'layout.user.link.terms': 'Ketentuan',
14 | 'app.preview.down.block': 'Unduh halaman ini dalam projek lokal anda',
15 | 'app.welcome.link.fetch-blocks': 'Dapatkan semua blok',
16 | 'app.welcome.link.block-list':
17 | 'Buat standar dengan cepat, halaman-halaman berdasarkan pengembangan `block`',
18 | ...globalHeader,
19 | ...menu,
20 | ...settingDrawer,
21 | ...settings,
22 | ...pwa,
23 | ...component,
24 | ...pages,
25 | };
26 |
--------------------------------------------------------------------------------
/src/pages/product/list/components/productModal.tsx:
--------------------------------------------------------------------------------
1 | import React, { useRef } from 'react'
2 | import { Modal } from 'antd'
3 | import ProductInfo from '@/components/ProductInfo'
4 |
5 | export type productProps = {
6 | modalVisible: boolean
7 | infoData?: any
8 | onCancel: () => void
9 | }
10 |
11 | const ProductModal = ({modalVisible, infoData, onCancel}: productProps) => {
12 |
13 | const productRef = useRef({})
14 |
15 | const onSubmit = async() => {
16 | const form = productRef.current.getForm()
17 | await form.validateFields()
18 | const data = form.getFieldsValue()
19 | console.log(data)
20 | }
21 |
22 | return (
23 |
30 |
31 |
32 | )
33 | }
34 |
35 | export default ProductModal
--------------------------------------------------------------------------------
/src/locales/en-US/globalHeader.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'component.globalHeader.search': 'Search',
3 | 'component.globalHeader.search.example1': 'Search example 1',
4 | 'component.globalHeader.search.example2': 'Search example 2',
5 | 'component.globalHeader.search.example3': 'Search example 3',
6 | 'component.globalHeader.help': 'Help',
7 | 'component.globalHeader.notification': 'Notification',
8 | 'component.globalHeader.notification.empty': 'You have viewed all notifications.',
9 | 'component.globalHeader.message': 'Message',
10 | 'component.globalHeader.message.empty': 'You have viewed all messsages.',
11 | 'component.globalHeader.event': 'Event',
12 | 'component.globalHeader.event.empty': 'You have viewed all events.',
13 | 'component.noticeIcon.clear': 'Clear',
14 | 'component.noticeIcon.cleared': 'Cleared',
15 | 'component.noticeIcon.empty': 'No notifications',
16 | 'component.noticeIcon.view-more': 'View more',
17 | };
18 |
--------------------------------------------------------------------------------
/mock/editor.ts:
--------------------------------------------------------------------------------
1 | import { Request, Response } from 'express';
2 | import Mock from 'mockjs'
3 | import moment from 'moment';
4 | const Random = Mock.Random
5 |
6 | export interface articleProps {
7 | id?: number
8 | createTime?: string
9 | title: string
10 | content: string
11 | }
12 | const articleList: articleProps[] = []
13 |
14 | // 文章列表
15 | const getArticleList = (req: Request, res: Response) => {
16 | res.send({
17 | data: articleList,
18 | success: true
19 | })
20 | }
21 | // 新增文章
22 | const addArticle = (req: Request, res: Response) => {
23 | const { title, content } = req.body
24 | articleList.push({
25 | id: Random.id(),
26 | createTime: moment().format('YYYY-MM-DD'),
27 | title,
28 | content
29 | })
30 |
31 | res.send({
32 | data: {},
33 | success: true
34 | })
35 | }
36 |
37 | export default {
38 | 'POST /api/article/list': getArticleList,
39 | 'POST /api/article/add': addArticle,
40 | };
41 |
--------------------------------------------------------------------------------
/src/pages/dataManage/useModel/componenets/page2.tsx:
--------------------------------------------------------------------------------
1 | import { useModel } from 'umi';
2 | import { Descriptions, Button } from 'antd';
3 |
4 | export default () => {
5 | const { count, addCount, substractCount } = useModel('product', model => (
6 | {
7 | count: model.count,
8 | addCount: model.addCount,
9 | substractCount: model.substractCount,
10 | }
11 | ))
12 |
13 | return <>
14 | 页面二
15 |
16 | T-shirt
17 | 799
18 | {count}
19 |
20 | 修改数据
21 |
24 |
27 | >
28 | };
--------------------------------------------------------------------------------
/src/locales/en-US.ts:
--------------------------------------------------------------------------------
1 | import component from './en-US/component';
2 | import globalHeader from './en-US/globalHeader';
3 | import menu from './en-US/menu';
4 | import pages from './en-US/pages';
5 | import pwa from './en-US/pwa';
6 | import settingDrawer from './en-US/settingDrawer';
7 | import settings from './en-US/settings';
8 |
9 | export default {
10 | 'navBar.lang': 'Languages',
11 | 'layout.user.link.help': 'Help',
12 | 'layout.user.link.privacy': 'Privacy',
13 | 'layout.user.link.terms': 'Terms',
14 | 'app.copyright.produced': 'Produced by Ant Financial Experience Department',
15 | 'app.preview.down.block': 'Download this page to your local project',
16 | 'app.welcome.link.fetch-blocks': 'Get all block',
17 | 'app.welcome.link.block-list': 'Quickly build standard, pages based on `block` development',
18 | ...globalHeader,
19 | ...menu,
20 | ...settingDrawer,
21 | ...settings,
22 | ...pwa,
23 | ...component,
24 | ...pages,
25 | };
26 |
--------------------------------------------------------------------------------
/src/locales/fa-IR/globalHeader.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'component.globalHeader.search': 'جستجو ',
3 | 'component.globalHeader.search.example1': 'مثال 1 را جستجو کنید',
4 | 'component.globalHeader.search.example2': 'مثال 2 را جستجو کنید',
5 | 'component.globalHeader.search.example3': 'مثال 3 را جستجو کنید',
6 | 'component.globalHeader.help': 'کمک',
7 | 'component.globalHeader.notification': 'اعلان',
8 | 'component.globalHeader.notification.empty': 'شما همه اعلان ها را مشاهده کرده اید.',
9 | 'component.globalHeader.message': 'پیام',
10 | 'component.globalHeader.message.empty': 'شما همه پیام ها را مشاهده کرده اید.',
11 | 'component.globalHeader.event': 'رویداد',
12 | 'component.globalHeader.event.empty': 'شما همه رویدادها را مشاهده کرده اید.',
13 | 'component.noticeIcon.clear': 'پاک کردن',
14 | 'component.noticeIcon.cleared': 'پاک شد',
15 | 'component.noticeIcon.empty': 'بدون اعلان',
16 | 'component.noticeIcon.view-more': 'نمایش بیشتر',
17 | };
18 |
--------------------------------------------------------------------------------
/src/pages/dataManage/useModel/componenets/page1.tsx:
--------------------------------------------------------------------------------
1 | // import React from 'react';
2 | import { useModel } from 'umi';
3 | import { Descriptions, Button } from 'antd';
4 |
5 | export default () => {
6 | const { count, addCount, substractCount } = useModel('product', model => (
7 | {
8 | count: model.count,
9 | addCount: model.addCount,
10 | substractCount: model.substractCount,
11 | }
12 | ))
13 |
14 | return <>
15 | 页面一
16 |
17 | T-shirt
18 | 799
19 | {count}
20 |
21 | 修改数据
22 |
25 |
28 | >
29 | };
--------------------------------------------------------------------------------
/src/locales/id-ID/globalHeader.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'component.globalHeader.search': 'Pencarian',
3 | 'component.globalHeader.search.example1': 'Contoh 1 Pencarian',
4 | 'component.globalHeader.search.example2': 'Contoh 2 Pencarian',
5 | 'component.globalHeader.search.example3': 'Contoh 3 Pencarian',
6 | 'component.globalHeader.help': 'Bantuan',
7 | 'component.globalHeader.notification': 'Notifikasi',
8 | 'component.globalHeader.notification.empty': 'Anda telah membaca semua notifikasi',
9 | 'component.globalHeader.message': 'Pesan',
10 | 'component.globalHeader.message.empty': 'Anda telah membaca semua pesan.',
11 | 'component.globalHeader.event': 'Acara',
12 | 'component.globalHeader.event.empty': 'Anda telah melihat semua acara.',
13 | 'component.noticeIcon.clear': 'Kosongkan',
14 | 'component.noticeIcon.cleared': 'Berhasil dikosongkan',
15 | 'component.noticeIcon.empty': 'Tidak ada pemberitahuan',
16 | 'component.noticeIcon.view-more': 'Melihat lebih',
17 | };
18 |
--------------------------------------------------------------------------------
/.github/workflows/preview-build.yml:
--------------------------------------------------------------------------------
1 | name: Preview Build
2 |
3 | on:
4 | pull_request:
5 | types: [opened, synchronize, reopened]
6 |
7 | jobs:
8 | build-preview:
9 | runs-on: ubuntu-latest
10 |
11 | steps:
12 | - uses: actions/checkout@v2
13 | with:
14 | ref: ${{ github.event.pull_request.head.sha }}
15 |
16 | - name: build
17 | run: |
18 | yarn
19 | yarn add umi-plugin-pro --save
20 | yarn build
21 |
22 | - name: upload dist artifact
23 | uses: actions/upload-artifact@v2
24 | with:
25 | name: dist
26 | path: dist/
27 | retention-days: 5
28 |
29 | - name: Save PR number
30 | if: ${{ always() }}
31 | run: echo ${{ github.event.number }} > ./pr-id.txt
32 |
33 | - name: Upload PR number
34 | if: ${{ always() }}
35 | uses: actions/upload-artifact@v2
36 | with:
37 | name: pr
38 | path: ./pr-id.txt
39 |
--------------------------------------------------------------------------------
/src/locales/pt-BR/globalHeader.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'component.globalHeader.search': 'Busca',
3 | 'component.globalHeader.search.example1': 'Exemplo de busca 1',
4 | 'component.globalHeader.search.example2': 'Exemplo de busca 2',
5 | 'component.globalHeader.search.example3': 'Exemplo de busca 3',
6 | 'component.globalHeader.help': 'Ajuda',
7 | 'component.globalHeader.notification': 'Notificação',
8 | 'component.globalHeader.notification.empty': 'Você visualizou todas as notificações.',
9 | 'component.globalHeader.message': 'Mensagem',
10 | 'component.globalHeader.message.empty': 'Você visualizou todas as mensagens.',
11 | 'component.globalHeader.event': 'Evento',
12 | 'component.globalHeader.event.empty': 'Você visualizou todos os eventos.',
13 | 'component.noticeIcon.clear': 'Limpar',
14 | 'component.noticeIcon.cleared': 'Limpo',
15 | 'component.noticeIcon.empty': 'Sem notificações',
16 | 'component.noticeIcon.loaded': 'Carregado',
17 | 'component.noticeIcon.view-more': 'Veja mais',
18 | };
19 |
--------------------------------------------------------------------------------
/src/components/Footer/index.tsx:
--------------------------------------------------------------------------------
1 | import { useIntl } from 'umi';
2 | import { GithubOutlined } from '@ant-design/icons';
3 | import { DefaultFooter } from '@ant-design/pro-layout';
4 |
5 | export default () => {
6 | const intl = useIntl();
7 | const defaultMessage = intl.formatMessage({
8 | id: 'app.copyright.produced',
9 | defaultMessage: '蚂蚁集团体验技术部出品',
10 | });
11 |
12 | return (
13 | ,
25 | href: 'https://github.com/ant-design/ant-design-pro',
26 | blankTarget: true,
27 | },
28 | {
29 | key: 'Ant Design',
30 | title: 'Ant Design',
31 | href: 'https://ant.design',
32 | blankTarget: true,
33 | },
34 | ]}
35 | />
36 | );
37 | };
38 |
--------------------------------------------------------------------------------
/src/pages/form/detail/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Descriptions, Card, Button } from 'antd'
3 | import { GithubOutlined } from '@ant-design/icons'
4 | import style from './index.less'
5 |
6 | const Detail: React.FC = () => {
7 | return (
8 |
9 |
10 | 这是子应用详情页
11 |
12 | Zhou Maomao
13 | 1810000000
14 | Hangzhou, Zhejiang
15 | empty
16 |
17 | No. 18, Wantang Road, Xihu District, Hangzhou, Zhejiang, China
18 |
19 |
20 |
23 |
24 | 自定义样式
25 |
26 |
27 |
28 | )
29 | }
30 |
31 | export default Detail
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Alipay.inc
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/services/swagger/typings.d.ts:
--------------------------------------------------------------------------------
1 | // @ts-ignore
2 | /* eslint-disable */
3 |
4 | declare namespace API {
5 | type Order = {
6 | id?: number;
7 | petId?: number;
8 | quantity?: number;
9 | shipDate?: string;
10 | /** Order Status */
11 | status?: 'placed' | 'approved' | 'delivered';
12 | complete?: boolean;
13 | };
14 |
15 | type Category = {
16 | id?: number;
17 | name?: string;
18 | };
19 |
20 | type User = {
21 | id?: number;
22 | username?: string;
23 | firstName?: string;
24 | lastName?: string;
25 | email?: string;
26 | password?: string;
27 | phone?: string;
28 | /** User Status */
29 | userStatus?: number;
30 | };
31 |
32 | type Tag = {
33 | id?: number;
34 | name?: string;
35 | };
36 |
37 | type Pet = {
38 | id?: number;
39 | category?: Category;
40 | name: string;
41 | photoUrls: string[];
42 | tags?: Tag[];
43 | /** pet status in the store */
44 | status?: 'available' | 'pending' | 'sold';
45 | };
46 |
47 | type ApiResponse = {
48 | code?: number;
49 | type?: string;
50 | message?: string;
51 | };
52 | }
53 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "build/dist",
4 | "module": "esnext",
5 | "target": "esnext",
6 | "lib": ["esnext", "dom"],
7 | "sourceMap": true,
8 | "baseUrl": ".",
9 | "jsx": "react-jsx",
10 | "resolveJsonModule": true,
11 | "allowSyntheticDefaultImports": true,
12 | "moduleResolution": "node",
13 | "forceConsistentCasingInFileNames": true,
14 | "noImplicitReturns": true,
15 | "suppressImplicitAnyIndexErrors": true,
16 | "noUnusedLocals": true,
17 | "allowJs": true,
18 | "skipLibCheck": true,
19 | "experimentalDecorators": true,
20 | "strict": true,
21 | "paths": {
22 | "@/*": ["./src/*"],
23 | "@@/*": ["./src/.umi/*"]
24 | }
25 | },
26 | "include": [
27 | "mock/**/*",
28 | "src/**/*",
29 | "tests/**/*",
30 | "test/**/*",
31 | "__test__/**/*",
32 | "typings/**/*",
33 | "config/**/*",
34 | ".eslintrc.js",
35 | ".stylelintrc.js",
36 | ".prettierrc.js",
37 | "jest.config.js",
38 | "mock/*"
39 | ],
40 | "exclude": ["node_modules", "build", "dist", "scripts", "src/.umi/*", "webpack", "jest"]
41 | }
42 |
--------------------------------------------------------------------------------
/src/global.less:
--------------------------------------------------------------------------------
1 | // @import '~antd/es/style/themes/default.less';
2 | @import (reference) '~antd/es/style/themes/index';
3 | @import './custom.css';
4 |
5 | html,
6 | body,
7 | #root {
8 | height: 100%;
9 | }
10 | html {
11 | --chid-primary-color: #f26;
12 | }
13 |
14 | .colorWeak {
15 | filter: invert(80%);
16 | }
17 |
18 | .ant-layout {
19 | min-height: 100vh;
20 | }
21 | .ant-pro-sider.ant-layout-sider.ant-pro-sider-fixed {
22 | left: unset;
23 | }
24 |
25 | canvas {
26 | display: block;
27 | }
28 |
29 | body {
30 | text-rendering: optimizeLegibility;
31 | -webkit-font-smoothing: antialiased;
32 | -moz-osx-font-smoothing: grayscale;
33 | }
34 |
35 | ul,
36 | ol {
37 | list-style: none;
38 | }
39 |
40 | @media (max-width: @screen-xs) {
41 | .ant-table {
42 | width: 100%;
43 | overflow-x: auto;
44 | &-thead > tr,
45 | &-tbody > tr {
46 | > th,
47 | > td {
48 | white-space: pre;
49 | > span {
50 | display: block;
51 | }
52 | }
53 | }
54 | }
55 | }
56 |
57 | // Compatible with IE11
58 | @media screen and(-ms-high-contrast: active), (-ms-high-contrast: none) {
59 | body .ant-design-pro > .ant-layout {
60 | min-height: 100vh;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/tests/PuppeteerEnvironment.js:
--------------------------------------------------------------------------------
1 | // eslint-disable-next-line
2 | const NodeEnvironment = require('jest-environment-node');
3 | const getBrowser = require('./getBrowser');
4 |
5 | class PuppeteerEnvironment extends NodeEnvironment {
6 | // Jest is not available here, so we have to reverse engineer
7 | // the setTimeout function, see https://github.com/facebook/jest/blob/v23.1.0/packages/jest-runtime/src/index.js#L823
8 | setTimeout(timeout) {
9 | if (this.global.jasmine) {
10 | // eslint-disable-next-line no-underscore-dangle
11 | this.global.jasmine.DEFAULT_TIMEOUT_INTERVAL = timeout;
12 | } else {
13 | this.global[Symbol.for('TEST_TIMEOUT_SYMBOL')] = timeout;
14 | }
15 | }
16 |
17 | async setup() {
18 | const browser = await getBrowser();
19 | const page = await browser.newPage();
20 | this.global.browser = browser;
21 | this.global.page = page;
22 | }
23 |
24 | async teardown() {
25 | const { page, browser } = this.global;
26 |
27 | if (page) {
28 | await page.close();
29 | }
30 |
31 | if (browser) {
32 | await browser.disconnect();
33 | }
34 |
35 | if (browser) {
36 | await browser.close();
37 | }
38 | }
39 | }
40 |
41 | module.exports = PuppeteerEnvironment;
42 |
--------------------------------------------------------------------------------
/.github/workflows/issue-open-check.yml:
--------------------------------------------------------------------------------
1 | name: Issue Open Check
2 |
3 | on:
4 | issues:
5 | types: [opened, edited]
6 |
7 | jobs:
8 | check-issue:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions-cool/issues-helper@v2.2.0
12 | id: check
13 | with:
14 | actions: 'check-issue'
15 | issue-number: ${{ github.event.issue.number }}
16 | title-excludes: '🐛[BUG], 👑 [需求], 🧐[问题]'
17 |
18 | - if: steps.check.outputs.check-result == 'false' && github.event.issue.state == 'open'
19 | uses: actions-cool/issues-helper@v2.2.0
20 | with:
21 | actions: 'create-comment, close-issue'
22 | issue-number: ${{ github.event.issue.number }}
23 | body: |
24 | 当前 Issue 未检测到标题,请规范填写,谢谢!
25 |
26 | The title of the current issue is not detected, please fill in according to the specifications, thank you!
27 |
28 | - if: steps.check.outputs.check-result == 'true'
29 | uses: actions-cool/issues-similarity-analysis@v1.1.0
30 | with:
31 | filter-threshold: 0.6
32 | title-excludes: '🐛[BUG], 👑 [需求], 🧐[问题]'
33 | comment-title: '### 以下的 Issues 可能会帮助到你 / The following issues may help you'
34 | show-footer: false
35 |
--------------------------------------------------------------------------------
/tests/getBrowser.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable global-require */
2 | /* eslint-disable import/no-extraneous-dependencies */
3 | const findChrome = require('carlo/lib/find_chrome');
4 |
5 | const getBrowser = async () => {
6 | try {
7 | // eslint-disable-next-line import/no-unresolved
8 | const puppeteer = require('puppeteer');
9 | const browser = await puppeteer.launch({
10 | args: [
11 | '--disable-gpu',
12 | '--disable-dev-shm-usage',
13 | '--no-first-run',
14 | '--no-zygote',
15 | '--no-sandbox',
16 | ],
17 | });
18 | return browser;
19 | } catch (error) {
20 | // console.log(error)
21 | }
22 |
23 | try {
24 | // eslint-disable-next-line import/no-unresolved
25 | const puppeteer = require('puppeteer-core');
26 | const findChromePath = await findChrome({});
27 | const { executablePath } = findChromePath;
28 | const browser = await puppeteer.launch({
29 | executablePath,
30 | args: [
31 | '--disable-gpu',
32 | '--disable-dev-shm-usage',
33 | '--no-first-run',
34 | '--no-zygote',
35 | '--no-sandbox',
36 | ],
37 | });
38 | return browser;
39 | } catch (error) {
40 | console.log('🧲 no find chrome');
41 | }
42 | throw new Error('no find puppeteer');
43 | };
44 |
45 | module.exports = getBrowser;
46 |
--------------------------------------------------------------------------------
/src/locales/zh-CN/settingDrawer.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'app.setting.pagestyle': '整体风格设置',
3 | 'app.setting.pagestyle.dark': '暗色菜单风格',
4 | 'app.setting.pagestyle.light': '亮色菜单风格',
5 | 'app.setting.content-width': '内容区域宽度',
6 | 'app.setting.content-width.fixed': '定宽',
7 | 'app.setting.content-width.fluid': '流式',
8 | 'app.setting.themecolor': '主题色',
9 | 'app.setting.themecolor.dust': '薄暮',
10 | 'app.setting.themecolor.volcano': '火山',
11 | 'app.setting.themecolor.sunset': '日暮',
12 | 'app.setting.themecolor.cyan': '明青',
13 | 'app.setting.themecolor.green': '极光绿',
14 | 'app.setting.themecolor.daybreak': '拂晓蓝(默认)',
15 | 'app.setting.themecolor.geekblue': '极客蓝',
16 | 'app.setting.themecolor.purple': '酱紫',
17 | 'app.setting.navigationmode': '导航模式',
18 | 'app.setting.sidemenu': '侧边菜单布局',
19 | 'app.setting.topmenu': '顶部菜单布局',
20 | 'app.setting.fixedheader': '固定 Header',
21 | 'app.setting.fixedsidebar': '固定侧边菜单',
22 | 'app.setting.fixedsidebar.hint': '侧边菜单布局时可配置',
23 | 'app.setting.hideheader': '下滑时隐藏 Header',
24 | 'app.setting.hideheader.hint': '固定 Header 时可配置',
25 | 'app.setting.othersettings': '其他设置',
26 | 'app.setting.weakmode': '色弱模式',
27 | 'app.setting.copy': '拷贝设置',
28 | 'app.setting.copyinfo': '拷贝成功,请到 config/defaultSettings.js 中替换默认配置',
29 | 'app.setting.production.hint':
30 | '配置栏只在开发环境用于预览,生产环境不会展现,请拷贝后手动修改配置文件',
31 | };
32 |
--------------------------------------------------------------------------------
/src/locales/zh-TW/settingDrawer.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'app.setting.pagestyle': '整體風格設置',
3 | 'app.setting.pagestyle.dark': '暗色菜單風格',
4 | 'app.setting.pagestyle.light': '亮色菜單風格',
5 | 'app.setting.content-width': '內容區域寬度',
6 | 'app.setting.content-width.fixed': '定寬',
7 | 'app.setting.content-width.fluid': '流式',
8 | 'app.setting.themecolor': '主題色',
9 | 'app.setting.themecolor.dust': '薄暮',
10 | 'app.setting.themecolor.volcano': '火山',
11 | 'app.setting.themecolor.sunset': '日暮',
12 | 'app.setting.themecolor.cyan': '明青',
13 | 'app.setting.themecolor.green': '極光綠',
14 | 'app.setting.themecolor.daybreak': '拂曉藍(默認)',
15 | 'app.setting.themecolor.geekblue': '極客藍',
16 | 'app.setting.themecolor.purple': '醬紫',
17 | 'app.setting.navigationmode': '導航模式',
18 | 'app.setting.sidemenu': '側邊菜單布局',
19 | 'app.setting.topmenu': '頂部菜單布局',
20 | 'app.setting.fixedheader': '固定 Header',
21 | 'app.setting.fixedsidebar': '固定側邊菜單',
22 | 'app.setting.fixedsidebar.hint': '側邊菜單布局時可配置',
23 | 'app.setting.hideheader': '下滑時隱藏 Header',
24 | 'app.setting.hideheader.hint': '固定 Header 時可配置',
25 | 'app.setting.othersettings': '其他設置',
26 | 'app.setting.weakmode': '色弱模式',
27 | 'app.setting.copy': '拷貝設置',
28 | 'app.setting.copyinfo': '拷貝成功,請到 config/defaultSettings.js 中替換默認配置',
29 | 'app.setting.production.hint':
30 | '配置欄只在開發環境用於預覽,生產環境不會展現,請拷貝後手動修改配置文件',
31 | };
32 |
--------------------------------------------------------------------------------
/tests/beforeTest.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable global-require */
2 | /* eslint-disable import/no-extraneous-dependencies */
3 | const { execSync } = require('child_process');
4 | const { join } = require('path');
5 | const findChrome = require('carlo/lib/find_chrome');
6 | const detectInstaller = require('detect-installer');
7 |
8 | const installPuppeteer = () => {
9 | // find can use package manager
10 | const packages = detectInstaller(join(__dirname, '../'));
11 | // get installed package manager
12 | const packageName = packages.find(detectInstaller.hasPackageCommand) || 'npm';
13 | console.log(`🤖 will use ${packageName} install puppeteer`);
14 | const command = `${packageName} ${packageName.includes('yarn') ? 'add' : 'i'} puppeteer`;
15 | execSync(command, {
16 | stdio: 'inherit',
17 | });
18 | };
19 |
20 | const initPuppeteer = async () => {
21 | try {
22 | // eslint-disable-next-line import/no-unresolved
23 | const findChromePath = await findChrome({});
24 | const { executablePath } = findChromePath;
25 | console.log(`🧲 find you browser in ${executablePath}`);
26 | return;
27 | } catch (error) {
28 | console.log('🧲 no find chrome');
29 | }
30 |
31 | try {
32 | require.resolve('puppeteer');
33 | } catch (error) {
34 | // need install puppeteer
35 | await installPuppeteer();
36 | }
37 | };
38 |
39 | initPuppeteer();
40 |
--------------------------------------------------------------------------------
/src/locales/ja-JP/settingDrawer.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'app.setting.pagestyle': 'ページスタイル設定',
3 | 'app.setting.pagestyle.dark': 'ダークスタイル',
4 | 'app.setting.pagestyle.light': 'ライトスタイル',
5 | 'app.setting.content-width': 'コンテンツの幅',
6 | 'app.setting.content-width.fixed': '固定',
7 | 'app.setting.content-width.fluid': '流体',
8 | 'app.setting.themecolor': 'テーマカラー',
9 | 'app.setting.themecolor.dust': 'ダストレッド',
10 | 'app.setting.themecolor.volcano': 'ボルケ-ノ',
11 | 'app.setting.themecolor.sunset': 'サンセットオレンジ',
12 | 'app.setting.themecolor.cyan': 'シアン',
13 | 'app.setting.themecolor.green': 'ポーラーグリーン',
14 | 'app.setting.themecolor.daybreak': '夜明けの青(デフォルト)',
15 | 'app.setting.themecolor.geekblue': 'ギーク ブルー',
16 | 'app.setting.themecolor.purple': 'ゴールデンパープル',
17 | 'app.setting.navigationmode': 'ナビゲーションモード',
18 | 'app.setting.sidemenu': 'サイドメニューのレイアウト',
19 | 'app.setting.topmenu': 'トップメニューのレイアウト',
20 | 'app.setting.fixedheader': '固定ヘッダー',
21 | 'app.setting.fixedsidebar': '固定サイドバー',
22 | 'app.setting.fixedsidebar.hint': 'サイドメニューのレイアウトで動作します',
23 | 'app.setting.hideheader': 'スクロール時の非表示ヘッダー',
24 | 'app.setting.hideheader.hint': '非表示ヘッダーが有効になっている場合に機能します',
25 | 'app.setting.othersettings': 'その他の設定',
26 | 'app.setting.weakmode': 'ウィークモード',
27 | 'app.setting.copy': 'コピー設定',
28 | 'app.setting.copyinfo':
29 | 'コピーが成功しました。src/models/setting.jsのdefaultSettingsを置き換えてください',
30 | 'app.setting.production.hint': '設定パネルは開発環境でのみ表示されます。手動で変更してください',
31 | };
32 |
--------------------------------------------------------------------------------
/src/pages/Admin.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { HeartTwoTone, SmileTwoTone } from '@ant-design/icons';
3 | import { Card, Typography, Alert } from 'antd';
4 | import { PageHeaderWrapper } from '@ant-design/pro-layout';
5 | import { useIntl } from 'umi';
6 |
7 | export default (): React.ReactNode => {
8 | const intl = useIntl();
9 | return (
10 |
16 |
17 |
30 |
31 | Ant Design Pro You
32 |
33 |
34 |
35 | Want to add more pages? Please refer to{' '}
36 |
37 | use block
38 |
39 | 。
40 |
41 |
42 | );
43 | };
44 |
--------------------------------------------------------------------------------
/src/pages/product/addProduct/index.tsx:
--------------------------------------------------------------------------------
1 | import React, { useRef } from 'react'
2 | import ProductInfo from '@/components/ProductInfo'
3 | import { Button, Collapse } from 'antd'
4 | import { history, useLocation } from 'umi'
5 |
6 | const { Panel } = Collapse
7 |
8 | const formInput = (props: any) => {
9 | const params = useLocation()
10 | console.log(props)
11 | console.log(params)
12 | // hash: ""
13 | // key: "inw4iu"
14 | // pathname: "/product/add"
15 | // query: {name: "跳转的参数"}
16 | // search: "name=%E8%B7%B3%E8%BD%AC%E7%9A%84%E5%8F%82%E6%95%B0"
17 |
18 | const childRef = useRef()
19 |
20 | // 保存
21 | const onSave = async() => {
22 | // 获取子组件数据
23 | const childForm = childRef.current.getForm()
24 | await childForm.validateFields()
25 | const data = childForm.getFieldsValue()
26 | console.log(data)
27 | }
28 |
29 | return (
30 |
31 |
32 | {/* */}
35 |
36 |
37 |
38 | {/*子组件 */}
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | )
53 | }
54 |
55 | export default formInput
--------------------------------------------------------------------------------
/src/locales/fa-IR/settingDrawer.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'app.setting.pagestyle': 'تنظیم نوع صفحه',
3 | 'app.setting.pagestyle.dark': 'سبک تیره',
4 | 'app.setting.pagestyle.light': 'سبک سبک',
5 | 'app.setting.content-width': 'عرض محتوا',
6 | 'app.setting.content-width.fixed': 'ثابت',
7 | 'app.setting.content-width.fluid': 'شناور',
8 | 'app.setting.themecolor': 'رنگ تم',
9 | 'app.setting.themecolor.dust': 'گرد و غبار قرمز',
10 | 'app.setting.themecolor.volcano': 'آتشفشان',
11 | 'app.setting.themecolor.sunset': 'غروب نارنجی',
12 | 'app.setting.themecolor.cyan': 'فیروزه ای',
13 | 'app.setting.themecolor.green': 'سبز قطبی',
14 | 'app.setting.themecolor.daybreak': 'آبی روشن(پیشفرض)',
15 | 'app.setting.themecolor.geekblue': 'چسب گیک',
16 | 'app.setting.themecolor.purple': 'بنفش طلایی',
17 | 'app.setting.navigationmode': 'حالت پیمایش',
18 | 'app.setting.sidemenu': 'طرح منوی کناری',
19 | 'app.setting.topmenu': 'طرح منوی بالایی',
20 | 'app.setting.fixedheader': 'سرصفحه ثابت',
21 | 'app.setting.fixedsidebar': 'نوار کناری ثابت',
22 | 'app.setting.fixedsidebar.hint': 'کار بر روی منوی کناری',
23 | 'app.setting.hideheader': 'هدر پنهان هنگام پیمایش',
24 | 'app.setting.hideheader.hint': 'وقتی Hidden Header فعال باشد کار می کند',
25 | 'app.setting.othersettings': 'تنظیمات دیگر',
26 | 'app.setting.weakmode': 'حالت ضعیف',
27 | 'app.setting.copy': 'تنظیمات کپی',
28 | 'app.setting.copyinfo':
29 | 'موفقیت در کپی کردن , لطفا defaultSettings را در src / models / setting.js جایگزین کنید',
30 | 'app.setting.production.hint':
31 | 'صفحه تنظیم فقط در محیط توسعه نمایش داده می شود ، لطفاً دستی تغییر دهید',
32 | };
33 |
--------------------------------------------------------------------------------
/src/locales/en-US/settingDrawer.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'app.setting.pagestyle': 'Page style setting',
3 | 'app.setting.pagestyle.dark': 'Dark style',
4 | 'app.setting.pagestyle.light': 'Light style',
5 | 'app.setting.content-width': 'Content Width',
6 | 'app.setting.content-width.fixed': 'Fixed',
7 | 'app.setting.content-width.fluid': 'Fluid',
8 | 'app.setting.themecolor': 'Theme Color',
9 | 'app.setting.themecolor.dust': 'Dust Red',
10 | 'app.setting.themecolor.volcano': 'Volcano',
11 | 'app.setting.themecolor.sunset': 'Sunset Orange',
12 | 'app.setting.themecolor.cyan': 'Cyan',
13 | 'app.setting.themecolor.green': 'Polar Green',
14 | 'app.setting.themecolor.daybreak': 'Daybreak Blue (default)',
15 | 'app.setting.themecolor.geekblue': 'Geek Glue',
16 | 'app.setting.themecolor.purple': 'Golden Purple',
17 | 'app.setting.navigationmode': 'Navigation Mode',
18 | 'app.setting.sidemenu': 'Side Menu Layout',
19 | 'app.setting.topmenu': 'Top Menu Layout',
20 | 'app.setting.fixedheader': 'Fixed Header',
21 | 'app.setting.fixedsidebar': 'Fixed Sidebar',
22 | 'app.setting.fixedsidebar.hint': 'Works on Side Menu Layout',
23 | 'app.setting.hideheader': 'Hidden Header when scrolling',
24 | 'app.setting.hideheader.hint': 'Works when Hidden Header is enabled',
25 | 'app.setting.othersettings': 'Other Settings',
26 | 'app.setting.weakmode': 'Weak Mode',
27 | 'app.setting.copy': 'Copy Setting',
28 | 'app.setting.copyinfo': 'copy success,please replace defaultSettings in src/models/setting.js',
29 | 'app.setting.production.hint':
30 | 'Setting panel shows in development environment only, please manually modify',
31 | };
32 |
--------------------------------------------------------------------------------
/tests/run-tests.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable eslint-comments/disable-enable-pair */
2 | /* eslint-disable @typescript-eslint/no-var-requires */
3 | /* eslint-disable eslint-comments/no-unlimited-disable */
4 | const { spawn } = require('child_process');
5 | // eslint-disable-next-line import/no-extraneous-dependencies
6 | const { kill } = require('cross-port-killer');
7 |
8 | const env = Object.create(process.env);
9 | env.BROWSER = 'none';
10 | env.TEST = true;
11 | env.UMI_UI = 'none';
12 | env.PROGRESS = 'none';
13 | // flag to prevent multiple test
14 | let once = false;
15 |
16 | const startServer = spawn(/^win/.test(process.platform) ? 'npm.cmd' : 'npm', ['run', 'serve'], {
17 | env,
18 | });
19 |
20 | startServer.stderr.on('data', (data) => {
21 | // eslint-disable-next-line
22 | console.log(data.toString());
23 | });
24 |
25 | startServer.on('exit', () => {
26 | kill(process.env.PORT || 8000);
27 | });
28 |
29 | console.log('Starting development server for e2e tests...');
30 | startServer.stdout.on('data', (data) => {
31 | console.log(data.toString());
32 | // hack code , wait umi
33 | if (!once && data.toString().indexOf('Serving your umi project!') >= 0) {
34 | // eslint-disable-next-line
35 | once = true;
36 | console.log('Development server is started, ready to run tests.');
37 | const testCmd = spawn(
38 | /^win/.test(process.platform) ? 'npm.cmd' : 'npm',
39 | ['test', '--', '--maxWorkers=1', '--runInBand'],
40 | {
41 | stdio: 'inherit',
42 | },
43 | );
44 | testCmd.on('exit', (code) => {
45 | console.log(code);
46 | startServer.kill();
47 | process.exit(code);
48 | });
49 | }
50 | });
51 |
--------------------------------------------------------------------------------
/src/pages/dataManage/project/components/four.tsx:
--------------------------------------------------------------------------------
1 | import { Descriptions, Form, Input, Button, Row, Col } from 'antd'
2 | import React from 'react'
3 | import { connect } from 'dva'
4 |
5 | const Project4: React.Fc = (props: any) => {
6 | const { useInfo } = props.user
7 |
8 | const onFinish = (values) => {
9 |
10 | props.dispatch({
11 | type: 'user/changeState',
12 | payload: values,
13 | })
14 | }
15 |
16 | return
17 |
18 | {useInfo.userName}
19 | {useInfo.age}
20 |
21 |
49 |
52 |
53 |
54 |
55 | }
56 |
57 | export default connect(({ user }) => ({
58 | user,
59 | }))(Project4)
--------------------------------------------------------------------------------
/src/pages/editor/add/index.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Button, message, Input } from 'antd'
3 | // 引入编辑器组件
4 | import BraftEditor from 'braft-editor'
5 | // 引入编辑器样式
6 | import 'braft-editor/dist/index.css'
7 | import { useState } from "react";
8 | import { addArticle } from '@/services/ant-design-pro'
9 |
10 | const AddEditor: React.FC = () => {
11 | const [editorState, setEditorState] = useState(BraftEditor.createEditorState(null))
12 | const [title, setTitle] = useState('')
13 |
14 | // 值改变
15 | const handleEditorChange = (state: any) => {
16 | setEditorState(state)
17 | }
18 | // 提交
19 | const submitContent = async() => {
20 | console.log(title, editorState)
21 | const stateHtml = editorState.toHTML()
22 | const stateRaw = editorState.toRAW()
23 | if (title && stateHtml !== '') {
24 | await addArticle({
25 | title,
26 | content: stateRaw
27 | })
28 | message.success('添加成功')
29 | } else {
30 | message.warning('请先填写标题和内容')
31 | }
32 | }
33 |
34 | return (
35 |
36 |
富文本编辑
37 |
38 |
39 |
文章标题
40 |
setTitle(e.target.value)} />
41 |
42 |
文章内容
43 |
48 |
49 |
52 |
53 | )
54 | }
55 |
56 | export default AddEditor
--------------------------------------------------------------------------------
/src/locales/id-ID/settingDrawer.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'app.setting.pagestyle': 'Pengaturan style Halaman',
3 | 'app.setting.pagestyle.dark': 'Style Gelap',
4 | 'app.setting.pagestyle.light': 'Style Cerah',
5 | 'app.setting.content-width': 'Lebar Konten',
6 | 'app.setting.content-width.fixed': 'Tetap',
7 | 'app.setting.content-width.fluid': 'Fluid',
8 | 'app.setting.themecolor': 'Theme Color',
9 | 'app.setting.themecolor.dust': 'Dust Red',
10 | 'app.setting.themecolor.volcano': 'Volcano',
11 | 'app.setting.themecolor.sunset': 'Sunset Orange',
12 | 'app.setting.themecolor.cyan': 'Cyan',
13 | 'app.setting.themecolor.green': 'Polar Green',
14 | 'app.setting.themecolor.daybreak': 'Daybreak Blue (bawaan)',
15 | 'app.setting.themecolor.geekblue': 'Geek Glue',
16 | 'app.setting.themecolor.purple': 'Golden Purple',
17 | 'app.setting.navigationmode': 'Mode Navigasi',
18 | 'app.setting.sidemenu': 'Susunan Menu Samping',
19 | 'app.setting.topmenu': 'Susunan Menu Atas',
20 | 'app.setting.fixedheader': 'Header Tetap',
21 | 'app.setting.fixedsidebar': 'Sidebar Tetap',
22 | 'app.setting.fixedsidebar.hint': 'Berjalan pada Susunan Menu Samping',
23 | 'app.setting.hideheader': 'Sembunyikan Header ketika gulir ke bawah',
24 | 'app.setting.hideheader.hint': 'Bekerja ketika Header tersembunyi dimunculkan',
25 | 'app.setting.othersettings': 'Pengaturan Lainnya',
26 | 'app.setting.weakmode': 'Mode Lemah',
27 | 'app.setting.copy': 'Salin Pengaturan',
28 | 'app.setting.copyinfo':
29 | 'Berhasil disalin,tolong ubah defaultSettings pada src/models/setting.js',
30 | 'app.setting.production.hint':
31 | 'Panel pengaturan hanya muncul pada lingkungan pengembangan, silahkan modifikasi secara menual',
32 | };
33 |
--------------------------------------------------------------------------------
/src/components/RightContent/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | @pro-header-hover-bg: rgba(0, 0, 0, 0.025);
4 |
5 | .menu {
6 | :global(.anticon) {
7 | margin-right: 8px;
8 | }
9 | :global(.ant-dropdown-menu-item) {
10 | min-width: 160px;
11 | }
12 | }
13 |
14 | .right {
15 | display: flex;
16 | float: right;
17 | height: 48px;
18 | margin-left: auto;
19 | overflow: hidden;
20 | .action {
21 | display: flex;
22 | align-items: center;
23 | height: 48px;
24 | padding: 0 12px;
25 | cursor: pointer;
26 | transition: all 0.3s;
27 | > span {
28 | vertical-align: middle;
29 | }
30 | &:hover {
31 | background: @pro-header-hover-bg;
32 | }
33 | &:global(.opened) {
34 | background: @pro-header-hover-bg;
35 | }
36 | }
37 | .search {
38 | padding: 0 12px;
39 | &:hover {
40 | background: transparent;
41 | }
42 | }
43 | .account {
44 | .avatar {
45 | margin-right: 8px;
46 | color: @primary-color;
47 | vertical-align: top;
48 | background: rgba(255, 255, 255, 0.85);
49 | }
50 | }
51 | }
52 |
53 | .dark {
54 | .action {
55 | &:hover {
56 | background: #252a3d;
57 | }
58 | &:global(.opened) {
59 | background: #252a3d;
60 | }
61 | }
62 | }
63 |
64 | @media only screen and (max-width: @screen-md) {
65 | :global(.ant-divider-vertical) {
66 | vertical-align: unset;
67 | }
68 | .name {
69 | display: none;
70 | }
71 | .right {
72 | position: absolute;
73 | top: 0;
74 | right: 12px;
75 | .account {
76 | .avatar {
77 | margin-right: 0;
78 | }
79 | }
80 | .search {
81 | display: none;
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/locales/pt-BR/settingDrawer.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'app.setting.pagestyle': 'Configuração de estilo da página',
3 | 'app.setting.pagestyle.dark': 'Dark style',
4 | 'app.setting.pagestyle.light': 'Light style',
5 | 'app.setting.content-width': 'Largura do conteúdo',
6 | 'app.setting.content-width.fixed': 'Fixo',
7 | 'app.setting.content-width.fluid': 'Fluido',
8 | 'app.setting.themecolor': 'Cor do Tema',
9 | 'app.setting.themecolor.dust': 'Dust Red',
10 | 'app.setting.themecolor.volcano': 'Volcano',
11 | 'app.setting.themecolor.sunset': 'Sunset Orange',
12 | 'app.setting.themecolor.cyan': 'Cyan',
13 | 'app.setting.themecolor.green': 'Polar Green',
14 | 'app.setting.themecolor.daybreak': 'Daybreak Blue (default)',
15 | 'app.setting.themecolor.geekblue': 'Geek Glue',
16 | 'app.setting.themecolor.purple': 'Golden Purple',
17 | 'app.setting.navigationmode': 'Modo de Navegação',
18 | 'app.setting.sidemenu': 'Layout do Menu Lateral',
19 | 'app.setting.topmenu': 'Layout do Menu Superior',
20 | 'app.setting.fixedheader': 'Cabeçalho fixo',
21 | 'app.setting.fixedsidebar': 'Barra lateral fixa',
22 | 'app.setting.fixedsidebar.hint': 'Funciona no layout do menu lateral',
23 | 'app.setting.hideheader': 'Esconder o cabeçalho quando rolar',
24 | 'app.setting.hideheader.hint': 'Funciona quando o esconder cabeçalho está abilitado',
25 | 'app.setting.othersettings': 'Outras configurações',
26 | 'app.setting.weakmode': 'Weak Mode',
27 | 'app.setting.copy': 'Copiar Configuração',
28 | 'app.setting.copyinfo':
29 | 'copiado com sucesso,por favor trocar o defaultSettings em src/models/setting.js',
30 | 'app.setting.production.hint':
31 | 'O painel de configuração apenas é exibido no ambiente de desenvolvimento, por favor modifique manualmente o',
32 | };
33 |
--------------------------------------------------------------------------------
/src/pages/editor/list/index.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import type { articleProps } from 'mock/editor'
3 | import ProTable from '@ant-design/pro-table';
4 | import type { ProColumns } from '@ant-design/pro-table';
5 | import { Button } from 'antd';
6 | import { PlusOutlined } from '@ant-design/icons';
7 | import { getArticleList } from '@/services/ant-design-pro'
8 | import { history } from 'umi'
9 |
10 | const EditorList: React.FC = () => {
11 |
12 | const columns: ProColumns[] = [
13 | {
14 | title: '序号',
15 | dataIndex: 'index',
16 | valueType: 'indexBorder',
17 | width: 48,
18 | },
19 | {
20 | title: '文章标题',
21 | dataIndex: 'title',
22 | ellipsis: true,
23 | },
24 | {
25 | title: '创建时间',
26 | dataIndex: 'createTime',
27 | },
28 | ]
29 |
30 | const getList = async() => {
31 | const { data } = await getArticleList()
32 | return {
33 | data,
34 | total: data.length
35 | }
36 | }
37 |
38 | return (
39 |
40 |
41 | columns={columns}
42 | request={getList}
43 | rowKey="id"
44 | search={false}
45 | pagination={{
46 | pageSize: 10,
47 | }}
48 | dateFormatter="string"
49 | headerTitle="文章列表"
50 | toolBarRender={() => [
51 | }
54 | type="primary"
55 | onClick={()=>{
56 | history.push({
57 | pathname: '/editor/add',
58 | query: {
59 | name: '跳转的参数'
60 | }
61 | })
62 | }}
63 | >
64 | 新建
65 | ,
66 | ]}
67 | />
68 |
69 | )
70 | }
71 |
72 | export default EditorList
--------------------------------------------------------------------------------
/src/locales/zh-CN/menu.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'menu.welcome': '欢迎',
3 | 'menu.more-blocks': '更多区块',
4 | 'menu.home': '首页',
5 | 'menu.admin': '管理页',
6 | 'menu.admin.sub-page': '二级管理页',
7 | 'menu.login': '登录',
8 | 'menu.register': '注册',
9 | 'menu.register.result': '注册结果',
10 | 'menu.dashboard': 'Dashboard',
11 | 'menu.dashboard.analysis': '分析页',
12 | 'menu.dashboard.monitor': '监控页',
13 | 'menu.dashboard.workplace': '工作台',
14 | 'menu.exception.403': '403',
15 | 'menu.exception.404': '404',
16 | 'menu.exception.500': '500',
17 | 'menu.form': '表单页',
18 | 'menu.form.basic-form': '基础表单',
19 | 'menu.form.step-form': '分步表单',
20 | 'menu.form.step-form.info': '分步表单(填写转账信息)',
21 | 'menu.form.step-form.confirm': '分步表单(确认转账信息)',
22 | 'menu.form.step-form.result': '分步表单(完成)',
23 | 'menu.form.advanced-form': '高级表单',
24 | 'menu.list': '列表页',
25 | 'menu.list.table-list': '查询表格',
26 | 'menu.list.basic-list': '标准列表',
27 | 'menu.list.card-list': '卡片列表',
28 | 'menu.list.search-list': '搜索列表',
29 | 'menu.list.search-list.articles': '搜索列表(文章)',
30 | 'menu.list.search-list.projects': '搜索列表(项目)',
31 | 'menu.list.search-list.applications': '搜索列表(应用)',
32 | 'menu.profile': '详情页',
33 | 'menu.profile.basic': '基础详情页',
34 | 'menu.profile.advanced': '高级详情页',
35 | 'menu.result': '结果页',
36 | 'menu.result.success': '成功页',
37 | 'menu.result.fail': '失败页',
38 | 'menu.exception': '异常页',
39 | 'menu.exception.not-permission': '403',
40 | 'menu.exception.not-find': '404',
41 | 'menu.exception.server-error': '500',
42 | 'menu.exception.trigger': '触发错误',
43 | 'menu.account': '个人页',
44 | 'menu.account.center': '个人中心',
45 | 'menu.account.settings': '个人设置',
46 | 'menu.account.trigger': '触发报错',
47 | 'menu.account.logout': '退出登录',
48 | 'menu.editor': '图形编辑器',
49 | 'menu.editor.flow': '流程编辑器',
50 | 'menu.editor.mind': '脑图编辑器',
51 | 'menu.editor.koni': '拓扑编辑器',
52 | };
53 |
--------------------------------------------------------------------------------
/src/locales/zh-TW/menu.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'menu.welcome': '歡迎',
3 | 'menu.more-blocks': '更多區塊',
4 | 'menu.home': '首頁',
5 | 'menu.login': '登錄',
6 | 'menu.admin': '权限',
7 | 'menu.admin.sub-page': '二级管理页',
8 | 'menu.exception.403': '403',
9 | 'menu.exception.404': '404',
10 | 'menu.exception.500': '500',
11 | 'menu.register': '註冊',
12 | 'menu.register.result': '註冊結果',
13 | 'menu.dashboard': 'Dashboard',
14 | 'menu.dashboard.analysis': '分析頁',
15 | 'menu.dashboard.monitor': '監控頁',
16 | 'menu.dashboard.workplace': '工作臺',
17 | 'menu.form': '表單頁',
18 | 'menu.form.basic-form': '基礎表單',
19 | 'menu.form.step-form': '分步表單',
20 | 'menu.form.step-form.info': '分步表單(填寫轉賬信息)',
21 | 'menu.form.step-form.confirm': '分步表單(確認轉賬信息)',
22 | 'menu.form.step-form.result': '分步表單(完成)',
23 | 'menu.form.advanced-form': '高級表單',
24 | 'menu.list': '列表頁',
25 | 'menu.list.table-list': '查詢表格',
26 | 'menu.list.basic-list': '標淮列表',
27 | 'menu.list.card-list': '卡片列表',
28 | 'menu.list.search-list': '搜索列表',
29 | 'menu.list.search-list.articles': '搜索列表(文章)',
30 | 'menu.list.search-list.projects': '搜索列表(項目)',
31 | 'menu.list.search-list.applications': '搜索列表(應用)',
32 | 'menu.profile': '詳情頁',
33 | 'menu.profile.basic': '基礎詳情頁',
34 | 'menu.profile.advanced': '高級詳情頁',
35 | 'menu.result': '結果頁',
36 | 'menu.result.success': '成功頁',
37 | 'menu.result.fail': '失敗頁',
38 | 'menu.account': '個人頁',
39 | 'menu.account.center': '個人中心',
40 | 'menu.account.settings': '個人設置',
41 | 'menu.account.trigger': '觸發報錯',
42 | 'menu.account.logout': '退出登錄',
43 | 'menu.exception': '异常页',
44 | 'menu.exception.not-permission': '403',
45 | 'menu.exception.not-find': '404',
46 | 'menu.exception.server-error': '500',
47 | 'menu.exception.trigger': '触发错误',
48 | 'menu.editor': '圖形編輯器',
49 | 'menu.editor.flow': '流程編輯器',
50 | 'menu.editor.mind': '腦圖編輯器',
51 | 'menu.editor.koni': '拓撲編輯器',
52 | };
53 |
--------------------------------------------------------------------------------
/src/services/swagger/store.ts:
--------------------------------------------------------------------------------
1 | // @ts-ignore
2 | /* eslint-disable */
3 | import { request } from 'umi';
4 |
5 | /** Returns pet inventories by status Returns a map of status codes to quantities GET /store/inventory */
6 | export async function getInventory(options?: { [key: string]: any }) {
7 | return request>('/store/inventory', {
8 | method: 'GET',
9 | ...(options || {}),
10 | });
11 | }
12 |
13 | /** Place an order for a pet POST /store/order */
14 | export async function placeOrder(body: API.Order, options?: { [key: string]: any }) {
15 | return request('/store/order', {
16 | method: 'POST',
17 | data: body,
18 | ...(options || {}),
19 | });
20 | }
21 |
22 | /** Find purchase order by ID For valid response try integer IDs with value >= 1 and <= 10. Other values will generated exceptions GET /store/order/${param0} */
23 | export async function getOrderById(
24 | params: {
25 | // path
26 | /** ID of pet that needs to be fetched */
27 | orderId: number;
28 | },
29 | options?: { [key: string]: any },
30 | ) {
31 | const { orderId: param0 } = params;
32 | return request(`/store/order/${param0}`, {
33 | method: 'GET',
34 | params: { ...params },
35 | ...(options || {}),
36 | });
37 | }
38 |
39 | /** Delete purchase order by ID For valid response try integer IDs with positive integer value. Negative or non-integer values will generate API errors DELETE /store/order/${param0} */
40 | export async function deleteOrder(
41 | params: {
42 | // path
43 | /** ID of the order that needs to be deleted */
44 | orderId: number;
45 | },
46 | options?: { [key: string]: any },
47 | ) {
48 | const { orderId: param0 } = params;
49 | return request(`/store/order/${param0}`, {
50 | method: 'DELETE',
51 | params: { ...params },
52 | ...(options || {}),
53 | });
54 | }
55 |
--------------------------------------------------------------------------------
/src/locales/ja-JP/menu.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'menu.welcome': 'ようこそ',
3 | 'menu.more-blocks': 'その他のブロック',
4 | 'menu.home': 'ホーム',
5 | 'menu.admin': '管理者',
6 | 'menu.admin.sub-page': 'サブページ',
7 | 'menu.login': 'ログイン',
8 | 'menu.register': '登録',
9 | 'menu.register.result': '登録結果',
10 | 'menu.dashboard': 'ダッシュボード',
11 | 'menu.dashboard.analysis': '分析',
12 | 'menu.dashboard.monitor': 'モニター',
13 | 'menu.dashboard.workplace': '職場',
14 | 'menu.exception.403': '403',
15 | 'menu.exception.404': '404',
16 | 'menu.exception.500': '500',
17 | 'menu.form': 'フォーム',
18 | 'menu.form.basic-form': '基本フォーム',
19 | 'menu.form.step-form': 'ステップフォーム',
20 | 'menu.form.step-form.info': 'ステップフォーム(転送情報の書き込み)',
21 | 'menu.form.step-form.confirm': 'ステップフォーム(転送情報の確認)',
22 | 'menu.form.step-form.result': 'ステップフォーム(完成)',
23 | 'menu.form.advanced-form': '高度なフォーム',
24 | 'menu.list': 'リスト',
25 | 'menu.list.table-list': '検索テーブル',
26 | 'menu.list.basic-list': '基本リスト',
27 | 'menu.list.card-list': 'カードリスト',
28 | 'menu.list.search-list': '検索リスト',
29 | 'menu.list.search-list.articles': '検索リスト(記事)',
30 | 'menu.list.search-list.projects': '検索リスト(プロジェクト)',
31 | 'menu.list.search-list.applications': '検索リスト(アプリ)',
32 | 'menu.profile': 'プロフィール',
33 | 'menu.profile.basic': '基本プロフィール',
34 | 'menu.profile.advanced': '高度なプロフィール',
35 | 'menu.result': '結果',
36 | 'menu.result.success': '成功',
37 | 'menu.result.fail': '失敗',
38 | 'menu.exception': '例外',
39 | 'menu.exception.not-permission': '403',
40 | 'menu.exception.not-find': '404',
41 | 'menu.exception.server-error': '500',
42 | 'menu.exception.trigger': 'トリガー',
43 | 'menu.account': 'アカウント',
44 | 'menu.account.center': 'アカウントセンター',
45 | 'menu.account.settings': 'アカウント設定',
46 | 'menu.account.trigger': 'トリガーエラー',
47 | 'menu.account.logout': 'ログアウト',
48 | 'menu.editor': 'グラフィックエディタ',
49 | 'menu.editor.flow': 'フローエディタ',
50 | 'menu.editor.mind': 'マインドエディター',
51 | 'menu.editor.koni': 'コニエディター',
52 | };
53 |
--------------------------------------------------------------------------------
/src/e2e/baseLayout.e2e.js:
--------------------------------------------------------------------------------
1 | const { uniq } = require('lodash');
2 | const RouterConfig = require('../../config/config').default.routes;
3 |
4 | const BASE_URL = `http://localhost:${process.env.PORT || 8001}`;
5 |
6 | function formatter(routes, parentPath = '') {
7 | const fixedParentPath = parentPath.replace(/\/{1,}/g, '/');
8 | let result = [];
9 | routes.forEach((item) => {
10 | if (item.path && !item.path.startsWith('/')) {
11 | result.push(`${fixedParentPath}/${item.path}`.replace(/\/{1,}/g, '/'));
12 | }
13 | if (item.path && item.path.startsWith('/')) {
14 | result.push(`${item.path}`.replace(/\/{1,}/g, '/'));
15 | }
16 | if (item.routes) {
17 | result = result.concat(
18 | formatter(item.routes, item.path ? `${fixedParentPath}/${item.path}` : parentPath),
19 | );
20 | }
21 | });
22 | return uniq(result.filter((item) => !!item));
23 | }
24 |
25 | beforeEach(async () => {
26 | await page.goto(`${BASE_URL}`);
27 | await page.evaluate(() => {
28 | localStorage.setItem('antd-pro-authority', '["admin"]');
29 | });
30 | });
31 |
32 | describe('Ant Design Pro E2E test', () => {
33 | const testPage = (path) => async () => {
34 | await page.goto(`${BASE_URL}${path}`);
35 | await page.waitForSelector('footer', {
36 | timeout: 2000,
37 | });
38 | const haveFooter = await page.evaluate(
39 | () => document.getElementsByTagName('footer').length > 0,
40 | );
41 | expect(haveFooter).toBeTruthy();
42 | };
43 |
44 | const routers = formatter(RouterConfig);
45 | routers.forEach((route) => {
46 | it(`test pages ${route}`, testPage(route));
47 | });
48 |
49 | it('topmenu should have footer', async () => {
50 | const params = '?navTheme=light&layout=topmenu';
51 | await page.goto(`${BASE_URL}${params}`);
52 | await page.waitForSelector('footer', {
53 | timeout: 2000,
54 | });
55 |
56 | const haveFooter = await page.evaluate(
57 | () => document.getElementsByTagName('footer').length > 0,
58 | );
59 | expect(haveFooter).toBeTruthy();
60 | });
61 | });
62 |
--------------------------------------------------------------------------------
/src/components/RightContent/index.tsx:
--------------------------------------------------------------------------------
1 | import { Space } from 'antd';
2 | import { QuestionCircleOutlined } from '@ant-design/icons';
3 | import React from 'react';
4 | import { useModel, SelectLang } from 'umi';
5 | import Avatar from './AvatarDropdown';
6 | import HeaderSearch from '../HeaderSearch';
7 | import styles from './index.less';
8 |
9 | export type SiderTheme = 'light' | 'dark';
10 |
11 | const GlobalHeaderRight: React.FC = () => {
12 | const { initialState } = useModel('@@initialState');
13 |
14 | if (!initialState || !initialState.settings) {
15 | return null;
16 | }
17 |
18 | const { navTheme, layout } = initialState.settings;
19 | let className = styles.right;
20 |
21 | if ((navTheme === 'dark' && layout === 'top') || layout === 'mix') {
22 | className = `${styles.right} ${styles.dark}`;
23 | }
24 | return (
25 |
26 | umi ui, value: 'umi ui' },
32 | {
33 | label: Ant Design,
34 | value: 'Ant Design',
35 | },
36 | {
37 | label: Pro Table,
38 | value: 'Pro Table',
39 | },
40 | {
41 | label: Pro Layout,
42 | value: 'Pro Layout',
43 | },
44 | ]}
45 | // onSearch={value => {
46 | // console.log('input', value);
47 | // }}
48 | />
49 | {
52 | window.open('https://pro.ant.design/docs/getting-started');
53 | }}
54 | >
55 |
56 |
57 |
58 |
59 |
60 | );
61 | };
62 | export default GlobalHeaderRight;
63 |
--------------------------------------------------------------------------------
/src/locales/fa-IR/menu.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'menu.welcome': 'خوش آمدید',
3 | 'menu.more-blocks': 'بلوک های بیشتر',
4 | 'menu.home': 'خانه',
5 | 'menu.admin': 'مدیر',
6 | 'menu.admin.sub-page': 'زیر صفحه',
7 | 'menu.login': 'ورود',
8 | 'menu.register': 'ثبت نام',
9 | 'menu.register.result': 'ثبت نام نتیجه',
10 | 'menu.dashboard': 'داشبورد',
11 | 'menu.dashboard.analysis': 'تحلیل و بررسی',
12 | 'menu.dashboard.monitor': 'نظارت',
13 | 'menu.dashboard.workplace': 'محل کار',
14 | 'menu.exception.403': '403',
15 | 'menu.exception.404': '404',
16 | 'menu.exception.500': '500',
17 | 'menu.form': 'فرم',
18 | 'menu.form.basic-form': 'فرم اساسی',
19 | 'menu.form.step-form': 'فرم مرحله',
20 | 'menu.form.step-form.info': 'فرم مرحله (نوشتن اطلاعات انتقال)',
21 | 'menu.form.step-form.confirm': 'فرم مرحله (تأیید اطلاعات انتقال)',
22 | 'menu.form.step-form.result': 'فرم مرحله (تمام شده)',
23 | 'menu.form.advanced-form': 'فرم پیشرفته',
24 | 'menu.list': 'لیست',
25 | 'menu.list.table-list': 'جدول جستجو',
26 | 'menu.list.basic-list': 'لیست اصلی',
27 | 'menu.list.card-list': 'لیست کارت',
28 | 'menu.list.search-list': 'لیست جستجو',
29 | 'menu.list.search-list.articles': 'لیست جستجو (مقالات)',
30 | 'menu.list.search-list.projects': 'لیست جستجو (پروژه ها)',
31 | 'menu.list.search-list.applications': 'لیست جستجو (برنامه ها)',
32 | 'menu.profile': 'مشخصات',
33 | 'menu.profile.basic': 'مشخصات عمومی',
34 | 'menu.profile.advanced': 'مشخصات پیشرفته',
35 | 'menu.result': 'نتیجه',
36 | 'menu.result.success': 'موفق',
37 | 'menu.result.fail': 'ناموفق',
38 | 'menu.exception': 'استثنا',
39 | 'menu.exception.not-permission': '403',
40 | 'menu.exception.not-find': '404',
41 | 'menu.exception.server-error': '500',
42 | 'menu.exception.trigger': 'راه اندازی',
43 | 'menu.account': 'حساب',
44 | 'menu.account.center': 'مرکز حساب',
45 | 'menu.account.settings': 'تنظیمات حساب',
46 | 'menu.account.trigger': 'خطای راه اندازی',
47 | 'menu.account.logout': 'خروج',
48 | 'menu.editor': 'ویرایشگر گرافیک',
49 | 'menu.editor.flow': 'ویرایشگر جریان',
50 | 'menu.editor.mind': 'ویرایشگر ذهن',
51 | 'menu.editor.koni': 'ویرایشگر Koni',
52 | };
53 |
--------------------------------------------------------------------------------
/src/locales/en-US/menu.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'menu.welcome': 'Welcome',
3 | 'menu.more-blocks': 'More Blocks',
4 | 'menu.home': 'Home',
5 | 'menu.admin': 'Admin',
6 | 'menu.admin.sub-page': 'Sub-Page',
7 | 'menu.login': 'Login',
8 | 'menu.register': 'Register',
9 | 'menu.register.result': 'Register Result',
10 | 'menu.dashboard': 'Dashboard',
11 | 'menu.dashboard.analysis': 'Analysis',
12 | 'menu.dashboard.monitor': 'Monitor',
13 | 'menu.dashboard.workplace': 'Workplace',
14 | 'menu.exception.403': '403',
15 | 'menu.exception.404': '404',
16 | 'menu.exception.500': '500',
17 | 'menu.form': 'Form',
18 | 'menu.form.basic-form': 'Basic Form',
19 | 'menu.form.step-form': 'Step Form',
20 | 'menu.form.step-form.info': 'Step Form(write transfer information)',
21 | 'menu.form.step-form.confirm': 'Step Form(confirm transfer information)',
22 | 'menu.form.step-form.result': 'Step Form(finished)',
23 | 'menu.form.advanced-form': 'Advanced Form',
24 | 'menu.list': 'List',
25 | 'menu.list.table-list': 'Search Table',
26 | 'menu.list.basic-list': 'Basic List',
27 | 'menu.list.card-list': 'Card List',
28 | 'menu.list.search-list': 'Search List',
29 | 'menu.list.search-list.articles': 'Search List(articles)',
30 | 'menu.list.search-list.projects': 'Search List(projects)',
31 | 'menu.list.search-list.applications': 'Search List(applications)',
32 | 'menu.profile': 'Profile',
33 | 'menu.profile.basic': 'Basic Profile',
34 | 'menu.profile.advanced': 'Advanced Profile',
35 | 'menu.result': 'Result',
36 | 'menu.result.success': 'Success',
37 | 'menu.result.fail': 'Fail',
38 | 'menu.exception': 'Exception',
39 | 'menu.exception.not-permission': '403',
40 | 'menu.exception.not-find': '404',
41 | 'menu.exception.server-error': '500',
42 | 'menu.exception.trigger': 'Trigger',
43 | 'menu.account': 'Account',
44 | 'menu.account.center': 'Account Center',
45 | 'menu.account.settings': 'Account Settings',
46 | 'menu.account.trigger': 'Trigger Error',
47 | 'menu.account.logout': 'Logout',
48 | 'menu.editor': 'Graphic Editor',
49 | 'menu.editor.flow': 'Flow Editor',
50 | 'menu.editor.mind': 'Mind Editor',
51 | 'menu.editor.koni': 'Koni Editor',
52 | };
53 |
--------------------------------------------------------------------------------
/src/pages/Welcome.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { PageContainer } from '@ant-design/pro-layout';
3 | import { Card, Alert, Typography } from 'antd';
4 | import { useIntl, FormattedMessage } from 'umi';
5 | import styles from './Welcome.less';
6 |
7 | const CodePreview: React.FC = ({ children }) => (
8 |
9 |
10 | {children}
11 |
12 |
13 | );
14 |
15 | export default (): React.ReactNode => {
16 | const intl = useIntl();
17 | return (
18 |
19 |
20 |
33 |
34 | {' '}
35 |
40 |
41 |
42 |
43 | yarn add @ant-design/pro-table
44 |
50 | {' '}
51 |
56 |
57 |
58 |
59 | yarn add @ant-design/pro-layout
60 |
61 |
62 | );
63 | };
64 |
--------------------------------------------------------------------------------
/src/locales/id-ID/menu.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'menu.welcome': 'Selamat Datang',
3 | 'menu.more-blocks': 'Blocks Lainnya',
4 | 'menu.home': 'Halaman Awal',
5 | 'menu.admin': 'Admin',
6 | 'menu.admin.sub-page': 'Sub-Halaman',
7 | 'menu.login': 'Masuk',
8 | 'menu.register': 'Pendaftaran',
9 | 'menu.register.result': 'Hasil Pendaftaran',
10 | 'menu.dashboard': 'Dasbor',
11 | 'menu.dashboard.analysis': 'Analisis',
12 | 'menu.dashboard.monitor': 'Monitor',
13 | 'menu.dashboard.workplace': 'Workplace',
14 | 'menu.exception.403': '403',
15 | 'menu.exception.404': '404',
16 | 'menu.exception.500': '500',
17 | 'menu.form': 'Form',
18 | 'menu.form.basic-form': 'Form Dasar',
19 | 'menu.form.step-form': 'Form Bertahap',
20 | 'menu.form.step-form.info': 'Form Bertahap(menulis informasi yang dibagikan)',
21 | 'menu.form.step-form.confirm': 'Form Bertahap(konfirmasi informasi yang dibagikan)',
22 | 'menu.form.step-form.result': 'Form Bertahap(selesai)',
23 | 'menu.form.advanced-form': 'Form Lanjutan',
24 | 'menu.list': 'Daftar',
25 | 'menu.list.table-list': 'Tabel Pencarian',
26 | 'menu.list.basic-list': 'Daftar Dasar',
27 | 'menu.list.card-list': 'Daftar Kartu',
28 | 'menu.list.search-list': 'Daftar Pencarian',
29 | 'menu.list.search-list.articles': 'Daftar Pencarian(artikel)',
30 | 'menu.list.search-list.projects': 'Daftar Pencarian(projek)',
31 | 'menu.list.search-list.applications': 'Daftar Pencarian(aplikasi)',
32 | 'menu.profile': 'Profil',
33 | 'menu.profile.basic': 'Profil Dasar',
34 | 'menu.profile.advanced': 'Profile Lanjutan',
35 | 'menu.result': 'Hasil',
36 | 'menu.result.success': 'Sukses',
37 | 'menu.result.fail': 'Gagal',
38 | 'menu.exception': 'Pengecualian',
39 | 'menu.exception.not-permission': '403',
40 | 'menu.exception.not-find': '404',
41 | 'menu.exception.server-error': '500',
42 | 'menu.exception.trigger': 'Jalankan',
43 | 'menu.account': 'Akun',
44 | 'menu.account.center': 'Detail Akun',
45 | 'menu.account.settings': 'Pengaturan Akun',
46 | 'menu.account.trigger': 'Mengaktivasi Error',
47 | 'menu.account.logout': 'Keluar',
48 | 'menu.editor': 'Penyusun Grafis',
49 | 'menu.editor.flow': 'Penyusun Alur',
50 | 'menu.editor.mind': 'Penyusun Mind',
51 | 'menu.editor.koni': 'Penyusun Koni',
52 | };
53 |
--------------------------------------------------------------------------------
/src/service-worker.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable eslint-comments/disable-enable-pair */
2 | /* eslint-disable no-restricted-globals */
3 | /* eslint-disable no-underscore-dangle */
4 | /* globals workbox */
5 | workbox.core.setCacheNameDetails({
6 | prefix: 'antd-pro',
7 | suffix: 'v5',
8 | });
9 | // Control all opened tabs ASAP
10 | workbox.clientsClaim();
11 |
12 | /**
13 | * Use precaching list generated by workbox in build process.
14 | * https://developers.google.com/web/tools/workbox/reference-docs/latest/workbox.precaching
15 | */
16 | workbox.precaching.precacheAndRoute(self.__precacheManifest || []);
17 |
18 | /**
19 | * Register a navigation route.
20 | * https://developers.google.com/web/tools/workbox/modules/workbox-routing#how_to_register_a_navigation_route
21 | */
22 | workbox.routing.registerNavigationRoute('/index.html');
23 |
24 | /**
25 | * Use runtime cache:
26 | * https://developers.google.com/web/tools/workbox/reference-docs/latest/workbox.routing#.registerRoute
27 | *
28 | * Workbox provides all common caching strategies including CacheFirst, NetworkFirst etc.
29 | * https://developers.google.com/web/tools/workbox/reference-docs/latest/workbox.strategies
30 | */
31 |
32 | /** Handle API requests */
33 | workbox.routing.registerRoute(/\/api\//, workbox.strategies.networkFirst());
34 |
35 | /** Handle third party requests */
36 | workbox.routing.registerRoute(
37 | /^https:\/\/gw\.alipayobjects\.com\//,
38 | workbox.strategies.networkFirst(),
39 | );
40 | workbox.routing.registerRoute(
41 | /^https:\/\/cdnjs\.cloudflare\.com\//,
42 | workbox.strategies.networkFirst(),
43 | );
44 | workbox.routing.registerRoute(/\/color.less/, workbox.strategies.networkFirst());
45 |
46 | /** Response to client after skipping waiting with MessageChannel */
47 | addEventListener('message', (event) => {
48 | const replyPort = event.ports[0];
49 | const message = event.data;
50 | if (replyPort && message && message.type === 'skip-waiting') {
51 | event.waitUntil(
52 | self.skipWaiting().then(
53 | () => {
54 | replyPort.postMessage({
55 | error: null,
56 | });
57 | },
58 | (error) => {
59 | replyPort.postMessage({
60 | error,
61 | });
62 | },
63 | ),
64 | );
65 | }
66 | });
67 |
--------------------------------------------------------------------------------
/src/locales/pt-BR/menu.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'menu.welcome': 'Welcome',
3 | 'menu.more-blocks': 'More Blocks',
4 | 'menu.home': 'Início',
5 | 'menu.login': 'Login',
6 | 'menu.admin': 'Admin',
7 | 'menu.admin.sub-page': 'Sub-Page',
8 | 'menu.register': 'Registro',
9 | 'menu.register.result': 'Resultado de registro',
10 | 'menu.dashboard': 'Dashboard',
11 | 'menu.dashboard.analysis': 'Análise',
12 | 'menu.dashboard.monitor': 'Monitor',
13 | 'menu.dashboard.workplace': 'Ambiente de Trabalho',
14 | 'menu.exception.403': '403',
15 | 'menu.exception.404': '404',
16 | 'menu.exception.500': '500',
17 | 'menu.form': 'Formulário',
18 | 'menu.form.basic-form': 'Formulário Básico',
19 | 'menu.form.step-form': 'Formulário Assistido',
20 | 'menu.form.step-form.info': 'Formulário Assistido(gravar informações de transferência)',
21 | 'menu.form.step-form.confirm': 'Formulário Assistido(confirmar informações de transferência)',
22 | 'menu.form.step-form.result': 'Formulário Assistido(finalizado)',
23 | 'menu.form.advanced-form': 'Formulário Avançado',
24 | 'menu.list': 'Lista',
25 | 'menu.list.table-list': 'Tabela de Busca',
26 | 'menu.list.basic-list': 'Lista Básica',
27 | 'menu.list.card-list': 'Lista de Card',
28 | 'menu.list.search-list': 'Lista de Busca',
29 | 'menu.list.search-list.articles': 'Lista de Busca(artigos)',
30 | 'menu.list.search-list.projects': 'Lista de Busca(projetos)',
31 | 'menu.list.search-list.applications': 'Lista de Busca(aplicações)',
32 | 'menu.profile': 'Perfil',
33 | 'menu.profile.basic': 'Perfil Básico',
34 | 'menu.profile.advanced': 'Perfil Avançado',
35 | 'menu.result': 'Resultado',
36 | 'menu.result.success': 'Sucesso',
37 | 'menu.result.fail': 'Falha',
38 | 'menu.exception': 'Exceção',
39 | 'menu.exception.not-permission': '403',
40 | 'menu.exception.not-find': '404',
41 | 'menu.exception.server-error': '500',
42 | 'menu.exception.trigger': 'Disparar',
43 | 'menu.account': 'Conta',
44 | 'menu.account.center': 'Central da Conta',
45 | 'menu.account.settings': 'Configurar Conta',
46 | 'menu.account.trigger': 'Disparar Erro',
47 | 'menu.account.logout': 'Sair',
48 | 'menu.editor': 'Graphic Editor',
49 | 'menu.editor.flow': 'Flow Editor',
50 | 'menu.editor.mind': 'Mind Editor',
51 | 'menu.editor.koni': 'Koni Editor',
52 | };
53 |
--------------------------------------------------------------------------------
/src/services/ant-design-pro/api.ts:
--------------------------------------------------------------------------------
1 | // @ts-ignore
2 | /* eslint-disable */
3 | import { request } from 'umi';
4 |
5 | /** 获取当前的用户 GET /api/currentUser */
6 | export async function currentUser(options?: { [key: string]: any }) {
7 | return request('/api/currentUser', {
8 | method: 'GET',
9 | ...(options || {}),
10 | });
11 | }
12 |
13 | /** 退出登录接口 POST /api/login/outLogin */
14 | export async function outLogin(options?: { [key: string]: any }) {
15 | return request>('/api/login/outLogin', {
16 | method: 'POST',
17 | ...(options || {}),
18 | });
19 | }
20 |
21 | /** 登录接口 POST /api/login/account */
22 | export async function login(body: API.LoginParams, options?: { [key: string]: any }) {
23 | return request('/api/login/account', {
24 | method: 'POST',
25 | headers: {
26 | 'Content-Type': 'application/json',
27 | },
28 | data: body,
29 | ...(options || {}),
30 | });
31 | }
32 |
33 | /** 此处后端没有提供注释 GET /api/notices */
34 | export async function getNotices(options?: { [key: string]: any }) {
35 | return request('/api/notices', {
36 | method: 'GET',
37 | ...(options || {}),
38 | });
39 | }
40 |
41 | /** 获取规则列表 GET /api/rule */
42 | export async function rule(
43 | params: {
44 | // query
45 | /** 当前的页码 */
46 | current?: number;
47 | /** 页面的容量 */
48 | pageSize?: number;
49 | },
50 | options?: { [key: string]: any },
51 | ) {
52 | return request('/api/rule', {
53 | method: 'GET',
54 | params: {
55 | ...params,
56 | },
57 | ...(options || {}),
58 | });
59 | }
60 |
61 | /** 新建规则 PUT /api/rule */
62 | export async function updateRule(options?: { [key: string]: any }) {
63 | return request('/api/rule', {
64 | method: 'PUT',
65 | ...(options || {}),
66 | });
67 | }
68 |
69 | /** 新建规则 POST /api/rule */
70 | export async function addRule(options?: { [key: string]: any }) {
71 | return request('/api/rule', {
72 | method: 'POST',
73 | ...(options || {}),
74 | });
75 | }
76 |
77 | /** 删除规则 DELETE /api/rule */
78 | export async function removeRule(options?: { [key: string]: any }) {
79 | return request>('/api/rule', {
80 | method: 'DELETE',
81 | ...(options || {}),
82 | });
83 | }
84 |
--------------------------------------------------------------------------------
/config/config.ts:
--------------------------------------------------------------------------------
1 | // https://umijs.org/config/
2 | import { defineConfig } from 'umi';
3 | import { join } from 'path';
4 |
5 | import defaultSettings from './defaultSettings';
6 | import proxy from './proxy';
7 | import routes from './routes';
8 |
9 | const { REACT_APP_ENV } = process.env;
10 |
11 | export default defineConfig({
12 | hash: true,
13 | antd: {},
14 | dva: {
15 | hmr: true,
16 | },
17 | layout: {
18 | // https://umijs.org/zh-CN/plugins/plugin-layout
19 | locale: true,
20 | siderWidth: 208,
21 | ...defaultSettings,
22 | },
23 | // layout: false,
24 | // https://umijs.org/zh-CN/plugins/plugin-locale
25 | locale: {
26 | // default zh-CN
27 | default: 'zh-CN',
28 | antd: true,
29 | // default true, when it is true, will use `navigator.language` overwrite default
30 | baseNavigator: true,
31 | },
32 | define: {
33 | URL_PREFIX: '/childapi',
34 | },
35 | devServer: {
36 | port: 8091,
37 | },
38 | dynamicImport: {
39 | loading: '@ant-design/pro-layout/es/PageLoading',
40 | },
41 | targets: {
42 | ie: 11,
43 | },
44 | // umi routes: https://umijs.org/docs/routing
45 | routes,
46 | // Theme for antd: https://ant.design/docs/react/customize-theme-cn
47 | theme: {
48 | // 'root-entry-name': 'variable',
49 | 'primary-color': defaultSettings.primaryColor,
50 | },
51 | // esbuild is father build tools
52 | // https://umijs.org/plugins/plugin-esbuild
53 | esbuild: {},
54 | title: false,
55 | ignoreMomentLocale: true,
56 | proxy: proxy[REACT_APP_ENV || 'dev'],
57 | manifest: {
58 | basePath: '/child-pro',
59 | },
60 | base: '/child-pro',
61 | // Fast Refresh 热更新
62 | fastRefresh: {},
63 | openAPI: [
64 | {
65 | requestLibPath: "import { request } from 'umi'",
66 | // 或者使用在线的版本
67 | // schemaPath: "https://gw.alipayobjects.com/os/antfincdn/M%24jrzTTYJN/oneapi.json"
68 | schemaPath: join(__dirname, 'oneapi.json'),
69 | mock: false,
70 | },
71 | {
72 | requestLibPath: "import { request } from 'umi'",
73 | schemaPath: 'https://gw.alipayobjects.com/os/antfincdn/CA1dOm%2631B/openapi.json',
74 | projectName: 'swagger',
75 | },
76 | ],
77 | nodeModulesTransform: { type: 'none' },
78 | // mfsu: {},
79 | webpack5: {},
80 | exportStatic: {},
81 | qiankun: {
82 | slave: {},
83 | },
84 | });
85 |
--------------------------------------------------------------------------------
/src/pages/form/upload/index.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Form, Button, Card, Input, Table } from 'antd'
3 | import ComUpload from "@/components/ComUpload";
4 |
5 | const layout = {
6 | labelCol: { span: 4 },
7 | wrapperCol: { span: 16 },
8 | }
9 |
10 | const UploadDemo: React.FC = () => {
11 | const [form] = Form.useForm()
12 |
13 | const dataSource = []
14 | for (let i = 0; i < 5; i++) {
15 | dataSource.push({
16 | key: i,
17 | name: `文件${i}`,
18 | fileList: [{
19 | fileName: `测试文件${i}`,
20 | fileUrl: 'http://dummyimage.com/400x300/f2cd79/FFF&text=qassj'
21 | }]
22 | })
23 | }
24 |
25 | const columns = [
26 | {
27 | title: '名称',
28 | dataIndex: 'name'
29 | },
30 | {
31 | title: '文件',
32 | dataIndex: 'fileList',
33 | render: (_: any) => (
34 |
35 | )
36 | }
37 | ]
38 |
39 |
40 | const onFinish = async(values: any) => {
41 | console.log(values)
42 | }
43 | return (
44 |
45 |
46 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
70 |
71 |
72 |
73 |
74 |
78 |
79 |
80 | )
81 | }
82 |
83 | export default UploadDemo
--------------------------------------------------------------------------------
/src/components/NoticeIcon/NoticeList.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .list {
4 | max-height: 400px;
5 | overflow: auto;
6 | &::-webkit-scrollbar {
7 | display: none;
8 | }
9 | .item {
10 | padding-right: 24px;
11 | padding-left: 24px;
12 | overflow: hidden;
13 | cursor: pointer;
14 | transition: all 0.3s;
15 |
16 | .meta {
17 | width: 100%;
18 | }
19 |
20 | .avatar {
21 | margin-top: 4px;
22 | background: @component-background;
23 | }
24 | .iconElement {
25 | font-size: 32px;
26 | }
27 |
28 | &.read {
29 | opacity: 0.4;
30 | }
31 | &:last-child {
32 | border-bottom: 0;
33 | }
34 | &:hover {
35 | background: @primary-1;
36 | }
37 | .title {
38 | margin-bottom: 8px;
39 | font-weight: normal;
40 | }
41 | .description {
42 | font-size: 12px;
43 | line-height: @line-height-base;
44 | }
45 | .datetime {
46 | margin-top: 4px;
47 | font-size: 12px;
48 | line-height: @line-height-base;
49 | }
50 | .extra {
51 | float: right;
52 | margin-top: -1.5px;
53 | margin-right: 0;
54 | color: @text-color-secondary;
55 | font-weight: normal;
56 | }
57 | }
58 | .loadMore {
59 | padding: 8px 0;
60 | color: @primary-6;
61 | text-align: center;
62 | cursor: pointer;
63 | &.loadedAll {
64 | color: rgba(0, 0, 0, 0.25);
65 | cursor: unset;
66 | }
67 | }
68 | }
69 |
70 | .notFound {
71 | padding: 73px 0 88px;
72 | color: @text-color-secondary;
73 | text-align: center;
74 | img {
75 | display: inline-block;
76 | height: 76px;
77 | margin-bottom: 16px;
78 | }
79 | }
80 |
81 | .bottomBar {
82 | height: 46px;
83 | color: @text-color;
84 | line-height: 46px;
85 | text-align: center;
86 | border-top: 1px solid @border-color-split;
87 | border-radius: 0 0 @border-radius-base @border-radius-base;
88 | transition: all 0.3s;
89 | div {
90 | display: inline-block;
91 | width: 50%;
92 | cursor: pointer;
93 | transition: all 0.3s;
94 | user-select: none;
95 |
96 | &:only-child {
97 | width: 100%;
98 | }
99 | &:not(:only-child):last-child {
100 | border-left: 1px solid @border-color-split;
101 | }
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/src/components/debounce/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Select, Spin } from 'antd';
3 | import debounce from 'lodash/debounce';
4 |
5 | const DebounceSelect = ({ fetchOptions, debounceTimeout = 800, ...props }) => {
6 | const [fetching, setFetching] = React.useState(false);
7 | const [options, setOptions] = React.useState([]);
8 | const fetchRef = React.useRef(0);
9 | const debounceFetcher = React.useMemo(() => {
10 | const loadOptions = (value) => {
11 | fetchRef.current += 1;
12 | const fetchId = fetchRef.current;
13 | setOptions([]);
14 | setFetching(true);
15 | fetchOptions(value).then((newOptions) => {
16 | if (fetchId !== fetchRef.current) {
17 | // for fetch callback order
18 | return;
19 | }
20 |
21 | setOptions(newOptions);
22 | setFetching(false);
23 | });
24 | };
25 |
26 | return debounce(loadOptions, debounceTimeout);
27 | }, [fetchOptions, debounceTimeout]);
28 | return (
29 | : null}
35 | {...props}
36 | options={options}
37 | />
38 | );
39 | } // Usage of DebounceSelect
40 |
41 | async function fetchUserList(username) {
42 | // console.log('fetching user', username);
43 | return fetch('https://randomuser.me/api/?results=5')
44 | .then((response) => response.json())
45 | .then((body) =>
46 | body.results.map((user) => ({
47 | label: `${user.name.first} ${user.name.last}`,
48 | value: user.login.username,
49 | phone: user.phone,
50 | email: user.email
51 | })),
52 | );
53 | }
54 |
55 | interface demoprops {
56 | value?: any
57 | onChange?: (val?: any, options?: any) => void
58 | }
59 |
60 | const Demo = ({val, onChange = () => {}}: demoprops) => {
61 | const [value, setValue] = React.useState(val || {});
62 |
63 | return (
64 | {
70 | setValue(newValue);
71 | onChange(newValue, options)
72 | }}
73 | style={{
74 | width: '100%',
75 | }}
76 | />
77 | );
78 | };
79 |
80 | export default Demo
--------------------------------------------------------------------------------
/src/pages/user/Login/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .container {
4 | display: flex;
5 | flex-direction: column;
6 | height: 100vh;
7 | overflow: auto;
8 | background: @layout-body-background;
9 | }
10 |
11 | .lang {
12 | width: 100%;
13 | height: 40px;
14 | line-height: 44px;
15 | text-align: right;
16 | :global(.ant-dropdown-trigger) {
17 | margin-right: 24px;
18 | }
19 | }
20 |
21 | .content {
22 | flex: 1;
23 | padding: 32px 0;
24 | }
25 |
26 | @media (min-width: @screen-md-min) {
27 | .container {
28 | background-image: url('https://gw.alipayobjects.com/zos/rmsportal/TVYTbAXWheQpRcWDaDMu.svg');
29 | background-repeat: no-repeat;
30 | background-position: center 110px;
31 | background-size: 100%;
32 | }
33 |
34 | .content {
35 | padding: 32px 0 24px;
36 | }
37 | }
38 |
39 | .top {
40 | text-align: center;
41 | }
42 |
43 | .header {
44 | height: 44px;
45 | line-height: 44px;
46 | a {
47 | text-decoration: none;
48 | }
49 | }
50 |
51 | .logo {
52 | height: 44px;
53 | margin-right: 16px;
54 | vertical-align: top;
55 | }
56 |
57 | .title {
58 | position: relative;
59 | top: 2px;
60 | color: @heading-color;
61 | font-weight: 600;
62 | font-size: 33px;
63 | font-family: Avenir, 'Helvetica Neue', Arial, Helvetica, sans-serif;
64 | }
65 |
66 | .desc {
67 | margin-top: 12px;
68 | margin-bottom: 40px;
69 | color: @text-color-secondary;
70 | font-size: @font-size-base;
71 | }
72 |
73 | .main {
74 | width: 328px;
75 | margin: 0 auto;
76 | @media screen and (max-width: @screen-sm) {
77 | width: 95%;
78 | max-width: 328px;
79 | }
80 |
81 | :global {
82 | .@{ant-prefix}-tabs-nav-list {
83 | margin: auto;
84 | font-size: 16px;
85 | }
86 | }
87 |
88 | .icon {
89 | margin-left: 16px;
90 | color: rgba(0, 0, 0, 0.2);
91 | font-size: 24px;
92 | vertical-align: middle;
93 | cursor: pointer;
94 | transition: color 0.3s;
95 |
96 | &:hover {
97 | color: @primary-color;
98 | }
99 | }
100 |
101 | .other {
102 | margin-top: 24px;
103 | line-height: 22px;
104 | text-align: left;
105 | .register {
106 | float: right;
107 | }
108 | }
109 |
110 | .prefixIcon {
111 | color: @primary-color;
112 | font-size: @font-size-base;
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/src/services/ant-design-pro/typings.d.ts:
--------------------------------------------------------------------------------
1 | // @ts-ignore
2 | /* eslint-disable */
3 |
4 | declare namespace API {
5 | type CurrentUser = {
6 | name?: string;
7 | avatar?: string;
8 | userid?: string;
9 | email?: string;
10 | signature?: string;
11 | title?: string;
12 | group?: string;
13 | tags?: { key?: string; label?: string }[];
14 | notifyCount?: number;
15 | unreadCount?: number;
16 | country?: string;
17 | access?: string;
18 | geographic?: {
19 | province?: { label?: string; key?: string };
20 | city?: { label?: string; key?: string };
21 | };
22 | address?: string;
23 | phone?: string;
24 | };
25 |
26 | type LoginResult = {
27 | status?: string;
28 | type?: string;
29 | currentAuthority?: string;
30 | };
31 |
32 | type PageParams = {
33 | current?: number;
34 | pageSize?: number;
35 | };
36 |
37 | type RuleListItem = {
38 | key?: number;
39 | disabled?: boolean;
40 | href?: string;
41 | avatar?: string;
42 | name?: string;
43 | owner?: string;
44 | desc?: string;
45 | callNo?: number;
46 | status?: number;
47 | updatedAt?: string;
48 | createdAt?: string;
49 | progress?: number;
50 | };
51 |
52 | type RuleList = {
53 | data?: RuleListItem[];
54 | /** 列表的内容总数 */
55 | total?: number;
56 | success?: boolean;
57 | };
58 |
59 | type FakeCaptcha = {
60 | code?: number;
61 | status?: string;
62 | };
63 |
64 | type LoginParams = {
65 | username?: string;
66 | password?: string;
67 | autoLogin?: boolean;
68 | type?: string;
69 | };
70 |
71 | type ErrorResponse = {
72 | /** 业务约定的错误码 */
73 | errorCode: string;
74 | /** 业务上的错误信息 */
75 | errorMessage?: string;
76 | /** 业务上的请求是否成功 */
77 | success?: boolean;
78 | };
79 |
80 | type NoticeIconList = {
81 | data?: NoticeIconItem[];
82 | /** 列表的内容总数 */
83 | total?: number;
84 | success?: boolean;
85 | };
86 |
87 | type NoticeIconItemType = 'notification' | 'message' | 'event';
88 |
89 | type NoticeIconItem = {
90 | id?: string;
91 | extra?: string;
92 | key?: string;
93 | read?: boolean;
94 | avatar?: string;
95 | title?: string;
96 | status?: string;
97 | datetime?: string;
98 | description?: string;
99 | type?: NoticeIconItemType;
100 | };
101 | }
102 |
--------------------------------------------------------------------------------
/src/locales/zh-CN/settings.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'app.settings.menuMap.basic': '基本设置',
3 | 'app.settings.menuMap.security': '安全设置',
4 | 'app.settings.menuMap.binding': '账号绑定',
5 | 'app.settings.menuMap.notification': '新消息通知',
6 | 'app.settings.basic.avatar': '头像',
7 | 'app.settings.basic.change-avatar': '更换头像',
8 | 'app.settings.basic.email': '邮箱',
9 | 'app.settings.basic.email-message': '请输入您的邮箱!',
10 | 'app.settings.basic.nickname': '昵称',
11 | 'app.settings.basic.nickname-message': '请输入您的昵称!',
12 | 'app.settings.basic.profile': '个人简介',
13 | 'app.settings.basic.profile-message': '请输入个人简介!',
14 | 'app.settings.basic.profile-placeholder': '个人简介',
15 | 'app.settings.basic.country': '国家/地区',
16 | 'app.settings.basic.country-message': '请输入您的国家或地区!',
17 | 'app.settings.basic.geographic': '所在省市',
18 | 'app.settings.basic.geographic-message': '请输入您的所在省市!',
19 | 'app.settings.basic.address': '街道地址',
20 | 'app.settings.basic.address-message': '请输入您的街道地址!',
21 | 'app.settings.basic.phone': '联系电话',
22 | 'app.settings.basic.phone-message': '请输入您的联系电话!',
23 | 'app.settings.basic.update': '更新基本信息',
24 | 'app.settings.security.strong': '强',
25 | 'app.settings.security.medium': '中',
26 | 'app.settings.security.weak': '弱',
27 | 'app.settings.security.password': '账户密码',
28 | 'app.settings.security.password-description': '当前密码强度',
29 | 'app.settings.security.phone': '密保手机',
30 | 'app.settings.security.phone-description': '已绑定手机',
31 | 'app.settings.security.question': '密保问题',
32 | 'app.settings.security.question-description': '未设置密保问题,密保问题可有效保护账户安全',
33 | 'app.settings.security.email': '备用邮箱',
34 | 'app.settings.security.email-description': '已绑定邮箱',
35 | 'app.settings.security.mfa': 'MFA 设备',
36 | 'app.settings.security.mfa-description': '未绑定 MFA 设备,绑定后,可以进行二次确认',
37 | 'app.settings.security.modify': '修改',
38 | 'app.settings.security.set': '设置',
39 | 'app.settings.security.bind': '绑定',
40 | 'app.settings.binding.taobao': '绑定淘宝',
41 | 'app.settings.binding.taobao-description': '当前未绑定淘宝账号',
42 | 'app.settings.binding.alipay': '绑定支付宝',
43 | 'app.settings.binding.alipay-description': '当前未绑定支付宝账号',
44 | 'app.settings.binding.dingding': '绑定钉钉',
45 | 'app.settings.binding.dingding-description': '当前未绑定钉钉账号',
46 | 'app.settings.binding.bind': '绑定',
47 | 'app.settings.notification.password': '账户密码',
48 | 'app.settings.notification.password-description': '其他用户的消息将以站内信的形式通知',
49 | 'app.settings.notification.messages': '系统消息',
50 | 'app.settings.notification.messages-description': '系统消息将以站内信的形式通知',
51 | 'app.settings.notification.todo': '待办任务',
52 | 'app.settings.notification.todo-description': '待办任务将以站内信的形式通知',
53 | 'app.settings.open': '开',
54 | 'app.settings.close': '关',
55 | };
56 |
--------------------------------------------------------------------------------
/src/locales/zh-TW/settings.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'app.settings.menuMap.basic': '基本設置',
3 | 'app.settings.menuMap.security': '安全設置',
4 | 'app.settings.menuMap.binding': '賬號綁定',
5 | 'app.settings.menuMap.notification': '新消息通知',
6 | 'app.settings.basic.avatar': '頭像',
7 | 'app.settings.basic.change-avatar': '更換頭像',
8 | 'app.settings.basic.email': '郵箱',
9 | 'app.settings.basic.email-message': '請輸入您的郵箱!',
10 | 'app.settings.basic.nickname': '昵稱',
11 | 'app.settings.basic.nickname-message': '請輸入您的昵稱!',
12 | 'app.settings.basic.profile': '個人簡介',
13 | 'app.settings.basic.profile-message': '請輸入個人簡介!',
14 | 'app.settings.basic.profile-placeholder': '個人簡介',
15 | 'app.settings.basic.country': '國家/地區',
16 | 'app.settings.basic.country-message': '請輸入您的國家或地區!',
17 | 'app.settings.basic.geographic': '所在省市',
18 | 'app.settings.basic.geographic-message': '請輸入您的所在省市!',
19 | 'app.settings.basic.address': '街道地址',
20 | 'app.settings.basic.address-message': '請輸入您的街道地址!',
21 | 'app.settings.basic.phone': '聯系電話',
22 | 'app.settings.basic.phone-message': '請輸入您的聯系電話!',
23 | 'app.settings.basic.update': '更新基本信息',
24 | 'app.settings.security.strong': '強',
25 | 'app.settings.security.medium': '中',
26 | 'app.settings.security.weak': '弱',
27 | 'app.settings.security.password': '賬戶密碼',
28 | 'app.settings.security.password-description': '當前密碼強度',
29 | 'app.settings.security.phone': '密保手機',
30 | 'app.settings.security.phone-description': '已綁定手機',
31 | 'app.settings.security.question': '密保問題',
32 | 'app.settings.security.question-description': '未設置密保問題,密保問題可有效保護賬戶安全',
33 | 'app.settings.security.email': '備用郵箱',
34 | 'app.settings.security.email-description': '已綁定郵箱',
35 | 'app.settings.security.mfa': 'MFA 設備',
36 | 'app.settings.security.mfa-description': '未綁定 MFA 設備,綁定後,可以進行二次確認',
37 | 'app.settings.security.modify': '修改',
38 | 'app.settings.security.set': '設置',
39 | 'app.settings.security.bind': '綁定',
40 | 'app.settings.binding.taobao': '綁定淘寶',
41 | 'app.settings.binding.taobao-description': '當前未綁定淘寶賬號',
42 | 'app.settings.binding.alipay': '綁定支付寶',
43 | 'app.settings.binding.alipay-description': '當前未綁定支付寶賬號',
44 | 'app.settings.binding.dingding': '綁定釘釘',
45 | 'app.settings.binding.dingding-description': '當前未綁定釘釘賬號',
46 | 'app.settings.binding.bind': '綁定',
47 | 'app.settings.notification.password': '賬戶密碼',
48 | 'app.settings.notification.password-description': '其他用戶的消息將以站內信的形式通知',
49 | 'app.settings.notification.messages': '系統消息',
50 | 'app.settings.notification.messages-description': '系統消息將以站內信的形式通知',
51 | 'app.settings.notification.todo': '待辦任務',
52 | 'app.settings.notification.todo-description': '待辦任務將以站內信的形式通知',
53 | 'app.settings.open': '開',
54 | 'app.settings.close': '關',
55 | };
56 |
--------------------------------------------------------------------------------
/src/global.tsx:
--------------------------------------------------------------------------------
1 | import { Button, message, notification } from 'antd';
2 | import { useIntl } from 'umi';
3 | import defaultSettings from '../config/defaultSettings';
4 |
5 | const { pwa } = defaultSettings;
6 | const isHttps = document.location.protocol === 'https:';
7 |
8 | // if pwa is true
9 | if (pwa) {
10 | // Notify user if offline now
11 | window.addEventListener('sw.offline', () => {
12 | message.warning(useIntl().formatMessage({ id: 'app.pwa.offline' }));
13 | });
14 |
15 | // Pop up a prompt on the page asking the user if they want to use the latest version
16 | window.addEventListener('sw.updated', (event: Event) => {
17 | const e = event as CustomEvent;
18 | const reloadSW = async () => {
19 | // Check if there is sw whose state is waiting in ServiceWorkerRegistration
20 | // https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration
21 | const worker = e.detail && e.detail.waiting;
22 | if (!worker) {
23 | return true;
24 | }
25 | // Send skip-waiting event to waiting SW with MessageChannel
26 | await new Promise((resolve, reject) => {
27 | const channel = new MessageChannel();
28 | channel.port1.onmessage = (msgEvent) => {
29 | if (msgEvent.data.error) {
30 | reject(msgEvent.data.error);
31 | } else {
32 | resolve(msgEvent.data);
33 | }
34 | };
35 | worker.postMessage({ type: 'skip-waiting' }, [channel.port2]);
36 | });
37 | // Refresh current page to use the updated HTML and other assets after SW has skiped waiting
38 | window.location.reload(true);
39 | return true;
40 | };
41 | const key = `open${Date.now()}`;
42 | const btn = (
43 |
52 | );
53 | notification.open({
54 | message: useIntl().formatMessage({ id: 'app.pwa.serviceworker.updated' }),
55 | description: useIntl().formatMessage({ id: 'app.pwa.serviceworker.updated.hint' }),
56 | btn,
57 | key,
58 | onClose: async () => null,
59 | });
60 | });
61 | } else if ('serviceWorker' in navigator && isHttps) {
62 | // unregister service worker
63 | const { serviceWorker } = navigator;
64 | if (serviceWorker.getRegistrations) {
65 | serviceWorker.getRegistrations().then((sws) => {
66 | sws.forEach((sw) => {
67 | sw.unregister();
68 | });
69 | });
70 | }
71 | serviceWorker.getRegistration().then((sw) => {
72 | if (sw) sw.unregister();
73 | });
74 |
75 | // remove all caches
76 | if (window.caches && window.caches.keys()) {
77 | caches.keys().then((keys) => {
78 | keys.forEach((key) => {
79 | caches.delete(key);
80 | });
81 | });
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/pages/dataManage/initialstate/componenets/page1.tsx:
--------------------------------------------------------------------------------
1 | // import React from 'react';
2 | import { useModel } from 'umi';
3 | import { Descriptions, Form, Input, Button, Row, Col } from 'antd';
4 |
5 | export default () => {
6 | const { initialState, loading, error, refresh, setInitialState } = useModel('@@initialState');
7 |
8 | console.log(initialState)
9 | const { currentUser } = initialState
10 |
11 | const onFinish = (values: any) => {
12 | console.log('Success:', values);
13 | setInitialState({...initialState, currentUser: values})
14 | }
15 |
16 | const onFinishFailed = (errorInfo: any) => {
17 | console.log('Failed:', errorInfo);
18 | }
19 |
20 | return <>
21 | 页面一
22 |
23 | {currentUser.name}
24 | {currentUser.phone}
25 | {currentUser.group}
26 | {currentUser.signature}
27 |
28 | {currentUser.address}
29 |
30 |
31 | 修改初始数据
32 |
91 |
94 |
95 |
96 | >
97 | };
--------------------------------------------------------------------------------
/src/locales/ja-JP/settings.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'app.settings.menuMap.basic': '基本設定',
3 | 'app.settings.menuMap.security': 'セキュリティ設定',
4 | 'app.settings.menuMap.binding': 'アカウントのバインド',
5 | 'app.settings.menuMap.notification': '新しいメッセージの通知',
6 | 'app.settings.basic.avatar': 'アバター',
7 | 'app.settings.basic.change-avatar': 'アバターを変更する',
8 | 'app.settings.basic.email': 'メール',
9 | 'app.settings.basic.email-message': 'メールアドレスを入力してください!',
10 | 'app.settings.basic.nickname': 'ニックネーム',
11 | 'app.settings.basic.nickname-message': 'ニックネームを入力してください!',
12 | 'app.settings.basic.profile': '個人プロフィール',
13 | 'app.settings.basic.profile-message': '個人プロフィールを入力してください!',
14 | 'app.settings.basic.profile-placeholder': '自己紹介',
15 | 'app.settings.basic.country': '国/地域',
16 | 'app.settings.basic.country-message': 'あなたの国を入力してください!',
17 | 'app.settings.basic.geographic': '州または市',
18 | 'app.settings.basic.geographic-message': '地理情報を入力してください!',
19 | 'app.settings.basic.address': '住所',
20 | 'app.settings.basic.address-message': '住所を入力してください!',
21 | 'app.settings.basic.phone': '電話番号',
22 | 'app.settings.basic.phone-message': '電話番号を入力してください!',
23 | 'app.settings.basic.update': '更新情報',
24 | 'app.settings.security.strong': '強い',
25 | 'app.settings.security.medium': 'ミディアム',
26 | 'app.settings.security.weak': '弱い',
27 | 'app.settings.security.password': 'アカウントパスワード',
28 | 'app.settings.security.password-description': '現在のパスワードの強度',
29 | 'app.settings.security.phone': 'セキュリティ電話番号',
30 | 'app.settings.security.phone-description': 'バインドされた電話番号',
31 | 'app.settings.security.question': '秘密の質問',
32 | 'app.settings.security.question-description':
33 | 'セキュリティの質問が設定されてません。セキュリティポリシーはアカウントのセキュリティを効果的に保護できます',
34 | 'app.settings.security.email': 'バックアップメール',
35 | 'app.settings.security.email-description': 'バインドされたメール',
36 | 'app.settings.security.mfa': '多要素認証デバイス',
37 | 'app.settings.security.mfa-description':
38 | 'バインドされていない多要素認証デバイスは、バインド後、2回確認できます',
39 | 'app.settings.security.modify': '変更する',
40 | 'app.settings.security.set': 'セットする',
41 | 'app.settings.security.bind': 'バインド',
42 | 'app.settings.binding.taobao': 'タオバオをバインドする',
43 | 'app.settings.binding.taobao-description': '現在バインドされていないタオバオアカウント',
44 | 'app.settings.binding.alipay': 'アリペイをバインドする',
45 | 'app.settings.binding.alipay-description': '現在バインドされていないアリペイアカウント',
46 | 'app.settings.binding.dingding': 'ディントークをバインドする',
47 | 'app.settings.binding.dingding-description': '現在バインドされていないディントークアカウント',
48 | 'app.settings.binding.bind': 'バインド',
49 | 'app.settings.notification.password': 'アカウントパスワード',
50 | 'app.settings.notification.password-description':
51 | '他のユーザーからのメッセージは、ステーションレターの形式で通知されます',
52 | 'app.settings.notification.messages': 'システムメッセージ',
53 | 'app.settings.notification.messages-description':
54 | 'システムメッセージは、ステーションレターの形式で通知されます',
55 | 'app.settings.notification.todo': 'To Do(用事) 通知',
56 | 'app.settings.notification.todo-description': 'To Doタスクは、内部レターの形式で通知されます',
57 | 'app.settings.open': '開く',
58 | 'app.settings.close': '閉じる',
59 | };
60 |
--------------------------------------------------------------------------------
/src/components/HeaderSearch/index.tsx:
--------------------------------------------------------------------------------
1 | import { SearchOutlined } from '@ant-design/icons';
2 | import { AutoComplete, Input } from 'antd';
3 | import useMergedState from 'rc-util/es/hooks/useMergedState';
4 | import type { AutoCompleteProps } from 'antd/es/auto-complete';
5 | import React, { useRef } from 'react';
6 |
7 | import classNames from 'classnames';
8 | import styles from './index.less';
9 |
10 | export type HeaderSearchProps = {
11 | onSearch?: (value?: string) => void;
12 | onChange?: (value?: string) => void;
13 | onVisibleChange?: (b: boolean) => void;
14 | className?: string;
15 | placeholder?: string;
16 | options: AutoCompleteProps['options'];
17 | defaultVisible?: boolean;
18 | visible?: boolean;
19 | defaultValue?: string;
20 | value?: string;
21 | };
22 |
23 | const HeaderSearch: React.FC = (props) => {
24 | const {
25 | className,
26 | defaultValue,
27 | onVisibleChange,
28 | placeholder,
29 | visible,
30 | defaultVisible,
31 | ...restProps
32 | } = props;
33 |
34 | const inputRef = useRef(null);
35 |
36 | const [value, setValue] = useMergedState(defaultValue, {
37 | value: props.value,
38 | onChange: props.onChange,
39 | });
40 |
41 | const [searchMode, setSearchMode] = useMergedState(defaultVisible ?? false, {
42 | value: props.visible,
43 | onChange: onVisibleChange,
44 | });
45 |
46 | const inputClass = classNames(styles.input, {
47 | [styles.show]: searchMode,
48 | });
49 | return (
50 | {
53 | setSearchMode(true);
54 | if (searchMode && inputRef.current) {
55 | inputRef.current.focus();
56 | }
57 | }}
58 | onTransitionEnd={({ propertyName }) => {
59 | if (propertyName === 'width' && !searchMode) {
60 | if (onVisibleChange) {
61 | onVisibleChange(searchMode);
62 | }
63 | }
64 | }}
65 | >
66 |
72 |
79 | {
86 | if (e.key === 'Enter') {
87 | if (restProps.onSearch) {
88 | restProps.onSearch(value);
89 | }
90 | }
91 | }}
92 | onBlur={() => {
93 | setSearchMode(false);
94 | }}
95 | />
96 |
97 |
98 | );
99 | };
100 |
101 | export default HeaderSearch;
102 |
--------------------------------------------------------------------------------
/src/components/RightContent/AvatarDropdown.tsx:
--------------------------------------------------------------------------------
1 | import React, { useCallback } from 'react';
2 | import { LogoutOutlined, SettingOutlined, UserOutlined } from '@ant-design/icons';
3 | import { Avatar, Menu, Spin } from 'antd';
4 | import { history, useModel } from 'umi';
5 | import { stringify } from 'querystring';
6 | import HeaderDropdown from '../HeaderDropdown';
7 | import styles from './index.less';
8 | import { outLogin } from '@/services/ant-design-pro/api';
9 | import type { MenuInfo } from 'rc-menu/lib/interface';
10 |
11 | export type GlobalHeaderRightProps = {
12 | menu?: boolean;
13 | };
14 |
15 | /**
16 | * 退出登录,并且将当前的 url 保存
17 | */
18 | const loginOut = async () => {
19 | await outLogin();
20 | const { query = {}, pathname } = history.location;
21 | const { redirect } = query;
22 | // Note: There may be security issues, please note
23 | if (window.location.pathname !== '/user/login' && !redirect) {
24 | history.replace({
25 | pathname: '/user/login',
26 | search: stringify({
27 | redirect: pathname,
28 | }),
29 | });
30 | }
31 | };
32 |
33 | const AvatarDropdown: React.FC = ({ menu }) => {
34 | const { initialState, setInitialState } = useModel('@@initialState');
35 |
36 | const onMenuClick = useCallback(
37 | (event: MenuInfo) => {
38 | const { key } = event;
39 | if (key === 'logout' && initialState) {
40 | setInitialState({ ...initialState, currentUser: undefined });
41 | loginOut();
42 | return;
43 | }
44 | history.push(`/account/${key}`);
45 | },
46 | [initialState, setInitialState],
47 | );
48 |
49 | const loading = (
50 |
51 |
58 |
59 | );
60 |
61 | if (!initialState) {
62 | return loading;
63 | }
64 |
65 | const { currentUser } = initialState;
66 |
67 | if (!currentUser || !currentUser.name) {
68 | return loading;
69 | }
70 |
71 | const menuHeaderDropdown = (
72 |
92 | );
93 | return (
94 |
95 |
96 |
97 | {currentUser.name}
98 |
99 |
100 | );
101 | };
102 |
103 | export default AvatarDropdown;
104 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6 |
7 | ## Our Standards
8 |
9 | Examples of behavior that contributes to creating a positive environment include:
10 |
11 | - Using welcoming and inclusive language
12 | - Being respectful of differing viewpoints and experiences
13 | - Gracefully accepting constructive criticism
14 | - Focusing on what is best for the community
15 | - Showing empathy towards other community members
16 |
17 | Examples of unacceptable behavior by participants include:
18 |
19 | - The use of sexualized language or imagery and unwelcome sexual attention or advances
20 | - Trolling, insulting/derogatory comments, and personal or political attacks
21 | - Public or private harassment
22 | - Publishing others' private information, such as a physical or electronic address, without explicit permission
23 | - Other conduct which could reasonably be considered inappropriate in a professional setting
24 |
25 | ## Our Responsibilities
26 |
27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28 |
29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30 |
31 | ## Scope
32 |
33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34 |
35 | ## Enforcement
36 |
37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at afc163@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38 |
39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40 |
41 | ## Attribution
42 |
43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
44 |
45 | [homepage]: http://contributor-covenant.org
46 | [version]: http://contributor-covenant.org/version/1/4/
47 |
--------------------------------------------------------------------------------
/src/services/swagger/user.ts:
--------------------------------------------------------------------------------
1 | // @ts-ignore
2 | /* eslint-disable */
3 | import { request } from 'umi';
4 |
5 | /** Create user This can only be done by the logged in user. POST /user */
6 | export async function createUser(body: API.User, options?: { [key: string]: any }) {
7 | return request('/user', {
8 | method: 'POST',
9 | data: body,
10 | ...(options || {}),
11 | });
12 | }
13 |
14 | /** Creates list of users with given input array POST /user/createWithArray */
15 | export async function createUsersWithArrayInput(
16 | body: API.User[],
17 | options?: { [key: string]: any },
18 | ) {
19 | return request('/user/createWithArray', {
20 | method: 'POST',
21 | data: body,
22 | ...(options || {}),
23 | });
24 | }
25 |
26 | /** Creates list of users with given input array POST /user/createWithList */
27 | export async function createUsersWithListInput(body: API.User[], options?: { [key: string]: any }) {
28 | return request('/user/createWithList', {
29 | method: 'POST',
30 | data: body,
31 | ...(options || {}),
32 | });
33 | }
34 |
35 | /** Logs user into the system GET /user/login */
36 | export async function loginUser(
37 | params: {
38 | // query
39 | /** The user name for login */
40 | username: string;
41 | /** The password for login in clear text */
42 | password: string;
43 | },
44 | options?: { [key: string]: any },
45 | ) {
46 | return request('/user/login', {
47 | method: 'GET',
48 | params: {
49 | ...params,
50 | },
51 | ...(options || {}),
52 | });
53 | }
54 |
55 | /** Logs out current logged in user session GET /user/logout */
56 | export async function logoutUser(options?: { [key: string]: any }) {
57 | return request('/user/logout', {
58 | method: 'GET',
59 | ...(options || {}),
60 | });
61 | }
62 |
63 | /** Get user by user name GET /user/${param0} */
64 | export async function getUserByName(
65 | params: {
66 | // path
67 | /** The name that needs to be fetched. Use user1 for testing. */
68 | username: string;
69 | },
70 | options?: { [key: string]: any },
71 | ) {
72 | const { username: param0 } = params;
73 | return request(`/user/${param0}`, {
74 | method: 'GET',
75 | params: { ...params },
76 | ...(options || {}),
77 | });
78 | }
79 |
80 | /** Updated user This can only be done by the logged in user. PUT /user/${param0} */
81 | export async function updateUser(
82 | params: {
83 | // path
84 | /** name that need to be updated */
85 | username: string;
86 | },
87 | body: API.User,
88 | options?: { [key: string]: any },
89 | ) {
90 | const { username: param0 } = params;
91 | return request(`/user/${param0}`, {
92 | method: 'PUT',
93 | params: { ...params },
94 | data: body,
95 | ...(options || {}),
96 | });
97 | }
98 |
99 | /** Delete user This can only be done by the logged in user. DELETE /user/${param0} */
100 | export async function deleteUser(
101 | params: {
102 | // path
103 | /** The name that needs to be deleted */
104 | username: string;
105 | },
106 | options?: { [key: string]: any },
107 | ) {
108 | const { username: param0 } = params;
109 | return request(`/user/${param0}`, {
110 | method: 'DELETE',
111 | params: { ...params },
112 | ...(options || {}),
113 | });
114 | }
115 |
--------------------------------------------------------------------------------
/.github/workflows/preview-deploy.yml:
--------------------------------------------------------------------------------
1 | name: Preview Deploy
2 |
3 | on:
4 | workflow_run:
5 | workflows: ['Preview Build']
6 | types:
7 | - completed
8 |
9 | jobs:
10 | success:
11 | runs-on: ubuntu-latest
12 | if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success'
13 | steps:
14 | - name: download pr artifact
15 | uses: dawidd6/action-download-artifact@v2
16 | with:
17 | workflow: ${{ github.event.workflow_run.workflow_id }}
18 | name: pr
19 |
20 | - name: save PR id
21 | id: pr
22 | run: echo "::set-output name=id::$(
45 |
46 |
47 | body-include: ''
48 | number: ${{ steps.pr.outputs.id }}
49 |
50 | - name: The job failed
51 | if: ${{ failure() }}
52 | uses: actions-cool/maintain-one-comment@v1.2.1
53 | with:
54 | token: ${{ secrets.GITHUB_TOKEN }}
55 | body: |
56 | 😭 Deploy PR Preview failed.
57 |
58 |
59 |
60 |
61 | body-include: ''
62 | number: ${{ steps.pr.outputs.id }}
63 |
64 | failed:
65 | runs-on: ubuntu-latest
66 | if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'failure'
67 | steps:
68 | - name: download pr artifact
69 | uses: dawidd6/action-download-artifact@v2
70 | with:
71 | workflow: ${{ github.event.workflow_run.workflow_id }}
72 | name: pr
73 |
74 | - name: save PR id
75 | id: pr
76 | run: echo "::set-output name=id::$(
86 |
87 |
88 | body-include: ''
89 | number: ${{ steps.pr.outputs.id }}
90 |
--------------------------------------------------------------------------------
/src/locales/fa-IR/settings.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'app.settings.menuMap.basic': 'تنظیمات پایه ',
3 | 'app.settings.menuMap.security': 'تنظیمات امنیتی',
4 | 'app.settings.menuMap.binding': 'صحافی حساب',
5 | 'app.settings.menuMap.notification': 'اعلان پیام جدید',
6 | 'app.settings.basic.avatar': 'آواتار',
7 | 'app.settings.basic.change-avatar': 'آواتار را تغییر دهید',
8 | 'app.settings.basic.email': 'ایمیل',
9 | 'app.settings.basic.email-message': 'لطفا ایمیل خود را وارد کنید!',
10 | 'app.settings.basic.nickname': 'نام مستعار',
11 | 'app.settings.basic.nickname-message': 'لطفاً نام مستعار خود را وارد کنید!',
12 | 'app.settings.basic.profile': 'پروفایل شخصی',
13 | 'app.settings.basic.profile-message': 'لطفاً مشخصات شخصی خود را وارد کنید!',
14 | 'app.settings.basic.profile-placeholder': 'معرفی مختصر خودتان',
15 | 'app.settings.basic.country': 'کشور / منطقه',
16 | 'app.settings.basic.country-message': 'لطفاً کشور خود را وارد کنید!',
17 | 'app.settings.basic.geographic': 'استان یا شهر',
18 | 'app.settings.basic.geographic-message': 'لطفاً اطلاعات جغرافیایی خود را وارد کنید!',
19 | 'app.settings.basic.address': 'آدرس خیابان',
20 | 'app.settings.basic.address-message': 'لطفا آدرس خود را وارد کنید!',
21 | 'app.settings.basic.phone': 'شماره تلفن',
22 | 'app.settings.basic.phone-message': 'لطفاً تلفن خود را وارد کنید!',
23 | 'app.settings.basic.update': 'به روز رسانی اطلاعات',
24 | 'app.settings.security.strong': 'قوی',
25 | 'app.settings.security.medium': 'متوسط',
26 | 'app.settings.security.weak': 'ضعیف',
27 | 'app.settings.security.password': 'رمز عبور حساب کاربری',
28 | 'app.settings.security.password-description': 'قدرت رمز عبور فعلی',
29 | 'app.settings.security.phone': 'تلفن امنیتی',
30 | 'app.settings.security.phone-description': 'تلفن مقید',
31 | 'app.settings.security.question': 'سوال امنیتی',
32 | 'app.settings.security.question-description':
33 | 'سوال امنیتی تنظیم نشده است و سیاست امنیتی می تواند به طور موثر از امنیت حساب محافظت کند',
34 | 'app.settings.security.email': 'ایمیل پشتیبان',
35 | 'app.settings.security.email-description': 'ایمیل مقید',
36 | 'app.settings.security.mfa': 'دستگاه MFA',
37 | 'app.settings.security.mfa-description':
38 | 'دستگاه MFA بسته نشده ، پس از اتصال ، می تواند دو بار تأیید شود',
39 | 'app.settings.security.modify': 'تغییر',
40 | 'app.settings.security.set': 'تنظیم',
41 | 'app.settings.security.bind': 'بستن',
42 | 'app.settings.binding.taobao': 'اتصال Taobao',
43 | 'app.settings.binding.taobao-description': 'حساب Taobao در حال حاضر بسته نشده است',
44 | 'app.settings.binding.alipay': 'اتصال Alipay',
45 | 'app.settings.binding.alipay-description': 'حساب Alipay در حال حاضر بسته نشده است',
46 | 'app.settings.binding.dingding': 'اتصال DingTalk',
47 | 'app.settings.binding.dingding-description': 'حساب DingTalk در حال حاضر محدود نشده است',
48 | 'app.settings.binding.bind': 'بستن',
49 | 'app.settings.notification.password': 'رمز عبور حساب کاربری',
50 | 'app.settings.notification.password-description':
51 | 'پیام های سایر کاربران در قالب یک نامه ایستگاهی اعلام خواهد شد',
52 | 'app.settings.notification.messages': 'پیام های سیستم',
53 | 'app.settings.notification.messages-description':
54 | 'پیام های سیستم به صورت نامه ایستگاه مطلع می شوند',
55 | 'app.settings.notification.todo': 'اعلان کارها',
56 | 'app.settings.notification.todo-description':
57 | 'لیست کارها به صورت نامه ای از ایستگاه اطلاع داده می شود',
58 | 'app.settings.open': 'باز کن',
59 | 'app.settings.close': 'بستن',
60 | };
61 |
--------------------------------------------------------------------------------
/src/locales/zh-CN/pages.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'pages.layouts.userLayout.title': 'Ant Design 是西湖区最具影响力的 Web 设计规范',
3 | 'pages.login.accountLogin.tab': '账户密码登录',
4 | 'pages.login.accountLogin.errorMessage': '错误的用户名和密码(admin/ant.design)',
5 | 'pages.login.failure': '登录失败,请重试!',
6 | 'pages.login.success': '登录成功!',
7 | 'pages.login.username.placeholder': '用户名: admin or user',
8 | 'pages.login.username.required': '用户名是必填项!',
9 | 'pages.login.password.placeholder': '密码: ant.design',
10 | 'pages.login.password.required': '密码是必填项!',
11 | 'pages.login.phoneLogin.tab': '手机号登录',
12 | 'pages.login.phoneLogin.errorMessage': '验证码错误',
13 | 'pages.login.phoneNumber.placeholder': '请输入手机号!',
14 | 'pages.login.phoneNumber.required': '手机号是必填项!',
15 | 'pages.login.phoneNumber.invalid': '不合法的手机号!',
16 | 'pages.login.captcha.placeholder': '请输入验证码!',
17 | 'pages.login.captcha.required': '验证码是必填项!',
18 | 'pages.login.phoneLogin.getVerificationCode': '获取验证码',
19 | 'pages.getCaptchaSecondText': '秒后重新获取',
20 | 'pages.login.rememberMe': '自动登录',
21 | 'pages.login.forgotPassword': '忘记密码 ?',
22 | 'pages.login.submit': '登录',
23 | 'pages.login.loginWith': '其他登录方式 :',
24 | 'pages.login.registerAccount': '注册账户',
25 | 'pages.welcome.advancedComponent': '高级表格',
26 | 'pages.welcome.link': '欢迎使用',
27 | 'pages.welcome.advancedLayout': '高级布局',
28 | 'pages.welcome.alertMessage': '更快更强的重型组件,已经发布。',
29 | 'pages.admin.subPage.title': ' 这个页面只有 admin 权限才能查看',
30 | 'pages.admin.subPage.alertMessage': 'umi ui 现已发布,欢迎使用 npm run ui 启动体验。',
31 | 'pages.searchTable.createForm.newRule': '新建规则',
32 | 'pages.searchTable.updateForm.ruleConfig': '规则配置',
33 | 'pages.searchTable.updateForm.basicConfig': '基本信息',
34 | 'pages.searchTable.updateForm.ruleName.nameLabel': '规则名称',
35 | 'pages.searchTable.updateForm.ruleName.nameRules': '请输入规则名称!',
36 | 'pages.searchTable.updateForm.ruleDesc.descLabel': '规则描述',
37 | 'pages.searchTable.updateForm.ruleDesc.descPlaceholder': '请输入至少五个字符',
38 | 'pages.searchTable.updateForm.ruleDesc.descRules': '请输入至少五个字符的规则描述!',
39 | 'pages.searchTable.updateForm.ruleProps.title': '配置规则属性',
40 | 'pages.searchTable.updateForm.object': '监控对象',
41 | 'pages.searchTable.updateForm.ruleProps.templateLabel': '规则模板',
42 | 'pages.searchTable.updateForm.ruleProps.typeLabel': '规则类型',
43 | 'pages.searchTable.updateForm.schedulingPeriod.title': '设定调度周期',
44 | 'pages.searchTable.updateForm.schedulingPeriod.timeLabel': '开始时间',
45 | 'pages.searchTable.updateForm.schedulingPeriod.timeRules': '请选择开始时间!',
46 | 'pages.searchTable.titleDesc': '描述',
47 | 'pages.searchTable.ruleName': '规则名称为必填项',
48 | 'pages.searchTable.titleCallNo': '服务调用次数',
49 | 'pages.searchTable.titleStatus': '状态',
50 | 'pages.searchTable.nameStatus.default': '关闭',
51 | 'pages.searchTable.nameStatus.running': '运行中',
52 | 'pages.searchTable.nameStatus.online': '已上线',
53 | 'pages.searchTable.nameStatus.abnormal': '异常',
54 | 'pages.searchTable.titleUpdatedAt': '上次调度时间',
55 | 'pages.searchTable.exception': '请输入异常原因!',
56 | 'pages.searchTable.titleOption': '操作',
57 | 'pages.searchTable.config': '配置',
58 | 'pages.searchTable.subscribeAlert': '订阅警报',
59 | 'pages.searchTable.title': '查询表格',
60 | 'pages.searchTable.new': '新建',
61 | 'pages.searchTable.chosen': '已选择',
62 | 'pages.searchTable.item': '项',
63 | 'pages.searchTable.totalServiceCalls': '服务调用次数总计',
64 | 'pages.searchTable.tenThousand': '万',
65 | 'pages.searchTable.batchDeletion': '批量删除',
66 | 'pages.searchTable.batchApproval': '批量审批',
67 | };
68 |
--------------------------------------------------------------------------------
/mock/notices.ts:
--------------------------------------------------------------------------------
1 | import { Request, Response } from 'express';
2 |
3 | const getNotices = (req: Request, res: Response) => {
4 | res.json({
5 | data: [
6 | {
7 | id: '000000001',
8 | avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png',
9 | title: '你收到了 14 份新周报',
10 | datetime: '2017-08-09',
11 | type: 'notification',
12 | },
13 | {
14 | id: '000000002',
15 | avatar: 'https://gw.alipayobjects.com/zos/rmsportal/OKJXDXrmkNshAMvwtvhu.png',
16 | title: '你推荐的 曲妮妮 已通过第三轮面试',
17 | datetime: '2017-08-08',
18 | type: 'notification',
19 | },
20 | {
21 | id: '000000003',
22 | avatar: 'https://gw.alipayobjects.com/zos/rmsportal/kISTdvpyTAhtGxpovNWd.png',
23 | title: '这种模板可以区分多种通知类型',
24 | datetime: '2017-08-07',
25 | read: true,
26 | type: 'notification',
27 | },
28 | {
29 | id: '000000004',
30 | avatar: 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png',
31 | title: '左侧图标用于区分不同的类型',
32 | datetime: '2017-08-07',
33 | type: 'notification',
34 | },
35 | {
36 | id: '000000005',
37 | avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png',
38 | title: '内容不要超过两行字,超出时自动截断',
39 | datetime: '2017-08-07',
40 | type: 'notification',
41 | },
42 | {
43 | id: '000000006',
44 | avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg',
45 | title: '曲丽丽 评论了你',
46 | description: '描述信息描述信息描述信息',
47 | datetime: '2017-08-07',
48 | type: 'message',
49 | clickClose: true,
50 | },
51 | {
52 | id: '000000007',
53 | avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg',
54 | title: '朱偏右 回复了你',
55 | description: '这种模板用于提醒谁与你发生了互动,左侧放『谁』的头像',
56 | datetime: '2017-08-07',
57 | type: 'message',
58 | clickClose: true,
59 | },
60 | {
61 | id: '000000008',
62 | avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg',
63 | title: '标题',
64 | description: '这种模板用于提醒谁与你发生了互动,左侧放『谁』的头像',
65 | datetime: '2017-08-07',
66 | type: 'message',
67 | clickClose: true,
68 | },
69 | {
70 | id: '000000009',
71 | title: '任务名称',
72 | description: '任务需要在 2017-01-12 20:00 前启动',
73 | extra: '未开始',
74 | status: 'todo',
75 | type: 'event',
76 | },
77 | {
78 | id: '000000010',
79 | title: '第三方紧急代码变更',
80 | description: '冠霖提交于 2017-01-06,需在 2017-01-07 前完成代码变更任务',
81 | extra: '马上到期',
82 | status: 'urgent',
83 | type: 'event',
84 | },
85 | {
86 | id: '000000011',
87 | title: '信息安全考试',
88 | description: '指派竹尔于 2017-01-09 前完成更新并发布',
89 | extra: '已耗时 8 天',
90 | status: 'doing',
91 | type: 'event',
92 | },
93 | {
94 | id: '000000012',
95 | title: 'ABCD 版本发布',
96 | description: '冠霖提交于 2017-01-06,需在 2017-01-07 前完成代码变更任务',
97 | extra: '进行中',
98 | status: 'processing',
99 | type: 'event',
100 | },
101 | ],
102 | });
103 | };
104 |
105 | export default {
106 | 'GET /api/notices': getNotices,
107 | };
108 |
--------------------------------------------------------------------------------
/src/components/NoticeIcon/NoticeList.tsx:
--------------------------------------------------------------------------------
1 | import { Avatar, List } from 'antd';
2 |
3 | import React from 'react';
4 | import classNames from 'classnames';
5 | import styles from './NoticeList.less';
6 |
7 | export type NoticeIconTabProps = {
8 | count?: number;
9 | showClear?: boolean;
10 | showViewMore?: boolean;
11 | style?: React.CSSProperties;
12 | title: string;
13 | tabKey: API.NoticeIconItemType;
14 | onClick?: (item: API.NoticeIconItem) => void;
15 | onClear?: () => void;
16 | emptyText?: string;
17 | clearText?: string;
18 | viewMoreText?: string;
19 | list: API.NoticeIconItem[];
20 | onViewMore?: (e: any) => void;
21 | };
22 | const NoticeList: React.FC = ({
23 | list = [],
24 | onClick,
25 | onClear,
26 | title,
27 | onViewMore,
28 | emptyText,
29 | showClear = true,
30 | clearText,
31 | viewMoreText,
32 | showViewMore = false,
33 | }) => {
34 | if (!list || list.length === 0) {
35 | return (
36 |
37 |

41 |
{emptyText}
42 |
43 | );
44 | }
45 | return (
46 |
47 |
48 | className={styles.list}
49 | dataSource={list}
50 | renderItem={(item, i) => {
51 | const itemCls = classNames(styles.item, {
52 | [styles.read]: item.read,
53 | });
54 | // eslint-disable-next-line no-nested-ternary
55 | const leftIcon = item.avatar ? (
56 | typeof item.avatar === 'string' ? (
57 |
58 | ) : (
59 | {item.avatar}
60 | )
61 | ) : null;
62 |
63 | return (
64 | {
68 | onClick?.(item);
69 | }}
70 | >
71 |
76 | {item.title}
77 | {item.extra}
78 |
79 | }
80 | description={
81 |
82 |
{item.description}
83 |
{item.datetime}
84 |
85 | }
86 | />
87 |
88 | );
89 | }}
90 | />
91 |
92 | {showClear ? (
93 |
94 | {clearText} {title}
95 |
96 | ) : null}
97 | {showViewMore ? (
98 |
{
100 | if (onViewMore) {
101 | onViewMore(e);
102 | }
103 | }}
104 | >
105 | {viewMoreText}
106 |
107 | ) : null}
108 |
109 |
110 | );
111 | };
112 |
113 | export default NoticeList;
114 |
--------------------------------------------------------------------------------
/src/locales/en-US/settings.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'app.settings.menuMap.basic': 'Basic Settings',
3 | 'app.settings.menuMap.security': 'Security Settings',
4 | 'app.settings.menuMap.binding': 'Account Binding',
5 | 'app.settings.menuMap.notification': 'New Message Notification',
6 | 'app.settings.basic.avatar': 'Avatar',
7 | 'app.settings.basic.change-avatar': 'Change avatar',
8 | 'app.settings.basic.email': 'Email',
9 | 'app.settings.basic.email-message': 'Please input your email!',
10 | 'app.settings.basic.nickname': 'Nickname',
11 | 'app.settings.basic.nickname-message': 'Please input your Nickname!',
12 | 'app.settings.basic.profile': 'Personal profile',
13 | 'app.settings.basic.profile-message': 'Please input your personal profile!',
14 | 'app.settings.basic.profile-placeholder': 'Brief introduction to yourself',
15 | 'app.settings.basic.country': 'Country/Region',
16 | 'app.settings.basic.country-message': 'Please input your country!',
17 | 'app.settings.basic.geographic': 'Province or city',
18 | 'app.settings.basic.geographic-message': 'Please input your geographic info!',
19 | 'app.settings.basic.address': 'Street Address',
20 | 'app.settings.basic.address-message': 'Please input your address!',
21 | 'app.settings.basic.phone': 'Phone Number',
22 | 'app.settings.basic.phone-message': 'Please input your phone!',
23 | 'app.settings.basic.update': 'Update Information',
24 | 'app.settings.security.strong': 'Strong',
25 | 'app.settings.security.medium': 'Medium',
26 | 'app.settings.security.weak': 'Weak',
27 | 'app.settings.security.password': 'Account Password',
28 | 'app.settings.security.password-description': 'Current password strength',
29 | 'app.settings.security.phone': 'Security Phone',
30 | 'app.settings.security.phone-description': 'Bound phone',
31 | 'app.settings.security.question': 'Security Question',
32 | 'app.settings.security.question-description':
33 | 'The security question is not set, and the security policy can effectively protect the account security',
34 | 'app.settings.security.email': 'Backup Email',
35 | 'app.settings.security.email-description': 'Bound Email',
36 | 'app.settings.security.mfa': 'MFA Device',
37 | 'app.settings.security.mfa-description':
38 | 'Unbound MFA device, after binding, can be confirmed twice',
39 | 'app.settings.security.modify': 'Modify',
40 | 'app.settings.security.set': 'Set',
41 | 'app.settings.security.bind': 'Bind',
42 | 'app.settings.binding.taobao': 'Binding Taobao',
43 | 'app.settings.binding.taobao-description': 'Currently unbound Taobao account',
44 | 'app.settings.binding.alipay': 'Binding Alipay',
45 | 'app.settings.binding.alipay-description': 'Currently unbound Alipay account',
46 | 'app.settings.binding.dingding': 'Binding DingTalk',
47 | 'app.settings.binding.dingding-description': 'Currently unbound DingTalk account',
48 | 'app.settings.binding.bind': 'Bind',
49 | 'app.settings.notification.password': 'Account Password',
50 | 'app.settings.notification.password-description':
51 | 'Messages from other users will be notified in the form of a station letter',
52 | 'app.settings.notification.messages': 'System Messages',
53 | 'app.settings.notification.messages-description':
54 | 'System messages will be notified in the form of a station letter',
55 | 'app.settings.notification.todo': 'To-do Notification',
56 | 'app.settings.notification.todo-description':
57 | 'The to-do list will be notified in the form of a letter from the station',
58 | 'app.settings.open': 'Open',
59 | 'app.settings.close': 'Close',
60 | };
61 |
--------------------------------------------------------------------------------
/src/locales/id-ID/settings.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'app.settings.menuMap.basic': 'Pengaturan Dasar',
3 | 'app.settings.menuMap.security': 'Pengaturan Keamanan',
4 | 'app.settings.menuMap.binding': 'Pengikatan Akun',
5 | 'app.settings.menuMap.notification': 'Notifikasi Pesan Baru',
6 | 'app.settings.basic.avatar': 'Avatar',
7 | 'app.settings.basic.change-avatar': 'Ubah avatar',
8 | 'app.settings.basic.email': 'Email',
9 | 'app.settings.basic.email-message': 'Tolong masukkan email!',
10 | 'app.settings.basic.nickname': 'Nickname',
11 | 'app.settings.basic.nickname-message': 'Tolong masukkan Nickname!',
12 | 'app.settings.basic.profile': 'Profil Personal',
13 | 'app.settings.basic.profile-message': 'Tolong masukkan profil personal!',
14 | 'app.settings.basic.profile-placeholder': 'Perkenalan Singkat tentang Diri Anda',
15 | 'app.settings.basic.country': 'Negara/Wilayah',
16 | 'app.settings.basic.country-message': 'Tolong masukkan negara anda!',
17 | 'app.settings.basic.geographic': 'Provinsi atau kota',
18 | 'app.settings.basic.geographic-message': 'Tolong masukkan info geografis anda!',
19 | 'app.settings.basic.address': 'Alamat Jalan',
20 | 'app.settings.basic.address-message': 'Tolong masukkan Alamat Jalan anda!',
21 | 'app.settings.basic.phone': 'Nomor Ponsel',
22 | 'app.settings.basic.phone-message': 'Tolong masukkan Nomor Ponsel anda!',
23 | 'app.settings.basic.update': 'Perbarui Informasi',
24 | 'app.settings.security.strong': 'Kuat',
25 | 'app.settings.security.medium': 'Sedang',
26 | 'app.settings.security.weak': 'Lemah',
27 | 'app.settings.security.password': 'Kata Sandi Akun',
28 | 'app.settings.security.password-description': 'Kekuatan Kata Sandi saat ini',
29 | 'app.settings.security.phone': 'Keamanan Ponsel',
30 | 'app.settings.security.phone-description': 'Mengikat Ponsel',
31 | 'app.settings.security.question': 'Pertanyaan Keamanan',
32 | 'app.settings.security.question-description':
33 | 'Pertanyaan Keamanan belum diatur, dan kebijakan keamanan dapat melindungi akun secara efektif',
34 | 'app.settings.security.email': 'Email Cadangan',
35 | 'app.settings.security.email-description': 'Mengikat Email',
36 | 'app.settings.security.mfa': 'Perangka MFA',
37 | 'app.settings.security.mfa-description':
38 | 'Tidak mengikat Perangkat MFA, setelah diikat, dapat dikonfirmasi dua kali',
39 | 'app.settings.security.modify': 'Modifikasi',
40 | 'app.settings.security.set': 'Setel',
41 | 'app.settings.security.bind': 'Ikat',
42 | 'app.settings.binding.taobao': 'Mengikat Taobao',
43 | 'app.settings.binding.taobao-description': 'Tidak mengikat akun Taobao saat ini',
44 | 'app.settings.binding.alipay': 'Mengikat Alipay',
45 | 'app.settings.binding.alipay-description': 'Tidak mengikat akun Alipay saat ini',
46 | 'app.settings.binding.dingding': 'Mengikat DingTalk',
47 | 'app.settings.binding.dingding-description': 'Tidak mengikat akun DingTalk',
48 | 'app.settings.binding.bind': 'Ikat',
49 | 'app.settings.notification.password': 'Kata Sandi Akun',
50 | 'app.settings.notification.password-description':
51 | 'Pesan dari pengguna lain akan diberitahu dalam bentuk surat',
52 | 'app.settings.notification.messages': 'Pesan Sistem',
53 | 'app.settings.notification.messages-description':
54 | 'Pesan sistem akan diberitahu dalam bentuk surat',
55 | 'app.settings.notification.todo': 'Notifikasi daftar To-do',
56 | 'app.settings.notification.todo-description':
57 | 'Daftar to-do akan diberitahukan dalam bentuk surat dari stasiun',
58 | 'app.settings.open': 'Buka',
59 | 'app.settings.close': 'Tutup',
60 | };
61 |
--------------------------------------------------------------------------------
/src/locales/ja-JP/pages.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'pages.layouts.userLayout.title': 'Ant Designは、西湖区で最も影響力のあるWebデザイン仕様です。',
3 | 'pages.login.accountLogin.tab': 'アカウントログイン',
4 | 'pages.login.accountLogin.errorMessage':
5 | 'ユーザー名/パスワードが正しくありません(admin/ant.design)',
6 | 'pages.login.username.placeholder': 'ユーザー名:adminまたはuser',
7 | 'pages.login.username.required': 'ユーザー名を入力してください!',
8 | 'pages.login.password.placeholder': 'パスワード:ant.design',
9 | 'pages.login.password.required': 'パスワードを入力してください!',
10 | 'pages.login.phoneLogin.tab': '電話ログイン',
11 | 'pages.login.phoneLogin.errorMessage': '検証コードエラー',
12 | 'pages.login.phoneNumber.placeholder': '電話番号',
13 | 'pages.login.phoneNumber.required': '電話番号を入力してください!',
14 | 'pages.login.phoneNumber.invalid': '電話番号が無効です!',
15 | 'pages.login.captcha.placeholder': '確認コード',
16 | 'pages.login.captcha.required': '確認コードを入力してください!',
17 | 'pages.login.phoneLogin.getVerificationCode': '確認コードを取得',
18 | 'pages.getCaptchaSecondText': '秒',
19 | 'pages.login.rememberMe': 'Remember me',
20 | 'pages.login.forgotPassword': 'パスワードをお忘れですか?',
21 | 'pages.login.submit': 'ログイン',
22 | 'pages.login.loginWith': 'その他のログイン方法:',
23 | 'pages.login.registerAccount': 'アカウント登録',
24 | 'pages.welcome.advancedComponent': '高度なコンポーネント',
25 | 'pages.welcome.link': 'ようこそ',
26 | 'pages.welcome.advancedLayout': '高度なレイアウト',
27 | 'pages.welcome.alertMessage': 'より高速で強力な頑丈なコンポーネントがリリースされました。',
28 | 'pages.admin.subPage.title': 'このページは管理者のみが表示できます',
29 | 'pages.admin.subPage.alertMessage':
30 | 'Umi uiがリリースされました。npm run uiを使用して体験してください。',
31 | 'pages.searchTable.createForm.newRule': '新しいルール',
32 | 'pages.searchTable.updateForm.ruleConfig': 'ルール構成',
33 | 'pages.searchTable.updateForm.basicConfig': '基本情報',
34 | 'pages.searchTable.updateForm.ruleName.nameLabel': 'ルール名',
35 | 'pages.searchTable.updateForm.ruleName.nameRules': 'ルール名を入力してください!',
36 | 'pages.searchTable.updateForm.ruleDesc.descLabel': 'ルールの説明',
37 | 'pages.searchTable.updateForm.ruleDesc.descPlaceholder': '5文字以上入力してください',
38 | 'pages.searchTable.updateForm.ruleDesc.descRules': '5文字以上のルールの説明を入力してください!',
39 | 'pages.searchTable.updateForm.ruleProps.title': 'プロパティの構成',
40 | 'pages.searchTable.updateForm.object': '監視対象',
41 | 'pages.searchTable.updateForm.ruleProps.templateLabel': 'ルールテンプレート',
42 | 'pages.searchTable.updateForm.ruleProps.typeLabel': 'ルールタイプ',
43 | 'pages.searchTable.updateForm.schedulingPeriod.title': 'スケジュール期間の設定',
44 | 'pages.searchTable.updateForm.schedulingPeriod.timeLabel': '開始時間',
45 | 'pages.searchTable.updateForm.schedulingPeriod.timeRules': '開始時間を選択してください!',
46 | 'pages.searchTable.titleDesc': '説明',
47 | 'pages.searchTable.ruleName': 'ルール名が必要です',
48 | 'pages.searchTable.titleCallNo': 'サービスコール数',
49 | 'pages.searchTable.titleStatus': 'ステータス',
50 | 'pages.searchTable.nameStatus.default': 'デフォルト',
51 | 'pages.searchTable.nameStatus.running': '起動中',
52 | 'pages.searchTable.nameStatus.online': 'オンライン',
53 | 'pages.searchTable.nameStatus.abnormal': '異常',
54 | 'pages.searchTable.titleUpdatedAt': '最終スケジュール',
55 | 'pages.searchTable.exception': '例外の理由を入力してください!',
56 | 'pages.searchTable.titleOption': 'オプション',
57 | 'pages.searchTable.config': '構成',
58 | 'pages.searchTable.subscribeAlert': 'アラートを購読する',
59 | 'pages.searchTable.title': 'お問い合わせフォーム',
60 | 'pages.searchTable.new': '新しい',
61 | 'pages.searchTable.chosen': '選んだ項目',
62 | 'pages.searchTable.item': '項目',
63 | 'pages.searchTable.totalServiceCalls': 'サービスコールの総数',
64 | 'pages.searchTable.tenThousand': '万',
65 | 'pages.searchTable.batchDeletion': 'バッチ削除',
66 | 'pages.searchTable.batchApproval': 'バッチ承認',
67 | };
68 |
--------------------------------------------------------------------------------
/src/components/ComUpload/index.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from 'react'
2 | import { Button, Upload, message } from 'antd'
3 | import { UploadOutlined, FileTextOutlined, FilePdfOutlined, FileExcelOutlined, FileImageOutlined, FileUnknownOutlined, FileGifOutlined, FileWordOutlined } from '@ant-design/icons'
4 |
5 | export type comuploadProps = {
6 | value?: any
7 | onChange?: (arr?: any) => void
8 | limit?: number
9 | isDetail?: boolean
10 | }
11 |
12 | const ComUpload: React.FC = ({ value = [], limit = 10, onChange, isDetail = false }) => {
13 | const [files, setFiles] = useState([])
14 | // console.log(3, value)
15 |
16 | useEffect(() => { // 展示传入的文件数据
17 | if (value && (value.length || value.fileName) ) { // 文件数值
18 | const newValues: any[] = []
19 | if (value && value.length) {
20 | value.forEach((item: any) => {
21 | const newItem = item
22 | if (!item.url) {
23 | newItem.name = item.fileName
24 | newItem.url = item.fileUrl
25 | newItem.uid = item.id ? item.id : Math.floor(Math.random() * 1000)
26 | }
27 | newValues.push(newItem)
28 | })
29 | } else if (value?.fileName) { // 文件对象
30 | newValues.push({
31 | name: value.fileName,
32 | url: value.fileUrl,
33 | uid: value.id ? value.id : Math.floor(Math.random() * 1000),
34 | })
35 | }
36 | setFiles(newValues)
37 |
38 | }
39 | }, [value])
40 |
41 | const action = `/api/upload/file`
42 |
43 | // 文件上传
44 | const changeFile = ({ file, fileList }: any) => {
45 | console.log(6, file, fileList)
46 | if (file.status !== 'uploading') {
47 | // 需要改变fileList的值,否则status的状态不会改变
48 | fileList = fileList.map((item: any) => {
49 | let newItem = {...item}
50 | if (item.response) {
51 | newItem = {
52 | fileName: item.name,
53 | fileUrl: item.response.data.fileUrl
54 | }
55 | }
56 | return newItem
57 | })
58 | onChange?.(fileList)
59 | }
60 | setFiles(fileList)
61 | }
62 |
63 | // 文件名icon
64 | const fileIcon = new Map([
65 | ['deflaut', ],
66 | ['txt', ],
67 | ['pdf', ],
68 | ['doc', ],
69 | ['docx', ],
70 | ['xls', ],
71 | ['xlsx', ],
72 | ['png', ],
73 | ['jpg', ],
74 | ['gif', ],
75 | ['unkown', ],
76 | ])
77 |
78 | const iconRender = (file: any) => {
79 | const { name } = file
80 | return fileIcon.get(name ? name.split('.')[1] : 'deflaut') ||
81 | }
82 |
83 | const checkFileSize = (file: any) => {
84 | const size = file.size / 1024 / 1024
85 | if (size > 10) {
86 | message.warn('上传文件大小不能超过10M。')
87 | return Upload.LIST_IGNORE
88 | }
89 | return true
90 | }
91 |
92 | return (
93 |
102 | { limit > files.length && !isDetail && limit > value.length ? } type="text" /> : null}
103 |
104 | )
105 | }
106 |
107 | export default ComUpload
108 |
--------------------------------------------------------------------------------
/src/locales/pt-BR/settings.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'app.settings.menuMap.basic': 'Configurações Básicas',
3 | 'app.settings.menuMap.security': 'Configurações de Segurança',
4 | 'app.settings.menuMap.binding': 'Vinculação de Conta',
5 | 'app.settings.menuMap.notification': 'Mensagens de Notificação',
6 | 'app.settings.basic.avatar': 'Avatar',
7 | 'app.settings.basic.change-avatar': 'Alterar avatar',
8 | 'app.settings.basic.email': 'Email',
9 | 'app.settings.basic.email-message': 'Por favor insira seu email!',
10 | 'app.settings.basic.nickname': 'Nome de usuário',
11 | 'app.settings.basic.nickname-message': 'Por favor insira seu nome de usuário!',
12 | 'app.settings.basic.profile': 'Perfil pessoal',
13 | 'app.settings.basic.profile-message': 'Por favor insira seu perfil pessoal!',
14 | 'app.settings.basic.profile-placeholder': 'Breve introdução sua',
15 | 'app.settings.basic.country': 'País/Região',
16 | 'app.settings.basic.country-message': 'Por favor insira país!',
17 | 'app.settings.basic.geographic': 'Província, estado ou cidade',
18 | 'app.settings.basic.geographic-message': 'Por favor insira suas informações geográficas!',
19 | 'app.settings.basic.address': 'Endereço',
20 | 'app.settings.basic.address-message': 'Por favor insira seu endereço!',
21 | 'app.settings.basic.phone': 'Número de telefone',
22 | 'app.settings.basic.phone-message': 'Por favor insira seu número de telefone!',
23 | 'app.settings.basic.update': 'Atualizar Informações',
24 | 'app.settings.security.strong': 'Forte',
25 | 'app.settings.security.medium': 'Média',
26 | 'app.settings.security.weak': 'Fraca',
27 | 'app.settings.security.password': 'Senha da Conta',
28 | 'app.settings.security.password-description': 'Força da senha',
29 | 'app.settings.security.phone': 'Telefone de Seguraça',
30 | 'app.settings.security.phone-description': 'Telefone vinculado',
31 | 'app.settings.security.question': 'Pergunta de Segurança',
32 | 'app.settings.security.question-description':
33 | 'A pergunta de segurança não está definida e a política de segurança pode proteger efetivamente a segurança da conta',
34 | 'app.settings.security.email': 'Email de Backup',
35 | 'app.settings.security.email-description': 'Email vinculado',
36 | 'app.settings.security.mfa': 'Dispositivo MFA',
37 | 'app.settings.security.mfa-description':
38 | 'O dispositivo MFA não vinculado, após a vinculação, pode ser confirmado duas vezes',
39 | 'app.settings.security.modify': 'Modificar',
40 | 'app.settings.security.set': 'Atribuir',
41 | 'app.settings.security.bind': 'Vincular',
42 | 'app.settings.binding.taobao': 'Vincular Taobao',
43 | 'app.settings.binding.taobao-description': 'Atualmente não vinculado à conta Taobao',
44 | 'app.settings.binding.alipay': 'Vincular Alipay',
45 | 'app.settings.binding.alipay-description': 'Atualmente não vinculado à conta Alipay',
46 | 'app.settings.binding.dingding': 'Vincular DingTalk',
47 | 'app.settings.binding.dingding-description': 'Atualmente não vinculado à conta DingTalk',
48 | 'app.settings.binding.bind': 'Vincular',
49 | 'app.settings.notification.password': 'Senha da Conta',
50 | 'app.settings.notification.password-description':
51 | 'Mensagens de outros usuários serão notificadas na forma de uma estação de letra',
52 | 'app.settings.notification.messages': 'Mensagens de Sistema',
53 | 'app.settings.notification.messages-description':
54 | 'Mensagens de sistema serão notificadas na forma de uma estação de letra',
55 | 'app.settings.notification.todo': 'Notificação de To-do',
56 | 'app.settings.notification.todo-description':
57 | 'A lista de to-do será notificada na forma de uma estação de letra',
58 | 'app.settings.open': 'Aberto',
59 | 'app.settings.close': 'Fechado',
60 | };
61 |
--------------------------------------------------------------------------------
/public/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/ProductInfo/index.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, forwardRef, useImperativeHandle } from 'react'
2 | import { Form, Input, Select,
3 | Row, Col, DatePicker } from 'antd'
4 | import moment from 'moment'
5 |
6 | const { Option } = Select
7 | const { TextArea } = Input
8 |
9 | const dateFormat = 'YYYY-MM-DD'
10 |
11 | export type productProps = {
12 | infoData?: any
13 | }
14 |
15 | const formInput = ({infoData}: productProps, ref: any) => {
16 | const [form] = Form.useForm()
17 |
18 | // 暴露组件的方法
19 | useImperativeHandle(ref, () => ({
20 | getForm: () => {
21 | return form
22 | }
23 | }))
24 |
25 | useEffect(() => {
26 | if (infoData) {
27 | form.setFieldsValue({...infoData,
28 | establishedTime: moment(infoData.establishedTime)})
29 | }
30 | }, [])
31 |
32 | const companyOptions = [
33 | {
34 | companyName: '大米科技有限公司',
35 | id: 1,
36 | companyCode: '1273883',
37 | desc: '这个公司非常棒',
38 | establishedTime: '2020-09-28'
39 | },
40 | {
41 | companyName: '大米科技有限公司2',
42 | id: 2,
43 | companyCode: '2273883',
44 | desc: '这个公司非常棒2',
45 | establishedTime: '2011-09-09'
46 | },
47 | {
48 | companyName: '大米科技有限公司3',
49 | id: 3,
50 | companyCode: '2273883',
51 | desc: '这个公司非常棒3',
52 | establishedTime: '2018-08-18'
53 | }
54 | ]
55 |
56 | // 根据选择公司进行回填
57 | const changeCompany = (val, option) => {
58 | console.log(option)
59 | form.setFieldsValue({
60 | ...option,
61 | establishedTime: moment(option.establishedtime)
62 | })
63 | }
64 | return (
65 |
66 |
128 |
129 | )
130 | }
131 |
132 | // 通过forwardRef传递
133 | export default forwardRef(formInput)
--------------------------------------------------------------------------------
/src/locales/fa-IR/pages.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'pages.layouts.userLayout.title': 'طراحی مورچه تأثیرگذارترین مشخصات طراحی وب در منطقه Xihu است',
3 | 'pages.login.accountLogin.tab': 'ورود به حساب کاربری',
4 | 'pages.login.accountLogin.errorMessage': 'نام کاربری / رمزعبور نادرست (مدیر / ant.design)',
5 | 'pages.login.username.placeholder': 'نام کاربری: مدیر یا کاربر',
6 | 'pages.login.username.required': 'لطفا نام کاربری خود را وارد کنید!',
7 | 'pages.login.password.placeholder': 'رمز عبور: ant.design',
8 | 'pages.login.password.required': 'لطفاً رمز ورود خود را وارد کنید!',
9 | 'pages.login.phoneLogin.tab': 'ورود به سیستم تلفن',
10 | 'pages.login.phoneLogin.errorMessage': 'خطای کد تأیید',
11 | 'pages.login.phoneNumber.placeholder': 'شماره تلفن',
12 | 'pages.login.phoneNumber.required': 'لطفاً شماره تلفن خود را وارد کنید!',
13 | 'pages.login.phoneNumber.invalid': 'شماره تلفن نامعتبر است!',
14 | 'pages.login.captcha.placeholder': 'کد تایید',
15 | 'pages.login.captcha.required': 'لطفا کد تأیید را وارد کنید!',
16 | 'pages.login.phoneLogin.getVerificationCode': 'دریافت کد',
17 | 'pages.getCaptchaSecondText': 'ثانیه',
18 | 'pages.login.rememberMe': 'مرا به خاطر بسپار',
19 | 'pages.login.forgotPassword': 'رمز عبور را فراموش کرده اید ?',
20 | 'pages.login.submit': 'ارسال',
21 | 'pages.login.loginWith': 'وارد شوید با :',
22 | 'pages.login.registerAccount': 'ثبت نام',
23 | 'pages.welcome.advancedComponent': 'مولفه پیشرفته',
24 | 'pages.welcome.link': 'خوش آمدید',
25 | 'pages.welcome.advancedLayout': 'چیدمان پیشرفته',
26 | 'pages.welcome.alertMessage': 'اجزای سنگین تر سریعتر و قوی تر آزاد شده اند.',
27 | 'pages.admin.subPage.title': 'این صفحه فقط توسط مدیر قابل مشاهده است',
28 | 'pages.admin.subPage.alertMessage':
29 | 'رابط کاربری Umi اکنون منتشر شده است ، برای شروع تجربه استفاده از npm run ui خوش آمدید.',
30 | 'pages.searchTable.createForm.newRule': 'قانون جدید',
31 | 'pages.searchTable.updateForm.ruleConfig': 'پیکربندی قانون',
32 | 'pages.searchTable.updateForm.basicConfig': 'اطلاعات اولیه',
33 | 'pages.searchTable.updateForm.ruleName.nameLabel': ' نام قانون',
34 | 'pages.searchTable.updateForm.ruleName.nameRules': 'لطفاً نام قانون را وارد کنید!',
35 | 'pages.searchTable.updateForm.ruleDesc.descLabel': 'شرح قانون',
36 | 'pages.searchTable.updateForm.ruleDesc.descPlaceholder': 'لطفاً حداقل پنج حرف وارد کنید',
37 | 'pages.searchTable.updateForm.ruleDesc.descRules':
38 | 'لطفاً حداقل یک قانون حاوی پنج کاراکتر شرح دهید!',
39 | 'pages.searchTable.updateForm.ruleProps.title': 'پیکربندی خصوصیات',
40 | 'pages.searchTable.updateForm.object': 'نظارت بر شی',
41 | 'pages.searchTable.updateForm.ruleProps.templateLabel': 'الگوی قانون',
42 | 'pages.searchTable.updateForm.ruleProps.typeLabel': 'نوع قانون',
43 | 'pages.searchTable.updateForm.schedulingPeriod.title': 'تنظیم دوره زمان بندی',
44 | 'pages.searchTable.updateForm.schedulingPeriod.timeLabel': 'زمان شروع',
45 | 'pages.searchTable.updateForm.schedulingPeriod.timeRules': 'لطفاً زمان شروع را انتخاب کنید!',
46 | 'pages.searchTable.titleDesc': 'شرح',
47 | 'pages.searchTable.ruleName': 'نام قانون لازم است',
48 | 'pages.searchTable.titleCallNo': 'تعداد تماس های خدماتی',
49 | 'pages.searchTable.titleStatus': 'وضعیت',
50 | 'pages.searchTable.nameStatus.default': 'پیش فرض',
51 | 'pages.searchTable.nameStatus.running': 'در حال دویدن',
52 | 'pages.searchTable.nameStatus.online': 'برخط',
53 | 'pages.searchTable.nameStatus.abnormal': 'غیرطبیعی',
54 | 'pages.searchTable.titleUpdatedAt': 'آخرین برنامه ریزی در',
55 | 'pages.searchTable.exception': 'لطفا دلیل استثنا را وارد کنید!',
56 | 'pages.searchTable.titleOption': 'گزینه',
57 | 'pages.searchTable.config': 'پیکربندی',
58 | 'pages.searchTable.subscribeAlert': 'مشترک شدن در هشدارها',
59 | 'pages.searchTable.title': 'فرم درخواست',
60 | 'pages.searchTable.new': 'جدید',
61 | 'pages.searchTable.chosen': 'انتخاب شده',
62 | 'pages.searchTable.item': 'مورد',
63 | 'pages.searchTable.totalServiceCalls': 'تعداد کل تماس های خدماتی',
64 | 'pages.searchTable.tenThousand': '0000',
65 | 'pages.searchTable.batchDeletion': 'حذف دسته ای',
66 | 'pages.searchTable.batchApproval': 'تصویب دسته ای',
67 | };
68 |
--------------------------------------------------------------------------------
/src/locales/id-ID/pages.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'pages.layouts.userLayout.title':
3 | 'Ant Design adalah spesifikasi desain Web yang paling berpengaruh di Kabupaten Xihu',
4 | 'pages.login.accountLogin.tab': 'Login dengan akun',
5 | 'pages.login.accountLogin.errorMessage': 'Nama pengguna dan kata sandi salah(admin/ant.design)',
6 | 'pages.login.username.placeholder': 'nama pengguna: admin atau user',
7 | 'pages.login.username.required': 'Nama pengguna harus diisi!',
8 | 'pages.login.password.placeholder': 'kata sandi: ant.design',
9 | 'pages.login.password.required': 'Kata sandi harus diisi!',
10 | 'pages.login.phoneLogin.tab': 'Login dengan ponsel',
11 | 'pages.login.phoneLogin.errorMessage': 'Kesalahan kode verifikasi',
12 | 'pages.login.phoneNumber.placeholder': 'masukkan nomor telepon',
13 | 'pages.login.phoneNumber.required': 'Nomor ponsel harus diisi!',
14 | 'pages.login.phoneNumber.invalid': 'Nomor ponsel tidak valid!',
15 | 'pages.login.captcha.placeholder': 'kode verifikasi',
16 | 'pages.login.captcha.required': 'Kode verifikasi diperlukan!',
17 | 'pages.login.phoneLogin.getVerificationCode': 'Dapatkan kode',
18 | 'pages.getCaptchaSecondText': 'detik tersisa',
19 | 'pages.login.rememberMe': 'Ingat saya',
20 | 'pages.login.forgotPassword': 'Lupa Kata Sandi?',
21 | 'pages.login.submit': 'Masuk',
22 | 'pages.login.loginWith': 'Masuk dengan :',
23 | 'pages.login.registerAccount': 'Daftar Akun',
24 | 'pages.welcome.advancedComponent': 'Formulir Lanjutan',
25 | 'pages.welcome.link': 'Selamat datang',
26 | 'pages.welcome.advancedLayout': 'Tata letak Lanjutan',
27 | 'pages.welcome.alertMessage':
28 | 'Komponen heavy-duty yang lebih cepat dan lebih kuat telah dirilis.',
29 | 'pages.admin.subPage.title': 'Halaman ini hanya dapat dilihat oleh admin',
30 | 'pages.admin.subPage.alertMessage':
31 | 'umi ui telah dirilis, silahkan gunakan npm run ui untuk memulai pengalaman.',
32 | 'pages.searchTable.createForm.newRule': 'Aturan baru',
33 | 'pages.searchTable.updateForm.ruleConfig': 'Konfigurasi aturan',
34 | 'pages.searchTable.updateForm.basicConfig': 'Informasi dasar',
35 | 'pages.searchTable.updateForm.ruleName.nameLabel': 'Nama aturan',
36 | 'pages.searchTable.updateForm.ruleName.nameRules': 'Harap masukkan nama aturan!',
37 | 'pages.searchTable.updateForm.ruleDesc.descLabel': 'Deskripsi aturan',
38 | 'pages.searchTable.updateForm.ruleDesc.descPlaceholder':
39 | 'Harap masukkan setidaknya lima karakter',
40 | 'pages.searchTable.updateForm.ruleDesc.descRules':
41 | 'Harap masukkan deskripsi aturan setidaknya lima karakter!',
42 | 'pages.searchTable.updateForm.ruleProps.title': 'Properti aturan',
43 | 'pages.searchTable.updateForm.object': 'Objek pemantauan',
44 | 'pages.searchTable.updateForm.ruleProps.templateLabel': 'Template aturan',
45 | 'pages.searchTable.updateForm.ruleProps.typeLabel': 'Jenis aturan',
46 | 'pages.searchTable.updateForm.schedulingPeriod.title': 'Periode penjadwalan',
47 | 'pages.searchTable.updateForm.schedulingPeriod.timeLabel': 'Waktu mulai',
48 | 'pages.searchTable.updateForm.schedulingPeriod.timeRules': 'Pilih waktu mulai!',
49 | 'pages.searchTable.titleDesc': 'deskripsi',
50 | 'pages.searchTable.ruleName': 'Nama aturan wajib diisi',
51 | 'pages.searchTable.titleCallNo': 'Jumlah panggilan',
52 | 'pages.searchTable.titleStatus': 'Status',
53 | 'pages.searchTable.nameStatus.default': 'default',
54 | 'pages.searchTable.nameStatus.running': 'menyala',
55 | 'pages.searchTable.nameStatus.online': 'online',
56 | 'pages.searchTable.nameStatus.abnormal': 'abnormal',
57 | 'pages.searchTable.titleUpdatedAt': 'Waktu terjadwal',
58 | 'pages.searchTable.exception': 'Harap masukkan alasan pengecualian!',
59 | 'pages.searchTable.titleOption': 'Pengoperasian',
60 | 'pages.searchTable.config': 'Konfigurasi',
61 | 'pages.searchTable.subscribeAlert': 'Berlangganan notifikasi',
62 | 'pages.searchTable.title': 'Formulir pertanyaan',
63 | 'pages.searchTable.new': 'Baru',
64 | 'pages.searchTable.chosen': 'Terpilih',
65 | 'pages.searchTable.item': 'item',
66 | 'pages.searchTable.totalServiceCalls': 'Jumlah total panggilan layanan',
67 | 'pages.searchTable.tenThousand': '0000',
68 | 'pages.searchTable.batchDeletion': 'Penghapusan batch',
69 | 'pages.searchTable.batchApproval': 'Persetujuan batch',
70 | };
71 |
--------------------------------------------------------------------------------