diff --git a/.umirc.js b/.umirc.js index 75ec0fc91214c0f490a31f8e6dd71856d8abe7d1..85f1038f928e8e09395f08268816b551e3e96b19 100644 --- a/.umirc.js +++ b/.umirc.js @@ -3,7 +3,7 @@ export default { [ 'umi-plugin-block-dev', { - layout: 'ant-design-pro-user', + layout: 'ant-design-pro', menu: { name: '主页', icon: 'home', diff --git a/Analysis/src/components/Charts/index.tsx b/Analysis/src/components/Charts/index.tsx index f025299399ac03e4e1d2dfabc4b2fb4ab2de89e1..5e0815f18ef573549dfc4c13de317568d02db80c 100644 --- a/Analysis/src/components/Charts/index.tsx +++ b/Analysis/src/components/Charts/index.tsx @@ -3,7 +3,6 @@ import ChartCard from './ChartCard'; import Field from './Field'; import Bar from './Bar'; import Pie from './Pie'; -import Radar from './Radar'; import Gauge from './Gauge'; import MiniArea from './MiniArea'; import MiniBar from './MiniBar'; @@ -19,7 +18,6 @@ const Charts = { Bar, Pie, Gauge, - Radar, MiniBar, MiniArea, MiniProgress, @@ -36,7 +34,6 @@ export { Bar, Pie, Gauge, - Radar, MiniBar, MiniArea, MiniProgress, diff --git a/Workplace/package.json b/Workplace/package.json index ff500b4c83538eef7bc851a675ace0a8bf2d5414..1adc1a0e9bf036222b7b3785e1cd7a7302464870 100644 --- a/Workplace/package.json +++ b/Workplace/package.json @@ -16,7 +16,8 @@ "moment": "^2.22.2", "prop-types": "^15.5.10", "react": "^16.6.3", - "umi-request": "^1.0.0" + "umi-request": "^1.0.0", + "bizcharts": "^3.5.2" }, "devDependencies": { "umi": "^2.6.9", @@ -24,4 +25,4 @@ "umi-plugin-react": "^1.3.0-beta.1" }, "license": "MIT" -} \ No newline at end of file +} diff --git a/Workplace/src/components/EditableLinkGroup/index.js b/Workplace/src/components/EditableLinkGroup/index.tsx similarity index 76% rename from Workplace/src/components/EditableLinkGroup/index.js rename to Workplace/src/components/EditableLinkGroup/index.tsx index ae3d93c712b8b019078fe37bd07286716349ef3f..122a0186801bc37bdc8193d00637f34357e9acf7 100644 --- a/Workplace/src/components/EditableLinkGroup/index.js +++ b/Workplace/src/components/EditableLinkGroup/index.tsx @@ -1,11 +1,20 @@ import React, { PureComponent, createElement } from 'react'; -import PropTypes from 'prop-types'; +import PropTypes, { string } from 'prop-types'; import { Button } from 'antd'; import styles from './index.less'; -// TODO: 添加逻辑 +export interface EditableLink { + title: string; + href: string; +} + +interface EditableLinkGroupProps { + onAdd: () => void; + links: EditableLink[]; + linkElement: React.Component; +} -class EditableLinkGroup extends PureComponent { +class EditableLinkGroup extends PureComponent { static propTypes = { links: PropTypes.array, onAdd: PropTypes.func, diff --git a/Workplace/src/components/PageHeaderWrapper/index.js b/Workplace/src/components/PageHeaderWrapper/index.js deleted file mode 100644 index d121b2c4994d8c5110f9ff69fd9079dddcd183dc..0000000000000000000000000000000000000000 --- a/Workplace/src/components/PageHeaderWrapper/index.js +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react'; -import { FormattedMessage } from 'umi-plugin-react/locale'; -import Link from 'umi/link'; -import { PageHeader } from 'ant-design-pro'; -import styles from './index.less'; - -const PageHeaderWrapper = ({ children, contentWidth, 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/Workplace/src/components/PageHeaderWrapper/index.less b/Workplace/src/components/PageHeaderWrapper/index.less index 39a449657a98b039c29e6654fd117267cbb5283a..908db575ae9f0a0cd75d04952ba4f37b3002da42 100644 --- a/Workplace/src/components/PageHeaderWrapper/index.less +++ b/Workplace/src/components/PageHeaderWrapper/index.less @@ -1,11 +1,86 @@ @import '~antd/lib/style/themes/default.less'; -.content { +.children-content { margin: 24px 24px 0; } -@media screen and (max-width: @screen-sm) { +.main { + .detail { + display: flex; + } + + .row { + display: flex; + width: 100%; + } + + .title-content { + margin-bottom: 16px; + } + + @media screen and (max-width: @screen-sm) { + .content { + margin: 24px 0 0; + } + } + + .title, .content { - margin: 24px 0 0; + flex: auto; + } + + .extraContent, + .main { + flex: 0 1 auto; + } + + .main { + width: 100%; + } + + .title { + margin-bottom: 16px; + } + + .logo, + .content, + .extraContent { + margin-bottom: 16px; + } + + .extraContent { + min-width: 242px; + margin-left: 88px; + text-align: right; + } +} + +@media screen and (max-width: @screen-xl) { + .extraContent { + margin-left: 44px; + } +} + +@media screen and (max-width: @screen-lg) { + .extraContent { + margin-left: 20px; + } +} + +@media screen and (max-width: @screen-md) { + .row { + display: block; + } + + .action, + .extraContent { + margin-left: 0; + text-align: left; + } +} + +@media screen and (max-width: @screen-sm) { + .detail { + display: block; } } diff --git a/Workplace/src/components/PageHeaderWrapper/index.tsx b/Workplace/src/components/PageHeaderWrapper/index.tsx new file mode 100644 index 0000000000000000000000000000000000000000..ef6422dae72dd08c3acf6d1b2315deedb2ae3ffb --- /dev/null +++ b/Workplace/src/components/PageHeaderWrapper/index.tsx @@ -0,0 +1,47 @@ +import React from 'react'; +import { RouteContext } from '@ant-design/pro-layout'; +import { PageHeader, Typography } from 'antd'; +import styles from './index.less'; +import { GridContent } from '@ant-design/pro-layout'; + +interface IPageHeaderWrapperProps { + content?: React.ReactNode; + title?: React.ReactNode; + extraContent?: React.ReactNode; +} + +const PageHeaderWrapper: React.SFC = ({ + children, + content, + title, + extraContent, + ...restProps +}) => ( + + {value => ( +
+ +
+
+
+ {content &&
{content}
} + {extraContent &&
{extraContent}
} +
+
+
+
+ {children ? ( + +
{children}
+
+ ) : null} +
+ )} +
+); + +export default PageHeaderWrapper; diff --git a/Workplace/src/components/Radar/autoHeight.tsx b/Workplace/src/components/Radar/autoHeight.tsx new file mode 100644 index 0000000000000000000000000000000000000000..aa25500027388d713c0cc4e9f19a087810646f8a --- /dev/null +++ b/Workplace/src/components/Radar/autoHeight.tsx @@ -0,0 +1,75 @@ +import React from 'react'; + +export type IReactComponent

= + | React.StatelessComponent

+ | React.ComponentClass

+ | React.ClassicComponentClass

; + +function computeHeight(node: HTMLDivElement) { + node.style.height = '100%'; + const totalHeight = parseInt(getComputedStyle(node).height + '', 10); + const padding = + parseInt(getComputedStyle(node).paddingTop + '', 10) + + parseInt(getComputedStyle(node).paddingBottom + '', 10); + return totalHeight - padding; +} + +function getAutoHeight(n: HTMLDivElement) { + if (!n) { + return 0; + } + + let node = n; + + let height = computeHeight(node); + const parentNode = node.parentNode as HTMLDivElement; + if (parentNode) { + height = computeHeight(parentNode); + } + + return height; +} + +interface IAutoHeightProps { + height?: number; +} + +function autoHeight() { + return function

( + WrappedComponent: React.ComponentClass

| React.SFC

+ ): React.ComponentClass

{ + class AutoHeightComponent extends React.Component

{ + state = { + computedHeight: 0, + }; + root!: HTMLDivElement; + componentDidMount() { + const { height } = this.props; + if (!height) { + const h = getAutoHeight(this.root); + // eslint-disable-next-line + this.setState({ computedHeight: h }); + if (h < 1) { + const h = getAutoHeight(this.root); + this.setState({ computedHeight: h }); + } + } + } + handleRoot = (node: HTMLDivElement) => { + this.root = node; + }; + render() { + const { height } = this.props; + const { computedHeight } = this.state; + const h = height || computedHeight; + return ( +

+ {h > 0 && } +
+ ); + } + } + return AutoHeightComponent; + }; +} +export default autoHeight; diff --git a/Analysis/src/components/Charts/Radar/index.less b/Workplace/src/components/Radar/index.less similarity index 100% rename from Analysis/src/components/Charts/Radar/index.less rename to Workplace/src/components/Radar/index.less diff --git a/Analysis/src/components/Charts/Radar/index.tsx b/Workplace/src/components/Radar/index.tsx similarity index 97% rename from Analysis/src/components/Charts/Radar/index.tsx rename to Workplace/src/components/Radar/index.tsx index ab79250db217fc03c9f21a6b694c1a15edaf9813..555da2da57a93a26f7fb9e64113b8f98e60f5529 100644 --- a/Analysis/src/components/Charts/Radar/index.tsx +++ b/Workplace/src/components/Radar/index.tsx @@ -1,7 +1,7 @@ import React, { Component } from 'react'; -import { Chart, G2, Tooltip, Geom, Coord, Axis } from 'bizcharts'; +import { Chart, Tooltip, Geom, Coord, Axis } from 'bizcharts'; import { Row, Col } from 'antd'; -import autoHeight from '../autoHeight'; +import autoHeight from './autoHeight'; import styles from './index.less'; export interface IRadarProps { diff --git a/Workplace/src/data.d.ts b/Workplace/src/data.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..36514554b311ab6b2f51fc68c5715d4559bf9f74 --- /dev/null +++ b/Workplace/src/data.d.ts @@ -0,0 +1,78 @@ +export interface ITag { + key: string; + label: string; +} + +export interface Province { + label: string; + key: string; +} + +export interface City { + label: string; + key: string; +} + +export interface Geographic { + province: Province; + city: City; +} + +export interface Notice { + id: string; + title: string; + logo: string; + description: string; + updatedAt: string; + member: string; + href: string; + memberLink: string; +} + +export interface CurrentUser { + name: string; + avatar: string; + userid: string; + notice: Notice[]; + email: string; + signature: string; + title: string; + group: string; + tags: ITag[]; + notifyCount: number; + unreadCount: number; + country: string; + geographic: Geographic; + address: string; + phone: string; +} + +export interface Member { + avatar: string; + name: string; + id: string; +} + +export interface Activeties { + id: string, + updatedAt: string, + user: { + name: string, + avatar: string, + }, + group: { + name: string, + link: string, + }, + project: { + name: string, + link: string, + }, + template: string, +} + +export interface RadarData { + label: string; + name: string; + value: number; +} diff --git a/Workplace/src/index.js b/Workplace/src/index.tsx similarity index 87% rename from Workplace/src/index.js rename to Workplace/src/index.tsx index 91cd597c79a3b117bf3c9c8e481dd70745b7eb27..5eb1d9867c7167eb9b283a1c31d96ebe86361e92 100644 --- a/Workplace/src/index.js +++ b/Workplace/src/index.tsx @@ -3,15 +3,17 @@ import moment from 'moment'; import { connect } from 'dva'; import Link from 'umi/link'; import { Row, Col, Card, List, Avatar } from 'antd'; +import { Dispatch } from 'redux'; + -import { Charts } from 'ant-design-pro'; import EditableLinkGroup from './components/EditableLinkGroup'; import PageHeaderWrapper from './components/PageHeaderWrapper'; +import Radar from './components/Radar'; +import { ModalState } from './model'; +import { CurrentUser, Activeties, RadarData, Notice } from './data'; import styles from './style.less'; -const { Radar } = Charts; - const links = [ { title: '操作一', @@ -39,16 +41,33 @@ const links = [ }, ]; -@connect(({ BLOCK_NAME_CAMEL_CASE: { user, project, activities, chart }, loading }) => ({ - currentUser: user.currentUser, - project, +interface BLOCK_NAME_CAMEL_CASEProps { + currentUser: CurrentUser; + projectNotice: Notice[]; + activities: Activeties[]; + radarData: RadarData[]; + dispatch: Dispatch; + currentUserLoading: boolean; + projectLoading: boolean; + activitiesLoading: boolean; +} + +@connect(({ + BLOCK_NAME_CAMEL_CASE: { currentUser, projectNotice, activities, radarData }, + loading, +}: { + BLOCK_NAME_CAMEL_CASE: ModalState, + loading: { effects: any }, +}) => ({ + currentUser, + projectNotice, activities, - chart, + radarData, currentUserLoading: loading.effects['BLOCK_NAME_CAMEL_CASE/fetchUserCurrent'], projectLoading: loading.effects['BLOCK_NAME_CAMEL_CASE/fetchProjectNotice'], activitiesLoading: loading.effects['BLOCK_NAME_CAMEL_CASE/fetchActivitiesList'], })) -class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent { +class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent { componentDidMount() { const { dispatch } = this.props; dispatch({ @@ -65,9 +84,9 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent { renderActivities() { const { - activities: { list }, + activities, } = this.props; - return list.map(item => { + return activities.map(item => { const events = item.template.split(/@\{([^{}]*)\}/gi).map(key => { if (item[key]) { return ( @@ -103,11 +122,10 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent { render() { const { currentUser, - currentUserLoading, - project: { notice }, + projectNotice, projectLoading, activitiesLoading, - chart: { radarData }, + radarData, } = this.props; const pageHeaderContent = @@ -150,7 +168,6 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent { return ( @@ -165,7 +182,7 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent { loading={projectLoading} bodyStyle={{ padding: 0 }} > - {notice.map(item => ( + {projectNotice.map(item => (
- {notice.map(item => ( + {projectNotice.map(item => ( diff --git a/Workplace/src/model.js b/Workplace/src/model.js deleted file mode 100644 index 0d19862f7f74bed3115b92e6413ff2ad2825aec9..0000000000000000000000000000000000000000 --- a/Workplace/src/model.js +++ /dev/null @@ -1,116 +0,0 @@ -import { queryCurrent, queryProjectNotice, queryActivities, fakeChartData } from './service'; - -export default { - namespace: 'BLOCK_NAME_CAMEL_CASE', - state: { - user: { - currentUser: {}, - }, - project: { - notice: [], - }, - activities: { - list: [], - }, - chart: { - visitData: [], - visitData2: [], - salesData: [], - searchData: [], - offlineData: [], - offlineChartData: [], - salesTypeData: [], - salesTypeDataOnline: [], - salesTypeDataOffline: [], - radarData: [], - loading: false, - }, - }, - reducers: { - saveCurrentUser(state, action) { - return { - ...state, - user: { - currentUser: action.payload || {}, - }, - }; - }, - saveNotice(state, action) { - return { - ...state, - project: { - notice: action.payload, - }, - }; - }, - saveList(state, action) { - return { - ...state, - activities: { - list: action.payload, - }, - }; - }, - saveChart(state, { payload }) { - return { - ...state, - chart: { - ...payload, - }, - }; - }, - clear(state) { - return { - ...state, - chart: { - visitData: [], - visitData2: [], - salesData: [], - searchData: [], - offlineData: [], - offlineChartData: [], - salesTypeData: [], - salesTypeDataOnline: [], - salesTypeDataOffline: [], - radarData: [], - }, - }; - }, - }, - effects: { - *init(_, { put }) { - yield put({ type: 'fetchUserCurrent' }); - yield put({ type: 'fetchProjectNotice' }); - yield put({ type: 'fetchActivitiesList' }); - yield put({ type: 'fetchChart' }); - }, - *fetchUserCurrent(_, { call, put }) { - const response = yield call(queryCurrent); - yield put({ - type: 'saveCurrentUser', - payload: response, - }); - }, - *fetchProjectNotice(_, { call, put }) { - const response = yield call(queryProjectNotice); - yield put({ - type: 'saveNotice', - payload: Array.isArray(response) ? response : [], - }); - }, - *fetchActivitiesList(_, { call, put }) { - const response = yield call(queryActivities); - yield put({ - type: 'saveList', - payload: Array.isArray(response) ? response : [], - }); - }, - *fetchChart(_, { call, put }) { - const response = yield call(fakeChartData); - yield put({ - type: 'saveChart', - payload: response, - }); - }, - }, -}; diff --git a/Workplace/src/model.ts b/Workplace/src/model.ts new file mode 100644 index 0000000000000000000000000000000000000000..89ecbf29e0dea16730658332f097a5d620c1ee6a --- /dev/null +++ b/Workplace/src/model.ts @@ -0,0 +1,104 @@ +import { EffectsCommandMap } from 'dva'; +import { Reducer, AnyAction } from 'redux'; +import { queryCurrent, queryProjectNotice, queryActivities, fakeChartData } from './service'; +import { CurrentUser, Notice, Activeties, RadarData } from './data'; + +export interface ModalState { + currentUser: Partial; + projectNotice: Notice[]; + activities: Activeties[]; + radarData: RadarData[]; +} + +export type Effect = ( + action: AnyAction, + effects: EffectsCommandMap & { select: (func: (state: ModalState) => T) => T } +) => void; + +export interface ModelType { + namespace: string; + state: ModalState; + reducers: { + save: Reducer; + clear: Reducer; + }; + effects: { + init: Effect; + fetchUserCurrent: Effect; + fetchProjectNotice: Effect; + fetchActivitiesList: Effect; + fetchChart: Effect; + }; +} + +const Model: ModelType = { + namespace: 'BLOCK_NAME_CAMEL_CASE', + state: { + currentUser: {}, + projectNotice: [], + activities: [], + radarData: [], + }, + effects: { + *init(_, { put }) { + yield put({ type: 'fetchUserCurrent' }); + yield put({ type: 'fetchProjectNotice' }); + yield put({ type: 'fetchActivitiesList' }); + yield put({ type: 'fetchChart' }); + }, + *fetchUserCurrent(_, { call, put }) { + const response = yield call(queryCurrent); + yield put({ + type: 'save', + payload: { + currentUser: response, + }, + }); + }, + *fetchProjectNotice(_, { call, put }) { + const response = yield call(queryProjectNotice); + yield put({ + type: 'save', + payload: { + projectNotice: Array.isArray(response) ? response : [], + } + }); + }, + *fetchActivitiesList(_, { call, put }) { + const response = yield call(queryActivities); + yield put({ + type: 'save', + payload: { + activities: Array.isArray(response) ? response : [], + } + }); + }, + *fetchChart(_, { call, put }) { + const { radarData } = yield call(fakeChartData); + yield put({ + type: 'save', + payload: { + radarData, + }, + }); + }, + }, + reducers: { + save(state, { payload }) { + return { + ...state, + ...payload, + }; + }, + clear() { + return { + currentUser: {}, + projectNotice: [], + activities: [], + radarData: [], + }; + }, + }, +}; + +export default Model; diff --git a/Workplace/src/service.js b/Workplace/src/service.ts similarity index 100% rename from Workplace/src/service.js rename to Workplace/src/service.ts