├── config ├── config ├── jest │ ├── cssTransform.js │ └── fileTransform.js ├── pnpTs.js ├── paths.js ├── env.js ├── modules.js ├── webpackDevServer.config.js └── webpack.config.js ├── public ├── robots.txt ├── favicon.ico ├── logo192.png ├── logo512.png ├── manifest.json └── index.html ├── src ├── logo.png ├── plugins │ ├── edit │ │ ├── config.js │ │ └── index.jsx │ ├── add │ │ ├── config.js │ │ └── index.js │ ├── del │ │ ├── config.js │ │ └── index.js │ ├── info │ │ ├── config.js │ │ └── index.jsx │ ├── examine │ │ ├── config.js │ │ └── index.jsx │ ├── export │ │ ├── config.js │ │ └── index.js │ ├── debt-information │ │ ├── config.js │ │ ├── index.less │ │ └── index.jsx │ ├── contract-information │ │ ├── config.js │ │ ├── index.less │ │ └── index.jsx │ ├── collateral-information │ │ ├── config.js │ │ ├── index.less │ │ └── index.jsx │ └── counter-collateral-information │ │ ├── config.js │ │ ├── index.less │ │ └── index.jsx ├── setupTests.js ├── App.test.js ├── pages-freely │ ├── index.js │ └── user │ │ └── index.jsx ├── pages │ ├── list │ │ ├── router.js │ │ ├── index.less │ │ ├── index.jsx │ │ ├── button-box.jsx │ │ ├── list.jsx │ │ └── search.jsx │ ├── detail │ │ ├── router.js │ │ ├── index.less │ │ └── index.jsx │ └── index │ │ ├── router.js │ │ └── index.jsx ├── index.less ├── App.less ├── index.js ├── routes.js ├── logo.svg ├── App.jsx └── serviceWorker.js ├── .gitignore ├── scripts ├── test.js ├── start.js └── build.js ├── README.md └── package.json /config/config: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | -------------------------------------------------------------------------------- /src/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuancy-code/react-plugin-demo/HEAD/src/logo.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuancy-code/react-plugin-demo/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuancy-code/react-plugin-demo/HEAD/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuancy-code/react-plugin-demo/HEAD/public/logo512.png -------------------------------------------------------------------------------- /src/plugins/edit/config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yuanchengyong 3 | * @Date: 2020-01-15 10:24:37 4 | * @Last Modified by: zyycy_love@126.com 5 | * @Last Modified time: 2020-03-25 10:12:54 6 | */ 7 | export default { 8 | id: "edit", 9 | index: "edit/index" 10 | }; 11 | -------------------------------------------------------------------------------- /src/plugins/add/config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yuanchengyong 3 | * @Date: 2020-01-15 10:24:37 4 | * @Last Modified by: zyycy_love@126.com 5 | * @Last Modified time: 2020-01-15 15:07:47 6 | */ 7 | export default { 8 | id: "listAdd", 9 | index: "add/index.js" 10 | }; 11 | -------------------------------------------------------------------------------- /src/plugins/del/config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yuanchengyong 3 | * @Date: 2020-01-15 10:57:03 4 | * @Last Modified by: zyycy_love@126.com 5 | * @Last Modified time: 2020-01-15 15:10:49 6 | */ 7 | export default { 8 | id: "listDel", 9 | index: "del/index.js" 10 | }; 11 | -------------------------------------------------------------------------------- /src/plugins/info/config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yuanchengyong 3 | * @Date: 2020-01-15 10:24:37 4 | * @Last Modified by: zyycy_love@126.com 5 | * @Last Modified time: 2020-01-15 17:22:48 6 | */ 7 | export default { 8 | id: "listInfo", 9 | index: "info/index" 10 | }; 11 | -------------------------------------------------------------------------------- /src/plugins/examine/config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yuanchengyong 3 | * @Date: 2020-01-15 10:24:37 4 | * @Last Modified by: zyycy_love@126.com 5 | * @Last Modified time: 2020-03-25 10:28:15 6 | */ 7 | export default { 8 | id: "examine", 9 | index: "examine/index" 10 | }; 11 | -------------------------------------------------------------------------------- /src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom/extend-expect'; 6 | -------------------------------------------------------------------------------- /src/plugins/export/config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yuanchengyong 3 | * @Date: 2020-01-15 10:24:37 4 | * @Last Modified by: zyycy_love@126.com 5 | * @Last Modified time: 2020-01-15 16:43:23 6 | */ 7 | export default { 8 | id: "listExport", 9 | index: "export/index.js" 10 | }; 11 | -------------------------------------------------------------------------------- /src/plugins/debt-information/config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yuanchengyong 3 | * @Date: 2020-01-15 10:57:03 4 | * @Last Modified by: yuanchengyong 5 | * @Last Modified time: 2020-02-19 14:46:47 6 | */ 7 | export default { 8 | id: "debtInfo", 9 | index: "debt-information/index.jsx" 10 | }; 11 | -------------------------------------------------------------------------------- /src/plugins/contract-information/config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yuanchengyong 3 | * @Date: 2020-01-15 10:57:03 4 | * @Last Modified by: yuanchengyong 5 | * @Last Modified time: 2020-02-20 11:28:47 6 | */ 7 | export default { 8 | id: "contractInfo", 9 | index: "contract-information/index.jsx" 10 | }; 11 | -------------------------------------------------------------------------------- /src/plugins/collateral-information/config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yuanchengyong 3 | * @Date: 2020-01-15 10:57:03 4 | * @Last Modified by: yuanchengyong 5 | * @Last Modified time: 2020-02-19 14:49:14 6 | */ 7 | export default { 8 | id: "collateralInfo", 9 | index: "collateral-information/index.jsx" 10 | }; 11 | -------------------------------------------------------------------------------- /src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from '@testing-library/react'; 3 | import App from './App'; 4 | 5 | test('renders learn react link', () => { 6 | const { getByText } = render(); 7 | const linkElement = getByText(/learn react/i); 8 | expect(linkElement).toBeInTheDocument(); 9 | }); 10 | -------------------------------------------------------------------------------- /src/plugins/counter-collateral-information/config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yuanchengyong 3 | * @Date: 2020-01-15 10:57:03 4 | * @Last Modified by: yuanchengyong 5 | * @Last Modified time: 2020-02-19 14:51:03 6 | */ 7 | export default { 8 | id: "counterCollateralInfo", 9 | index: "counter-collateral-information/index.jsx" 10 | }; 11 | -------------------------------------------------------------------------------- /src/pages-freely/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yuanchengyong 3 | * @Date: 2020-01-13 17:19:05 4 | * @Last Modified by: zyycy_love@126.com 5 | * @Last Modified time: 2020-01-13 17:20:59 6 | */ 7 | import User from "./user"; 8 | const routes = [ 9 | { 10 | path: "/user", 11 | component: User 12 | } 13 | ]; 14 | export default routes; 15 | -------------------------------------------------------------------------------- /src/pages/list/router.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yuanchengyong 3 | * @Date: 2020-01-13 14:06:12 4 | * @Last Modified by: zyycy_love@126.com 5 | * @Last Modified time: 2020-01-13 15:08:28 6 | */ 7 | import List from "./index" 8 | const routes = [ 9 | { 10 | path: "/list", 11 | component: List 12 | } 13 | ]; 14 | export default routes; 15 | -------------------------------------------------------------------------------- /src/pages/detail/router.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yuanchengyong 3 | * @Date: 2020-01-13 14:06:12 4 | * @Last Modified by: yuanchengyong 5 | * @Last Modified time: 2020-03-25 23:43:53 6 | */ 7 | import Detail from "./index" 8 | const routes = [ 9 | { 10 | path: "/detail/:id?", 11 | component: Detail 12 | } 13 | ]; 14 | export default routes; 15 | -------------------------------------------------------------------------------- /src/pages/index/router.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yuanchengyong 3 | * @Date: 2020-01-13 14:06:12 4 | * @Last Modified by: zyycy_love@126.com 5 | * @Last Modified time: 2020-01-13 15:03:31 6 | */ 7 | import Index from "./index"; 8 | const routes = [ 9 | { 10 | path: "/index", 11 | component: Index 12 | } 13 | ]; 14 | export default routes; 15 | -------------------------------------------------------------------------------- /src/plugins/add/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yuanchengyong 3 | * @Date: 2020-01-15 09:24:28 4 | * @Last Modified by: zyycy_love@126.com 5 | * @Last Modified time: 2020-01-15 15:25:45 6 | */ 7 | import { message } from "antd"; 8 | 9 | export default function(config = {}) { 10 | const { calllBack = () => {} } = config; 11 | message.success("添加成功!"); 12 | calllBack(); 13 | } 14 | -------------------------------------------------------------------------------- /config/jest/cssTransform.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // This is a custom Jest transformer turning style imports into empty objects. 4 | // http://facebook.github.io/jest/docs/en/webpack.html 5 | 6 | module.exports = { 7 | process() { 8 | return 'module.exports = {};'; 9 | }, 10 | getCacheKey() { 11 | // The output is always the same. 12 | return 'cssTransform'; 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /src/pages/list/index.less: -------------------------------------------------------------------------------- 1 | .list-content { 2 | .group-area { 3 | border: 1px solid #eaeaea; 4 | padding: 20px; 5 | background: #f9f9f9; 6 | } 7 | .list-area { 8 | padding: 24px 0 0 0; 9 | } 10 | .button-area { 11 | text-align: right; 12 | margin-top: 24px; 13 | .button-box { 14 | .ant-btn { 15 | margin-left: 10px; 16 | } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /src/index.less: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 5 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 6 | sans-serif; 7 | -webkit-font-smoothing: antialiased; 8 | -moz-osx-font-smoothing: grayscale; 9 | } 10 | 11 | code { 12 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 13 | monospace; 14 | } 15 | -------------------------------------------------------------------------------- /src/plugins/export/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yuanchengyong 3 | * @Date: 2020-01-15 09:24:28 4 | * @Last Modified by: zyycy_love@126.com 5 | * @Last Modified time: 2020-03-25 15:24:22 6 | */ 7 | import { message } from "antd"; 8 | 9 | export default function(config = {}) { 10 | const { callBack = () => {}, listSelected = [] } = config; 11 | if (listSelected.length === 0) { 12 | message.warn("请选择!"); 13 | return false; 14 | } 15 | message.warning("暂时无法导出!"); 16 | callBack(); 17 | } 18 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /src/plugins/edit/index.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yuanchengyong 3 | * @Date: 2020-01-15 09:24:28 4 | * @Last Modified by: zyycy_love@126.com 5 | * @Last Modified time: 2020-03-25 11:38:51 6 | */ 7 | import { message, Modal } from "antd"; 8 | const { confirm } = Modal; 9 | export default function (config = {}) { 10 | const { onOk = () => { }, onCancel = () => { } } = config; 11 | confirm({ 12 | title: "您确定要编辑吗?", 13 | okText: "确定", 14 | cancelText: "取消", 15 | onOk() { 16 | message.success("编辑成功!"); 17 | onOk("Ok"); 18 | }, 19 | onCancel() { 20 | onCancel("Cancel"); 21 | } 22 | }); 23 | } 24 | -------------------------------------------------------------------------------- /src/plugins/examine/index.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yuanchengyong 3 | * @Date: 2020-01-15 09:24:28 4 | * @Last Modified by: zyycy_love@126.com 5 | * @Last Modified time: 2020-03-25 11:38:56 6 | */ 7 | import { message, Modal } from "antd"; 8 | const { confirm } = Modal; 9 | export default function (config = {}) { 10 | const { onOk = () => { }, onCancel = () => { } } = config; 11 | confirm({ 12 | title: "您确定要送审吗?", 13 | okText: "确定", 14 | cancelText: "取消", 15 | onOk() { 16 | message.success("送审成功..."); 17 | onOk("Ok"); 18 | }, 19 | onCancel() { 20 | onCancel("Cancel"); 21 | } 22 | }); 23 | } 24 | -------------------------------------------------------------------------------- /src/pages/index/index.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yuanchengyong 3 | * @Date: 2020-01-09 10:00:15 4 | * @Last Modified by: zyycy_love@126.com 5 | * @Last Modified time: 2020-01-13 17:24:11 6 | */ 7 | import React from "react"; 8 | import { Link } from 'react-router-dom'; 9 | 10 | function Example() { 11 | return ( 12 |
13 |

