├── .gitignore ├── .npmrc ├── .prettierignore ├── .prettierrc.js ├── README.md ├── build.sh ├── config ├── config.js ├── proxy.config.js ├── routes.config.js ├── routes │ └── base.js └── webpack.config.js ├── declaration.d.ts ├── doc ├── archImage.html └── img │ ├── arch.png │ ├── demo.jpg │ ├── demo.png │ └── demo_doc_1.png ├── mock ├── .gitkeep └── api │ ├── demo.js │ ├── globalInfo.js │ ├── map │ └── line.js │ ├── orderList.js │ └── users.js ├── nginx ├── demo-ui.conf └── demo-upstream.conf ├── package-lock.json ├── package.json ├── public ├── iconfont │ ├── iconfont.css │ ├── iconfont.woff │ └── original │ │ ├── demo.css │ │ ├── demo_index.html │ │ ├── iconfont.css │ │ ├── iconfont.eot │ │ ├── iconfont.js │ │ ├── iconfont.svg │ │ ├── iconfont.ttf │ │ ├── iconfont.woff │ │ └── iconfont.woff2 └── img │ ├── favicon.png │ └── logo.png ├── shell ├── analyze.sh ├── proxy.sh ├── removeCache.sh ├── start.sh └── tslint.sh ├── src ├── components │ ├── ChartComponent.tsx │ ├── Loading.tsx │ └── icon │ │ ├── Icon.less │ │ └── Icon.tsx ├── global.less ├── layouts │ ├── Index.conf.ts │ ├── Index.less │ ├── Index.tsx │ └── navBar │ │ ├── NavBar.less │ │ ├── NavBar.tsx │ │ └── NavBarConfig.ts ├── models │ └── Global.ts ├── pages │ ├── 404.tsx │ ├── Index.less │ ├── Index.tsx │ ├── document.ejs │ ├── empty │ │ └── views │ │ │ ├── Empty.less │ │ │ └── Empty.tsx │ ├── forbidden │ │ └── views │ │ │ ├── Forbidden.less │ │ │ └── Forbidden.tsx │ ├── login │ │ └── views │ │ │ ├── Login.less │ │ │ ├── Login.tsx │ │ │ └── img │ │ │ └── bg_1.jpg │ ├── orderList │ │ ├── models │ │ │ └── OrderList.ts │ │ ├── services │ │ │ └── OrderList.ts │ │ └── views │ │ │ ├── OrderList.less │ │ │ ├── OrderList.tsx │ │ │ ├── img │ │ │ └── product1.jpg │ │ │ └── util │ │ │ ├── OrderDelete.tsx │ │ │ ├── OrderEvaluate.tsx │ │ │ └── OrderRebuy.tsx │ ├── register │ │ └── views │ │ │ ├── Register.agree.tsx │ │ │ ├── Register.less │ │ │ ├── Register.tsx │ │ │ └── img │ │ │ └── bg_1.jpg │ ├── setting │ │ ├── img │ │ │ └── photo.jpg │ │ └── views │ │ │ ├── Setting.less │ │ │ ├── Setting.tsx │ │ │ ├── info │ │ │ ├── Info.less │ │ │ └── Info.tsx │ │ │ └── util │ │ │ └── LoginOut.tsx │ ├── shoppingCar │ │ ├── models │ │ │ └── ShoppingCar.ts │ │ ├── services │ │ │ └── ShoppingCar.ts │ │ └── views │ │ │ ├── ShoppingCar.less │ │ │ ├── ShoppingCar.tsx │ │ │ ├── img │ │ │ └── product1.jpg │ │ │ └── util │ │ │ ├── ScarClean.tsx │ │ │ ├── ScarDelete.tsx │ │ │ └── ScarPay.tsx │ └── welcome │ │ ├── Welcome.less │ │ ├── Welcome.tsx │ │ ├── banner │ │ ├── Banner.less │ │ ├── Banner.tsx │ │ ├── BannerConfig.ts │ │ └── image │ │ │ ├── banner1.jpg │ │ │ ├── banner2.jpg │ │ │ └── banner3.jpg │ │ ├── chart │ │ ├── Chart.less │ │ ├── Chart.tsx │ │ └── EchartOption.ts │ │ ├── product │ │ ├── Product.less │ │ ├── Product.tsx │ │ └── img │ │ │ ├── product1.jpg │ │ │ └── product2.jpg │ │ └── quick │ │ ├── Quick.conf.ts │ │ ├── Quick.less │ │ └── Quick.tsx └── utils │ ├── GlobalInterface.ts │ └── Request.ts ├── tsconfig.json └── tslint.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Node template 3 | # Logs 4 | logs 5 | *.log 6 | npm-debug.log* 7 | yarn-debug.log* 8 | yarn-error.log* 9 | yarn.lock 10 | 11 | # Runtime data 12 | pids 13 | *.pid 14 | *.seed 15 | *.pid.lock 16 | 17 | # Directory for instrumented libs generated by jscoverage/JSCover 18 | lib-cov 19 | 20 | # Coverage directory used by tools like istanbul 21 | coverage 22 | 23 | # nyc test coverage 24 | .nyc_output 25 | 26 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 27 | .grunt 28 | 29 | # Bower dependency directory (https://bower.io/) 30 | bower_components 31 | 32 | # node-waf configuration 33 | .lock-wscript 34 | 35 | # Dependency directories 36 | build/Release 37 | node_modules/ 38 | jspm_packages/ 39 | src/pages/.umi/ 40 | src/pages/.umi-production/ 41 | typings/ 42 | 43 | # Optional npm cache directory 44 | .npm 45 | 46 | # Optional eslint cache 47 | .eslintcache 48 | 49 | # Optional REPL history 50 | .node_repl_history 51 | 52 | # Output of 'npm pack' 53 | *.tgz 54 | 55 | # Yarn Integrity file 56 | .yarn-integrity 57 | 58 | # dotenv environment variables file 59 | .env 60 | 61 | # idea 62 | .idea/ 63 | .project 64 | 65 | # jest 66 | .jest/ 67 | 68 | .DS_Store 69 | 70 | dist 71 | output 72 | 73 | .cache 74 | .cache-loader/ 75 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | registry=https://registry.npm.taobao.org -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | *.log 3 | /build 4 | /built 5 | .DS_Store 6 | .reviewboardrc 7 | /rev 8 | /.vscode 9 | /.idea -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 格式化配置 3 | */ 4 | module.exports = { 5 | tabWidth: 4, 6 | singleQuote: true, 7 | arrowParens: 'always', 8 | semi: true, 9 | printWidth: 100, 10 | trailingComma: 'es5', 11 | trailingComma: 'none' 12 | }; 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### **开始前,请花几分钟了解以下信息** 2 | 3 | --- 4 | 5 | ```1、项目起步``` ```2、依赖安装``` ```3、启动本地项目``` ```4、构建生产文件``` 6 | 7 | ```5、shell命令示例``` ```6、参考文档``` ```7、一分钟科普``` ```8、Dva使用示例``` 8 | 9 | --- 10 | 11 | * 脚手架默认效果 PC版=>[点击可查看ReactForWeb](https://github.com/vaotoo/ReactForWeb) 12 | 13 | ![avatar](doc/img/demo.png) 14 | 15 | ```默认效果及功能``` 首页效果、菜单栏页、锚点页、列表页、数据可视化、二级页面、数据交互 16 | 17 | --- 18 | 19 | * 架构概况 20 | 21 | ![avatar](doc/img/arch.png) 22 | 23 | --- 24 | 25 | * 目录说明 26 | 27 | ![avatar](doc/img/demo_doc_1.png) 28 | 29 | --- 30 | 31 | * 1、项目起步 32 | 33 | * 环境说明 34 | 35 | * NPM(国内建议使用淘宝镜像)NodeJs > 7.x 36 | 37 | * 每次安装设置(临时使用) 38 | 39 | `npm i --registry=https://registry.npm.taobao.org` 40 | 41 | `npm i yourPackageName --registry=https://registry.npm.taobao.org` 42 | 43 | * 全局安装设置(长期使用) 44 | 45 | `npm config set registry https://registry.npm.taobao.org` 46 | 47 | * 查看npm源地址 48 | 49 | `npm config get registry` 50 | 51 | 52 | * 2、依赖安装 53 | 54 | * npm install 55 | 56 | 57 | * 3、启动本地项目 58 | 59 | * npm start 60 | 61 | 62 | * 4、构建生产文件 63 | 64 | * npm run build 65 | 66 | 67 | * 5、shell命令示例 68 | 69 | * 启动项目 ```sh shell/start.sh``` 70 | 71 | * 启用代理 ```sh shell/proxy.sh``` 72 | 73 | * 清除缓存 ```sh shell/removeCache.sh``` 74 | 75 | 76 | * 6、参考文档 77 | 78 | * ```React + Dva + Antd + Umi``` 79 | 80 | * [React](https://reactjs.org/) 81 | 82 | * [React Router](http://react-guide.github.io/react-router-cn/index.html) 83 | 84 | * [DvaJs](https://dvajs.com/guide/introduce-class.html) 85 | 86 | * [Redux](https://www.redux.org.cn/) 87 | 88 | * [Redux-saga](https://redux-saga-in-chinese.js.org/) 89 | 90 | * [AntDesign](https://ant.design/) 91 | 92 | * [UmiJs](https://umijs.org/zh/guide/) 93 | 94 | * [TypeScript](https://www.tslang.cn/) 95 | 96 | * [TSConfig](https://www.tslang.cn/docs/handbook/tsconfig-json.html) 97 | 98 | * [TSLint](https://palantir.github.io/tslint/usage/configuration/) 99 | 100 | * [TSLint-React](https://www.npmjs.com/package/tslint-react) 101 | 102 | 103 | * 7、一分钟科普 104 | 105 | * **React** 106 | 107 | React是一个为数据提供渲染为HTML视图的开源JavaScript 库。React视图通常采用包含以自定义HTML标记规定的其他组件的组件渲染。React为程序员提供了一种子组件不能直接影响外层组件的模型,数据改变时对HTML文档的有效更新,和现代单页应用中组件之间干净的分离。 108 | 109 | * **React-Router** 110 | 111 | React Router 是一个基于 React 之上的强大路由库,它可以让你向应用中快速地添加视图和数据流,同时保持页面与URL间的同步。 112 | 113 | * **Dva** 114 | 115 | Dva首先是一个基于 redux 和 redux-saga 的数据流方案,然后为了简化开发体验,dva 还额外内置了react-router 和 fetch,所以也可以理解为一个轻量级的应用框架。 116 | 117 | * **Redux** 118 | 119 | Redux 是 JavaScript 状态容器,提供可预测化的状态管理。可以让你构建一致化的应用,运行于不同的环境(客户端、服务器、原生应用),并且易于测试。 120 | 121 | * **Redux-saga** 122 | 123 | Redux-saga 是一个用于管理应用程序 Side Effect(副作用,例如异步获取数据,访问浏览器缓存等)的 library,它的目标是让副作用管理更容易,执行更高效,测试更简单,在处理故障时更容易。 124 | 125 | * **TypeScript** 126 | 127 | TypeScript是一种由微软开发的自由和开源的编程语言。它是JavaScript的一个严格超集,并添加了可选的静态类型和基于类的面向对象编程。C#的首席架构师以及Delphi和Turbo Pascal的创始人安德斯·海尔斯伯格参与了TypeScript的开发。 128 | 129 | * **Ant Design** 130 | 131 | Ant Design是阿里巴巴(蚂蚁金服体验技术部)经过大量的项目实践和总结,逐步打磨出一个服务于企业级产品的设计体系。基于『确定』和『自然』的设计价值观,通过模块化的解决方案,降低冗余的生产成本,让设计者专注于更好的用户体验。 132 | 133 | * **UmiJs** 134 | 135 | Umi 是阿里巴巴蚂蚁金服的底层前端框架,是一个可插拔的企业级 react 应用框架。Umi 以路由为基础的,支持类 next.js 的约定式路由,以及各种进阶的路由功能,并以此进行功能扩展,比如支持路由级的按需加载。然后配以完善的插件体系,覆盖从源码到构建产物的每个生命周期,支持各种功能扩展和业务需求,目前内外部加起来已有 50+ 的插件。 136 | 137 | 138 | * 8、Dva使用示例 139 | 140 | 请参考[ReactForWeb中的说明](https://github.com/vaotoo/ReactForWeb) 141 | 142 | 143 | ```注意``` models/global.ts为全局数据,如非必要请勿加入过多数据,页面级数据请参照pages/menuExample中的示例 144 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | rm -rf dist 4 | rm -rf output 5 | 6 | mkdir output 7 | 8 | npm install 9 | npm run build 10 | 11 | mv dist output -------------------------------------------------------------------------------- /config/config.js: -------------------------------------------------------------------------------- 1 | import routesConfig from './routes.config'; 2 | import webpackConfig from './webpack.config'; 3 | import proxyConfig from './proxy.config'; 4 | 5 | export default Object.assign({ 6 | plugins: [ 7 | ['umi-plugin-react', { 8 | antd: true, 9 | fastClick: true, 10 | title: { 11 | defaultTitle: '请自行设置默认标题', 12 | separator: '-' 13 | }, 14 | dva: { 15 | immer: true 16 | }, 17 | dynamicImport: { 18 | webpackChunkName: true, 19 | loadingComponent: './components/Loading.tsx' 20 | } 21 | }] 22 | ] 23 | }, routesConfig, webpackConfig, proxyConfig); -------------------------------------------------------------------------------- /config/proxy.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | proxy: { 3 | '/api': { 4 | 'target': 'http://110.119.120.10/', 5 | 'changeOrigin': true, 6 | 'pathRewrite': { 7 | '^/api': '' 8 | } 9 | } 10 | } 11 | }; -------------------------------------------------------------------------------- /config/routes.config.js: -------------------------------------------------------------------------------- 1 | import baseRoutes from './routes/base'; 2 | 3 | export default { 4 | routes: [{ 5 | path: '/', 6 | component: '../layouts/index', 7 | routes: [ 8 | ...baseRoutes 9 | ] 10 | }] 11 | } -------------------------------------------------------------------------------- /config/routes/base.js: -------------------------------------------------------------------------------- 1 | export default [{ 2 | path: '/', 3 | component: 'index' 4 | }, { 5 | title: '访问异常', 6 | path: '/404', 7 | component: '404' 8 | }, { 9 | path: '/logout', 10 | redirect: '/' 11 | }, { 12 | title: '购物车', 13 | path: '/shoppingCar', 14 | component: 'shoppingCar/views/shoppingCar' 15 | }, { 16 | title: '订单列表', 17 | path: '/orderList', 18 | component: 'orderList/views/orderList' 19 | }, { 20 | title: '设置', 21 | path: '/setting', 22 | component: 'setting/views/setting' 23 | }, { 24 | title: '登录', 25 | path: '/login', 26 | component: 'login/views/login' 27 | }, { 28 | title: '注册', 29 | path: '/register', 30 | component: 'register/views/register' 31 | }, { 32 | title: '没有权限', 33 | path: '/forbidden', 34 | component: 'forbidden/views/Forbidden' 35 | }]; 36 | -------------------------------------------------------------------------------- /config/webpack.config.js: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | 3 | process.noDeprecation = true; 4 | 5 | const ROOT_PATH = path.resolve(__dirname, '../'); 6 | const NODE_PATH = path.resolve(ROOT_PATH, 'node_modules'); 7 | const GroupConf = (chunkName, regExpkey, isPages) => ({ 8 | name: chunkName, 9 | chunks: 'async', 10 | test: (module) => { 11 | const reg = new RegExp(`\/${isPages ? 'src\/pages' : 'node_modules'}\/${regExpkey}`); 12 | return reg.test(module.context); 13 | }, 14 | priority: 20, 15 | maxAsyncRequests: 10, 16 | maxInitialRequests: 10, 17 | reuseExistingChunk: true 18 | }); 19 | 20 | export default { 21 | hash: true, 22 | outputPath: '/dist/assets/', 23 | publicPath: '/assets/', 24 | urlLoaderExcludes: [/.svg$/], 25 | ignoreMomentLocale: true, 26 | chainWebpack(config) { 27 | config.merge({ 28 | optimization: { 29 | splitChunks: { 30 | chunks: 'async', 31 | minSize: 0, 32 | minChunks: 1, 33 | maxAsyncRequests: 10, 34 | maxInitialRequests: 10, 35 | cacheGroups: { 36 | antd: GroupConf('antd', 'antd\/'), 37 | antdm: GroupConf('antdm', 'antd-mobile'), 38 | antrc: GroupConf('antrc', 'rc-.*'), 39 | antrmc: GroupConf('antrmc', 'rmc-.*'), 40 | draft: GroupConf('draft', 'draft-js'), 41 | immutable: GroupConf('immutable', 'immutable'), 42 | corePlugs: GroupConf('corePlugs', '(zrender.*|lodash.*|moment)'), 43 | pages: GroupConf('pages', '[^fullScreen]', true) 44 | } 45 | } 46 | }, 47 | resolve: { 48 | alias: { 49 | '@utils': path.resolve(ROOT_PATH, 'src/utils'), 50 | '@pages': path.resolve(ROOT_PATH, 'src/pages'), 51 | '@components': path.resolve(ROOT_PATH, 'src/components'), 52 | '@globalModels': path.resolve(ROOT_PATH, 'src/models'), 53 | '@globalServices': path.resolve(ROOT_PATH, 'src/services') 54 | } 55 | }, 56 | module: { 57 | rule: { 58 | 'svg-oader': { 59 | test: /\.svg$/, 60 | use: { 61 | 'svg-inline-loader': { 62 | loader: 'svg-inline-loader', 63 | options: { 64 | removeTags: true 65 | } 66 | } 67 | } 68 | }, 69 | 'px2rem-loader': { 70 | test: /\.(less|tsx|ts)$/, 71 | use: { 72 | 'webpack-px2rem-loader': { 73 | loader: 'webpack-px2rem-loader', 74 | options: { 75 | // 1rem=npx 默认为 10 76 | basePx: 100, 77 | // 只会转换大于min的px 默认为0 78 | // 因为很小的px(比如border的1px)转换为rem后在很小的设备上结果会小于1px,有的设备就会不显示 79 | min: 1, 80 | // 转换后的rem值保留的小数点后位数 默认为3 81 | floatWidth: 3 82 | } 83 | } 84 | }, 85 | include: [ 86 | path.resolve(ROOT_PATH, 'src') 87 | ], 88 | exclude: [ 89 | NODE_PATH, 90 | path.resolve(ROOT_PATH, 'src/global.less') 91 | ] 92 | } 93 | } 94 | } 95 | }); 96 | } 97 | }; 98 | -------------------------------------------------------------------------------- /declaration.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.json' { 2 | const content: { [key: string]: any }; 3 | export = content; 4 | } 5 | 6 | declare module '*.less' { 7 | const content: { [className: string]: string }; 8 | export = content; 9 | } 10 | 11 | declare module '*.css' { 12 | const content: { [className: string]: string }; 13 | export = content; 14 | } -------------------------------------------------------------------------------- /doc/archImage.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ARCH 7 | 124 | 125 | 126 | 127 | 128 |
129 |
130 |
131 |
132 |
路由
133 |
134 | 136 | 138 |
139 |
140 |
141 |
数据
142 |
143 |
144 | 146 | 148 |
149 |
150 |
DvaJs
151 |
152 | 154 | 156 |
157 |
158 |
159 |
160 |
161 |
交互、视觉、体验
162 |
163 | 165 |
166 | 167 | 169 |
170 |
171 |
172 |
173 |
稳定、性能、效率
174 |
175 |
176 | 177 | 179 |
180 |
181 |
UmiJS
182 |
183 | 185 | 187 |
188 |
189 |
190 |
191 |
192 |
193 | 213 |
214 | 215 | 216 | -------------------------------------------------------------------------------- /doc/img/arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaotoo/ReactForH5/4960a213e66581bbc2a88793165c2a8332fe2ae7/doc/img/arch.png -------------------------------------------------------------------------------- /doc/img/demo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaotoo/ReactForH5/4960a213e66581bbc2a88793165c2a8332fe2ae7/doc/img/demo.jpg -------------------------------------------------------------------------------- /doc/img/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaotoo/ReactForH5/4960a213e66581bbc2a88793165c2a8332fe2ae7/doc/img/demo.png -------------------------------------------------------------------------------- /doc/img/demo_doc_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaotoo/ReactForH5/4960a213e66581bbc2a88793165c2a8332fe2ae7/doc/img/demo_doc_1.png -------------------------------------------------------------------------------- /mock/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaotoo/ReactForH5/4960a213e66581bbc2a88793165c2a8332fe2ae7/mock/.gitkeep -------------------------------------------------------------------------------- /mock/api/demo.js: -------------------------------------------------------------------------------- 1 | export default { 2 | 'GET /api/demo': { 3 | "data": [], 4 | "errmsg": "success", 5 | "errno": 0 6 | } 7 | } -------------------------------------------------------------------------------- /mock/api/globalInfo.js: -------------------------------------------------------------------------------- 1 | export default { 2 | 'GET /api/globalInfo': { 3 | "data": { 4 | "userName": "zhaoyang", 5 | "isLogin": true 6 | }, 7 | "errmsg": "success", 8 | "errno": 0 9 | } 10 | } -------------------------------------------------------------------------------- /mock/api/map/line.js: -------------------------------------------------------------------------------- 1 | export default { 2 | 'GET /api/map/line': { 3 | "data": [{ 4 | "name": "海门", 5 | "value": [121.15, 31.89, 9] 6 | }, 7 | { 8 | "name": "鄂尔多斯", 9 | "value": [109.781327, 39.608266, 12] 10 | }, 11 | { 12 | "name": "招远", 13 | "value": [120.38, 37.35, 12] 14 | }, 15 | { 16 | "name": "舟山", 17 | "value": [122.207216, 29.985295, 12] 18 | }, 19 | { 20 | "name": "齐齐哈尔", 21 | "value": [123.97, 47.33, 14] 22 | }, 23 | { 24 | "name": "盐城", 25 | "value": [120.13, 33.38, 15] 26 | }, 27 | { 28 | "name": "赤峰", 29 | "value": [118.87, 42.28, 16] 30 | }], 31 | "errmsg": "success", 32 | "errno": 0 33 | } 34 | } -------------------------------------------------------------------------------- /mock/api/orderList.js: -------------------------------------------------------------------------------- 1 | export default { 2 | 'GET /api/orderList': { 3 | "data": [{ 4 | "id": 111, 5 | "price": 10000, 6 | "productName": "iPhoneX", 7 | "administrator": 'zhaoyang', 8 | "createTime": '2018-12-12', 9 | "userType": 1 10 | }, { 11 | "id": 112, 12 | "price": 13000, 13 | "productName": "iPhoneXS", 14 | "administrator": 'zhaoyang', 15 | "createTime": '2018-12-12', 16 | "userType": 1 17 | }, { 18 | "id": 113, 19 | "price": 9000, 20 | "productName": "iPhoneXR", 21 | "administrator": 'zhaoyang', 22 | "createTime": '2018-12-12', 23 | "userType": 2 24 | }, { 25 | "id": 114, 26 | "price": 7000, 27 | "productName": "iPhone8", 28 | "administrator": 'zhaoyang', 29 | "createTime": '2018-11-10', 30 | "userType": 2 31 | }, { 32 | "id": 115, 33 | "price": 6000, 34 | "productName": "iPhone7", 35 | "administrator": 'zhaoyang', 36 | "createTime": '2018-10-16', 37 | "userType": 1 38 | }, { 39 | "id": 116, 40 | "price": 4500, 41 | "productName": "iPhone6", 42 | "administrator": 'zhaoyang', 43 | "createTime": '2017-11-11', 44 | "userType": 1 45 | }], 46 | "errmsg": "success", 47 | "errno": 0 48 | } 49 | } -------------------------------------------------------------------------------- /mock/api/users.js: -------------------------------------------------------------------------------- 1 | export default { 2 | 'GET /api/users': { 3 | "data": [{ 4 | "id": 111, 5 | "systemName": "奔驰", 6 | "administrator": 'zhaoyang', 7 | "createTime": '2018-12-12', 8 | "userType": 1 9 | }, { 10 | "id": 112, 11 | "systemName": "宝马", 12 | "administrator": 'zhaoyang', 13 | "createTime": '2018-12-12', 14 | "userType": 1 15 | }, { 16 | "id": 113, 17 | "systemName": "奥迪", 18 | "administrator": 'zhaoyang', 19 | "createTime": '2018-12-12', 20 | "userType": 2 21 | }, { 22 | "id": 114, 23 | "systemName": "凯迪拉克", 24 | "administrator": 'zhaoyang', 25 | "createTime": '2018-12-12', 26 | "userType": 2 27 | }, { 28 | "id": 115, 29 | "systemName": "沃尔沃", 30 | "administrator": 'zhaoyang', 31 | "createTime": '2018-12-12', 32 | "userType": 1 33 | }], 34 | "errmsg": "success", 35 | "errno": 0 36 | } 37 | } -------------------------------------------------------------------------------- /nginx/demo-ui.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 8088; 3 | gzip on; 4 | gzip_comp_level 3; 5 | gzip_types text/plain application/x-javascript application/javascript application/json text/css image/svg+xml image/*; 6 | 7 | set $output "/yourSystem/app/yourProject/dist"; 8 | 9 | #access_log /usr/local/var/log/nginx/yourProject.access.log main; 10 | #error_log /usr/local/var/log/nginx/yourProject.error.log; 11 | 12 | #yourProject apisrv api 13 | location /api/yourProject/test { 14 | proxy_pass http://yourProjectServer/yourProject/test; 15 | break; 16 | } 17 | 18 | #yourProject assets 19 | location /assets { 20 | root $output; 21 | break; 22 | } 23 | 24 | #yourProject 25 | location / { 26 | add_header Cache-Control no-store; 27 | root $output; 28 | error_page 400 403 404 500 502 503 504 = "/error/error.html"; 29 | rewrite / "/assets/index.html" break; 30 | break; 31 | } 32 | } -------------------------------------------------------------------------------- /nginx/demo-upstream.conf: -------------------------------------------------------------------------------- 1 | upstream archDemoServer { 2 | # online 3 | server 100.90.174.37:8084 weight=1; 4 | server 10.89.151.32:8084 weight=1; 5 | 6 | # small线上小流量 7 | #server 100.90.209.14:8084 weight=1; 8 | 9 | # preview 10 | # server 100.69.102.31:8096 weight=1; 11 | } 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "start": "umi dev", 5 | "proxy": "MOCK=none umi dev", 6 | "build": "umi build", 7 | "analyze": "ANALYZE=1 umi build", 8 | "tslint": "tslint -p . -c tslint.json" 9 | }, 10 | "pre-commit": [ 11 | "tslint" 12 | ], 13 | "dependencies": { 14 | "@types/echarts": "~4.1.0", 15 | "axios": "~0.19.0", 16 | "antd-mobile": "~2.2.9", 17 | "dva": "~2.4.1", 18 | "echarts": "~4.1.0", 19 | "enquire-js": "~0.2.1", 20 | "react": "~16.8.3", 21 | "react-fastclick": "~3.0.2", 22 | "react-router": "~4.3.1", 23 | "umi": "~2.5.6", 24 | "umi-plugin-dva": "~1.5.0", 25 | "umi-plugin-react": "~1.7.1", 26 | "webpack": "~4.28.4" 27 | }, 28 | "devDependencies": { 29 | "husky": "~0.12.0", 30 | "lodash-decorators": "~6.0.1", 31 | "prettier": "^1.19.1", 32 | "react-helmet": "~5.2.0", 33 | "svg-inline-loader": "~0.8.0", 34 | "tslint-react": "~3.6.0", 35 | "webpack-px2rem-loader": "~1.0.2" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /public/iconfont/iconfont.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "iconfont"; 3 | src: url('iconfont.woff?t=1559539580693') format('woff'); 4 | } 5 | 6 | .iconfont { 7 | font-family: "iconfont" !important; 8 | font-size: 16px; 9 | font-style: normal; 10 | -webkit-font-smoothing: antialiased; 11 | -moz-osx-font-smoothing: grayscale; 12 | } 13 | 14 | .lock:before { 15 | content: "\e6c0"; 16 | } 17 | 18 | .unlock:before { 19 | content: "\e6c2"; 20 | } 21 | 22 | .game:before { 23 | content: "\e6df"; 24 | } 25 | 26 | .yunshuzhongwuliu-xianxing:before { 27 | content: "\e882"; 28 | } 29 | 30 | .baoguofahuo-xianxing:before { 31 | content: "\e884"; 32 | } 33 | 34 | .caigou-xianxing:before { 35 | content: "\e887"; 36 | } 37 | 38 | .shangpin-xianxing:before { 39 | content: "\e889"; 40 | } 41 | 42 | .peizaizhuangche-xianxing:before { 43 | content: "\e88a"; 44 | } 45 | 46 | .zhiliang-xianxing:before { 47 | content: "\e88b"; 48 | } 49 | 50 | .anquanbaozhang-xianxing:before { 51 | content: "\e88c"; 52 | } 53 | 54 | .zhongzhuanzhan-xianxing:before { 55 | content: "\e88e"; 56 | } 57 | 58 | .qianshoushenpitongguo-xianxing:before { 59 | content: "\e891"; 60 | } 61 | 62 | .juqianshou-xianxing:before { 63 | content: "\e892"; 64 | } 65 | 66 | .jijianfasong-xianxing:before { 67 | content: "\e893"; 68 | } 69 | 70 | .qiyeyuanquwuye-xianxing:before { 71 | content: "\e894"; 72 | } 73 | 74 | .jifen-xianxing:before { 75 | content: "\e897"; 76 | } 77 | 78 | .youhuijuan-xianxing:before { 79 | content: "\e898"; 80 | } 81 | 82 | .danju-xianxing:before { 83 | content: "\e89a"; 84 | } 85 | 86 | .chuangjiandanju-xianxing:before { 87 | content: "\e89c"; 88 | } 89 | 90 | .zhangdan-xianxing:before { 91 | content: "\e89e"; 92 | } 93 | 94 | .tijikongjian-xianxing:before { 95 | content: "\e89f"; 96 | } 97 | 98 | .yewu-xianxing:before { 99 | content: "\e8a0"; 100 | } 101 | 102 | .quanxianyuechi-xianxing:before { 103 | content: "\e8a3"; 104 | } 105 | 106 | .hezuoguanxi-xianxing:before { 107 | content: "\e8a8"; 108 | } 109 | 110 | .-fuwu-xianxing:before { 111 | content: "\e8a9"; 112 | } 113 | 114 | .-kefu-xianxing:before { 115 | content: "\e8ab"; 116 | } 117 | 118 | .caiwu-xianxing:before { 119 | content: "\e8ae"; 120 | } 121 | 122 | .mianfei-xianxing:before { 123 | content: "\e8b1"; 124 | } 125 | 126 | .tuikuan:before { 127 | content: "\e8b2"; 128 | } 129 | 130 | .jisuanqilishuai-xianxing:before { 131 | content: "\e8b4"; 132 | } 133 | 134 | .youxiajiaogouxuan:before { 135 | content: "\e8b7"; 136 | } 137 | 138 | .fujian:before { 139 | content: "\e8cc"; 140 | } 141 | 142 | .rili:before { 143 | content: "\e8cf"; 144 | } 145 | 146 | .yiban:before { 147 | content: "\e8da"; 148 | } 149 | 150 | .manyi:before { 151 | content: "\e8db"; 152 | } 153 | 154 | .bumanyi:before { 155 | content: "\e8dc"; 156 | } 157 | 158 | .zhixiangzuo:before { 159 | content: "\e8f4"; 160 | } 161 | 162 | .zhixiangyou:before { 163 | content: "\e8f5"; 164 | } 165 | 166 | .zhixiangshang:before { 167 | content: "\e8f6"; 168 | } 169 | 170 | .zhixiangxia:before { 171 | content: "\e8f7"; 172 | } 173 | 174 | .biaotou-zhengxu:before { 175 | content: "\e8f8"; 176 | } 177 | 178 | .biaotou-daoxu:before { 179 | content: "\e8f9"; 180 | } 181 | 182 | .quanping:before { 183 | content: "\e8fa"; 184 | } 185 | 186 | .tuichuquanping:before { 187 | content: "\e8fb"; 188 | } 189 | 190 | .dianpu-xianxing:before { 191 | content: "\e90e"; 192 | } 193 | 194 | .yinhangqia-xianxing:before { 195 | content: "\e936"; 196 | } 197 | 198 | .hongbao-xianxing:before { 199 | content: "\e937"; 200 | } 201 | 202 | .gongnengdingyi:before { 203 | content: "\eb62"; 204 | } 205 | 206 | .jichuguanli:before { 207 | content: "\eb63"; 208 | } 209 | 210 | .peiwangyindao:before { 211 | content: "\eb65"; 212 | } 213 | 214 | .renjijiaohu:before { 215 | content: "\eb66"; 216 | } 217 | 218 | .quanxianshenpi:before { 219 | content: "\eb67"; 220 | } 221 | 222 | .yishouquan:before { 223 | content: "\eb68"; 224 | } 225 | 226 | .shujukanban:before { 227 | content: "\eb69"; 228 | } 229 | 230 | .yingyongguanli:before { 231 | content: "\eb6a"; 232 | } 233 | 234 | .yibiaopan:before { 235 | content: "\eb6b"; 236 | } 237 | 238 | .icon_loading:before { 239 | content: "\eb80"; 240 | } 241 | 242 | .shuaxin:before { 243 | content: "\ec08"; 244 | } 245 | 246 | .baocun:before { 247 | content: "\ec09"; 248 | } 249 | 250 | .fabu:before { 251 | content: "\ec0a"; 252 | } 253 | 254 | .xiangxiazhanhang:before { 255 | content: "\ec0b"; 256 | } 257 | 258 | .xiangshangzhanhang:before { 259 | content: "\ec0c"; 260 | } 261 | 262 | .left-circle:before { 263 | content: "\e77f"; 264 | } 265 | 266 | .play-circle:before { 267 | content: "\e781"; 268 | } 269 | 270 | .right-circle:before { 271 | content: "\e783"; 272 | } 273 | 274 | .timeout:before { 275 | content: "\e784"; 276 | } 277 | 278 | .logout:before { 279 | content: "\e78c"; 280 | } 281 | 282 | .kefu:before { 283 | content: "\ec2e"; 284 | } 285 | 286 | .sousuobianxiao:before { 287 | content: "\ec32"; 288 | } 289 | 290 | .sousuofangda:before { 291 | content: "\ec33"; 292 | } 293 | 294 | .xinhao:before { 295 | content: "\ec4a"; 296 | } 297 | 298 | .lanya:before { 299 | content: "\ec4b"; 300 | } 301 | 302 | .Wi-Fi:before { 303 | content: "\ec4c"; 304 | } 305 | 306 | .zihangche:before { 307 | content: "\ec69"; 308 | } 309 | 310 | .liebiao:before { 311 | content: "\ec6b"; 312 | } 313 | 314 | .qiche:before { 315 | content: "\ec6d"; 316 | } 317 | 318 | .duigoux:before { 319 | content: "\ec9e"; 320 | } 321 | 322 | .guanbi:before { 323 | content: "\eca0"; 324 | } 325 | 326 | .shengyinkai:before { 327 | content: "\eca6"; 328 | } 329 | 330 | .shoucang_shixin:before { 331 | content: "\eca7"; 332 | } 333 | 334 | .shoucang:before { 335 | content: "\eca8"; 336 | } 337 | 338 | .shengyinwu:before { 339 | content: "\eca9"; 340 | } 341 | 342 | .shengyinjingyin:before { 343 | content: "\ecaa"; 344 | } 345 | 346 | .icon_add:before { 347 | content: "\eb8f"; 348 | } 349 | 350 | .icon_addmessage:before { 351 | content: "\eb90"; 352 | } 353 | 354 | .icon_addresslist:before { 355 | content: "\eb91"; 356 | } 357 | 358 | .icon_affiliations_li:before { 359 | content: "\eb92"; 360 | } 361 | 362 | .icon_addperson:before { 363 | content: "\eb93"; 364 | } 365 | 366 | .icon_boss:before { 367 | content: "\eb94"; 368 | } 369 | 370 | .icon_alipay_line:before { 371 | content: "\eb95"; 372 | } 373 | 374 | .icon_addressbook:before { 375 | content: "\eb96"; 376 | } 377 | 378 | .icon_at:before { 379 | content: "\eb97"; 380 | } 381 | 382 | .icon_airplay:before { 383 | content: "\eb98"; 384 | } 385 | 386 | .icon_calendar:before { 387 | content: "\eb99"; 388 | } 389 | 390 | .icon_attestation:before { 391 | content: "\eb9a"; 392 | } 393 | 394 | .icon_camera:before { 395 | content: "\eb9b"; 396 | } 397 | 398 | .icon_certificate_fil:before { 399 | content: "\eb9c"; 400 | } 401 | 402 | .icon_coinpurse_line:before { 403 | content: "\eb9d"; 404 | } 405 | 406 | .icon_collect:before { 407 | content: "\eb9e"; 408 | } 409 | 410 | .icon_compile:before { 411 | content: "\eb9f"; 412 | } 413 | 414 | .icon_details:before { 415 | content: "\eba0"; 416 | } 417 | 418 | .icon_circle_line:before { 419 | content: "\eba1"; 420 | } 421 | 422 | .icon_cloud_history:before { 423 | content: "\eba2"; 424 | } 425 | 426 | .icon_community_line:before { 427 | content: "\eba3"; 428 | } 429 | 430 | .icon_discovery:before { 431 | content: "\eba4"; 432 | } 433 | 434 | .icon_delete:before { 435 | content: "\eba5"; 436 | } 437 | 438 | .icon_dispose:before { 439 | content: "\eba6"; 440 | } 441 | 442 | .icon_doc:before { 443 | content: "\eba7"; 444 | } 445 | 446 | .icon_cspace:before { 447 | content: "\eba8"; 448 | } 449 | 450 | .icon_exchange:before { 451 | content: "\eba9"; 452 | } 453 | 454 | .icon_ding:before { 455 | content: "\ebaa"; 456 | } 457 | 458 | .icon_down:before { 459 | content: "\ebab"; 460 | } 461 | 462 | .icon_dingtalk_line:before { 463 | content: "\ebac"; 464 | } 465 | 466 | .icon_gift:before { 467 | content: "\ebad"; 468 | } 469 | 470 | .icon_glass:before { 471 | content: "\ebae"; 472 | } 473 | 474 | .icon_file:before { 475 | content: "\ebaf"; 476 | } 477 | 478 | .icon_GPS:before { 479 | content: "\ebb0"; 480 | } 481 | 482 | .icon_hardware_fill:before { 483 | content: "\ebb1"; 484 | } 485 | 486 | .icon_HRM:before { 487 | content: "\ebb2"; 488 | } 489 | 490 | .icon_im_more:before { 491 | content: "\ebb3"; 492 | } 493 | 494 | .icon_Eapp_line:before { 495 | content: "\ebb4"; 496 | } 497 | 498 | .icon_group:before { 499 | content: "\ebb5"; 500 | } 501 | 502 | .icon_horn:before { 503 | content: "\ebb6"; 504 | } 505 | 506 | .icon_im_face:before { 507 | content: "\ebb7"; 508 | } 509 | 510 | .icon_homepage:before { 511 | content: "\ebb8"; 512 | } 513 | 514 | .icon_invite:before { 515 | content: "\ebb9"; 516 | } 517 | 518 | .icon_launch_page:before { 519 | content: "\ebba"; 520 | } 521 | 522 | .icon_likegood:before { 523 | content: "\ebbb"; 524 | } 525 | 526 | .icon_index_line:before { 527 | content: "\ebbc"; 528 | } 529 | 530 | .icon_live:before { 531 | content: "\ebbd"; 532 | } 533 | 534 | .icon_link:before { 535 | content: "\ebbe"; 536 | } 537 | 538 | .icon_im_voice:before { 539 | content: "\ebbf"; 540 | } 541 | 542 | .icon_mobilephone:before { 543 | content: "\ebc0"; 544 | } 545 | 546 | .icon_dmail:before { 547 | content: "\ebc1"; 548 | } 549 | 550 | .icon_message:before { 551 | content: "\ebc2"; 552 | } 553 | 554 | .icon_new_recruit:before { 555 | content: "\ebc3"; 556 | } 557 | 558 | .icon_little_taget:before { 559 | content: "\ebc4"; 560 | } 561 | 562 | .icon_more:before { 563 | content: "\ebc5"; 564 | } 565 | 566 | .icon_left:before { 567 | content: "\ebc6"; 568 | } 569 | 570 | .icon_next_arrow:before { 571 | content: "\ebc7"; 572 | } 573 | 574 | .icon_notice:before { 575 | content: "\ebc8"; 576 | } 577 | 578 | .icon_nomemo:before { 579 | content: "\ebc9"; 580 | } 581 | 582 | .icon_newgroup:before { 583 | content: "\ebca"; 584 | } 585 | 586 | .icon_namecard:before { 587 | content: "\ebcb"; 588 | } 589 | 590 | .icon_phone:before { 591 | content: "\ebcc"; 592 | } 593 | 594 | .icon_qq:before { 595 | content: "\ebcd"; 596 | } 597 | 598 | .icon_photo:before { 599 | content: "\ebce"; 600 | } 601 | 602 | .icon_medal:before { 603 | content: "\ebcf"; 604 | } 605 | 606 | .icon_redpacket:before { 607 | content: "\ebd0"; 608 | } 609 | 610 | .icon_patriarch:before { 611 | content: "\ebd1"; 612 | } 613 | 614 | .icon_roundclose:before { 615 | content: "\ebd2"; 616 | } 617 | 618 | .icon_im_keyboard:before { 619 | content: "\ebd3"; 620 | } 621 | 622 | .icon_roundreduce:before { 623 | content: "\ebd4"; 624 | } 625 | 626 | .icon_railway:before { 627 | content: "\ebd5"; 628 | } 629 | 630 | .icon_QRcode:before { 631 | content: "\ebd6"; 632 | } 633 | 634 | .icon_savememo:before { 635 | content: "\ebd7"; 636 | } 637 | 638 | .icon_roundadd:before { 639 | content: "\ebd8"; 640 | } 641 | 642 | .icon_refresh:before { 643 | content: "\ebd9"; 644 | } 645 | 646 | .icon_search:before { 647 | content: "\ebda"; 648 | } 649 | 650 | .icon_scan:before { 651 | content: "\ebdb"; 652 | } 653 | 654 | .icon_send:before { 655 | content: "\ebdc"; 656 | } 657 | 658 | .icon_principal:before { 659 | content: "\ebdd"; 660 | } 661 | 662 | .icon_service:before { 663 | content: "\ebde"; 664 | } 665 | 666 | .icon_scan_namecard:before { 667 | content: "\ebdf"; 668 | } 669 | 670 | .icon_secret:before { 671 | content: "\ebe0"; 672 | } 673 | 674 | .icon_share:before { 675 | content: "\ebe1"; 676 | } 677 | 678 | .icon_signin_line:before { 679 | content: "\ebe2"; 680 | } 681 | 682 | .icon_sms:before { 683 | content: "\ebe3"; 684 | } 685 | 686 | .icon_sketch:before { 687 | content: "\ebe4"; 688 | } 689 | 690 | .icon_setting:before { 691 | content: "\ebe5"; 692 | } 693 | 694 | .icon_signal:before { 695 | content: "\ebe6"; 696 | } 697 | 698 | .icon_skin:before { 699 | content: "\ebe7"; 700 | } 701 | 702 | .icon_star:before { 703 | content: "\ebe8"; 704 | } 705 | 706 | .icon_subordinate:before { 707 | content: "\ebe9"; 708 | } 709 | 710 | .icon_task:before { 711 | content: "\ebea"; 712 | } 713 | 714 | .icon_statistics:before { 715 | content: "\ebeb"; 716 | } 717 | 718 | .icon_threeline_fill:before { 719 | content: "\ebec"; 720 | } 721 | 722 | .icon_study:before { 723 | content: "\ebed"; 724 | } 725 | 726 | .icon_voice:before { 727 | content: "\ebee"; 728 | } 729 | 730 | .icon_square:before { 731 | content: "\ebef"; 732 | } 733 | 734 | .icon_wechat:before { 735 | content: "\ebf0"; 736 | } 737 | 738 | .icon_sport:before { 739 | content: "\ebf1"; 740 | } 741 | 742 | .icon_work:before { 743 | content: "\ebf2"; 744 | } 745 | 746 | .icon_warn:before { 747 | content: "\ebf3"; 748 | } 749 | 750 | .icon_workmore:before { 751 | content: "\ebf4"; 752 | } 753 | 754 | .icon_safety:before { 755 | content: "\ebf5"; 756 | } 757 | 758 | .icon_workset:before { 759 | content: "\ebf6"; 760 | } 761 | 762 | .icon_voipphone:before { 763 | content: "\ebf7"; 764 | } 765 | 766 | .icon_shield:before { 767 | content: "\ebf8"; 768 | } 769 | 770 | .icon_shakehands:before { 771 | content: "\ebf9"; 772 | } 773 | 774 | .icon_video:before { 775 | content: "\ebfa"; 776 | } 777 | 778 | .icon_task_done:before { 779 | content: "\ebfb"; 780 | } 781 | 782 | .icon_meeting:before { 783 | content: "\ebfc"; 784 | } 785 | 786 | .icon_synergy:before { 787 | content: "\ebfd"; 788 | } 789 | 790 | .icon_workfile_line:before { 791 | content: "\ebfe"; 792 | } -------------------------------------------------------------------------------- /public/iconfont/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaotoo/ReactForH5/4960a213e66581bbc2a88793165c2a8332fe2ae7/public/iconfont/iconfont.woff -------------------------------------------------------------------------------- /public/iconfont/original/demo.css: -------------------------------------------------------------------------------- 1 | /* Logo 字体 */ 2 | @font-face { 3 | font-family: "iconfont logo"; 4 | src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834'); 5 | src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'), 6 | url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'), 7 | url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'), 8 | url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg'); 9 | } 10 | 11 | .logo { 12 | font-family: "iconfont logo"; 13 | font-size: 160px; 14 | font-style: normal; 15 | -webkit-font-smoothing: antialiased; 16 | -moz-osx-font-smoothing: grayscale; 17 | } 18 | 19 | /* tabs */ 20 | .nav-tabs { 21 | position: relative; 22 | } 23 | 24 | .nav-tabs .nav-more { 25 | position: absolute; 26 | right: 0; 27 | bottom: 0; 28 | height: 42px; 29 | line-height: 42px; 30 | color: #666; 31 | } 32 | 33 | #tabs { 34 | border-bottom: 1px solid #eee; 35 | } 36 | 37 | #tabs li { 38 | cursor: pointer; 39 | width: 100px; 40 | height: 40px; 41 | line-height: 40px; 42 | text-align: center; 43 | font-size: 16px; 44 | border-bottom: 2px solid transparent; 45 | position: relative; 46 | z-index: 1; 47 | margin-bottom: -1px; 48 | color: #666; 49 | } 50 | 51 | 52 | #tabs .active { 53 | border-bottom-color: #f00; 54 | color: #222; 55 | } 56 | 57 | .tab-container .content { 58 | display: none; 59 | } 60 | 61 | /* 页面布局 */ 62 | .main { 63 | padding: 30px 100px; 64 | width: 960px; 65 | margin: 0 auto; 66 | } 67 | 68 | .main .logo { 69 | color: #333; 70 | text-align: left; 71 | margin-bottom: 30px; 72 | line-height: 1; 73 | height: 110px; 74 | margin-top: -50px; 75 | overflow: hidden; 76 | *zoom: 1; 77 | } 78 | 79 | .main .logo a { 80 | font-size: 160px; 81 | color: #333; 82 | } 83 | 84 | .helps { 85 | margin-top: 40px; 86 | } 87 | 88 | .helps pre { 89 | padding: 20px; 90 | margin: 10px 0; 91 | border: solid 1px #e7e1cd; 92 | background-color: #fffdef; 93 | overflow: auto; 94 | } 95 | 96 | .icon_lists { 97 | width: 100% !important; 98 | overflow: hidden; 99 | *zoom: 1; 100 | } 101 | 102 | .icon_lists li { 103 | width: 100px; 104 | margin-bottom: 10px; 105 | margin-right: 20px; 106 | text-align: center; 107 | list-style: none !important; 108 | cursor: default; 109 | } 110 | 111 | .icon_lists li .code-name { 112 | line-height: 1.2; 113 | } 114 | 115 | .icon_lists .icon { 116 | display: block; 117 | height: 100px; 118 | line-height: 100px; 119 | font-size: 42px; 120 | margin: 10px auto; 121 | color: #333; 122 | -webkit-transition: font-size 0.25s linear, width 0.25s linear; 123 | -moz-transition: font-size 0.25s linear, width 0.25s linear; 124 | transition: font-size 0.25s linear, width 0.25s linear; 125 | } 126 | 127 | .icon_lists .icon:hover { 128 | font-size: 100px; 129 | } 130 | 131 | .icon_lists .svg-icon { 132 | /* 通过设置 font-size 来改变图标大小 */ 133 | width: 1em; 134 | /* 图标和文字相邻时,垂直对齐 */ 135 | vertical-align: -0.15em; 136 | /* 通过设置 color 来改变 SVG 的颜色/fill */ 137 | fill: currentColor; 138 | /* path 和 stroke 溢出 viewBox 部分在 IE 下会显示 139 | normalize.css 中也包含这行 */ 140 | overflow: hidden; 141 | } 142 | 143 | .icon_lists li .name, 144 | .icon_lists li .code-name { 145 | color: #666; 146 | } 147 | 148 | /* markdown 样式 */ 149 | .markdown { 150 | color: #666; 151 | font-size: 14px; 152 | line-height: 1.8; 153 | } 154 | 155 | .highlight { 156 | line-height: 1.5; 157 | } 158 | 159 | .markdown img { 160 | vertical-align: middle; 161 | max-width: 100%; 162 | } 163 | 164 | .markdown h1 { 165 | color: #404040; 166 | font-weight: 500; 167 | line-height: 40px; 168 | margin-bottom: 24px; 169 | } 170 | 171 | .markdown h2, 172 | .markdown h3, 173 | .markdown h4, 174 | .markdown h5, 175 | .markdown h6 { 176 | color: #404040; 177 | margin: 1.6em 0 0.6em 0; 178 | font-weight: 500; 179 | clear: both; 180 | } 181 | 182 | .markdown h1 { 183 | font-size: 28px; 184 | } 185 | 186 | .markdown h2 { 187 | font-size: 22px; 188 | } 189 | 190 | .markdown h3 { 191 | font-size: 16px; 192 | } 193 | 194 | .markdown h4 { 195 | font-size: 14px; 196 | } 197 | 198 | .markdown h5 { 199 | font-size: 12px; 200 | } 201 | 202 | .markdown h6 { 203 | font-size: 12px; 204 | } 205 | 206 | .markdown hr { 207 | height: 1px; 208 | border: 0; 209 | background: #e9e9e9; 210 | margin: 16px 0; 211 | clear: both; 212 | } 213 | 214 | .markdown p { 215 | margin: 1em 0; 216 | } 217 | 218 | .markdown>p, 219 | .markdown>blockquote, 220 | .markdown>.highlight, 221 | .markdown>ol, 222 | .markdown>ul { 223 | width: 80%; 224 | } 225 | 226 | .markdown ul>li { 227 | list-style: circle; 228 | } 229 | 230 | .markdown>ul li, 231 | .markdown blockquote ul>li { 232 | margin-left: 20px; 233 | padding-left: 4px; 234 | } 235 | 236 | .markdown>ul li p, 237 | .markdown>ol li p { 238 | margin: 0.6em 0; 239 | } 240 | 241 | .markdown ol>li { 242 | list-style: decimal; 243 | } 244 | 245 | .markdown>ol li, 246 | .markdown blockquote ol>li { 247 | margin-left: 20px; 248 | padding-left: 4px; 249 | } 250 | 251 | .markdown code { 252 | margin: 0 3px; 253 | padding: 0 5px; 254 | background: #eee; 255 | border-radius: 3px; 256 | } 257 | 258 | .markdown strong, 259 | .markdown b { 260 | font-weight: 600; 261 | } 262 | 263 | .markdown>table { 264 | border-collapse: collapse; 265 | border-spacing: 0px; 266 | empty-cells: show; 267 | border: 1px solid #e9e9e9; 268 | width: 95%; 269 | margin-bottom: 24px; 270 | } 271 | 272 | .markdown>table th { 273 | white-space: nowrap; 274 | color: #333; 275 | font-weight: 600; 276 | } 277 | 278 | .markdown>table th, 279 | .markdown>table td { 280 | border: 1px solid #e9e9e9; 281 | padding: 8px 16px; 282 | text-align: left; 283 | } 284 | 285 | .markdown>table th { 286 | background: #F7F7F7; 287 | } 288 | 289 | .markdown blockquote { 290 | font-size: 90%; 291 | color: #999; 292 | border-left: 4px solid #e9e9e9; 293 | padding-left: 0.8em; 294 | margin: 1em 0; 295 | } 296 | 297 | .markdown blockquote p { 298 | margin: 0; 299 | } 300 | 301 | .markdown .anchor { 302 | opacity: 0; 303 | transition: opacity 0.3s ease; 304 | margin-left: 8px; 305 | } 306 | 307 | .markdown .waiting { 308 | color: #ccc; 309 | } 310 | 311 | .markdown h1:hover .anchor, 312 | .markdown h2:hover .anchor, 313 | .markdown h3:hover .anchor, 314 | .markdown h4:hover .anchor, 315 | .markdown h5:hover .anchor, 316 | .markdown h6:hover .anchor { 317 | opacity: 1; 318 | display: inline-block; 319 | } 320 | 321 | .markdown>br, 322 | .markdown>p>br { 323 | clear: both; 324 | } 325 | 326 | 327 | .hljs { 328 | display: block; 329 | background: white; 330 | padding: 0.5em; 331 | color: #333333; 332 | overflow-x: auto; 333 | } 334 | 335 | .hljs-comment, 336 | .hljs-meta { 337 | color: #969896; 338 | } 339 | 340 | .hljs-string, 341 | .hljs-variable, 342 | .hljs-template-variable, 343 | .hljs-strong, 344 | .hljs-emphasis, 345 | .hljs-quote { 346 | color: #df5000; 347 | } 348 | 349 | .hljs-keyword, 350 | .hljs-selector-tag, 351 | .hljs-type { 352 | color: #a71d5d; 353 | } 354 | 355 | .hljs-literal, 356 | .hljs-symbol, 357 | .hljs-bullet, 358 | .hljs-attribute { 359 | color: #0086b3; 360 | } 361 | 362 | .hljs-section, 363 | .hljs-name { 364 | color: #63a35c; 365 | } 366 | 367 | .hljs-tag { 368 | color: #333333; 369 | } 370 | 371 | .hljs-title, 372 | .hljs-attr, 373 | .hljs-selector-id, 374 | .hljs-selector-class, 375 | .hljs-selector-attr, 376 | .hljs-selector-pseudo { 377 | color: #795da3; 378 | } 379 | 380 | .hljs-addition { 381 | color: #55a532; 382 | background-color: #eaffea; 383 | } 384 | 385 | .hljs-deletion { 386 | color: #bd2c00; 387 | background-color: #ffecec; 388 | } 389 | 390 | .hljs-link { 391 | text-decoration: underline; 392 | } 393 | 394 | /* 代码高亮 */ 395 | /* PrismJS 1.15.0 396 | https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */ 397 | /** 398 | * prism.js default theme for JavaScript, CSS and HTML 399 | * Based on dabblet (http://dabblet.com) 400 | * @author Lea Verou 401 | */ 402 | code[class*="language-"], 403 | pre[class*="language-"] { 404 | color: black; 405 | background: none; 406 | text-shadow: 0 1px white; 407 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; 408 | text-align: left; 409 | white-space: pre; 410 | word-spacing: normal; 411 | word-break: normal; 412 | word-wrap: normal; 413 | line-height: 1.5; 414 | 415 | -moz-tab-size: 4; 416 | -o-tab-size: 4; 417 | tab-size: 4; 418 | 419 | -webkit-hyphens: none; 420 | -moz-hyphens: none; 421 | -ms-hyphens: none; 422 | hyphens: none; 423 | } 424 | 425 | pre[class*="language-"]::-moz-selection, 426 | pre[class*="language-"] ::-moz-selection, 427 | code[class*="language-"]::-moz-selection, 428 | code[class*="language-"] ::-moz-selection { 429 | text-shadow: none; 430 | background: #b3d4fc; 431 | } 432 | 433 | pre[class*="language-"]::selection, 434 | pre[class*="language-"] ::selection, 435 | code[class*="language-"]::selection, 436 | code[class*="language-"] ::selection { 437 | text-shadow: none; 438 | background: #b3d4fc; 439 | } 440 | 441 | @media print { 442 | 443 | code[class*="language-"], 444 | pre[class*="language-"] { 445 | text-shadow: none; 446 | } 447 | } 448 | 449 | /* Code blocks */ 450 | pre[class*="language-"] { 451 | padding: 1em; 452 | margin: .5em 0; 453 | overflow: auto; 454 | } 455 | 456 | :not(pre)>code[class*="language-"], 457 | pre[class*="language-"] { 458 | background: #f5f2f0; 459 | } 460 | 461 | /* Inline code */ 462 | :not(pre)>code[class*="language-"] { 463 | padding: .1em; 464 | border-radius: .3em; 465 | white-space: normal; 466 | } 467 | 468 | .token.comment, 469 | .token.prolog, 470 | .token.doctype, 471 | .token.cdata { 472 | color: slategray; 473 | } 474 | 475 | .token.punctuation { 476 | color: #999; 477 | } 478 | 479 | .namespace { 480 | opacity: .7; 481 | } 482 | 483 | .token.property, 484 | .token.tag, 485 | .token.boolean, 486 | .token.number, 487 | .token.constant, 488 | .token.symbol, 489 | .token.deleted { 490 | color: #905; 491 | } 492 | 493 | .token.selector, 494 | .token.attr-name, 495 | .token.string, 496 | .token.char, 497 | .token.builtin, 498 | .token.inserted { 499 | color: #690; 500 | } 501 | 502 | .token.operator, 503 | .token.entity, 504 | .token.url, 505 | .language-css .token.string, 506 | .style .token.string { 507 | color: #9a6e3a; 508 | background: hsla(0, 0%, 100%, .5); 509 | } 510 | 511 | .token.atrule, 512 | .token.attr-value, 513 | .token.keyword { 514 | color: #07a; 515 | } 516 | 517 | .token.function, 518 | .token.class-name { 519 | color: #DD4A68; 520 | } 521 | 522 | .token.regex, 523 | .token.important, 524 | .token.variable { 525 | color: #e90; 526 | } 527 | 528 | .token.important, 529 | .token.bold { 530 | font-weight: bold; 531 | } 532 | 533 | .token.italic { 534 | font-style: italic; 535 | } 536 | 537 | .token.entity { 538 | cursor: help; 539 | } 540 | -------------------------------------------------------------------------------- /public/iconfont/original/iconfont.css: -------------------------------------------------------------------------------- 1 | @font-face {font-family: "iconfont"; 2 | src: url('iconfont.eot?t=1559539580693'); /* IE9 */ 3 | src: url('iconfont.eot?t=1559539580693#iefix') format('embedded-opentype'), /* IE6-IE8 */ 4 | url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'), 5 | url('iconfont.woff?t=1559539580693') format('woff'), 6 | url('iconfont.ttf?t=1559539580693') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ 7 | url('iconfont.svg?t=1559539580693#iconfont') format('svg'); /* iOS 4.1- */ 8 | } 9 | 10 | .iconfont { 11 | font-family: "iconfont" !important; 12 | font-size: 16px; 13 | font-style: normal; 14 | -webkit-font-smoothing: antialiased; 15 | -moz-osx-font-smoothing: grayscale; 16 | } 17 | 18 | .lock:before { 19 | content: "\e6c0"; 20 | } 21 | 22 | .unlock:before { 23 | content: "\e6c2"; 24 | } 25 | 26 | .game:before { 27 | content: "\e6df"; 28 | } 29 | 30 | .yunshuzhongwuliu-xianxing:before { 31 | content: "\e882"; 32 | } 33 | 34 | .baoguofahuo-xianxing:before { 35 | content: "\e884"; 36 | } 37 | 38 | .caigou-xianxing:before { 39 | content: "\e887"; 40 | } 41 | 42 | .shangpin-xianxing:before { 43 | content: "\e889"; 44 | } 45 | 46 | .peizaizhuangche-xianxing:before { 47 | content: "\e88a"; 48 | } 49 | 50 | .zhiliang-xianxing:before { 51 | content: "\e88b"; 52 | } 53 | 54 | .anquanbaozhang-xianxing:before { 55 | content: "\e88c"; 56 | } 57 | 58 | .zhongzhuanzhan-xianxing:before { 59 | content: "\e88e"; 60 | } 61 | 62 | .qianshoushenpitongguo-xianxing:before { 63 | content: "\e891"; 64 | } 65 | 66 | .juqianshou-xianxing:before { 67 | content: "\e892"; 68 | } 69 | 70 | .jijianfasong-xianxing:before { 71 | content: "\e893"; 72 | } 73 | 74 | .qiyeyuanquwuye-xianxing:before { 75 | content: "\e894"; 76 | } 77 | 78 | .jifen-xianxing:before { 79 | content: "\e897"; 80 | } 81 | 82 | .youhuijuan-xianxing:before { 83 | content: "\e898"; 84 | } 85 | 86 | .danju-xianxing:before { 87 | content: "\e89a"; 88 | } 89 | 90 | .chuangjiandanju-xianxing:before { 91 | content: "\e89c"; 92 | } 93 | 94 | .zhangdan-xianxing:before { 95 | content: "\e89e"; 96 | } 97 | 98 | .tijikongjian-xianxing:before { 99 | content: "\e89f"; 100 | } 101 | 102 | .yewu-xianxing:before { 103 | content: "\e8a0"; 104 | } 105 | 106 | .quanxianyuechi-xianxing:before { 107 | content: "\e8a3"; 108 | } 109 | 110 | .hezuoguanxi-xianxing:before { 111 | content: "\e8a8"; 112 | } 113 | 114 | .-fuwu-xianxing:before { 115 | content: "\e8a9"; 116 | } 117 | 118 | .-kefu-xianxing:before { 119 | content: "\e8ab"; 120 | } 121 | 122 | .caiwu-xianxing:before { 123 | content: "\e8ae"; 124 | } 125 | 126 | .mianfei-xianxing:before { 127 | content: "\e8b1"; 128 | } 129 | 130 | .tuikuan:before { 131 | content: "\e8b2"; 132 | } 133 | 134 | .jisuanqilishuai-xianxing:before { 135 | content: "\e8b4"; 136 | } 137 | 138 | .youxiajiaogouxuan:before { 139 | content: "\e8b7"; 140 | } 141 | 142 | .fujian:before { 143 | content: "\e8cc"; 144 | } 145 | 146 | .rili:before { 147 | content: "\e8cf"; 148 | } 149 | 150 | .yiban:before { 151 | content: "\e8da"; 152 | } 153 | 154 | .manyi:before { 155 | content: "\e8db"; 156 | } 157 | 158 | .bumanyi:before { 159 | content: "\e8dc"; 160 | } 161 | 162 | .zhixiangzuo:before { 163 | content: "\e8f4"; 164 | } 165 | 166 | .zhixiangyou:before { 167 | content: "\e8f5"; 168 | } 169 | 170 | .zhixiangshang:before { 171 | content: "\e8f6"; 172 | } 173 | 174 | .zhixiangxia:before { 175 | content: "\e8f7"; 176 | } 177 | 178 | .biaotou-zhengxu:before { 179 | content: "\e8f8"; 180 | } 181 | 182 | .biaotou-daoxu:before { 183 | content: "\e8f9"; 184 | } 185 | 186 | .quanping:before { 187 | content: "\e8fa"; 188 | } 189 | 190 | .tuichuquanping:before { 191 | content: "\e8fb"; 192 | } 193 | 194 | .dianpu-xianxing:before { 195 | content: "\e90e"; 196 | } 197 | 198 | .yinhangqia-xianxing:before { 199 | content: "\e936"; 200 | } 201 | 202 | .hongbao-xianxing:before { 203 | content: "\e937"; 204 | } 205 | 206 | .gongnengdingyi:before { 207 | content: "\eb62"; 208 | } 209 | 210 | .jichuguanli:before { 211 | content: "\eb63"; 212 | } 213 | 214 | .peiwangyindao:before { 215 | content: "\eb65"; 216 | } 217 | 218 | .renjijiaohu:before { 219 | content: "\eb66"; 220 | } 221 | 222 | .quanxianshenpi:before { 223 | content: "\eb67"; 224 | } 225 | 226 | .yishouquan:before { 227 | content: "\eb68"; 228 | } 229 | 230 | .shujukanban:before { 231 | content: "\eb69"; 232 | } 233 | 234 | .yingyongguanli:before { 235 | content: "\eb6a"; 236 | } 237 | 238 | .yibiaopan:before { 239 | content: "\eb6b"; 240 | } 241 | 242 | .icon_loading:before { 243 | content: "\eb80"; 244 | } 245 | 246 | .shuaxin:before { 247 | content: "\ec08"; 248 | } 249 | 250 | .baocun:before { 251 | content: "\ec09"; 252 | } 253 | 254 | .fabu:before { 255 | content: "\ec0a"; 256 | } 257 | 258 | .xiangxiazhanhang:before { 259 | content: "\ec0b"; 260 | } 261 | 262 | .xiangshangzhanhang:before { 263 | content: "\ec0c"; 264 | } 265 | 266 | .left-circle:before { 267 | content: "\e77f"; 268 | } 269 | 270 | .play-circle:before { 271 | content: "\e781"; 272 | } 273 | 274 | .right-circle:before { 275 | content: "\e783"; 276 | } 277 | 278 | .timeout:before { 279 | content: "\e784"; 280 | } 281 | 282 | .logout:before { 283 | content: "\e78c"; 284 | } 285 | 286 | .kefu:before { 287 | content: "\ec2e"; 288 | } 289 | 290 | .sousuobianxiao:before { 291 | content: "\ec32"; 292 | } 293 | 294 | .sousuofangda:before { 295 | content: "\ec33"; 296 | } 297 | 298 | .xinhao:before { 299 | content: "\ec4a"; 300 | } 301 | 302 | .lanya:before { 303 | content: "\ec4b"; 304 | } 305 | 306 | .Wi-Fi:before { 307 | content: "\ec4c"; 308 | } 309 | 310 | .zihangche:before { 311 | content: "\ec69"; 312 | } 313 | 314 | .liebiao:before { 315 | content: "\ec6b"; 316 | } 317 | 318 | .qiche:before { 319 | content: "\ec6d"; 320 | } 321 | 322 | .duigoux:before { 323 | content: "\ec9e"; 324 | } 325 | 326 | .guanbi:before { 327 | content: "\eca0"; 328 | } 329 | 330 | .shengyinkai:before { 331 | content: "\eca6"; 332 | } 333 | 334 | .shoucang_shixin:before { 335 | content: "\eca7"; 336 | } 337 | 338 | .shoucang:before { 339 | content: "\eca8"; 340 | } 341 | 342 | .shengyinwu:before { 343 | content: "\eca9"; 344 | } 345 | 346 | .shengyinjingyin:before { 347 | content: "\ecaa"; 348 | } 349 | 350 | .icon_add:before { 351 | content: "\eb8f"; 352 | } 353 | 354 | .icon_addmessage:before { 355 | content: "\eb90"; 356 | } 357 | 358 | .icon_addresslist:before { 359 | content: "\eb91"; 360 | } 361 | 362 | .icon_affiliations_li:before { 363 | content: "\eb92"; 364 | } 365 | 366 | .icon_addperson:before { 367 | content: "\eb93"; 368 | } 369 | 370 | .icon_boss:before { 371 | content: "\eb94"; 372 | } 373 | 374 | .icon_alipay_line:before { 375 | content: "\eb95"; 376 | } 377 | 378 | .icon_addressbook:before { 379 | content: "\eb96"; 380 | } 381 | 382 | .icon_at:before { 383 | content: "\eb97"; 384 | } 385 | 386 | .icon_airplay:before { 387 | content: "\eb98"; 388 | } 389 | 390 | .icon_calendar:before { 391 | content: "\eb99"; 392 | } 393 | 394 | .icon_attestation:before { 395 | content: "\eb9a"; 396 | } 397 | 398 | .icon_camera:before { 399 | content: "\eb9b"; 400 | } 401 | 402 | .icon_certificate_fil:before { 403 | content: "\eb9c"; 404 | } 405 | 406 | .icon_coinpurse_line:before { 407 | content: "\eb9d"; 408 | } 409 | 410 | .icon_collect:before { 411 | content: "\eb9e"; 412 | } 413 | 414 | .icon_compile:before { 415 | content: "\eb9f"; 416 | } 417 | 418 | .icon_details:before { 419 | content: "\eba0"; 420 | } 421 | 422 | .icon_circle_line:before { 423 | content: "\eba1"; 424 | } 425 | 426 | .icon_cloud_history:before { 427 | content: "\eba2"; 428 | } 429 | 430 | .icon_community_line:before { 431 | content: "\eba3"; 432 | } 433 | 434 | .icon_discovery:before { 435 | content: "\eba4"; 436 | } 437 | 438 | .icon_delete:before { 439 | content: "\eba5"; 440 | } 441 | 442 | .icon_dispose:before { 443 | content: "\eba6"; 444 | } 445 | 446 | .icon_doc:before { 447 | content: "\eba7"; 448 | } 449 | 450 | .icon_cspace:before { 451 | content: "\eba8"; 452 | } 453 | 454 | .icon_exchange:before { 455 | content: "\eba9"; 456 | } 457 | 458 | .icon_ding:before { 459 | content: "\ebaa"; 460 | } 461 | 462 | .icon_down:before { 463 | content: "\ebab"; 464 | } 465 | 466 | .icon_dingtalk_line:before { 467 | content: "\ebac"; 468 | } 469 | 470 | .icon_gift:before { 471 | content: "\ebad"; 472 | } 473 | 474 | .icon_glass:before { 475 | content: "\ebae"; 476 | } 477 | 478 | .icon_file:before { 479 | content: "\ebaf"; 480 | } 481 | 482 | .icon_GPS:before { 483 | content: "\ebb0"; 484 | } 485 | 486 | .icon_hardware_fill:before { 487 | content: "\ebb1"; 488 | } 489 | 490 | .icon_HRM:before { 491 | content: "\ebb2"; 492 | } 493 | 494 | .icon_im_more:before { 495 | content: "\ebb3"; 496 | } 497 | 498 | .icon_Eapp_line:before { 499 | content: "\ebb4"; 500 | } 501 | 502 | .icon_group:before { 503 | content: "\ebb5"; 504 | } 505 | 506 | .icon_horn:before { 507 | content: "\ebb6"; 508 | } 509 | 510 | .icon_im_face:before { 511 | content: "\ebb7"; 512 | } 513 | 514 | .icon_homepage:before { 515 | content: "\ebb8"; 516 | } 517 | 518 | .icon_invite:before { 519 | content: "\ebb9"; 520 | } 521 | 522 | .icon_launch_page:before { 523 | content: "\ebba"; 524 | } 525 | 526 | .icon_likegood:before { 527 | content: "\ebbb"; 528 | } 529 | 530 | .icon_index_line:before { 531 | content: "\ebbc"; 532 | } 533 | 534 | .icon_live:before { 535 | content: "\ebbd"; 536 | } 537 | 538 | .icon_link:before { 539 | content: "\ebbe"; 540 | } 541 | 542 | .icon_im_voice:before { 543 | content: "\ebbf"; 544 | } 545 | 546 | .icon_mobilephone:before { 547 | content: "\ebc0"; 548 | } 549 | 550 | .icon_dmail:before { 551 | content: "\ebc1"; 552 | } 553 | 554 | .icon_message:before { 555 | content: "\ebc2"; 556 | } 557 | 558 | .icon_new_recruit:before { 559 | content: "\ebc3"; 560 | } 561 | 562 | .icon_little_taget:before { 563 | content: "\ebc4"; 564 | } 565 | 566 | .icon_more:before { 567 | content: "\ebc5"; 568 | } 569 | 570 | .icon_left:before { 571 | content: "\ebc6"; 572 | } 573 | 574 | .icon_next_arrow:before { 575 | content: "\ebc7"; 576 | } 577 | 578 | .icon_notice:before { 579 | content: "\ebc8"; 580 | } 581 | 582 | .icon_nomemo:before { 583 | content: "\ebc9"; 584 | } 585 | 586 | .icon_newgroup:before { 587 | content: "\ebca"; 588 | } 589 | 590 | .icon_namecard:before { 591 | content: "\ebcb"; 592 | } 593 | 594 | .icon_phone:before { 595 | content: "\ebcc"; 596 | } 597 | 598 | .icon_qq:before { 599 | content: "\ebcd"; 600 | } 601 | 602 | .icon_photo:before { 603 | content: "\ebce"; 604 | } 605 | 606 | .icon_medal:before { 607 | content: "\ebcf"; 608 | } 609 | 610 | .icon_redpacket:before { 611 | content: "\ebd0"; 612 | } 613 | 614 | .icon_patriarch:before { 615 | content: "\ebd1"; 616 | } 617 | 618 | .icon_roundclose:before { 619 | content: "\ebd2"; 620 | } 621 | 622 | .icon_im_keyboard:before { 623 | content: "\ebd3"; 624 | } 625 | 626 | .icon_roundreduce:before { 627 | content: "\ebd4"; 628 | } 629 | 630 | .icon_railway:before { 631 | content: "\ebd5"; 632 | } 633 | 634 | .icon_QRcode:before { 635 | content: "\ebd6"; 636 | } 637 | 638 | .icon_savememo:before { 639 | content: "\ebd7"; 640 | } 641 | 642 | .icon_roundadd:before { 643 | content: "\ebd8"; 644 | } 645 | 646 | .icon_refresh:before { 647 | content: "\ebd9"; 648 | } 649 | 650 | .icon_search:before { 651 | content: "\ebda"; 652 | } 653 | 654 | .icon_scan:before { 655 | content: "\ebdb"; 656 | } 657 | 658 | .icon_send:before { 659 | content: "\ebdc"; 660 | } 661 | 662 | .icon_principal:before { 663 | content: "\ebdd"; 664 | } 665 | 666 | .icon_service:before { 667 | content: "\ebde"; 668 | } 669 | 670 | .icon_scan_namecard:before { 671 | content: "\ebdf"; 672 | } 673 | 674 | .icon_secret:before { 675 | content: "\ebe0"; 676 | } 677 | 678 | .icon_share:before { 679 | content: "\ebe1"; 680 | } 681 | 682 | .icon_signin_line:before { 683 | content: "\ebe2"; 684 | } 685 | 686 | .icon_sms:before { 687 | content: "\ebe3"; 688 | } 689 | 690 | .icon_sketch:before { 691 | content: "\ebe4"; 692 | } 693 | 694 | .icon_setting:before { 695 | content: "\ebe5"; 696 | } 697 | 698 | .icon_signal:before { 699 | content: "\ebe6"; 700 | } 701 | 702 | .icon_skin:before { 703 | content: "\ebe7"; 704 | } 705 | 706 | .icon_star:before { 707 | content: "\ebe8"; 708 | } 709 | 710 | .icon_subordinate:before { 711 | content: "\ebe9"; 712 | } 713 | 714 | .icon_task:before { 715 | content: "\ebea"; 716 | } 717 | 718 | .icon_statistics:before { 719 | content: "\ebeb"; 720 | } 721 | 722 | .icon_threeline_fill:before { 723 | content: "\ebec"; 724 | } 725 | 726 | .icon_study:before { 727 | content: "\ebed"; 728 | } 729 | 730 | .icon_voice:before { 731 | content: "\ebee"; 732 | } 733 | 734 | .icon_square:before { 735 | content: "\ebef"; 736 | } 737 | 738 | .icon_wechat:before { 739 | content: "\ebf0"; 740 | } 741 | 742 | .icon_sport:before { 743 | content: "\ebf1"; 744 | } 745 | 746 | .icon_work:before { 747 | content: "\ebf2"; 748 | } 749 | 750 | .icon_warn:before { 751 | content: "\ebf3"; 752 | } 753 | 754 | .icon_workmore:before { 755 | content: "\ebf4"; 756 | } 757 | 758 | .icon_safety:before { 759 | content: "\ebf5"; 760 | } 761 | 762 | .icon_workset:before { 763 | content: "\ebf6"; 764 | } 765 | 766 | .icon_voipphone:before { 767 | content: "\ebf7"; 768 | } 769 | 770 | .icon_shield:before { 771 | content: "\ebf8"; 772 | } 773 | 774 | .icon_shakehands:before { 775 | content: "\ebf9"; 776 | } 777 | 778 | .icon_video:before { 779 | content: "\ebfa"; 780 | } 781 | 782 | .icon_task_done:before { 783 | content: "\ebfb"; 784 | } 785 | 786 | .icon_meeting:before { 787 | content: "\ebfc"; 788 | } 789 | 790 | .icon_synergy:before { 791 | content: "\ebfd"; 792 | } 793 | 794 | .icon_workfile_line:before { 795 | content: "\ebfe"; 796 | } 797 | 798 | -------------------------------------------------------------------------------- /public/iconfont/original/iconfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaotoo/ReactForH5/4960a213e66581bbc2a88793165c2a8332fe2ae7/public/iconfont/original/iconfont.eot -------------------------------------------------------------------------------- /public/iconfont/original/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaotoo/ReactForH5/4960a213e66581bbc2a88793165c2a8332fe2ae7/public/iconfont/original/iconfont.ttf -------------------------------------------------------------------------------- /public/iconfont/original/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaotoo/ReactForH5/4960a213e66581bbc2a88793165c2a8332fe2ae7/public/iconfont/original/iconfont.woff -------------------------------------------------------------------------------- /public/iconfont/original/iconfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaotoo/ReactForH5/4960a213e66581bbc2a88793165c2a8332fe2ae7/public/iconfont/original/iconfont.woff2 -------------------------------------------------------------------------------- /public/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaotoo/ReactForH5/4960a213e66581bbc2a88793165c2a8332fe2ae7/public/img/favicon.png -------------------------------------------------------------------------------- /public/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaotoo/ReactForH5/4960a213e66581bbc2a88793165c2a8332fe2ae7/public/img/logo.png -------------------------------------------------------------------------------- /shell/analyze.sh: -------------------------------------------------------------------------------- 1 | npm run analyze -------------------------------------------------------------------------------- /shell/proxy.sh: -------------------------------------------------------------------------------- 1 | npm run proxy -------------------------------------------------------------------------------- /shell/removeCache.sh: -------------------------------------------------------------------------------- 1 | rm -rf node_modules/.cache/ -------------------------------------------------------------------------------- /shell/start.sh: -------------------------------------------------------------------------------- 1 | echo "\033[33m==================开始清理缓存==================\033[0m" 2 | rm -rf ../node_modules/.cache/ 3 | echo "\033[33m==================清理缓存结束==================\033[0m" 4 | 5 | echo "\033[33m==================开始启动应用==================\033[0m" 6 | npm run start -------------------------------------------------------------------------------- /shell/tslint.sh: -------------------------------------------------------------------------------- 1 | npm run tslint -------------------------------------------------------------------------------- /src/components/ChartComponent.tsx: -------------------------------------------------------------------------------- 1 | import React, { CSSProperties } from 'react'; 2 | import echarts, { ECharts, EChartOption } from 'echarts'; 3 | import { Bind } from 'lodash-decorators'; 4 | 5 | /** 6 | * Echarts 通用颜色设置项 7 | */ 8 | export const colorList: string[] = [ 9 | '#0099CC', 10 | '#FF9900', 11 | '#666699', 12 | '#FF6666', 13 | '#009966', 14 | '#FFCC99', 15 | '#CC6600', 16 | '#CC0066', 17 | '#0066CC', 18 | '#339933' 19 | ]; 20 | 21 | export const colorList2: string[][] = [ 22 | ['#2272A3', 'rgba(35,116,166,0.75);', 'rgba(34,114,163,0.50);', 'rgba(34,114,163,0.30)'], 23 | ['#BA4C6D', '#D67C7C', '#DE8181', '#EBB6A4'], 24 | ['#74A0A1', '#649DA3', '#73B5BD', '#82AFB5'], 25 | ['#F2D1B3', '#D48920', '#E09122', '#E99722'] 26 | ]; 27 | 28 | /** 29 | * 可视化图表(继承自echarts) 30 | * @description style 样式设置 31 | * @description className 自定义样式名 32 | * @description option 图表配置 @see https://echarts.baidu.com/option.html 33 | * @description onClick 图标点击事件 34 | */ 35 | interface IChartProps { 36 | style?: CSSProperties; 37 | className?: string; 38 | option: EChartOption; 39 | onClick?(params: any): void; 40 | } 41 | 42 | interface IChartState { } 43 | 44 | /** 45 | * 图表可视化组件 46 | */ 47 | export default class ChartComponent extends React.PureComponent { 48 | private chartElement: HTMLDivElement | undefined; 49 | private chartInstance: ECharts | undefined; 50 | 51 | constructor(props: IChartProps, context?: any) { 52 | super(props, context); 53 | } 54 | 55 | /** 56 | * 设置chart容器节点对象。 57 | * @param {HTMLDivElement} divElement 58 | */ 59 | @Bind() 60 | private setChartContainer(divElement: HTMLDivElement): void { 61 | this.chartElement = divElement; 62 | } 63 | 64 | /** 65 | * 监听浏览器窗口变化 66 | */ 67 | @Bind() 68 | private onResize(): void { 69 | this.chartInstance && this.chartInstance.resize(); 70 | } 71 | 72 | /** 73 | * 组装ECharts 74 | */ 75 | private executeECharts(props?: IChartProps): void { 76 | const chartProps: IChartProps = props || this.props; 77 | 78 | if (!this.chartInstance && this.chartElement) { 79 | this.chartInstance = echarts.init(this.chartElement); 80 | chartProps.onClick && this.chartInstance.on('click', (conf: any) => { 81 | chartProps.onClick && chartProps.onClick(conf); 82 | }); 83 | } 84 | 85 | if (this.chartInstance) { 86 | this.chartInstance.showLoading(); 87 | this.chartInstance.setOption(chartProps.option); 88 | this.chartInstance.hideLoading(); 89 | } 90 | } 91 | 92 | public componentDidMount(): void { 93 | this.executeECharts(); 94 | window.addEventListener('resize', this.onResize); 95 | } 96 | 97 | public componentWillUnmount(): void { 98 | window.removeEventListener('resize', this.onResize); 99 | this.chartInstance && this.chartInstance.dispose(); 100 | this.chartInstance = undefined; 101 | } 102 | 103 | public componentWillReceiveProps(nextProps: IChartProps) { 104 | this.executeECharts(nextProps); 105 | } 106 | 107 | public render(): React.ReactNode { 108 | const height: string | number = this.props.style && this.props.style.height || 200; 109 | return ( 110 |
115 | ); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/components/Loading.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2018-present, DiDi, Inc. 3 | * All rights reserved. 4 | * 5 | * @author zhao668055@126.com 6 | * 7 | */ 8 | import React from 'react'; 9 | import Icon from '@components/icon/Icon'; 10 | 11 | /** 12 | * Loading 13 | */ 14 | export default class LoadingComponent extends React.Component { 15 | public render(): React.ReactNode { 16 | return ( 17 |
26 | 33 | 40 | 加载中... 41 | 42 |
43 | ); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/components/icon/Icon.less: -------------------------------------------------------------------------------- 1 | .icon { 2 | padding: 0 1px; 3 | display: inline-block; 4 | } -------------------------------------------------------------------------------- /src/components/icon/Icon.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import style from './Icon.less'; 3 | 4 | interface IIconProps { 5 | type: string; 6 | className?: string; 7 | style?: React.CSSProperties; 8 | } 9 | 10 | interface IIconState { } 11 | 12 | class IconComponent extends React.Component { 13 | constructor(props: IIconProps, context?: any) { 14 | super(props, context); 15 | } 16 | 17 | public render(): React.ReactNode { 18 | return ( 19 | 28 | {this.props.children} 29 | 30 | ); 31 | } 32 | } 33 | 34 | export default IconComponent; 35 | -------------------------------------------------------------------------------- /src/global.less: -------------------------------------------------------------------------------- 1 | :global { 2 | html { 3 | font-size: 100px; 4 | 5 | body { 6 | font-size: 0.14rem; 7 | background-color: #fff; 8 | overflow-x: hidden; 9 | overflow-y: auto; 10 | } 11 | 12 | #root { 13 | height: 100%; 14 | } 15 | 16 | .am-list-item { 17 | padding-left: 0; 18 | 19 | .am-list-line { 20 | padding-left: .15rem; 21 | } 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /src/layouts/Index.conf.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 不需要公共导航 3 | */ 4 | export const UnNeedNavBar = (): boolean => { 5 | // 路由列表 6 | const routerList: string[] = ['login', 'register']; 7 | 8 | return !new RegExp(routerList.join('|'), 'gi').test(location.pathname); 9 | }; 10 | -------------------------------------------------------------------------------- /src/layouts/Index.less: -------------------------------------------------------------------------------- 1 | .appContent { 2 | min-height: 100%; 3 | 4 | .content { 5 | min-height: 100%; 6 | padding: 0 0 60px 0; 7 | } 8 | } -------------------------------------------------------------------------------- /src/layouts/Index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { connect } from 'dva'; 3 | import router from 'umi/router'; 4 | import Request from '@utils/Request'; 5 | import withRouter from 'umi/withRouter'; 6 | import { IGlobalInfo } from '@globalModels/Global'; 7 | import { IGlobalInterface } from '@utils/GlobalInterface'; 8 | import { UnNeedNavBar } from './Index.conf'; 9 | import NavBar from './navBar/NavBar'; 10 | import style from './Index.less'; 11 | 12 | interface IIndexProps extends IGlobalInterface { } 13 | 14 | interface IIndexState { } 15 | 16 | class IndexComponent extends React.Component { 17 | constructor(props: IIndexProps, context?: any) { 18 | super(props, context); 19 | } 20 | 21 | /** 22 | * 获取全局需要的数据 23 | */ 24 | private async fetchGlobalInfo(): Promise { 25 | const result: IGlobalInfo = await Request.get('/api/globalInfo') || {}; 26 | 27 | result.isLogin ? 28 | this.props.dispatch({ 29 | type: 'GlobalInfoModels/changeGlobalInfo', 30 | data: result 31 | }) : 32 | router.push('login'); 33 | } 34 | 35 | public componentWillMount(): void { 36 | this.fetchGlobalInfo(); 37 | } 38 | 39 | public render(): React.ReactNode { 40 | return ( 41 |
42 |
43 | {this.props.children} 44 |
45 | {UnNeedNavBar() ? : ''} 46 |
47 | ); 48 | } 49 | } 50 | 51 | export default withRouter(connect()(IndexComponent)); 52 | -------------------------------------------------------------------------------- /src/layouts/navBar/NavBar.less: -------------------------------------------------------------------------------- 1 | .navBarContent { 2 | width: 100%; 3 | position: fixed; 4 | bottom: 0; 5 | left: 0; 6 | z-index: 9; 7 | 8 | :global { 9 | .am-tab-bar { 10 | // box-shadow: 0 5px 20px 0 #999; 11 | 12 | .am-tab-bar-bar { 13 | height: 60px; 14 | border: 0; 15 | background-color: #f5f5f5 !important; 16 | } 17 | } 18 | } 19 | 20 | .itemIcon, 21 | .itemIconCur { 22 | color: #666; 23 | font-size: 24px; 24 | width: 26px; 25 | height: 26px; 26 | line-height: 26px; 27 | text-align: center; 28 | } 29 | 30 | .itemIconCur { 31 | color: #06c; 32 | } 33 | 34 | .itemContent { 35 | width: 100%; 36 | height: 100%; 37 | position: relative; 38 | z-index: 1; 39 | } 40 | } -------------------------------------------------------------------------------- /src/layouts/navBar/NavBar.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import router from 'umi/router'; 3 | import { Bind } from 'lodash-decorators'; 4 | import { TabBar } from 'antd-mobile'; 5 | import Icon from '@components/icon/Icon'; 6 | import { NavBarList, INavBarInfo } from './NavBarConfig'; 7 | import style from './NavBar.less'; 8 | 9 | interface INavBarProps { } 10 | 11 | interface INavBarState { 12 | selectedTab: string; 13 | } 14 | 15 | class NavBarComponent extends React.Component { 16 | constructor(props: INavBarProps, context?: any) { 17 | super(props, context); 18 | this.state = { 19 | selectedTab: location.pathname 20 | }; 21 | } 22 | 23 | /** 24 | * TabBar点击触发 25 | * @param path 26 | */ 27 | @Bind() 28 | private onPress(path: string): void { 29 | this.setState({ 30 | selectedTab: path 31 | }, () => { 32 | router.push(this.state.selectedTab); 33 | }); 34 | } 35 | 36 | /** 37 | * 组装导航 38 | */ 39 | private executeTabBarItem(): React.ReactNode { 40 | const itemNode: React.ReactNode = NavBarList.map((item: INavBarInfo, index: number) => { 41 | return ( 42 | } 47 | selectedIcon={} 48 | selected={this.state.selectedTab === item.path} 49 | onPress={this.onPress.bind(this, item.path)} 50 | /> 51 | ); 52 | }); 53 | return itemNode; 54 | } 55 | 56 | public render(): React.ReactNode { 57 | return ( 58 |
59 | 60 | {this.executeTabBarItem()} 61 | 62 |
63 | ); 64 | } 65 | } 66 | 67 | export default NavBarComponent; 68 | -------------------------------------------------------------------------------- /src/layouts/navBar/NavBarConfig.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @description title 标题 3 | * @description path 路径 4 | * @description badge 徽标数字 5 | * @description icon 自定义图标 6 | */ 7 | export interface INavBarInfo { 8 | title: string; 9 | path: string; 10 | badge: number; 11 | icon: string; 12 | } 13 | 14 | export const NavBarList: INavBarInfo[] = [{ 15 | title: '首页', 16 | path: '/', 17 | badge: 0, 18 | icon: 'dianpu-xianxing' 19 | }, { 20 | title: '购物车', 21 | path: '/shoppingCar', 22 | badge: 1, 23 | icon: 'caigou-xianxing' 24 | }, { 25 | title: '订单列表', 26 | path: '/orderList', 27 | badge: 20, 28 | icon: 'liebiao' 29 | }, { 30 | title: '我', 31 | path: '/setting', 32 | badge: 0, 33 | icon: 'icon_signal' 34 | }]; 35 | -------------------------------------------------------------------------------- /src/models/Global.ts: -------------------------------------------------------------------------------- 1 | export interface IGlobalInfo { 2 | userName: string; 3 | isLogin: boolean; 4 | } 5 | 6 | const defaultState: IGlobalInfo = { 7 | userName: 'noName', 8 | isLogin: false 9 | }; 10 | 11 | export default { 12 | namespace: 'GlobalInfoModels', 13 | state: { ...defaultState }, 14 | reducers: { 15 | // 保存 16 | changeGlobalInfo(state: IGlobalInfo, { data }) { 17 | return { 18 | ...state, 19 | ...data 20 | }; 21 | } 22 | }, 23 | effects: { 24 | // 更改 25 | // * xxx({ data }, { put }) { 26 | // yield put({ 27 | // type: 'saveGlobalInfo', 28 | // data: data 29 | // }); 30 | // } 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /src/pages/404.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Icon from '@components/icon/Icon'; 3 | import style from './Index.less'; 4 | 5 | class ErrorComponent extends React.Component { 6 | public render(): React.ReactNode { 7 | return ( 8 |
9 |
10 | 11 | 很抱歉,您的访问异常了,请稍后重试~ 12 |
13 |
14 | ); 15 | } 16 | } 17 | 18 | export default ErrorComponent; 19 | -------------------------------------------------------------------------------- /src/pages/Index.less: -------------------------------------------------------------------------------- 1 | .indexContent { 2 | padding: 0; 3 | overflow: visible; 4 | } 5 | 6 | .errorContent { 7 | height: 600px; 8 | text-align: center; 9 | position: relative; 10 | 11 | .errorMsg { 12 | height: 50px; 13 | line-height: 50px; 14 | font-size: 18px; 15 | margin: auto; 16 | position: absolute; 17 | left: 0; 18 | right: 0; 19 | top: 0; 20 | bottom: 0; 21 | z-index: 1; 22 | 23 | .errorIcon { 24 | color: #f00; 25 | font-size: 50px; 26 | line-height: 50px; 27 | vertical-align: middle; 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/pages/Index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Welcome from './welcome/Welcome'; 3 | import style from './Index.less'; 4 | 5 | interface IIndexProps { } 6 | 7 | interface IIndexState { } 8 | 9 | class IndexComponent extends React.Component { 10 | constructor(props: IIndexProps, context?: any) { 11 | super(props, context); 12 | } 13 | 14 | public render(): React.ReactNode { 15 | return ( 16 |
17 | 18 |
19 | ); 20 | } 21 | } 22 | 23 | export default IndexComponent; 24 | -------------------------------------------------------------------------------- /src/pages/document.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <% var title = context.config.plugins[0][1].title.defaultTitle; %> 5 | <% var version = new Date().getTime(); %> 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | <%= title %> 21 | 22 | 23 | 24 |
25 |
26 | 加载中... 27 |
28 |
29 | 30 | 31 | -------------------------------------------------------------------------------- /src/pages/empty/views/Empty.less: -------------------------------------------------------------------------------- 1 | .emptyContent { 2 | min-height: 300px; 3 | line-height: 300px; 4 | text-align: center; 5 | } -------------------------------------------------------------------------------- /src/pages/empty/views/Empty.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import style from './Empty.less'; 3 | 4 | interface IEmptyProps { } 5 | 6 | interface IEmptyState { } 7 | 8 | class EmptyComponent extends React.Component { 9 | constructor(props: IEmptyProps, context?: any) { 10 | super(props, context); 11 | } 12 | 13 | public render(): React.ReactNode { 14 | return ( 15 |
16 | 请开始你的表演 17 |
18 | ); 19 | } 20 | } 21 | 22 | export default EmptyComponent; 23 | -------------------------------------------------------------------------------- /src/pages/forbidden/views/Forbidden.less: -------------------------------------------------------------------------------- 1 | .content { 2 | line-height: 500px; 3 | text-align: center; 4 | } -------------------------------------------------------------------------------- /src/pages/forbidden/views/Forbidden.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import style from './Forbidden.less'; 3 | 4 | interface IForbiddenProps { } 5 | 6 | interface IForbiddenState { } 7 | 8 | class ForbiddenComponent extends React.Component { 9 | constructor(props: IForbiddenProps, context?: any) { 10 | super(props, context); 11 | } 12 | 13 | public render(): React.ReactNode { 14 | return ( 15 |
16 | 没有权限 17 |
18 | ); 19 | } 20 | } 21 | 22 | export default ForbiddenComponent; 23 | -------------------------------------------------------------------------------- /src/pages/login/views/Login.less: -------------------------------------------------------------------------------- 1 | .loginContent { 2 | .banner { 3 | height: 200px; 4 | background: url(./img/bg_1.jpg) center center no-repeat; 5 | background-size: cover; 6 | } 7 | 8 | .btnbox { 9 | padding: 10px; 10 | 11 | :global { 12 | .am-list-item { 13 | margin-bottom: 20px; 14 | } 15 | } 16 | } 17 | 18 | .regLink { 19 | line-height: 30px; 20 | text-align: center; 21 | } 22 | } -------------------------------------------------------------------------------- /src/pages/login/views/Login.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Link from 'umi/link'; 3 | import router from 'umi/router'; 4 | import { Bind } from 'lodash-decorators'; 5 | import { Button, InputItem } from 'antd-mobile'; 6 | import Icon from '@components/icon/Icon'; 7 | import style from './Login.less'; 8 | 9 | interface ILoginProps { } 10 | 11 | interface ILoginState { 12 | loading: boolean; 13 | numError: boolean; 14 | pwdError: boolean; 15 | disabled: boolean; 16 | } 17 | 18 | interface ILoginQuery { 19 | userNum: string; 20 | password: string; 21 | } 22 | 23 | class LoginComponent extends React.Component { 24 | private LoginQuery: ILoginQuery = { 25 | userNum: '', 26 | password: '' 27 | }; 28 | 29 | constructor(props: ILoginProps, context?: any) { 30 | super(props, context); 31 | this.state = { 32 | loading: false, 33 | numError: false, 34 | pwdError: false, 35 | disabled: true 36 | }; 37 | } 38 | 39 | @Bind() 40 | private onNumInput(value: string): void { 41 | this.LoginQuery.userNum = value; 42 | this.resetButtonDisabled(); 43 | } 44 | 45 | @Bind() 46 | private onPwdInput(value: string): void { 47 | this.LoginQuery.password = value; 48 | this.resetButtonDisabled(); 49 | } 50 | 51 | @Bind() 52 | private resetButtonDisabled(): void { 53 | this.setState({ 54 | disabled: this.LoginQuery.userNum && this.LoginQuery.password ? false : true 55 | }); 56 | } 57 | 58 | @Bind() 59 | private onSubmit(): void { 60 | this.setState({ 61 | loading: true, 62 | disabled: true 63 | }, () => { 64 | setTimeout(() => { 65 | this.setState({ 66 | loading: false, 67 | disabled: false 68 | }); 69 | router.push('/'); 70 | }, 3000); 71 | }); 72 | } 73 | 74 | public render(): React.ReactNode { 75 | 76 | return ( 77 |
78 |
79 |
80 | 88 | 账号 89 | 90 | 98 | 密码 99 | 100 | 108 |
109 |
110 | 没有账号,立即注册开启体验之旅~ 111 |
112 |
113 | ); 114 | } 115 | } 116 | 117 | export default LoginComponent; 118 | -------------------------------------------------------------------------------- /src/pages/login/views/img/bg_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaotoo/ReactForH5/4960a213e66581bbc2a88793165c2a8332fe2ae7/src/pages/login/views/img/bg_1.jpg -------------------------------------------------------------------------------- /src/pages/orderList/models/OrderList.ts: -------------------------------------------------------------------------------- 1 | import * as orderListService from '../services/OrderList'; 2 | 3 | export interface IOrderListInfo { 4 | list: any[]; 5 | total: number; 6 | } 7 | 8 | const defaultState: IOrderListInfo = { 9 | list: [], 10 | total: 0 11 | }; 12 | 13 | export default { 14 | namespace: 'OrderList_Models', 15 | state: { ...defaultState }, 16 | reducers: { 17 | changeState(state: IOrderListInfo, { data }) { 18 | return { 19 | ...state, 20 | ...data 21 | }; 22 | } 23 | }, 24 | effects: { 25 | * fetchOrderList({ data }, { call, put }) { 26 | const result = yield call(orderListService.fetchOrderList, data); 27 | yield put({ 28 | type: 'changeState', 29 | data: { 30 | list: result, 31 | total: 125 32 | } 33 | }); 34 | } 35 | }, 36 | subscriptions: { 37 | setup({ history, dispatch }) { 38 | return history.listen(({ pathname, query }) => { 39 | pathname === '/orderList' && dispatch({ 40 | type: 'fetchOrderList', 41 | data: query 42 | }); 43 | }); 44 | } 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /src/pages/orderList/services/OrderList.ts: -------------------------------------------------------------------------------- 1 | import Request from '@utils/Request'; 2 | 3 | export function fetchOrderList({ page = 1 }) { 4 | return Request.get('/api/orderList', { 5 | params: { 6 | page: page, 7 | limit: 5 8 | } 9 | }); 10 | } 11 | -------------------------------------------------------------------------------- /src/pages/orderList/views/OrderList.less: -------------------------------------------------------------------------------- 1 | .orderListContent { 2 | :global { 3 | .am-tabs { 4 | z-index: 2; 5 | } 6 | 7 | .am-swipe-btn-text { 8 | padding: 0; 9 | } 10 | } 11 | 12 | .listBox { 13 | margin-top: -1px; 14 | margin-bottom: -1px; 15 | } 16 | 17 | .listItem { 18 | .main { 19 | height: 100px; 20 | display: flex; 21 | 22 | p { 23 | padding: 0; 24 | margin: 0; 25 | } 26 | 27 | .image { 28 | width: 100px; 29 | min-width: 100px; 30 | height: 100px; 31 | background: url(./img/product1.jpg) center center no-repeat; 32 | background-size: cover; 33 | border-radius: 5px; 34 | } 35 | 36 | .point { 37 | width: 100%; 38 | line-height: 30px; 39 | padding-left: 10px; 40 | position: relative; 41 | z-index: 1; 42 | overflow: hidden; 43 | 44 | .status { 45 | color: #999; 46 | font-size: 12px; 47 | width: 35px; 48 | height: 35px; 49 | line-height: 30px; 50 | border: 2px solid #ccc; 51 | border-radius: 100%; 52 | transform: rotate(55deg); 53 | text-align: center; 54 | position: absolute; 55 | top: 0; 56 | right: 0; 57 | z-index: 3; 58 | } 59 | 60 | .title { 61 | font-size: 16px; 62 | text-overflow: ellipsis; 63 | white-space: nowrap; 64 | word-break: break-all; 65 | overflow: hidden; 66 | } 67 | 68 | .price { 69 | color: #f00; 70 | text-align: right; 71 | } 72 | 73 | .time { 74 | color: #999; 75 | font-size: 12px; 76 | text-align: right; 77 | } 78 | } 79 | } 80 | 81 | .actionList { 82 | line-height: 50px; 83 | font-size: 14px; 84 | padding-top: 5px; 85 | display: flex; 86 | flex-wrap: nowrap; 87 | justify-content: space-between; 88 | 89 | :global { 90 | .am-button { 91 | color: #666; 92 | } 93 | } 94 | } 95 | } 96 | 97 | .empty { 98 | :global { 99 | .iconfont { 100 | margin-right: 5px; 101 | } 102 | 103 | .am-list-content { 104 | color: #999; 105 | font-size: 14px; 106 | font-weight: 400; 107 | text-align: center; 108 | } 109 | } 110 | } 111 | } -------------------------------------------------------------------------------- /src/pages/orderList/views/OrderList.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { connect } from 'dva'; 3 | import { Models } from 'rmc-tabs'; 4 | import { Bind } from 'lodash-decorators'; 5 | import { List, Tabs, Button } from 'antd-mobile'; 6 | import Icon from '@components/icon/Icon'; 7 | import { IOrderListInfo } from '../models/OrderList'; 8 | import { OrderRebuy } from './util/OrderRebuy'; 9 | import { OrderDelete } from './util/OrderDelete'; 10 | import { OrderEvaluate } from './util/OrderEvaluate'; 11 | import style from './OrderList.less'; 12 | 13 | interface IOrderListProps extends IOrderListInfo { } 14 | 15 | interface IOrderListState { 16 | tabsKey: string; 17 | } 18 | 19 | class ListComponent extends React.Component { 20 | constructor(props: IOrderListProps, context?: any) { 21 | super(props, context); 22 | this.state = { 23 | tabsKey: '0' 24 | }; 25 | } 26 | 27 | @Bind() 28 | private executeListItem(list: any): JSX.Element { 29 | const itemNode: JSX.Element[] = list.map((item: any, index: number) => { 30 | return ( 31 | 32 |
33 |
34 |
35 |
36 |
完成
37 |

{item.productName}

38 |

¥{item.price}

39 |

{item.createTime}

40 |
41 |
42 |
43 | 49 | 55 | 61 |
62 |
63 | 64 | ); 65 | }); 66 | return ( 67 | 68 | { 69 | itemNode.length ? itemNode : 70 | 71 | 暂无数据 72 | 73 | } 74 | 75 | ); 76 | } 77 | 78 | @Bind() 79 | private onChange(tab: Models.TabData, index: number): void { 80 | this.setState({ 81 | tabsKey: tab.key as string 82 | }); 83 | } 84 | 85 | public render(): React.ReactNode { 86 | const key = this.state.tabsKey; 87 | const tabs = [{ 88 | title: '全部', key: '0' 89 | }, { 90 | title: '待付款', key: '1' 91 | }, { 92 | title: '已完成', key: '2' 93 | }, { 94 | title: '已取消', key: '3' 95 | }]; 96 | 97 | return ( 98 |
99 | 103 |
107 | {this.executeListItem(this.props.list)} 108 |
109 |
113 | {this.executeListItem([])} 114 |
115 |
119 | {this.executeListItem([])} 120 |
121 |
125 | {this.executeListItem([])} 126 |
127 |
128 | ); 129 | } 130 | } 131 | 132 | export default connect( 133 | (state: any) => state.OrderList_Models 134 | )(ListComponent); 135 | -------------------------------------------------------------------------------- /src/pages/orderList/views/img/product1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaotoo/ReactForH5/4960a213e66581bbc2a88793165c2a8332fe2ae7/src/pages/orderList/views/img/product1.jpg -------------------------------------------------------------------------------- /src/pages/orderList/views/util/OrderDelete.tsx: -------------------------------------------------------------------------------- 1 | import { ActionSheet, Toast } from 'antd-mobile'; 2 | 3 | /** 4 | * 删除订单 5 | * @param orderId 6 | */ 7 | export const OrderDelete = (orderId: number): void => { 8 | ActionSheet.showActionSheetWithOptions({ 9 | maskClosable: true, 10 | cancelButtonIndex: 1, 11 | destructiveButtonIndex: 0, 12 | options: ['确定删除', '取消'], 13 | message: '删除后将无法恢复' 14 | }, (buttonIndex: number) => { 15 | if (buttonIndex === 0) { 16 | Toast.success('删除成功'); 17 | } 18 | }); 19 | }; 20 | -------------------------------------------------------------------------------- /src/pages/orderList/views/util/OrderEvaluate.tsx: -------------------------------------------------------------------------------- 1 | import { ActionSheet, Toast } from 'antd-mobile'; 2 | 3 | /** 4 | * 订单评价 5 | * @param orderId 6 | */ 7 | export const OrderEvaluate = (orderId: number): void => { 8 | ActionSheet.showActionSheetWithOptions({ 9 | maskClosable: true, 10 | cancelButtonIndex: 3, 11 | destructiveButtonIndex: 0, 12 | options: ['好评', '中评', '差评', '取消'], 13 | message: '请选择评分' 14 | }, (buttonIndex: number) => { 15 | buttonIndex !== 3 && Toast.success('评价成功'); 16 | }); 17 | }; 18 | -------------------------------------------------------------------------------- /src/pages/orderList/views/util/OrderRebuy.tsx: -------------------------------------------------------------------------------- 1 | import { Toast } from 'antd-mobile'; 2 | 3 | /** 4 | * 再次购买 5 | * @param orderId 6 | */ 7 | export const OrderRebuy = (orderId: number): void => { 8 | Toast.success('已加入到购物车'); 9 | }; 10 | -------------------------------------------------------------------------------- /src/pages/register/views/Register.agree.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Modal } from 'antd-mobile'; 3 | import style from './Register.less'; 4 | 5 | export const RegisterAgree = (): void => { 6 | const content: React.ReactNode = ( 7 |
8 | @@@用户服务协议
9 | 1.1
10 | @@@(###)的各项网络服务的所有权和运营权归@@@所有。 11 | @@@依照本服务条款及其不时发布的操作规则提供网络服务,此外,当服务使用者(以下称“用户”)使用@@@各项分类服务时, 用户应当同意本服务条款的全部内容并遵守与该项服务相关的规则与要点。 12 | 前述所有规则与要点均构成本服务条款的一部分。 13 | 用户必须完全同意所有服务条款并完成注册程序,才能成为@@@的正式用户。 14 | @@@:服务条款 关于网站服务内容
15 | 2.1
16 | @@@网络服务的具体内容由@@@根据实际情况提供,包括但不限于文字、图片、视频、用户、空间、小组等信息和频道。 17 | @@@保留随时变更、中断或终止部分或全部网络服务的权利。 18 | 本网为用户提供的电子信息空间是为用户储存信息而设,用户有权在合法范围内自由上传、储存电子信息,用户所上传信息的行为并非约稿范畴之列而系自发行为,本网无需对此支付任何费用。
19 | 2.2
本网站的内容主要来自注册用户所发表的文章。 20 | 本网站用户以任何形式上传、发布于本网站的信息内容,为用户个人行为,仅代表用户或作者个人观点,与本站立场无关。 21 | 用户自行承担其上传的信息内容产生的一切法律责任。如果第三方对该内容提出包括版权在内的异议,本站应核实第三方的权利请求,将该内容删除。 22 | 2.3 在本网站公共论坛发布内容时,请严格遵守《中华人民共和国著作权法》;转贴文章, 请注明原始出处和时间,并注意原作者的版权声明,用户需承担转贴可能引起的版权责任。 23 | 2.4 用户理解@@@仅提供相关的网络服务, 除此之外与相关网络服务有关的设备(如电脑、调制解调器及其他与接入互联网有关的装置)及所需的费用(如为接入互联网而支付的电话费及上网费)均应由用户自行负担。 24 | 用户理解并同意:@@@有权决定授予用户使用电子空间的大小并有权根据公司经营情况而减少或增加用户的电子使用空间或决定是否转为有偿服务。 25 | @@@:服务条款 服务的变更、中断或终止 26 | 3.1 鉴于网络服务的特殊性,@@@有权随时变更或中断或终止部分或全部网络服务,不需对用户或第三方负责。 27 | 3.2 为了网站的正常运行, @@@定期或不定期地对提供网络服务的平台(如互联网网站、移动网络等)或相关的设备进行检修或者维护而造成网络服务的中断, 28 | @@@将尽力避免服务中断或将中断时间限制在最短时间内,在合理时间内的服务中断,@@@无需为此承担任何责任。 29 | 3.3 如发生下列任何一种情形,@@@有权随时中断或终止向用户提供网络服务(含封禁帐号、IP等)而无需对用户或任何第三方承担任何责任: 30 | (1)用户提供的资料不真实; 31 | (2)利用本网服务损害他人的知识产权或名誉权等合法权利。 32 | (3)用户经本网要求(包括但不限于因用户发布信息侵权等事因)而拒绝提供真实姓名、住址、联系方式等信息。 33 | (4)用户有违反本服务条款规定的其他行为; 34 | 3.4 @@@有权决定对曾经免费使用的业务收取相应的费用。在此情况下,@@@会提前10天在网站进行公告。 如用户拒绝支付该费用,@@@有权中断所提供的网络服务。 35 | @@@:服务条款 网上注册 36 | 4.1 用户在申请使用@@@网络服务时,必须向@@@提供准确的个人资料,如个人资料有任何变动,必须及时更新。 37 | 用户一旦注册成功,成为@@@的合法用户,将得到一个密码和用户名。每个用户应当对以其用户名进行的所有活动和事件承担全部责任。 38 | @@@:服务条款 用户名、用户密码和安全性 39 | 5.1 用户将对用户名和密码安全承担全部责任。用户可随时根据提示改变用户的密码。 40 | 用户不应将其帐号、密码转让或出借予他人使用。如用户发现其帐号遭他人非法使用或存在安全漏洞的情况,应立即通知@@@。 因黑客行为或用户的保管疏忽导致帐号、密码遭他人非法使用,@@@不承担任何责任。 41 | 5.2 如用户注册的免费网络服务的帐号在任何连续 180 日内未实际使用,则@@@有权删除该帐号并停止为该用户提供相关的网络服务。 42 | @@@:服务条款 用户隐私制度 43 | 6.1 尊重和保护用户个人隐私是@@@的一项基本政策。 @@@不会在未经合法用户授权时对外披露用户注册资料及用户保存在@@@中的非公开内容,但下列情况除外: 44 | (1) 事先获得用户的明确授权; 45 | (2) 根据有关法律法规的规定或相关政府主管部门的要求; 46 | (3) 为维护社会公共利益的需要; 47 | (4) 为维护@@@的合法权益。 48 | @@@:服务条款 对用户的管理 49 | 7.1 用户必须遵守以下原则 50 | (1) 遵守中国有关法律和法规; 51 | (2) 遵守所有使用网络服务的网络协议、规定、程序和惯例; 52 | (3) 不得为任何非法目的而使用网络服务系统; 53 | (4) 不得传输任何骚扰性的、中伤他人的、辱骂性的、恐吓性的、庸俗的、淫秽的、教唆他人实施犯罪行为等非法的信息资料; 54 | (5) 不得侵犯其他任何第三方的专利权、著作权、商标权、名誉权、肖像权及其他任何合法权益; 55 | 此外,本网有权对用户发布的可能导致社会负面影响的敏感信息予以删除(本网有权对是否为敏感信息进行认定)。 本网站有权认定和删除提交者所提交的任何不符合国家法律、法规和政策的任何言论、文字和图片。 56 | (6) 不得利用@@@网络服务系统进行任何不利于@@@的行为; 57 | (7) 不干扰或混乱网络服务; 58 | (8) 未经许可不得非法进入其它电脑系统。 59 | (9) 不得恶意修改他人上传的信息。 60 | 用户应严格遵守如上内容,违规用户将受到包括信用扣除、封禁帐号、IP等不同形式的处罚。 61 | 7.2 用户需独立对自己在网上的行为承担法律责任。 62 | 若用户的行为不符合上述服务条款,@@@有权做出独立判断立即取消用户服务帐号, 用户若在@@@网上散布和传播反动、色情或其他违反国家法律的信息,@@@的系统记录有可能作为用户违反法律的证据。 63 | 7.3 @@@不对用户所发布信息的删除或储存失败承担任何责任。 64 | @@@有权判定用户的行为是否符合中国法律法规的规定以及@@@服务条款的要求, 如果用户违背了中国法律法规的规定或服务条款的规定,@@@有中断对其提供服务的权利。 65 | 7.4 对于用户通过@@@网络技术服务(包括但不限于文字、图片、视频、用户、空间、小组等信息和频道)上传到@@@网上可公开获取区域的任何内容, 66 | 用户同意授予@@@在全世界范围内永久性的、不可撤销的、免费的使用权和进行再许可的权利(包括开发和运营各类电信增值业务及无线互联网业务, 如:短信、彩信、WAP、IVR、手机报、手机客户端等形式)。 67 | 7.5 用户同意:本网站中的内容除作者申明保留版权或该内容从其他网站转载而附带有原所有站的版权声明者, 68 | 其内容的复制权、发行权、信息网络传播权、改编权、翻译权、汇编权等权利归@@@所有,@@@有权就第三方的侵权行为独立提起诉讼并取得收益。 69 | 7.6 用户上传本网站的信息内容视为许可本站以合理的方式使用, 70 | 本站有权对其中精彩的图文进行推广(含站内首页、子频道等链接推广或编辑出版等)而无需对此支付任何费用。 71 | 此外,用户对本网为推广市场授权他人使用其图文的行为表示理解并承诺不收取任何费用,@@@可授权第三方标示来源“@@@”,用户愿意以此作为对网站做出的贡献。 72 | @@@:服务条款 关于内容所有权 73 | 8.1 @@@对其独立采编的或从第三方获得合法许可的信息内容, 包括但不限于文字、软件、声音、图片、录像、图表等,拥有所有权和合法使用权。 所有这些内容受版权、商标和其它财产所有权法律的保护。 74 | 8.2 用户只有在获得@@@或其他相关权利人的授权之后才能使用这些内容,而不能擅自复制、传播、修改这些内容、 或未经@@@及其他有权许可方书面许可创造与上述内容有关的派生内容或产品。 75 | 个人网站转载刊登@@@文章图片,请在文章题目附近用显要字体写明来自@@@并链接到 ###。 除合理使用外,未经许可,任何人不得大规模复制本网内容; 76 | 8.3 已经载本站原创文章图片的媒体或者商业网站,除了@@@的合作者外, 请在文章图片题目附近用显要字体写明来自@@@并链接到 ### , 对此,@@@仍然保留索取费用的权利; 77 | 8.4 关于图片:本站独立拍摄的图片任何媒体及网站均可以在不删除版权标志及标明出处的前提下使用,但本网站不排除会收取一定的费用。 78 | @@@:服务条款 免责声明 79 | @@@在我们能知悉的范围内努力保证所有采写文章的真实性和正确性,但不对真实性和正确性做任何保证。 80 | 本站采写文章图片如果和事实有所出入,本站不承担连带责任;本网站所刊载的文章资料、图片、图表仅供参考使用。 81 | 本站所刊载的内容,并不代表同意其说法或描述,仅为提供更多信息,也不构成任何投资建议、医疗建议等。 82 | 用户同意对@@@网络服务的使用承担全部风险,并对因其使用@@@网络服务而产生的一切后果承担全部风险, 83 | @@@对用户不作任何类型的担保,也不承担任何责任。 84 | @@@不担保网络服务一定能满足用户的要求,也不担保网络服务不会中断,对服务的及时性、安全性、准确性都不作担保。 85 | 对于因不可抗力或@@@不能避免或控制的原因造成的网络服务中断或其它缺陷,@@@不承担任何责任,但将尽力减少因此而给用户造成的损失和影响。 86 | 9.1 @@@采用的非本站原创文章图片等内容 87 | 9.1.1 如果您是文章、图片等等资料的版权所有人,请与@@@联系并说明具体文章标题,@@@会及时加上版权信息,如果您反对@@@的使用, 本着对版权人尊重的原则,@@@会立即取消有版权问题的内容。 88 | 9.1.2 在本网站发表、转载的文章仅代表作者本人观点,本网站没有义务查实文章或图片、音频、视频文件的出处及其真实性。 89 | 9.1.3 本网站上用户所发表的文章及其它附属品(如示例代码、截图及音、视频等),如果侵犯了第三方的知识产权或其他权利, 责任由作者或转载者本人承担,本网站对此不承担责任。 90 | 9.2 其他说明 91 | 9.2.1 @@@对于任何包含、经由、或链接、下载或从任何与本网站有关服务(以下简称「服务」)所获得的资讯、内容或广告(以下简称「资料」), 92 | 不声明或保证其内容的正确性或可靠性;并且,对于您通过「服务」上的广告、资讯或邀约而展示、购买或取得的任何产品、资讯或资料(「产品」), 93 | 本网亦不负品质保证的责任。 您于此接受并承认信赖任何「资料」所生的风险应自行承担。@@@,有权但无此义务,改善或更正在「服务」或「资料」任何部分的错误或疏失。 94 | 9.2.2 @@@的服务与资料是基于「现状」提供,而且@@@明确地表示拒绝对于「服务」、「资料」或「产品」给予任何明示或暗示的保证,包括但不限于, 得为商业使用或适合于特定目的的保证。 95 | @@@对于因「服务」、「资料」或「产品」所生的任何直接、间接、附带的或因此而导致的衍生性损失概不负责。 96 | 9.2.3 @@@尊重他人的任何权利 ( 包括知识产权 ) ,同时也要求@@@的使用者也尊重他人之权利。在适当情况下,自行决定终止侵害或违反他人权利的使用者的帐号。 97 | 9.2.4 @@@不担保有关网络服务一定能满足用户的全部要求,也不担保网络服务不会受中断,对网络服务的及时性、安全性、准确性都不作担保。 98 | 9.2.5 当本网站以链接形式推荐其他网站内容时,由于本站并不控制相关网站和资源,因此访问者需理解并同意,本站并不对这些网站或资源的可用性负责, 99 | 且不保证从这些网站获取的任何内容、产品、服务或其他材料的真实性、合法性,对于任何因使用或信赖从此类网站或资源上获取的内容、产品、 服务或其他材料而造成(或声称造成)的任何直接或间接损失,本站均不承担任何责任。 100 | 发生下列情况时,@@@亦毋需承担任何责任。 101 | a 、由于您将用户密码告知他人或与他人共享注册帐户,由此导致的任何个人资料泄露。 102 | b 、任何由于黑客政击、计算机病毒侵入或发作、因政府管制而造成的暂时性关闭等影响网络正常经营之不可抗力而造成的个人资料泄露、丢失、被盗用或被篡改等。 103 | c 、由于与本网站链接的其它网站所造成的个人资料泄露及由此而导致的任何法律争议和后果。 104 | 9.3、@@@文责说明 105 | 9.3.1. @@@的词条内容为网络协作资料,参与协作者可拥有署名权,受法律保护。 106 | 9.3.2. 不得在@@@上复制、发布、传播以下信息: 107 | ◆反对宪法所确定的基本原则的; 108 | ◆危害国家安全,泄露国家秘密,颠覆国家政权,破坏国家统一的; 109 | ◆损害国家荣誉和利益的; 110 | ◆煽动民族仇恨、民族歧视,破坏民族团结的; 111 | ◆破坏国家宗教政策,宣扬邪教和封建迷信的; 112 | ◆散布谣言,扰乱社会秩序,破坏社会稳定的; 113 | ◆散布淫秽、色情、赌博、暴力、凶杀、恐怖或者教唆犯罪的; 114 | ◆侮辱或者诽谤他人,侵害他人合法权益的; 115 | ◆含有法律、行政法规禁止的其他内容的。 116 | 9.3.3. 不利用@@@从事以下活动: 117 | ◆未经允许,进入计算机信息网络或者使用计算机信息网络资源; 118 | ◆未经允许,对计算机信息网络功能进行删除、修改或者增加; 119 | ◆未经允许,对进入计算机信息网络中存储、处理或者传输的数据和应用程序进行删除、修改或者增加; 120 | ◆故意制作、传播计算机病毒等破坏性程序; 121 | ◆其他危害计算机信息网络安全的行为。 122 | 9.3.4. 本网站文章仅代表作者本人的观点,不代表本网站的观点和看法,与本网站立场无关,文责作者自负。 123 | 9.3.5. 本网站郑重提醒访问者:请在转载有关文章时务必尊重该文章的版权、著作权; 如果您发现有您未署名的文章,请立即和@@@联系,@@@会在第一时间加上您的署名或做相关处理。 124 | @@@:服务条款 版权、名誉权争议及损害赔偿责任 125 | 10.1 用户及访问者理解:本网内容系由网友编辑上传,如发生涉嫌侵犯版权、名誉权、肖像权等内容请及时与本网联系, 联系时请附上身份证明、企业营业执照、权利权属证明、具体侵权网址、诉求、有效联系方式等证件、材料及信息。 126 | 本网将会本着尊重他人合法权利的原则对侵权信息予以移除。 127 | 10.2 用户同意保障和维护@@@及其他用户的利益,如因用户违反有关法律、法规或本服务条款的任何条款而给@@@或任何其他第三人造成损失, 128 | 用户同意承担由此造成的损害赔偿责任。@@@对用户使用网络服务所产生的任何直接、间接、偶然、特殊及继起的损害不负责任, 129 | 这些损害可能来自:不正当使用网络服务(含使用侵权信息)、在网上购买商品或进行同类型服务、在网上进行交易、非法使用网络服务或用户传送的信息有所变动。 130 | @@@:服务条款 关于协议修改 131 | 11.1 @@@将有权随时修改本协议的有关条款,一旦本协议的内容发生变动,@@@将会通过适当方式向其前向用户提示计划修改内容。 132 | 11.2 如果不同意@@@对本协议相关条款所做的修改,用户有权停止使用网络服务。如果用户继续使用网络服务,则视为用户接受@@@对本协议相关条款所做的修改。 133 | @@@:服务条款 适用法律 134 | 12.1 本服务条款的订立、执行和解释及争议的解决均应适用中国法律并受中国法院管辖。 135 | 如本服务条款与中华人民共和国法律相抵触时,则该等条款将按法律规定重新修订,而其它条款则依旧有效并具有法律效力。 136 | 如双方就本服务条款内容或其执行发生任何争议,双方应尽量友好协商解决; 137 | 协商不成时,由@@@所在地的人民法院进行管辖。 138 | @@@:服务条款 其他规定 139 | 13.1 本服务条款中的标题仅为方便而设,在解释本服务条款时应被忽略。 140 |
141 | ); 142 | Modal.alert('注册协议', content); 143 | }; 144 | -------------------------------------------------------------------------------- /src/pages/register/views/Register.less: -------------------------------------------------------------------------------- 1 | .registerContent { 2 | :global { 3 | .am-checkbox-agree-label { 4 | color: #999; 5 | } 6 | } 7 | 8 | .banner { 9 | height: 200px; 10 | line-height: 200px; 11 | font-size: 30px; 12 | color: #fff; 13 | background: url(./img/bg_1.jpg) center center no-repeat; 14 | background-size: cover; 15 | background-color: #333; 16 | text-shadow: 1px 1px 5px #000; 17 | text-align: center; 18 | } 19 | 20 | .btnbox { 21 | padding: 10px; 22 | 23 | :global { 24 | .am-list-item { 25 | margin-bottom: 20px; 26 | } 27 | } 28 | } 29 | 30 | .loginLink { 31 | line-height: 30px; 32 | text-align: center; 33 | } 34 | 35 | .agreeBox { 36 | display: flex; 37 | justify-content: space-between; 38 | 39 | .seeAgree { 40 | font-size: 15px; 41 | padding: 9px; 42 | display: block; 43 | } 44 | 45 | :global { 46 | .icon_shakehands { 47 | margin-right: 2px; 48 | } 49 | } 50 | } 51 | 52 | } 53 | 54 | .agreeContent { 55 | font-size: 14px; 56 | max-height: 350px; 57 | overflow-x: hidden; 58 | overflow-y: auto; 59 | text-align: left; 60 | } -------------------------------------------------------------------------------- /src/pages/register/views/Register.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Link from 'umi/link'; 3 | import router from 'umi/router'; 4 | import { Bind } from 'lodash-decorators'; 5 | import { Button, Checkbox, InputItem, Toast } from 'antd-mobile'; 6 | import Icon from '@components/icon/Icon'; 7 | import { RegisterAgree } from './Register.agree'; 8 | import style from './Register.less'; 9 | 10 | interface IRegisterProps { } 11 | 12 | interface IRegisterState { 13 | loading: boolean; 14 | numError: boolean; 15 | pwdError: boolean; 16 | pwdChkError: boolean; 17 | disabled: boolean; 18 | isAgree: boolean; 19 | } 20 | 21 | interface IRegisterQuery { 22 | userNum: string; 23 | password: string; 24 | passwordCheck: string; 25 | } 26 | 27 | class LoginComponent extends React.Component { 28 | private RegisterQuery: IRegisterQuery = { 29 | userNum: '', 30 | password: '', 31 | passwordCheck: '' 32 | }; 33 | 34 | constructor(props: IRegisterProps, context?: any) { 35 | super(props, context); 36 | this.state = { 37 | loading: false, 38 | numError: false, 39 | pwdError: false, 40 | pwdChkError: false, 41 | disabled: true, 42 | isAgree: true 43 | }; 44 | } 45 | 46 | @Bind() 47 | private onNumInput(value: string): void { 48 | this.RegisterQuery.userNum = value; 49 | this.resetButtonDisabled(); 50 | } 51 | 52 | @Bind() 53 | private onPwdInput(value: string): void { 54 | this.RegisterQuery.password = value; 55 | this.resetButtonDisabled(); 56 | } 57 | 58 | @Bind() 59 | private onPwdCheckInput(value: string): void { 60 | this.RegisterQuery.passwordCheck = value; 61 | this.resetButtonDisabled(); 62 | } 63 | 64 | @Bind() 65 | private onAgreeChange(): void { 66 | this.setState({ 67 | isAgree: !this.state.isAgree 68 | }, this.resetButtonDisabled); 69 | } 70 | 71 | @Bind() 72 | private resetButtonDisabled(): void { 73 | this.setState({ 74 | disabled: this.RegisterQuery.userNum && 75 | this.RegisterQuery.password && 76 | this.RegisterQuery.passwordCheck && 77 | this.state.isAgree ? 78 | false : true 79 | }); 80 | } 81 | 82 | /** 83 | * 查看协议 84 | */ 85 | private seeAgree(): void { 86 | RegisterAgree(); 87 | } 88 | 89 | @Bind() 90 | private onSubmit(): void { 91 | const isFail: boolean = this.RegisterQuery.passwordCheck !== this.RegisterQuery.password; 92 | 93 | this.setState({ 94 | pwdChkError: isFail 95 | }, () => { 96 | isFail && Toast.fail('两次密码不一致'); 97 | }); 98 | 99 | !isFail && this.setState({ 100 | loading: true, 101 | disabled: true 102 | }, () => { 103 | setTimeout(() => { 104 | this.setState({ 105 | loading: false, 106 | disabled: false 107 | }); 108 | router.push('/'); 109 | }, 3000); 110 | }); 111 | } 112 | 113 | public render(): React.ReactNode { 114 | 115 | return ( 116 |
117 |
118 | 我们一起来改变~ 119 |
120 |
121 | 129 | 登录账号 130 | 131 | 139 | 设置密码 140 | 141 | 149 | 重复密码 150 | 151 | 159 |
160 | 164 | 同意注册协议 165 | 166 | 171 | 查看协议 172 | 173 |
174 |
175 |
176 | 已有账号,立即登录 177 |
178 |
179 | ); 180 | } 181 | } 182 | 183 | export default LoginComponent; 184 | -------------------------------------------------------------------------------- /src/pages/register/views/img/bg_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaotoo/ReactForH5/4960a213e66581bbc2a88793165c2a8332fe2ae7/src/pages/register/views/img/bg_1.jpg -------------------------------------------------------------------------------- /src/pages/setting/img/photo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaotoo/ReactForH5/4960a213e66581bbc2a88793165c2a8332fe2ae7/src/pages/setting/img/photo.jpg -------------------------------------------------------------------------------- /src/pages/setting/views/Setting.less: -------------------------------------------------------------------------------- 1 | .settingContent { 2 | font-size: 16px; 3 | text-align: center; 4 | } -------------------------------------------------------------------------------- /src/pages/setting/views/Setting.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Bind } from 'lodash-decorators'; 3 | import { List, Modal, InputItem, Button } from 'antd-mobile'; 4 | import Icon from '@components/icon/Icon'; 5 | import { ExitLogin } from './util/LoginOut'; 6 | import Info from './info/Info'; 7 | import style from './Setting.less'; 8 | 9 | interface IEmptyProps { } 10 | 11 | interface IEmptyState { 12 | showUpdate: boolean; 13 | } 14 | 15 | class EmptyComponent extends React.Component { 16 | constructor(props: IEmptyProps, context?: any) { 17 | super(props, context); 18 | this.state = { 19 | showUpdate: false 20 | }; 21 | } 22 | 23 | @Bind() 24 | private onClick(info: any): void { 25 | if (info === 'exit') { 26 | ExitLogin(); 27 | } else { 28 | this.setState({ 29 | showUpdate: true 30 | }); 31 | } 32 | } 33 | 34 | @Bind() 35 | private closeModal(): void { 36 | this.setState({ 37 | showUpdate: false 38 | }); 39 | } 40 | 41 | public render(): React.ReactNode { 42 | return ( 43 |
44 | 45 | 46 | 49 | 更换手机号 50 | 51 | 54 | 退出账号 55 | 56 | 57 | 62 | 63 | 64 | 67 | 68 | 69 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 |
82 | ); 83 | } 84 | } 85 | 86 | export default EmptyComponent; 87 | -------------------------------------------------------------------------------- /src/pages/setting/views/info/Info.less: -------------------------------------------------------------------------------- 1 | .infoContent { 2 | background-color: #f80; 3 | position: relative; 4 | 5 | .content { 6 | padding: 10px 10px 30px; 7 | display: flex; 8 | justify-content: space-between; 9 | flex-wrap: nowrap; 10 | 11 | .photo { 12 | width: 100px; 13 | min-width: 100px; 14 | height: 100px; 15 | border-radius: 100%; 16 | border: 2px solid #fff; 17 | background: url(../../img/photo.jpg) center center no-repeat; 18 | background-size: cover; 19 | } 20 | 21 | .detail { 22 | color: #fff; 23 | width: 100%; 24 | line-height: 30px; 25 | padding-left: 10px; 26 | text-align: left; 27 | } 28 | } 29 | 30 | .layer { 31 | width: 100%; 32 | height: 20px; 33 | background-color: #fff; 34 | border-radius: 100px 100px 0 0; 35 | position: absolute; 36 | bottom: -1px; 37 | left: 0; 38 | z-index: 3; 39 | } 40 | } -------------------------------------------------------------------------------- /src/pages/setting/views/info/Info.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import style from './Info.less'; 3 | 4 | interface IInfoProps { } 5 | 6 | interface IInfoState { } 7 | 8 | class IconComponent extends React.Component { 9 | constructor(props: IInfoProps, context?: any) { 10 | super(props, context); 11 | } 12 | 13 | public render(): React.ReactNode { 14 | return ( 15 |
16 |
17 |
18 |
19 |
188****9898
20 |
性别:男
21 |
昵称:-
22 |
23 |
24 |
25 |
26 | ); 27 | } 28 | } 29 | 30 | export default IconComponent; 31 | -------------------------------------------------------------------------------- /src/pages/setting/views/util/LoginOut.tsx: -------------------------------------------------------------------------------- 1 | import router from 'umi/router'; 2 | import { ActionSheet, Toast } from 'antd-mobile'; 3 | 4 | /** 5 | * 退出账号 6 | */ 7 | export const ExitLogin = (): void => { 8 | ActionSheet.showActionSheetWithOptions({ 9 | maskClosable: true, 10 | cancelButtonIndex: 1, 11 | destructiveButtonIndex: 0, 12 | options: ['确定退出', '取消'], 13 | message: '确定要退出当前账号吗?' 14 | }, (buttonIndex: number) => { 15 | if (buttonIndex === 0) { 16 | Toast.success('退出成功'); 17 | router.push('/login'); 18 | } 19 | }); 20 | }; 21 | -------------------------------------------------------------------------------- /src/pages/shoppingCar/models/ShoppingCar.ts: -------------------------------------------------------------------------------- 1 | import * as shoppingCarService from '../services/ShoppingCar'; 2 | 3 | export interface IShoppingCarInfo { 4 | list: any[]; 5 | total: number; 6 | } 7 | 8 | const defaultState: IShoppingCarInfo = { 9 | list: [], 10 | total: 0 11 | }; 12 | 13 | export default { 14 | namespace: 'ShoppingCar_Models', 15 | state: { ...defaultState }, 16 | reducers: { 17 | changeState(state: IShoppingCarInfo, { data }) { 18 | return { 19 | ...state, 20 | ...data 21 | }; 22 | } 23 | }, 24 | effects: { 25 | * fetchShoppingCarList({ data }, { call, put }) { 26 | const result = yield call(shoppingCarService.fetchShoppingCarList, data); 27 | yield put({ 28 | type: 'changeState', 29 | data: { 30 | list: result, 31 | total: 125 32 | } 33 | }); 34 | } 35 | }, 36 | subscriptions: { 37 | setup({ history, dispatch }) { 38 | return history.listen(({ pathname, query }) => { 39 | pathname === '/shoppingCar' && dispatch({ 40 | type: 'fetchShoppingCarList', 41 | data: query 42 | }); 43 | }); 44 | } 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /src/pages/shoppingCar/services/ShoppingCar.ts: -------------------------------------------------------------------------------- 1 | import Request from '@utils/Request'; 2 | 3 | export function fetchShoppingCarList({ page = 1 }) { 4 | return Request.get('/api/orderList', { 5 | params: { 6 | page: page, 7 | limit: 5 8 | } 9 | }); 10 | } 11 | -------------------------------------------------------------------------------- /src/pages/shoppingCar/views/ShoppingCar.less: -------------------------------------------------------------------------------- 1 | .shoppingCarContent { 2 | 3 | .listBox { 4 | margin-top: -1px; 5 | padding-bottom: 50px; 6 | 7 | .listItem { 8 | .main { 9 | height: 100px; 10 | display: flex; 11 | 12 | p { 13 | padding: 0; 14 | margin: 0; 15 | } 16 | 17 | .image { 18 | width: 100px; 19 | min-width: 100px; 20 | height: 100px; 21 | background: url(./img/product1.jpg) center center no-repeat; 22 | background-size: cover; 23 | border-radius: 5px; 24 | } 25 | 26 | .point { 27 | width: 100%; 28 | line-height: 30px; 29 | padding-left: 10px; 30 | position: relative; 31 | z-index: 1; 32 | overflow: hidden; 33 | 34 | .title { 35 | font-size: 16px; 36 | text-overflow: ellipsis; 37 | white-space: nowrap; 38 | word-break: break-all; 39 | overflow: hidden; 40 | } 41 | 42 | .price { 43 | color: #f00; 44 | text-align: right; 45 | } 46 | } 47 | } 48 | 49 | .actionList { 50 | line-height: 50px; 51 | font-size: 14px; 52 | padding-top: 5px; 53 | display: flex; 54 | flex-wrap: nowrap; 55 | justify-content: space-between; 56 | 57 | :global { 58 | .am-button { 59 | color: #666; 60 | } 61 | } 62 | } 63 | } 64 | 65 | .empty { 66 | line-height: 50px; 67 | 68 | :global { 69 | .iconfont { 70 | margin-right: 5px; 71 | } 72 | 73 | .am-list-content { 74 | color: #999; 75 | font-size: 14px; 76 | font-weight: 400; 77 | text-align: center; 78 | } 79 | } 80 | } 81 | } 82 | 83 | .buttonList { 84 | width: 100%; 85 | display: flex; 86 | flex-wrap: nowrap; 87 | justify-content: space-between; 88 | position: fixed; 89 | bottom: 60px; 90 | z-index: 2; 91 | 92 | .carButton { 93 | &:first-child { 94 | background-color: #f90; 95 | } 96 | 97 | &:last-child { 98 | background-color: #ccc; 99 | } 100 | 101 | color: #fff; 102 | font-size: 14px; 103 | width: 50%; 104 | height: 50px; 105 | line-height: 50px; 106 | text-align: center; 107 | } 108 | } 109 | } -------------------------------------------------------------------------------- /src/pages/shoppingCar/views/ShoppingCar.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { connect } from 'dva'; 3 | import { Bind } from 'lodash-decorators'; 4 | import { List, Button, Stepper } from 'antd-mobile'; 5 | import Icon from '@components/icon/Icon'; 6 | import { IShoppingCarInfo } from '../models/ShoppingCar'; 7 | import { ScarPay } from './util/ScarPay'; 8 | import { ScarClean } from './util/ScarClean'; 9 | import { ScarDelete } from './util/ScarDelete'; 10 | import style from './ShoppingCar.less'; 11 | 12 | interface IShoppingCarProps extends IShoppingCarInfo { } 13 | 14 | interface IShoppingCarState { } 15 | 16 | class ShoppingCarComponent extends React.Component { 17 | constructor(props: IShoppingCarProps, context?: any) { 18 | super(props, context); 19 | } 20 | 21 | @Bind() 22 | private executeListItem(list: any): JSX.Element { 23 | const itemNode: JSX.Element[] = list.map((item: any, index: number) => { 24 | return ( 25 | 26 |
27 |
28 |
29 |
30 |

{item.productName}

31 |

¥{item.price}

32 |
33 |
34 |
35 | 41 | 47 |
48 |
49 | 50 | ); 51 | }); 52 | return ( 53 | 54 | { 55 | itemNode.length ? itemNode : 56 | 57 | 暂无数据 58 | 59 | } 60 | 61 | ); 62 | } 63 | 64 | public render(): React.ReactNode { 65 | return ( 66 |
67 | {this.executeListItem(this.props.list)} 68 |
69 |
70 | 去支付 71 |
72 |
73 | 清空 74 |
75 |
76 |
77 | ); 78 | } 79 | } 80 | 81 | export default connect( 82 | (state: any) => state.ShoppingCar_Models 83 | )(ShoppingCarComponent); 84 | -------------------------------------------------------------------------------- /src/pages/shoppingCar/views/img/product1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaotoo/ReactForH5/4960a213e66581bbc2a88793165c2a8332fe2ae7/src/pages/shoppingCar/views/img/product1.jpg -------------------------------------------------------------------------------- /src/pages/shoppingCar/views/util/ScarClean.tsx: -------------------------------------------------------------------------------- 1 | import { ActionSheet, Toast } from 'antd-mobile'; 2 | 3 | /** 4 | * 清空 5 | */ 6 | export const ScarClean = (): void => { 7 | ActionSheet.showActionSheetWithOptions({ 8 | maskClosable: true, 9 | cancelButtonIndex: 1, 10 | destructiveButtonIndex: 0, 11 | options: ['确定', '取消'], 12 | message: '清空将删除购物车中所有商品' 13 | }, (buttonIndex: number) => { 14 | if (buttonIndex === 0) { 15 | Toast.success('清空成功'); 16 | } 17 | }); 18 | }; 19 | -------------------------------------------------------------------------------- /src/pages/shoppingCar/views/util/ScarDelete.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ActionSheet, Toast } from 'antd-mobile'; 3 | 4 | /** 5 | * 删除 6 | */ 7 | export const ScarDelete = (productId: number): void => { 8 | ActionSheet.showActionSheetWithOptions({ 9 | maskClosable: true, 10 | cancelButtonIndex: 1, 11 | destructiveButtonIndex: 0, 12 | options: ['确定', '取消'], 13 | message: '确定要删除此商品么?' 14 | }, (buttonIndex: number) => { 15 | if (buttonIndex === 0) { 16 | Toast.success('删除成功'); 17 | } 18 | }); 19 | }; 20 | -------------------------------------------------------------------------------- /src/pages/shoppingCar/views/util/ScarPay.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ActionSheet, Toast } from 'antd-mobile'; 3 | 4 | /** 5 | * 去支付 6 | */ 7 | export const ScarPay = (): void => { 8 | ActionSheet.showActionSheetWithOptions({ 9 | maskClosable: true, 10 | cancelButtonIndex: 1, 11 | destructiveButtonIndex: 0, 12 | options: ['确定', '取消'], 13 | title:
金额:¥889.56
, 14 | message: '支付前请确认金额' 15 | }, (buttonIndex: number) => { 16 | if (buttonIndex === 0) { 17 | Toast.success('支付成功'); 18 | } 19 | }); 20 | }; 21 | -------------------------------------------------------------------------------- /src/pages/welcome/Welcome.less: -------------------------------------------------------------------------------- 1 | .welcomeContent { 2 | min-height: 500px; 3 | } -------------------------------------------------------------------------------- /src/pages/welcome/Welcome.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Banner from './banner/Banner'; 3 | import Quick from './quick/Quick'; 4 | import Product from './product/Product'; 5 | import Chart from './chart/Chart'; 6 | import style from './Welcome.less'; 7 | 8 | interface IWelcomeProps { } 9 | 10 | interface IWelcomeState { } 11 | 12 | class WelcomeComponent extends React.Component { 13 | constructor(props: IWelcomeProps, context?: any) { 14 | super(props, context); 15 | } 16 | 17 | public render(): React.ReactNode { 18 | return ( 19 |
20 | 21 | 22 | 23 | 24 |
25 | ); 26 | } 27 | } 28 | 29 | export default WelcomeComponent; 30 | -------------------------------------------------------------------------------- /src/pages/welcome/banner/Banner.less: -------------------------------------------------------------------------------- 1 | .banner { 2 | position: relative; 3 | overflow: hidden; 4 | 5 | .carousel { 6 | :global { 7 | .am-carousel-wrap { 8 | padding-bottom: 20px; 9 | } 10 | } 11 | 12 | .item { 13 | height: 150px; 14 | position: relative; 15 | z-index: 1; 16 | } 17 | 18 | .itemImg { 19 | width: 100%; 20 | height: 100%; 21 | background-position: 0 0; 22 | background-repeat: no-repeat; 23 | background-size: cover; 24 | position: relative; 25 | z-index: 1; 26 | } 27 | 28 | .itemDesc { 29 | color: #fff; 30 | background-color: rgba(0, 0, 0, .6); 31 | width: 100%; 32 | height: 45px; 33 | line-height: 35px; 34 | padding: 0 10px; 35 | position: absolute; 36 | left: 0; 37 | bottom: 0; 38 | z-index: 3; 39 | } 40 | } 41 | 42 | .layer { 43 | width: 100%; 44 | height: 20px; 45 | background-color: #fff; 46 | border-radius: 100px 100px 0 0; 47 | position: absolute; 48 | bottom: -1px; 49 | left: 0; 50 | z-index: 3; 51 | } 52 | } -------------------------------------------------------------------------------- /src/pages/welcome/banner/Banner.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Carousel } from 'antd-mobile'; 3 | import { BannerList, IBannerInfo } from './BannerConfig'; 4 | import style from './Banner.less'; 5 | 6 | interface IBannerProps { } 7 | 8 | interface IBannerState { } 9 | 10 | class BannerComponent extends React.Component { 11 | constructor(props: IBannerProps, context?: any) { 12 | super(props, context); 13 | } 14 | 15 | private executeItem(): React.ReactNode { 16 | const itemNode: React.ReactNode = BannerList.map((item: IBannerInfo, index: number) => { 17 | return ( 18 |
19 | {/* 24 | {item.desc} 25 | */} 26 |
30 |
31 | ); 32 | }); 33 | return itemNode; 34 | } 35 | 36 | public render() { 37 | return ( 38 |
39 | 44 | {this.executeItem()} 45 | 46 |
47 |
48 | ); 49 | } 50 | } 51 | 52 | export default BannerComponent; 53 | -------------------------------------------------------------------------------- /src/pages/welcome/banner/BannerConfig.ts: -------------------------------------------------------------------------------- 1 | export interface IBannerInfo { 2 | img: string; 3 | desc: string; 4 | href: string; 5 | } 6 | 7 | export const BannerList: IBannerInfo[] = [{ 8 | img: require('./image/banner1.jpg'), 9 | desc: '百度一下 你就知道', 10 | href: 'http://www.baidu.com' 11 | }, { 12 | img: require('./image/banner2.jpg'), 13 | desc: '不需要别人给与 你要的触手可及', 14 | href: 'http://www.google.com' 15 | }, { 16 | img: require('./image/banner3.jpg'), 17 | desc: 'Google', 18 | href: 'http://www.google.com' 19 | }]; 20 | -------------------------------------------------------------------------------- /src/pages/welcome/banner/image/banner1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaotoo/ReactForH5/4960a213e66581bbc2a88793165c2a8332fe2ae7/src/pages/welcome/banner/image/banner1.jpg -------------------------------------------------------------------------------- /src/pages/welcome/banner/image/banner2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaotoo/ReactForH5/4960a213e66581bbc2a88793165c2a8332fe2ae7/src/pages/welcome/banner/image/banner2.jpg -------------------------------------------------------------------------------- /src/pages/welcome/banner/image/banner3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaotoo/ReactForH5/4960a213e66581bbc2a88793165c2a8332fe2ae7/src/pages/welcome/banner/image/banner3.jpg -------------------------------------------------------------------------------- /src/pages/welcome/chart/Chart.less: -------------------------------------------------------------------------------- 1 | .chartContent { 2 | padding-bottom: 20px; 3 | 4 | .chartPanel { 5 | position: relative; 6 | } 7 | } -------------------------------------------------------------------------------- /src/pages/welcome/chart/Chart.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Bind } from 'lodash-decorators'; 3 | import EChart from '@components/ChartComponent'; 4 | import { loadChartOption } from './EchartOption'; 5 | import style from './Chart.less'; 6 | 7 | interface IChartDemoProps { } 8 | 9 | interface IChartDemoState { } 10 | 11 | class ChartDemoComponent extends React.Component { 12 | constructor(props: IChartDemoProps, context?: any) { 13 | super(props, context); 14 | } 15 | 16 | public render(): React.ReactNode { 17 | return ( 18 |
19 | 24 |
25 | ); 26 | } 27 | } 28 | 29 | export default ChartDemoComponent; 30 | -------------------------------------------------------------------------------- /src/pages/welcome/chart/EchartOption.ts: -------------------------------------------------------------------------------- 1 | import { EChartOption } from 'echarts'; 2 | import { colorList } from '@components/ChartComponent'; 3 | 4 | export const loadChartOption = (): EChartOption => { 5 | return { 6 | color: colorList, 7 | legend: { 8 | data: ['微信朋友圈', '微信小程序', '直接访问'] 9 | }, 10 | grid: { 11 | left: '4%', 12 | right: '4%', 13 | top: '15%', 14 | bottom: '2%', 15 | containLabel: true 16 | }, 17 | xAxis: [{ 18 | type: 'category', 19 | boundaryGap: false, 20 | splitLine: { 21 | lineStyle: { 22 | type: 'dashed' 23 | } 24 | }, 25 | axisTick: { 26 | show: false 27 | }, 28 | axisLine: { 29 | show: false 30 | }, 31 | data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'] 32 | }], 33 | yAxis: [{ 34 | type: 'value', 35 | splitLine: { 36 | lineStyle: { 37 | type: 'dashed' 38 | } 39 | }, 40 | axisTick: { 41 | show: false 42 | }, 43 | axisLine: { 44 | show: false 45 | }, 46 | axisLabel: { 47 | inside: true, 48 | margin: 0, 49 | verticalAlign: 'bottom' 50 | }, 51 | z: 10 52 | }], 53 | series: [{ 54 | name: '微信朋友圈', 55 | type: 'line', 56 | stack: '总量', 57 | smooth: true, 58 | showSymbol: false, 59 | areaStyle: {}, 60 | lineStyle: { 61 | width: 0 62 | }, 63 | data: [1220, 2132, 1101, 3134, 5990, 1230, 3210] 64 | }, { 65 | name: '微信小程序', 66 | type: 'line', 67 | stack: '总量', 68 | smooth: true, 69 | showSymbol: false, 70 | areaStyle: {}, 71 | lineStyle: { 72 | width: 0 73 | }, 74 | data: [1220, 2182, 2191, 2234, 1290, 1330, 1310] 75 | }, { 76 | name: '直接访问', 77 | type: 'line', 78 | stack: '总量', 79 | smooth: true, 80 | showSymbol: false, 81 | areaStyle: {}, 82 | lineStyle: { 83 | width: 0 84 | }, 85 | data: [1320, 1332, 1301, 1334, 1390, 2330, 1320] 86 | }] 87 | }; 88 | }; 89 | -------------------------------------------------------------------------------- /src/pages/welcome/product/Product.less: -------------------------------------------------------------------------------- 1 | .productContent { 2 | .productItem { 3 | padding: 10px; 4 | border-top: 1px solid #eee; 5 | 6 | .title { 7 | color: #333; 8 | font-size: 16px; 9 | font-weight: 700; 10 | line-height: 40px; 11 | } 12 | 13 | .content { 14 | display: flex; 15 | flex-wrap: wrap; 16 | 17 | .item { 18 | width: 100%; 19 | height: 100px; 20 | margin-bottom: 10px; 21 | background-color: #f5f5f5; 22 | background-position: center center; 23 | background-size: cover; 24 | background-repeat: no-repeat; 25 | position: relative; 26 | z-index: 1; 27 | } 28 | 29 | .price { 30 | color: #fff; 31 | padding: 0 5px; 32 | background-color: #f00; 33 | border-radius: 5px; 34 | position: absolute; 35 | right: 5px; 36 | top: 5px; 37 | z-index: 3; 38 | } 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /src/pages/welcome/product/Product.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Moment from 'moment'; 3 | import { Bind } from 'lodash-decorators'; 4 | import { DatePicker, List, Pagination, Icon } from 'antd-mobile'; 5 | import style from './Product.less'; 6 | 7 | interface IProductProps { } 8 | 9 | interface IProductState { 10 | dateTime: Date | undefined; 11 | } 12 | 13 | class ProductComponent extends React.Component { 14 | constructor(props: IProductProps, context?: any) { 15 | super(props, context); 16 | this.state = { 17 | dateTime: undefined 18 | }; 19 | } 20 | 21 | private executeItem(): React.ReactNode { 22 | const imgMap = { 23 | 1: require('./img/product1.jpg'), 24 | 2: require('./img/product2.jpg') 25 | }; 26 | 27 | const nodeList = [1, 2, 3, 4, 5].map((value, index: number) => { 28 | return ( 29 |
36 | 37 | ¥{Math.floor(Math.random() * 1000)} 38 | 39 |
40 | ); 41 | }); 42 | return nodeList; 43 | } 44 | 45 | public render(): React.ReactNode { 46 | return ( 47 |
48 |
49 |
50 | 特价专区 51 |
52 |
53 | {this.executeItem()} 54 |
55 |
56 |
57 |
58 | 热卖专区 59 |
60 |
61 | {this.executeItem()} 62 |
63 |
64 |
65 | ); 66 | } 67 | } 68 | 69 | export default ProductComponent; 70 | -------------------------------------------------------------------------------- /src/pages/welcome/product/img/product1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaotoo/ReactForH5/4960a213e66581bbc2a88793165c2a8332fe2ae7/src/pages/welcome/product/img/product1.jpg -------------------------------------------------------------------------------- /src/pages/welcome/product/img/product2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaotoo/ReactForH5/4960a213e66581bbc2a88793165c2a8332fe2ae7/src/pages/welcome/product/img/product2.jpg -------------------------------------------------------------------------------- /src/pages/welcome/quick/Quick.conf.ts: -------------------------------------------------------------------------------- 1 | interface IQuickInfo { 2 | title: string; 3 | icon: string; 4 | href: string; 5 | background?: string; 6 | } 7 | 8 | export const QuickList: IQuickInfo[] = [{ 9 | title: '热门商品', 10 | icon: 'shangpin-xianxing', 11 | href: 'javascript:;', 12 | background: '#09c' 13 | }, { 14 | title: '账单', 15 | icon: 'zhangdan-xianxing', 16 | href: 'javascript:;' 17 | }, { 18 | title: '礼包', 19 | icon: 'icon_gift', 20 | href: 'javascript:;', 21 | background: '#ce7676' 22 | }, { 23 | title: '计算工具', 24 | icon: 'jisuanqilishuai-xianxing', 25 | href: 'javascript:;', 26 | background: '#b59361' 27 | }, { 28 | title: '园区', 29 | icon: 'qiyeyuanquwuye-xianxing', 30 | href: 'javascript:;', 31 | background: '#08f' 32 | }, { 33 | title: '寄件', 34 | icon: 'jijianfasong-xianxing', 35 | href: 'javascript:;' 36 | }, { 37 | title: '物流状态', 38 | icon: 'yunshuzhongwuliu-xianxing', 39 | href: 'javascript:;', 40 | background: '#09f' 41 | }, { 42 | title: '游戏', 43 | icon: 'game', 44 | href: 'javascript:;' 45 | }]; 46 | -------------------------------------------------------------------------------- /src/pages/welcome/quick/Quick.less: -------------------------------------------------------------------------------- 1 | .quickContent { 2 | padding: 0 10px 10px; 3 | position: relative; 4 | display: flex; 5 | flex-wrap: wrap; 6 | justify-content: space-between; 7 | 8 | .item { 9 | width: 25%; 10 | min-width: 25%; 11 | text-align: center; 12 | padding-bottom: 10px; 13 | 14 | .icon { 15 | width: 50px; 16 | height: 50px; 17 | line-height: 50px; 18 | font-size: 30px; 19 | color: #fff; 20 | background-color: #f90; 21 | border-radius: 100%; 22 | 23 | &:active { 24 | opacity: .7; 25 | } 26 | } 27 | 28 | .title { 29 | line-height: 30px; 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /src/pages/welcome/quick/Quick.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Bind } from 'lodash-decorators'; 3 | import { Toast } from 'antd-mobile'; 4 | import Icon from '@components/icon/Icon'; 5 | import style from './Quick.less'; 6 | import { QuickList } from './Quick.conf'; 7 | 8 | interface IQuickProps { } 9 | 10 | interface IQuickState { } 11 | 12 | class ProductComponent extends React.Component { 13 | constructor(props: IQuickProps, context?: any) { 14 | super(props, context); 15 | } 16 | 17 | @Bind() 18 | private onClick(title: string): void { 19 | Toast.fail(`${title}功能暂未开放`); 20 | } 21 | 22 | private executeItem(): React.ReactNode { 23 | const nodeList = QuickList.map((item, index: number) => { 24 | return ( 25 |
30 | 35 |
36 | {item.title} 37 |
38 |
39 | ); 40 | }); 41 | return nodeList; 42 | } 43 | 44 | public render(): React.ReactNode { 45 | return ( 46 |
47 | {this.executeItem()} 48 |
49 | ); 50 | } 51 | } 52 | 53 | export default ProductComponent; 54 | -------------------------------------------------------------------------------- /src/utils/GlobalInterface.ts: -------------------------------------------------------------------------------- 1 | import { Dispatch } from 'react'; 2 | import { RouteComponentProps } from 'react-router'; 3 | 4 | export interface IGlobalInterface extends RouteComponentProps { 5 | dispatch: Dispatch; 6 | } 7 | -------------------------------------------------------------------------------- /src/utils/Request.ts: -------------------------------------------------------------------------------- 1 | import router from 'umi/router'; 2 | import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'; 3 | // import { message } from 'antd'; 4 | 5 | /** 6 | * 全局接口响应状态码枚举 7 | * @description Success 正常 8 | * @description UnLogin 未登录 9 | * @description NoPermission 没有权限 10 | */ 11 | enum GlobalResponseCode { 12 | Success = 0, 13 | UnLogin = -1, 14 | NoPermission = 403 15 | } 16 | 17 | /** 18 | * 全局请求扩展配置 19 | */ 20 | const axiosConfig = { 21 | success: (config: AxiosRequestConfig) => { 22 | config.headers['Accept'] = 'application/json'; 23 | config.withCredentials = true; 24 | return config; 25 | }, 26 | error: (error: any) => Promise.reject(error) 27 | }; 28 | 29 | /** 30 | * 全局请求响应处理 31 | * @see http://www.axios-js.com/ 32 | */ 33 | const axiosResponse = { 34 | success: ({ data }: AxiosResponse) => { 35 | const errno = data ? +data.errno : -110; 36 | switch (true) { 37 | // 接口正常 38 | case errno === GlobalResponseCode.Success: 39 | return data.data; 40 | // 未登录 41 | case errno === GlobalResponseCode.UnLogin: 42 | window.location.href = data.loginUrl; 43 | return null; 44 | // 没有权限 45 | case errno === GlobalResponseCode.NoPermission: 46 | router.push('/forbidden'); 47 | return null; 48 | // 接口异常 49 | default: 50 | // message.error(data.error_msg || '系统错误,请稍后再试!'); 51 | return Promise.reject(); 52 | } 53 | }, 54 | error: (error: any) => Promise.reject(error) 55 | }; 56 | 57 | axios.interceptors.request.use(axiosConfig.success, axiosConfig.error); 58 | axios.interceptors.response.use(axiosResponse.success, axiosResponse.error); 59 | 60 | export default axios; 61 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // TypeScript编译选项 3 | // https://www.tslang.cn/docs/handbook/compiler-options.html 4 | "compilerOptions": { 5 | // 指定 ECMAScript 目标版本: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT' 6 | "target": "ES2015", 7 | // 指定生成哪个模块系统代码: "None", "CommonJS", "AMD", "System", "UMD", "ES6" 或 "ES2015"。 8 | // 只有 "AMD"和 "System"能和 --outFile一起使用。 9 | // "ES6"和 "ES2015"可使用在目标输出为 "ES5"或更低的情况下。 10 | // ESNext 是一个 JavaScript 库,可以将 ES6 草案规范语法转成 JavaScript 语法 11 | "module": "ESNext", 12 | // 允许编译javascript文件 13 | "allowJs": true, 14 | // 在 .js 文件中报告错误。与 --allowJs 配合使用。 15 | "checkJs": true, 16 | // 在 .tsx 文件里支持JSX: "React"或 "Preserve" 17 | "jsx": "react", 18 | // 生成相应的 .map文件 19 | "sourceMap": true, 20 | // 重定向输出目录 21 | "outDir": "./dist/assets/", 22 | // 删除所有注释,除了以 /!* 开头的版权信息。 23 | "removeComments": true, 24 | // 从 tslib 导入辅助工具函数(比如 __extends, __rest等) 25 | "importHelpers": true, 26 | // 启用所有严格类型检查选项。 27 | // 启用 --strict 相当于启用 --noImplicitAny、--noImplicitThis、--alwaysStrict、--strictNullChecks 28 | // 和 --strictFunctionTypes、--strictPropertyInitialization。 29 | "strict": true, 30 | // 在表达式和声明上有隐含的 any类型时报错。 31 | "noImplicitAny": false, 32 | // 在严格的 null检查模式下, null和 undefined值不包含在任何类型里 33 | // 只允许用它们自己和 any来赋值(有个例外, undefined可以赋值到 void) 34 | "strictNullChecks": true, 35 | // 禁用函数参数双向协变检查 36 | "strictFunctionTypes": true, 37 | // 以严格模式解析并为每个源文件生成 "use strict"语句 38 | "alwaysStrict": true, 39 | // 决定如何处理模块。或者是"Node"对于Node.js/io.js,或者是"Classic"(默认) 40 | "moduleResolution": "node", 41 | // 解析非相对模块名的基准目录 42 | "baseUrl": "./", 43 | // 模块名到基于 baseUrl的路径映射的列表 44 | "paths": { 45 | "*": [ 46 | "*", 47 | "src/*" 48 | ], 49 | "@utils/*": [ 50 | "./src/utils/*" 51 | ], 52 | "@pages/*": [ 53 | "./src/pages/*" 54 | ], 55 | "@components/*": [ 56 | "./src/components/*" 57 | ], 58 | "@globalModels/*": [ 59 | "./src/models/*" 60 | ], 61 | "@globalServices/*": [ 62 | "./src/services/*" 63 | ] 64 | }, 65 | // 根(root)文件夹列表,表示运行时组合工程结构的内容 66 | "rootDirs": [ 67 | "./src" 68 | ], 69 | // 要包含的类型声明文件名列表 70 | "types": [ 71 | "node" 72 | ], 73 | // 允许从没有设置默认导出的模块中默认导入。这并不影响代码的输出,仅为了类型检查。 74 | "allowSyntheticDefaultImports": true, 75 | // 启用实验性的ES装饰器 76 | "experimentalDecorators": true, 77 | // 给源码里的装饰器声明加上设计类型元数据 78 | "emitDecoratorMetadata": true 79 | }, 80 | // 包含的文件 81 | "include": [ 82 | "./src/", 83 | "./declaration.d.ts" 84 | ] 85 | } -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "error", 3 | "extends": [ 4 | "tslint:recommended", 5 | "tslint-react" 6 | ], 7 | "jsRules": { 8 | "quotemark": [ 9 | true, 10 | "single", 11 | "avoid-escape", 12 | "avoid-template", 13 | "jsx-double" 14 | ], 15 | "no-string-literal": false, 16 | "object-literal-shorthand": false, 17 | "object-literal-sort-keys": [ 18 | false, 19 | "ignore-case", 20 | "match-declaration-order" 21 | ], 22 | "semicolon": [ 23 | true, 24 | "always", 25 | "ignore-bound-class-methods" 26 | ] 27 | }, 28 | "rules": { 29 | "align": [ 30 | true, 31 | "parameters", 32 | "statements" 33 | ], 34 | "array-type": [ 35 | true, 36 | "array-simple" 37 | ], 38 | "class-name": true, 39 | "comment-format": [ 40 | true, 41 | "check-space" 42 | ], 43 | "max-line-length": { 44 | "options": [ 45 | 120 46 | ] 47 | }, 48 | "max-file-line-count": [ 49 | true, 50 | 500 51 | ], 52 | "max-classes-per-file": [ 53 | true, 54 | 3 55 | ], 56 | "indent": [ 57 | true, 58 | "spaces", 59 | 4 60 | ], 61 | "interface-name": [ 62 | true, 63 | "always-prefix" 64 | ], 65 | "import-spacing": true, 66 | "new-parens": true, 67 | "no-duplicate-imports": true, 68 | "no-debugger": false, 69 | "no-console": false, 70 | "no-angle-bracket-type-assertion": true, 71 | "no-trailing-whitespace": true, 72 | "no-var-requires": false, 73 | "no-string-literal": false, 74 | "no-unused-expression": false, 75 | "no-empty-interface": false, 76 | "no-bitwise": false, 77 | "no-empty": [ 78 | true, 79 | "allow-empty-catch" 80 | ], 81 | "quotemark": [ 82 | true, 83 | "single", 84 | "avoid-escape", 85 | "avoid-template", 86 | "jsx-double" 87 | ], 88 | "trailing-comma": [ 89 | true, 90 | { 91 | "multiline": "never", 92 | "singleline": "never" 93 | } 94 | ], 95 | "prefer-method-signature": true, 96 | "prefer-const": [ 97 | true, 98 | { 99 | "destructuring": "all" 100 | } 101 | ], 102 | "ordered-imports": [ 103 | false, 104 | { 105 | "grouped-imports": false, 106 | "import-sources-order": "case-insensitive", 107 | "named-imports-order": "case-insensitive" 108 | } 109 | ], 110 | "object-literal-shorthand": false, 111 | "object-literal-sort-keys": [ 112 | false, 113 | "ignore-case", 114 | "match-declaration-order" 115 | ], 116 | "member-ordering": [ 117 | true, 118 | { 119 | "order": [ 120 | "static-field", 121 | "instance-field", 122 | "constructor" 123 | ] 124 | } 125 | ], 126 | "encoding": true, 127 | "jsdoc-format": [ 128 | true, 129 | "check-multiline-start" 130 | ], 131 | "jsx-alignment": true, 132 | "jsx-curly-spacing": false, 133 | "jsx-self-close": true, 134 | "jsx-wrap-multiline": true, 135 | "jsx-no-multiline-js": false, 136 | "jsx-key": true 137 | }, 138 | "rulesDirectory": [ 139 | "src/" 140 | ] 141 | } --------------------------------------------------------------------------------