diff --git a/AccountCenter/.gitignore b/AccountCenter/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8ce76bc425533aa85835a516e25a0d7218a6e15b --- /dev/null +++ b/AccountCenter/.gitignore @@ -0,0 +1,7 @@ +/yarn.lock +/package-lock.json +/dist +/node_modules + +.umi +.umi-production diff --git a/AccountCenter/.umirc.js b/AccountCenter/.umirc.js new file mode 100644 index 0000000000000000000000000000000000000000..6f5bf0564d9bd0bd2952b8c733821edae8d6c4f8 --- /dev/null +++ b/AccountCenter/.umirc.js @@ -0,0 +1,13 @@ +export default { + plugins: [ + ['umi-plugin-block-dev', { layout: 'ant-design-pro' }], + [ + 'umi-plugin-react', + { + dva: true, + locale: true, + antd: true, + }, + ], + ], +}; diff --git a/AccountCenter/README.md b/AccountCenter/README.md new file mode 100644 index 0000000000000000000000000000000000000000..ddecd3225528d0712bd911d273df731ba6a87e26 --- /dev/null +++ b/AccountCenter/README.md @@ -0,0 +1,17 @@ +# @umi-blocks/ant-design-pro/accountcenter + +AccountCenter + +## Usage + +```sh +umi block add ant-design-pro/AccountCenter +``` + +## SNAPSHOT + +![SNAPSHOT](./snapshot.png) + +## LICENSE + +MIT diff --git a/AccountCenter/package.json b/AccountCenter/package.json new file mode 100644 index 0000000000000000000000000000000000000000..d8cd626ee453fa1ec271aeea23ef596930a38e20 --- /dev/null +++ b/AccountCenter/package.json @@ -0,0 +1,25 @@ +{ + "name": "@umi-block/account-center", + "version": "0.0.1", + "description": "AccountCenter", + "main": "src/index.js", + "scripts": { + "dev": "umi dev" + }, + "repository": { + "type": "git", + "url": "https://github.com/umijs/umi-blocks/ant-design-pro/accountcenter" + }, + "dependencies": { + "antd": "^3.10.9", + "dva": "^2.4.0", + "react": "^16.6.3", + "umi-request": "^1.0.0" + }, + "devDependencies": { + "umi": "^2.3.0-beta.1", + "umi-plugin-react": "^1.3.0-beta.1", + "umi-plugin-block-dev": "^1.0.0" + }, + "license": "ISC" +} diff --git a/AccountCenter/snapshot.png b/AccountCenter/snapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..a5a4515c4af4dde29296e704f1f4804ffe686fca Binary files /dev/null and b/AccountCenter/snapshot.png differ diff --git a/src/pages/Account/Center/Center.less b/AccountCenter/src/Center.less similarity index 92% rename from src/pages/Account/Center/Center.less rename to AccountCenter/src/Center.less index 37d6a203e668df00d742f20c366721a18304600c..c6125f1e6f3ba76be4ae149cc0daed39ca62e10f 100644 --- a/src/pages/Account/Center/Center.less +++ b/AccountCenter/src/Center.less @@ -1,5 +1,4 @@ @import '~antd/lib/style/themes/default.less'; -@import '~@/utils/utils.less'; .avatarHolder { text-align: center; @@ -80,7 +79,10 @@ margin-bottom: 24px; color: @text-color; transition: color 0.3s; - .textOverflow(); + overflow: hidden; + text-overflow: ellipsis; + word-break: break-all; + white-space: nowrap; &:hover { color: @primary-color; diff --git a/AccountCenter/src/_mock.js b/AccountCenter/src/_mock.js new file mode 100644 index 0000000000000000000000000000000000000000..3c9ef791dce51d8bed8dc2b6f2dcc56d7e8bc046 --- /dev/null +++ b/AccountCenter/src/_mock.js @@ -0,0 +1,138 @@ +const titles = [ + 'Alipay', + 'Angular', + 'Ant Design', + 'Ant Design Pro', + 'Bootstrap', + 'React', + 'Vue', + 'Webpack', +]; +const avatars = [ + 'https://gw.alipayobjects.com/zos/rmsportal/WdGqmHpayyMjiEhcKoVE.png', // Alipay + 'https://gw.alipayobjects.com/zos/rmsportal/zOsKZmFRdUtvpqCImOVY.png', // Angular + 'https://gw.alipayobjects.com/zos/rmsportal/dURIMkkrRFpPgTuzkwnB.png', // Ant Design + 'https://gw.alipayobjects.com/zos/rmsportal/sfjbOqnsXXJgNCjCzDBL.png', // Ant Design Pro + 'https://gw.alipayobjects.com/zos/rmsportal/siCrBXXhmvTQGWPNLBow.png', // Bootstrap + 'https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png', // React + 'https://gw.alipayobjects.com/zos/rmsportal/ComBAopevLwENQdKWiIn.png', // Vue + 'https://gw.alipayobjects.com/zos/rmsportal/nxkuOJlFJuAUhzlMTCEe.png', // Webpack +]; + +const getNotice = [ + { + id: 'xxx1', + title: titles[0], + logo: avatars[0], + description: '那是一种内在的东西,他们到达不了,也无法触及的', + updatedAt: new Date(), + member: '科学搬砖组', + href: '', + memberLink: '', + }, + { + id: 'xxx2', + title: titles[1], + logo: avatars[1], + description: '希望是一个好东西,也许是最好的,好东西是不会消亡的', + updatedAt: new Date('2017-07-24'), + member: '全组都是吴彦祖', + href: '', + memberLink: '', + }, + { + id: 'xxx3', + title: titles[2], + logo: avatars[2], + description: '城镇中有那么多的酒馆,她却偏偏走进了我的酒馆', + updatedAt: new Date(), + member: '中二少女团', + href: '', + memberLink: '', + }, + { + id: 'xxx4', + title: titles[3], + logo: avatars[3], + description: '那时候我只会想自己想要什么,从不想自己拥有什么', + updatedAt: new Date('2017-07-23'), + member: '程序员日常', + href: '', + memberLink: '', + }, + { + id: 'xxx5', + title: titles[4], + logo: avatars[4], + description: '凛冬将至', + updatedAt: new Date('2017-07-23'), + member: '高逼格设计天团', + href: '', + memberLink: '', + }, + { + id: 'xxx6', + title: titles[5], + logo: avatars[5], + description: '生命就像一盒巧克力,结果往往出人意料', + updatedAt: new Date('2017-07-23'), + member: '骗你来学计算机', + href: '', + memberLink: '', + }, +]; + +export default { + // 支持值为 Object 和 Array + 'GET /api/BLOCK_NAME/currentUser': { + name: 'Serati Ma', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png', + userid: '00000001', + email: 'antdesign@alipay.com', + signature: '海纳百川,有容乃大', + title: '交互专家', + group: '蚂蚁金服-某某某事业群-某某平台部-某某技术部-UED', + notice: getNotice, + tags: [ + { + key: '0', + label: '很有想法的', + }, + { + key: '1', + label: '专注设计', + }, + { + key: '2', + label: '辣~', + }, + { + key: '3', + label: '大长腿', + }, + { + key: '4', + label: '川妹子', + }, + { + key: '5', + label: '海纳百川', + }, + ], + notifyCount: 12, + unreadCount: 11, + country: 'China', + geographic: { + province: { + label: '浙江省', + key: '330000', + }, + city: { + label: '杭州市', + key: '330100', + }, + }, + address: '西湖区工专路 77 号', + phone: '0752-268888888', + }, +}; diff --git a/AccountCenter/src/index.js b/AccountCenter/src/index.js new file mode 100644 index 0000000000000000000000000000000000000000..a8dc908478b04b4442c5a2ed3a081c31e4d76771 --- /dev/null +++ b/AccountCenter/src/index.js @@ -0,0 +1,191 @@ +import React, { PureComponent } from 'react'; +import { connect } from 'dva'; +import Link from 'umi/link'; +import { Card, Row, Col, Icon, Avatar, Tag, Divider, Input } from 'antd'; +import styles from './Center.less'; + +const operationTabList = [ + { + key: 'articles', + tab: ( + + 文章 (8) + + ), + }, + { + key: 'applications', + tab: ( + + 应用 (8) + + ), + }, + { + key: 'projects', + tab: ( + + 项目 (8) + + ), + }, +]; + +@connect(({ loading, BLOCK_NAME_CAMEL_CASE }) => ({ + currentUser: BLOCK_NAME_CAMEL_CASE.currentUser, + currentUserLoading: loading.effects['BLOCK_NAME_CAMEL_CASE/fetchCurrent'], +})) +class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent { + static getDerivedStateFromProps(props, state) { + const { match, location } = props; + const { tabKey } = state; + const urlTabKey = location.pathname.replace(`${match.path}/`, ''); + if (urlTabKey && urlTabKey !== '/' && tabKey !== urlTabKey) { + return { + tabKey: urlTabKey, + }; + } + return null; + } + + state = { + newTags: [], + inputVisible: false, + inputValue: '', + tabKey: 'articles', + }; + + componentDidMount() { + const { dispatch } = this.props; + dispatch({ + type: 'BLOCK_NAME_CAMEL_CASE/fetchCurrent', + }); + } + + onTabChange = key => { + // If you need to sync state to url + // const { match } = this.props; + // router.push(`${match.url}/${key}`); + this.setState({ + tabKey: key, + }); + }; + + showInput = () => { + this.setState({ inputVisible: true }, () => this.input.focus()); + }; + + saveInputRef = input => { + this.input = input; + }; + + handleInputChange = e => { + this.setState({ inputValue: e.target.value }); + }; + + handleInputConfirm = () => { + const { state } = this; + const { inputValue } = state; + let { newTags } = state; + if (inputValue && newTags.filter(tag => tag.label === inputValue).length === 0) { + newTags = [...newTags, { key: `new-${newTags.length}`, label: inputValue }]; + } + this.setState({ + newTags, + inputVisible: false, + inputValue: '', + }); + }; + + render() { + const { newTags, inputVisible, inputValue, tabKey } = this.state; + const { currentUser, currentUserLoading, children } = this.props; + const dataLoading = currentUserLoading || !(currentUser && Object.keys(currentUser).length); + return ( + + + + {!dataLoading ? ( +
+
+ +
{currentUser.name}
+
{currentUser.signature}
+
+
+

+ + {currentUser.title} +

+

+ + {currentUser.group} +

+

+ + {currentUser.geographic.province.label} + {currentUser.geographic.city.label} +

