Commit 6c519bb2 authored by 陈帅's avatar 陈帅

commit

parent 0d5b157e
const parser = require('@babel/parser');
const traverse = require('@babel/traverse');
const generate = require('@babel/generator');
const t = require('@babel/types');
const path = require('path');
const fs = require('fs');
const fetch = require('node-fetch');
const exec = require('child_process').exec;
const prettier = require('prettier');
const getNewRouteCode = require('./repalceRouter');
const router = require('./router.config');
const getNewRouteCode = (configPath, newRoute, absSrcPath) => {
const ast = parser.parse(fs.readFileSync(configPath, 'utf-8'), {
sourceType: 'module',
plugins: ['typescript'],
});
let routesNode = null;
const importModules = [];
// 查询当前配置文件是否导出 routes 属性
traverse.default(ast, {
Program({ node }) {
// find import
const { body } = node;
body.forEach(item => {
if (t.isImportDeclaration(item)) {
const { specifiers } = item;
const defaultEpecifier = specifiers.find(s => {
return t.isImportDefaultSpecifier(s) && t.isIdentifier(s.local);
});
if (defaultEpecifier && t.isStringLiteral(item.source)) {
importModules.push({
identifierName: defaultEpecifier.local.name,
modulePath: item.source.value,
});
}
}
});
},
ObjectExpression({ node, parent }) {
// find routes on object, like { routes: [] }
if (t.isArrayExpression(parent)) {
// children routes
return;
}
const { properties } = node;
properties.forEach(p => {
const { key, value } = p;
if (t.isObjectProperty(p) && t.isIdentifier(key) && key.name === 'routes') {
if (value) {
// find json file program expression
(p.value = parser.parse(JSON.stringify(newRoute)).program.body[0].expression),
(routesNode = value);
}
}
});
},
});
if (routesNode) {
const code = generateCode(ast);
return { code, routesPath: configPath };
} else {
throw new Error('route array config not found.');
}
};
/**
* 生成代码
* @param {*} ast
*/
function generateCode(ast) {
const newCode = generate.default(ast, {}).code;
return prettier.format(newCode, {
// format same as ant-design-pro
singleQuote: true,
trailingComma: 'es5',
printWidth: 100,
parser: 'typescript',
});
}
const relativePath = path.join(__dirname, '../config/config.ts');
const filterParentRouter = router => {
return [...router]
.map(item => {
if (item.routes) {
return { ...item, routes: filterParentRouter(item.routes) };
}
return null;
})
.filter(item => item);
};
const parentRouter = filterParentRouter(router);
const { routesPath, code } = getNewRouteCode(relativePath, parentRouter);
// write ParentRouter
fs.writeFileSync(routesPath, code);
const findAllInstallRouter = router => {
let routers = [];
router.forEach(item => {
......@@ -116,8 +27,16 @@ const findAllInstallRouter = router => {
return routers;
};
const installRouters = findAllInstallRouter(router);
let i = 0;
const filterParentRouter = router => {
return [...router]
.map(item => {
if (item.routes) {
return { ...item, routes: filterParentRouter(item.routes) };
}
return null;
})
.filter(item => item);
};
const firstUpperCase = pathString => {
return pathString
.replace('.', '')
......@@ -126,22 +45,44 @@ const firstUpperCase = pathString => {
.filter(s => s)
.join('');
};
const installBlock = () => {
const item = installRouters[i];
if (!item || !item.path) {
return;
}
console.log('install ' + item.name + ' to: ' + item.component);
const cmd = `umi block add https://github.com/ant-design/pro-blocks/tree/master/${firstUpperCase(
item.path,
)} --npm-client=cnpm --path=${item.path}`;
console.log(cmd);
exec(cmd, { encoding: 'utf8' }, (error, statusbar) => {
if (error) console.log(error);
console.log(statusbar);
i += 1;
installBlock();
const execCmd = shell => {
return new Promise((resolve, reject) => {
exec(shell, { encoding: 'utf8' }, (error, statusbar) => {
if (error) {
console.log(error);
return reject(error);
}
console.log(statusbar);
resolve();
});
});
};
// replace router config
const parentRouter = filterParentRouter(router);
const { routesPath, code } = getNewRouteCode(relativePath, parentRouter);
// write ParentRouter
fs.writeFileSync(routesPath, code);
const installBlock = () => {
const installRouters = findAllInstallRouter(router);
const installBlockIteration = async i => {
const item = installRouters[i];
if (!item || !item.path) {
return;
}
console.log('install ' + item.name + ' to: ' + item.component);
const cmd = `umi block add https://github.com/ant-design/pro-blocks/tree/master/${firstUpperCase(
item.path,
)} --npm-client=cnpm --path=${item.path}`;
const data = await fetch(
` https://github.com/ant-design/pro-blocks/tree/master/${firstUpperCase(item.path)}`,
);
await execCmd(cmd);
installBlockIteration(i + 1);
};
installBlockIteration(0);
};
installBlock();
const parser = require('@babel/parser');
const traverse = require('@babel/traverse');
const generate = require('@babel/generator');
const t = require('@babel/types');
const fs = require('fs');
const prettier = require('prettier');
const getNewRouteCode = (configPath, newRoute, absSrcPath) => {
const ast = parser.parse(fs.readFileSync(configPath, 'utf-8'), {
sourceType: 'module',
plugins: ['typescript'],
});
let routesNode = null;
const importModules = [];
// 查询当前配置文件是否导出 routes 属性
traverse.default(ast, {
Program({ node }) {
// find import
const { body } = node;
body.forEach(item => {
if (t.isImportDeclaration(item)) {
const { specifiers } = item;
const defaultEpecifier = specifiers.find(s => {
return t.isImportDefaultSpecifier(s) && t.isIdentifier(s.local);
});
if (defaultEpecifier && t.isStringLiteral(item.source)) {
importModules.push({
identifierName: defaultEpecifier.local.name,
modulePath: item.source.value,
});
}
}
});
},
ObjectExpression({ node, parent }) {
// find routes on object, like { routes: [] }
if (t.isArrayExpression(parent)) {
// children routes
return;
}
const { properties } = node;
properties.forEach(p => {
const { key, value } = p;
if (t.isObjectProperty(p) && t.isIdentifier(key) && key.name === 'routes') {
if (value) {
// find json file program expression
(p.value = parser.parse(JSON.stringify(newRoute)).program.body[0].expression),
(routesNode = value);
}
}
});
},
});
if (routesNode) {
const code = generateCode(ast);
return { code, routesPath: configPath };
} else {
throw new Error('route array config not found.');
}
};
/**
* 生成代码
* @param {*} ast
*/
function generateCode(ast) {
const newCode = generate.default(ast, {}).code;
return prettier.format(newCode, {
// format same as ant-design-pro
singleQuote: true,
trailingComma: 'es5',
printWidth: 100,
parser: 'typescript',
});
}
module.exports = getNewRouteCode;
......@@ -57,12 +57,12 @@ module.exports = [
{
path: '/form/basic-form',
name: 'basicform',
component: './Forms/BasicForm',
component: './Form/BasicForm',
},
{
path: '/form/step-form',
name: 'stepform',
component: './Forms/StepForm',
component: './Form/StepForm',
hideChildrenInMenu: true,
// routes: [
// {
......@@ -72,17 +72,17 @@ module.exports = [
// {
// path: '/form/step-form/info',
// name: 'info',
// component: './Forms/StepForm/Step1',
// component: './Form/StepForm/Step1',
// },
// {
// path: '/form/step-form/confirm',
// name: 'confirm',
// component: './Forms/StepForm/Step2',
// component: './Form/StepForm/Step2',
// },
// {
// path: '/form/step-form/result',
// name: 'result',
// component: './Forms/StepForm/Step3',
// component: './Form/StepForm/Step3',
// },
// ],
},
......@@ -90,7 +90,7 @@ module.exports = [
path: '/form/advanced-form',
name: 'advancedform',
authority: ['admin'],
component: './Forms/AdvancedForm',
component: './Form/AdvancedForm',
},
],
},
......@@ -103,22 +103,22 @@ module.exports = [
{
path: '/list/table-list',
name: 'searchtable',
component: './List/TableList',
component: './list/Tablelist',
},
{
path: '/list/basic-list',
name: 'basiclist',
component: './List/BasicList',
component: './list/Basiclist',
},
{
path: '/list/card-list',
name: 'cardlist',
component: './List/CardList',
component: './list/Cardlist',
},
{
path: '/list/search',
name: 'search-list',
component: './List/List',
component: './list/search',
routes: [
{
path: '/list/search',
......@@ -127,17 +127,17 @@ module.exports = [
{
path: '/list/search/articles',
name: 'articles',
component: './List/Articles',
component: './list/Articles',
},
{
path: '/list/search/projects',
name: 'projects',
component: './List/Projects',
component: './list/Projects',
},
{
path: '/list/search/applications',
name: 'applications',
component: './List/Applications',
component: './list/Applications',
},
],
},
......@@ -202,12 +202,6 @@ module.exports = [
name: 'server-error',
component: './Exception/500',
},
{
path: '/exception/trigger',
name: 'trigger',
hideInMenu: true,
component: './Exception/TriggerException',
},
],
},
{
......
.copy-block {
position: absolute;
right: 80px;
bottom: 40px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 80px;
height: 80px;
font-size: 20px;
background: #fff;
border-radius: 40px;
box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14),
0 1px 10px 0 rgba(0, 0, 0, 0.12);
cursor: pointer;
.copy-block-text {
font-size: 12px;
}
}
.copy-block-code {
color: #fff;
background: #000;
}
import React from 'react';
import { Icon, Typography, Tooltip } from 'antd';
import styles from './index.less';
const firstUpperCase = (pathString: string) => {
return pathString
.replace('.', '')
.split(/\/|\-/)
.map(s => s.toLowerCase().replace(/( |^)[a-z]/g, L => L.toUpperCase()))
.filter(s => s)
.join('');
};
const BlockCodeView: React.SFC<{
url: string;
}> = ({ url }) => {
console.log(url);
const blockUrl = `umi block add https://github.com/ant-design/pro-blocks/tree/master/${firstUpperCase(
url,
)} --npm-client=cnpm --path=${url}`;
return (
<div>
<Typography.Paragraph copyable>
<code className={styles['copy-block-code']}>{blockUrl}</code>
</Typography.Paragraph>
</div>
);
};
export default ({ url }: { url: string }) => {
return (
<Tooltip placement="topLeft" title={<BlockCodeView url={url} />} trigger="click">
<div className={styles['copy-block']}>
<Icon type="code" />
<div className={styles['copy-block-text']}>
下载到
<br />
项目中
</div>
</div>
</Tooltip>
);
};
......@@ -3,7 +3,7 @@ import { NoticeItem } from '@/models/global';
import { CurrentUser } from '@/models/user';
import React, { Component } from 'react';
import { Spin, Tag, Menu, Icon, Avatar, Tooltip, message } from 'antd';
import { ClickParam } from 'antd/es/menu';
import { ClickParam } from 'antd/lib/menu';
import { FormattedMessage, formatMessage } from 'umi-plugin-react/locale';
import moment from 'moment';
import groupBy from 'lodash/groupBy';
......@@ -13,6 +13,7 @@ import HeaderDropdown from '../HeaderDropdown';
import SelectLang from '../SelectLang';
import styles from './index.less';
import { connect } from 'dva';
import router from 'umi/router';
export type SiderTheme = 'light' | 'dark';
......@@ -95,27 +96,32 @@ class GlobalHeaderRight extends Component<GlobalHeaderRightProps> {
});
}
};
onMenuClick = (event: ClickParam) => {
const { onMenuClick } = this.props;
if (onMenuClick) {
onMenuClick(event);
return;
}
const { key } = event;
router.push(`/account/${key}`);
};
render() {
const { currentUser, fetchingNotices, onNoticeVisibleChange, onMenuClick, theme } = this.props;
const { currentUser, fetchingNotices, onNoticeVisibleChange, theme } = this.props;
const menu = (
<Menu className={styles.menu} selectedKeys={[]} onClick={onMenuClick}>
<Menu.Item key="userCenter">
<Menu className={styles.menu} selectedKeys={[]} onClick={this.onMenuClick}>
<Menu.Item key="center">
<Icon type="user" />
<FormattedMessage id="menu.account.center" defaultMessage="account center" />
</Menu.Item>
<Menu.Item key="userinfo">
<Menu.Item key="settings">
<Icon type="setting" />
<FormattedMessage id="menu.account.settings" defaultMessage="account settings" />
</Menu.Item>
<Menu.Item key="triggerError">
<Icon type="close-circle" />
<FormattedMessage id="menu.account.trigger" defaultMessage="Trigger Error" />
</Menu.Item>
<Menu.Divider />
<Menu.Item key="logout">
{/* <Menu.Divider /> */}
{/* <Menu.Item key="logout">
<Icon type="logout" />
<FormattedMessage id="menu.account.logout" defaultMessage="logout" />
</Menu.Item>
</Menu.Item> */}
</Menu>
);
const noticeData = this.getNoticeData();
......
import { ConnectState, ConnectProps } from '@/models/connect';
import RightContent from '@/components/GlobalHeader/RightContent';
import CopyBlock from '@/components/CopyBlock';
import { connect } from 'dva';
import React, { useState } from 'react';
import logo from '../assets/logo.svg';
......@@ -42,7 +43,7 @@ const filterMenuData = (menuList: MenuDataItem[], locale: boolean): MenuDataItem
};
const BasicLayout: React.FC<BasicLayoutProps> = props => {
const { dispatch, children, settings } = props;
const { dispatch, children, settings, location } = props;
/**
* constructor
*/
......@@ -73,15 +74,18 @@ const BasicLayout: React.FC<BasicLayoutProps> = props => {
>
{children}
</BasicLayoutComponents>
<SettingDrawer
settings={settings}
onSettingChange={config =>
dispatch!({
type: 'settings/changeSetting',
payload: config,
})
}
/>
{ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION === 'site' && (
<SettingDrawer
settings={settings}
onSettingChange={config =>
dispatch!({
type: 'settings/changeSetting',
payload: config,
})
}
/>
)}
<CopyBlock url={location.pathname} />
</>
);
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment