├── .gitignore
├── 1.1 数据结构:栈
├── demo01.html
├── demo02.html
├── demo03.html
└── demo04.html
├── 1.1.1 数组与Map
├── index.html
└── process.html
├── 1.2 数据结构:堆
├── demo01.html
└── demo02.html
├── 1.3 数据结构:队列
└── demo01.html
├── 1.4 数据结构:链表
└── demo01.html
├── 2.1 函数
└── 状态管理模块.html
├── 2.13 函数组合
├── demo01.html
└── demo02.html
├── 2.14 柯里化
├── 1.js
└── index.html
├── 2.2 作用域与作用域链
└── demo01.html
├── 2.3 函数调用栈
├── demo01.html
└── demo02.html
├── 2.4 执行上下文
└── demo01.html
├── 2.5 闭包
├── demo01.html
├── demo02.html
├── demo03.html
├── demo04.html
├── demo05.html
└── test.html
├── 2.7 this
└── demo01.html
├── 2.8 函数式编程
└── demo01.html
├── 3.0 对象
├── demo01.html
├── demo02.html
├── demo03.html
├── demo04.html
└── demo05.html
├── 3.1 一切始于封装
└── demo.html
├── 3.16 运动框架
├── demo.html
└── index.js
├── 4.6 jQuery 封装思维
└── index.html
├── 4.7 拖拽
├── index.html
└── index.js
├── 4.8 选项卡对象
├── index.html
└── index.js
├── 4.9 无缝滚动对象
├── index.html
└── index.js
├── 5.2 单例模式
├── 1.js
├── 2.js
├── 3.js
├── 4.js
└── index.html
├── 5.3 工厂模式
├── 1.js
├── 2.js
├── 3.js
├── 4.js
├── 5.js
└── index.html
├── 5.4 观察者模式
├── 1.js
├── 2.js
├── 3.js
├── 4.js
└── index.html
├── 5.5 代理模式
├── 1.js
├── 2.js
└── index.html
├── 5.6 策略模式
├── 1.js
├── 2.js
├── 3.js
└── index.html
├── 5.7 装饰者模式
├── 1.js
├── 2.js
└── index.html
├── 6.1 ES6常用语法
├── 1.js
├── 2.js
├── 3.js
└── index.html
├── 6.6 Promise封装
├── 1.js
├── 2.js
├── index.html
└── promise.js
├── 6.7 事件循环
├── 1.js
├── 2.js
├── 3.js
├── 4.js
├── 5.js
├── 6.js
├── 7.js
├── 8.js
└── index.html
├── 6.8 模块化
├── 1.js
├── 2.js
├── 3.js
├── 4.js
├── 5.js
├── 6.js
└── index.html
├── 6.8.1 模块化语法
└── my-app
│ ├── .eslintcache
│ ├── .gitignore
│ ├── README.md
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
│ ├── src
│ ├── App.css
│ ├── App.test.tsx
│ ├── App.tsx
│ ├── index.css
│ ├── index.tsx
│ ├── logo.svg
│ ├── person.ts
│ ├── person2.ts
│ ├── react-app-env.d.ts
│ ├── reportWebVitals.ts
│ └── setupTests.ts
│ ├── tsconfig.json
│ └── yarn.lock
├── 6.9模块化开发实例
├── controldiv
│ ├── .eslintcache
│ ├── .gitignore
│ ├── README.md
│ ├── package.json
│ ├── public
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ ├── logo192.png
│ │ ├── logo512.png
│ │ ├── manifest.json
│ │ └── robots.txt
│ ├── src
│ │ ├── App.test.tsx
│ │ ├── App.tsx
│ │ ├── box.ts
│ │ ├── controlButtons
│ │ │ ├── bgColor.ts
│ │ │ ├── borderColor.ts
│ │ │ ├── height.ts
│ │ │ ├── index.ts
│ │ │ ├── show.ts
│ │ │ └── width.ts
│ │ ├── index.css
│ │ ├── index.tsx
│ │ ├── logo.svg
│ │ ├── react-app-env.d.ts
│ │ ├── register.ts
│ │ ├── setupTests.ts
│ │ ├── state.ts
│ │ └── utils.ts
│ ├── tsconfig.json
│ └── yarn.lock
└── zhihunew
│ ├── .eslintcache
│ ├── .gitignore
│ ├── README.md
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
│ ├── src
│ ├── App.css
│ ├── App.test.tsx
│ ├── App.tsx
│ ├── api.ts
│ ├── data.ts
│ ├── index.css
│ ├── index.tsx
│ ├── logo.svg
│ ├── react-app-env.d.ts
│ ├── render.ts
│ ├── reportWebVitals.ts
│ ├── request.ts
│ └── setupTests.ts
│ ├── tsconfig.json
│ └── yarn.lock
├── 7.1组件化
└── tab
│ ├── .eslintcache
│ ├── .gitignore
│ ├── README.md
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
│ ├── src
│ ├── App.css
│ ├── App.test.tsx
│ ├── App.tsx
│ ├── Tabbar
│ │ ├── index.css
│ │ └── index.tsx
│ ├── index.css
│ ├── index.tsx
│ ├── logo.svg
│ ├── react-app-env.d.ts
│ ├── reportWebVitals.ts
│ ├── setupTests.ts
│ ├── tab.css
│ └── tab.ts
│ ├── tsconfig.json
│ └── yarn.lock
├── 7.2webpack
├── .gitignore
├── index.html
├── package-lock.json
├── package.json
├── src
│ ├── inbox.jpg
│ ├── index.css
│ ├── index.js
│ └── test.scss
└── webpack.config.js
├── 7.3React
└── controldiv
│ ├── .eslintcache
│ ├── .gitignore
│ ├── README.md
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
│ ├── src
│ ├── App.css
│ ├── App.test.tsx
│ ├── App.tsx
│ ├── components
│ │ └── Toast
│ │ │ ├── Container.tsx
│ │ │ ├── Item.tsx
│ │ │ ├── container.css
│ │ │ ├── index.tsx
│ │ │ └── item.css
│ ├── index.css
│ ├── index.tsx
│ ├── logo.svg
│ ├── react-app-env.d.ts
│ ├── reportWebVitals.ts
│ └── setupTests.ts
│ ├── tsconfig.json
│ └── yarn.lock
├── 7.4admin
├── .gitignore
├── CODE_OF_CONDUCT.md
├── Dockerfile
├── Dockerfile.dev
├── Dockerfile.hub
├── LICENSE
├── README.ar-DZ.md
├── README.fr-FR.md
├── README.ja-JP.md
├── README.md
├── README.pt-BR.md
├── README.ru-RU.md
├── README.tr-TR.md
├── README.zh-CN.md
├── azure-pipelines.yml
├── config
│ ├── config.dev.ts
│ ├── config.ts
│ ├── defaultSettings.ts
│ └── proxy.ts
├── docker
│ ├── docker-compose.dev.yml
│ ├── docker-compose.yml
│ └── nginx.conf
├── jest.config.js
├── jsconfig.json
├── mock
│ ├── listTableList.ts
│ ├── notices.ts
│ ├── route.ts
│ └── user.ts
├── package.json
├── public
│ ├── CNAME
│ ├── favicon.ico
│ ├── home_bg.png
│ ├── icons
│ │ ├── icon-128x128.png
│ │ ├── icon-192x192.png
│ │ └── icon-512x512.png
│ └── pro_icon.svg
├── src
│ ├── assets
│ │ └── logo.svg
│ ├── components
│ │ ├── Authorized
│ │ │ ├── Authorized.tsx
│ │ │ ├── AuthorizedRoute.tsx
│ │ │ ├── CheckPermissions.tsx
│ │ │ ├── PromiseRender.tsx
│ │ │ ├── Secured.tsx
│ │ │ ├── index.tsx
│ │ │ └── renderAuthorize.ts
│ │ ├── GlobalHeader
│ │ │ ├── AvatarDropdown.tsx
│ │ │ ├── NoticeIconView.tsx
│ │ │ ├── RightContent.tsx
│ │ │ └── index.less
│ │ ├── HeaderDropdown
│ │ │ ├── index.less
│ │ │ └── index.tsx
│ │ ├── HeaderSearch
│ │ │ ├── index.less
│ │ │ └── index.tsx
│ │ ├── NoticeIcon
│ │ │ ├── NoticeList.less
│ │ │ ├── NoticeList.tsx
│ │ │ ├── index.less
│ │ │ └── index.tsx
│ │ └── PageLoading
│ │ │ └── index.tsx
│ ├── e2e
│ │ ├── __mocks__
│ │ │ └── antd-pro-merge-less.js
│ │ └── baseLayout.e2e.js
│ ├── global.less
│ ├── global.tsx
│ ├── layouts
│ │ ├── BasicLayout.tsx
│ │ ├── BlankLayout.tsx
│ │ ├── SecurityLayout.tsx
│ │ ├── UserLayout.less
│ │ └── UserLayout.tsx
│ ├── locales
│ │ ├── en-US.ts
│ │ ├── en-US
│ │ │ ├── component.ts
│ │ │ ├── globalHeader.ts
│ │ │ ├── menu.ts
│ │ │ ├── pages.ts
│ │ │ ├── pwa.ts
│ │ │ ├── settingDrawer.ts
│ │ │ └── settings.ts
│ │ ├── id-ID.ts
│ │ ├── id-ID
│ │ │ ├── component.ts
│ │ │ ├── globalHeader.ts
│ │ │ ├── menu.ts
│ │ │ ├── pages.ts
│ │ │ ├── pwa.ts
│ │ │ ├── settingDrawer.ts
│ │ │ └── settings.ts
│ │ ├── ja-JP.ts
│ │ ├── ja-JP
│ │ │ ├── component.ts
│ │ │ ├── globalHeader.ts
│ │ │ ├── menu.ts
│ │ │ ├── pages.ts
│ │ │ ├── pwa.ts
│ │ │ ├── settingDrawer.ts
│ │ │ └── settings.ts
│ │ ├── pt-BR.ts
│ │ ├── pt-BR
│ │ │ ├── component.ts
│ │ │ ├── globalHeader.ts
│ │ │ ├── menu.ts
│ │ │ ├── pwa.ts
│ │ │ ├── settingDrawer.ts
│ │ │ └── settings.ts
│ │ ├── zh-CN.ts
│ │ ├── zh-CN
│ │ │ ├── component.ts
│ │ │ ├── globalHeader.ts
│ │ │ ├── menu.ts
│ │ │ ├── pages.ts
│ │ │ ├── pwa.ts
│ │ │ ├── settingDrawer.ts
│ │ │ └── settings.ts
│ │ ├── zh-TW.ts
│ │ └── zh-TW
│ │ │ ├── component.ts
│ │ │ ├── globalHeader.ts
│ │ │ ├── menu.ts
│ │ │ ├── pwa.ts
│ │ │ ├── settingDrawer.ts
│ │ │ └── settings.ts
│ ├── manifest.json
│ ├── models
│ │ ├── connect.d.ts
│ │ ├── global.ts
│ │ ├── login.ts
│ │ ├── setting.ts
│ │ └── user.ts
│ ├── pages
│ │ ├── 404.tsx
│ │ ├── Admin.tsx
│ │ ├── TableList
│ │ │ ├── components
│ │ │ │ └── UpdateForm.tsx
│ │ │ ├── data.d.ts
│ │ │ ├── index.tsx
│ │ │ └── service.ts
│ │ ├── User
│ │ │ ├── login
│ │ │ │ ├── index.less
│ │ │ │ └── index.tsx
│ │ │ ├── register-result
│ │ │ │ ├── index.tsx
│ │ │ │ ├── locales
│ │ │ │ │ ├── en-US.ts
│ │ │ │ │ ├── zh-CN.ts
│ │ │ │ │ └── zh-TW.ts
│ │ │ │ └── style.less
│ │ │ └── register
│ │ │ │ ├── _mock.ts
│ │ │ │ ├── index.tsx
│ │ │ │ ├── locales
│ │ │ │ ├── en-US.ts
│ │ │ │ ├── zh-CN.ts
│ │ │ │ └── zh-TW.ts
│ │ │ │ ├── model.ts
│ │ │ │ ├── service.ts
│ │ │ │ └── style.less
│ │ ├── Welcome.less
│ │ ├── Welcome.tsx
│ │ ├── account
│ │ │ ├── center
│ │ │ │ ├── Center.less
│ │ │ │ ├── _mock.ts
│ │ │ │ ├── components
│ │ │ │ │ ├── Applications
│ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ ├── ArticleListContent
│ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ ├── Articles
│ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ ├── AvatarList
│ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ └── Projects
│ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ └── index.tsx
│ │ │ │ ├── data.d.ts
│ │ │ │ ├── index.tsx
│ │ │ │ ├── model.ts
│ │ │ │ └── service.ts
│ │ │ └── settings
│ │ │ │ ├── _mock.ts
│ │ │ │ ├── components
│ │ │ │ ├── BaseView.less
│ │ │ │ ├── GeographicView.less
│ │ │ │ ├── GeographicView.tsx
│ │ │ │ ├── PhoneView.less
│ │ │ │ ├── PhoneView.tsx
│ │ │ │ ├── base.tsx
│ │ │ │ ├── binding.tsx
│ │ │ │ ├── notification.tsx
│ │ │ │ └── security.tsx
│ │ │ │ ├── data.d.ts
│ │ │ │ ├── geographic
│ │ │ │ ├── city.json
│ │ │ │ └── province.json
│ │ │ │ ├── index.tsx
│ │ │ │ ├── locales
│ │ │ │ ├── en-US.ts
│ │ │ │ ├── zh-CN.ts
│ │ │ │ └── zh-TW.ts
│ │ │ │ ├── model.ts
│ │ │ │ ├── service.ts
│ │ │ │ └── style.less
│ │ ├── dashboard
│ │ │ ├── analysis
│ │ │ │ ├── _mock.ts
│ │ │ │ ├── components
│ │ │ │ │ ├── Charts
│ │ │ │ │ │ ├── Bar
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── ChartCard
│ │ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── Field
│ │ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── Gauge
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── MiniArea
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── MiniBar
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── MiniProgress
│ │ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── Pie
│ │ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── TagCloud
│ │ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── TimelineChart
│ │ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── WaterWave
│ │ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── autoHeight.tsx
│ │ │ │ │ │ ├── bizcharts.tsx
│ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ ├── IntroduceRow.tsx
│ │ │ │ │ ├── NumberInfo
│ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ ├── OfflineData.tsx
│ │ │ │ │ ├── PageLoading
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ ├── ProportionSales.tsx
│ │ │ │ │ ├── SalesCard.tsx
│ │ │ │ │ ├── TopSearch.tsx
│ │ │ │ │ └── Trend
│ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ └── index.tsx
│ │ │ │ ├── data.d.ts
│ │ │ │ ├── index.tsx
│ │ │ │ ├── locales
│ │ │ │ │ ├── en-US.ts
│ │ │ │ │ ├── pt-BR.ts
│ │ │ │ │ ├── zh-CN.ts
│ │ │ │ │ └── zh-TW.ts
│ │ │ │ ├── model.ts
│ │ │ │ ├── service.ts
│ │ │ │ ├── style.less
│ │ │ │ └── utils
│ │ │ │ │ ├── Yuan.tsx
│ │ │ │ │ ├── utils.less
│ │ │ │ │ └── utils.ts
│ │ │ ├── monitor
│ │ │ │ ├── _mock.ts
│ │ │ │ ├── components
│ │ │ │ │ ├── ActiveChart
│ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ └── Charts
│ │ │ │ │ │ ├── Gauge
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── Map
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── MiniArea
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── Pie
│ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── TagCloud
│ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── WaterWave
│ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── autoHeight.tsx
│ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ └── index.tsx
│ │ │ │ ├── data.d.ts
│ │ │ │ ├── index.tsx
│ │ │ │ ├── locales
│ │ │ │ │ ├── en-US.ts
│ │ │ │ │ ├── pt-BR.ts
│ │ │ │ │ ├── zh-CN.ts
│ │ │ │ │ └── zh-TW.ts
│ │ │ │ ├── model.ts
│ │ │ │ ├── service.ts
│ │ │ │ └── style.less
│ │ │ └── workplace
│ │ │ │ ├── _mock.ts
│ │ │ │ ├── components
│ │ │ │ ├── EditableLinkGroup
│ │ │ │ │ ├── index.less
│ │ │ │ │ └── index.tsx
│ │ │ │ └── Radar
│ │ │ │ │ ├── autoHeight.tsx
│ │ │ │ │ ├── index.less
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── data.d.ts
│ │ │ │ ├── index.tsx
│ │ │ │ ├── model.ts
│ │ │ │ ├── service.ts
│ │ │ │ └── style.less
│ │ ├── document.ejs
│ │ ├── editor
│ │ │ ├── flow
│ │ │ │ ├── common
│ │ │ │ │ └── IconFont
│ │ │ │ │ │ └── index.ts
│ │ │ │ ├── components
│ │ │ │ │ ├── EditorContextMenu
│ │ │ │ │ │ ├── FlowContextMenu.tsx
│ │ │ │ │ │ ├── KoniContextMenu.tsx
│ │ │ │ │ │ ├── MenuItem.tsx
│ │ │ │ │ │ ├── MindContextMenu.tsx
│ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ ├── EditorDetailPanel
│ │ │ │ │ │ ├── DetailForm.tsx
│ │ │ │ │ │ ├── FlowDetailPanel.tsx
│ │ │ │ │ │ ├── KoniDetailPanel.tsx
│ │ │ │ │ │ ├── MindDetailPanel.tsx
│ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ ├── EditorItemPanel
│ │ │ │ │ │ ├── FlowItemPanel.tsx
│ │ │ │ │ │ ├── KoniItemPanel.tsx
│ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ ├── EditorMinimap
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ └── EditorToolbar
│ │ │ │ │ │ ├── FlowToolbar.tsx
│ │ │ │ │ │ ├── KoniToolbar.tsx
│ │ │ │ │ │ ├── MindToolbar.tsx
│ │ │ │ │ │ ├── ToolbarButton.tsx
│ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ └── index.tsx
│ │ │ │ ├── index.less
│ │ │ │ ├── index.tsx
│ │ │ │ └── locales
│ │ │ │ │ ├── en-US.ts
│ │ │ │ │ └── zh-CN.ts
│ │ │ ├── koni
│ │ │ │ ├── common
│ │ │ │ │ └── IconFont
│ │ │ │ │ │ └── index.ts
│ │ │ │ ├── components
│ │ │ │ │ ├── EditorContextMenu
│ │ │ │ │ │ ├── FlowContextMenu.tsx
│ │ │ │ │ │ ├── KoniContextMenu.tsx
│ │ │ │ │ │ ├── MenuItem.tsx
│ │ │ │ │ │ ├── MindContextMenu.tsx
│ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ ├── EditorDetailPanel
│ │ │ │ │ │ ├── DetailForm.tsx
│ │ │ │ │ │ ├── FlowDetailPanel.tsx
│ │ │ │ │ │ ├── KoniDetailPanel.tsx
│ │ │ │ │ │ ├── MindDetailPanel.tsx
│ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ ├── EditorItemPanel
│ │ │ │ │ │ ├── FlowItemPanel.tsx
│ │ │ │ │ │ ├── KoniItemPanel.tsx
│ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ ├── EditorMinimap
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ └── EditorToolbar
│ │ │ │ │ │ ├── FlowToolbar.tsx
│ │ │ │ │ │ ├── KoniToolbar.tsx
│ │ │ │ │ │ ├── MindToolbar.tsx
│ │ │ │ │ │ ├── ToolbarButton.tsx
│ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ └── index.tsx
│ │ │ │ ├── index.less
│ │ │ │ ├── index.tsx
│ │ │ │ └── locales
│ │ │ │ │ ├── en-US.ts
│ │ │ │ │ └── zh-CN.ts
│ │ │ └── mind
│ │ │ │ ├── common
│ │ │ │ └── IconFont
│ │ │ │ │ └── index.ts
│ │ │ │ ├── components
│ │ │ │ ├── EditorContextMenu
│ │ │ │ │ ├── FlowContextMenu.tsx
│ │ │ │ │ ├── KoniContextMenu.tsx
│ │ │ │ │ ├── MenuItem.tsx
│ │ │ │ │ ├── MindContextMenu.tsx
│ │ │ │ │ ├── index.less
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── EditorDetailPanel
│ │ │ │ │ ├── DetailForm.tsx
│ │ │ │ │ ├── FlowDetailPanel.tsx
│ │ │ │ │ ├── KoniDetailPanel.tsx
│ │ │ │ │ ├── MindDetailPanel.tsx
│ │ │ │ │ ├── index.less
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── EditorItemPanel
│ │ │ │ │ ├── FlowItemPanel.tsx
│ │ │ │ │ ├── KoniItemPanel.tsx
│ │ │ │ │ ├── index.less
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── EditorMinimap
│ │ │ │ │ └── index.tsx
│ │ │ │ └── EditorToolbar
│ │ │ │ │ ├── FlowToolbar.tsx
│ │ │ │ │ ├── KoniToolbar.tsx
│ │ │ │ │ ├── MindToolbar.tsx
│ │ │ │ │ ├── ToolbarButton.tsx
│ │ │ │ │ ├── index.less
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── index.less
│ │ │ │ ├── index.tsx
│ │ │ │ ├── locales
│ │ │ │ ├── en-US.ts
│ │ │ │ └── zh-CN.ts
│ │ │ │ └── worldCup2018.json
│ │ ├── exception
│ │ │ ├── 403
│ │ │ │ └── index.tsx
│ │ │ ├── 404
│ │ │ │ └── index.tsx
│ │ │ └── 500
│ │ │ │ ├── index.tsx
│ │ │ │ └── locales
│ │ │ │ ├── en-US.ts
│ │ │ │ ├── pt-BR.ts
│ │ │ │ ├── zh-CN.ts
│ │ │ │ └── zh-TW.ts
│ │ ├── form
│ │ │ ├── advanced-form
│ │ │ │ ├── _mock.ts
│ │ │ │ ├── components
│ │ │ │ │ └── TableForm.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── model.ts
│ │ │ │ ├── service.ts
│ │ │ │ └── style.less
│ │ │ ├── basic-form
│ │ │ │ ├── _mock.ts
│ │ │ │ ├── index.tsx
│ │ │ │ ├── locales
│ │ │ │ │ ├── en-US.ts
│ │ │ │ │ ├── pt-BR.ts
│ │ │ │ │ ├── zh-CN.ts
│ │ │ │ │ └── zh-TW.ts
│ │ │ │ ├── model.ts
│ │ │ │ ├── service.ts
│ │ │ │ └── style.less
│ │ │ └── step-form
│ │ │ │ ├── _mock.ts
│ │ │ │ ├── components
│ │ │ │ ├── Step1
│ │ │ │ │ ├── index.less
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── Step2
│ │ │ │ │ ├── index.less
│ │ │ │ │ └── index.tsx
│ │ │ │ └── Step3
│ │ │ │ │ ├── index.less
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── locales
│ │ │ │ ├── en-US.ts
│ │ │ │ ├── pt-BR.ts
│ │ │ │ ├── zh-CN.ts
│ │ │ │ └── zh-TW.ts
│ │ │ │ ├── model.ts
│ │ │ │ ├── service.ts
│ │ │ │ └── style.less
│ │ ├── list
│ │ │ ├── basic-list
│ │ │ │ ├── _mock.ts
│ │ │ │ ├── components
│ │ │ │ │ └── OperationModal.tsx
│ │ │ │ ├── data.d.ts
│ │ │ │ ├── index.tsx
│ │ │ │ ├── model.ts
│ │ │ │ ├── service.ts
│ │ │ │ ├── style.less
│ │ │ │ └── utils
│ │ │ │ │ └── utils.less
│ │ │ ├── card-list
│ │ │ │ ├── _mock.ts
│ │ │ │ ├── data.d.ts
│ │ │ │ ├── index.tsx
│ │ │ │ ├── model.ts
│ │ │ │ ├── service.ts
│ │ │ │ ├── style.less
│ │ │ │ └── utils
│ │ │ │ │ └── utils.less
│ │ │ ├── search
│ │ │ │ ├── applications
│ │ │ │ │ ├── _mock.ts
│ │ │ │ │ ├── components
│ │ │ │ │ │ ├── StandardFormRow
│ │ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ └── TagSelect
│ │ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ ├── data.d.ts
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── model.ts
│ │ │ │ │ ├── service.ts
│ │ │ │ │ ├── style.less
│ │ │ │ │ └── utils
│ │ │ │ │ │ └── utils.less
│ │ │ │ ├── articles
│ │ │ │ │ ├── _mock.ts
│ │ │ │ │ ├── components
│ │ │ │ │ │ ├── ArticleListContent
│ │ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ ├── StandardFormRow
│ │ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ │ └── TagSelect
│ │ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ │ └── index.tsx
│ │ │ │ │ ├── data.d.ts
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── model.ts
│ │ │ │ │ ├── service.ts
│ │ │ │ │ └── style.less
│ │ │ │ ├── index.tsx
│ │ │ │ └── projects
│ │ │ │ │ ├── _mock.ts
│ │ │ │ │ ├── components
│ │ │ │ │ ├── AvatarList
│ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ ├── StandardFormRow
│ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ └── TagSelect
│ │ │ │ │ │ ├── index.less
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ ├── data.d.ts
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── model.ts
│ │ │ │ │ ├── service.ts
│ │ │ │ │ ├── style.less
│ │ │ │ │ └── utils
│ │ │ │ │ └── utils.less
│ │ │ └── table-list
│ │ │ │ ├── _mock.ts
│ │ │ │ ├── components
│ │ │ │ ├── CreateForm.tsx
│ │ │ │ └── UpdateForm.tsx
│ │ │ │ ├── data.d.ts
│ │ │ │ ├── index.tsx
│ │ │ │ └── service.ts
│ │ ├── profile
│ │ │ ├── advanced
│ │ │ │ ├── _mock.ts
│ │ │ │ ├── data.d.ts
│ │ │ │ ├── index.tsx
│ │ │ │ ├── model.ts
│ │ │ │ ├── service.ts
│ │ │ │ └── style.less
│ │ │ └── basic
│ │ │ │ ├── _mock.ts
│ │ │ │ ├── data.d.ts
│ │ │ │ ├── index.tsx
│ │ │ │ ├── model.ts
│ │ │ │ ├── service.ts
│ │ │ │ └── style.less
│ │ └── result
│ │ │ ├── fail
│ │ │ ├── index.less
│ │ │ ├── index.tsx
│ │ │ └── locales
│ │ │ │ ├── en-US.ts
│ │ │ │ ├── zh-CN.ts
│ │ │ │ └── zh-TW.ts
│ │ │ └── success
│ │ │ ├── index.less
│ │ │ ├── index.tsx
│ │ │ └── locales
│ │ │ ├── en-US.ts
│ │ │ ├── zh-CN.ts
│ │ │ └── zh-TW.ts
│ ├── service-worker.js
│ ├── services
│ │ ├── login.ts
│ │ └── user.ts
│ ├── typings.d.ts
│ └── utils
│ │ ├── Authorized.ts
│ │ ├── authority.ts
│ │ ├── request.ts
│ │ ├── utils.less
│ │ ├── utils.test.ts
│ │ └── utils.ts
├── tests
│ ├── PuppeteerEnvironment.js
│ ├── beforeTest.js
│ ├── getBrowser.js
│ └── run-tests.js
└── tsconfig.json
├── README.md
└── other
└── demo01.html
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 | dist
--------------------------------------------------------------------------------
/1.1 数据结构:栈/demo01.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
8 |
9 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/1.1.1 数组与Map/process.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 视频进度条
8 |
24 |
25 |
26 |
27 |
基础概念
28 |
火焰图及性能优化
29 |
栈的实现
30 |
栈的算法题
31 |
嵌套思维与实践场景
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/2.14 柯里化/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 函数式编程 - 柯里化
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/2.3 函数调用栈/demo01.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 函数调用栈
7 |
8 |
9 |
26 |
27 |
--------------------------------------------------------------------------------
/2.3 函数调用栈/demo02.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 函数调用栈:闭包
7 |
8 |
9 |
21 |
22 |
--------------------------------------------------------------------------------
/2.4 执行上下文/demo01.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 执行上下文
7 |
8 |
9 |
24 |
25 |
--------------------------------------------------------------------------------
/2.5 闭包/demo01.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 闭包
7 |
8 |
9 |
10 |
44 |
45 |
--------------------------------------------------------------------------------
/2.5 闭包/demo02.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 闭包
7 |
8 |
9 |
10 |
56 |
57 |
--------------------------------------------------------------------------------
/2.5 闭包/test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 调试工具
7 |
8 |
9 |
10 |
29 |
30 |
--------------------------------------------------------------------------------
/2.8 函数式编程/demo01.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 封装
7 |
8 |
9 |
10 |
11 |
34 |
35 |
--------------------------------------------------------------------------------
/3.0 对象/demo01.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 对象
7 |
8 |
9 |
35 |
36 |
--------------------------------------------------------------------------------
/3.0 对象/demo02.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 对象
7 |
8 |
9 |
40 |
41 |
--------------------------------------------------------------------------------
/3.0 对象/demo03.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 对象
7 |
8 |
9 |
31 |
32 |
--------------------------------------------------------------------------------
/3.0 对象/demo04.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 对象
7 |
8 |
9 |
20 |
21 |
--------------------------------------------------------------------------------
/3.16 运动框架/demo.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/4.7 拖拽/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/5.2 单例模式/1.js:
--------------------------------------------------------------------------------
1 | class Login {
2 | // 使用静态属性在内存存储实例
3 | static instance = null
4 | constructor(parentNode) {
5 | // 判断,如果已经存在实例,直接返回该实例
6 | if (Login.instance) {
7 | return Login.instance
8 | }
9 | this.parentNode = parentNode
10 | this.render()
11 | Login.instance = this
12 | return this
13 | }
14 |
15 | show() { }
16 | hide() { }
17 | // 渲染 DOM 节点
18 | render() { }
19 | }
20 |
21 | const p2 = new Login()
22 | const p1 = new Login()
23 |
24 | console.log(p1 === p2) // true
25 |
--------------------------------------------------------------------------------
/5.2 单例模式/2.js:
--------------------------------------------------------------------------------
1 | const Login = (function () {
2 | // 使用 闭包 在内存存储实例
3 | let instance = null
4 | class LoginComponent {
5 | constructor(parentNode) {
6 | // 判断,如果已经存在实例,直接返回该实例
7 | if (instance) {
8 | return instance
9 | }
10 | this.parentNode = parentNode
11 | this.render()
12 | instance = this
13 | return this
14 | }
15 |
16 | show() { }
17 | hide() { }
18 | // 渲染 DOM 节点
19 | render() { }
20 | }
21 | return LoginComponent
22 | })()
23 |
24 | const p2 = new Login()
25 | const p1 = new Login()
26 |
27 | console.log(p1 === p2) // true
28 |
--------------------------------------------------------------------------------
/5.2 单例模式/3.js:
--------------------------------------------------------------------------------
1 | class Login {
2 | constructor() { }
3 | show() { }
4 | hide() { }
5 | // 渲染 DOM 节点
6 | render() { }
7 | }
8 |
9 | const LoginProxy = (function () {
10 | let instance = null
11 | return function() {
12 | if (!instance) {
13 | instance = new Login()
14 | }
15 | return instance
16 | }
17 | })()
18 |
19 | const p1 = new LoginProxy()
20 | const p2 = new LoginProxy()
21 |
22 | console.log(p1 === p2)
--------------------------------------------------------------------------------
/5.2 单例模式/4.js:
--------------------------------------------------------------------------------
1 | class Login {
2 | constructor() { }
3 | show() { }
4 | hide() { }
5 | // 渲染 DOM 节点
6 | render() { }
7 | }
8 |
9 | function singleCreator(constructor) {
10 | let instance = null
11 | return function() {
12 | if (!instance) {
13 | instance = new constructor()
14 | }
15 | return instance
16 | }
17 | }
18 |
19 | const _Login = singleCreator(Login)
20 |
21 | const p1 = new _Login()
22 | const p2 = new _Login()
23 | console.log(p1)
24 | console.log(p1 === p2, 4)
--------------------------------------------------------------------------------
/5.2 单例模式/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 单例模式
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/5.3 工厂模式/2.js:
--------------------------------------------------------------------------------
1 | class PhoneFactory {
2 | constructor(type) {
3 | if (type == 'xiaomi') {
4 | this.materials = {
5 | 1: 'xiaomi_material1',
6 | 2: 'xiaomi_material2',
7 | 3: 'xiaomi_material3',
8 | }
9 | }
10 | if (type == 'iphone') {
11 | this.materials = {
12 | 1: 'iphone_material1',
13 | 2: 'iphone_material2',
14 | 3: 'iphone_material3',
15 | }
16 | }
17 | if (type == 'huawei') {
18 | this.materials = {
19 | 1: 'huawei_material1',
20 | 2: 'huawei_material2',
21 | 3: 'huawei_material3',
22 | }
23 | }
24 | }
25 | step1() {}
26 | step2() {}
27 | step3() {}
28 | step4() {}
29 | }
30 |
31 | const xm = new PhoneFactory('xiaomi')
32 | const ip = new PhoneFactory('iphone')
33 | const hw = new PhoneFactory('huawei')
34 |
35 | function foo() {}
36 |
37 | function factory(type) {
38 | return new window[type]()
39 | }
40 |
41 | factory('foo')
42 |
--------------------------------------------------------------------------------
/5.3 工厂模式/3.js:
--------------------------------------------------------------------------------
1 | function Factory() {}
2 | Factory.prototype.create = function(type) {
3 | var cur = this.config[type]
4 | if (cur) {
5 | return new this.config[type]()
6 | }
7 | }
8 | Factory.prototype.config = {}
9 | Factory.prototype.setConfig = function(type, sub) {
10 | this.config[type] = sub
11 | }
12 |
13 |
14 | class Xiaomi5 {
15 | constructor() {
16 | this.materials = {
17 | 1: 'xiaomi_material1',
18 | 2: 'xiaomi_material2',
19 | 3: 'xiaomi_material3',
20 | }
21 | }
22 | step1() {}
23 | step2() {}
24 | step3() {}
25 | step4() {}
26 | }
27 |
28 | new Factory().setConfig('xiaomi5', Xiaomi5)
29 |
--------------------------------------------------------------------------------
/5.3 工厂模式/4.js:
--------------------------------------------------------------------------------
1 | const config = {
2 | xiaomi: {
3 | 1: 'xiaomi_material1',
4 | 2: 'xiaomi_material2',
5 | 3: 'xiaomi_material3',
6 | },
7 | iphone: {
8 | 1: 'iphone_material1',
9 | 2: 'iphone_material2',
10 | 3: 'iphone_material3',
11 | },
12 | huawei: {
13 | 1: 'huawei_material1',
14 | 2: 'huawei_material2',
15 | 3: 'huawei_material3',
16 | }
17 | }
18 |
19 | class PhoneFactory {
20 | constructor(type) {
21 | this.materials = config[type]
22 | }
23 | step1() {}
24 | step2() {}
25 | step3() {}
26 | step4() {}
27 | }
28 |
29 | const xm = new PhoneFactory('xiaomi')
30 | const ip = new PhoneFactory('iphone')
31 | const hw = new PhoneFactory('huawei')
--------------------------------------------------------------------------------
/5.3 工厂模式/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 工厂模式
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/5.4 观察者模式/1.js:
--------------------------------------------------------------------------------
1 | var event = new Event('build')
2 |
3 | // 观察者
4 | document.addEventListener('build', function () {
5 | console.log('我是新增的一个观察者1,我现在观察到 document 触发了 build 事件')
6 | })
7 |
8 | // 观察者
9 | document.addEventListener('build', function () {
10 | console.log('我是新增的一个观察者2,我现在观察到 document 触发了 build 事件')
11 | })
12 |
13 | // 被观察者 触发事件
14 | document.dispatchEvent(event)
--------------------------------------------------------------------------------
/5.4 观察者模式/2.js:
--------------------------------------------------------------------------------
1 | let subjectid = 0
2 | let observerid = 0
3 |
4 | class Subject {
5 | constructor(name) {
6 | // 观察者队列
7 | this.observers = []
8 | this.id = subjectid++
9 | this.name = name
10 | }
11 |
12 | // 添加观察者
13 | addListener(observer) {
14 | this.observers.push(observer)
15 | }
16 |
17 | // 删除观察者
18 | removeListener(observer) {
19 | this.observers = this.observers.filter(item => item.id !== observer.id)
20 | }
21 |
22 | // 通知
23 | dispatch() {
24 | this.observers.forEach(item => {
25 | item.watch(this.name)
26 | })
27 | }
28 | }
29 |
30 | class Observer {
31 | constructor() {
32 | this.id = observerid++
33 | }
34 | watch(subjectName) {
35 | console.log(`观察者${this.id}发现了被观察者 ${subjectName} 产生了变化。`)
36 | }
37 | }
38 |
39 | const sub = new Subject('div元素')
40 | const observer1 = new Observer()
41 | const observer2 = new Observer()
42 |
43 | sub.addListener(observer1)
44 | sub.addListener(observer2)
45 |
46 | sub.dispatch()
47 |
--------------------------------------------------------------------------------
/5.4 观察者模式/3.js:
--------------------------------------------------------------------------------
1 | class Subject {
2 | constructor(name) {
3 | // 观察者队列
4 | // 格式为: { click: [fn1, fn2], scroll: [fn1, fn2] }
5 | this.events = {}
6 | this.name = name
7 | }
8 |
9 | // 添加观察者
10 | addListener(type, fn) {
11 | const cbs = this.events[type]
12 | if (cbs && cbs.length > 0) {
13 | const _cbs = cbs.filter(cb => cb != cbs)
14 | _cbs.push(fn)
15 | this.events[type] = _cbs
16 | } else {
17 | this.events[type] = [fn]
18 | }
19 | }
20 |
21 | // 删除观察者
22 | removeListener(type) {
23 | delete this.events[type]
24 | }
25 |
26 | // 通知
27 | dispatch(type) {
28 | this.events[type].forEach(cb => cb())
29 | }
30 | }
31 |
32 | const sub = new Subject('div')
33 |
34 | sub.addListener('build', function() {
35 | console.log('build 事件触发1')
36 | })
37 | sub.addListener('build', function () {
38 | console.log('build 事件触发2')
39 | })
40 | sub.addListener('click', function() {
41 | console.log('click 事件触发')
42 | })
43 |
44 | sub.dispatch('build')
45 |
--------------------------------------------------------------------------------
/5.4 观察者模式/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 观察者模式
7 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/5.5 代理模式/2.js:
--------------------------------------------------------------------------------
1 | var targetImage = (function () {
2 | var imgNode = document.createElement('img');
3 | document.body.appendChild(imgNode);
4 | return {
5 | setSrc: function (src) {
6 | imgNode.src = src;
7 | }
8 | }
9 | })();
10 |
11 | var proxyImage = (function() {
12 | var img = new Image();
13 | // 先加载 loading 或者默认图片用于快速显示
14 | targetImage.setSrc('loading.gif')
15 | img.onload = img.onerror = function () {
16 | // 加载完成之后,替换目标图片
17 | targetImage.setSrc(img.src);
18 | };
19 |
20 | return {
21 | setSrc: function (src) {
22 | // 此时开始加载图片
23 | img.src = src;
24 | }
25 | }
26 | })();
27 |
28 | proxyImage.setSrc('https://cn.bing.com/sa/simg/hpb/LaDigue_EN-CA1115245085_1920x1080.jpg');
29 |
--------------------------------------------------------------------------------
/5.5 代理模式/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 代理模式
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/5.6 策略模式/1.js:
--------------------------------------------------------------------------------
1 | function getBouns(base, level) {
2 | if (level == 'A') {
3 | return base * 5
4 | }
5 | if (level == 'B') {
6 | return base * 4
7 | }
8 | if (level == 'C') {
9 | return base * 3
10 | }
11 | if (level == 'D') {
12 | return base * 2
13 | }
14 | if (level == 'E') {
15 | return base * 1
16 | }
17 | }
18 |
19 |
20 | const p1 = {
21 | name: '张三',
22 | base: 1000,
23 | level: 'A'
24 | }
25 | p1.bouns = getBouns(p1.base, p1.level)
26 |
27 | console.log(p1)
--------------------------------------------------------------------------------
/5.6 策略模式/2.js:
--------------------------------------------------------------------------------
1 | const map = {
2 | A: function(base) {
3 | return base * 5
4 | },
5 | B: function (base) {
6 | return base * 4
7 | },
8 | C: function (base) {
9 | return base * 3
10 | },
11 | D: function (base) {
12 | return base * 2
13 | },
14 | E: function (base) {
15 | return base * 1
16 | },
17 | }
18 |
19 | function getBouns(base, level) {
20 | return map[level](base)
21 | }
22 |
23 |
24 | const p2 = {
25 | name: '李四',
26 | base: 1200,
27 | level: 'B'
28 | }
29 | p2.bouns = getBouns(p2.base, p2.level)
30 |
31 | console.log(p2)
--------------------------------------------------------------------------------
/5.6 策略模式/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 策略模式
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/5.7 装饰者模式/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 装饰者模式
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/6.1 ES6常用语法/1.js:
--------------------------------------------------------------------------------
1 | {
2 | let a = 20
3 | }
4 |
5 | // Uncaught ReferenceError: a is not defined
6 | console.log(a)
--------------------------------------------------------------------------------
/6.1 ES6常用语法/3.js:
--------------------------------------------------------------------------------
1 | // var tom = {
2 | // name: 'TOM',
3 | // age: 20,
4 | // gender: 1,
5 | // job: 'studend'
6 | // }
7 |
8 | // const {
9 | // name: name,
10 | // age: age,
11 | // gender: gender,
12 | // job: job
13 | // } = tom;
14 |
15 | // const peoples = {
16 | // counts: 100,
17 | // detail: {
18 | // tom: {
19 | // name: 'tom',
20 | // age: 20,
21 | // gender: 1,
22 | // job: 'student'
23 | // }
24 | // }
25 | // }
26 |
27 | // // 获取tom
28 | // const { detail: { tom } } = peoples;
29 |
30 | // // 直接获取tom的age与gender
31 | // const { detail: { tom: { age, gender } } } = peoples;
32 |
33 |
34 | // var a = 10;
35 | // var b = 20;
36 |
37 | // [a, b] = [b, a];
38 | // console.log(a); // 20
39 | // console.log(b); // 10
40 |
41 |
42 | const p = {
43 | name: 'tony'
44 | }
45 | p.__proto__.age = 20
46 |
47 | const {name, age} = p
48 | console.log(name, age) // tony 20
--------------------------------------------------------------------------------
/6.1 ES6常用语法/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ES6+ 常用语法
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/6.6 Promise封装/1.js:
--------------------------------------------------------------------------------
1 | const p = new MyPromise2((resolve, reject) => {
2 | setTimeout(() => {
3 | resolve('World')
4 | }, 1000)
5 | })
6 |
7 | console.log(p)
8 |
9 | p.then(res => {
10 | console.log('1 then:', res)
11 | return 'hello ' + res
12 | }).then(res => {
13 | console.log('2 then:', res)
14 | }).catch(err => {
15 | console.log('catch', err)
16 | }).finally(() => {
17 | console.log('我都会执行')
18 | })
--------------------------------------------------------------------------------
/6.6 Promise封装/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 封装 Promise 对象
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/6.7 事件循环/1.js:
--------------------------------------------------------------------------------
1 | new Promise(resolve => {
2 | resolve()
3 | })
4 | .then(() => {
5 | Promise(resolve => {
6 | resolve()
7 | })
8 | .then(() => {
9 | console.log(1)
10 | })
11 | .then(() => {
12 | console.log(2)
13 | })
14 | .then(() => {
15 | console.log(3.1)
16 | })
17 | })
18 | .then(() => {
19 | console.log(1.1)
20 | new Promise((resolve => {
21 | resolve()
22 | }))
23 | .then(() => {
24 | new Promise(resolve => {
25 | resolve()
26 | })
27 | .then(() => {
28 | console.log(4)
29 | })
30 | .then(() => {
31 | console.log(6)
32 | })
33 | }).then(() => {
34 | console.log(5)
35 | })
36 | })
37 | .then(() => {
38 | console.log(3)
39 | })
40 | console.log(0)
41 |
42 |
--------------------------------------------------------------------------------
/6.7 事件循环/2.js:
--------------------------------------------------------------------------------
1 | // 队列分析,数字表示右侧代码行数
2 | queue = [4]
3 | // 已经知道了 回调 4 的返回结果为 undefined,所以 18 也可以入列了
4 | queue = [8, 18] // 4 出列、8、18入列,
5 |
6 | // 执行 8,输出1,得知了 8 的返回结果为 undefined,11也可以入列
7 | queue = [18, 11]
8 |
9 | // 执行 18,输出 1.1,23 可直接入列,同时能得知 18 的返回结果,37入列
10 | queue = [11, 23, 37]
11 |
12 | // 执行 11,输出 2,得到11的返回结果,14可入列
13 | queue = [23, 37, 14]
14 |
15 | // 执行 23,27可直接入列,同时得到 23 的返回结果,33可直接入列
16 | queue = [37, 14, 27, 33]
17 |
18 | // 执行 37,输出 3
19 | queue = [14, 27, 33]
20 |
21 | // 执行 14,输出3.1
22 | queue = [27, 33]
23 |
24 | // 执行 27,输出 4,得到27的返回结果,30可直接入列
25 | queue = [33, 30]
26 |
27 | // 执行 33,输出 5
28 | queue = [30]
29 |
30 | // 执行 30,输出 6
31 | queue = []
32 |
33 | // 输出结果
34 | // 0
35 | // 1
36 | // 1.1
37 | // 2
38 | // 3
39 | // 3.1
40 | // 4
41 | // 5
42 | // 6
--------------------------------------------------------------------------------
/6.7 事件循环/3.js:
--------------------------------------------------------------------------------
1 | const p1 = new Promise((resolve) => {
2 | resolve()
3 | }).then(function f1() {
4 | console.log(1)
5 | const p2 = new Promise(resolve => {
6 | resolve()
7 | }).then(function f3() {
8 | console.log(2)
9 | }).then(function f4() {
10 | console.log(4)
11 | })
12 | }).then(function f2() {
13 | console.log(3)
14 | })
15 |
16 | console.log(0)
--------------------------------------------------------------------------------
/6.7 事件循环/4.js:
--------------------------------------------------------------------------------
1 | const p1 = new Promise((resolve) => {
2 | resolve()
3 | }).then(function f1() {
4 | console.log(1)
5 | const p2 = new Promise(resolve => {
6 | resolve()
7 | }).then(function f3() {
8 | console.log(2)
9 | }).then(function f4() {
10 | console.log(4)
11 | })
12 | }).then(function f2() {
13 | console.log(3)
14 | let index = 0
15 | const queue = [m1]
16 |
17 | function m1() {
18 | console.log('m1')
19 | if (index < 10) {
20 | queue.push(m2)
21 | }
22 | }
23 |
24 | function m2() {
25 | console.log('m2')
26 | index++;
27 | queue.push(m1)
28 | }
29 |
30 | let cb
31 | while(cb = queue.shift()) {
32 | cb()
33 | }
34 | })
35 |
36 | console.log(0)
--------------------------------------------------------------------------------
/6.7 事件循环/5.js:
--------------------------------------------------------------------------------
1 | const btn = document.querySelector('#button')
2 | btn.addEventListener('click', function() {
3 | new Promise(res => res()).then(() => {
4 | console.log(3)
5 | })
6 | console.log(1)
7 | }, false)
8 |
9 | btn.addEventListener('click', function () {
10 | new Promise(res => res()).then(() => {
11 | console.log(4)
12 | })
13 | console.log(2)
14 | }, false)
15 |
16 | // btn.click()
17 |
18 | requestIdleCallback((deadline) => {
19 | console.log(deadline)
20 | })
21 |
22 | requestAnimationFrame(() => {
23 | console.log('requestAnimationFrame')
24 | })
25 |
26 | console.log('empty callstack')
27 |
28 |
29 | // UI render
30 | // requestAnimationFrame
31 | // I/O
32 | // setTimeout
--------------------------------------------------------------------------------
/6.7 事件循环/6.js:
--------------------------------------------------------------------------------
1 | document.onclick = () => {
2 | console.log('s')
3 | setTimeout(() => {
4 | console.log(0)
5 | }, 0)
6 |
7 | setTimeout(() => {
8 | console.log(1)
9 | }, 1000)
10 |
11 | setTimeout(() => {
12 | console.log(2)
13 | }, 2000)
14 |
15 | for (var i = 0; i < 5000000000; i++);
16 | console.log('e')
17 | }
18 |
--------------------------------------------------------------------------------
/6.7 事件循环/7.js:
--------------------------------------------------------------------------------
1 | // demo01 出自于上面我引用文章的一个例子,我们来根据上面的结论,一步一步分析具体的执行过程。
2 | // 为了方便理解,我以打印出来的字符作为当前的任务名称
3 | setTimeout(function s1() {
4 | console.log(5);
5 | }, 1)
6 |
7 | setTimeout(function s2() {
8 | console.log(6);
9 | }, 0)
10 |
11 | new Promise(function (resolve) {
12 | console.log(1);
13 | for (var i = 0; i < 1000; i++) {
14 | i == 99 && resolve();
15 | }
16 | console.log(2);
17 | }).then(function p1() {
18 | console.log(4);
19 | })
20 |
21 | console.log(3);
22 |
--------------------------------------------------------------------------------
/6.7 事件循环/8.js:
--------------------------------------------------------------------------------
1 | // 用数组模拟一个队列
2 | var tasks = [];
3 |
4 | // 模拟一个事件分发器
5 | var addFn1 = function (task) {
6 | tasks.push(task);
7 | }
8 |
9 | // 执行所有的任务
10 | var flush = function () {
11 | tasks.map(function (task) {
12 | task();
13 | })
14 | }
15 |
16 | // 最后利用setTimeout/或者其他你认为合适的方式丢入事件循环中
17 | setTimeout(function () {
18 | flush();
19 | })
20 |
21 | // 当然,也可以不用丢进事件循环,而是我们自己手动在适当的时机去执行对应的某一个方法
22 | var dispatch = function (name) {
23 | tasks.map(function (item) {
24 | if (item.name == name) {
25 | item.handler();
26 | }
27 | })
28 | }
29 |
30 | // 当然,我们把任务丢进去的时候,多保存一个name即可。
31 | // 这时候,task的格式就如下
32 | demoTask = {
33 | name: 'demo',
34 | handler: function () { }
35 | }
36 |
37 | // 于是,一个订阅-通知的设计模式就这样轻松的被实现了
--------------------------------------------------------------------------------
/6.8 模块化/1.js:
--------------------------------------------------------------------------------
1 | // 自执行函数模拟模块化
2 |
3 | // Person 模块
4 | (() => {
5 | // 实例个数,模块内部变量,外部无法直接访问,
6 | let number = 0
7 | function Person(name, age) {
8 | number ++
9 | this.name = name
10 | this.age = age
11 | }
12 |
13 | Person.prototype.getName = function() {
14 | return this.name
15 | }
16 |
17 | Person.getInstanceNumber = function() {
18 | return number
19 | }
20 |
21 | // 对外抛出接口
22 | window.Person = Person
23 | })();
24 |
25 |
26 | // main 模块
27 | (() => {
28 | // 引入模块
29 | const Person = window.Person
30 |
31 | const p1 = new Person('Tom', 20)
32 | const p2 = new Person('Jake', 20)
33 | const p3 = new Person('Alex', 20)
34 |
35 | p1.getName()
36 |
37 | console.log('实例化个数', Person.getInstanceNumber())
38 | })()
--------------------------------------------------------------------------------
/6.8 模块化/2.js:
--------------------------------------------------------------------------------
1 | // CommonJS
2 |
3 | // person 模块
4 | // person.js
5 | let number = 0
6 | function Person(name, age) {
7 | number++
8 | this.name = name
9 | this.age = age
10 | }
11 |
12 | // 对外暴露接口
13 | Person.prototype.getName = function () {
14 | return this.name
15 | }
16 |
17 | // 对外暴露接口
18 | module.exports.getInstanceNumber = function () {
19 | return number
20 | }
21 | module.exports.Person = Person
22 |
23 | // ----------------
24 | // main.js
25 | // 引入模块
26 | const person = require('./person.js')
27 |
28 | const {Person, getInstanceNumber} = person
29 |
30 | const p1 = new Person('Tom', 20)
31 | const p2 = new Person('Jake', 20)
32 | const p3 = new Person('Alex', 20)
33 |
34 | p1.getName()
35 | p2.getName()
36 | p3.getName()
37 |
38 | console.log('实例化个数', getInstanceNumber())
39 |
--------------------------------------------------------------------------------
/6.8 模块化/3.js:
--------------------------------------------------------------------------------
1 | // AMD
2 |
3 | // person.js
4 | define(function() {
5 | let number = 0
6 | function Person(name, age) {
7 | number++
8 | this.name = name
9 | this.age = age
10 | }
11 |
12 | // 对外暴露接口
13 | Person.prototype.getName = function () {
14 | return this.name
15 | }
16 |
17 | function getInstanceNumber() {
18 | return number
19 | }
20 |
21 | // 对外暴露接口
22 | return {
23 | getInstanceNumber,
24 | Person
25 | }
26 | })
27 |
28 |
29 | // mian.js
30 |
31 | // main.js
32 | // 引入模块
33 | define(['./person.js'], function(person) {
34 | const { Person, getInstanceNumber } = person
35 |
36 | const p1 = new Person('Tom', 20)
37 | const p2 = new Person('Jake', 20)
38 | const p3 = new Person('Alex', 20)
39 |
40 | p1.getName()
41 | p2.getName()
42 | p3.getName()
43 |
44 | console.log('实例化个数', getInstanceNumber())
45 | })
46 |
--------------------------------------------------------------------------------
/6.8 模块化/4.js:
--------------------------------------------------------------------------------
1 | // person.js
2 | define(function(require, exports, module) {
3 | let number = 0
4 | function Person(name, age) {
5 | number++
6 | this.name = name
7 | this.age = age
8 | }
9 |
10 | // 对外暴露接口
11 | Person.prototype.getName = function () {
12 | return this.name
13 | }
14 |
15 | // 对外暴露接口
16 | module.exports.getInstanceNumber = function () {
17 | return number
18 | }
19 | module.exports.Person = Person
20 | })
21 |
22 |
23 | // mian.js
24 | define(function(require) {
25 | const person = require('./person.js')
26 | const { Person, getInstanceNumber } = person
27 |
28 | const p1 = new Person('Tom', 20)
29 | const p2 = new Person('Jake', 20)
30 | const p3 = new Person('Alex', 20)
31 |
32 | p1.getName()
33 | p2.getName()
34 | p3.getName()
35 |
36 | console.log('实例化个数', getInstanceNumber())
37 |
38 | })
--------------------------------------------------------------------------------
/6.8 模块化/5.js:
--------------------------------------------------------------------------------
1 | (function(root, factory) {
2 | if (typeof define === 'function' && define.amd) { // AMD
3 | define(['person'], factory)
4 | } else if (typeof define === 'function' && define.cmd) { // CMD
5 | define(function(require, exports, module) {
6 | module.exports = factory()
7 | })
8 | } else if (typeof exports === 'object') { // CommonJS
9 | module.exports = factory()
10 | } else { // global
11 | root.person = factory()
12 | }
13 | })(this, function() {
14 | let number = 0
15 | function Person(name, age) {
16 | number++
17 | this.name = name
18 | this.age = age
19 | }
20 |
21 | // 对外暴露接口
22 | Person.prototype.getName = function () {
23 | return this.name
24 | }
25 |
26 | function getInstanceNumber () {
27 | return number
28 | }
29 |
30 | return {
31 | Person,
32 | getInstanceNumber
33 | }
34 | })
35 |
--------------------------------------------------------------------------------
/6.8 模块化/6.js:
--------------------------------------------------------------------------------
1 | // CommonJS
2 |
3 | // person 模块
4 | // person.js
5 | let number = 0
6 | export function Person(name, age) { // 暴露接口
7 | number++
8 | this.name = name
9 | this.age = age
10 | }
11 |
12 | // 对外暴露接口
13 | Person.prototype.getName = function () {
14 | return this.name
15 | }
16 |
17 | // 对外暴露接口
18 | export const getInstanceNumber = function () {
19 | return number
20 | }
21 |
22 | // ----------------
23 | // main.js
24 | // 引入模块
25 | import {Person, getInstanceNumber} from './person.js'
26 |
27 | const p1 = new Person('Tom', 20)
28 | const p2 = new Person('Jake', 20)
29 | const p3 = new Person('Alex', 20)
30 |
31 | p1.getName()
32 | p2.getName()
33 | p3.getName()
34 |
35 | console.log('实例化个数', getInstanceNumber())
36 |
--------------------------------------------------------------------------------
/6.8 模块化/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/6.8.1 模块化语法/my-app/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/6.8.1 模块化语法/my-app/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangbo5207/jsCore/4d6aae959f9ff22d3ba84a0845b662fc8c85572f/6.8.1 模块化语法/my-app/public/favicon.ico
--------------------------------------------------------------------------------
/6.8.1 模块化语法/my-app/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangbo5207/jsCore/4d6aae959f9ff22d3ba84a0845b662fc8c85572f/6.8.1 模块化语法/my-app/public/logo192.png
--------------------------------------------------------------------------------
/6.8.1 模块化语法/my-app/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangbo5207/jsCore/4d6aae959f9ff22d3ba84a0845b662fc8c85572f/6.8.1 模块化语法/my-app/public/logo512.png
--------------------------------------------------------------------------------
/6.8.1 模块化语法/my-app/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/6.8.1 模块化语法/my-app/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/6.8.1 模块化语法/my-app/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/6.8.1 模块化语法/my-app/src/App.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render, screen } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | render();
7 | const linkElement = screen.getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/6.8.1 模块化语法/my-app/src/App.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import logo from './logo.svg';
3 | import './App.css';
4 |
5 | function App() {
6 | return (
7 |
23 | );
24 | }
25 |
26 | export default App;
27 |
--------------------------------------------------------------------------------
/6.8.1 模块化语法/my-app/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/6.8.1 模块化语法/my-app/src/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import reportWebVitals from './reportWebVitals';
6 |
7 | import Person from './person'
8 | import Person2, {fn, bar} from './person2'
9 |
10 | ReactDOM.render(
11 |
12 |
13 | ,
14 | document.getElementById('root')
15 | );
16 |
17 | // If you want to start measuring performance in your app, pass a function
18 | // to log results (for example: reportWebVitals(console.log))
19 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
20 | reportWebVitals();
21 |
22 |
23 | const p1 = new Person('TOM', 20)
24 | console.log(p1.getName())
25 |
26 |
--------------------------------------------------------------------------------
/6.8.1 模块化语法/my-app/src/person.ts:
--------------------------------------------------------------------------------
1 | class Person {
2 | private name: string
3 | private age: number
4 |
5 | constructor(name: string, age: number) {
6 | this.name = name
7 | this.age = age
8 | }
9 | getName() {
10 | return this.name
11 | }
12 | }
13 |
14 | export default Person
--------------------------------------------------------------------------------
/6.8.1 模块化语法/my-app/src/person2.ts:
--------------------------------------------------------------------------------
1 | export function fn() {
2 | console.log('this is a function named fn.');
3 | }
4 |
5 | export function bar() {
6 | console.log('hello everybody.');
7 | }
8 |
9 | class Person {
10 | private name: string
11 | private age: number
12 |
13 | constructor(name: string, age: number) {
14 | this.name = name;
15 | this.age = age;
16 | }
17 | getName() {
18 | return this.name
19 | }
20 | }
21 |
22 | export default Person;
--------------------------------------------------------------------------------
/6.8.1 模块化语法/my-app/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/6.8.1 模块化语法/my-app/src/reportWebVitals.ts:
--------------------------------------------------------------------------------
1 | import { ReportHandler } from 'web-vitals';
2 |
3 | const reportWebVitals = (onPerfEntry?: ReportHandler) => {
4 | if (onPerfEntry && onPerfEntry instanceof Function) {
5 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
6 | getCLS(onPerfEntry);
7 | getFID(onPerfEntry);
8 | getFCP(onPerfEntry);
9 | getLCP(onPerfEntry);
10 | getTTFB(onPerfEntry);
11 | });
12 | }
13 | };
14 |
15 | export default reportWebVitals;
16 |
--------------------------------------------------------------------------------
/6.8.1 模块化语法/my-app/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/6.8.1 模块化语法/my-app/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "dom",
6 | "dom.iterable",
7 | "esnext"
8 | ],
9 | "allowJs": true,
10 | "skipLibCheck": true,
11 | "esModuleInterop": true,
12 | "allowSyntheticDefaultImports": true,
13 | "strict": true,
14 | "forceConsistentCasingInFileNames": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "module": "esnext",
17 | "moduleResolution": "node",
18 | "resolveJsonModule": true,
19 | "isolatedModules": true,
20 | "noEmit": true,
21 | "jsx": "react-jsx"
22 | },
23 | "include": [
24 | "src"
25 | ]
26 | }
27 |
--------------------------------------------------------------------------------
/6.9模块化开发实例/controldiv/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/6.9模块化开发实例/controldiv/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangbo5207/jsCore/4d6aae959f9ff22d3ba84a0845b662fc8c85572f/6.9模块化开发实例/controldiv/public/favicon.ico
--------------------------------------------------------------------------------
/6.9模块化开发实例/controldiv/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangbo5207/jsCore/4d6aae959f9ff22d3ba84a0845b662fc8c85572f/6.9模块化开发实例/controldiv/public/logo192.png
--------------------------------------------------------------------------------
/6.9模块化开发实例/controldiv/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangbo5207/jsCore/4d6aae959f9ff22d3ba84a0845b662fc8c85572f/6.9模块化开发实例/controldiv/public/logo512.png
--------------------------------------------------------------------------------
/6.9模块化开发实例/controldiv/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/6.9模块化开发实例/controldiv/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/6.9模块化开发实例/controldiv/src/App.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render, screen } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | render();
7 | const linkElement = screen.getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/6.9模块化开发实例/controldiv/src/App.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | function App() {
3 | return (
4 |
5 | );
6 | }
7 |
8 | export default App;
9 |
--------------------------------------------------------------------------------
/6.9模块化开发实例/controldiv/src/controlButtons/bgColor.ts:
--------------------------------------------------------------------------------
1 | import { setState } from '../state';
2 |
3 | const input = document.querySelector('.bgcolor_input');
4 | const btn = document.querySelector('.bgcolor_btn');
5 |
6 | if (!input || !btn) {
7 | throw new Error('元素对象不存在')
8 | }
9 |
10 | btn.addEventListener('click', () => {
11 | if (input.value) {
12 | setState('backgroundColor', input.value);
13 | }
14 | }, false);
--------------------------------------------------------------------------------
/6.9模块化开发实例/controldiv/src/controlButtons/borderColor.ts:
--------------------------------------------------------------------------------
1 | import { setState } from '../state';
2 |
3 | const input = document.querySelector('.bdcolor_input');
4 | const btn = document.querySelector('.bdcolor_btn');
5 |
6 | if (!input || !btn) {
7 | throw new Error('元素对象不存在')
8 | }
9 |
10 |
11 | btn.addEventListener('click', () => {
12 | if (input.value) {
13 | setState('borderColor', input.value);
14 | }
15 | }, false);
--------------------------------------------------------------------------------
/6.9模块化开发实例/controldiv/src/controlButtons/height.ts:
--------------------------------------------------------------------------------
1 | import { getState, setState } from '../state';
2 |
3 | const red_btn = document.querySelector('.height_reduce');
4 | const add_btn = document.querySelector('.height_add');
5 | const height_input = document.querySelector('.height_input');
6 |
7 | if (!red_btn || !add_btn || !height_input) {
8 | throw new Error('元素对象不存在')
9 | }
10 |
11 | height_input.value = getState('height') || 200;
12 |
13 | red_btn.addEventListener('click', () => {
14 | const cur = getState('height');
15 | if (cur > 50) {
16 | setState('height', cur - 5);
17 | height_input.value = cur - 5 + '';
18 | }
19 | }, false)
20 |
21 | add_btn.addEventListener('click', () => {
22 | const cur = getState('height');
23 | if (cur < 400) {
24 | setState('height', cur + 5);
25 | height_input.value = cur + 5;
26 | }
27 | }, false)
--------------------------------------------------------------------------------
/6.9模块化开发实例/controldiv/src/controlButtons/index.ts:
--------------------------------------------------------------------------------
1 | import './show';
2 | import './bgColor';
3 | import './borderColor';
4 | import './width';
5 | import './height';
--------------------------------------------------------------------------------
/6.9模块化开发实例/controldiv/src/controlButtons/show.ts:
--------------------------------------------------------------------------------
1 | import { getState, setState } from '../state';
2 |
3 | const btn = document.querySelector('.show');
4 |
5 | if (!btn) {
6 | throw new Error('元素对象不存在')
7 | }
8 |
9 | btn.addEventListener('click', () => {
10 | setState('show', !getState('show'))
11 | }, false);
--------------------------------------------------------------------------------
/6.9模块化开发实例/controldiv/src/controlButtons/width.ts:
--------------------------------------------------------------------------------
1 | import { getState, setState } from '../state';
2 |
3 | const red_btn = document.querySelector('.width_reduce');
4 | const add_btn = document.querySelector('.width_add');
5 |
6 | if (!red_btn || !add_btn) {
7 | throw new Error('元素对象不存在')
8 | }
9 |
10 | red_btn.addEventListener('click', () => {
11 | const cur = getState('width');
12 | if (cur > 50) {
13 | setState('width', cur - 5);
14 | }
15 | }, false)
16 |
17 | add_btn.addEventListener('click', () => {
18 | const cur = getState('width');
19 | if (cur < 400) {
20 | setState('width', cur + 5);
21 | }
22 | }, false)
--------------------------------------------------------------------------------
/6.9模块化开发实例/controldiv/src/index.css:
--------------------------------------------------------------------------------
1 | #control .target {
2 | width: 200px;
3 | height: 200px;
4 | background-color: #cccccc;
5 | transition: 0.3s;
6 | }
7 | #control .target.hide {
8 | display: none;
9 | }
--------------------------------------------------------------------------------
/6.9模块化开发实例/controldiv/src/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 | import './index.css';
5 | import './box'
6 | import './controlButtons'
7 |
8 | ReactDOM.render(
9 |
10 |
11 | ,
12 | document.getElementById('root')
13 | );
14 |
--------------------------------------------------------------------------------
/6.9模块化开发实例/controldiv/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/6.9模块化开发实例/controldiv/src/register.ts:
--------------------------------------------------------------------------------
1 | import {registerState} from './state'
2 |
3 | registerState('show', true)
4 | registerState('backgroundColor', '#cccccc')
5 | registerState('borderColor', '#000')
6 | registerState('width', 200)
7 | registerState('height', 200)
--------------------------------------------------------------------------------
/6.9模块化开发实例/controldiv/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/6.9模块化开发实例/controldiv/src/utils.ts:
--------------------------------------------------------------------------------
1 | export const getStyle = (ele: Element, key: any) => {
2 | if (window.getComputedStyle) {
3 | return window.getComputedStyle(ele, null)[key]
4 | }
5 | // @ts-ignore for IE
6 | return ele.currentStyle[key]
7 | }
--------------------------------------------------------------------------------
/6.9模块化开发实例/controldiv/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "dom",
6 | "dom.iterable",
7 | "esnext"
8 | ],
9 | "allowJs": true,
10 | "skipLibCheck": true,
11 | "esModuleInterop": true,
12 | "allowSyntheticDefaultImports": true,
13 | "strict": true,
14 | "forceConsistentCasingInFileNames": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "module": "esnext",
17 | "moduleResolution": "node",
18 | "resolveJsonModule": true,
19 | "isolatedModules": true,
20 | "noEmit": true,
21 | "jsx": "react-jsx"
22 | },
23 | "include": [
24 | "src"
25 | ]
26 | }
27 |
--------------------------------------------------------------------------------
/6.9模块化开发实例/zhihunew/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/6.9模块化开发实例/zhihunew/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangbo5207/jsCore/4d6aae959f9ff22d3ba84a0845b662fc8c85572f/6.9模块化开发实例/zhihunew/public/favicon.ico
--------------------------------------------------------------------------------
/6.9模块化开发实例/zhihunew/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangbo5207/jsCore/4d6aae959f9ff22d3ba84a0845b662fc8c85572f/6.9模块化开发实例/zhihunew/public/logo192.png
--------------------------------------------------------------------------------
/6.9模块化开发实例/zhihunew/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangbo5207/jsCore/4d6aae959f9ff22d3ba84a0845b662fc8c85572f/6.9模块化开发实例/zhihunew/public/logo512.png
--------------------------------------------------------------------------------
/6.9模块化开发实例/zhihunew/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/6.9模块化开发实例/zhihunew/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/6.9模块化开发实例/zhihunew/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/6.9模块化开发实例/zhihunew/src/App.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render, screen } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | render();
7 | const linkElement = screen.getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/6.9模块化开发实例/zhihunew/src/App.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import './App.css';
3 |
4 | function App() {
5 | return (
6 |
7 | );
8 | }
9 |
10 | export default App;
11 |
--------------------------------------------------------------------------------
/6.9模块化开发实例/zhihunew/src/api.ts:
--------------------------------------------------------------------------------
1 | import {get} from './request'
2 | import news, {Newspaper} from './data'
3 |
4 |
5 |
6 | export function newsApi() {
7 | // 本来应该如此请求接口,但是由于跨域限制,因此我们这里模拟该接口的行为返回数据 mock
8 | // return get('https://news-at.zhihu.com/api/4/news/latest')
9 | return new Promise((resolve) => {
10 | setTimeout(() => {
11 | resolve(news)
12 | }, 1000)
13 | })
14 | }
15 |
16 | export function other1Api(url: string) {}
17 |
18 | export function other2Api(url: string) {}
19 |
20 | export function other3Api(url: string) {}
21 |
22 | // 实践中可能还会有更多 api 请求
--------------------------------------------------------------------------------
/6.9模块化开发实例/zhihunew/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/6.9模块化开发实例/zhihunew/src/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import reportWebVitals from './reportWebVitals';
6 | import './render'
7 |
8 | ReactDOM.render(
9 |
10 |
11 | ,
12 | document.getElementById('root')
13 | );
14 |
15 | // If you want to start measuring performance in your app, pass a function
16 | // to log results (for example: reportWebVitals(console.log))
17 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
18 | reportWebVitals();
19 |
--------------------------------------------------------------------------------
/6.9模块化开发实例/zhihunew/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/6.9模块化开发实例/zhihunew/src/render.ts:
--------------------------------------------------------------------------------
1 | import {newsApi} from './api'
2 |
3 | const news = document.querySelector('#news')
4 |
5 | if (!news) {
6 | throw new Error('容器元素不存在')
7 | }
8 |
9 | // 初始值
10 | news.innerHTML = '数据加载中...'
11 |
12 | newsApi().then(res => {
13 | const top = `
14 |
22 | `
23 |
24 | const list = `
25 |
33 | `
34 | news.innerHTML = `${top}${list}`
35 | })
36 |
--------------------------------------------------------------------------------
/6.9模块化开发实例/zhihunew/src/reportWebVitals.ts:
--------------------------------------------------------------------------------
1 | import { ReportHandler } from 'web-vitals';
2 |
3 | const reportWebVitals = (onPerfEntry?: ReportHandler) => {
4 | if (onPerfEntry && onPerfEntry instanceof Function) {
5 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
6 | getCLS(onPerfEntry);
7 | getFID(onPerfEntry);
8 | getFCP(onPerfEntry);
9 | getLCP(onPerfEntry);
10 | getTTFB(onPerfEntry);
11 | });
12 | }
13 | };
14 |
15 | export default reportWebVitals;
16 |
--------------------------------------------------------------------------------
/6.9模块化开发实例/zhihunew/src/request.ts:
--------------------------------------------------------------------------------
1 | // 简易版,未考虑参数情况,请勿运用于实践
2 | export function get(url: string): Promise {
3 | return new Promise((resolve, reject) => {
4 | const XHR = new XMLHttpRequest()
5 | XHR.open('GET', url, true)
6 | XHR.send()
7 |
8 | XHR.onreadystatechange = () => {
9 | if (XHR.readyState == 4) {
10 | if (XHR.status == 200) {
11 | try {
12 | resolve(JSON.parse(XHR.responseText))
13 | } catch(e) {
14 | reject(e)
15 | }
16 | } else {
17 | reject(new Error(XHR.statusText))
18 | }
19 | }
20 | }
21 | })
22 | }
--------------------------------------------------------------------------------
/6.9模块化开发实例/zhihunew/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/6.9模块化开发实例/zhihunew/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "dom",
6 | "dom.iterable",
7 | "esnext"
8 | ],
9 | "allowJs": true,
10 | "skipLibCheck": true,
11 | "esModuleInterop": true,
12 | "allowSyntheticDefaultImports": true,
13 | "strict": true,
14 | "forceConsistentCasingInFileNames": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "module": "esnext",
17 | "moduleResolution": "node",
18 | "resolveJsonModule": true,
19 | "isolatedModules": true,
20 | "noEmit": true,
21 | "jsx": "react-jsx"
22 | },
23 | "include": [
24 | "src"
25 | ]
26 | }
27 |
--------------------------------------------------------------------------------
/7.1组件化/tab/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/7.1组件化/tab/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangbo5207/jsCore/4d6aae959f9ff22d3ba84a0845b662fc8c85572f/7.1组件化/tab/public/favicon.ico
--------------------------------------------------------------------------------
/7.1组件化/tab/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangbo5207/jsCore/4d6aae959f9ff22d3ba84a0845b662fc8c85572f/7.1组件化/tab/public/logo192.png
--------------------------------------------------------------------------------
/7.1组件化/tab/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangbo5207/jsCore/4d6aae959f9ff22d3ba84a0845b662fc8c85572f/7.1组件化/tab/public/logo512.png
--------------------------------------------------------------------------------
/7.1组件化/tab/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/7.1组件化/tab/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/7.1组件化/tab/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/7.1组件化/tab/src/App.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render, screen } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | render();
7 | const linkElement = screen.getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/7.1组件化/tab/src/App.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import './App.css';
3 |
4 | import Tabbar from './Tabbar'
5 |
6 | function App() {
7 | return (
8 |
12 | );
13 | }
14 |
15 | export default App;
16 |
--------------------------------------------------------------------------------
/7.1组件化/tab/src/Tabbar/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | }
4 |
5 | html, body {
6 | height: 100%;
7 | }
8 |
9 | .tab_container {
10 | width: 300px;
11 | margin: 20px auto;
12 | border: 1px solid #CCC;
13 | height: 400px;
14 | }
15 |
16 | .titles {
17 | display: flex;
18 | height: 44px;
19 | border-bottom: 1px solid #CCC;
20 | }
21 |
22 | .titles .item {
23 | flex: 1;
24 | height: 100%;
25 | text-align: center;
26 | line-height: 44px;
27 | font-size: 12px;
28 | }
29 |
30 | .titles .item.active {
31 | background-color: orange;
32 | color: #FFF;
33 | }
34 |
35 | .contents {
36 | position: relative;
37 | height: 100%;
38 | }
39 |
40 | .contents .item {
41 | position: absolute;
42 | top: 0;
43 | left: 0;
44 | bottom: 0;
45 | right: 0;
46 | display: none;
47 | align-items: center;
48 | justify-content: center;
49 | }
50 |
51 | .contents .item.active {
52 | display: flex;
53 | }
--------------------------------------------------------------------------------
/7.1组件化/tab/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/7.1组件化/tab/src/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import reportWebVitals from './reportWebVitals';
6 |
7 | import './tab'
8 | import './tab.css'
9 |
10 | ReactDOM.render(
11 |
12 |
13 | ,
14 | document.getElementById('root')
15 | );
16 |
17 | // If you want to start measuring performance in your app, pass a function
18 | // to log results (for example: reportWebVitals(console.log))
19 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
20 | reportWebVitals();
21 |
--------------------------------------------------------------------------------
/7.1组件化/tab/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/7.1组件化/tab/src/reportWebVitals.ts:
--------------------------------------------------------------------------------
1 | import { ReportHandler } from 'web-vitals';
2 |
3 | const reportWebVitals = (onPerfEntry?: ReportHandler) => {
4 | if (onPerfEntry && onPerfEntry instanceof Function) {
5 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
6 | getCLS(onPerfEntry);
7 | getFID(onPerfEntry);
8 | getFCP(onPerfEntry);
9 | getLCP(onPerfEntry);
10 | getTTFB(onPerfEntry);
11 | });
12 | }
13 | };
14 |
15 | export default reportWebVitals;
16 |
--------------------------------------------------------------------------------
/7.1组件化/tab/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/7.1组件化/tab/src/tab.css:
--------------------------------------------------------------------------------
1 |
2 | body {
3 | margin: 0;
4 | }
5 |
6 | html, body {
7 | height: 100%;
8 | }
9 |
10 | #tab-root {
11 | width: 300px;
12 | margin: 20px auto;
13 | border: 1px solid #CCC;
14 | height: 400px;
15 | }
16 |
17 | .titles {
18 | display: flex;
19 | height: 44px;
20 | border-bottom: 1px solid #CCC;
21 | }
22 |
23 | .titles .item {
24 | flex: 1;
25 | height: 100%;
26 | text-align: center;
27 | line-height: 44px;
28 | font-size: 12px;
29 | }
30 |
31 | .titles .item.active {
32 | background-color: orange;
33 | color: #FFF;
34 | }
35 |
36 | .contents {
37 | position: relative;
38 | height: 100%;
39 | }
40 |
41 | .contents .item {
42 | position: absolute;
43 | top: 0;
44 | left: 0;
45 | bottom: 0;
46 | right: 0;
47 | display: none;
48 | align-items: center;
49 | justify-content: center;
50 | }
51 |
52 | .contents .item.active {
53 | display: flex;
54 | }
--------------------------------------------------------------------------------
/7.1组件化/tab/src/tab.ts:
--------------------------------------------------------------------------------
1 | const titles = document.querySelector('.titles');
2 | const contents = document.querySelector('.contents');
3 |
4 | if (!titles || !contents) {
5 | throw new Error('element not exist.')
6 | }
7 |
8 | let index = 0;
9 |
10 | titles.onclick = (event) => {
11 | const activeTitle = event.target as HTMLElement;
12 |
13 | if (!activeTitle) {
14 | return;
15 | }
16 |
17 | const aindex = Number(activeTitle.dataset.index);
18 |
19 | if (aindex !== index) {
20 | titles.children[index].classList.remove('active');
21 | contents.children[index].classList.remove('active');
22 |
23 | activeTitle.classList.add('active');
24 | contents.children[aindex].classList.add('active');
25 | index = aindex;
26 | }
27 | }
28 |
29 | export default {}
--------------------------------------------------------------------------------
/7.1组件化/tab/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "dom",
6 | "dom.iterable",
7 | "esnext"
8 | ],
9 | "allowJs": true,
10 | "skipLibCheck": true,
11 | "esModuleInterop": true,
12 | "allowSyntheticDefaultImports": true,
13 | "strict": true,
14 | "forceConsistentCasingInFileNames": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "module": "esnext",
17 | "moduleResolution": "node",
18 | "resolveJsonModule": true,
19 | "isolatedModules": true,
20 | "noEmit": true,
21 | "jsx": "react-jsx"
22 | },
23 | "include": [
24 | "src"
25 | ]
26 | }
27 |
--------------------------------------------------------------------------------
/7.2webpack/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/7.2webpack/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | webpack 起步
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/7.2webpack/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "7.2webpack",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "start": "webpack serve --open",
9 | "build": "webpack --config webpack.config.js"
10 | },
11 | "keywords": [],
12 | "author": "",
13 | "license": "ISC",
14 | "devDependencies": {
15 | "clean-webpack-plugin": "^3.0.0",
16 | "css-loader": "^5.0.1",
17 | "html-webpack-plugin": "^4.5.1",
18 | "node-sass": "^5.0.0",
19 | "sass-loader": "^10.1.1",
20 | "style-loader": "^2.0.0",
21 | "webpack": "^5.15.0",
22 | "webpack-cli": "^4.3.1",
23 | "webpack-dev-server": "^3.11.2"
24 | },
25 | "dependencies": {
26 | "lodash": "^4.17.20"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/7.2webpack/src/inbox.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangbo5207/jsCore/4d6aae959f9ff22d3ba84a0845b662fc8c85572f/7.2webpack/src/inbox.jpg
--------------------------------------------------------------------------------
/7.2webpack/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | background-color: orange;
3 | color: #FFF;
4 | }
--------------------------------------------------------------------------------
/7.2webpack/src/index.js:
--------------------------------------------------------------------------------
1 | import _ from 'lodash'
2 | import './index.css'
3 | import './test.scss'
4 | import Inbox from './inbox.jpg'
5 |
6 | function component() {
7 | const element = document.createElement('div');
8 | element.innerHTML = _.join(['Hello', 'webpack'], ' ');
9 |
10 | const img = new Image()
11 | img.src = Inbox
12 | element.appendChild(img)
13 |
14 | return element;
15 | }
16 |
17 | document.body.appendChild(component());
--------------------------------------------------------------------------------
/7.2webpack/src/test.scss:
--------------------------------------------------------------------------------
1 | body {
2 | font-size: 50px;
3 | }
--------------------------------------------------------------------------------
/7.3React/controldiv/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/7.3React/controldiv/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangbo5207/jsCore/4d6aae959f9ff22d3ba84a0845b662fc8c85572f/7.3React/controldiv/public/favicon.ico
--------------------------------------------------------------------------------
/7.3React/controldiv/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangbo5207/jsCore/4d6aae959f9ff22d3ba84a0845b662fc8c85572f/7.3React/controldiv/public/logo192.png
--------------------------------------------------------------------------------
/7.3React/controldiv/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangbo5207/jsCore/4d6aae959f9ff22d3ba84a0845b662fc8c85572f/7.3React/controldiv/public/logo512.png
--------------------------------------------------------------------------------
/7.3React/controldiv/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/7.3React/controldiv/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/7.3React/controldiv/src/App.css:
--------------------------------------------------------------------------------
1 | #control {
2 | width: 500px;
3 | margin: 100px auto;
4 | }
5 |
6 | #control .target {
7 | width: 200px;
8 | height: 200px;
9 | border: 2px solid #FFF;
10 | background-color: #cccccc;
11 | transition: 0.3s;
12 | }
13 | #control .target.hide {
14 | display: none;
15 | }
--------------------------------------------------------------------------------
/7.3React/controldiv/src/App.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render, screen } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | render();
7 | const linkElement = screen.getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/7.3React/controldiv/src/components/Toast/Item.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useRef } from 'react';
2 | import "./item.css";
3 |
4 | export interface ToastProps {
5 | id: string,
6 | duration: number,
7 | onClose?: (id: string, isShowMask: boolean) => any,
8 | isShowMask: boolean,
9 | text: string,
10 | type: 'info' | 'warning' | 'danger'
11 | }
12 |
13 | export default function ToastItem(props: ToastProps) {
14 | const {id, duration, onClose, isShowMask, text} = props
15 | const tiemr = useRef()
16 | tiemr.current = setTimeout(() => {
17 | onClose && onClose(id, isShowMask)
18 | }, duration)
19 |
20 | useEffect(() => {
21 | return () => {
22 | // @ts-ignore
23 | clearTimeout(tiemr.current)
24 | }
25 | }, [])
26 |
27 | return (
28 | {text}
29 | )
30 | }
--------------------------------------------------------------------------------
/7.3React/controldiv/src/components/Toast/container.css:
--------------------------------------------------------------------------------
1 |
2 | .toast-container {
3 | margin: 0;
4 | padding: 0;
5 | }
6 |
7 | .mask {
8 | position: fixed;
9 | left: 0;
10 | right: 0;
11 | top: 0;
12 | bottom: 0;
13 | background: rgba(0, 0, 0, 0.1);
14 | z-index: 100;
15 | }
16 |
17 | .toast-wrap {
18 | position: fixed;
19 | left: 50%;
20 | top: 30%;
21 | transform: translateX(-50%);
22 | z-index: 200;
23 | }
--------------------------------------------------------------------------------
/7.3React/controldiv/src/components/Toast/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import Container from './Container';
4 |
5 | const toastContainerDiv = document.createElement('div');
6 | document.body.appendChild(toastContainerDiv);
7 |
8 | // 这里返回的是 ToastContainer 组件引用
9 | const getToastContainerRef = () => {
10 | return ReactDOM.render(, toastContainerDiv);
11 | }
12 |
13 | // 获取 container 实例
14 | let containerRef = getToastContainerRef();
15 |
16 | const destroy = () => {
17 | ReactDOM.unmountComponentAtNode(toastContainerDiv);
18 | containerRef = getToastContainerRef();
19 | }
20 |
21 | export default {
22 | // @ts-ignore
23 | info: (text, duration, isShowMask) => (containerRef.push({ type: 'info', text, duration, isShowMask })),
24 | hide: destroy
25 | };
--------------------------------------------------------------------------------
/7.3React/controldiv/src/components/Toast/item.css:
--------------------------------------------------------------------------------
1 | .toast-item {
2 | padding: 5px 8px;
3 | background: rgba(0, 0, 0, 0.7);
4 | color: #fff;
5 | border-radius: 3px;
6 | margin-top: 10px;
7 | }
--------------------------------------------------------------------------------
/7.3React/controldiv/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
--------------------------------------------------------------------------------
/7.3React/controldiv/src/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import reportWebVitals from './reportWebVitals';
6 |
7 | ReactDOM.render(
8 |
9 |
10 | ,
11 | document.getElementById('root')
12 | );
13 |
14 | // If you want to start measuring performance in your app, pass a function
15 | // to log results (for example: reportWebVitals(console.log))
16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
17 | reportWebVitals();
18 |
--------------------------------------------------------------------------------
/7.3React/controldiv/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/7.3React/controldiv/src/reportWebVitals.ts:
--------------------------------------------------------------------------------
1 | import { ReportHandler } from 'web-vitals';
2 |
3 | const reportWebVitals = (onPerfEntry?: ReportHandler) => {
4 | if (onPerfEntry && onPerfEntry instanceof Function) {
5 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
6 | getCLS(onPerfEntry);
7 | getFID(onPerfEntry);
8 | getFCP(onPerfEntry);
9 | getLCP(onPerfEntry);
10 | getTTFB(onPerfEntry);
11 | });
12 | }
13 | };
14 |
15 | export default reportWebVitals;
16 |
--------------------------------------------------------------------------------
/7.3React/controldiv/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/7.3React/controldiv/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "dom",
6 | "dom.iterable",
7 | "esnext"
8 | ],
9 | "allowJs": true,
10 | "skipLibCheck": true,
11 | "esModuleInterop": true,
12 | "allowSyntheticDefaultImports": true,
13 | "strict": true,
14 | "forceConsistentCasingInFileNames": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "module": "esnext",
17 | "moduleResolution": "node",
18 | "resolveJsonModule": true,
19 | "isolatedModules": true,
20 | "noEmit": true,
21 | "jsx": "preserve",
22 | },
23 | "include": [
24 | "src"
25 | ]
26 | }
27 |
--------------------------------------------------------------------------------
/7.4admin/.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
--------------------------------------------------------------------------------
/7.4admin/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 |
--------------------------------------------------------------------------------
/7.4admin/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 |
--------------------------------------------------------------------------------
/7.4admin/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;"]
--------------------------------------------------------------------------------
/7.4admin/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 |
--------------------------------------------------------------------------------
/7.4admin/config/defaultSettings.ts:
--------------------------------------------------------------------------------
1 | import { Settings as ProSettings } from '@ant-design/pro-layout';
2 |
3 | type DefaultSettings = Partial & {
4 | pwa: boolean;
5 | };
6 |
7 | const proSettings: DefaultSettings = {
8 | navTheme: 'dark',
9 | // 拂晓蓝
10 | primaryColor: '#1890ff',
11 | layout: 'side',
12 | contentWidth: 'Fluid',
13 | fixedHeader: false,
14 | fixSiderbar: true,
15 | colorWeak: false,
16 | title: 'Ant Design Pro',
17 | pwa: false,
18 | iconfontUrl: '',
19 | };
20 |
21 | export type { DefaultSettings };
22 |
23 | export default proSettings;
24 |
--------------------------------------------------------------------------------
/7.4admin/config/proxy.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * 在生产环境 代理是无法生效的,所以这里没有生产环境的配置
3 | * The agent cannot take effect in the production environment
4 | * so there is no configuration of the production environment
5 | * For details, please see
6 | * https://pro.ant.design/docs/deploy
7 | */
8 | export default {
9 | dev: {
10 | '/api/': {
11 | target: 'https://preview.pro.ant.design',
12 | changeOrigin: true,
13 | pathRewrite: { '^': '' },
14 | },
15 | },
16 | test: {
17 | '/api/': {
18 | target: 'https://preview.pro.ant.design',
19 | changeOrigin: true,
20 | pathRewrite: { '^': '' },
21 | },
22 | },
23 | pre: {
24 | '/api/': {
25 | target: 'your pre url',
26 | changeOrigin: true,
27 | pathRewrite: { '^': '' },
28 | },
29 | },
30 | };
31 |
--------------------------------------------------------------------------------
/7.4admin/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 |
--------------------------------------------------------------------------------
/7.4admin/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 |
--------------------------------------------------------------------------------
/7.4admin/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 |
--------------------------------------------------------------------------------
/7.4admin/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | testURL: 'http://localhost:8000',
3 | testEnvironment: './tests/PuppeteerEnvironment',
4 | verbose: false,
5 | globals: {
6 | ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION: false,
7 | localStorage: null,
8 | },
9 | };
10 |
--------------------------------------------------------------------------------
/7.4admin/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "emitDecoratorMetadata": true,
4 | "experimentalDecorators": true,
5 | "baseUrl": ".",
6 | "paths": {
7 | "@/*": ["./src/*"]
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/7.4admin/mock/route.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | '/api/auth_routes': {
3 | '/form/advanced-form': { authority: ['admin', 'user'] },
4 | },
5 | };
6 |
--------------------------------------------------------------------------------
/7.4admin/public/CNAME:
--------------------------------------------------------------------------------
1 | preview.pro.ant.design
--------------------------------------------------------------------------------
/7.4admin/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangbo5207/jsCore/4d6aae959f9ff22d3ba84a0845b662fc8c85572f/7.4admin/public/favicon.ico
--------------------------------------------------------------------------------
/7.4admin/public/home_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangbo5207/jsCore/4d6aae959f9ff22d3ba84a0845b662fc8c85572f/7.4admin/public/home_bg.png
--------------------------------------------------------------------------------
/7.4admin/public/icons/icon-128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangbo5207/jsCore/4d6aae959f9ff22d3ba84a0845b662fc8c85572f/7.4admin/public/icons/icon-128x128.png
--------------------------------------------------------------------------------
/7.4admin/public/icons/icon-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangbo5207/jsCore/4d6aae959f9ff22d3ba84a0845b662fc8c85572f/7.4admin/public/icons/icon-192x192.png
--------------------------------------------------------------------------------
/7.4admin/public/icons/icon-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangbo5207/jsCore/4d6aae959f9ff22d3ba84a0845b662fc8c85572f/7.4admin/public/icons/icon-512x512.png
--------------------------------------------------------------------------------
/7.4admin/public/pro_icon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/7.4admin/src/components/Authorized/AuthorizedRoute.tsx:
--------------------------------------------------------------------------------
1 | import { Redirect, Route } from 'umi';
2 |
3 | import React from 'react';
4 | import Authorized from './Authorized';
5 | import type { IAuthorityType } from './CheckPermissions';
6 |
7 | type AuthorizedRouteProps = {
8 | currentAuthority: string;
9 | component: React.ComponentClass;
10 | render: (props: any) => React.ReactNode;
11 | redirectPath: string;
12 | authority: IAuthorityType;
13 | };
14 |
15 | const AuthorizedRoute: React.SFC = ({
16 | component: Component,
17 | render,
18 | authority,
19 | redirectPath,
20 | ...rest
21 | }) => (
22 | } />}
25 | >
26 | (Component ? : render(props))}
29 | />
30 |
31 | );
32 |
33 | export default AuthorizedRoute;
34 |
--------------------------------------------------------------------------------
/7.4admin/src/components/Authorized/index.tsx:
--------------------------------------------------------------------------------
1 | import Authorized from './Authorized';
2 | import Secured from './Secured';
3 | import check from './CheckPermissions';
4 | import renderAuthorize from './renderAuthorize';
5 |
6 | Authorized.Secured = Secured;
7 | Authorized.check = check;
8 |
9 | const RenderAuthorize = renderAuthorize(Authorized);
10 |
11 | export default RenderAuthorize;
12 |
--------------------------------------------------------------------------------
/7.4admin/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 |
--------------------------------------------------------------------------------
/7.4admin/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 |
--------------------------------------------------------------------------------
/7.4admin/src/components/HeaderSearch/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .headerSearch {
4 | .input {
5 | width: 0;
6 | min-width: 0;
7 | overflow: hidden;
8 | background: transparent;
9 | border-radius: 0;
10 | transition: width 0.3s, margin-left 0.3s;
11 | :global(.ant-select-selection) {
12 | background: transparent;
13 | }
14 | input {
15 | padding-right: 0;
16 | padding-left: 0;
17 | border: 0;
18 | box-shadow: none !important;
19 | }
20 | &,
21 | &:hover,
22 | &:focus {
23 | border-bottom: 1px solid @border-color-base;
24 | }
25 | &.show {
26 | width: 210px;
27 | margin-left: 8px;
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/7.4admin/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 |
--------------------------------------------------------------------------------
/7.4admin/src/components/PageLoading/index.tsx:
--------------------------------------------------------------------------------
1 | import { PageLoading } from '@ant-design/pro-layout';
2 |
3 | // loading components from code split
4 | // https://umijs.org/plugin/umi-plugin-react.html#dynamicimport
5 | export default PageLoading;
6 |
--------------------------------------------------------------------------------
/7.4admin/src/e2e/__mocks__/antd-pro-merge-less.js:
--------------------------------------------------------------------------------
1 | export default undefined;
2 |
--------------------------------------------------------------------------------
/7.4admin/src/global.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | html,
4 | body,
5 | #root {
6 | height: 100%;
7 | }
8 |
9 | .colorWeak {
10 | filter: invert(80%);
11 | }
12 |
13 | .ant-layout {
14 | min-height: 100vh;
15 | }
16 |
17 | canvas {
18 | display: block;
19 | }
20 |
21 | body {
22 | text-rendering: optimizeLegibility;
23 | -webkit-font-smoothing: antialiased;
24 | -moz-osx-font-smoothing: grayscale;
25 | }
26 |
27 | ul,
28 | ol {
29 | list-style: none;
30 | }
31 |
32 | @media (max-width: @screen-xs) {
33 | .ant-table {
34 | width: 100%;
35 | overflow-x: auto;
36 | &-thead > tr,
37 | &-tbody > tr {
38 | > th,
39 | > td {
40 | white-space: pre;
41 | > span {
42 | display: block;
43 | }
44 | }
45 | }
46 | }
47 | }
48 |
49 | // 兼容IE11
50 | @media screen and(-ms-high-contrast: active), (-ms-high-contrast: none) {
51 | body .ant-design-pro > .ant-layout {
52 | min-height: 100vh;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/7.4admin/src/layouts/BlankLayout.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Inspector } from 'react-dev-inspector';
3 |
4 | const InspectorWrapper = process.env.NODE_ENV === 'development' ? Inspector : React.Fragment;
5 |
6 | const Layout: React.FC = ({ children }) => {
7 | return {children};
8 | };
9 |
10 | export default Layout;
11 |
--------------------------------------------------------------------------------
/7.4admin/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 pwa from './en-US/pwa';
5 | import settingDrawer from './en-US/settingDrawer';
6 | import settings from './en-US/settings';
7 | import pages from './en-US/pages';
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.preview.down.block': 'Download this page to your local project',
15 | 'app.welcome.link.fetch-blocks': 'Get all block',
16 | 'app.welcome.link.block-list': 'Quickly build standard, pages based on `block` development',
17 | ...globalHeader,
18 | ...menu,
19 | ...settingDrawer,
20 | ...settings,
21 | ...pwa,
22 | ...component,
23 | ...pages,
24 | };
25 |
--------------------------------------------------------------------------------
/7.4admin/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 |
--------------------------------------------------------------------------------
/7.4admin/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 |
--------------------------------------------------------------------------------
/7.4admin/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 |
--------------------------------------------------------------------------------
/7.4admin/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 |
--------------------------------------------------------------------------------
/7.4admin/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 |
--------------------------------------------------------------------------------
/7.4admin/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 |
--------------------------------------------------------------------------------
/7.4admin/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 |
--------------------------------------------------------------------------------
/7.4admin/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 |
--------------------------------------------------------------------------------
/7.4admin/src/locales/ja-JP/component.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'component.tagSelect.expand': '展開',
3 | 'component.tagSelect.collapse': '折りたたむ',
4 | 'component.tagSelect.all': 'すべて',
5 | };
6 |
--------------------------------------------------------------------------------
/7.4admin/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 |
--------------------------------------------------------------------------------
/7.4admin/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 |
--------------------------------------------------------------------------------
/7.4admin/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 |
8 | export default {
9 | 'navBar.lang': 'Idiomas',
10 | 'layout.user.link.help': 'ajuda',
11 | 'layout.user.link.privacy': 'política de privacidade',
12 | 'layout.user.link.terms': 'termos de serviços',
13 | 'app.preview.down.block': 'Download this page to your local project',
14 | ...globalHeader,
15 | ...menu,
16 | ...settingDrawer,
17 | ...settings,
18 | ...pwa,
19 | ...component,
20 | };
21 |
--------------------------------------------------------------------------------
/7.4admin/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 |
--------------------------------------------------------------------------------
/7.4admin/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 |
--------------------------------------------------------------------------------
/7.4admin/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 |
--------------------------------------------------------------------------------
/7.4admin/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.preview.down.block': '下载此页面到本地项目',
15 | 'app.welcome.link.fetch-blocks': '获取全部区块',
16 | 'app.welcome.link.block-list': '基于 block 开发,快速构建标准页面',
17 | ...pages,
18 | ...globalHeader,
19 | ...menu,
20 | ...settingDrawer,
21 | ...settings,
22 | ...pwa,
23 | ...component,
24 | };
25 |
--------------------------------------------------------------------------------
/7.4admin/src/locales/zh-CN/component.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'component.tagSelect.expand': '展开',
3 | 'component.tagSelect.collapse': '收起',
4 | 'component.tagSelect.all': '全部',
5 | };
6 |
--------------------------------------------------------------------------------
/7.4admin/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 |
--------------------------------------------------------------------------------
/7.4admin/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 |
--------------------------------------------------------------------------------
/7.4admin/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 |
--------------------------------------------------------------------------------
/7.4admin/src/locales/zh-TW/component.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'component.tagSelect.expand': '展開',
3 | 'component.tagSelect.collapse': '收起',
4 | 'component.tagSelect.all': '全部',
5 | };
6 |
--------------------------------------------------------------------------------
/7.4admin/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 |
--------------------------------------------------------------------------------
/7.4admin/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 |
--------------------------------------------------------------------------------
/7.4admin/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 |
--------------------------------------------------------------------------------
/7.4admin/src/models/connect.d.ts:
--------------------------------------------------------------------------------
1 | import type { MenuDataItem, Settings as ProSettings } from '@ant-design/pro-layout';
2 | import { GlobalModelState } from './global';
3 | import { UserModelState } from './user';
4 | import type { StateType } from './login';
5 |
6 | export { GlobalModelState, UserModelState };
7 |
8 | export type Loading = {
9 | global: boolean;
10 | effects: Record;
11 | models: {
12 | global?: boolean;
13 | menu?: boolean;
14 | setting?: boolean;
15 | user?: boolean;
16 | login?: boolean;
17 | };
18 | };
19 |
20 | export type ConnectState = {
21 | global: GlobalModelState;
22 | loading: Loading;
23 | settings: ProSettings;
24 | user: UserModelState;
25 | login: StateType;
26 | };
27 |
28 | export type Route = {
29 | routes?: Route[];
30 | } & MenuDataItem;
31 |
--------------------------------------------------------------------------------
/7.4admin/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 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/TableList/data.d.ts:
--------------------------------------------------------------------------------
1 | export type TableListItem = {
2 | key: number;
3 | disabled?: boolean;
4 | href: string;
5 | avatar: string;
6 | name: string;
7 | owner: string;
8 | desc: string;
9 | callNo: number;
10 | status: number;
11 | updatedAt: Date;
12 | createdAt: Date;
13 | progress: number;
14 | };
15 |
16 | export type TableListPagination = {
17 | total: number;
18 | pageSize: number;
19 | current: number;
20 | };
21 |
22 | export type TableListData = {
23 | list: TableListItem[];
24 | pagination: Partial;
25 | };
26 |
27 | export type TableListParams = {
28 | status?: string;
29 | name?: string;
30 | desc?: string;
31 | key?: number;
32 | pageSize?: number;
33 | currentPage?: number;
34 | filter?: Record;
35 | sorter?: Record;
36 | };
37 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/TableList/service.ts:
--------------------------------------------------------------------------------
1 | import request from '@/utils/request';
2 | import type { TableListParams, TableListItem } from './data.d';
3 |
4 | export async function queryRule(params?: TableListParams) {
5 | return request('/api/rule', {
6 | params,
7 | });
8 | }
9 |
10 | export async function removeRule(params: { key: number[] }) {
11 | return request('/api/rule', {
12 | method: 'POST',
13 | data: {
14 | ...params,
15 | method: 'delete',
16 | },
17 | });
18 | }
19 |
20 | export async function addRule(params: TableListItem) {
21 | return request('/api/rule', {
22 | method: 'POST',
23 | data: {
24 | ...params,
25 | method: 'post',
26 | },
27 | });
28 | }
29 |
30 | export async function updateRule(params: TableListParams) {
31 | return request('/api/rule', {
32 | method: 'POST',
33 | data: {
34 | ...params,
35 | method: 'update',
36 | },
37 | });
38 | }
39 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/User/login/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .main {
4 | width: 328px;
5 | margin: 0 auto;
6 | @media screen and (max-width: @screen-sm) {
7 | width: 95%;
8 | max-width: 328px;
9 | }
10 |
11 | :global {
12 | .@{ant-prefix}-tabs-nav-list {
13 | margin: auto;
14 | font-size: 16px;
15 | }
16 | }
17 |
18 | .icon {
19 | margin-left: 16px;
20 | color: rgba(0, 0, 0, 0.2);
21 | font-size: 24px;
22 | vertical-align: middle;
23 | cursor: pointer;
24 | transition: color 0.3s;
25 |
26 | &:hover {
27 | color: @primary-color;
28 | }
29 | }
30 |
31 | .other {
32 | margin-top: 24px;
33 | line-height: 22px;
34 | text-align: left;
35 | .register {
36 | float: right;
37 | }
38 | }
39 |
40 | .prefixIcon {
41 | color: @primary-color;
42 | font-size: @font-size-base;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/User/register-result/style.less:
--------------------------------------------------------------------------------
1 | .registerResult {
2 | width: 800px;
3 | min-height: 400px;
4 | margin: auto;
5 | padding: 80px;
6 | background: none;
7 | :global {
8 | .anticon {
9 | font-size: 64px;
10 | }
11 | }
12 | .title {
13 | margin-top: 32px;
14 | font-size: 20px;
15 | line-height: 28px;
16 | }
17 | .actions {
18 | margin-top: 40px;
19 | a + a {
20 | margin-left: 8px;
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/User/register/_mock.ts:
--------------------------------------------------------------------------------
1 | // eslint-disable-next-line import/no-extraneous-dependencies
2 | import { Request, Response } from 'express';
3 |
4 | export default {
5 | 'POST /api/register': (_: Request, res: Response) => {
6 | res.send({ status: 'ok', currentAuthority: 'user' });
7 | },
8 | };
9 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/User/register/service.ts:
--------------------------------------------------------------------------------
1 | import request from 'umi-request';
2 | import { UserRegisterParams } from './index';
3 |
4 | export async function fakeRegister(params: UserRegisterParams) {
5 | return request('/api/register', {
6 | method: 'POST',
7 | data: params,
8 | });
9 | }
10 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/User/register/style.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .main {
4 | width: 368px;
5 | margin: 0 auto;
6 |
7 | h3 {
8 | margin-bottom: 20px;
9 | font-size: 16px;
10 | }
11 |
12 | .password {
13 | margin-bottom: 24px;
14 | :global {
15 | .ant-form-item-explain {
16 | display: none;
17 | }
18 | }
19 | }
20 |
21 | .getCaptcha {
22 | display: block;
23 | width: 100%;
24 | }
25 |
26 | .submit {
27 | width: 50%;
28 | }
29 |
30 | .login {
31 | float: right;
32 | line-height: @btn-height-lg;
33 | }
34 | }
35 |
36 | .success,
37 | .warning,
38 | .error {
39 | transition: color 0.3s;
40 | }
41 |
42 | .success {
43 | color: @success-color;
44 | }
45 |
46 | .warning {
47 | color: @warning-color;
48 | }
49 |
50 | .error {
51 | color: @error-color;
52 | }
53 |
54 | .progress-pass > .progress {
55 | :global {
56 | .ant-progress-bg {
57 | background-color: @warning-color;
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/7.4admin/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 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/account/center/components/ArticleListContent/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .listContent {
4 | .description {
5 | max-width: 720px;
6 | line-height: 22px;
7 | }
8 | .extra {
9 | margin-top: 16px;
10 | color: @text-color-secondary;
11 | line-height: 22px;
12 | & > :global(.ant-avatar) {
13 | position: relative;
14 | top: 1px;
15 | width: 20px;
16 | height: 20px;
17 | margin-right: 8px;
18 | vertical-align: top;
19 | }
20 | & > em {
21 | margin-left: 16px;
22 | color: @disabled-color;
23 | font-style: normal;
24 | }
25 | }
26 | }
27 |
28 | @media screen and (max-width: @screen-xs) {
29 | .listContent {
30 | .extra {
31 | & > em {
32 | display: block;
33 | margin-top: 8px;
34 | margin-left: 0;
35 | }
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/account/center/components/ArticleListContent/index.tsx:
--------------------------------------------------------------------------------
1 | import { Avatar } from 'antd';
2 | import React from 'react';
3 | import moment from 'moment';
4 | import styles from './index.less';
5 |
6 | export interface ApplicationsProps {
7 | data: {
8 | content?: string;
9 | updatedAt?: any;
10 | avatar?: string;
11 | owner?: string;
12 | href?: string;
13 | };
14 | }
15 | const ArticleListContent: React.FC = ({
16 | data: { content, updatedAt, avatar, owner, href },
17 | }) => (
18 |
19 |
{content}
20 |
21 |
22 |
{owner} 发布在
{href}
23 |
{moment(updatedAt).format('YYYY-MM-DD HH:mm')}
24 |
25 |
26 | );
27 |
28 | export default ArticleListContent;
29 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/account/center/components/Articles/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .articleList {
4 | :global {
5 | .ant-list-item:first-child {
6 | padding-top: 0;
7 | }
8 | }
9 | }
10 | a.listItemMetaTitle {
11 | color: @heading-color;
12 | }
13 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/account/center/service.ts:
--------------------------------------------------------------------------------
1 | import request from 'umi-request';
2 |
3 | export async function queryCurrent() {
4 | return request('/api/currentUser');
5 | }
6 |
7 | export async function queryFakeList(params: { count: number }) {
8 | return request('/api/fake_list', {
9 | params,
10 | });
11 | }
12 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/account/settings/components/GeographicView.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .row {
4 | .item {
5 | width: 50%;
6 | max-width: 220px;
7 | }
8 | .item:first-child {
9 | width: ~'calc(50% - 8px)';
10 | margin-right: 8px;
11 | }
12 | }
13 |
14 | @media screen and (max-width: @screen-sm) {
15 | .item:first-child {
16 | margin: 0;
17 | margin-bottom: 8px;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/account/settings/components/PhoneView.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .area_code {
4 | width: 30%;
5 | max-width: 128px;
6 | margin-right: 8px;
7 | }
8 | .phone_number {
9 | width: ~'calc(70% - 8px)';
10 | max-width: 312px;
11 | }
12 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/account/settings/data.d.ts:
--------------------------------------------------------------------------------
1 | export interface TagType {
2 | key: string;
3 | label: string;
4 | }
5 |
6 | export interface GeographicItemType {
7 | name: string;
8 | id: string;
9 | }
10 |
11 | export interface GeographicType {
12 | province: GeographicItemType;
13 | city: GeographicItemType;
14 | }
15 |
16 | export interface NoticeType {
17 | id: string;
18 | title: string;
19 | logo: string;
20 | description: string;
21 | updatedAt: string;
22 | member: string;
23 | href: string;
24 | memberLink: string;
25 | }
26 |
27 | export interface CurrentUser {
28 | name: string;
29 | avatar: string;
30 | userid: string;
31 | notice: NoticeType[];
32 | email: string;
33 | signature: string;
34 | title: string;
35 | group: string;
36 | tags: TagType[];
37 | notifyCount: number;
38 | unreadCount: number;
39 | country: string;
40 | geographic: GeographicType;
41 | address: string;
42 | phone: string;
43 | }
44 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/account/settings/service.ts:
--------------------------------------------------------------------------------
1 | import request from 'umi-request';
2 |
3 | export async function queryCurrent() {
4 | return request('/api/currentUser');
5 | }
6 |
7 | export async function queryProvince() {
8 | return request('/api/geographic/province');
9 | }
10 |
11 | export async function queryCity(province: string) {
12 | return request(`/api/geographic/city/${province}`);
13 | }
14 |
15 | export async function query() {
16 | return request('/api/users');
17 | }
18 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/dashboard/analysis/components/Charts/Field/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .field {
4 | margin: 0;
5 | overflow: hidden;
6 | white-space: nowrap;
7 | text-overflow: ellipsis;
8 | .label,
9 | .number {
10 | font-size: @font-size-base;
11 | line-height: 22px;
12 | }
13 | .number {
14 | margin-left: 8px;
15 | color: @heading-color;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/dashboard/analysis/components/Charts/Field/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import styles from './index.less';
3 |
4 | export interface FieldProps {
5 | label: React.ReactNode;
6 | value: React.ReactNode;
7 | style?: React.CSSProperties;
8 | }
9 |
10 | const Field: React.FC = ({ label, value, ...rest }) => (
11 |
12 | {label}
13 | {value}
14 |
15 | );
16 |
17 | export default Field;
18 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/dashboard/analysis/components/Charts/MiniProgress/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .miniProgress {
4 | position: relative;
5 | width: 100%;
6 | padding: 5px 0;
7 | .progressWrap {
8 | position: relative;
9 | background-color: @background-color-base;
10 | }
11 | .progress {
12 | width: 0;
13 | height: 100%;
14 | background-color: @primary-color;
15 | border-radius: 1px 0 0 1px;
16 | transition: all 0.4s cubic-bezier(0.08, 0.82, 0.17, 1) 0s;
17 | }
18 | .target {
19 | position: absolute;
20 | top: 0;
21 | bottom: 0;
22 | z-index: 9;
23 | width: 20px;
24 | span {
25 | position: absolute;
26 | top: 0;
27 | left: 0;
28 | width: 2px;
29 | height: 4px;
30 | border-radius: 100px;
31 | }
32 | span:last-child {
33 | top: auto;
34 | bottom: 0;
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/dashboard/analysis/components/Charts/TagCloud/index.less:
--------------------------------------------------------------------------------
1 | .tagCloud {
2 | overflow: hidden;
3 | canvas {
4 | transform-origin: 0 0;
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/dashboard/analysis/components/Charts/TimelineChart/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .timelineChart {
4 | background: @component-background;
5 | }
6 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/dashboard/analysis/components/Charts/WaterWave/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .waterWave {
4 | position: relative;
5 | display: inline-block;
6 | transform-origin: left;
7 | .text {
8 | position: absolute;
9 | top: 32px;
10 | left: 0;
11 | width: 100%;
12 | text-align: center;
13 | span {
14 | color: @text-color-secondary;
15 | font-size: 14px;
16 | line-height: 22px;
17 | }
18 | h4 {
19 | color: @heading-color;
20 | font-size: 24px;
21 | line-height: 32px;
22 | }
23 | }
24 | .waterWaveCanvasWrapper {
25 | transform: scale(0.5);
26 | transform-origin: 0 0;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/dashboard/analysis/components/Charts/bizcharts.tsx:
--------------------------------------------------------------------------------
1 | import * as BizChart from 'bizcharts';
2 |
3 | export default BizChart;
4 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/dashboard/analysis/components/Charts/index.less:
--------------------------------------------------------------------------------
1 | .miniChart {
2 | position: relative;
3 | width: 100%;
4 | .chartContent {
5 | position: absolute;
6 | bottom: -28px;
7 | width: 100%;
8 | > div {
9 | margin: 0 -5px;
10 | overflow: hidden;
11 | }
12 | }
13 | .chartLoading {
14 | position: absolute;
15 | top: 16px;
16 | left: 50%;
17 | margin-left: -7px;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/dashboard/analysis/components/PageLoading/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Spin } from 'antd';
3 |
4 | // loading components from code split
5 | // https://umijs.org/plugin/umi-plugin-react.html#dynamicimport
6 | export default () => (
7 |
8 |
9 |
10 | );
11 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/dashboard/analysis/components/Trend/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .trendItem {
4 | display: inline-block;
5 | font-size: @font-size-base;
6 | line-height: 22px;
7 |
8 | .up,
9 | .down {
10 | position: relative;
11 | top: 1px;
12 | margin-left: 4px;
13 | span {
14 | font-size: 12px;
15 | transform: scale(0.83);
16 | }
17 | }
18 | .up {
19 | color: @red-6;
20 | }
21 | .down {
22 | top: -1px;
23 | color: @green-6;
24 | }
25 |
26 | &.trendItemGrey .up,
27 | &.trendItemGrey .down {
28 | color: @text-color;
29 | }
30 |
31 | &.reverseColor .up {
32 | color: @green-6;
33 | }
34 | &.reverseColor .down {
35 | color: @red-6;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/dashboard/analysis/data.d.ts:
--------------------------------------------------------------------------------
1 | export interface VisitDataType {
2 | x: string;
3 | y: number;
4 | }
5 |
6 | export interface SearchDataType {
7 | index: number;
8 | keyword: string;
9 | count: number;
10 | range: number;
11 | status: number;
12 | }
13 |
14 | export interface OfflineDataType {
15 | name: string;
16 | cvr: number;
17 | }
18 |
19 | export interface OfflineChartData {
20 | x: any;
21 | y1: number;
22 | y2: number;
23 | }
24 |
25 | export interface RadarData {
26 | name: string;
27 | label: string;
28 | value: number;
29 | }
30 |
31 | export interface AnalysisData {
32 | visitData: VisitDataType[];
33 | visitData2: VisitDataType[];
34 | salesData: VisitDataType[];
35 | searchData: SearchDataType[];
36 | offlineData: OfflineDataType[];
37 | offlineChartData: OfflineChartData[];
38 | salesTypeData: VisitDataType[];
39 | salesTypeDataOnline: VisitDataType[];
40 | salesTypeDataOffline: VisitDataType[];
41 | radarData: RadarData[];
42 | }
43 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/dashboard/analysis/service.ts:
--------------------------------------------------------------------------------
1 | import request from 'umi-request';
2 |
3 | export async function fakeChartData() {
4 | return request('/api/fake_chart_data');
5 | }
6 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/dashboard/analysis/utils/Yuan.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { yuan } from '../components/Charts';
3 | /**
4 | * 减少使用 dangerouslySetInnerHTML
5 | */
6 | export default class Yuan extends React.Component<{
7 | children: React.ReactText;
8 | }> {
9 | main: HTMLSpanElement | undefined | null = null;
10 |
11 | componentDidMount() {
12 | this.renderToHtml();
13 | }
14 |
15 | componentDidUpdate() {
16 | this.renderToHtml();
17 | }
18 |
19 | renderToHtml = () => {
20 | const { children } = this.props;
21 | if (this.main) {
22 | this.main.innerHTML = yuan(children);
23 | }
24 | };
25 |
26 | render() {
27 | return (
28 | {
30 | this.main = ref;
31 | }}
32 | />
33 | );
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/dashboard/monitor/_mock.ts:
--------------------------------------------------------------------------------
1 | import mockjs from 'mockjs';
2 |
3 | export default {
4 | 'GET /api/tags': mockjs.mock({
5 | 'list|100': [{ name: '@city', 'value|1-100': 150, 'type|0-2': 1 }],
6 | }),
7 | };
8 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/dashboard/monitor/components/Charts/TagCloud/index.less:
--------------------------------------------------------------------------------
1 | .tagCloud {
2 | overflow: hidden;
3 | canvas {
4 | transform-origin: 0 0;
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/dashboard/monitor/components/Charts/WaterWave/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .waterWave {
4 | position: relative;
5 | display: inline-block;
6 | transform-origin: left;
7 | .text {
8 | position: absolute;
9 | top: 32px;
10 | left: 0;
11 | width: 100%;
12 | text-align: center;
13 | span {
14 | color: @text-color-secondary;
15 | font-size: 14px;
16 | line-height: 22px;
17 | }
18 | h4 {
19 | color: @heading-color;
20 | font-size: 24px;
21 | line-height: 32px;
22 | }
23 | }
24 | .waterWaveCanvasWrapper {
25 | transform: scale(0.5);
26 | transform-origin: 0 0;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/dashboard/monitor/components/Charts/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .miniChart {
4 | position: relative;
5 | width: 100%;
6 | .chartContent {
7 | position: absolute;
8 | bottom: -28px;
9 | width: 100%;
10 | > div {
11 | margin: 0 -5px;
12 | overflow: hidden;
13 | }
14 | }
15 | .chartLoading {
16 | position: absolute;
17 | top: 16px;
18 | left: 50%;
19 | margin-left: -7px;
20 | }
21 | }
22 |
23 | :global {
24 | body .l7-popup-content {
25 | background: @component-background;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/dashboard/monitor/components/Charts/index.tsx:
--------------------------------------------------------------------------------
1 | import Gauge from './Gauge';
2 | import MiniArea from './MiniArea';
3 | import Pie from './Pie';
4 | import TagCloud from './TagCloud';
5 | import WaterWave from './WaterWave';
6 | import Map from './Map';
7 |
8 | const Charts = {
9 | Pie,
10 | WaterWave,
11 | Gauge,
12 | MiniArea,
13 | TagCloud,
14 | Map,
15 | };
16 |
17 | export { Charts as default, Pie, WaterWave, Gauge, TagCloud, MiniArea, Map };
18 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/dashboard/monitor/data.d.ts:
--------------------------------------------------------------------------------
1 | export interface TagType {
2 | name: string;
3 | value: string;
4 | type: string;
5 | }
6 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/dashboard/monitor/model.ts:
--------------------------------------------------------------------------------
1 | import { Effect, Reducer } from 'umi';
2 |
3 | import { TagType } from './data.d';
4 | import { queryTags } from './service';
5 |
6 | export interface StateType {
7 | tags: TagType[];
8 | }
9 |
10 | export interface ModelType {
11 | namespace: string;
12 | state: StateType;
13 | effects: {
14 | fetchTags: Effect;
15 | };
16 | reducers: {
17 | saveTags: Reducer;
18 | };
19 | }
20 |
21 | const Model: ModelType = {
22 | namespace: 'dashboardAndmonitor',
23 |
24 | state: {
25 | tags: [],
26 | },
27 |
28 | effects: {
29 | *fetchTags(_, { call, put }) {
30 | const response = yield call(queryTags);
31 | yield put({
32 | type: 'saveTags',
33 | payload: response.list,
34 | });
35 | },
36 | },
37 |
38 | reducers: {
39 | saveTags(state, action) {
40 | return {
41 | ...state,
42 | tags: action.payload,
43 | };
44 | },
45 | },
46 | };
47 |
48 | export default Model;
49 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/dashboard/monitor/service.ts:
--------------------------------------------------------------------------------
1 | import request from 'umi-request';
2 |
3 | export async function queryTags() {
4 | return request('/api/tags');
5 | }
6 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/dashboard/monitor/style.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .mapChart {
4 | height: 452px;
5 | padding-top: 24px;
6 | img {
7 | display: inline-block;
8 | max-width: 100%;
9 | max-height: 437px;
10 | }
11 | }
12 |
13 | .pieCard :global(.pie-stat) {
14 | font-size: 24px !important;
15 | }
16 |
17 | @media screen and (max-width: @screen-lg) {
18 | .mapChart {
19 | height: auto;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/dashboard/workplace/components/EditableLinkGroup/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .linkGroup {
4 | padding: 20px 0 8px 24px;
5 | font-size: 0;
6 | & > a {
7 | display: inline-block;
8 | width: 25%;
9 | margin-bottom: 13px;
10 | color: @text-color;
11 | font-size: @font-size-base;
12 | &:hover {
13 | color: @primary-color;
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/dashboard/workplace/service.ts:
--------------------------------------------------------------------------------
1 | import request from 'umi-request';
2 |
3 | export async function queryProjectNotice() {
4 | return request('/api/project/notice');
5 | }
6 |
7 | export async function queryActivities() {
8 | return request('/api/activities');
9 | }
10 |
11 | export async function fakeChartData() {
12 | return request('/api/fake_chart_data');
13 | }
14 |
15 | export async function queryCurrent() {
16 | return request('/api/currentUser');
17 | }
18 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/flow/common/IconFont/index.ts:
--------------------------------------------------------------------------------
1 | import { createFromIconfontCN } from '@ant-design/icons';
2 |
3 | const IconFont = createFromIconfontCN({
4 | scriptUrl: 'https://at.alicdn.com/t/font_1101588_01zniftxm9yp.js',
5 | });
6 |
7 | export default IconFont;
8 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/flow/components/EditorContextMenu/KoniContextMenu.tsx:
--------------------------------------------------------------------------------
1 | import FlowContextMenu from './FlowContextMenu';
2 |
3 | export default FlowContextMenu;
4 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/flow/components/EditorContextMenu/MenuItem.tsx:
--------------------------------------------------------------------------------
1 | import { Command } from 'gg-editor';
2 | import React from 'react';
3 | import IconFont from '../../common/IconFont';
4 | import styles from './index.less';
5 |
6 | const upperFirst = (str: string) =>
7 | str.toLowerCase().replace(/( |^)[a-z]/g, (l: string) => l.toUpperCase());
8 |
9 | interface MenuItemProps {
10 | command: string;
11 | icon?: string;
12 | text?: string;
13 | }
14 | const MenuItem: React.FC = (props) => {
15 | const { command, icon, text } = props;
16 |
17 | return (
18 |
19 |
20 |
21 | {text || upperFirst(command)}
22 |
23 |
24 | );
25 | };
26 |
27 | export default MenuItem;
28 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/flow/components/EditorContextMenu/MindContextMenu.tsx:
--------------------------------------------------------------------------------
1 | import { CanvasMenu, ContextMenu, NodeMenu } from 'gg-editor';
2 |
3 | import React from 'react';
4 | import MenuItem from './MenuItem';
5 | import styles from './index.less';
6 |
7 | const MindContextMenu = () => (
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | );
22 |
23 | export default MindContextMenu;
24 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/flow/components/EditorContextMenu/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .contextMenu {
4 | display: none;
5 | overflow: hidden;
6 | background: @component-background;
7 | border-radius: 4px;
8 | box-shadow: @box-shadow-base;
9 |
10 | .item {
11 | display: flex;
12 | align-items: center;
13 | padding: 5px 12px;
14 | cursor: pointer;
15 | transition: all 0.3s;
16 | user-select: none;
17 |
18 | &:hover {
19 | background: @select-item-selected-bg;
20 | }
21 |
22 | span.anticon {
23 | margin-right: 8px;
24 | }
25 | }
26 |
27 | :global {
28 | .disable {
29 | :local {
30 | .item {
31 | color: @disabled-color;
32 | cursor: auto;
33 |
34 | &:hover {
35 | background: @item-hover-bg;
36 | }
37 | }
38 | }
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/flow/components/EditorContextMenu/index.tsx:
--------------------------------------------------------------------------------
1 | import FlowContextMenu from './FlowContextMenu';
2 | import KoniContextMenu from './KoniContextMenu';
3 | import MindContextMenu from './MindContextMenu';
4 |
5 | export { FlowContextMenu, MindContextMenu, KoniContextMenu };
6 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/flow/components/EditorDetailPanel/FlowDetailPanel.tsx:
--------------------------------------------------------------------------------
1 | import { CanvasPanel, DetailPanel, EdgePanel, GroupPanel, MultiPanel, NodePanel } from 'gg-editor';
2 |
3 | import { Card } from 'antd';
4 | import React from 'react';
5 | import DetailForm from './DetailForm';
6 | import styles from './index.less';
7 |
8 | const FlowDetailPanel = () => (
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | );
27 |
28 | export default FlowDetailPanel;
29 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/flow/components/EditorDetailPanel/KoniDetailPanel.tsx:
--------------------------------------------------------------------------------
1 | import FlowDetailPanel from './FlowDetailPanel';
2 |
3 | export default FlowDetailPanel;
4 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/flow/components/EditorDetailPanel/MindDetailPanel.tsx:
--------------------------------------------------------------------------------
1 | import { CanvasPanel, DetailPanel, NodePanel } from 'gg-editor';
2 |
3 | import { Card } from 'antd';
4 | import React from 'react';
5 | import DetailForm from './DetailForm';
6 | import styles from './index.less';
7 |
8 | const MindDetailPanel = () => (
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | );
18 |
19 | export default MindDetailPanel;
20 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/flow/components/EditorDetailPanel/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .detailPanel {
4 | flex: 1;
5 | background-color: @component-background;
6 | }
7 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/flow/components/EditorDetailPanel/index.tsx:
--------------------------------------------------------------------------------
1 | import FlowDetailPanel from './FlowDetailPanel';
2 | import KoniDetailPanel from './KoniDetailPanel';
3 | import MindDetailPanel from './MindDetailPanel';
4 |
5 | export { FlowDetailPanel, MindDetailPanel, KoniDetailPanel };
6 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/flow/components/EditorItemPanel/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .itemPanel {
4 | flex: 1;
5 |
6 | :global {
7 | .ant-card {
8 | height: 100%;
9 | }
10 | .ant-card-body {
11 | display: flex;
12 | flex-direction: column;
13 | align-items: center;
14 | > div {
15 | margin-bottom: 16px;
16 | }
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/flow/components/EditorItemPanel/index.tsx:
--------------------------------------------------------------------------------
1 | import FlowItemPanel from './FlowItemPanel';
2 | import KoniItemPanel from './KoniItemPanel';
3 |
4 | export { FlowItemPanel, KoniItemPanel };
5 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/flow/components/EditorMinimap/index.tsx:
--------------------------------------------------------------------------------
1 | import { Card } from 'antd';
2 | import { Minimap } from 'gg-editor';
3 | import React from 'react';
4 |
5 | const EditorMinimap = () => (
6 |
7 |
8 |
9 | );
10 |
11 | export default EditorMinimap;
12 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/flow/components/EditorToolbar/KoniToolbar.tsx:
--------------------------------------------------------------------------------
1 | import FlowToolbar from './FlowToolbar';
2 |
3 | export default FlowToolbar;
4 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/flow/components/EditorToolbar/ToolbarButton.tsx:
--------------------------------------------------------------------------------
1 | import { Command } from 'gg-editor';
2 | import React from 'react';
3 | import { Tooltip } from 'antd';
4 | import IconFont from '../../common/IconFont';
5 | import styles from './index.less';
6 |
7 | const upperFirst = (str: string) =>
8 | str.toLowerCase().replace(/( |^)[a-z]/g, (l: string) => l.toUpperCase());
9 |
10 | interface ToolbarButtonProps {
11 | command: string;
12 | icon?: string;
13 | text?: string;
14 | }
15 | const ToolbarButton: React.FC = (props) => {
16 | const { command, icon, text } = props;
17 |
18 | return (
19 |
20 |
25 |
26 |
27 |
28 | );
29 | };
30 |
31 | export default ToolbarButton;
32 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/flow/components/EditorToolbar/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .toolbar {
4 | display: flex;
5 | align-items: center;
6 |
7 | :global {
8 | .command .anticon {
9 | display: inline-block;
10 | width: 27px;
11 | height: 27px;
12 | margin: 0 6px;
13 | padding-top: 6px;
14 | text-align: center;
15 | cursor: pointer;
16 |
17 | &:hover {
18 | border: 1px solid @item-active-bg;
19 | }
20 | }
21 |
22 | .disable .anticon {
23 | color: @text-color-secondary;
24 | cursor: auto;
25 |
26 | &:hover {
27 | border: 1px solid @border-color-base;
28 | }
29 | }
30 | }
31 | }
32 |
33 | .tooltip {
34 | :global {
35 | .ant-tooltip-inner {
36 | font-size: 12px;
37 | border-radius: 0;
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/flow/components/EditorToolbar/index.tsx:
--------------------------------------------------------------------------------
1 | import FlowToolbar from './FlowToolbar';
2 | import KoniToolbar from './KoniToolbar';
3 | import MindToolbar from './MindToolbar';
4 |
5 | export { FlowToolbar, MindToolbar, KoniToolbar };
6 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/flow/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .editor {
4 | display: flex;
5 | flex: 1;
6 | flex-direction: column;
7 | width: 100%;
8 | height: calc(100vh - 250px);
9 | background: @component-background;
10 | }
11 |
12 | .editorHd {
13 | padding: 8px;
14 | background: @descriptions-bg;
15 | border: 1px solid @item-active-bg;
16 | }
17 |
18 | .editorBd {
19 | flex: 1;
20 | }
21 |
22 | .editorSidebar,
23 | .editorContent {
24 | display: flex;
25 | flex-direction: column;
26 | }
27 |
28 | .editorSidebar {
29 | background: @descriptions-bg;
30 | :global {
31 | .g6-editor-minimap-container {
32 | background: none !important ;
33 | }
34 | }
35 | &:first-child {
36 | border-right: 1px solid @item-active-bg;
37 | }
38 |
39 | &:last-child {
40 | border-left: 1px solid @item-active-bg;
41 | }
42 | }
43 |
44 | .flow,
45 | .mind,
46 | .koni {
47 | flex: 1;
48 | }
49 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/flow/locales/en-US.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'editorandflow.description':
3 | 'The flow chart is an excellent way to represent the idea of the algorithm',
4 | };
5 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/flow/locales/zh-CN.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'editorandflow.description': '千言万语不如一张图,流程图是表示算法思路的好方法',
3 | };
4 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/koni/common/IconFont/index.ts:
--------------------------------------------------------------------------------
1 | import { createFromIconfontCN } from '@ant-design/icons';
2 |
3 | const IconFont = createFromIconfontCN({
4 | scriptUrl: 'https://at.alicdn.com/t/font_1101588_01zniftxm9yp.js',
5 | });
6 |
7 | export default IconFont;
8 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/koni/components/EditorContextMenu/KoniContextMenu.tsx:
--------------------------------------------------------------------------------
1 | import FlowContextMenu from './FlowContextMenu';
2 |
3 | export default FlowContextMenu;
4 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/koni/components/EditorContextMenu/MenuItem.tsx:
--------------------------------------------------------------------------------
1 | import { Command } from 'gg-editor';
2 | import React from 'react';
3 | import IconFont from '../../common/IconFont';
4 | import styles from './index.less';
5 |
6 | const upperFirst = (str: string) =>
7 | str.toLowerCase().replace(/( |^)[a-z]/g, (l: string) => l.toUpperCase());
8 |
9 | interface MenuItemProps {
10 | command: string;
11 | icon?: string;
12 | text?: string;
13 | }
14 | const MenuItem: React.FC = (props) => {
15 | const { command, icon, text } = props;
16 |
17 | return (
18 |
19 |
20 |
21 | {text || upperFirst(command)}
22 |
23 |
24 | );
25 | };
26 |
27 | export default MenuItem;
28 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/koni/components/EditorContextMenu/MindContextMenu.tsx:
--------------------------------------------------------------------------------
1 | import { CanvasMenu, ContextMenu, NodeMenu } from 'gg-editor';
2 |
3 | import React from 'react';
4 | import MenuItem from './MenuItem';
5 | import styles from './index.less';
6 |
7 | const MindContextMenu = () => (
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | );
22 |
23 | export default MindContextMenu;
24 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/koni/components/EditorContextMenu/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .contextMenu {
4 | display: none;
5 | overflow: hidden;
6 | background: @component-background;
7 | border-radius: 4px;
8 | box-shadow: @box-shadow-base;
9 | .item {
10 | display: flex;
11 | align-items: center;
12 | padding: 5px 12px;
13 | cursor: pointer;
14 | transition: all 0.3s;
15 | user-select: none;
16 |
17 | &:hover {
18 | background: @select-item-selected-bg;
19 | }
20 |
21 | .anticon {
22 | margin-right: 8px;
23 | }
24 | }
25 |
26 | :global {
27 | .disable {
28 | :local {
29 | .item {
30 | color: @disabled-color;
31 | cursor: auto;
32 |
33 | &:hover {
34 | background: @item-hover-bg;
35 | }
36 | }
37 | }
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/koni/components/EditorContextMenu/index.tsx:
--------------------------------------------------------------------------------
1 | import FlowContextMenu from './FlowContextMenu';
2 | import KoniContextMenu from './KoniContextMenu';
3 | import MindContextMenu from './MindContextMenu';
4 |
5 | export { FlowContextMenu, MindContextMenu, KoniContextMenu };
6 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/koni/components/EditorDetailPanel/FlowDetailPanel.tsx:
--------------------------------------------------------------------------------
1 | import { CanvasPanel, DetailPanel, EdgePanel, GroupPanel, MultiPanel, NodePanel } from 'gg-editor';
2 |
3 | import { Card } from 'antd';
4 | import React from 'react';
5 | import DetailForm from './DetailForm';
6 | import styles from './index.less';
7 |
8 | const FlowDetailPanel = () => (
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | );
27 |
28 | export default FlowDetailPanel;
29 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/koni/components/EditorDetailPanel/KoniDetailPanel.tsx:
--------------------------------------------------------------------------------
1 | import FlowDetailPanel from './FlowDetailPanel';
2 |
3 | export default FlowDetailPanel;
4 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/koni/components/EditorDetailPanel/MindDetailPanel.tsx:
--------------------------------------------------------------------------------
1 | import { CanvasPanel, DetailPanel, NodePanel } from 'gg-editor';
2 |
3 | import { Card } from 'antd';
4 | import React from 'react';
5 | import DetailForm from './DetailForm';
6 | import styles from './index.less';
7 |
8 | const MindDetailPanel = () => (
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | );
18 |
19 | export default MindDetailPanel;
20 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/koni/components/EditorDetailPanel/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .detailPanel {
4 | flex: 1;
5 | background-color: @component-background;
6 | }
7 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/koni/components/EditorDetailPanel/index.tsx:
--------------------------------------------------------------------------------
1 | import FlowDetailPanel from './FlowDetailPanel';
2 | import KoniDetailPanel from './KoniDetailPanel';
3 | import MindDetailPanel from './MindDetailPanel';
4 |
5 | export { FlowDetailPanel, MindDetailPanel, KoniDetailPanel };
6 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/koni/components/EditorItemPanel/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .itemPanel {
4 | flex: 1;
5 |
6 | :global {
7 | .ant-card {
8 | height: 100%;
9 | }
10 | .ant-card-body {
11 | display: flex;
12 | flex-direction: column;
13 | align-items: center;
14 | > div {
15 | margin-bottom: 16px;
16 | }
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/koni/components/EditorItemPanel/index.tsx:
--------------------------------------------------------------------------------
1 | import FlowItemPanel from './FlowItemPanel';
2 | import KoniItemPanel from './KoniItemPanel';
3 |
4 | export { FlowItemPanel, KoniItemPanel };
5 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/koni/components/EditorMinimap/index.tsx:
--------------------------------------------------------------------------------
1 | import { Card } from 'antd';
2 | import { Minimap } from 'gg-editor';
3 | import React from 'react';
4 |
5 | const EditorMinimap = () => (
6 |
7 |
8 |
9 | );
10 |
11 | export default EditorMinimap;
12 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/koni/components/EditorToolbar/KoniToolbar.tsx:
--------------------------------------------------------------------------------
1 | import FlowToolbar from './FlowToolbar';
2 |
3 | export default FlowToolbar;
4 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/koni/components/EditorToolbar/ToolbarButton.tsx:
--------------------------------------------------------------------------------
1 | import { Command } from 'gg-editor';
2 | import React from 'react';
3 | import { Tooltip } from 'antd';
4 | import IconFont from '../../common/IconFont';
5 | import styles from './index.less';
6 |
7 | const upperFirst = (str: string) =>
8 | str.toLowerCase().replace(/( |^)[a-z]/g, (l: string) => l.toUpperCase());
9 |
10 | interface ToolbarButtonProps {
11 | command: string;
12 | icon?: string;
13 | text?: string;
14 | }
15 | const ToolbarButton: React.FC = (props) => {
16 | const { command, icon, text } = props;
17 |
18 | return (
19 |
20 |
25 |
26 |
27 |
28 | );
29 | };
30 |
31 | export default ToolbarButton;
32 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/koni/components/EditorToolbar/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .toolbar {
4 | display: flex;
5 | align-items: center;
6 | :global {
7 | .command .anticon {
8 | display: inline-block;
9 | width: 27px;
10 | height: 27px;
11 | margin: 0 6px;
12 | padding-top: 6px;
13 | text-align: center;
14 | cursor: pointer;
15 |
16 | &:hover {
17 | border: 1px solid @item-active-bg;
18 | }
19 | }
20 |
21 | .disable .anticon {
22 | color: @text-color-secondary;
23 | cursor: auto;
24 |
25 | &:hover {
26 | border: 1px solid @border-color-base;
27 | }
28 | }
29 | }
30 | }
31 |
32 | .tooltip {
33 | :global {
34 | .ant-tooltip-inner {
35 | font-size: 12px;
36 | border-radius: 0;
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/koni/components/EditorToolbar/index.tsx:
--------------------------------------------------------------------------------
1 | import FlowToolbar from './FlowToolbar';
2 | import KoniToolbar from './KoniToolbar';
3 | import MindToolbar from './MindToolbar';
4 |
5 | export { FlowToolbar, MindToolbar, KoniToolbar };
6 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/koni/locales/en-US.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'editorandkoni.description':
3 | 'The topology diagram refers to the network structure diagram composed of network node devices and communication media',
4 | };
5 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/koni/locales/zh-CN.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'editorandkoni.description': '拓扑结构图是指由网络节点设备和通信介质构成的网络结构图',
3 | };
4 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/mind/common/IconFont/index.ts:
--------------------------------------------------------------------------------
1 | import { createFromIconfontCN } from '@ant-design/icons';
2 |
3 | const IconFont = createFromIconfontCN({
4 | scriptUrl: 'https://at.alicdn.com/t/font_1101588_01zniftxm9yp.js',
5 | });
6 |
7 | export default IconFont;
8 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/mind/components/EditorContextMenu/KoniContextMenu.tsx:
--------------------------------------------------------------------------------
1 | import FlowContextMenu from './FlowContextMenu';
2 |
3 | export default FlowContextMenu;
4 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/mind/components/EditorContextMenu/MenuItem.tsx:
--------------------------------------------------------------------------------
1 | import { Command } from 'gg-editor';
2 | import React from 'react';
3 | import IconFont from '../../common/IconFont';
4 | import styles from './index.less';
5 |
6 | const upperFirst = (str: string) =>
7 | str.toLowerCase().replace(/( |^)[a-z]/g, (l: string) => l.toUpperCase());
8 |
9 | interface MenuItemProps {
10 | command: string;
11 | icon?: string;
12 | text?: string;
13 | }
14 | const MenuItem: React.FC = (props) => {
15 | const { command, icon, text } = props;
16 |
17 | return (
18 |
19 |
20 |
21 | {text || upperFirst(command)}
22 |
23 |
24 | );
25 | };
26 |
27 | export default MenuItem;
28 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/mind/components/EditorContextMenu/MindContextMenu.tsx:
--------------------------------------------------------------------------------
1 | import { CanvasMenu, ContextMenu, NodeMenu } from 'gg-editor';
2 |
3 | import React from 'react';
4 | import MenuItem from './MenuItem';
5 | import styles from './index.less';
6 |
7 | const MindContextMenu = () => (
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | );
22 |
23 | export default MindContextMenu;
24 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/mind/components/EditorContextMenu/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .contextMenu {
4 | display: none;
5 | overflow: hidden;
6 | background: @component-background;
7 | border-radius: 4px;
8 | box-shadow: @box-shadow-base;
9 | .item {
10 | display: flex;
11 | align-items: center;
12 | padding: 5px 12px;
13 | cursor: pointer;
14 | transition: all 0.3s;
15 | user-select: none;
16 |
17 | &:hover {
18 | background: @select-item-selected-bg;
19 | }
20 |
21 | .anticon {
22 | margin-right: 8px;
23 | }
24 | }
25 |
26 | :global {
27 | .disable {
28 | :local {
29 | .item {
30 | color: @disabled-color;
31 | cursor: auto;
32 |
33 | &:hover {
34 | background: @item-hover-bg;
35 | }
36 | }
37 | }
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/mind/components/EditorContextMenu/index.tsx:
--------------------------------------------------------------------------------
1 | import FlowContextMenu from './FlowContextMenu';
2 | import KoniContextMenu from './KoniContextMenu';
3 | import MindContextMenu from './MindContextMenu';
4 |
5 | export { FlowContextMenu, MindContextMenu, KoniContextMenu };
6 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/mind/components/EditorDetailPanel/FlowDetailPanel.tsx:
--------------------------------------------------------------------------------
1 | import { CanvasPanel, DetailPanel, EdgePanel, GroupPanel, MultiPanel, NodePanel } from 'gg-editor';
2 |
3 | import { Card } from 'antd';
4 | import React from 'react';
5 | import DetailForm from './DetailForm';
6 | import styles from './index.less';
7 |
8 | const FlowDetailPanel = () => (
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | );
27 |
28 | export default FlowDetailPanel;
29 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/mind/components/EditorDetailPanel/KoniDetailPanel.tsx:
--------------------------------------------------------------------------------
1 | import FlowDetailPanel from './FlowDetailPanel';
2 |
3 | export default FlowDetailPanel;
4 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/mind/components/EditorDetailPanel/MindDetailPanel.tsx:
--------------------------------------------------------------------------------
1 | import { CanvasPanel, DetailPanel, NodePanel } from 'gg-editor';
2 |
3 | import { Card } from 'antd';
4 | import React from 'react';
5 | import DetailForm from './DetailForm';
6 | import styles from './index.less';
7 |
8 | const MindDetailPanel = () => (
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | );
18 |
19 | export default MindDetailPanel;
20 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/mind/components/EditorDetailPanel/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .detailPanel {
4 | flex: 1;
5 | background-color: @component-background;
6 | }
7 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/mind/components/EditorDetailPanel/index.tsx:
--------------------------------------------------------------------------------
1 | import FlowDetailPanel from './FlowDetailPanel';
2 | import KoniDetailPanel from './KoniDetailPanel';
3 | import MindDetailPanel from './MindDetailPanel';
4 |
5 | export { FlowDetailPanel, MindDetailPanel, KoniDetailPanel };
6 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/mind/components/EditorItemPanel/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .itemPanel {
4 | flex: 1;
5 |
6 | :global {
7 | .ant-card {
8 | height: 100%;
9 | }
10 | .ant-card-body {
11 | display: flex;
12 | flex-direction: column;
13 | align-items: center;
14 | > div {
15 | margin-bottom: 16px;
16 | }
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/mind/components/EditorItemPanel/index.tsx:
--------------------------------------------------------------------------------
1 | import FlowItemPanel from './FlowItemPanel';
2 | import KoniItemPanel from './KoniItemPanel';
3 |
4 | export { FlowItemPanel, KoniItemPanel };
5 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/mind/components/EditorMinimap/index.tsx:
--------------------------------------------------------------------------------
1 | import { Card } from 'antd';
2 | import { Minimap } from 'gg-editor';
3 | import React from 'react';
4 |
5 | const EditorMinimap = () => (
6 |
7 |
8 |
9 | );
10 |
11 | export default EditorMinimap;
12 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/mind/components/EditorToolbar/KoniToolbar.tsx:
--------------------------------------------------------------------------------
1 | import FlowToolbar from './FlowToolbar';
2 |
3 | export default FlowToolbar;
4 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/mind/components/EditorToolbar/ToolbarButton.tsx:
--------------------------------------------------------------------------------
1 | import { Command } from 'gg-editor';
2 | import React from 'react';
3 | import { Tooltip } from 'antd';
4 | import IconFont from '../../common/IconFont';
5 | import styles from './index.less';
6 |
7 | const upperFirst = (str: string) =>
8 | str.toLowerCase().replace(/( |^)[a-z]/g, (l: string) => l.toUpperCase());
9 |
10 | interface ToolbarButtonProps {
11 | command: string;
12 | icon?: string;
13 | text?: string;
14 | }
15 | const ToolbarButton: React.FC = (props) => {
16 | const { command, icon, text } = props;
17 |
18 | return (
19 |
20 |
25 |
26 |
27 |
28 | );
29 | };
30 |
31 | export default ToolbarButton;
32 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/mind/components/EditorToolbar/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .toolbar {
4 | display: flex;
5 | align-items: center;
6 |
7 | :global {
8 | .command .anticon {
9 | display: inline-block;
10 | width: 27px;
11 | height: 27px;
12 | margin: 0 6px;
13 | padding-top: 6px;
14 | text-align: center;
15 | cursor: pointer;
16 |
17 | &:hover {
18 | border: 1px solid @item-active-bg;
19 | }
20 | }
21 |
22 | .disable .anticon {
23 | color: @text-color-secondary;
24 | cursor: auto;
25 |
26 | &:hover {
27 | border: 1px solid @border-color-base;
28 | }
29 | }
30 | }
31 | }
32 |
33 | .tooltip {
34 | :global {
35 | .ant-tooltip-inner {
36 | font-size: 12px;
37 | border-radius: 0;
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/mind/components/EditorToolbar/index.tsx:
--------------------------------------------------------------------------------
1 | import FlowToolbar from './FlowToolbar';
2 | import KoniToolbar from './KoniToolbar';
3 | import MindToolbar from './MindToolbar';
4 |
5 | export { FlowToolbar, MindToolbar, KoniToolbar };
6 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/mind/locales/en-US.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'editorandmind.description':
3 | 'The brain map is an effective graphical thinking tool for expressing divergent thinking. It is simple but effective and is a practical thinking tool',
4 | };
5 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/editor/mind/locales/zh-CN.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'editorandmind.description':
3 | '脑图是表达发散性思维的有效图形思维工具 ,它简单却又很有效,是一种实用性的思维工具',
4 | };
5 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/exception/403/index.tsx:
--------------------------------------------------------------------------------
1 | import { Link } from 'umi';
2 | import { Result, Button } from 'antd';
3 | import React from 'react';
4 |
5 | export default () => (
6 |
15 |
16 |
17 | }
18 | />
19 | );
20 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/exception/404/index.tsx:
--------------------------------------------------------------------------------
1 | import { Link } from 'umi';
2 | import { Result, Button } from 'antd';
3 | import React from 'react';
4 |
5 | export default () => (
6 |
15 |
16 |
17 | }
18 | />
19 | );
20 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/exception/500/index.tsx:
--------------------------------------------------------------------------------
1 | import { Link } from 'umi';
2 | import { Result, Button } from 'antd';
3 | import React from 'react';
4 |
5 | export default () => (
6 |
15 |
16 |
17 | }
18 | />
19 | );
20 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/exception/500/locales/en-US.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'exceptionand500.exception.back': 'Back to home',
3 | 'exceptionand500.description.500': 'Sorry, the server is reporting an error.',
4 | };
5 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/exception/500/locales/pt-BR.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'exceptionand500.exception.back': 'Voltar para Início',
3 | 'exceptionand500.description.500': 'Desculpe, o servidor está reportando um erro.',
4 | };
5 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/exception/500/locales/zh-CN.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'exceptionand500.exception.back': '返回首页',
3 | 'exceptionand500.description.500': '抱歉,服务器出错了。',
4 | };
5 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/exception/500/locales/zh-TW.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'exceptionand500.exception.back': '返回首頁',
3 | 'exceptionand500.description.500': '抱歉,服務器出錯了。',
4 | };
5 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/form/advanced-form/_mock.ts:
--------------------------------------------------------------------------------
1 | // eslint-disable-next-line import/no-extraneous-dependencies
2 | import { Request, Response } from 'express';
3 |
4 | export default {
5 | 'POST /api/forms': (_: Request, res: Response) => {
6 | res.send({ message: 'Ok' });
7 | },
8 | };
9 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/form/advanced-form/model.ts:
--------------------------------------------------------------------------------
1 | import { Effect } from 'umi';
2 | import { message } from 'antd';
3 | import { fakeSubmitForm } from './service';
4 |
5 | export interface ModelType {
6 | namespace: string;
7 | state: {};
8 | effects: {
9 | submitAdvancedForm: Effect;
10 | };
11 | }
12 |
13 | const Model: ModelType = {
14 | namespace: 'formAndadvancedForm',
15 |
16 | state: {},
17 |
18 | effects: {
19 | *submitAdvancedForm({ payload }, { call }) {
20 | yield call(fakeSubmitForm, payload);
21 | message.success('提交成功');
22 | },
23 | },
24 | };
25 |
26 | export default Model;
27 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/form/advanced-form/service.ts:
--------------------------------------------------------------------------------
1 | import request from 'umi-request';
2 |
3 | export async function fakeSubmitForm(params: any) {
4 | return request('/api/forms', {
5 | method: 'POST',
6 | data: params,
7 | });
8 | }
9 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/form/basic-form/_mock.ts:
--------------------------------------------------------------------------------
1 | // eslint-disable-next-line import/no-extraneous-dependencies
2 | import { Request, Response } from 'express';
3 |
4 | export default {
5 | 'POST /api/forms': (_: Request, res: Response) => {
6 | res.send({ message: 'Ok' });
7 | },
8 | };
9 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/form/basic-form/model.ts:
--------------------------------------------------------------------------------
1 | import { Effect } from 'umi';
2 | import { message } from 'antd';
3 | import { fakeSubmitForm } from './service';
4 |
5 | export interface ModelType {
6 | namespace: string;
7 | state: {};
8 | effects: {
9 | submitRegularForm: Effect;
10 | };
11 | }
12 | const Model: ModelType = {
13 | namespace: 'formAndbasicForm',
14 |
15 | state: {},
16 |
17 | effects: {
18 | *submitRegularForm({ payload }, { call }) {
19 | yield call(fakeSubmitForm, payload);
20 | message.success('提交成功');
21 | },
22 | },
23 | };
24 |
25 | export default Model;
26 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/form/basic-form/service.ts:
--------------------------------------------------------------------------------
1 | import request from 'umi-request';
2 |
3 | export async function fakeSubmitForm(params: any) {
4 | return request('/api/forms', {
5 | method: 'POST',
6 | data: params,
7 | });
8 | }
9 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/form/step-form/_mock.ts:
--------------------------------------------------------------------------------
1 | // eslint-disable-next-line import/no-extraneous-dependencies
2 | import { Request, Response } from 'express';
3 |
4 | export default {
5 | 'POST /api/forms': (_: Request, res: Response) => {
6 | res.send({ message: 'Ok' });
7 | },
8 | };
9 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/form/step-form/service.ts:
--------------------------------------------------------------------------------
1 | import request from 'umi-request';
2 |
3 | export async function fakeSubmitForm(params: any) {
4 | return request('/api/forms', {
5 | method: 'POST',
6 | data: params,
7 | });
8 | }
9 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/list/basic-list/data.d.ts:
--------------------------------------------------------------------------------
1 | export interface Member {
2 | avatar: string;
3 | name: string;
4 | id: string;
5 | }
6 |
7 | export interface BasicListItemDataType {
8 | id: string;
9 | owner: string;
10 | title: string;
11 | avatar: string;
12 | cover: string;
13 | status: 'normal' | 'exception' | 'active' | 'success';
14 | percent: number;
15 | logo: string;
16 | href: string;
17 | body?: any;
18 | updatedAt: number;
19 | createdAt: number;
20 | subDescription: string;
21 | description: string;
22 | activeUser: number;
23 | newUser: number;
24 | star: number;
25 | like: number;
26 | message: number;
27 | content: string;
28 | members: Member[];
29 | }
30 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/list/card-list/data.d.ts:
--------------------------------------------------------------------------------
1 | export interface Member {
2 | avatar: string;
3 | name: string;
4 | id: string;
5 | }
6 |
7 | export interface CardListItemDataType {
8 | id: string;
9 | owner: string;
10 | title: string;
11 | avatar: string;
12 | cover: string;
13 | status: 'normal' | 'exception' | 'active' | 'success';
14 | percent: number;
15 | logo: string;
16 | href: string;
17 | body?: any;
18 | updatedAt: number;
19 | createdAt: number;
20 | subDescription: string;
21 | description: string;
22 | activeUser: number;
23 | newUser: number;
24 | star: number;
25 | like: number;
26 | message: number;
27 | content: string;
28 | members: Member[];
29 | }
30 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/list/card-list/service.ts:
--------------------------------------------------------------------------------
1 | import request from 'umi-request';
2 |
3 | export async function queryFakeList(params: { count: number }) {
4 | return request('/api/fake_list', {
5 | params,
6 | });
7 | }
8 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/list/search/applications/components/TagSelect/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .tagSelect {
4 | position: relative;
5 | max-height: 32px;
6 | margin-left: -8px;
7 | overflow: hidden;
8 | line-height: 32px;
9 | transition: all 0.3s;
10 | user-select: none;
11 | :global {
12 | .ant-tag {
13 | margin-right: 24px;
14 | padding: 0 8px;
15 | font-size: @font-size-base;
16 | }
17 | }
18 | &.expanded {
19 | max-height: 200px;
20 | transition: all 0.3s;
21 | }
22 | .trigger {
23 | position: absolute;
24 | top: 0;
25 | right: 0;
26 |
27 | span.anticon {
28 | font-size: 12px;
29 | }
30 | }
31 | &.hasExpandTag {
32 | padding-right: 50px;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/list/search/applications/data.d.ts:
--------------------------------------------------------------------------------
1 | export interface Member {
2 | avatar: string;
3 | name: string;
4 | id: string;
5 | }
6 |
7 | export interface ListItemDataType {
8 | id: string;
9 | owner: string;
10 | title: string;
11 | avatar: string;
12 | cover: string;
13 | status: 'normal' | 'exception' | 'active' | 'success';
14 | percent: number;
15 | logo: string;
16 | href: string;
17 | body?: any;
18 | updatedAt: number;
19 | createdAt: number;
20 | subDescription: string;
21 | description: string;
22 | activeUser: number;
23 | newUser: number;
24 | star: number;
25 | like: number;
26 | message: number;
27 | content: string;
28 | members: Member[];
29 | }
30 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/list/search/applications/service.ts:
--------------------------------------------------------------------------------
1 | import request from 'umi-request';
2 | import { ListItemDataType } from './data.d';
3 |
4 | export async function queryFakeList(params: ListItemDataType) {
5 | return request('/api/fake_list', {
6 | params,
7 | });
8 | }
9 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/list/search/articles/components/ArticleListContent/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .listContent {
4 | .description {
5 | max-width: 720px;
6 | line-height: 22px;
7 | }
8 | .extra {
9 | margin-top: 16px;
10 | color: @text-color-secondary;
11 | line-height: 22px;
12 | & > :global(.ant-avatar) {
13 | position: relative;
14 | top: 1px;
15 | width: 20px;
16 | height: 20px;
17 | margin-right: 8px;
18 | vertical-align: top;
19 | }
20 | & > em {
21 | margin-left: 16px;
22 | color: @disabled-color;
23 | font-style: normal;
24 | }
25 | }
26 | }
27 |
28 | @media screen and (max-width: @screen-xs) {
29 | .listContent {
30 | .extra {
31 | & > em {
32 | display: block;
33 | margin-top: 8px;
34 | margin-left: 0;
35 | }
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/list/search/articles/components/ArticleListContent/index.tsx:
--------------------------------------------------------------------------------
1 | import { Avatar } from 'antd';
2 | import React from 'react';
3 | import moment from 'moment';
4 | import styles from './index.less';
5 |
6 | interface ArticleListContentProps {
7 | data: {
8 | content: React.ReactNode;
9 | updatedAt: number;
10 | avatar: string;
11 | owner: string;
12 | href: string;
13 | };
14 | }
15 |
16 | const ArticleListContent: React.FC = ({
17 | data: { content, updatedAt, avatar, owner, href },
18 | }) => (
19 |
20 |
{content}
21 |
22 |
23 |
{owner} 发布在
{href}
24 |
{moment(updatedAt).format('YYYY-MM-DD HH:mm')}
25 |
26 |
27 | );
28 |
29 | export default ArticleListContent;
30 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/list/search/articles/components/TagSelect/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .tagSelect {
4 | position: relative;
5 | max-height: 32px;
6 | margin-left: -8px;
7 | overflow: hidden;
8 | line-height: 32px;
9 | transition: all 0.3s;
10 | user-select: none;
11 | :global {
12 | .ant-tag {
13 | margin-right: 24px;
14 | padding: 0 8px;
15 | font-size: @font-size-base;
16 | }
17 | }
18 | &.expanded {
19 | max-height: 200px;
20 | transition: all 0.3s;
21 | }
22 | .trigger {
23 | position: absolute;
24 | top: 0;
25 | right: 0;
26 | span.anticon {
27 | font-size: 12px;
28 | }
29 | }
30 | &.hasExpandTag {
31 | padding-right: 50px;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/list/search/articles/data.d.ts:
--------------------------------------------------------------------------------
1 | export interface Member {
2 | avatar: string;
3 | name: string;
4 | id: string;
5 | }
6 |
7 | export interface ListItemDataType {
8 | id: string;
9 | owner: string;
10 | title: string;
11 | avatar: string;
12 | cover: string;
13 | status: 'normal' | 'exception' | 'active' | 'success';
14 | percent: number;
15 | logo: string;
16 | href: string;
17 | body?: any;
18 | updatedAt: number;
19 | createdAt: number;
20 | subDescription: string;
21 | description: string;
22 | activeUser: number;
23 | newUser: number;
24 | star: number;
25 | like: number;
26 | message: number;
27 | content: string;
28 | members: Member[];
29 | }
30 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/list/search/articles/service.ts:
--------------------------------------------------------------------------------
1 | import request from 'umi-request';
2 | import { ListItemDataType } from './data.d';
3 |
4 | export async function queryFakeList(params: ListItemDataType) {
5 | return request('/api/fake_list', {
6 | params,
7 | });
8 | }
9 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/list/search/articles/style.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | a.listItemMetaTitle {
4 | color: @heading-color;
5 | }
6 | .listItemExtra {
7 | width: 272px;
8 | height: 1px;
9 | }
10 | .selfTrigger {
11 | margin-left: 12px;
12 | }
13 |
14 | @media screen and (max-width: @screen-xs) {
15 | .selfTrigger {
16 | display: block;
17 | margin-left: 0;
18 | }
19 | }
20 | @media screen and (max-width: @screen-md) {
21 | .selfTrigger {
22 | display: block;
23 | margin-left: 0;
24 | }
25 | }
26 | @media screen and (max-width: @screen-lg) {
27 | .listItemExtra {
28 | width: 0;
29 | height: 1px;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/list/search/projects/components/TagSelect/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .tagSelect {
4 | position: relative;
5 | max-height: 32px;
6 | margin-left: -8px;
7 | overflow: hidden;
8 | line-height: 32px;
9 | transition: all 0.3s;
10 | user-select: none;
11 | :global {
12 | .ant-tag {
13 | margin-right: 24px;
14 | padding: 0 8px;
15 | font-size: @font-size-base;
16 | }
17 | }
18 | &.expanded {
19 | max-height: 200px;
20 | transition: all 0.3s;
21 | }
22 | .trigger {
23 | position: absolute;
24 | top: 0;
25 | right: 0;
26 | span.anticon {
27 | font-size: 12px;
28 | }
29 | }
30 | &.hasExpandTag {
31 | padding-right: 50px;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/list/search/projects/data.d.ts:
--------------------------------------------------------------------------------
1 | export interface Member {
2 | avatar: string;
3 | name: string;
4 | id: string;
5 | }
6 |
7 | export interface ListItemDataType {
8 | id: string;
9 | owner: string;
10 | title: string;
11 | avatar: string;
12 | cover: string;
13 | status: 'normal' | 'exception' | 'active' | 'success';
14 | percent: number;
15 | logo: string;
16 | href: string;
17 | body?: any;
18 | updatedAt: number;
19 | createdAt: number;
20 | subDescription: string;
21 | description: string;
22 | activeUser: number;
23 | newUser: number;
24 | star: number;
25 | like: number;
26 | message: number;
27 | content: string;
28 | members: Member[];
29 | }
30 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/list/search/projects/service.ts:
--------------------------------------------------------------------------------
1 | import request from 'umi-request';
2 |
3 | export async function queryFakeList(params: { count: number }) {
4 | return request('/api/fake_list', {
5 | params,
6 | });
7 | }
8 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/list/table-list/components/CreateForm.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Modal } from 'antd';
3 |
4 | interface CreateFormProps {
5 | modalVisible: boolean;
6 | onCancel: () => void;
7 | }
8 |
9 | const CreateForm: React.FC = (props) => {
10 | const { modalVisible, onCancel } = props;
11 |
12 | return (
13 | onCancel()}
18 | footer={null}
19 | >
20 | {props.children}
21 |
22 | );
23 | };
24 |
25 | export default CreateForm;
26 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/list/table-list/data.d.ts:
--------------------------------------------------------------------------------
1 | export interface TableListItem {
2 | key: number;
3 | disabled?: boolean;
4 | href: string;
5 | avatar: string;
6 | name: string;
7 | owner: string;
8 | desc: string;
9 | callNo: number;
10 | status: string;
11 | updatedAt: Date;
12 | createdAt: Date;
13 | progress: number;
14 | }
15 |
16 | export interface TableListPagination {
17 | total: number;
18 | pageSize: number;
19 | current: number;
20 | }
21 |
22 | export interface TableListData {
23 | list: TableListItem[];
24 | pagination: Partial;
25 | }
26 |
27 | export interface TableListParams {
28 | status?: string;
29 | name?: string;
30 | desc?: string;
31 | key?: number;
32 | pageSize?: number;
33 | currentPage?: number;
34 | filter?: { [key: string]: any[] };
35 | sorter?: { [key: string]: any };
36 | }
37 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/list/table-list/service.ts:
--------------------------------------------------------------------------------
1 | import request from 'umi-request';
2 | import { TableListParams } from './data.d';
3 |
4 | export async function queryRule(params?: TableListParams) {
5 | return request('/api/rule', {
6 | params,
7 | });
8 | }
9 |
10 | export async function removeRule(params: { key: number[] }) {
11 | return request('/api/rule', {
12 | method: 'POST',
13 | data: {
14 | ...params,
15 | method: 'delete',
16 | },
17 | });
18 | }
19 |
20 | export async function addRule(params: TableListParams) {
21 | return request('/api/rule', {
22 | method: 'POST',
23 | data: {
24 | ...params,
25 | method: 'post',
26 | },
27 | });
28 | }
29 |
30 | export async function updateRule(params: TableListParams) {
31 | return request('/api/rule', {
32 | method: 'POST',
33 | data: {
34 | ...params,
35 | method: 'update',
36 | },
37 | });
38 | }
39 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/profile/advanced/data.d.ts:
--------------------------------------------------------------------------------
1 | export interface AdvancedOperation1 {
2 | key: string;
3 | type: string;
4 | name: string;
5 | status: string;
6 | updatedAt: string;
7 | memo: string;
8 | }
9 |
10 | export interface AdvancedOperation2 {
11 | key: string;
12 | type: string;
13 | name: string;
14 | status: string;
15 | updatedAt: string;
16 | memo: string;
17 | }
18 |
19 | export interface AdvancedOperation3 {
20 | key: string;
21 | type: string;
22 | name: string;
23 | status: string;
24 | updatedAt: string;
25 | memo: string;
26 | }
27 |
28 | export interface AdvancedProfileData {
29 | advancedOperation1: AdvancedOperation1[];
30 | advancedOperation2: AdvancedOperation2[];
31 | advancedOperation3: AdvancedOperation3[];
32 | }
33 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/profile/advanced/service.ts:
--------------------------------------------------------------------------------
1 | import request from 'umi-request';
2 |
3 | export async function queryAdvancedProfile() {
4 | return request('/api/profile/advanced');
5 | }
6 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/profile/basic/data.d.ts:
--------------------------------------------------------------------------------
1 | export interface BasicGood {
2 | id: string;
3 | name?: string;
4 | barcode?: string;
5 | price?: string;
6 | num?: string | number;
7 | amount?: string | number;
8 | }
9 |
10 | export interface BasicProgress {
11 | key: string;
12 | time: string;
13 | rate: string;
14 | status: string;
15 | operator: string;
16 | cost: string;
17 | }
18 |
19 | export interface BasicProfileDataType {
20 | basicGoods: BasicGood[];
21 | basicProgress: BasicProgress[];
22 | }
23 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/profile/basic/model.ts:
--------------------------------------------------------------------------------
1 | import { Effect, Reducer } from 'umi';
2 |
3 | import { BasicGood } from './data.d';
4 | import { queryBasicProfile } from './service';
5 |
6 | export interface StateType {
7 | basicGoods: BasicGood[];
8 | }
9 |
10 | export interface ModelType {
11 | namespace: string;
12 | state: StateType;
13 | effects: {
14 | fetchBasic: Effect;
15 | };
16 | reducers: {
17 | show: Reducer;
18 | };
19 | }
20 |
21 | const Model: ModelType = {
22 | namespace: 'profileAndbasic',
23 |
24 | state: {
25 | basicGoods: [],
26 | },
27 |
28 | effects: {
29 | *fetchBasic(_, { call, put }) {
30 | const response = yield call(queryBasicProfile);
31 | yield put({
32 | type: 'show',
33 | payload: response,
34 | });
35 | },
36 | },
37 |
38 | reducers: {
39 | show(state, { payload }) {
40 | return {
41 | ...state,
42 | ...payload,
43 | };
44 | },
45 | },
46 | };
47 |
48 | export default Model;
49 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/profile/basic/service.ts:
--------------------------------------------------------------------------------
1 | import request from 'umi-request';
2 |
3 | export async function queryBasicProfile() {
4 | return request('/api/profile/basic');
5 | }
6 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/profile/basic/style.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .title {
4 | margin-bottom: 16px;
5 | color: @heading-color;
6 | font-weight: 500;
7 | font-size: 16px;
8 | }
9 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/result/fail/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .error_icon {
4 | color: @highlight-color;
5 | }
6 | .title {
7 | margin-bottom: 16px;
8 | color: @heading-color;
9 | font-weight: 500;
10 | font-size: 16px;
11 | }
12 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/result/fail/locales/en-US.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'resultandfail.error.title': 'Submission Failed',
3 | 'resultandfail.error.description':
4 | 'Please check and modify the following information before resubmitting.',
5 | 'resultandfail.error.hint-title': 'The content you submitted has the following error:',
6 | 'resultandfail.error.hint-text1': 'Your account has been frozen',
7 | 'resultandfail.error.hint-btn1': 'Thaw immediately',
8 | 'resultandfail.error.hint-text2': 'Your account is not yet eligible to apply',
9 | 'resultandfail.error.hint-btn2': 'Upgrade immediately',
10 | 'resultandfail.error.btn-text': 'Return to modify',
11 | };
12 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/result/fail/locales/zh-CN.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'resultandfail.error.title': '提交失败',
3 | 'resultandfail.error.description': '请核对并修改以下信息后,再重新提交。',
4 | 'resultandfail.error.hint-title': '您提交的内容有如下错误:',
5 | 'resultandfail.error.hint-text1': '您的账户已被冻结',
6 | 'resultandfail.error.hint-btn1': '立即解冻',
7 | 'resultandfail.error.hint-text2': '您的账户还不具备申请资格',
8 | 'resultandfail.error.hint-btn2': '立即升级',
9 | 'resultandfail.error.btn-text': '返回修改',
10 | };
11 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/result/fail/locales/zh-TW.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'resultandfail.error.title': '提交失敗',
3 | 'resultandfail.error.description': '請核對並修改以下信息後,再重新提交。',
4 | 'resultandfail.error.hint-title': '您提交的內容有如下錯誤:',
5 | 'resultandfail.error.hint-text1': '您的賬戶已被凍結',
6 | 'resultandfail.error.hint-btn1': '立即解凍',
7 | 'resultandfail.error.hint-text2': '您的賬戶還不具備申請資格',
8 | 'resultandfail.error.hint-btn2': '立即升級',
9 | 'resultandfail.error.btn-text': '返回修改',
10 | };
11 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/result/success/index.less:
--------------------------------------------------------------------------------
1 | @import '~antd/es/style/themes/default.less';
2 |
3 | .title {
4 | position: relative;
5 | color: @text-color;
6 | font-size: 12px;
7 | text-align: center;
8 | }
9 |
10 | .head-title {
11 | margin-bottom: 20px;
12 | color: @heading-color;
13 | font-weight: 500px;
14 | font-size: 16px;
15 | }
16 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/result/success/locales/zh-CN.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'resultandsuccess.success.title': '提交成功',
3 | 'resultandsuccess.success.description':
4 | '提交结果页用于反馈一系列操作任务的处理结果, 如果仅是简单操作,使用 Message 全局提示反馈即可。 本文字区域可以展示简单的补充说明,如果有类似展示 “单据”的需求,下面这个灰色区域可以呈现比较复杂的内容。',
5 | 'resultandsuccess.success.operate-title': '项目名称',
6 | 'resultandsuccess.success.operate-id': '项目 ID',
7 | 'resultandsuccess.success.principal': '负责人',
8 | 'resultandsuccess.success.operate-time': '生效时间',
9 | 'resultandsuccess.success.step1-title': '创建项目',
10 | 'resultandsuccess.success.step1-operator': '曲丽丽',
11 | 'resultandsuccess.success.step2-title': '部门初审',
12 | 'resultandsuccess.success.step2-operator': '周毛毛',
13 | 'resultandsuccess.success.step2-extra': '催一下',
14 | 'resultandsuccess.success.step3-title': '财务复核',
15 | 'resultandsuccess.success.step4-title': '完成',
16 | 'resultandsuccess.success.btn-return': '返回列表',
17 | 'resultandsuccess.success.btn-project': '查看项目',
18 | 'resultandsuccess.success.btn-print': '打印',
19 | };
20 |
--------------------------------------------------------------------------------
/7.4admin/src/pages/result/success/locales/zh-TW.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'resultandsuccess.success.title': '提交成功',
3 | 'resultandsuccess.success.description':
4 | '提交結果頁用於反饋壹系列操作任務的處理結果, 如果僅是簡單操作,使用 Message 全局提示反饋即可。 本文字區域可以展示簡單的補充說明,如果有類似展示 “單據”的需求,下面這個灰色區域可以呈現比較復雜的內容。',
5 | 'resultandsuccess.success.operate-title': '項目名稱',
6 | 'resultandsuccess.success.operate-id': '項目 ID',
7 | 'resultandsuccess.success.principal': '負責人',
8 | 'resultandsuccess.success.operate-time': '生效時間',
9 | 'resultandsuccess.success.step1-title': '創建項目',
10 | 'resultandsuccess.success.step1-operator': '曲麗麗',
11 | 'resultandsuccess.success.step2-title': '部門初審',
12 | 'resultandsuccess.success.step2-operator': '周毛毛',
13 | 'resultandsuccess.success.step2-extra': '催壹下',
14 | 'resultandsuccess.success.step3-title': '財務復核',
15 | 'resultandsuccess.success.step4-title': '完成',
16 | 'resultandsuccess.success.btn-return': '返回列表',
17 | 'resultandsuccess.success.btn-project': '查看項目',
18 | 'resultandsuccess.success.btn-print': '打印',
19 | };
20 |
--------------------------------------------------------------------------------
/7.4admin/src/services/login.ts:
--------------------------------------------------------------------------------
1 | import request from '@/utils/request';
2 |
3 | export type LoginParamsType = {
4 | userName: string;
5 | password: string;
6 | mobile: string;
7 | captcha: string;
8 | };
9 |
10 | export async function fakeAccountLogin(params: LoginParamsType) {
11 | return request('/api/login/account', {
12 | method: 'POST',
13 | data: params,
14 | });
15 | }
16 |
17 | export async function getFakeCaptcha(mobile: string) {
18 | return request(`/api/login/captcha?mobile=${mobile}`);
19 | }
20 |
--------------------------------------------------------------------------------
/7.4admin/src/services/user.ts:
--------------------------------------------------------------------------------
1 | import request from '@/utils/request';
2 |
3 | export async function query(): Promise {
4 | return request('/api/users');
5 | }
6 |
7 | export async function queryCurrent(): Promise {
8 | return request('/api/currentUser');
9 | }
10 |
11 | export async function queryNotices(): Promise {
12 | return request('/api/notices');
13 | }
14 |
--------------------------------------------------------------------------------
/7.4admin/src/utils/Authorized.ts:
--------------------------------------------------------------------------------
1 | import RenderAuthorize from '@/components/Authorized';
2 | import { getAuthority } from './authority';
3 | /* eslint-disable eslint-comments/disable-enable-pair */
4 | /* eslint-disable import/no-mutable-exports */
5 | let Authorized = RenderAuthorize(getAuthority());
6 |
7 | // Reload the rights component
8 | const reloadAuthorized = (): void => {
9 | Authorized = RenderAuthorize(getAuthority());
10 | };
11 |
12 | /**
13 | * hard code
14 | * block need it。
15 | */
16 | window.reloadAuthorized = reloadAuthorized;
17 |
18 | export { reloadAuthorized };
19 | export default Authorized;
20 |
--------------------------------------------------------------------------------
/7.4admin/src/utils/utils.less:
--------------------------------------------------------------------------------
1 | // mixins for clearfix
2 | // ------------------------
3 | .clearfix() {
4 | zoom: 1;
5 | &::before,
6 | &::after {
7 | display: table;
8 | content: ' ';
9 | }
10 | &::after {
11 | clear: both;
12 | height: 0;
13 | font-size: 0;
14 | visibility: hidden;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/7.4admin/src/utils/utils.ts:
--------------------------------------------------------------------------------
1 | import { parse } from 'querystring';
2 |
3 | /* eslint no-useless-escape:0 import/prefer-default-export:0 */
4 | const reg = /(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/;
5 |
6 | export const isUrl = (path: string): boolean => reg.test(path);
7 |
8 | export const isAntDesignPro = (): boolean => {
9 | if (ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION === 'site') {
10 | return true;
11 | }
12 | return window.location.hostname === 'preview.pro.ant.design';
13 | };
14 |
15 | // 给官方演示站点用,用于关闭真实开发环境不需要使用的特性
16 | export const isAntDesignProOrDev = (): boolean => {
17 | const { NODE_ENV } = process.env;
18 | if (NODE_ENV === 'development') {
19 | return true;
20 | }
21 | return isAntDesignPro();
22 | };
23 |
24 | export const getPageQuery = () => parse(window.location.href.split('?')[1]);
25 |
--------------------------------------------------------------------------------
/other/demo01.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | DOM 渲染是否异步
7 |
8 |
9 |
10 | 默认文本
11 |
26 |
27 |
--------------------------------------------------------------------------------