This is 'Index' component

14 | List 16 |
17 | Detail 19 |
20 | ); 21 | } 22 | export default Example; -------------------------------------------------------------------------------- /src/App.less: -------------------------------------------------------------------------------- 1 | html { 2 | * { 3 | margin: 0; 4 | padding: 0; 5 | } 6 | 7 | p { 8 | margin: 0; 9 | } 10 | } 11 | 12 | .app { 13 | .logo { 14 | height: 100%; 15 | background: url(./logo.png) no-repeat; 16 | background-size: auto 50%; 17 | margin: 0 20px 0 0; 18 | background-position: 0 center; 19 | float: left; 20 | color: #fff; 21 | text-indent: 77px; 22 | font-size: 14px; 23 | } 24 | 25 | .user-info { 26 | float: right; 27 | color: #fff; 28 | 29 | .user-name { 30 | margin-left: 10px; 31 | } 32 | } 33 | 34 | .container { 35 | height: calc(~"100vh - 64px"); 36 | } 37 | } -------------------------------------------------------------------------------- /src/plugins/debt-information/index.less: -------------------------------------------------------------------------------- 1 | .debt-info-plugin{ 2 | .title { 3 | font-size: 16px; 4 | color: #4b4b4b; 5 | font-weight: bold; 6 | margin: 10px 0; 7 | .antion{ 8 | cursor: pointer; 9 | } 10 | .antion-up { 11 | &::after { 12 | content: "▲"; 13 | margin: 0 5px; 14 | color: #4b81fd; 15 | } 16 | } 17 | 18 | .antion-down { 19 | &::after { 20 | content: "▼"; 21 | margin: 0 5px; 22 | color: #4b81fd; 23 | } 24 | } 25 | } 26 | 27 | } -------------------------------------------------------------------------------- /src/plugins/collateral-information/index.less: -------------------------------------------------------------------------------- 1 | .collateral-info-plugin{ 2 | .title { 3 | font-size: 16px; 4 | color: #4b4b4b; 5 | font-weight: bold; 6 | margin: 10px 0; 7 | .antion{ 8 | cursor: pointer; 9 | } 10 | .antion-up { 11 | &::after { 12 | content: "▲"; 13 | margin: 0 5px; 14 | color: #4b81fd; 15 | } 16 | } 17 | 18 | .antion-down { 19 | &::after { 20 | content: "▼"; 21 | margin: 0 5px; 22 | color: #4b81fd; 23 | } 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/plugins/counter-collateral-information/index.less: -------------------------------------------------------------------------------- 1 | .counter-collateral-plugin{ 2 | .title { 3 | font-size: 16px; 4 | color: #4b4b4b; 5 | font-weight: bold; 6 | margin: 10px 0; 7 | .antion{ 8 | cursor: pointer; 9 | } 10 | .antion-up { 11 | &::after { 12 | content: "▲"; 13 | margin: 0 5px; 14 | color: #4b81fd; 15 | } 16 | } 17 | 18 | .antion-down { 19 | &::after { 20 | content: "▼"; 21 | margin: 0 5px; 22 | color: #4b81fd; 23 | } 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/pages-freely/user/index.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yuanchengyong 3 | * @Date: 2020-01-09 10:00:15 4 | * @Last Modified by: zyycy_love@126.com 5 | * @Last Modified time: 2020-01-13 17:23:05 6 | */ 7 | import React from "react"; 8 | import { useState } from 'react'; 9 | 10 | 11 | function Example() { 12 | // Declare a new state variable, which we'll call "count" 13 | const [count, setCount] = useState(0); 14 | return ( 15 |
16 |

This is 'User' component

17 |

You clicked {count} times

18 | 19 |
20 | ); 21 | } 22 | export default Example; -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom"; 3 | import "./index.less"; 4 | import App from "./App"; 5 | import * as serviceWorker from "./serviceWorker"; 6 | import {register} from "react-plugin-system"; 7 | 8 | let pages = require.context("@plugins", true, /\/.*config\.js$/); 9 | pages.keys().map(key => { 10 | let config = pages(key).default; 11 | // 注册插件 12 | register(config); 13 | return config; 14 | }); 15 | 16 | ReactDOM.render(, document.getElementById("root")); 17 | 18 | // If you want your app to work offline and load faster, you can change 19 | // unregister() to register() below. Note this comes with some pitfalls. 20 | // Learn more about service workers: https://bit.ly/CRA-PWA 21 | serviceWorker.unregister(); 22 | -------------------------------------------------------------------------------- /config/pnpTs.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { resolveModuleName } = require('ts-pnp'); 4 | 5 | exports.resolveModuleName = ( 6 | typescript, 7 | moduleName, 8 | containingFile, 9 | compilerOptions, 10 | resolutionHost 11 | ) => { 12 | return resolveModuleName( 13 | moduleName, 14 | containingFile, 15 | compilerOptions, 16 | resolutionHost, 17 | typescript.resolveModuleName 18 | ); 19 | }; 20 | 21 | exports.resolveTypeReferenceDirective = ( 22 | typescript, 23 | moduleName, 24 | containingFile, 25 | compilerOptions, 26 | resolutionHost 27 | ) => { 28 | return resolveModuleName( 29 | moduleName, 30 | containingFile, 31 | compilerOptions, 32 | resolutionHost, 33 | typescript.resolveTypeReferenceDirective 34 | ); 35 | }; 36 | -------------------------------------------------------------------------------- /src/plugins/del/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yuanchengyong 3 | * @Date: 2020-01-15 09:15:48 4 | * @Last Modified by: zyycy_love@126.com 5 | * @Last Modified time: 2020-03-25 15:22:04 6 | */ 7 | import { message, Modal } from "antd"; 8 | const { confirm } = Modal; 9 | 10 | export default function(config) { 11 | const { onOk = () => {}, onCancel = () => {}, listSelected = [] } = config; 12 | if (listSelected.length === 0) { 13 | message.warn("请选择!"); 14 | return false; 15 | } 16 | confirm({ 17 | title: "您确定要删除吗?", 18 | content: "删除后将无法恢复,请再次确认!", 19 | okText: "确定", 20 | cancelText: "取消", 21 | onOk() { 22 | message.success("删除成功!"); 23 | onOk("Ok"); 24 | }, 25 | onCancel() { 26 | onCancel("Cancel"); 27 | } 28 | }); 29 | } 30 | -------------------------------------------------------------------------------- /src/routes.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yuanchengyong 3 | * @Date: 2020-01-13 14:09:45 4 | * @Last Modified by: yuanchengyong 5 | * @Last Modified time: 2020-02-20 11:32:37 6 | */ 7 | import routesFreely from "./pages-freely/index"; 8 | let pages = require.context("./pages", true, /\/.*router\.js$/); 9 | let routes = []; 10 | let pathKeys = []; 11 | pages.keys().map(key => { 12 | let route = pages(key).default; 13 | route.map(item => { 14 | let path = item.path; 15 | if (pathKeys.includes(path)) { 16 | console.warn(`Route "${path}" already exists, please modify!`); 17 | } 18 | pathKeys.push(path); 19 | return item; 20 | }); 21 | routes = [...routes, ...route]; 22 | return routes; 23 | }); 24 | 25 | export default [ 26 | ...routes, // 自动加载route.js文件 27 | ...routesFreely // 自由定义路由 28 | ]; 29 | -------------------------------------------------------------------------------- /src/plugins/info/index.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yuanchengyong 3 | * @Date: 2020-01-15 09:24:28 4 | * @Last Modified by: zyycy_love@126.com 5 | * @Last Modified time: 2020-01-15 17:43:48 6 | */ 7 | import React from "react"; 8 | import { Button, notification } from "antd"; 9 | 10 | 11 | 12 | export default class Info extends React.Component { 13 | constructor(props) { 14 | super(props); 15 | this.state = {}; 16 | } 17 | clickHandle = () => { 18 | const { onClose = () => { } } = this.props; 19 | notification['info']({ 20 | message: '项目信息', 21 | description: 22 | '这是通知的内容。这是通知的内容。这是通知的内容。', 23 | onClose: () => { 24 | onClose('User Close') 25 | } 26 | }); 27 | } 28 | render() { 29 | return ; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/pages/list/index.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yuanchengyong 3 | * @Date: 2020-01-09 10:00:15 4 | * @Last Modified by: zyycy_love@126.com 5 | * @Last Modified time: 2020-03-25 15:15:24 6 | */ 7 | import React, { useState } from 'react' 8 | import SearchArea from "./search"; 9 | import ListArea from "./list"; 10 | import ButtonBox from "./button-box"; 11 | import "./index.less"; 12 | 13 | export default function () { 14 | const [listSelected, setListSelected] = useState([]); 15 | return
16 |
17 | 18 |
19 |
20 | 21 |
22 |
23 | { 24 | setListSelected(selectedRows); 25 | }} /> 26 |
27 |
28 | }; -------------------------------------------------------------------------------- /src/pages/detail/index.less: -------------------------------------------------------------------------------- 1 | .content-detail { 2 | .fc-blue { 3 | font-size: 24px; 4 | color: #3c76f9; 5 | font-weight: bold; 6 | } 7 | 8 | .mr10 { 9 | margin-right: 10px; 10 | } 11 | 12 | .big-title-warp { 13 | .group-title { 14 | padding: 0 20px 10px 0; 15 | color: #4b4b4b; 16 | font-weight: bold; 17 | font-size: 16px; 18 | } 19 | } 20 | 21 | .top-base-content { 22 | background: #edf4ff; 23 | border: 1px solid #edf4ff; 24 | padding: 24px; 25 | margin-top: 16px; 26 | 27 | .code-item { 28 | font-size: 16px; 29 | color: #333; 30 | margin-bottom: 30px; 31 | font-weight: bold; 32 | } 33 | 34 | .top-info-item { 35 | font-size: 16px; 36 | color: #000; 37 | line-height: 35px; 38 | 39 | .item { 40 | border-right: 1px solid #ccddf7; 41 | } 42 | } 43 | } 44 | 45 | .detail-content { 46 | margin: 20px 0; 47 | 48 | } 49 | .title-info { 50 | .button-list { 51 | text-align: right; 52 | .ant-btn { 53 | margin-left: 10px; 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/plugins/contract-information/index.less: -------------------------------------------------------------------------------- 1 | .contract-info-plugin { 2 | .list { 3 | margin: 0 0 20px 0; 4 | .title { 5 | font-size: 16px; 6 | color: #4b4b4b; 7 | font-weight: bold; 8 | margin: 10px 0; 9 | .antion{ 10 | cursor: pointer; 11 | } 12 | .antion-up { 13 | &::after { 14 | content: "▲"; 15 | margin: 0 5px; 16 | color: #4b81fd; 17 | } 18 | } 19 | 20 | .antion-down { 21 | &::after { 22 | content: "▼"; 23 | margin: 0 5px; 24 | color: #4b81fd; 25 | } 26 | } 27 | } 28 | 29 | .info { 30 | background: #f7f7f7; 31 | padding: 20px; 32 | 33 | .item { 34 | line-height: 36px; 35 | font-size: 16px; 36 | color: #999; 37 | 38 | .item-title { 39 | &::after { 40 | content: ":"; 41 | } 42 | } 43 | 44 | .item-value { 45 | color: #444; 46 | } 47 | } 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /config/jest/fileTransform.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const camelcase = require('camelcase'); 5 | 6 | // This is a custom Jest transformer turning file imports into filenames. 7 | // http://facebook.github.io/jest/docs/en/webpack.html 8 | 9 | module.exports = { 10 | process(src, filename) { 11 | const assetFilename = JSON.stringify(path.basename(filename)); 12 | 13 | if (filename.match(/\.svg$/)) { 14 | // Based on how SVGR generates a component name: 15 | // https://github.com/smooth-code/svgr/blob/01b194cf967347d43d4cbe6b434404731b87cf27/packages/core/src/state.js#L6 16 | const pascalCaseFilename = camelcase(path.parse(filename).name, { 17 | pascalCase: true, 18 | }); 19 | const componentName = `Svg${pascalCaseFilename}`; 20 | return `const React = require('react'); 21 | module.exports = { 22 | __esModule: true, 23 | default: ${assetFilename}, 24 | ReactComponent: React.forwardRef(function ${componentName}(props, ref) { 25 | return { 26 | $$typeof: Symbol.for('react.element'), 27 | type: 'svg', 28 | ref: ref, 29 | key: null, 30 | props: Object.assign({}, props, { 31 | children: ${assetFilename} 32 | }) 33 | }; 34 | }), 35 | };`; 36 | } 37 | 38 | return `module.exports = ${assetFilename};`; 39 | }, 40 | }; 41 | -------------------------------------------------------------------------------- /scripts/test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Do this as the first thing so that any code reading it knows the right env. 4 | process.env.BABEL_ENV = 'test'; 5 | process.env.NODE_ENV = 'test'; 6 | process.env.PUBLIC_URL = ''; 7 | 8 | // Makes the script crash on unhandled rejections instead of silently 9 | // ignoring them. In the future, promise rejections that are not handled will 10 | // terminate the Node.js process with a non-zero exit code. 11 | process.on('unhandledRejection', err => { 12 | throw err; 13 | }); 14 | 15 | // Ensure environment variables are read. 16 | require('../config/env'); 17 | 18 | 19 | const jest = require('jest'); 20 | const execSync = require('child_process').execSync; 21 | let argv = process.argv.slice(2); 22 | 23 | function isInGitRepository() { 24 | try { 25 | execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore' }); 26 | return true; 27 | } catch (e) { 28 | return false; 29 | } 30 | } 31 | 32 | function isInMercurialRepository() { 33 | try { 34 | execSync('hg --cwd . root', { stdio: 'ignore' }); 35 | return true; 36 | } catch (e) { 37 | return false; 38 | } 39 | } 40 | 41 | // Watch unless on CI or explicitly running all tests 42 | if ( 43 | !process.env.CI && 44 | argv.indexOf('--watchAll') === -1 && 45 | argv.indexOf('--watchAll=false') === -1 46 | ) { 47 | // https://github.com/facebook/create-react-app/issues/5210 48 | const hasSourceControl = isInGitRepository() || isInMercurialRepository(); 49 | argv.push(hasSourceControl ? '--watch' : '--watchAll'); 50 | } 51 | 52 | 53 | jest.run(argv); 54 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | Template Build Demo 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/pages/list/button-box.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yuanchengyong 3 | * @Date: 2020-01-14 15:51:18 4 | * @Last Modified by: zyycy_love@126.com 5 | * @Last Modified time: 2020-03-25 15:23:57 6 | */ 7 | import React from "react"; 8 | import { Button } from 'antd'; 9 | import { callPlugin, Plugin } from "react-plugin-system"; 10 | 11 | class ButtonBox extends React.Component { 12 | constructor(props) { 13 | super(props); 14 | this.state = {}; 15 | } 16 | /** 17 | * 新增 18 | */ 19 | addHandle = async () => { 20 | // 调用插件 21 | let path = (callPlugin('listAdd')); 22 | let plugin = await import("@plugins/" + path); 23 | (plugin.default)({ a: 1 }); 24 | 25 | } 26 | /** 27 | * 删除 28 | */ 29 | delHandle = async () => { 30 | const { listSelected } = this.props; 31 | // 调用插件 32 | let path = (callPlugin('listDel')); 33 | let plugin = await import("@plugins/" + path); 34 | (plugin.default)({ listSelected }); 35 | } 36 | /** 37 | * 导出 38 | */ 39 | exportHandle = async () => { 40 | const { listSelected } = this.props; 41 | // 调用插件 42 | let path = (callPlugin('listExport')); 43 | let plugin = await import("@plugins/" + path); 44 | (plugin.default)({ listSelected }); 45 | } 46 | /** 47 | * 信息点击关闭 48 | */ 49 | infoCloseHandel = (data) => { 50 | console.log(data) 51 | } 52 | render() { 53 | let path = (callPlugin('listInfo')); 54 | return
55 | 56 | 57 | 58 | { return import("@plugins/" + path) }} onClose={this.infoCloseHandel} /> 59 |
60 | } 61 | } 62 | 63 | export default ButtonBox; -------------------------------------------------------------------------------- /src/plugins/collateral-information/index.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yuanchengyong 3 | * @Date: 2020-01-15 09:15:48 4 | * @Last Modified by: yuanchengyong 5 | * @Last Modified time: 2020-02-20 13:41:45 6 | * @Des 担保物信息 7 | */ 8 | import React from "react"; 9 | import { Table } from "antd"; 10 | 11 | import "./index.less"; 12 | const columns = [ 13 | { 14 | title: "序号", 15 | dataIndex: "a", 16 | key: "a", 17 | render: (text, record, i) => { 18 | return i + 1; 19 | } 20 | }, 21 | { 22 | title: "担保方式", 23 | dataIndex: "b", 24 | key: "b" 25 | }, 26 | { 27 | title: "担保物编号", 28 | dataIndex: "c", 29 | key: "c" 30 | }, 31 | { 32 | title: "担保物名称", 33 | dataIndex: "d", 34 | key: "d" 35 | }, 36 | { 37 | title: "担保物类型", 38 | dataIndex: "e", 39 | key: "e" 40 | }, 41 | { 42 | title: "担保物价值/保证责任金额", 43 | dataIndex: "f", 44 | key: "f" 45 | }, 46 | { 47 | title: "备注", 48 | dataIndex: "g", 49 | key: "g" 50 | } 51 | ]; 52 | const data = [ 53 | { 54 | id: 1, 55 | b: "连带责任担保", 56 | c: "PD-001", 57 | d: "xx区10000平面房产", 58 | e: "房产", 59 | f: "102,787,121,224.00", 60 | g: "无" 61 | }, 62 | { 63 | id: 2, 64 | b: "连带责任担保", 65 | c: "PD-002", 66 | d: "xx区20000平面房产", 67 | e: "房产", 68 | f: "202,787,121,224.00", 69 | g: "无" 70 | } 71 | ]; 72 | export default class Info extends React.Component { 73 | constructor(props) { 74 | super(props); 75 | this.state = {}; 76 | } 77 | 78 | render() { 79 | return ( 80 |
81 |
82 | 担保物信息 83 |
84 |
85 | { 88 | return record.id; 89 | }} 90 | dataSource={data} 91 | /> 92 | 93 | 94 | ); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/plugins/counter-collateral-information/index.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yuanchengyong 3 | * @Date: 2020-01-15 09:15:48 4 | * @Last Modified by: yuanchengyong 5 | * @Last Modified time: 2020-02-20 13:47:04 6 | * @Des 反担保信息 7 | */ 8 | import React from "react"; 9 | import { Table } from "antd"; 10 | 11 | import "./index.less"; 12 | const columns = [ 13 | { 14 | title: "序号", 15 | dataIndex: "a", 16 | key: "a", 17 | render: (text, record, i) => { 18 | return i + 1; 19 | } 20 | }, 21 | { 22 | title: "反担保类型", 23 | dataIndex: "b", 24 | key: "b" 25 | }, 26 | { 27 | title: "反担保保证人全称", 28 | dataIndex: "c", 29 | key: "c" 30 | }, 31 | { 32 | title: "反担保资产类型", 33 | dataIndex: "d", 34 | key: "d" 35 | }, 36 | { 37 | title: "反担保质押物编码", 38 | dataIndex: "e", 39 | key: "e" 40 | }, 41 | { 42 | title: "反担保质押物价值", 43 | dataIndex: "f", 44 | key: "f" 45 | }, 46 | { 47 | title: "反担保金额", 48 | dataIndex: "g", 49 | key: "g" 50 | }, 51 | { 52 | title: "反担保到期日", 53 | dataIndex: "h", 54 | key: "h" 55 | }, 56 | { 57 | title: "备注", 58 | dataIndex: "i", 59 | key: "i" 60 | } 61 | ]; 62 | const data = [ 63 | { 64 | id: 1, 65 | b: "连带责任担保", 66 | c: "xx市A集团A1分公司", 67 | d: "连带责任担保", 68 | e: "DD-001-9121", 69 | f: "102,787,121,224.00", 70 | g: "544,444,787.00", 71 | h: "2020-12-20", 72 | i: "无", 73 | }, 74 | { 75 | id: 2, 76 | b: "连带责任担保", 77 | c: "xx市B集团B1分公司", 78 | d: "连带责任担保", 79 | e: "DD-001-3121", 80 | f: "12,787,121,224.00", 81 | g: "44,444,787.00", 82 | h: "2020-12-20", 83 | i: "无", 84 | } 85 | ]; 86 | export default class Info extends React.Component { 87 | constructor(props) { 88 | super(props); 89 | this.state = {}; 90 | } 91 | 92 | render() { 93 | return ( 94 |
95 |
96 | 反担保信息 97 |
98 |
99 |
{ 102 | return record.id; 103 | }} 104 | dataSource={data} 105 | /> 106 | 107 | 108 | ); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/plugins/debt-information/index.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yuanchengyong 3 | * @Date: 2020-01-15 09:15:48 4 | * @Last Modified by: zyycy_love@126.com 5 | * @Last Modified time: 2020-03-26 09:42:29 6 | * @Des 债务信息 7 | */ 8 | import React from "react"; 9 | import { Table } from "antd"; 10 | 11 | import "./index.less"; 12 | const columns = [ 13 | { 14 | title: "序号", 15 | dataIndex: "a", 16 | key: "a", 17 | width: 140, 18 | render: (text, record, i) => { 19 | return i + 1; 20 | } 21 | }, 22 | { 23 | title: "债务编码", 24 | dataIndex: "b", 25 | key: "b" 26 | }, 27 | { 28 | title: "债务名称", 29 | dataIndex: "c", 30 | key: "c" 31 | }, 32 | { 33 | title: "融资类型", 34 | dataIndex: "d", 35 | key: "d" 36 | }, 37 | { 38 | title: "本金偿还方式", 39 | dataIndex: "e", 40 | key: "e" 41 | }, 42 | { 43 | title: "币种", 44 | dataIndex: "f", 45 | key: "f" 46 | }, 47 | { 48 | title: "起息日", 49 | dataIndex: "g", 50 | key: "g" 51 | }, 52 | { 53 | title: "执行利率(%)", 54 | dataIndex: "h", 55 | key: "h" 56 | }, 57 | { 58 | title: "到期日", 59 | dataIndex: "i", 60 | key: "i" 61 | }, 62 | { 63 | title: "期限(月)", 64 | dataIndex: "j", 65 | key: "j" 66 | }, 67 | { 68 | title: "担保债务本金余额(原币)", 69 | dataIndex: "k", 70 | key: "k" 71 | }, 72 | { 73 | title: "已代偿总金额(原币)", 74 | dataIndex: "l", 75 | key: "l" 76 | }, 77 | { 78 | title: "备注", 79 | dataIndex: "m", 80 | key: "m" 81 | } 82 | ]; 83 | const data = [ 84 | { 85 | id: 1, 86 | b: "DC-199-12", 87 | c: "皮冻-001", 88 | d: "地方债券", 89 | e: "到期偿还", 90 | f: "人民币", 91 | g: "2019-09-21", 92 | h: "0.12", 93 | i: "2020-09-21", 94 | j: "12", 95 | k: "125,121,455,450.00", 96 | l: "35,121,455,450.00", 97 | m: "无" 98 | }, 99 | { 100 | id: 2, 101 | b: "DC-199-21", 102 | c: "皮冻-021", 103 | d: "地方债券", 104 | e: "到期偿还", 105 | f: "人民币", 106 | g: "2019-09-21", 107 | h: "0.12", 108 | i: "2020-09-21", 109 | j: "12", 110 | k: "125,121,455,450.00", 111 | l: "35,121,455,450.00", 112 | m: "无" 113 | } 114 | ]; 115 | export default class Info extends React.Component { 116 | constructor(props) { 117 | super(props); 118 | this.state = {}; 119 | } 120 | 121 | render() { 122 | return ( 123 |
124 |
125 | 债务信息 126 |
127 |
128 |
{ return record.id }} dataSource={data} scroll={{ x: 2200 }} /> 129 | 130 | 131 | ); 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /config/paths.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const fs = require('fs'); 5 | const url = require('url'); 6 | 7 | // Make sure any symlinks in the project folder are resolved: 8 | // https://github.com/facebook/create-react-app/issues/637 9 | const appDirectory = fs.realpathSync(process.cwd()); 10 | const resolveApp = relativePath => path.resolve(appDirectory, relativePath); 11 | 12 | const envPublicUrl = process.env.PUBLIC_URL; 13 | 14 | function ensureSlash(inputPath, needsSlash) { 15 | const hasSlash = inputPath.endsWith('/'); 16 | if (hasSlash && !needsSlash) { 17 | return inputPath.substr(0, inputPath.length - 1); 18 | } else if (!hasSlash && needsSlash) { 19 | return `${inputPath}/`; 20 | } else { 21 | return inputPath; 22 | } 23 | } 24 | 25 | const getPublicUrl = appPackageJson => 26 | envPublicUrl || require(appPackageJson).homepage; 27 | 28 | // We use `PUBLIC_URL` environment variable or "homepage" field to infer 29 | // "public path" at which the app is served. 30 | // Webpack needs to know it to put the right