+
+ +
+
标签
+ {currentUser.tags.concat(newTags).map(item => ( + {item.label} + ))} + {inputVisible && ( + + )} + {!inputVisible && ( + + + + )} +
+ +
+
团队
+ + {currentUser.notice.map(item => ( + + + + {item.member} + + + ))} + +
+
+ ) : null} +
+ + + + {children || tabKey} + + +
+ ); + } +} + +export default PAGE_NAME_UPPER_CAMEL_CASE; diff --git a/src/models/user.js b/AccountCenter/src/model.js similarity index 90% rename from src/models/user.js rename to AccountCenter/src/model.js index c84ebbcfc8ed31efef71df8e8fc7d350894a1722..f927b437690729e549debbb3c3bd24965a4d2db6 100644 --- a/src/models/user.js +++ b/AccountCenter/src/model.js @@ -1,7 +1,7 @@ -import { query as queryUsers, queryCurrent } from '@/services/user'; +import { query as queryUsers, queryCurrent } from './service'; export default { - namespace: 'user', + namespace: 'BLOCK_NAME_CAMEL_CASE', state: { list: [], diff --git a/AccountCenter/src/service.js b/AccountCenter/src/service.js new file mode 100644 index 0000000000000000000000000000000000000000..6fdf83df65bd2e0e359eb6f1bc9d8ee076cff540 --- /dev/null +++ b/AccountCenter/src/service.js @@ -0,0 +1,9 @@ +import request from 'umi-request'; + +export async function query() { + return request('/api/BLOCK_NAME/users'); +} + +export async function queryCurrent() { + return request('/api/BLOCK_NAME/currentUser'); +} diff --git a/AccountSettings/.gitignore b/AccountSettings/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8ce76bc425533aa85835a516e25a0d7218a6e15b --- /dev/null +++ b/AccountSettings/.gitignore @@ -0,0 +1,7 @@ +/yarn.lock +/package-lock.json +/dist +/node_modules + +.umi +.umi-production diff --git a/AccountSettings/.umirc.js b/AccountSettings/.umirc.js new file mode 100644 index 0000000000000000000000000000000000000000..70ab1e9b79813e2a091d036d763edc262cdf23bf --- /dev/null +++ b/AccountSettings/.umirc.js @@ -0,0 +1,18 @@ +export default { + plugins: [ + [ + 'umi-plugin-block-dev', + { + layout: 'ant-design-pro', + }, + ], + [ + 'umi-plugin-react', + { + dva: true, + locale: true, + antd: true, + }, + ], + ], +}; diff --git a/AccountSettings/README.md b/AccountSettings/README.md new file mode 100644 index 0000000000000000000000000000000000000000..ff93fb84f9dd39bfc6030305f82e62296c339502 --- /dev/null +++ b/AccountSettings/README.md @@ -0,0 +1,17 @@ +# @umi-blocks/ant-design-pro/accountsettings + +AccountSettings + +## Usage + +```sh +umi block add ant-design-pro/AccountSettings +``` + +## SNAPSHOT + +![SNAPSHOT](./snapshot.png) + +## LICENSE + +MIT diff --git a/AccountSettings/jsconfig.json b/AccountSettings/jsconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..f87334d482029d82509ddb6c0dab5ab62236cd15 --- /dev/null +++ b/AccountSettings/jsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + } + } +} diff --git a/AccountSettings/package.json b/AccountSettings/package.json new file mode 100644 index 0000000000000000000000000000000000000000..8901d45c231094e654de3bd20d13725f03a245ea --- /dev/null +++ b/AccountSettings/package.json @@ -0,0 +1,25 @@ +{ + "name": "@umi-block/account-settings", + "version": "0.0.1", + "description": "AccountSettings", + "main": "src/index.js", + "scripts": { + "dev": "umi dev" + }, + "repository": { + "type": "git", + "url": "https://github.com/umijs/umi-blocks/ant-design-pro/accountsettings" + }, + "dependencies": { + "antd": "^3.10.9", + "dva": "^2.4.0", + "react": "^16.6.3", + "umi-request": "^1.0.0" + }, + "devDependencies": { + "umi": "^2.3.0-beta.1", + "umi-plugin-block-dev": "^1.0.0", + "umi-plugin-react": "^1.3.0-beta.1" + }, + "license": "ISC" +} diff --git a/AccountSettings/snapshot.png b/AccountSettings/snapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..a4f5f1c375689badbf56331fb7e11dc39f4513ae Binary files /dev/null and b/AccountSettings/snapshot.png differ diff --git a/AccountSettings/src/_mock.js b/AccountSettings/src/_mock.js new file mode 100644 index 0000000000000000000000000000000000000000..6533a3386ea3930d739fe63e381562ef4397ae4c --- /dev/null +++ b/AccountSettings/src/_mock.js @@ -0,0 +1,66 @@ +import city from './geographic/city.json'; +import province from './geographic/province.json'; + +function getProvince(req, res) { + return res.json(province); +} + +function getCity(req, res) { + return res.json(city[req.params.province]); +} +// 代码中会兼容本地 service mock 以及部署站点的静态数据 +export default { + // 支持值为 Object 和 Array + 'GET /api/BLOCK_NAME/currentUser': { + name: 'Serati Ma', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png', + userid: '00000001', + email: 'antdesign@alipay.com', + signature: '海纳百川,有容乃大', + title: '交互专家', + group: '蚂蚁金服-某某某事业群-某某平台部-某某技术部-UED', + tags: [ + { + key: '0', + label: '很有想法的', + }, + { + key: '1', + label: '专注设计', + }, + { + key: '2', + label: '辣~', + }, + { + key: '3', + label: '大长腿', + }, + { + key: '4', + label: '川妹子', + }, + { + key: '5', + label: '海纳百川', + }, + ], + notifyCount: 12, + unreadCount: 11, + country: 'China', + geographic: { + province: { + label: '浙江省', + key: '330000', + }, + city: { + label: '杭州市', + key: '330100', + }, + }, + address: '西湖区工专路 77 号', + phone: '0752-268888888', + }, + 'GET /api/BLOCK_NAME/province': getProvince, + 'GET /api/BLOCK_NAME/city/:province': getCity, +}; diff --git a/src/pages/Account/Settings/BaseView.less b/AccountSettings/src/components/BaseView.less similarity index 100% rename from src/pages/Account/Settings/BaseView.less rename to AccountSettings/src/components/BaseView.less diff --git a/src/pages/Account/Settings/GeographicView.js b/AccountSettings/src/components/GeographicView.js similarity index 85% rename from src/pages/Account/Settings/GeographicView.js rename to AccountSettings/src/components/GeographicView.js index d33cb13871d39ef38ad986013339200c072b2d64..c5274b7c894d9edb52298219c35126a26357561c 100644 --- a/src/pages/Account/Settings/GeographicView.js +++ b/AccountSettings/src/components/GeographicView.js @@ -10,19 +10,19 @@ const nullSlectItem = { key: '', }; -@connect(({ geographic }) => { - const { province, isLoading, city } = geographic; +@connect(({ BLOCK_NAME_CAMEL_CASE, loading }) => { + const { province, city } = BLOCK_NAME_CAMEL_CASE; return { province, city, - isLoading, + loading: loading.models.BLOCK_NAME_CAMEL_CASE, }; }) class GeographicView extends PureComponent { componentDidMount = () => { const { dispatch } = this.props; dispatch({ - type: 'geographic/fetchProvince', + type: 'BLOCK_NAME_CAMEL_CASE/fetchProvince', }); }; @@ -31,7 +31,7 @@ class GeographicView extends PureComponent { if (!props.value && !!value && !!value.province) { dispatch({ - type: 'geographic/fetchCity', + type: 'BLOCK_NAME_CAMEL_CASE/fetchCity', payload: value.province.key, }); } @@ -65,7 +65,7 @@ class GeographicView extends PureComponent { selectProvinceItem = item => { const { dispatch, onChange } = this.props; dispatch({ - type: 'geographic/fetchCity', + type: 'BLOCK_NAME_CAMEL_CASE/fetchCity', payload: item.key, }); onChange({ @@ -99,9 +99,9 @@ class GeographicView extends PureComponent { render() { const { province, city } = this.conversionObject(); - const { isLoading } = this.props; + const { loading } = this.props; return ( - + )} - + {getFieldDecorator('name', { rules: [ { required: true, - message: formatMessage({ id: 'app.settings.basic.nickname-message' }, {}), + message: formatMessage({ id: 'BLOCK_NAME.basic.nickname-message' }, {}), }, ], })()} - + {getFieldDecorator('profile', { rules: [ { required: true, - message: formatMessage({ id: 'app.settings.basic.profile-message' }, {}), + message: formatMessage({ id: 'BLOCK_NAME.basic.profile-message' }, {}), }, ], })( )} - + {getFieldDecorator('country', { rules: [ { required: true, - message: formatMessage({ id: 'app.settings.basic.country-message' }, {}), + message: formatMessage({ id: 'BLOCK_NAME.basic.country-message' }, {}), }, ], })( @@ -139,12 +138,12 @@ class BaseView extends Component { )} - + {getFieldDecorator('geographic', { rules: [ { required: true, - message: formatMessage({ id: 'app.settings.basic.geographic-message' }, {}), + message: formatMessage({ id: 'BLOCK_NAME.basic.geographic-message' }, {}), }, { validator: validatorGeographic, @@ -152,22 +151,22 @@ class BaseView extends Component { ], })()} - + {getFieldDecorator('address', { rules: [ { required: true, - message: formatMessage({ id: 'app.settings.basic.address-message' }, {}), + message: formatMessage({ id: 'BLOCK_NAME.basic.address-message' }, {}), }, ], })()} - + {getFieldDecorator('phone', { rules: [ { required: true, - message: formatMessage({ id: 'app.settings.basic.phone-message' }, {}), + message: formatMessage({ id: 'BLOCK_NAME.basic.phone-message' }, {}), }, { validator: validatorPhone }, ], @@ -175,7 +174,7 @@ class BaseView extends Component { diff --git a/src/pages/Account/Settings/BindingView.js b/AccountSettings/src/components/binding.js similarity index 59% rename from src/pages/Account/Settings/BindingView.js rename to AccountSettings/src/components/binding.js index 29a29890ca0d5ab339f872f1fe614ff9b0122ea4..c95eca62ab0a200b78bcf0cb3a043dfc808ebde5 100644 --- a/src/pages/Account/Settings/BindingView.js +++ b/AccountSettings/src/components/binding.js @@ -5,31 +5,31 @@ import { Icon, List } from 'antd'; class BindingView extends Component { getData = () => [ { - title: formatMessage({ id: 'app.settings.binding.taobao' }, {}), - description: formatMessage({ id: 'app.settings.binding.taobao-description' }, {}), + title: formatMessage({ id: 'BLOCK_NAME.binding.taobao' }, {}), + description: formatMessage({ id: 'BLOCK_NAME.binding.taobao-description' }, {}), actions: [ - + , ], avatar: , }, { - title: formatMessage({ id: 'app.settings.binding.alipay' }, {}), - description: formatMessage({ id: 'app.settings.binding.alipay-description' }, {}), + title: formatMessage({ id: 'BLOCK_NAME.binding.alipay' }, {}), + description: formatMessage({ id: 'BLOCK_NAME.binding.alipay-description' }, {}), actions: [ - + , ], avatar: , }, { - title: formatMessage({ id: 'app.settings.binding.dingding' }, {}), - description: formatMessage({ id: 'app.settings.binding.dingding-description' }, {}), + title: formatMessage({ id: 'BLOCK_NAME.binding.dingding' }, {}), + description: formatMessage({ id: 'BLOCK_NAME.binding.dingding-description' }, {}), actions: [ - + , ], avatar: , diff --git a/src/pages/Account/Settings/NotificationView.js b/AccountSettings/src/components/notification.js similarity index 55% rename from src/pages/Account/Settings/NotificationView.js rename to AccountSettings/src/components/notification.js index 96677bbd269501cb9e901ea0f30b58ed2e51d774..b61eac3e68bd65000fe3043c8c2c70bb79da2227 100644 --- a/src/pages/Account/Settings/NotificationView.js +++ b/AccountSettings/src/components/notification.js @@ -6,25 +6,25 @@ class NotificationView extends Component { getData = () => { const Action = ( ); return [ { - title: formatMessage({ id: 'app.settings.notification.password' }, {}), - description: formatMessage({ id: 'app.settings.notification.password-description' }, {}), + title: formatMessage({ id: 'BLOCK_NAME.notification.password' }, {}), + description: formatMessage({ id: 'BLOCK_NAME.notification.password-description' }, {}), actions: [Action], }, { - title: formatMessage({ id: 'app.settings.notification.messages' }, {}), - description: formatMessage({ id: 'app.settings.notification.messages-description' }, {}), + title: formatMessage({ id: 'BLOCK_NAME.notification.messages' }, {}), + description: formatMessage({ id: 'BLOCK_NAME.notification.messages-description' }, {}), actions: [Action], }, { - title: formatMessage({ id: 'app.settings.notification.todo' }, {}), - description: formatMessage({ id: 'app.settings.notification.todo-description' }, {}), + title: formatMessage({ id: 'BLOCK_NAME.notification.todo' }, {}), + description: formatMessage({ id: 'BLOCK_NAME.notification.todo-description' }, {}), actions: [Action], }, ]; diff --git a/src/pages/Account/Settings/SecurityView.js b/AccountSettings/src/components/security.js similarity index 50% rename from src/pages/Account/Settings/SecurityView.js rename to AccountSettings/src/components/security.js index 0706bd0b9b2988bb41bcc2a3fe9ab20f65f6bf16..96685c0fb911c20d2e73a644fd7aa3f82d1ebe3d 100644 --- a/src/pages/Account/Settings/SecurityView.js +++ b/AccountSettings/src/components/security.js @@ -6,17 +6,17 @@ import { List } from 'antd'; const passwordStrength = { strong: ( - + ), medium: ( - + ), weak: ( - + Weak ), @@ -25,58 +25,58 @@ const passwordStrength = { class SecurityView extends Component { getData = () => [ { - title: formatMessage({ id: 'app.settings.security.password' }, {}), + title: formatMessage({ id: 'BLOCK_NAME.security.password' }, {}), description: ( - {formatMessage({ id: 'app.settings.security.password-description' })}: + {formatMessage({ id: 'BLOCK_NAME.security.password-description' })}: {passwordStrength.strong} ), actions: [ - + , ], }, { - title: formatMessage({ id: 'app.settings.security.phone' }, {}), + title: formatMessage({ id: 'BLOCK_NAME.security.phone' }, {}), description: `${formatMessage( - { id: 'app.settings.security.phone-description' }, + { id: 'BLOCK_NAME.security.phone-description' }, {} )}:138****8293`, actions: [ - + , ], }, { - title: formatMessage({ id: 'app.settings.security.question' }, {}), - description: formatMessage({ id: 'app.settings.security.question-description' }, {}), + title: formatMessage({ id: 'BLOCK_NAME.security.question' }, {}), + description: formatMessage({ id: 'BLOCK_NAME.security.question-description' }, {}), actions: [ - + , ], }, { - title: formatMessage({ id: 'app.settings.security.email' }, {}), + title: formatMessage({ id: 'BLOCK_NAME.security.email' }, {}), description: `${formatMessage( - { id: 'app.settings.security.email-description' }, + { id: 'BLOCK_NAME.security.email-description' }, {} )}:ant***sign.com`, actions: [ - + , ], }, { - title: formatMessage({ id: 'app.settings.security.mfa' }, {}), - description: formatMessage({ id: 'app.settings.security.mfa-description' }, {}), + title: formatMessage({ id: 'BLOCK_NAME.security.mfa' }, {}), + description: formatMessage({ id: 'BLOCK_NAME.security.mfa-description' }, {}), actions: [ - + , ], }, diff --git a/mock/geographic/city.json b/AccountSettings/src/geographic/city.json similarity index 100% rename from mock/geographic/city.json rename to AccountSettings/src/geographic/city.json diff --git a/mock/geographic/province.json b/AccountSettings/src/geographic/province.json similarity index 100% rename from mock/geographic/province.json rename to AccountSettings/src/geographic/province.json diff --git a/AccountSettings/src/index.js b/AccountSettings/src/index.js new file mode 100644 index 0000000000000000000000000000000000000000..32985cfec461b82e1e85c134a9a03ece7d4e75b3 --- /dev/null +++ b/AccountSettings/src/index.js @@ -0,0 +1,137 @@ +import React, { Component } from 'react'; +import { connect } from 'dva'; +import { FormattedMessage } from 'umi/locale'; +import { Menu } from 'antd'; +import styles from './style.less'; +import BaseView from './components/base'; +import SecurityView from './components/security'; +import BindingView from './components/binding'; +import NotificationView from './components/notification'; + +const { Item } = Menu; + +@connect(({ BLOCK_NAME_CAMEL_CASE }) => ({ + currentUser: BLOCK_NAME_CAMEL_CASE.currentUser, +})) +class PAGE_NAME_UPPER_CAMEL_CASE extends Component { + constructor(props) { + super(props); + const menuMap = { + base: , + security: ( + + ), + binding: ( + + ), + notification: ( + + ), + }; + this.state = { + mode: 'inline', + menuMap, + selectKey: 'base', + }; + } + + componentDidMount() { + const { dispatch } = this.props; + dispatch({ + type: 'BLOCK_NAME_CAMEL_CASE/fetchCurrent', + }); + window.addEventListener('resize', this.resize); + this.resize(); + } + + componentWillUnmount() { + window.removeEventListener('resize', this.resize); + } + + getmenu = () => { + const { menuMap } = this.state; + return Object.keys(menuMap).map(item => {menuMap[item]}); + }; + + getRightTitle = () => { + const { selectKey, menuMap } = this.state; + return menuMap[selectKey]; + }; + + selectKey = ({ key }) => { + this.setState({ + selectKey: key, + }); + }; + + resize = () => { + if (!this.main) { + return; + } + requestAnimationFrame(() => { + if (!this.main) { + return; + } + let mode = 'inline'; + const { offsetWidth } = this.main; + if (this.main.offsetWidth < 641 && offsetWidth > 400) { + mode = 'horizontal'; + } + if (window.innerWidth < 768 && offsetWidth > 400) { + mode = 'horizontal'; + } + this.setState({ + mode, + }); + }); + }; + + renderChildren = () => { + const { selectKey } = this.state; + switch (selectKey) { + case 'base': + return ; + case 'security': + return ; + case 'binding': + return ; + case 'notification': + return ; + default: + break; + } + + return null; + }; + + render() { + const { currentUser } = this.props; + if (!currentUser.userid) { + return ''; + } + const { mode, selectKey } = this.state; + return ( +
{ + this.main = ref; + }} + > +
+ + {this.getmenu()} + +
+
+
{this.getRightTitle()}
+ {this.renderChildren()} +
+
+ ); + } +} + +export default PAGE_NAME_UPPER_CAMEL_CASE; diff --git a/AccountSettings/src/locales/en-US.js b/AccountSettings/src/locales/en-US.js new file mode 100644 index 0000000000000000000000000000000000000000..aab0f68db624474e8f1e43686648c6391af1fd9d --- /dev/null +++ b/AccountSettings/src/locales/en-US.js @@ -0,0 +1,60 @@ +export default { + 'BLOCK_NAME.menuMap.basic': 'Basic Settings', + 'BLOCK_NAME.menuMap.security': 'Security Settings', + 'BLOCK_NAME.menuMap.binding': 'Account Binding', + 'BLOCK_NAME.menuMap.notification': 'New Message Notification', + 'BLOCK_NAME.basic.avatar': 'Avatar', + 'BLOCK_NAME.basic.change-avatar': 'Change avatar', + 'BLOCK_NAME.basic.email': 'Email', + 'BLOCK_NAME.basic.email-message': 'Please input your email!', + 'BLOCK_NAME.basic.nickname': 'Nickname', + 'BLOCK_NAME.basic.nickname-message': 'Please input your Nickname!', + 'BLOCK_NAME.basic.profile': 'Personal profile', + 'BLOCK_NAME.basic.profile-message': 'Please input your personal profile!', + 'BLOCK_NAME.basic.profile-placeholder': 'Brief introduction to yourself', + 'BLOCK_NAME.basic.country': 'Country/Region', + 'BLOCK_NAME.basic.country-message': 'Please input your country!', + 'BLOCK_NAME.basic.geographic': 'Province or city', + 'BLOCK_NAME.basic.geographic-message': 'Please input your geographic info!', + 'BLOCK_NAME.basic.address': 'Street Address', + 'BLOCK_NAME.basic.address-message': 'Please input your address!', + 'BLOCK_NAME.basic.phone': 'Phone Number', + 'BLOCK_NAME.basic.phone-message': 'Please input your phone!', + 'BLOCK_NAME.basic.update': 'Update Information', + 'BLOCK_NAME.security.strong': 'Strong', + 'BLOCK_NAME.security.medium': 'Medium', + 'BLOCK_NAME.security.weak': 'Weak', + 'BLOCK_NAME.security.password': 'Account Password', + 'BLOCK_NAME.security.password-description': 'Current password strength:', + 'BLOCK_NAME.security.phone': 'Security Phone', + 'BLOCK_NAME.security.phone-description': 'Bound phone:', + 'BLOCK_NAME.security.question': 'Security Question', + 'BLOCK_NAME.security.question-description': + 'The security question is not set, and the security policy can effectively protect the account security', + 'BLOCK_NAME.security.email': 'Backup Email', + 'BLOCK_NAME.security.email-description': 'Bound Email:', + 'BLOCK_NAME.security.mfa': 'MFA Device', + 'BLOCK_NAME.security.mfa-description': + 'Unbound MFA device, after binding, can be confirmed twice', + 'BLOCK_NAME.security.modify': 'Modify', + 'BLOCK_NAME.security.set': 'Set', + 'BLOCK_NAME.security.bind': 'Bind', + 'BLOCK_NAME.binding.taobao': 'Binding Taobao', + 'BLOCK_NAME.binding.taobao-description': 'Currently unbound Taobao account', + 'BLOCK_NAME.binding.alipay': 'Binding Alipay', + 'BLOCK_NAME.binding.alipay-description': 'Currently unbound Alipay account', + 'BLOCK_NAME.binding.dingding': 'Binding DingTalk', + 'BLOCK_NAME.binding.dingding-description': 'Currently unbound DingTalk account', + 'BLOCK_NAME.binding.bind': 'Bind', + 'BLOCK_NAME.notification.password': 'Account Password', + 'BLOCK_NAME.notification.password-description': + 'Messages from other users will be notified in the form of a station letter', + 'BLOCK_NAME.notification.messages': 'System Messages', + 'BLOCK_NAME.notification.messages-description': + 'System messages will be notified in the form of a station letter', + 'BLOCK_NAME.notification.todo': 'To-do Notification', + 'BLOCK_NAME.notification.todo-description': + 'The to-do list will be notified in the form of a letter from the station', + 'BLOCK_NAME.settings.open': 'Open', + 'BLOCK_NAME.settings.close': 'Close', +}; diff --git a/AccountSettings/src/locales/zh-CN.js b/AccountSettings/src/locales/zh-CN.js new file mode 100644 index 0000000000000000000000000000000000000000..29c5674b831184c5967a1c2982f9a8773c71678c --- /dev/null +++ b/AccountSettings/src/locales/zh-CN.js @@ -0,0 +1,55 @@ +export default { + 'BLOCK_NAME.menuMap.basic': '基本设置', + 'BLOCK_NAME.menuMap.security': '安全设置', + 'BLOCK_NAME.menuMap.binding': '账号绑定', + 'BLOCK_NAME.menuMap.notification': '新消息通知', + 'BLOCK_NAME.basic.avatar': '头像', + 'BLOCK_NAME.basic.change-avatar': '更换头像', + 'BLOCK_NAME.basic.email': '邮箱', + 'BLOCK_NAME.basic.email-message': '请输入您的邮箱!', + 'BLOCK_NAME.basic.nickname': '昵称', + 'BLOCK_NAME.basic.nickname-message': '请输入您的昵称!', + 'BLOCK_NAME.basic.profile': '个人简介', + 'BLOCK_NAME.basic.profile-message': '请输入个人简介!', + 'BLOCK_NAME.basic.profile-placeholder': '个人简介', + 'BLOCK_NAME.basic.country': '国家/地区', + 'BLOCK_NAME.basic.country-message': '请输入您的国家或地区!', + 'BLOCK_NAME.basic.geographic': '所在省市', + 'BLOCK_NAME.basic.geographic-message': '请输入您的所在省市!', + 'BLOCK_NAME.basic.address': '街道地址', + 'BLOCK_NAME.basic.address-message': '请输入您的街道地址!', + 'BLOCK_NAME.basic.phone': '联系电话', + 'BLOCK_NAME.basic.phone-message': '请输入您的联系电话!', + 'BLOCK_NAME.basic.update': '更新基本信息', + 'BLOCK_NAME.security.strong': '强', + 'BLOCK_NAME.security.medium': '中', + 'BLOCK_NAME.security.weak': '弱', + 'BLOCK_NAME.security.password': '账户密码', + 'BLOCK_NAME.security.password-description': '当前密码强度:', + 'BLOCK_NAME.security.phone': '密保手机', + 'BLOCK_NAME.security.phone-description': '已绑定手机:', + 'BLOCK_NAME.security.question': '密保问题', + 'BLOCK_NAME.security.question-description': '未设置密保问题,密保问题可有效保护账户安全', + 'BLOCK_NAME.security.email': '备用邮箱', + 'BLOCK_NAME.security.email-description': '已绑定邮箱:', + 'BLOCK_NAME.security.mfa': 'MFA 设备', + 'BLOCK_NAME.security.mfa-description': '未绑定 MFA 设备,绑定后,可以进行二次确认', + 'BLOCK_NAME.security.modify': '修改', + 'BLOCK_NAME.security.set': '设置', + 'BLOCK_NAME.security.bind': '绑定', + 'BLOCK_NAME.binding.taobao': '绑定淘宝', + 'BLOCK_NAME.binding.taobao-description': '当前未绑定淘宝账号', + 'BLOCK_NAME.binding.alipay': '绑定支付宝', + 'BLOCK_NAME.binding.alipay-description': '当前未绑定支付宝账号', + 'BLOCK_NAME.binding.dingding': '绑定钉钉', + 'BLOCK_NAME.binding.dingding-description': '当前未绑定钉钉账号', + 'BLOCK_NAME.binding.bind': '绑定', + 'BLOCK_NAME.notification.password': '账户密码', + 'BLOCK_NAME.notification.password-description': '其他用户的消息将以站内信的形式通知', + 'BLOCK_NAME.notification.messages': '系统消息', + 'BLOCK_NAME.notification.messages-description': '系统消息将以站内信的形式通知', + 'BLOCK_NAME.notification.todo': '待办任务', + 'BLOCK_NAME.notification.todo-description': '待办任务将以站内信的形式通知', + 'BLOCK_NAME.settings.open': '开', + 'BLOCK_NAME.settings.close': '关', +}; diff --git a/AccountSettings/src/locales/zh-TW.js b/AccountSettings/src/locales/zh-TW.js new file mode 100644 index 0000000000000000000000000000000000000000..a65cf7e96dad48d3cce631bd4e199eab9ec13d2e --- /dev/null +++ b/AccountSettings/src/locales/zh-TW.js @@ -0,0 +1,55 @@ +export default { + 'BLOCK_NAME.menuMap.basic': '基本設置', + 'BLOCK_NAME.menuMap.security': '安全設置', + 'BLOCK_NAME.menuMap.binding': '賬號綁定', + 'BLOCK_NAME.menuMap.notification': '新消息通知', + 'BLOCK_NAME.basic.avatar': '頭像', + 'BLOCK_NAME.basic.change-avatar': '更換頭像', + 'BLOCK_NAME.basic.email': '郵箱', + 'BLOCK_NAME.basic.email-message': '請輸入您的郵箱!', + 'BLOCK_NAME.basic.nickname': '昵稱', + 'BLOCK_NAME.basic.nickname-message': '請輸入您的昵稱!', + 'BLOCK_NAME.basic.profile': '個人簡介', + 'BLOCK_NAME.basic.profile-message': '請輸入個人簡介!', + 'BLOCK_NAME.basic.profile-placeholder': '個人簡介', + 'BLOCK_NAME.basic.country': '國家/地區', + 'BLOCK_NAME.basic.country-message': '請輸入您的國家或地區!', + 'BLOCK_NAME.basic.geographic': '所在省市', + 'BLOCK_NAME.basic.geographic-message': '請輸入您的所在省市!', + 'BLOCK_NAME.basic.address': '街道地址', + 'BLOCK_NAME.basic.address-message': '請輸入您的街道地址!', + 'BLOCK_NAME.basic.phone': '聯系電話', + 'BLOCK_NAME.basic.phone-message': '請輸入您的聯系電話!', + 'BLOCK_NAME.basic.update': '更新基本信息', + 'BLOCK_NAME.security.strong': '強', + 'BLOCK_NAME.security.medium': '中', + 'BLOCK_NAME.security.weak': '弱', + 'BLOCK_NAME.security.password': '賬戶密碼', + 'BLOCK_NAME.security.password-description': '當前密碼強度:', + 'BLOCK_NAME.security.phone': '密保手機', + 'BLOCK_NAME.security.phone-description': '已綁定手機:', + 'BLOCK_NAME.security.question': '密保問題', + 'BLOCK_NAME.security.question-description': '未設置密保問題,密保問題可有效保護賬戶安全', + 'BLOCK_NAME.security.email': '備用郵箱', + 'BLOCK_NAME.security.email-description': '已綁定郵箱:', + 'BLOCK_NAME.security.mfa': 'MFA 設備', + 'BLOCK_NAME.security.mfa-description': '未綁定 MFA 設備,綁定後,可以進行二次確認', + 'BLOCK_NAME.security.modify': '修改', + 'BLOCK_NAME.security.set': '設置', + 'BLOCK_NAME.security.bind': '綁定', + 'BLOCK_NAME.binding.taobao': '綁定淘寶', + 'BLOCK_NAME.binding.taobao-description': '當前未綁定淘寶賬號', + 'BLOCK_NAME.binding.alipay': '綁定支付寶', + 'BLOCK_NAME.binding.alipay-description': '當前未綁定支付寶賬號', + 'BLOCK_NAME.binding.dingding': '綁定釘釘', + 'BLOCK_NAME.binding.dingding-description': '當前未綁定釘釘賬號', + 'BLOCK_NAME.binding.bind': '綁定', + 'BLOCK_NAME.notification.password': '賬戶密碼', + 'BLOCK_NAME.notification.password-description': '其他用戶的消息將以站內信的形式通知', + 'BLOCK_NAME.notification.messages': '系統消息', + 'BLOCK_NAME.notification.messages-description': '系統消息將以站內信的形式通知', + 'BLOCK_NAME.notification.todo': '待辦任務', + 'BLOCK_NAME.notification.todo-description': '待辦任務將以站內信的形式通知', + 'BLOCK_NAME.settings.open': '開', + 'BLOCK_NAME.settings.close': '關', +}; diff --git a/src/pages/Account/Settings/models/geographic.js b/AccountSettings/src/model.js similarity index 50% rename from src/pages/Account/Settings/models/geographic.js rename to AccountSettings/src/model.js index a501920c7159e773285f23311e52366c563235f8..99fc23a30a72cb3660cace5a027eca3548640012 100644 --- a/src/pages/Account/Settings/models/geographic.js +++ b/AccountSettings/src/model.js @@ -1,15 +1,30 @@ -import { queryProvince, queryCity } from '@/services/geographic'; +import { query as queryUsers, queryCurrent, queryProvince, queryCity } from './service'; export default { - namespace: 'geographic', + namespace: 'BLOCK_NAME_CAMEL_CASE', state: { + list: [], + currentUser: {}, province: [], city: [], - isLoading: false, }, effects: { + *fetch(_, { call, put }) { + const response = yield call(queryUsers); + yield put({ + type: 'save', + payload: response, + }); + }, + *fetchCurrent(_, { call, put }) { + const response = yield call(queryCurrent); + yield put({ + type: 'saveCurrentUser', + payload: response, + }); + }, *fetchProvince(_, { call, put }) { yield put({ type: 'changeLoading', @@ -20,29 +35,39 @@ export default { type: 'setProvince', payload: response, }); - yield put({ - type: 'changeLoading', - payload: false, - }); }, *fetchCity({ payload }, { call, put }) { - yield put({ - type: 'changeLoading', - payload: true, - }); const response = yield call(queryCity, payload); yield put({ type: 'setCity', payload: response, }); - yield put({ - type: 'changeLoading', - payload: false, - }); }, }, reducers: { + save(state, action) { + return { + ...state, + list: action.payload, + }; + }, + saveCurrentUser(state, action) { + return { + ...state, + currentUser: action.payload || {}, + }; + }, + changeNotifyCount(state, action) { + return { + ...state, + currentUser: { + ...state.currentUser, + notifyCount: action.payload.totalCount, + unreadCount: action.payload.unreadCount, + }, + }; + }, setProvince(state, action) { return { ...state, diff --git a/AccountSettings/src/service.js b/AccountSettings/src/service.js new file mode 100644 index 0000000000000000000000000000000000000000..104bb1e95faf1c80935bdcf42af0807c2e3304e0 --- /dev/null +++ b/AccountSettings/src/service.js @@ -0,0 +1,17 @@ +import request from 'umi-request'; + +export async function queryCurrent() { + return request('/api/BLOCK_NAME/currentUser'); +} + +export async function queryProvince() { + return request('/api/BLOCK_NAME/province'); +} + +export async function queryCity(province) { + return request(`/api/BLOCK_NAME/city/${province}`); +} + +export async function query() { + return request('/api/BLOCK_NAME/users'); +} diff --git a/src/pages/Account/Settings/Info.less b/AccountSettings/src/style.less similarity index 100% rename from src/pages/Account/Settings/Info.less rename to AccountSettings/src/style.less diff --git a/AdvancedForm/.gitignore b/AdvancedForm/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8ce76bc425533aa85835a516e25a0d7218a6e15b --- /dev/null +++ b/AdvancedForm/.gitignore @@ -0,0 +1,7 @@ +/yarn.lock +/package-lock.json +/dist +/node_modules + +.umi +.umi-production diff --git a/AdvancedForm/.umirc.js b/AdvancedForm/.umirc.js new file mode 100644 index 0000000000000000000000000000000000000000..545b4c7a99507a4973cd944fc2eafbd612ead8ef --- /dev/null +++ b/AdvancedForm/.umirc.js @@ -0,0 +1,12 @@ +export default { + plugins: [ + ['umi-plugin-block-dev', { + layout: 'ant-design-pro', + }], + ['umi-plugin-react', { + dva: true, + locale: true, + antd: true, + }] + ], +} diff --git a/AdvancedForm/README.md b/AdvancedForm/README.md new file mode 100644 index 0000000000000000000000000000000000000000..cc9bfcbe5ab7d1712f074c3a8c5d750c3278a589 --- /dev/null +++ b/AdvancedForm/README.md @@ -0,0 +1,17 @@ +# @umi-blocks/ant-design-pro/advancedform + +AdvancedForm + +## Usage + +```sh +umi block add ant-design-pro/advancedform +``` + +## SNAPSHOT + +![SNAPSHOT](./snapshot.png) + +## LICENSE + +MIT diff --git a/AdvancedForm/package.json b/AdvancedForm/package.json new file mode 100644 index 0000000000000000000000000000000000000000..a26dc013f98971eeab36d1c4ac42957c4385ea0b --- /dev/null +++ b/AdvancedForm/package.json @@ -0,0 +1,27 @@ +{ + "name": "@umi-block/advanced-form", + "version": "0.0.1", + "description": "AdvancedForm", + "main": "src/index.js", + "scripts": { + "dev": "umi dev" + }, + "repository": { + "type": "git", + "url": "https://github.com/umijs/umi-blocks/ant-design-pro/advancedform" + }, + "dependencies": { + "ant-design-pro": "^2.1.1", + "antd": "^3.10.9", + "dva": "^2.4.0", + "lodash": "^4.17.10", + "react": "^16.6.3", + "umi-request": "^1.0.0" + }, + "devDependencies": { + "umi": "^2.3.0-beta.1", + "umi-plugin-react": "^1.3.0-beta.1", + "umi-plugin-block-dev": "^1.0.0" + }, + "license": "ISC" +} diff --git a/AdvancedForm/snapshot.png b/AdvancedForm/snapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..c6c31d206674a32f789305620dd9334a2dbdd935 Binary files /dev/null and b/AdvancedForm/snapshot.png differ diff --git a/AdvancedForm/src/_mock.js b/AdvancedForm/src/_mock.js new file mode 100644 index 0000000000000000000000000000000000000000..8e7996deae35737ca576735528af9f6eaa281b98 --- /dev/null +++ b/AdvancedForm/src/_mock.js @@ -0,0 +1,5 @@ +export default { + 'POST /api/BLOCK_NAME/forms': (req, res) => { + res.send({ message: 'Ok' }); + }, +}; diff --git a/AdvancedForm/src/components/PageHeaderWrapper/index.js b/AdvancedForm/src/components/PageHeaderWrapper/index.js new file mode 100644 index 0000000000000000000000000000000000000000..c11873f2c8c24d44391261910d5adb52ab916d1a --- /dev/null +++ b/AdvancedForm/src/components/PageHeaderWrapper/index.js @@ -0,0 +1,25 @@ +import React from 'react'; +import { FormattedMessage } from 'umi/locale'; +import Link from 'umi/link'; +import { PageHeader } from 'ant-design-pro'; +import styles from './index.less'; + +const PageHeaderWrapper = ({ children, wrapperClassName, ...restProps }) => ( +
+ } + key="pageheader" + {...restProps} + linkElement={Link} + itemRender={item => { + if (item.locale) { + return ; + } + return item.title; + }} + /> + {children ?
{children}
: null} +
+); + +export default PageHeaderWrapper; diff --git a/src/components/PageHeaderWrapper/index.less b/AdvancedForm/src/components/PageHeaderWrapper/index.less similarity index 100% rename from src/components/PageHeaderWrapper/index.less rename to AdvancedForm/src/components/PageHeaderWrapper/index.less diff --git a/src/pages/Forms/TableForm.js b/AdvancedForm/src/components/TableForm.js similarity index 98% rename from src/pages/Forms/TableForm.js rename to AdvancedForm/src/components/TableForm.js index ae2723e7ba4eea80351d5a3d772fba89404e2c5c..66f941dcfaa7dd029d3cb2b5597c0771214af5c0 100644 --- a/src/pages/Forms/TableForm.js +++ b/AdvancedForm/src/components/TableForm.js @@ -1,7 +1,7 @@ import React, { PureComponent, Fragment } from 'react'; import { Table, Button, Input, message, Popconfirm, Divider } from 'antd'; -import isEqual from 'lodash/isEqual'; -import styles from './style.less'; +import { isEqual } from 'lodash'; +import styles from '../style.less'; class TableForm extends PureComponent { index = 0; diff --git a/src/pages/Forms/AdvancedForm.js b/AdvancedForm/src/index.js similarity index 96% rename from src/pages/Forms/AdvancedForm.js rename to AdvancedForm/src/index.js index fbd39689351b897e42538e7590a21aa6c112c8c7..e2045c2699f32ca3d69ffb032587aec34595dfcf 100644 --- a/src/pages/Forms/AdvancedForm.js +++ b/AdvancedForm/src/index.js @@ -13,9 +13,9 @@ import { Popover, } from 'antd'; import { connect } from 'dva'; -import FooterToolbar from '@/components/FooterToolbar'; -import PageHeaderWrapper from '@/components/PageHeaderWrapper'; -import TableForm from './TableForm'; +import { FooterToolbar } from 'ant-design-pro'; +import PageHeaderWrapper from './components/PageHeaderWrapper'; +import TableForm from './components/TableForm'; import styles from './style.less'; const { Option } = Select; @@ -58,10 +58,10 @@ const tableData = [ ]; @connect(({ loading }) => ({ - submitting: loading.effects['form/submitAdvancedForm'], + submitting: loading.effects['BLOCK_NAME_CAMEL_CASE/submitAdvancedForm'], })) @Form.create() -class AdvancedForm extends PureComponent { +class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent { state = { width: '100%', }; @@ -139,7 +139,7 @@ class AdvancedForm extends PureComponent { if (!error) { // submit the values dispatch({ - type: 'form/submitAdvancedForm', + type: 'BLOCK_NAME_CAMEL_CASE/submitAdvancedForm', payload: values, }); } @@ -320,4 +320,4 @@ class AdvancedForm extends PureComponent { } } -export default AdvancedForm; +export default PAGE_NAME_UPPER_CAMEL_CASE; diff --git a/AdvancedForm/src/locales/en-US.js b/AdvancedForm/src/locales/en-US.js new file mode 100644 index 0000000000000000000000000000000000000000..3356dda0f90eaa80e52b8bc4bd9002f62d9d4bc8 --- /dev/null +++ b/AdvancedForm/src/locales/en-US.js @@ -0,0 +1,61 @@ +export default { + 'BLOCK_NAME.basic.title': 'Basic form', + 'BLOCK_NAME.basic.description': + 'Form pages are used to collect or verify information to users, and basic forms are common in scenarios where there are fewer data items.', + + 'BLOCK_NAME.email.required': 'Please enter your email!', + 'BLOCK_NAME.email.wrong-format': 'The email address is in the wrong format!', + 'BLOCK_NAME.userName.required': 'Please enter your userName!', + 'BLOCK_NAME.password.required': 'Please enter your password!', + 'BLOCK_NAME.password.twice': 'The passwords entered twice do not match!', + 'BLOCK_NAME.strength.msg': + "Please enter at least 6 characters and don't use passwords that are easy to guess.", + 'BLOCK_NAME.strength.strong': 'Strength: strong', + 'BLOCK_NAME.strength.medium': 'Strength: medium', + 'BLOCK_NAME.strength.short': 'Strength: too short', + 'BLOCK_NAME.confirm-password.required': 'Please confirm your password!', + 'BLOCK_NAME.phone-number.required': 'Please enter your phone number!', + 'BLOCK_NAME.phone-number.wrong-format': 'Malformed phone number!', + 'BLOCK_NAME.verification-code.required': 'Please enter the verification code!', + 'BLOCK_NAME.title.required': 'Please enter a title', + 'BLOCK_NAME.date.required': 'Please select the start and end date', + 'BLOCK_NAME.goal.required': 'Please enter a description of the goal', + 'BLOCK_NAME.standard.required': 'Please enter a metric', + + 'BLOCK_NAME.form.get-captcha': 'Get Captcha', + 'BLOCK_NAME.captcha.second': 'sec', + 'BLOCK_NAME.form.optional': ' (optional) ', + 'BLOCK_NAME.form.submit': 'Submit', + 'BLOCK_NAME.form.save': 'Save', + 'BLOCK_NAME.email.placeholder': 'Email', + 'BLOCK_NAME.password.placeholder': 'Password', + 'BLOCK_NAME.confirm-password.placeholder': 'Confirm password', + 'BLOCK_NAME.phone-number.placeholder': 'Phone number', + 'BLOCK_NAME.verification-code.placeholder': 'Verification code', + 'BLOCK_NAME.title.label': 'Title', + 'BLOCK_NAME.title.placeholder': 'Give the target a name', + 'BLOCK_NAME.date.label': 'Start and end date', + 'BLOCK_NAME.placeholder.start': 'Start date', + 'BLOCK_NAME.placeholder.end': 'End date', + 'BLOCK_NAME.goal.label': 'Goal description', + 'BLOCK_NAME.goal.placeholder': 'Please enter your work goals', + 'BLOCK_NAME.standard.label': 'Metrics', + 'BLOCK_NAME.standard.placeholder': 'Please enter a metric', + 'BLOCK_NAME.client.label': 'Client', + 'BLOCK_NAME.label.tooltip': 'Target service object', + 'BLOCK_NAME.client.placeholder': + 'Please describe your customer service, internal customers directly @ Name / job number', + 'BLOCK_NAME.invites.label': 'Inviting critics', + 'BLOCK_NAME.invites.placeholder': 'Please direct @ Name / job number, you can invite up to 5 people', + 'BLOCK_NAME.weight.label': 'Weight', + 'BLOCK_NAME.weight.placeholder': 'Please enter weight', + 'BLOCK_NAME.public.label': 'Target disclosure', + 'BLOCK_NAME.label.help': 'Customers and invitees are shared by default', + 'BLOCK_NAME.radio.public': 'Public', + 'BLOCK_NAME.radio.partially-public': 'Partially public', + 'BLOCK_NAME.radio.private': 'Private', + 'BLOCK_NAME.publicUsers.placeholder': 'Open to', + 'BLOCK_NAME.option.A': 'Colleague A', + 'BLOCK_NAME.option.B': 'Colleague B', + 'BLOCK_NAME.option.C': 'Colleague C', +}; diff --git a/AdvancedForm/src/locales/pt-BR.js b/AdvancedForm/src/locales/pt-BR.js new file mode 100644 index 0000000000000000000000000000000000000000..1cc9013111adbea37ac80892f11b28d487566f72 --- /dev/null +++ b/AdvancedForm/src/locales/pt-BR.js @@ -0,0 +1,57 @@ +export default { + 'BLOCK_NAME.basic.title': 'Basic form', + 'BLOCK_NAME.basic.description': + 'Form pages are used to collect or verify information to users, and basic forms are common in scenarios where there are fewer data items.', + + 'BLOCK_NAME.email.required': 'Por favor insira seu email!', + 'BLOCK_NAME.email.wrong-format': 'O email está errado!', + 'BLOCK_NAME.userName.required': 'Por favor insira nome de usuário!', + 'BLOCK_NAME.password.required': 'Por favor insira sua senha!', + 'BLOCK_NAME.password.twice': 'As senhas não estão iguais!', + 'BLOCK_NAME.strength.msg': + 'Por favor insira pelo menos 6 caracteres e não use senhas fáceis de adivinhar.', + 'BLOCK_NAME.strength.strong': 'Força: forte', + 'BLOCK_NAME.strength.medium': 'Força: média', + 'BLOCK_NAME.strength.short': 'Força: curta', + 'BLOCK_NAME.confirm-password.required': 'Por favor confirme sua senha!', + 'BLOCK_NAME.phone-number.required': 'Por favor insira seu telefone!', + 'BLOCK_NAME.phone-number.wrong-format': 'Formato de telefone errado!', + 'BLOCK_NAME.verification-code.required': 'Por favor insira seu código de verificação!', + + 'BLOCK_NAME.form.get-captcha': 'Get Captcha', + 'BLOCK_NAME.captcha.second': 'sec', + 'BLOCK_NAME.email.placeholder': 'Email', + 'BLOCK_NAME.password.placeholder': 'Senha', + 'BLOCK_NAME.confirm-password.placeholder': 'Confirme a senha', + 'BLOCK_NAME.phone-number.placeholder': 'Telefone', + 'BLOCK_NAME.verification-code.placeholder': 'Código de verificação', + 'BLOCK_NAME.form.optional': ' (optional) ', + 'BLOCK_NAME.form.submit': 'Submit', + 'BLOCK_NAME.form.save': 'Save', + 'BLOCK_NAME.title.label': 'Title', + 'BLOCK_NAME.title.placeholder': 'Give the target a name', + 'BLOCK_NAME.date.label': 'Start and end date', + 'BLOCK_NAME.placeholder.start': 'Start date', + 'BLOCK_NAME.placeholder.end': 'End date', + 'BLOCK_NAME.goal.label': 'Goal description', + 'BLOCK_NAME.goal.placeholder': 'Please enter your work goals', + 'BLOCK_NAME.standard.label': 'Metrics', + 'BLOCK_NAME.standard.placeholder': 'Please enter a metric', + 'BLOCK_NAME.client.label': 'Client', + 'BLOCK_NAME.label.tooltip': 'Target service object', + 'BLOCK_NAME.client.placeholder': + 'Please describe your customer service, internal customers directly @ Name / job number', + 'BLOCK_NAME.invites.label': 'Inviting critics', + 'BLOCK_NAME.invites.placeholder': 'Please direct @ Name / job number, you can invite up to 5 people', + 'BLOCK_NAME.weight.label': 'Weight', + 'BLOCK_NAME.weight.placeholder': 'Please enter weight', + 'BLOCK_NAME.public.label': 'Target disclosure', + 'BLOCK_NAME.label.help': 'Customers and invitees are shared by default', + 'BLOCK_NAME.radio.public': 'Public', + 'BLOCK_NAME.radio.partially-public': 'Partially public', + 'BLOCK_NAME.radio.private': 'Private', + 'BLOCK_NAME.publicUsers.placeholder': 'Open to', + 'BLOCK_NAME.option.A': 'Colleague A', + 'BLOCK_NAME.option.B': 'Colleague B', + 'BLOCK_NAME.option.C': 'Colleague C', +}; diff --git a/AdvancedForm/src/locales/zh-CN.js b/AdvancedForm/src/locales/zh-CN.js new file mode 100644 index 0000000000000000000000000000000000000000..d9a4b1deb9b5d6f5aa748d6a7aa85ee087cbd416 --- /dev/null +++ b/AdvancedForm/src/locales/zh-CN.js @@ -0,0 +1,59 @@ +export default { + 'BLOCK_NAME.basic.title': '基础表单', + 'BLOCK_NAME.basic.description': + '表单页用于向用户收集或验证信息,基础表单常见于数据项较少的表单场景。', + + 'BLOCK_NAME.email.required': '请输入邮箱地址!', + 'BLOCK_NAME.email.wrong-format': '邮箱地址格式错误!', + 'BLOCK_NAME.userName.required': '请输入用户名!', + 'BLOCK_NAME.password.required': '请输入密码!', + 'BLOCK_NAME.password.twice': '两次输入的密码不匹配!', + 'BLOCK_NAME.strength.msg': '请至少输入 6 个字符。请不要使用容易被猜到的密码。', + 'BLOCK_NAME.strength.strong': '强度:强', + 'BLOCK_NAME.strength.medium': '强度:中', + 'BLOCK_NAME.strength.short': '强度:太短', + 'BLOCK_NAME.confirm-password.required': '请确认密码!', + 'BLOCK_NAME.phone-number.required': '请输入手机号!', + 'BLOCK_NAME.phone-number.wrong-format': '手机号格式错误!', + 'BLOCK_NAME.verification-code.required': '请输入验证码!', + 'BLOCK_NAME.title.required': '请输入标题', + 'BLOCK_NAME.date.required': '请选择起止日期', + 'BLOCK_NAME.goal.required': '请输入目标描述', + 'BLOCK_NAME.standard.required': '请输入衡量标准', + + 'BLOCK_NAME.form.get-captcha': '获取验证码', + 'BLOCK_NAME.captcha.second': '秒', + 'BLOCK_NAME.form.optional': '(选填)', + 'BLOCK_NAME.form.submit': '提交', + 'BLOCK_NAME.form.save': '保存', + 'BLOCK_NAME.email.placeholder': '邮箱', + 'BLOCK_NAME.password.placeholder': '至少6位密码,区分大小写', + 'BLOCK_NAME.confirm-password.placeholder': '确认密码', + 'BLOCK_NAME.phone-number.placeholder': '手机号', + 'BLOCK_NAME.verification-code.placeholder': '验证码', + 'BLOCK_NAME.title.label': '标题', + 'BLOCK_NAME.title.placeholder': '给目标起个名字', + 'BLOCK_NAME.date.label': '起止日期', + 'BLOCK_NAME.placeholder.start': '开始日期', + 'BLOCK_NAME.placeholder.end': '结束日期', + 'BLOCK_NAME.goal.label': '目标描述', + 'BLOCK_NAME.goal.placeholder': '请输入你的阶段性工作目标', + 'BLOCK_NAME.standard.label': '衡量标准', + 'BLOCK_NAME.standard.placeholder': '请输入衡量标准', + 'BLOCK_NAME.client.label': '客户', + 'BLOCK_NAME.label.tooltip': '目标的服务对象', + 'BLOCK_NAME.client.placeholder': '请描述你服务的客户,内部客户直接 @姓名/工号', + 'BLOCK_NAME.invites.label': '邀评人', + 'BLOCK_NAME.invites.placeholder': '请直接 @姓名/工号,最多可邀请 5 人', + 'BLOCK_NAME.weight.label': '权重', + 'BLOCK_NAME.weight.placeholder': '请输入', + 'BLOCK_NAME.public.label': '目标公开', + 'BLOCK_NAME.label.help': '客户、邀评人默认被分享', + 'BLOCK_NAME.radio.public': '公开', + 'BLOCK_NAME.radio.partially-public': '部分公开', + 'BLOCK_NAME.radio.private': '不公开', + 'BLOCK_NAME.publicUsers.placeholder': '公开给', + 'BLOCK_NAME.option.A': '同事甲', + 'BLOCK_NAME.option.B': '同事乙', + 'BLOCK_NAME.option.C': '同事丙', +}; diff --git a/AdvancedForm/src/locales/zh-TW.js b/AdvancedForm/src/locales/zh-TW.js new file mode 100644 index 0000000000000000000000000000000000000000..d42f8520ecb62730bdca8f6aa83ec32982c05932 --- /dev/null +++ b/AdvancedForm/src/locales/zh-TW.js @@ -0,0 +1,59 @@ +export default { + 'BLOCK_NAME.basic.title': '基礎表單', + 'BLOCK_NAME.basic.description': + '表單頁用於向用戶收集或驗證信息,基礎表單常見於數據項較少的表單場景。', + + 'BLOCK_NAME.email.required': '請輸入郵箱地址!', + 'BLOCK_NAME.email.wrong-format': '郵箱地址格式錯誤!', + 'BLOCK_NAME.userName.required': '請輸入賬戶!', + 'BLOCK_NAME.password.required': '請輸入密碼!', + 'BLOCK_NAME.password.twice': '兩次輸入的密碼不匹配!', + 'BLOCK_NAME.strength.msg': '請至少輸入 6 個字符。請不要使用容易被猜到的密碼。', + 'BLOCK_NAME.strength.strong': '強度:強', + 'BLOCK_NAME.strength.medium': '強度:中', + 'BLOCK_NAME.strength.short': '強度:太短', + 'BLOCK_NAME.confirm-password.required': '請確認密碼!', + 'BLOCK_NAME.phone-number.required': '請輸入手機號!', + 'BLOCK_NAME.phone-number.wrong-format': '手機號格式錯誤!', + 'BLOCK_NAME.verification-code.required': '請輸入驗證碼!', + 'BLOCK_NAME.title.required': '請輸入標題', + 'BLOCK_NAME.date.required': '請選擇起止日期', + 'BLOCK_NAME.goal.required': '請輸入目標描述', + 'BLOCK_NAME.standard.required': '請輸入衡量標淮', + + 'BLOCK_NAME.form.get-captcha': '獲取驗證碼', + 'BLOCK_NAME.captcha.second': '秒', + 'BLOCK_NAME.form.optional': '(選填)', + 'BLOCK_NAME.form.submit': '提交', + 'BLOCK_NAME.form.save': '保存', + 'BLOCK_NAME.email.placeholder': '郵箱', + 'BLOCK_NAME.password.placeholder': '至少6位密碼,區分大小寫', + 'BLOCK_NAME.confirm-password.placeholder': '確認密碼', + 'BLOCK_NAME.phone-number.placeholder': '手機號', + 'BLOCK_NAME.verification-code.placeholder': '驗證碼', + 'BLOCK_NAME.title.label': '標題', + 'BLOCK_NAME.title.placeholder': '給目標起個名字', + 'BLOCK_NAME.date.label': '起止日期', + 'BLOCK_NAME.placeholder.start': '開始日期', + 'BLOCK_NAME.placeholder.end': '結束日期', + 'BLOCK_NAME.goal.label': '目標描述', + 'BLOCK_NAME.goal.placeholder': '請輸入妳的階段性工作目標', + 'BLOCK_NAME.standard.label': '衡量標淮', + 'BLOCK_NAME.standard.placeholder': '請輸入衡量標淮', + 'BLOCK_NAME.client.label': '客戶', + 'BLOCK_NAME.label.tooltip': '目標的服務對象', + 'BLOCK_NAME.client.placeholder': '請描述妳服務的客戶,內部客戶直接 @姓名/工號', + 'BLOCK_NAME.invites.label': '邀評人', + 'BLOCK_NAME.invites.placeholder': '請直接 @姓名/工號,最多可邀請 5 人', + 'BLOCK_NAME.weight.label': '權重', + 'BLOCK_NAME.weight.placeholder': '請輸入', + 'BLOCK_NAME.public.label': '目標公開', + 'BLOCK_NAME.label.help': '客戶、邀評人默認被分享', + 'BLOCK_NAME.radio.public': '公開', + 'BLOCK_NAME.radio.partially-public': '部分公開', + 'BLOCK_NAME.radio.private': '不公開', + 'BLOCK_NAME.publicUsers.placeholder': '公開給', + 'BLOCK_NAME.option.A': '同事甲', + 'BLOCK_NAME.option.B': '同事乙', + 'BLOCK_NAME.option.C': '同事丙', +}; diff --git a/AdvancedForm/src/model.js b/AdvancedForm/src/model.js new file mode 100644 index 0000000000000000000000000000000000000000..d07e01930a93912389fa3f9fd35d121276b3207c --- /dev/null +++ b/AdvancedForm/src/model.js @@ -0,0 +1,15 @@ +import { message } from 'antd'; +import { fakeSubmitForm } from './service'; + +export default { + namespace: 'BLOCK_NAME_CAMEL_CASE', + + state: {}, + + effects: { + *submitAdvancedForm({ payload }, { call }) { + yield call(fakeSubmitForm, payload); + message.success('提交成功'); + }, + }, +}; diff --git a/AdvancedForm/src/service.js b/AdvancedForm/src/service.js new file mode 100644 index 0000000000000000000000000000000000000000..77e522c8ca3527da73e4fc1e879705931c277028 --- /dev/null +++ b/AdvancedForm/src/service.js @@ -0,0 +1,8 @@ +import request from 'umi-request'; + +export async function fakeSubmitForm(params) { + return request('/api/BLOCK_NAME/forms', { + method: 'POST', + data: params, + }); +} diff --git a/src/pages/Forms/style.less b/AdvancedForm/src/style.less similarity index 100% rename from src/pages/Forms/style.less rename to AdvancedForm/src/style.less diff --git a/AdvancedProfile/.gitignore b/AdvancedProfile/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8ce76bc425533aa85835a516e25a0d7218a6e15b --- /dev/null +++ b/AdvancedProfile/.gitignore @@ -0,0 +1,7 @@ +/yarn.lock +/package-lock.json +/dist +/node_modules + +.umi +.umi-production diff --git a/AdvancedProfile/.umirc.js b/AdvancedProfile/.umirc.js new file mode 100644 index 0000000000000000000000000000000000000000..545b4c7a99507a4973cd944fc2eafbd612ead8ef --- /dev/null +++ b/AdvancedProfile/.umirc.js @@ -0,0 +1,12 @@ +export default { + plugins: [ + ['umi-plugin-block-dev', { + layout: 'ant-design-pro', + }], + ['umi-plugin-react', { + dva: true, + locale: true, + antd: true, + }] + ], +} diff --git a/AdvancedProfile/README.md b/AdvancedProfile/README.md new file mode 100644 index 0000000000000000000000000000000000000000..9fde77c0432168fd9de1b9174a67ba7732518bd0 --- /dev/null +++ b/AdvancedProfile/README.md @@ -0,0 +1,17 @@ +# @umi-blocks/ant-design-pro/advancedprofile + +AdvancedProfile + +## Usage + +```sh +umi block add ant-design-pro/advancedprofile +``` + +## SNAPSHOT + +![SNAPSHOT](./snapshot.png) + +## LICENSE + +MIT diff --git a/AdvancedProfile/package.json b/AdvancedProfile/package.json new file mode 100644 index 0000000000000000000000000000000000000000..65437eb63f4ea64badf6ee14032824c4ab7bc3b6 --- /dev/null +++ b/AdvancedProfile/package.json @@ -0,0 +1,28 @@ +{ + "name": "@umi-block/advanced-profile", + "version": "0.0.1", + "description": "AdvancedProfile", + "main": "src/index.js", + "scripts": { + "dev": "umi dev" + }, + "repository": { + "type": "git", + "url": "https://github.com/umijs/umi-blocks/ant-design-pro/advancedprofile" + }, + "dependencies": { + "ant-design-pro": "^2.1.1", + "antd": "^3.10.9", + "classnames": "^2.2.6", + "dva": "^2.4.0", + "lodash-decorators": "^6.0.0", + "react": "^16.6.3", + "umi-request": "^1.0.0" + }, + "devDependencies": { + "umi": "^2.3.0-beta.1", + "umi-plugin-react": "^1.3.0-beta.1", + "umi-plugin-block-dev": "^1.0.0" + }, + "license": "ISC" +} diff --git a/AdvancedProfile/snapshot.png b/AdvancedProfile/snapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..09173fd37a0ddcab8ee8a5429ee0d0d89e364798 Binary files /dev/null and b/AdvancedProfile/snapshot.png differ diff --git a/AdvancedProfile/src/_mock.js b/AdvancedProfile/src/_mock.js new file mode 100644 index 0000000000000000000000000000000000000000..6a34f734f7da4a3879ba6acde2a98e96248f33dc --- /dev/null +++ b/AdvancedProfile/src/_mock.js @@ -0,0 +1,74 @@ +const advancedOperation1 = [ + { + key: 'op1', + type: '订购关系生效', + name: '曲丽丽', + status: 'agree', + updatedAt: '2017-10-03 19:23:12', + memo: '-', + }, + { + key: 'op2', + type: '财务复审', + name: '付小小', + status: 'reject', + updatedAt: '2017-10-03 19:23:12', + memo: '不通过原因', + }, + { + key: 'op3', + type: '部门初审', + name: '周毛毛', + status: 'agree', + updatedAt: '2017-10-03 19:23:12', + memo: '-', + }, + { + key: 'op4', + type: '提交订单', + name: '林东东', + status: 'agree', + updatedAt: '2017-10-03 19:23:12', + memo: '很棒', + }, + { + key: 'op5', + type: '创建订单', + name: '汗牙牙', + status: 'agree', + updatedAt: '2017-10-03 19:23:12', + memo: '-', + }, +]; + +const advancedOperation2 = [ + { + key: 'op1', + type: '订购关系生效', + name: '曲丽丽', + status: 'agree', + updatedAt: '2017-10-03 19:23:12', + memo: '-', + }, +]; + +const advancedOperation3 = [ + { + key: 'op1', + type: '创建订单', + name: '汗牙牙', + status: 'agree', + updatedAt: '2017-10-03 19:23:12', + memo: '-', + }, +]; + +const getProfileAdvancedData = { + advancedOperation1, + advancedOperation2, + advancedOperation3, +}; + +export default { + 'GET /api/BLOCK_NAME/advanced': getProfileAdvancedData, +}; diff --git a/AdvancedProfile/src/components/PageHeaderWrapper/index.js b/AdvancedProfile/src/components/PageHeaderWrapper/index.js new file mode 100644 index 0000000000000000000000000000000000000000..165ae2524640af9bfb6a72e918852e8e60480fc7 --- /dev/null +++ b/AdvancedProfile/src/components/PageHeaderWrapper/index.js @@ -0,0 +1,26 @@ +import React from 'react'; +import { FormattedMessage } from 'umi/locale'; +import Link from 'umi/link'; +import { PageHeader } from 'ant-design-pro'; +import styles from './index.less'; + +const PageHeaderWrapper = ({ children, contentWidth, wrapperClassName, top, ...restProps }) => ( +
+ } + key="pageheader" + {...restProps} + linkElement={Link} + itemRender={item => { + if (item.locale) { + return ; + } + return item.title; + }} + /> + {children ?
{children}
: null} +
+); + +export default PageHeaderWrapper; diff --git a/AdvancedProfile/src/components/PageHeaderWrapper/index.less b/AdvancedProfile/src/components/PageHeaderWrapper/index.less new file mode 100644 index 0000000000000000000000000000000000000000..39a449657a98b039c29e6654fd117267cbb5283a --- /dev/null +++ b/AdvancedProfile/src/components/PageHeaderWrapper/index.less @@ -0,0 +1,11 @@ +@import '~antd/lib/style/themes/default.less'; + +.content { + margin: 24px 24px 0; +} + +@media screen and (max-width: @screen-sm) { + .content { + margin: 24px 0 0; + } +} diff --git a/src/pages/Profile/AdvancedProfile.js b/AdvancedProfile/src/index.js similarity index 94% rename from src/pages/Profile/AdvancedProfile.js rename to AdvancedProfile/src/index.js index 0006f993af920de30a7921cbbd2d2a9af74e66c7..341c0aa39b74b5b99e6b52a64cfd74749cb6d961 100644 --- a/src/pages/Profile/AdvancedProfile.js +++ b/AdvancedProfile/src/index.js @@ -18,9 +18,9 @@ import { Divider, } from 'antd'; import classNames from 'classnames'; -import DescriptionList from '@/components/DescriptionList'; -import PageHeaderWrapper from '@/components/PageHeaderWrapper'; -import styles from './AdvancedProfile.less'; +import { DescriptionList } from 'ant-design-pro'; +import PageHeaderWrapper from './components/PageHeaderWrapper'; +import styles from './style.less'; const { Step } = Steps; const { Description } = DescriptionList; @@ -180,11 +180,11 @@ const columns = [ }, ]; -@connect(({ profile, loading }) => ({ - profile, - loading: loading.effects['profile/fetchAdvanced'], +@connect(({ BLOCK_NAME_CAMEL_CASE, loading }) => ({ + BLOCK_NAME_CAMEL_CASE, + loading: loading.effects['BLOCK_NAME_CAMEL_CASE/fetchAdvanced'], })) -class AdvancedProfile extends Component { +class PAGE_NAME_UPPER_CAMEL_CASE extends Component { state = { operationkey: 'tab1', stepDirection: 'horizontal', @@ -193,7 +193,7 @@ class AdvancedProfile extends Component { componentDidMount() { const { dispatch } = this.props; dispatch({ - type: 'profile/fetchAdvanced', + type: 'BLOCK_NAME_CAMEL_CASE/fetchAdvanced', }); this.setStepDirection(); @@ -227,8 +227,8 @@ class AdvancedProfile extends Component { render() { const { stepDirection, operationkey } = this.state; - const { profile, loading } = this.props; - const { advancedOperation1, advancedOperation2, advancedOperation3 } = profile; + const { BLOCK_NAME_CAMEL_CASE, loading } = this.props; + const { advancedOperation1, advancedOperation2, advancedOperation3 } = BLOCK_NAME_CAMEL_CASE; const contentList = { tab1: ( ( } + title={} action={ } + title={} > @@ -33,18 +34,18 @@ const IntroduceRow = memo(({ loading, visitData }) => ( total={() => 126560} footer={ } + label={} value={`¥${numeral(12423).format('0,0')}`} /> } contentHeight={46} > - + 12% - + 11% @@ -54,10 +55,10 @@ const IntroduceRow = memo(({ loading, visitData }) => ( } + title={} action={ } + title={} > @@ -65,7 +66,7 @@ const IntroduceRow = memo(({ loading, visitData }) => ( total={numeral(8846).format('0,0')} footer={ } + label={} value={numeral(1234).format('0,0')} /> } @@ -78,10 +79,10 @@ const IntroduceRow = memo(({ loading, visitData }) => ( } + title={} action={ } + title={} > @@ -91,7 +92,7 @@ const IntroduceRow = memo(({ loading, visitData }) => ( } @@ -109,13 +110,13 @@ const IntroduceRow = memo(({ loading, visitData }) => ( bordered={false} title={ } action={ } + title={} > @@ -124,11 +125,11 @@ const IntroduceRow = memo(({ loading, visitData }) => ( footer={
- + 12% - + 11%
diff --git a/src/pages/Dashboard/OfflineData.js b/Analysis/src/components/OfflineData.js similarity index 80% rename from src/pages/Dashboard/OfflineData.js rename to Analysis/src/components/OfflineData.js index f7d06ef07b8f10f93a86320b3b17d081816a462f..274c1e0d4157c373ee8e0e01f32078e1c6dc720d 100755 --- a/src/pages/Dashboard/OfflineData.js +++ b/Analysis/src/components/OfflineData.js @@ -1,9 +1,10 @@ import React, { memo } from 'react'; import { Card, Tabs, Row, Col } from 'antd'; import { formatMessage, FormattedMessage } from 'umi/locale'; -import styles from './Analysis.less'; -import { TimelineChart, Pie } from '@/components/Charts'; -import NumberInfo from '@/components/NumberInfo'; +import { Charts, NumberInfo } from 'ant-design-pro'; +import styles from '../style.less'; + +const { TimelineChart, Pie } = Charts; const CustomTab = ({ data, currentTabKey: currentKey }) => ( @@ -11,7 +12,7 @@ const CustomTab = ({ data, currentTabKey: currentKey }) => ( + } gap={2} total={`${data.cvr * 100}%`} @@ -50,8 +51,8 @@ const OfflineData = memo( height={400} data={offlineChartData} titleMap={{ - y1: formatMessage({ id: 'app.analysis.traffic' }), - y2: formatMessage({ id: 'app.analysis.payments' }), + y1: formatMessage({ id: 'BLOCK_NAME.analysis.traffic' }), + y2: formatMessage({ id: 'BLOCK_NAME.analysis.payments' }), }} /> diff --git a/src/components/PageLoading/index.js b/Analysis/src/components/PageLoading/index.js similarity index 100% rename from src/components/PageLoading/index.js rename to Analysis/src/components/PageLoading/index.js diff --git a/Analysis/src/components/ProportionSales.js b/Analysis/src/components/ProportionSales.js new file mode 100755 index 0000000000000000000000000000000000000000..51d44be2070a1fa9c332dd90fd12766b5df15747 --- /dev/null +++ b/Analysis/src/components/ProportionSales.js @@ -0,0 +1,65 @@ +import React, { memo } from 'react'; +import { Card, Radio } from 'antd'; +import { Charts } from 'ant-design-pro'; +import { FormattedMessage } from 'umi/locale'; +import styles from '../style.less'; +import Yuan from '../utils/Yuan'; + +const { Pie } = Charts; + +const ProportionSales = memo( + ({ dropdownGroup, salesType, loading, salesPieData, handleChangeSalesType }) => ( + + } + bodyStyle={{ padding: 24 }} + extra={ +
+ {dropdownGroup} +
+ + + + + + + + + + + +
+
+ } + style={{ marginTop: 24 }} + > +
+

+ +

+ } + total={() => {salesPieData.reduce((pre, now) => now.y + pre, 0)}} + data={salesPieData} + valueFormat={value => {value}} + height={248} + lineWidth={4} + /> +
+
+ ) +); + +export default ProportionSales; diff --git a/src/pages/Dashboard/SalesCard.js b/Analysis/src/components/SalesCard.js similarity index 82% rename from src/pages/Dashboard/SalesCard.js rename to Analysis/src/components/SalesCard.js index 3ab577757067c329a79028cbec08deb3dfc61787..893314eb075fb6511ad8233e366d94054bbaa592 100755 --- a/src/pages/Dashboard/SalesCard.js +++ b/Analysis/src/components/SalesCard.js @@ -2,8 +2,10 @@ import React, { memo } from 'react'; import { Row, Col, Card, Tabs, DatePicker } from 'antd'; import { FormattedMessage, formatMessage } from 'umi/locale'; import numeral from 'numeral'; -import styles from './Analysis.less'; -import { Bar } from '@/components/Charts'; +import { Charts } from 'ant-design-pro'; +import styles from '../style.less'; + +const { Bar } = Charts; const { RangePicker } = DatePicker; const { TabPane } = Tabs; @@ -11,7 +13,7 @@ const { TabPane } = Tabs; const rankingListData = []; for (let i = 0; i < 7; i += 1) { rankingListData.push({ - title: formatMessage({ id: 'app.analysis.test' }, { no: i }), + title: formatMessage({ id: 'BLOCK_NAME.analysis.test' }, { no: i }), total: 323234, }); } @@ -25,16 +27,16 @@ const SalesCard = memo(
} + tab={} key="sales" > @@ -58,7 +60,7 @@ const SalesCard = memo( height={295} title={ } @@ -70,7 +72,7 @@ const SalesCard = memo(

@@ -96,7 +98,7 @@ const SalesCard = memo( } + tab={} key="views" > @@ -106,7 +108,7 @@ const SalesCard = memo( height={292} title={ } @@ -118,7 +120,7 @@ const SalesCard = memo(

diff --git a/src/pages/Dashboard/TopSearch.js b/Analysis/src/components/TopSearch.js similarity index 69% rename from src/pages/Dashboard/TopSearch.js rename to Analysis/src/components/TopSearch.js index 4e75ea7d51ebba6a5d52e336c24d318f8e5d5a41..9946b2ad5763b7bcde5ddda74fa202e467660f20 100755 --- a/src/pages/Dashboard/TopSearch.js +++ b/Analysis/src/components/TopSearch.js @@ -1,35 +1,35 @@ import React, { memo } from 'react'; import { Row, Col, Table, Tooltip, Card, Icon } from 'antd'; import { FormattedMessage } from 'umi/locale'; -import Trend from '@/components/Trend'; +import { Trend, NumberInfo, Charts } from 'ant-design-pro'; import numeral from 'numeral'; -import styles from './Analysis.less'; -import NumberInfo from '@/components/NumberInfo'; -import { MiniArea } from '@/components/Charts'; +import styles from '../style.less'; + +const { MiniArea } = Charts; const columns = [ { - title: , + title: , dataIndex: 'index', key: 'index', }, { title: ( - + ), dataIndex: 'keyword', key: 'keyword', render: text => {text}, }, { - title: , + title: , dataIndex: 'count', key: 'count', sorter: (a, b) => a.count - b.count, className: styles.alignRight, }, { - title: , + title: , dataIndex: 'range', key: 'range', sorter: (a, b) => a.range - b.range, @@ -47,7 +47,7 @@ const TopSearch = memo(({ loading, visitData2, searchData, dropdownGroup }) => ( loading={loading} bordered={false} title={ - + } extra={dropdownGroup} style={{ marginTop: 24 }} @@ -57,9 +57,9 @@ const TopSearch = memo(({ loading, visitData2, searchData, dropdownGroup }) => ( - + } + title={} > @@ -77,11 +77,11 @@ const TopSearch = memo(({ loading, visitData2, searchData, dropdownGroup }) => ( subTitle={ } + title={} > diff --git a/src/pages/Dashboard/Analysis.js b/Analysis/src/index.js similarity index 62% rename from src/pages/Dashboard/Analysis.js rename to Analysis/src/index.js index 0b85db70bb39bb5923a209d432b9f7fe54528638..d175e701cf2f48ce9bb371d6eccfaebb7d83c974 100644 --- a/src/pages/Dashboard/Analysis.js +++ b/Analysis/src/index.js @@ -2,23 +2,22 @@ import React, { Component, Suspense } from 'react'; import { connect } from 'dva'; import { Row, Col, Icon, Menu, Dropdown } from 'antd'; -import GridContent from '@/components/PageHeaderWrapper/GridContent'; -import { getTimeDistance } from '@/utils/utils'; +import { getTimeDistance } from './utils/utils'; -import styles from './Analysis.less'; -import PageLoading from '@/components/PageLoading'; +import styles from './style.less'; +import PageLoading from './components/PageLoading'; -const IntroduceRow = React.lazy(() => import('./IntroduceRow')); -const SalesCard = React.lazy(() => import('./SalesCard')); -const TopSearch = React.lazy(() => import('./TopSearch')); -const ProportionSales = React.lazy(() => import('./ProportionSales')); -const OfflineData = React.lazy(() => import('./OfflineData')); +const IntroduceRow = React.lazy(() => import('./components/IntroduceRow')); +const SalesCard = React.lazy(() => import('./components/SalesCard')); +const TopSearch = React.lazy(() => import('./components/TopSearch')); +const ProportionSales = React.lazy(() => import('./components/ProportionSales')); +const OfflineData = React.lazy(() => import('./components/OfflineData')); -@connect(({ chart, loading }) => ({ - chart, - loading: loading.effects['chart/fetch'], +@connect(({ BLOCK_NAME_CAMEL_CASE, loading }) => ({ + BLOCK_NAME_CAMEL_CASE, + loading: loading.effects['BLOCK_NAME_CAMEL_CASE/fetch'], })) -class Analysis extends Component { +class PAGE_NAME_UPPER_CAMEL_CASE extends Component { state = { salesType: 'all', currentTabKey: '', @@ -29,7 +28,7 @@ class Analysis extends Component { const { dispatch } = this.props; this.reqRef = requestAnimationFrame(() => { dispatch({ - type: 'chart/fetch', + type: 'BLOCK_NAME_CAMEL_CASE/fetch', }); }); } @@ -37,7 +36,7 @@ class Analysis extends Component { componentWillUnmount() { const { dispatch } = this.props; dispatch({ - type: 'chart/clear', + type: 'BLOCK_NAME_CAMEL_CASE/clear', }); cancelAnimationFrame(this.reqRef); clearTimeout(this.timeoutId); @@ -62,7 +61,7 @@ class Analysis extends Component { }); dispatch({ - type: 'chart/fetchSalesData', + type: 'BLOCK_NAME_CAMEL_CASE/fetchSalesData', }); }; @@ -73,7 +72,7 @@ class Analysis extends Component { }); dispatch({ - type: 'chart/fetchSalesData', + type: 'BLOCK_NAME_CAMEL_CASE/fetchSalesData', }); }; @@ -94,7 +93,7 @@ class Analysis extends Component { render() { const { rangePickerValue, salesType, currentTabKey } = this.state; - const { chart, loading } = this.props; + const { BLOCK_NAME_CAMEL_CASE, loading } = this.props; const { visitData, visitData2, @@ -105,7 +104,7 @@ class Analysis extends Component { salesTypeData, salesTypeDataOnline, salesTypeDataOffline, - } = chart; + } = BLOCK_NAME_CAMEL_CASE; let salesPieData; if (salesType === 'all') { salesPieData = salesTypeData; @@ -130,7 +129,7 @@ class Analysis extends Component { const activeKey = currentTabKey || (offlineData[0] && offlineData[0].name); return ( - + }> @@ -144,32 +143,30 @@ class Analysis extends Component { selectDate={this.selectDate} /> -
- -
- - - - - - - - - - - + + + + + + + + + + + + - + ); } } -export default Analysis; +export default PAGE_NAME_UPPER_CAMEL_CASE; diff --git a/Analysis/src/locales/en-US.js b/Analysis/src/locales/en-US.js new file mode 100644 index 0000000000000000000000000000000000000000..dc611a18c309b8b0681b951229f0c9e8de50235c --- /dev/null +++ b/Analysis/src/locales/en-US.js @@ -0,0 +1,34 @@ +export default { + 'BLOCK_NAME.analysis.test': 'Gongzhuan No.{no} shop', + 'BLOCK_NAME.analysis.introduce': 'Introduce', + 'BLOCK_NAME.analysis.total-sales': 'Total Sales', + 'BLOCK_NAME.analysis.day-sales': 'Daily Sales', + 'BLOCK_NAME.analysis.visits': 'Visits', + 'BLOCK_NAME.analysis.visits-trend': 'Visits Trend', + 'BLOCK_NAME.analysis.visits-ranking': 'Visits Ranking', + 'BLOCK_NAME.analysis.day-visits': 'Daily Visits', + 'BLOCK_NAME.analysis.week': 'WoW Change', + 'BLOCK_NAME.analysis.day': 'DoD Change', + 'BLOCK_NAME.analysis.payments': 'Payments', + 'BLOCK_NAME.analysis.conversion-rate': 'Conversion Rate', + 'BLOCK_NAME.analysis.operational-effect': 'Operational Effect', + 'BLOCK_NAME.analysis.sales-trend': 'Stores Sales Trend', + 'BLOCK_NAME.analysis.sales-ranking': 'Sales Ranking', + 'BLOCK_NAME.analysis.all-year': 'All Year', + 'BLOCK_NAME.analysis.all-month': 'All Month', + 'BLOCK_NAME.analysis.all-week': 'All Week', + 'BLOCK_NAME.analysis.all-day': 'All day', + 'BLOCK_NAME.analysis.search-users': 'Search Users', + 'BLOCK_NAME.analysis.per-capita-search': 'Per Capita Search', + 'BLOCK_NAME.analysis.online-top-search': 'Online Top Search', + 'BLOCK_NAME.analysis.the-proportion-of-sales': 'The Proportion Of Sales', + 'BLOCK_NAME.channel.all': 'ALL', + 'BLOCK_NAME.channel.online': 'Online', + 'BLOCK_NAME.channel.stores': 'Stores', + 'BLOCK_NAME.analysis.sales': 'Sales', + 'BLOCK_NAME.analysis.traffic': 'Traffic', + 'BLOCK_NAME.table.rank': 'Rank', + 'BLOCK_NAME.table.search-keyword': 'Keyword', + 'BLOCK_NAME.table.users': 'Users', + 'BLOCK_NAME.table.weekly-range': 'Weekly Range', +}; diff --git a/Analysis/src/locales/pt-BR.js b/Analysis/src/locales/pt-BR.js new file mode 100644 index 0000000000000000000000000000000000000000..ead8d95952b2bc7d2b62191b3d13edf5223794ba --- /dev/null +++ b/Analysis/src/locales/pt-BR.js @@ -0,0 +1,34 @@ +export default { + 'BLOCK_NAME.analysis.test': 'Gongzhuan No.{no} shop', + 'BLOCK_NAME.analysis.introduce': 'Introduzir', + 'BLOCK_NAME.analysis.total-sales': 'Vendas Totais', + 'BLOCK_NAME.analysis.day-sales': 'Vendas do Dia', + 'BLOCK_NAME.analysis.visits': 'Visitas', + 'BLOCK_NAME.analysis.visits-trend': 'Tendência de Visitas', + 'BLOCK_NAME.analysis.visits-ranking': 'Ranking de Visitas', + 'BLOCK_NAME.analysis.day-visits': 'Visitas do Dia', + 'BLOCK_NAME.analysis.week': 'Taxa Semanal', + 'BLOCK_NAME.analysis.day': 'Taxa Diária', + 'BLOCK_NAME.analysis.payments': 'Pagamentos', + 'BLOCK_NAME.analysis.conversion-rate': 'Taxa de Conversão', + 'BLOCK_NAME.analysis.operational-effect': 'Efeito Operacional', + 'BLOCK_NAME.analysis.sales-trend': 'Tendência de Vendas das Lojas', + 'BLOCK_NAME.analysis.sales-ranking': 'Ranking de Vendas', + 'BLOCK_NAME.$2': 'Todo ano', + 'BLOCK_NAME.analysis.all-month': 'Todo mês', + 'BLOCK_NAME.analysis.all-week': 'Toda semana', + 'BLOCK_NAME.analysis.all-day': 'Todo dia', + 'BLOCK_NAME.analysis.search-users': 'Pesquisa de Usuários', + 'BLOCK_NAME.analysis.per-capita-search': 'Busca Per Capta', + 'BLOCK_NAME.analysis.online-top-search': 'Mais Buscadas Online', + 'BLOCK_NAME.analysis.the-proportion-of-sales': 'The Proportion Of Sales', + 'BLOCK_NAME.channel.all': 'Tudo', + 'BLOCK_NAME.channel.online': 'Online', + 'BLOCK_NAME.channel.stores': 'Lojas', + 'BLOCK_NAME.analysis.sales': 'Vendas', + 'BLOCK_NAME.analysis.traffic': 'Tráfego', + 'BLOCK_NAME.table.rank': 'Rank', + 'BLOCK_NAME.table.search-keyword': 'Palavra chave', + 'BLOCK_NAME.table.users': 'Usuários', + 'BLOCK_NAME.table.weekly-range': 'Faixa Semanal', +}; diff --git a/Analysis/src/locales/zh-CN.js b/Analysis/src/locales/zh-CN.js new file mode 100644 index 0000000000000000000000000000000000000000..1c1620ef5a85b1cfa04338d9b6cb24356bd48478 --- /dev/null +++ b/Analysis/src/locales/zh-CN.js @@ -0,0 +1,34 @@ +export default { + 'BLOCK_NAME.analysis.test': '工专路 {no} 号店', + 'BLOCK_NAME.analysis.introduce': '指标说明', + 'BLOCK_NAME.analysis.total-sales': '总销售额', + 'BLOCK_NAME.analysis.day-sales': '日销售额', + 'BLOCK_NAME.analysis.visits': '访问量', + 'BLOCK_NAME.analysis.visits-trend': '访问量趋势', + 'BLOCK_NAME.analysis.visits-ranking': '门店访问量排名', + 'BLOCK_NAME.analysis.day-visits': '日访问量', + 'BLOCK_NAME.analysis.week': '周同比', + 'BLOCK_NAME.analysis.day': '日同比', + 'BLOCK_NAME.analysis.payments': '支付笔数', + 'BLOCK_NAME.analysis.conversion-rate': '转化率', + 'BLOCK_NAME.analysis.operational-effect': '运营活动效果', + 'BLOCK_NAME.analysis.sales-trend': '销售趋势', + 'BLOCK_NAME.analysis.sales-ranking': '门店销售额排名', + 'BLOCK_NAME.analysis.all-year': '全年', + 'BLOCK_NAME.analysis.all-month': '本月', + 'BLOCK_NAME.analysis.all-week': '本周', + 'BLOCK_NAME.analysis.all-day': '今日', + 'BLOCK_NAME.analysis.search-users': '搜索用户数', + 'BLOCK_NAME.analysis.per-capita-search': '人均搜索次数', + 'BLOCK_NAME.analysis.online-top-search': '线上热门搜索', + 'BLOCK_NAME.analysis.the-proportion-of-sales': '销售额类别占比', + 'BLOCK_NAME.channel.all': '全部渠道', + 'BLOCK_NAME.channel.online': '线上', + 'BLOCK_NAME.channel.stores': '门店', + 'BLOCK_NAME.analysis.sales': '销售额', + 'BLOCK_NAME.analysis.traffic': '客流量', + 'BLOCK_NAME.table.rank': '排名', + 'BLOCK_NAME.table.search-keyword': '搜索关键词', + 'BLOCK_NAME.table.users': '用户数', + 'BLOCK_NAME.table.weekly-range': '周涨幅', +}; diff --git a/Analysis/src/locales/zh-TW.js b/Analysis/src/locales/zh-TW.js new file mode 100644 index 0000000000000000000000000000000000000000..2238e4413000dc1c9aae2b48170ab9b56ee982b3 --- /dev/null +++ b/Analysis/src/locales/zh-TW.js @@ -0,0 +1,34 @@ +export default { + 'BLOCK_NAME.analysis.test': '工專路 {no} 號店', + 'BLOCK_NAME.analysis.introduce': '指標說明', + 'BLOCK_NAME.analysis.total-sales': '總銷售額', + 'BLOCK_NAME.analysis.day-sales': '日銷售額', + 'BLOCK_NAME.analysis.visits': '訪問量', + 'BLOCK_NAME.analysis.visits-trend': '訪問量趨勢', + 'BLOCK_NAME.analysis.visits-ranking': '門店訪問量排名', + 'BLOCK_NAME.analysis.day-visits': '日訪問量', + 'BLOCK_NAME.analysis.week': '周同比', + 'BLOCK_NAME.analysis.day': '日同比', + 'BLOCK_NAME.analysis.payments': '支付筆數', + 'BLOCK_NAME.analysis.conversion-rate': '轉化率', + 'BLOCK_NAME.analysis.operational-effect': '運營活動效果', + 'BLOCK_NAME.analysis.sales-trend': '銷售趨勢', + 'BLOCK_NAME.analysis.sales-ranking': '門店銷售額排名', + 'BLOCK_NAME.analysis.all-year': '全年', + 'BLOCK_NAME.analysis.all-month': '本月', + 'BLOCK_NAME.analysis.all-week': '本周', + 'BLOCK_NAME.analysis.all-day': '今日', + 'BLOCK_NAME.analysis.search-users': '搜索用戶數', + 'BLOCK_NAME.analysis.per-capita-search': '人均搜索次數', + 'BLOCK_NAME.analysis.online-top-search': '線上熱門搜索', + 'BLOCK_NAME.analysis.the-proportion-of-sales': '銷售額類別占比', + 'BLOCK_NAME.channel.all': '全部渠道', + 'BLOCK_NAME.channel.online': '線上', + 'BLOCK_NAME.channel.stores': '門店', + 'BLOCK_NAME.analysis.sales': '銷售額', + 'BLOCK_NAME.analysis.traffic': '客流量', + 'BLOCK_NAME.table.rank': '排名', + 'BLOCK_NAME.table.search-keyword': '搜索關鍵詞', + 'BLOCK_NAME.table.users': '用戶數', + 'BLOCK_NAME.table.weekly-range': '周漲幅', +}; diff --git a/src/pages/Dashboard/models/chart.js b/Analysis/src/model.js similarity index 93% rename from src/pages/Dashboard/models/chart.js rename to Analysis/src/model.js index 8dfe4a93f5b9b1efbc957fc7034e9949b67f1d29..4e062cc3d5c754a193a46a7890998a469b23623a 100644 --- a/src/pages/Dashboard/models/chart.js +++ b/Analysis/src/model.js @@ -1,7 +1,7 @@ -import { fakeChartData } from '@/services/api'; +import { fakeChartData } from './service'; export default { - namespace: 'chart', + namespace: 'BLOCK_NAME_CAMEL_CASE', state: { visitData: [], diff --git a/Analysis/src/service.js b/Analysis/src/service.js new file mode 100644 index 0000000000000000000000000000000000000000..65a1eb216b35a29d86124f9a0810df99e5e16845 --- /dev/null +++ b/Analysis/src/service.js @@ -0,0 +1,5 @@ +import request from 'umi-request'; + +export async function fakeChartData() { + return request('/api/BLOCK_NAME/fake_chart_data'); +} diff --git a/src/pages/Dashboard/Analysis.less b/Analysis/src/style.less similarity index 89% rename from src/pages/Dashboard/Analysis.less rename to Analysis/src/style.less index 70877d6636cb5cffdadd44e242776cbdd4fdd663..4df48a03b85e6b8933688e478095e0f84d38ca17 100644 --- a/src/pages/Dashboard/Analysis.less +++ b/Analysis/src/style.less @@ -1,5 +1,5 @@ @import '~antd/lib/style/themes/default.less'; -@import '~@/utils/utils.less'; +@import './utils/utils.less'; .iconGroup { i { @@ -134,25 +134,6 @@ } } -.twoColLayout { - .salesCard { - height: calc(100% - 24px); - } - div[class^='ant-col']:last-child { - right: 0\9; - height: 100%\9; - position: absolute\9; - } - :global { - .ant-row { - display: flex; - display: block\9; - flex-flow: row wrap; - position: relative\9; - } - } -} - .trendText { margin-left: 8px; color: @heading-color; diff --git a/src/utils/Yuan.js b/Analysis/src/utils/Yuan.js similarity index 90% rename from src/utils/Yuan.js rename to Analysis/src/utils/Yuan.js index 434a57fb7cfc547015cfff71ac427b85be27817b..415e95574b059a85ba89116446f6f72620e34bdd 100644 --- a/src/utils/Yuan.js +++ b/Analysis/src/utils/Yuan.js @@ -1,5 +1,5 @@ import React from 'react'; -import { yuan } from '@/components/Charts'; +import { yuan } from 'ant-design-pro/lib/Charts'; /** * 减少使用 dangerouslySetInnerHTML */ diff --git a/Analysis/src/utils/utils.js b/Analysis/src/utils/utils.js new file mode 100644 index 0000000000000000000000000000000000000000..6e77bd481b045873e3b5853bca1fb361e02cd115 --- /dev/null +++ b/Analysis/src/utils/utils.js @@ -0,0 +1,50 @@ +import moment from 'moment'; + +export function fixedZero(val) { + return val * 1 < 10 ? `0${val}` : val; +} + +export function getTimeDistance(type) { + const now = new Date(); + const oneDay = 1000 * 60 * 60 * 24; + + if (type === 'today') { + now.setHours(0); + now.setMinutes(0); + now.setSeconds(0); + return [moment(now), moment(now.getTime() + (oneDay - 1000))]; + } + + if (type === 'week') { + let day = now.getDay(); + now.setHours(0); + now.setMinutes(0); + now.setSeconds(0); + + if (day === 0) { + day = 6; + } else { + day -= 1; + } + + const beginTime = now.getTime() - day * oneDay; + + return [moment(beginTime), moment(beginTime + (7 * oneDay - 1000))]; + } + + if (type === 'month') { + const year = now.getFullYear(); + const month = now.getMonth(); + const nextDate = moment(now).add(1, 'months'); + const nextYear = nextDate.year(); + const nextMonth = nextDate.month(); + + return [ + moment(`${year}-${fixedZero(month + 1)}-01 00:00:00`), + moment(moment(`${nextYear}-${fixedZero(nextMonth + 1)}-01 00:00:00`).valueOf() - 1000), + ]; + } + + const year = now.getFullYear(); + return [moment(`${year}-01-01 00:00:00`), moment(`${year}-12-31 23:59:59`)]; +} diff --git a/src/utils/utils.less b/Analysis/src/utils/utils.less similarity index 100% rename from src/utils/utils.less rename to Analysis/src/utils/utils.less diff --git a/BasicForm/.gitignore b/BasicForm/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8ce76bc425533aa85835a516e25a0d7218a6e15b --- /dev/null +++ b/BasicForm/.gitignore @@ -0,0 +1,7 @@ +/yarn.lock +/package-lock.json +/dist +/node_modules + +.umi +.umi-production diff --git a/BasicForm/.umirc.js b/BasicForm/.umirc.js new file mode 100644 index 0000000000000000000000000000000000000000..545b4c7a99507a4973cd944fc2eafbd612ead8ef --- /dev/null +++ b/BasicForm/.umirc.js @@ -0,0 +1,12 @@ +export default { + plugins: [ + ['umi-plugin-block-dev', { + layout: 'ant-design-pro', + }], + ['umi-plugin-react', { + dva: true, + locale: true, + antd: true, + }] + ], +} diff --git a/BasicForm/README.md b/BasicForm/README.md new file mode 100644 index 0000000000000000000000000000000000000000..69953537b61aaf96956d40ff11f1a7e5cd499ec8 --- /dev/null +++ b/BasicForm/README.md @@ -0,0 +1,17 @@ +# @umi-blocks/ant-design-pro/basicform + +BasicForm + +## Usage + +```sh +umi block add ant-design-pro/basicform +``` + +## SNAPSHOT + +![SNAPSHOT](./snapshot.png) + +## LICENSE + +MIT diff --git a/BasicForm/package.json b/BasicForm/package.json new file mode 100644 index 0000000000000000000000000000000000000000..1f96d53fc5d3818656c3de984a31757e0a34dc2c --- /dev/null +++ b/BasicForm/package.json @@ -0,0 +1,26 @@ +{ + "name": "@umi-block/basic-form", + "version": "0.0.1", + "description": "BasicForm", + "main": "src/index.js", + "scripts": { + "dev": "umi dev" + }, + "repository": { + "type": "git", + "url": "https://github.com/umijs/umi-blocks/ant-design-pro/basicform" + }, + "dependencies": { + "ant-design-pro": "^2.1.1", + "antd": "^3.10.9", + "dva": "^2.4.0", + "react": "^16.6.3", + "umi-request": "^1.0.0" + }, + "devDependencies": { + "umi": "^2.3.0-beta.1", + "umi-plugin-react": "^1.3.0-beta.1", + "umi-plugin-block-dev": "^1.0.0" + }, + "license": "ISC" +} diff --git a/BasicForm/snapshot.png b/BasicForm/snapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..587cbcbf72eeda1e384d233af0dee728274922b3 Binary files /dev/null and b/BasicForm/snapshot.png differ diff --git a/BasicForm/src/_mock.js b/BasicForm/src/_mock.js new file mode 100644 index 0000000000000000000000000000000000000000..8e7996deae35737ca576735528af9f6eaa281b98 --- /dev/null +++ b/BasicForm/src/_mock.js @@ -0,0 +1,5 @@ +export default { + 'POST /api/BLOCK_NAME/forms': (req, res) => { + res.send({ message: 'Ok' }); + }, +}; diff --git a/BasicForm/src/components/PageHeaderWrapper/index.js b/BasicForm/src/components/PageHeaderWrapper/index.js new file mode 100644 index 0000000000000000000000000000000000000000..c11873f2c8c24d44391261910d5adb52ab916d1a --- /dev/null +++ b/BasicForm/src/components/PageHeaderWrapper/index.js @@ -0,0 +1,25 @@ +import React from 'react'; +import { FormattedMessage } from 'umi/locale'; +import Link from 'umi/link'; +import { PageHeader } from 'ant-design-pro'; +import styles from './index.less'; + +const PageHeaderWrapper = ({ children, wrapperClassName, ...restProps }) => ( +
+ } + key="pageheader" + {...restProps} + linkElement={Link} + itemRender={item => { + if (item.locale) { + return ; + } + return item.title; + }} + /> + {children ?
{children}
: null} +
+); + +export default PageHeaderWrapper; diff --git a/BasicForm/src/components/PageHeaderWrapper/index.less b/BasicForm/src/components/PageHeaderWrapper/index.less new file mode 100644 index 0000000000000000000000000000000000000000..39a449657a98b039c29e6654fd117267cbb5283a --- /dev/null +++ b/BasicForm/src/components/PageHeaderWrapper/index.less @@ -0,0 +1,11 @@ +@import '~antd/lib/style/themes/default.less'; + +.content { + margin: 24px 24px 0; +} + +@media screen and (max-width: @screen-sm) { + .content { + margin: 24px 0 0; + } +} diff --git a/src/pages/Forms/BasicForm.js b/BasicForm/src/index.js similarity index 66% rename from src/pages/Forms/BasicForm.js rename to BasicForm/src/index.js index 55833150a1ed63d053e894968d35ac548c3129ae..bdef2fee1739adaf2cc34e920a96293d805dffd9 100644 --- a/src/pages/Forms/BasicForm.js +++ b/BasicForm/src/index.js @@ -13,7 +13,7 @@ import { Icon, Tooltip, } from 'antd'; -import PageHeaderWrapper from '@/components/PageHeaderWrapper'; +import PageHeaderWrapper from './components/PageHeaderWrapper'; import styles from './style.less'; const FormItem = Form.Item; @@ -22,17 +22,17 @@ const { RangePicker } = DatePicker; const { TextArea } = Input; @connect(({ loading }) => ({ - submitting: loading.effects['form/submitRegularForm'], + submitting: loading.effects['BLOCK_NAME_CAMEL_CASE/submitRegularForm'], })) @Form.create() -class BasicForms extends PureComponent { +class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent { handleSubmit = e => { const { dispatch, form } = this.props; e.preventDefault(); form.validateFieldsAndScroll((err, values) => { if (!err) { dispatch({ - type: 'form/submitRegularForm', + type: 'BLOCK_NAME_CAMEL_CASE/submitRegularForm', payload: values, }); } @@ -66,67 +66,67 @@ class BasicForms extends PureComponent { return ( } - content={} + title={} + content={} >
- }> + }> {getFieldDecorator('title', { rules: [ { required: true, - message: formatMessage({ id: 'validation.title.required' }), + message: formatMessage({ id: 'BLOCK_NAME.title.required' }), }, ], - })()} + })()} - }> + }> {getFieldDecorator('date', { rules: [ { required: true, - message: formatMessage({ id: 'validation.date.required' }), + message: formatMessage({ id: 'BLOCK_NAME.date.required' }), }, ], })( )} - }> + }> {getFieldDecorator('goal', { rules: [ { required: true, - message: formatMessage({ id: 'validation.goal.required' }), + message: formatMessage({ id: 'BLOCK_NAME.goal.required' }), }, ], })(