| | |
| | | {this.props.editLevel === 'HS' ? <Button className="level4-close" type="primary" onClick={this.exitManage}>退出</Button> : null} |
| | | {/* 进入编辑按钮 */} |
| | | {this.props.editState && !this.props.editLevel ? <Icon onClick={this.enterEdit} className="edit-check" type="edit" /> : null} |
| | | {/* {this.props.editState && !this.props.editLevel && options.sysType === 'local' && window.GLOB.systemType !== 'production' ? |
| | | {this.props.editState && !this.props.editLevel && options.sysType === 'local' && window.GLOB.systemType !== 'production' ? |
| | | <a href="#/mobmanage" target="_blank" className="mobile" type="edit"> 应用管理 <Icon type="arrow-right" /></a> : null |
| | | } */} |
| | | } |
| | | {/* window.btoa(window.encodeURIComponent(JSON.stringify({ MenuType: 'home', MenuId: 'home_page_id', MenuName: '首页' }))) */} |
| | | {this.props.editState && !this.props.editLevel && window.GLOB.systemType !== 'production' ? |
| | | <a className="home-edit" href={`#/menudesign/JTdCJTIyTWVudVR5cGUlMjIlM0ElMjJob21lJTIyJTJDJTIyTWVudUlkJTIyJTNBJTIyaG9tZV9wYWdlX2lkJTIyJTJDJTIyTWVudU5hbWUlMjIlM0ElMjIlRTklQTYlOTYlRTklQTElQjUlMjIlN0Q=`} target="_blank" rel="noopener noreferrer"> |
| | | 首页 <Icon type="arrow-right" /> |
| | | </a> : null |
| | | } |
| | | {/* 编辑菜单 */} |
| | | {this.props.editLevel === 'level1' ? <EditMenu menulist={this.state.menulist} reload={this.reload} exitEdit={this.exitEdit}/> : null} |
| | | {/* 头像、用户名 */} |
| | |
| | | padding: 0px 25px; |
| | | height: 26px; |
| | | line-height: 26px; |
| | | color: #000000; |
| | | color: rgba(0, 0, 0, 0.85); |
| | | cursor: pointer; |
| | | } |
| | | .ant-menu-item:hover { |
| | |
| | | } |
| | | .mobile { |
| | | position: absolute; |
| | | top: 135px; |
| | | right: 50px; |
| | | color: #1890ff; |
| | | } |
| | | .home-edit { |
| | | position: absolute; |
| | | top: 100px; |
| | | right: 50px; |
| | | color: #1890ff; |
| | |
| | | |
| | | componentDidMount () { |
| | | let home = { |
| | | MenuID: '1576117946681plembmkk9akkv8sn0vtdfdsfaf', |
| | | MenuID: 'home_page_id', |
| | | MenuName: '首页', |
| | | MenuNo: 'MESOrderDetailMwe', |
| | | PageParam: {}, |
| | | id: 1, |
| | | selected: true, |
| | | src: '', |
| | | text: '首页', |
| | | type: 'Home' |
| | | } |
| | | this.props.modifyTabview([home]) |
| | |
| | | key={view.MenuID} |
| | | > |
| | | {this.selectcomponent(view)} |
| | | {options.sysType !== 'cloud' && menuType !== 'HS' && !['CommonTable', 'TreePage', 'ManageTable', 'CalendarPage'].includes(view.type) ? |
| | | {options.sysType !== 'cloud' && menuType !== 'HS' && !['CommonTable', 'TreePage', 'ManageTable', 'CalendarPage', 'Home'].includes(view.type) ? |
| | | <Button |
| | | icon="copy" |
| | | shape="circle" |
| | |
| | | position: relative; |
| | | box-sizing: border-box; |
| | | background: #ffffff; |
| | | background-position: center center; |
| | | background-repeat: no-repeat; |
| | | background-size: cover; |
| | | border-style: solid; |
| | | border-width: 0; |
| | | |
| | |
| | | * @param {Array} columns // 显示列 |
| | | */ |
| | | export function getPieChartOptionForm (card, columns) { |
| | | |
| | | let xfields = columns.filter(item => /^Nvarchar/ig.test(item.datatype)) |
| | | let yfields = columns.filter(item => /^(Int|Decimal)/ig.test(item.datatype)) |
| | | |
| | |
| | | } |
| | | return item |
| | | }) |
| | | }, () => { |
| | | if (val === 'ring') { |
| | | this.props.form.setFieldsValue({innerRadius: 50}) |
| | | } else if (val === 'nightingale') { |
| | | this.props.form.setFieldsValue({innerRadius: 0}) |
| | | } |
| | | }) |
| | | } |
| | | } |
| | |
| | | shape: card.subtype, // 图表类型 |
| | | width: 12, |
| | | height: 400, |
| | | label: 'outer', |
| | | name: card.name |
| | | } |
| | | |
| | | if (card.subtype === 'ring') { |
| | | _plot.innerRadius = 50 |
| | | } |
| | | |
| | | let dataName = '' |
| | |
| | | pierender = () => { |
| | | const { card } = this.state |
| | | let plot = {...card.plot, height: card.plot.height - 80} |
| | | // let color = plot.color || 'rgba(0, 0, 0, 0.85)' |
| | | let color = plot.color || 'rgba(0, 0, 0, 0.85)' |
| | | |
| | | let transfield = {} |
| | | card.columns.forEach(col => { |
| | | if (col.field) { |
| | | transfield[col.field] = col.label |
| | | } |
| | | }) |
| | | let X_axis = plot.Xaxis || 'x' |
| | | let Y_axis = plot.Yaxis || 'y' |
| | | |
| | |
| | | if (plot.shape === 'nightingale') { |
| | | chart.coordinate('polar', { |
| | | innerRadius: plot.innerRadius ? (plot.innerRadius / 100) : 0, |
| | | radius: plot.radius ? (plot.radius / 100) : 0.75, |
| | | radius: plot.radius ? (plot.radius / 100) : 0.85, |
| | | }) |
| | | } else { |
| | | chart.coordinate('theta', { |
| | | innerRadius: plot.shape !== 'pie' && plot.innerRadius ? (plot.innerRadius / 100) : 0, |
| | | radius: plot.radius ? (plot.radius / 100) : 0.75, |
| | | radius: plot.radius ? (plot.radius / 100) : 0.85, |
| | | }) |
| | | } |
| | | |
| | |
| | | } else if (plot.shape === 'nightingale') { |
| | | chart.legend(X_axis, { |
| | | position: plot.legend, |
| | | itemName: { |
| | | style: { |
| | | fill: color, |
| | | } |
| | | } |
| | | }) |
| | | } else { |
| | | chart.legend({ |
| | | position: plot.legend |
| | | position: plot.legend, |
| | | itemName: { |
| | | style: { |
| | | fill: color, |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | |
| | | style: { |
| | | lineWidth: 0.5, |
| | | }, |
| | | }, |
| | | style: { |
| | | fill: color |
| | | } |
| | | }) |
| | | } |
| | |
| | | if (plot.label !== 'false') { |
| | | let _label = {} |
| | | if (plot.label === 'inner') { |
| | | _label = { |
| | | offset: -15, |
| | | _label.offset = -15 |
| | | } else { |
| | | _label.style = { |
| | | fill: color |
| | | } |
| | | } |
| | | |
| | |
| | | position: relative; |
| | | box-sizing: border-box; |
| | | background: #ffffff; |
| | | background-position: center center; |
| | | background-repeat: no-repeat; |
| | | background-size: cover; |
| | | border-style: solid; |
| | | border-width: 0; |
| | | |
| | |
| | | position: relative; |
| | | box-sizing: border-box; |
| | | background: #ffffff; |
| | | background-position: center center; |
| | | background-repeat: no-repeat; |
| | | background-size: cover; |
| | | border-style: solid; |
| | | border-width: 0; |
| | | |
| | |
| | | const presetColors = [ |
| | | '#f5222d', '#fa541c', '#fa8c16', '#faad14', '#fadb14', '#a0d911', '#52c41a', '#13c2c2', '#1890ff', '#2f54eb', '#722ed1', |
| | | '#eb2f96', '#595959', '#ffa39e', '#ffbb96', '#ffd591', '#ffe58f', '#fffb8f', '#eaff8f', '#b7eb8f', '#87e8de', '#91d5ff', |
| | | '#adc6ff', '#d3adf7', '#ffadd2', '#d9d9d9', '#000000', '#ffffff', 'transparent' |
| | | '#adc6ff', '#d3adf7', '#ffadd2', '#d9d9d9', '#434343', '#000000', '#ffffff', 'transparent' |
| | | ] |
| | | |
| | | class ColorSketch extends Component { |
| | |
| | | {path: '/main', name: 'main', component: Main, auth: true}, |
| | | {path: '/mobmanage', name: 'mobmanage', component: MobManage, auth: true}, |
| | | {path: '/mobdesign/:appId/:appType/:appCode/:appName', name: 'mobdesign', component: MobDesign, auth: true}, |
| | | {path: '/menudesign/:MenuId/:ParentId/:MenuName/:MenuNo', name: 'menudesign', component: MenuDesign, auth: true}, |
| | | {path: '/menudesign/:param', name: 'menudesign', component: MenuDesign, auth: true}, |
| | | {path: '/paramsmain/:param', name: 'pmain', component: Main, auth: true} |
| | | ] |
| | | |
| | |
| | | state.tabviews = [] |
| | | } else { |
| | | state.tabviews = [{ |
| | | MenuID: '1576117946681plembmkk9akkv8sn0vtdfdsfaf', |
| | | MenuID: 'home_page_id', |
| | | MenuName: '首页', |
| | | MenuNo: 'MESOrderDetailMwe', |
| | | selected: true, |
| | | text: '首页', |
| | | type: 'Home' |
| | | }] |
| | | } |
| | |
| | | .custom-card-box { |
| | | background: #ffffff; |
| | | background-position: center center; |
| | | background-repeat: no-repeat; |
| | | background-size: cover; |
| | | min-height: 100px; |
| | | display: flex; |
| | | position: relative; |
| | |
| | | } |
| | | img { |
| | | width: 15px; |
| | | height: 100px; |
| | | padding: 0 2px; |
| | | height: 70px; |
| | | cursor: pointer; |
| | | } |
| | | } |
| | |
| | | _config.plot.height = _config.plot.height - 30 |
| | | } |
| | | |
| | | if (_config.style) { |
| | | _config.style = {..._config.style, minHeight: (config.plot.height || 400)} |
| | | } else { |
| | | _config.style = {minHeight: (config.plot.height || 400)} |
| | | } |
| | | |
| | | this.setState({ |
| | | config: _config, |
| | | data: _data, |
| | |
| | | .custom-line-chart-plot-box { |
| | | background: #ffffff; |
| | | background-position: center center; |
| | | background-repeat: no-repeat; |
| | | background-size: cover; |
| | | border-style: solid; |
| | | border-width: 0; |
| | | min-height: 100px; |
| | | |
| | | > .chart-header { |
| | | height: 45px; |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Chart } from '@antv/g2' |
| | | import DataSet from '@antv/data-set' |
| | | import { Spin, Empty, notification } from 'antd' |
| | | |
| | | // import searchLine from '../../share/searchLine' |
| | | import Api from '@/api' |
| | | import Utils from '@/utils/utils.js' |
| | | import UtilsDM from '@/utils/utils-datamanage.js' |
| | | import zhCN from '@/locales/zh-CN/main.js' |
| | | import enUS from '@/locales/en-US/main.js' |
| | | import './index.scss' |
| | | |
| | | class LineChart extends Component { |
| | | static propTpyes = { |
| | | BID: PropTypes.any, // 父级Id |
| | | data: PropTypes.array, // 统一查询数据 |
| | | config: PropTypes.object, // 组件配置信息 |
| | | mainSearch: PropTypes.any, // 全局搜索条件 |
| | | menuType: PropTypes.any, // 菜单类型 |
| | | dataManager: PropTypes.any, // 数据权限 |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, // 字典 |
| | | config: null, // 图表配置信息 |
| | | empty: true, // 图表数据为空 |
| | | loading: false, // 数据加载状态 |
| | | chartId: Utils.getuuid(), // 图表Id |
| | | title: '', // 组件标题 |
| | | sync: false, // 是否统一请求数据 |
| | | plot: null, // 图表设置 |
| | | data: null, // 数据 |
| | | search: null, // 搜索条件 |
| | | showHeader: false // 存在标题、搜索、或统计数据时显示 |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { config, data } = this.props |
| | | let _config = fromJS(config).toJS() |
| | | |
| | | let _data = null |
| | | let _sync = config.setting.sync === 'true' |
| | | |
| | | if (config.setting.sync === 'true' && data) { |
| | | _data = data[config.dataName] || [] |
| | | _sync = false |
| | | } |
| | | |
| | | let showHeader = false |
| | | if (config.plot.title || config.search.length > 0) { |
| | | showHeader = true |
| | | _config.plot.height = _config.plot.height - 80 |
| | | } else { |
| | | _config.plot.height = _config.plot.height - 30 |
| | | } |
| | | |
| | | if (_config.style) { |
| | | _config.style = {..._config.style, minHeight: (config.plot.height || 400)} |
| | | } else { |
| | | _config.style = {minHeight: (config.plot.height || 400)} |
| | | } |
| | | |
| | | this.setState({ |
| | | config: _config, |
| | | data: _data, |
| | | arr_field: _config.columns.map(col => col.field).join(','), |
| | | plot: _config.plot, |
| | | sync: _sync, |
| | | title: config.plot.title, |
| | | search: Utils.initMainSearch(config.search), |
| | | showHeader |
| | | }, () => { |
| | | if (config.setting.sync !== 'true') { |
| | | this.loadData() |
| | | } else if (config.setting.sync === 'true') { |
| | | if (!_data) { |
| | | this.setState({ |
| | | loading: true |
| | | }) |
| | | } else { |
| | | this.handleData() |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 校验图表的按钮组,如果为统计图表,计算图表字段 |
| | | */ |
| | | componentDidMount () { |
| | | |
| | | } |
| | | |
| | | /** |
| | | * @description 图表数据更新,刷新内容 |
| | | */ |
| | | UNSAFE_componentWillReceiveProps (nextProps) { |
| | | const { sync, config } = this.state |
| | | |
| | | if (sync && !is(fromJS(this.props.data), fromJS(nextProps.data))) { |
| | | let _data = [] |
| | | if (nextProps.data && nextProps.data[config.dataName]) { |
| | | _data = nextProps.data[config.dataName] || [] |
| | | } |
| | | |
| | | this.setState({sync: false, loading: false, data: _data}, () => { |
| | | this.handleData() |
| | | }) |
| | | } |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | handleData = () => { |
| | | let _element = document.getElementById(this.state.chartId) |
| | | if (_element) { |
| | | _element.innerHTML = '' |
| | | } |
| | | this.pierender() |
| | | } |
| | | |
| | | async loadData () { |
| | | const { mainSearch, BID, menuType, dataManager } = this.props |
| | | const { config, arr_field, search } = this.state |
| | | |
| | | let searches = fromJS(search).toJS() |
| | | if (mainSearch && mainSearch.length > 0) { // 主表搜索条件 |
| | | searches = [...mainSearch, ...searches] |
| | | } |
| | | |
| | | this.setState({ |
| | | loading: true |
| | | }) |
| | | |
| | | let _orderBy = config.setting.order || '' |
| | | let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, '', '', BID, menuType, dataManager) |
| | | |
| | | let result = await Api.genericInterface(param) |
| | | if (result.status) { |
| | | this.setState({ |
| | | data: result.data, |
| | | loading: false |
| | | }, () => { |
| | | this.handleData() |
| | | }) |
| | | } else { |
| | | this.setState({ |
| | | loading: false |
| | | }) |
| | | notification.error({ |
| | | top: 92, |
| | | message: result.message, |
| | | duration: 10 |
| | | }) |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @description 图表数据预处理 |
| | | * 1、通过显示列进行数据类型转换 |
| | | * 2、重复数据:取平均值、累计、去重 |
| | | * 3、柱状图数据补齐 |
| | | */ |
| | | getdata = () => { |
| | | const { data, plot, config } = this.state |
| | | |
| | | if (!data) { |
| | | this.setState({empty: true}) |
| | | return [] |
| | | } |
| | | |
| | | let decimal = 0 |
| | | config.columns.forEach(col => { |
| | | if (plot.Yaxis === col.field && /Decimal/ig.test(col.datatype)) { |
| | | decimal = +col.datatype.replace(/^Decimal\(18,/ig, '').replace(/\)/ig, '') |
| | | } |
| | | }) |
| | | |
| | | let _data = [] |
| | | let _cdata = fromJS(data).toJS() |
| | | |
| | | if (plot.repeat === 'average') { |
| | | let _mdata = new Map() |
| | | _cdata.forEach(item => { |
| | | if (typeof(item[plot.Yaxis]) !== 'number') { |
| | | item[plot.Yaxis] = parseFloat(item[plot.Yaxis]) |
| | | if (isNaN(item[plot.Yaxis])) { |
| | | item[plot.Yaxis] = 0 |
| | | } |
| | | } |
| | | |
| | | if (item[plot.Xaxis] && !_mdata.has(item[plot.Xaxis])) { |
| | | item.$count = 1 |
| | | _mdata.set(item[plot.Xaxis], item) |
| | | } else if (item[plot.Xaxis]) { |
| | | let _item = _mdata.get(item[plot.Xaxis]) |
| | | _item.$count++ |
| | | _item[plot.Yaxis] += item[plot.Yaxis] |
| | | _mdata.set(item[plot.Xaxis], _item) |
| | | } |
| | | }) |
| | | |
| | | _data = [..._mdata.values()] |
| | | _data = _data.map(item => { |
| | | item[plot.Yaxis] = item[plot.Yaxis] / item.$count |
| | | item[plot.Yaxis] = item[plot.Yaxis].toFixed(decimal) |
| | | item[plot.Yaxis] = +item[plot.Yaxis] |
| | | |
| | | return item |
| | | }) |
| | | } else if (plot.repeat === 'cumsum') { |
| | | let _mdata = new Map() |
| | | _cdata.forEach(item => { |
| | | if (typeof(item[plot.Yaxis]) !== 'number') { |
| | | item[plot.Yaxis] = parseFloat(item[plot.Yaxis]) |
| | | if (isNaN(item[plot.Yaxis])) { |
| | | item[plot.Yaxis] = 0 |
| | | } |
| | | } |
| | | |
| | | if (item[plot.Xaxis] && !_mdata.has(item[plot.Xaxis])) { |
| | | _mdata.set(item[plot.Xaxis], item) |
| | | } else if (item[plot.Xaxis]) { |
| | | let _item = _mdata.get(item[plot.Xaxis]) |
| | | _item[plot.Yaxis] += item[plot.Yaxis] |
| | | _mdata.set(item[plot.Xaxis], _item) |
| | | } |
| | | }) |
| | | |
| | | _data = [..._mdata.values()] |
| | | _data = _data.map(item => { |
| | | item[plot.Yaxis] = item[plot.Yaxis].toFixed(decimal) |
| | | item[plot.Yaxis] = +item[plot.Yaxis] |
| | | return item |
| | | }) |
| | | } else { // plot.repeat === 'unrepeat' |
| | | let _mdata = new Map() |
| | | _cdata.forEach(item => { |
| | | if (item[plot.Xaxis] && !_mdata.has(item[plot.Xaxis])) { |
| | | if (typeof(item[plot.Yaxis]) !== 'number') { |
| | | item[plot.Yaxis] = parseFloat(item[plot.Yaxis]) |
| | | if (isNaN(item[plot.Yaxis])) { |
| | | item[plot.Yaxis] = 0 |
| | | } |
| | | } |
| | | |
| | | item[plot.Yaxis] = item[plot.Yaxis].toFixed(decimal) |
| | | item[plot.Yaxis] = +item[plot.Yaxis] |
| | | |
| | | _mdata.set(item[plot.Xaxis], item) |
| | | } |
| | | }) |
| | | |
| | | _data = [..._mdata.values()] |
| | | } |
| | | |
| | | this.setState({empty: _data.length === 0}) |
| | | return _data |
| | | } |
| | | |
| | | /** |
| | | * @description 饼图渲染 |
| | | */ |
| | | pierender = () => { |
| | | const { plot, chartId } = this.state |
| | | let color = plot.color || 'rgba(0, 0, 0, 0.85)' |
| | | |
| | | let X_axis = plot.Xaxis || 'x' |
| | | let Y_axis = plot.Yaxis || 'y' |
| | | |
| | | let data = this.getdata(X_axis, Y_axis) |
| | | |
| | | const ds = new DataSet() |
| | | const dv = ds.createView().source(data) |
| | | |
| | | const chart = new Chart({ |
| | | container: chartId, |
| | | autoFit: true, |
| | | height: plot.height || 400 |
| | | }) |
| | | |
| | | if (plot.shape !== 'nightingale' && plot.show !== 'value') { |
| | | dv.transform({ |
| | | type: 'percent', |
| | | field: Y_axis, |
| | | dimension: X_axis, |
| | | as: 'percent' |
| | | }) |
| | | |
| | | chart.scale('percent', { |
| | | formatter: (val) => { |
| | | val = val * 100 + '%' |
| | | return val |
| | | } |
| | | }) |
| | | |
| | | Y_axis = 'percent' // 显示百分比 |
| | | } |
| | | chart.data(dv.rows) |
| | | |
| | | if (plot.shape === 'nightingale') { |
| | | chart.coordinate('polar', { |
| | | innerRadius: plot.innerRadius ? (plot.innerRadius / 100) : 0, |
| | | radius: plot.radius ? (plot.radius / 100) : 0.75, |
| | | }) |
| | | } else { |
| | | chart.coordinate('theta', { |
| | | innerRadius: plot.shape !== 'pie' && plot.innerRadius ? (plot.innerRadius / 100) : 0, |
| | | radius: plot.radius ? (plot.radius / 100) : 0.75, |
| | | }) |
| | | } |
| | | |
| | | if (!plot.legend || plot.legend === 'hidden') { |
| | | chart.legend(false) |
| | | } else if (plot.shape === 'nightingale') { |
| | | chart.legend(X_axis, { |
| | | position: plot.legend, |
| | | itemName: { |
| | | style: { |
| | | fill: color, |
| | | } |
| | | } |
| | | }) |
| | | } else { |
| | | chart.legend({ |
| | | position: plot.legend, |
| | | itemName: { |
| | | style: { |
| | | fill: color, |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | if (plot.tooltip !== 'true') { |
| | | chart.tooltip(false) |
| | | } else { |
| | | chart.tooltip({ |
| | | showTitle: false, |
| | | showMarkers: false |
| | | }) |
| | | } |
| | | |
| | | if (plot.shape !== 'nightingale') { |
| | | let _chart = chart |
| | | .interval() |
| | | .adjust('stack') |
| | | .position(Y_axis) |
| | | .color(X_axis) |
| | | .tooltip(`${X_axis}*${Y_axis}`, (name, value) => { |
| | | if (plot.show !== 'value') { |
| | | value = (value * 100).toFixed(2) + '%' |
| | | } |
| | | return { |
| | | name: name, |
| | | value: value |
| | | } |
| | | }) |
| | | if (plot.label !== 'false') { |
| | | if (plot.label === 'inner') { |
| | | _chart.label(Y_axis, { |
| | | offset: -30, |
| | | content: (data) => { |
| | | let _label = '' |
| | | let _val = '' |
| | | if (plot.show !== 'value') { |
| | | _val = `${(data[Y_axis] * 100).toFixed(2)}%` |
| | | } else { |
| | | _val = `${data[Y_axis]}` |
| | | } |
| | | if (plot.label === 'inner') { |
| | | _label = _val |
| | | } else { |
| | | _label = `${data[X_axis]}: ${_val}` |
| | | } |
| | | return _label |
| | | }, |
| | | style: { |
| | | textAlign: 'center', |
| | | fontSize: 16, |
| | | shadowBlur: 2, |
| | | shadowColor: 'rgba(0, 0, 0, .45)', |
| | | fill: '#fff', |
| | | } |
| | | }) |
| | | } else { |
| | | _chart.label(Y_axis, { |
| | | layout: { type: 'pie-spider' }, |
| | | labelHeight: 20, |
| | | content: (data) => { |
| | | let _label = '' |
| | | let _val = '' |
| | | if (plot.show !== 'value') { |
| | | _val = `${(data[Y_axis] * 100).toFixed(2)}%` |
| | | } else { |
| | | _val = `${data[Y_axis]}` |
| | | } |
| | | if (plot.label === 'inner') { |
| | | _label = _val |
| | | } else { |
| | | _label = `${data[X_axis]}: ${_val}` |
| | | } |
| | | return _label |
| | | }, |
| | | labelLine: { |
| | | style: { |
| | | lineWidth: 0.5, |
| | | }, |
| | | }, |
| | | style: { |
| | | fill: color |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | chart.interaction('element-active') |
| | | } else { |
| | | chart.axis(false) |
| | | chart.interaction('element-highlight') |
| | | let _chart = chart |
| | | .interval() |
| | | .position(`${X_axis}*${Y_axis}`) |
| | | .color(X_axis) |
| | | |
| | | if (plot.label !== 'false') { |
| | | let _label = {} |
| | | if (plot.label === 'inner') { |
| | | _label.offset = -15 |
| | | } else { |
| | | _label.style = { |
| | | fill: color |
| | | } |
| | | } |
| | | |
| | | _chart.label(X_axis, _label) |
| | | .style({ |
| | | lineWidth: 1, |
| | | stroke: '#fff', |
| | | }) |
| | | } |
| | | } |
| | | |
| | | chart.render() |
| | | } |
| | | |
| | | render() { |
| | | const { showHeader, config, loading, title, empty } = this.state |
| | | |
| | | return ( |
| | | <div className="custom-pie-chart-plot-box" style={config.style}> |
| | | {loading ? |
| | | <div className="loading-mask"> |
| | | <div className="ant-spin-blur"></div> |
| | | <Spin /> |
| | | </div> : null |
| | | } |
| | | {showHeader ? <div className="chart-header"> |
| | | <span className="chart-title">{title}</span> |
| | | {/* <searchLine /> */} |
| | | </div> : null} |
| | | <div className="canvas-wrap"> |
| | | <div className={'canvas' + (empty ? ' empty' : '')} id={this.state.chartId}></div> |
| | | </div> |
| | | {empty ? <Empty description={false}/> : null} |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default LineChart |
New file |
| | |
| | | .custom-pie-chart-plot-box { |
| | | background: #ffffff; |
| | | background-position: center center; |
| | | background-repeat: no-repeat; |
| | | background-size: cover; |
| | | border-style: solid; |
| | | border-width: 0; |
| | | min-height: 100px; |
| | | |
| | | > .chart-header { |
| | | height: 45px; |
| | | border-bottom: 1px solid #e8e8e8; |
| | | overflow: hidden; |
| | | text-decoration: inherit; |
| | | font-weight: inherit; |
| | | font-style: inherit; |
| | | |
| | | .chart-title { |
| | | // font-size: 16px; |
| | | float: left; |
| | | line-height: 45px; |
| | | margin-left: 10px; |
| | | text-decoration: inherit; |
| | | font-weight: inherit; |
| | | font-style: inherit; |
| | | } |
| | | } |
| | | |
| | | .canvas-wrap { |
| | | margin: 0 0px; |
| | | position: relative; |
| | | .chart-action { |
| | | position: absolute; |
| | | top: 2px; |
| | | right: 5px; |
| | | z-index: 1; |
| | | } |
| | | .chart-action.with-title { |
| | | top: 35px; |
| | | } |
| | | } |
| | | |
| | | .canvas { |
| | | margin: 0; |
| | | // border: 1px solid #e8e8e8; |
| | | padding: 15px; |
| | | letter-spacing: 0px; |
| | | } |
| | | .canvas.empty { |
| | | div { |
| | | opacity: 0; |
| | | } |
| | | } |
| | | .ant-empty { |
| | | position: absolute; |
| | | top: calc(50% - 34px); |
| | | left: calc(50% - 92px); |
| | | |
| | | .ant-empty-image { |
| | | height: 60px; |
| | | } |
| | | } |
| | | .loading-mask { |
| | | position: absolute; |
| | | left: 20px; |
| | | top: 0; |
| | | right: 20px; |
| | | bottom: 30px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | text-align: justify; |
| | | z-index: 1; |
| | | |
| | | .ant-spin-blur { |
| | | position: absolute; |
| | | width: 100%; |
| | | height: 100%; |
| | | opacity: 0.5; |
| | | background: #ffffff; |
| | | } |
| | | } |
| | | .chart-title + .loading-mask { |
| | | top: 40px; |
| | | } |
| | | > .ant-select { |
| | | width: 150px; |
| | | float: right; |
| | | position: relative; |
| | | z-index: 1; |
| | | .ant-select-selection { |
| | | min-height: 24px; |
| | | height: 28px; |
| | | li { |
| | | background: unset; |
| | | border: 0; |
| | | width: 99%; |
| | | padding: 0; |
| | | margin-right: 0; |
| | | cursor: pointer; |
| | | |
| | | .type-label { |
| | | overflow: hidden; |
| | | word-break: break-word; |
| | | white-space: nowrap; |
| | | text-overflow: ellipsis; |
| | | } |
| | | } |
| | | li + li { |
| | | margin-top: 0; |
| | | width: 1%; |
| | | opacity: 0; |
| | | } |
| | | } |
| | | } |
| | | > .ant-select.ant-select-focused { |
| | | .ant-select-selection { |
| | | li { |
| | | width: 50%; |
| | | } |
| | | li + li { |
| | | width: 49%; |
| | | opacity: 1; |
| | | } |
| | | } |
| | | } |
| | | .g2-tooltip-list{ |
| | | display: none; |
| | | } |
| | | .g2-tooltip-title + .g2-tooltip-list{ |
| | | display: block; |
| | | } |
| | | } |
| | |
| | | |
| | | // 通用组件 |
| | | const AntvBarAndLine = asyncSpinComponent(() => import('@/tabviews/custom/components/chart/antv-bar-line')) |
| | | const AntvPie = asyncSpinComponent(() => import('@/tabviews/custom/components/chart/antv-pie')) |
| | | const AntvTabs = asyncSpinComponent(() => import('@/tabviews/custom/components/tabs/antv-tabs')) |
| | | |
| | | class MainSearch extends Component { |
| | |
| | | <AntvBarAndLine config={item} BID={BID} mainSearch={mainSearch} menuType={menuType} dataManager={dataManager} /> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'pie') { |
| | | return ( |
| | | <Col span={item.width} key={item.uuid}> |
| | | <AntvPie config={item} BID={BID} mainSearch={mainSearch} menuType={menuType} dataManager={dataManager} /> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'tabs') { |
| | | return ( |
| | | <Col span={item.width} key={item.uuid}> |
| | |
| | | position: relative; |
| | | box-sizing: border-box; |
| | | background: #ffffff; |
| | | background-position: center center; |
| | | background-repeat: no-repeat; |
| | | background-size: cover; |
| | | border-style: solid; |
| | | border-width: 0; |
| | | } |
| | |
| | | |
| | | // 通用组件 |
| | | const AntvBarAndLine = asyncSpinComponent(() => import('./components/chart/antv-bar-line')) |
| | | const AntvPie = asyncSpinComponent(() => import('./components/chart/antv-pie')) |
| | | const AntvTabs = asyncSpinComponent(() => import('./components/tabs/antv-tabs')) |
| | | const DataCard = asyncSpinComponent(() => import('./components/card/data-card')) |
| | | |
| | | class NormalTable extends Component { |
| | | class CustomPage extends Component { |
| | | static propTpyes = { |
| | | param: PropTypes.any, // 其他页面传递的参数 |
| | | MenuID: PropTypes.string, // 菜单Id |
| | |
| | | <AntvBarAndLine config={item} data={data} BID={BID} mainSearch={mainSearch} menuType={menuType} dataManager={dataManager} /> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'pie') { |
| | | return ( |
| | | <Col span={item.width} key={item.uuid}> |
| | | <AntvPie config={item} data={data} BID={BID} mainSearch={mainSearch} menuType={menuType} dataManager={dataManager} /> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'tabs') { |
| | | return ( |
| | | <Col span={item.width} key={item.uuid}> |
| | |
| | | |
| | | |
| | | render() { |
| | | const { menuType } = this.props |
| | | const { menuType, MenuNo } = this.props |
| | | const { loadingview, viewlost, config } = this.state |
| | | |
| | | return ( |
| | | <div className="custom-page-wrap" id={this.state.ContainerId} style={config ? config.style : null}> |
| | | {loadingview && <Spin size="large" />} |
| | | <Row>{this.getComponents()}</Row> |
| | | {options.sysType !== 'cloud' && menuType !== 'HS' ? <Button |
| | | {MenuNo && options.sysType !== 'cloud' && menuType !== 'HS' ? <Button |
| | | icon="copy" |
| | | shape="circle" |
| | | className="common-table-copy" |
| | |
| | | } |
| | | } |
| | | |
| | | export default connect(mapStateToProps, mapDispatchToProps)(NormalTable) |
| | | export default connect(mapStateToProps, mapDispatchToProps)(CustomPage) |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import { Chart } from '@antv/g2' |
| | | import { Icon, Tabs, Slider } from 'antd' |
| | | import './index.scss' |
| | | |
| | | const { TabPane } = Tabs |
| | | |
| | | class DefaultHome extends Component { |
| | | componentDidMount () { |
| | | const data = [ |
| | | { year: '2013 年', sales: 38 }, |
| | | { year: '2014 年', sales: 52 }, |
| | | { year: '2015 年', sales: 61 }, |
| | | { year: '2016 年', sales: 55 }, |
| | | { year: '2017 年', sales: 48 }, |
| | | { year: '2018 年', sales: 38 }, |
| | | { year: '2019 年', sales: 61 }, |
| | | { year: '2020 年', sales: 45 }, |
| | | ] |
| | | const chart = new Chart({ |
| | | container: 'home_page_id', |
| | | autoFit: true, |
| | | height: 400, |
| | | }) |
| | | |
| | | chart.data(data); |
| | | chart.scale('sales', { |
| | | nice: true, |
| | | }) |
| | | |
| | | chart.tooltip({ |
| | | showMarkers: false, |
| | | shared: true |
| | | }) |
| | | |
| | | chart.interval().position('year*sales').tooltip(`year*sales`, (name, value) => { |
| | | return { |
| | | name: '维修数', |
| | | value: value |
| | | } |
| | | }) |
| | | |
| | | chart.render() |
| | | } |
| | | |
| | | render() { |
| | | return ( |
| | | <div className="home-view"> |
| | | <div className="ant-row-flex"> |
| | | <div className="ant-col ant-col-sm-6"> |
| | | <div className="ant-card"> |
| | | <div className="ant-card-body"> |
| | | <div className="antd-chart-card"> |
| | | <div className="antd-chart-top"> |
| | | <div className="antd-meta-wrap"> |
| | | <div className="antd-meta"> |
| | | <span> |
| | | <span>维修总数</span> |
| | | </span> |
| | | <span className="antd-action"> |
| | | <Icon type="info-circle-o" /> |
| | | </span> |
| | | </div> |
| | | <div className="antd-total"> |
| | | <span>100</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div className="antd-chart-content"> |
| | | <div className="antd-content-fixed"> |
| | | <div className="antd-trend-item" style={{marginRight: '16px'}}> |
| | | <span> |
| | | <span>周同比</span> |
| | | <span className="antd-trend-text">10%</span> |
| | | </span> |
| | | <span className="antd-trend-up"> |
| | | <Icon type="caret-up" /> |
| | | </span> |
| | | </div> |
| | | <div className="antd-trend-item"> |
| | | <span> |
| | | <span>日同比</span> |
| | | <span className="antd-trend-text">10%</span> |
| | | </span> |
| | | <span className="antd-trend-down"> |
| | | <Icon type="caret-down" /> |
| | | </span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div className="antd-chart-footer"> |
| | | <div className="antd-field"> |
| | | <span className="antd-label"> |
| | | <span>维修总数</span> |
| | | </span> |
| | | <span className="antd-number">100</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div className="ant-col ant-col-sm-6"> |
| | | <div className="ant-card"> |
| | | <div className="ant-card-body"> |
| | | <div className="antd-chart-card"> |
| | | <div className="antd-chart-top"> |
| | | <div className="antd-meta-wrap"> |
| | | <div className="antd-meta"> |
| | | <span> |
| | | <span>超时工单</span> |
| | | </span> |
| | | <span className="antd-action"> |
| | | <Icon type="info-circle-o" /> |
| | | </span> |
| | | </div> |
| | | <div className="antd-total"> |
| | | <span>100</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div className="antd-chart-content"> |
| | | <div className="antd-content-fixed orange"> |
| | | <Slider defaultValue={67} tipFormatter={null} /> |
| | | <div className="mask"></div> |
| | | </div> |
| | | </div> |
| | | <div className="antd-chart-footer"> |
| | | <div className="antd-field"> |
| | | <span className="antd-label"> |
| | | <span>超时工单</span> |
| | | </span> |
| | | <span className="antd-number">100</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div className="ant-col ant-col-sm-6"> |
| | | <div className="ant-card"> |
| | | <div className="ant-card-body"> |
| | | <div className="antd-chart-card"> |
| | | <div className="antd-chart-top"> |
| | | <div className="antd-meta-wrap"> |
| | | <div className="antd-meta"> |
| | | <span> |
| | | <span>关单</span> |
| | | </span> |
| | | <span className="antd-action"> |
| | | <Icon type="info-circle-o" /> |
| | | </span> |
| | | </div> |
| | | <div className="antd-total"> |
| | | <span>100</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div className="antd-chart-content"> |
| | | <div className="antd-content-fixed primary"> |
| | | <Slider defaultValue={77} tipFormatter={null} /> |
| | | <div className="mask"></div> |
| | | </div> |
| | | </div> |
| | | <div className="antd-chart-footer"> |
| | | <div className="antd-field"> |
| | | <span className="antd-label"> |
| | | <span>关单</span> |
| | | </span> |
| | | <span className="antd-number">100</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div className="ant-col ant-col-sm-6"> |
| | | <div className="ant-card"> |
| | | <div className="ant-card-body"> |
| | | <div className="antd-chart-card"> |
| | | <div className="antd-chart-top"> |
| | | <div className="antd-meta-wrap"> |
| | | <div className="antd-meta"> |
| | | <span> |
| | | <span>原件邮寄</span> |
| | | </span> |
| | | <span className="antd-action"> |
| | | <Icon type="info-circle-o" /> |
| | | </span> |
| | | </div> |
| | | <div className="antd-total"> |
| | | <span>100</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div className="antd-chart-content"> |
| | | <div className="antd-content-fixed"> |
| | | <Slider defaultValue={87} tipFormatter={null} /> |
| | | <div className="mask"></div> |
| | | </div> |
| | | </div> |
| | | <div className="antd-chart-footer"> |
| | | <div className="antd-trend-item" style={{marginRight: '16px'}}> |
| | | <span> |
| | | <span>周同比</span> |
| | | <span className="antd-trend-text">10%</span> |
| | | </span> |
| | | <span className="antd-trend-up"> |
| | | <Icon type="caret-up" /> |
| | | </span> |
| | | </div> |
| | | <div className="antd-trend-item"> |
| | | <span> |
| | | <span>日同比</span> |
| | | <span className="antd-trend-text">10%</span> |
| | | </span> |
| | | <span className="antd-trend-down"> |
| | | <Icon type="caret-down" /> |
| | | </span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <Tabs defaultActiveKey="1"> |
| | | <TabPane tab="维修总数" key="1"> |
| | | <div className="sale-trend ant-col ant-col-xs-16"> |
| | | <div id="home_page_id"></div> |
| | | </div> |
| | | <div className="ant-col ant-col-xs-8"> |
| | | <div className="antd-sales-rank"> |
| | | <h4 className="antd-ranking-title">产品排名</h4> |
| | | <ul className="antd-ranking-list"> |
| | | <li> |
| | | <span className="antd-ranking-active">1</span> |
| | | <span className="antd-ranking-title">KU699</span> |
| | | <span>723,234</span> |
| | | </li> |
| | | <li> |
| | | <span className="antd-ranking-active">2</span> |
| | | <span className="antd-ranking-title">KU110</span> |
| | | <span>683,434</span> |
| | | </li> |
| | | <li> |
| | | <span className="antd-ranking-active">3</span> |
| | | <span className="antd-ranking-title">KU110K</span> |
| | | <span>527,264</span> |
| | | </li> |
| | | <li> |
| | | <span className="antd-ranking-number">4</span> |
| | | <span className="antd-ranking-title">KU066.9</span> |
| | | <span>493,233</span> |
| | | </li> |
| | | <li> |
| | | <span className="antd-ranking-number">5</span> |
| | | <span className="antd-ranking-title">KU079</span> |
| | | <span>323,734</span> |
| | | </li> |
| | | <li> |
| | | <span className="antd-ranking-number">6</span> |
| | | <span className="antd-ranking-title">KU153</span> |
| | | <span>303,934</span> |
| | | </li> |
| | | <li> |
| | | <span className="antd-ranking-number">7</span> |
| | | <span className="antd-ranking-title">KU151</span> |
| | | <span>227,244</span> |
| | | </li> |
| | | <li> |
| | | <span className="antd-ranking-number">8</span> |
| | | <span className="antd-ranking-title">KU720</span> |
| | | <span>223,734</span> |
| | | </li> |
| | | </ul> |
| | | </div> |
| | | </div> |
| | | </TabPane> |
| | | </Tabs> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default DefaultHome |
New file |
| | |
| | | .home-view { |
| | | position: relative; |
| | | width: 100%; |
| | | min-height: calc(100vh - 92px); |
| | | height: 100%; |
| | | background: #f0f2f5; |
| | | padding: 24px; |
| | | .ant-row-flex { |
| | | display: flex; |
| | | flex-flow: row wrap; |
| | | margin-left: -12px; |
| | | margin-right: -12px; |
| | | .ant-col { |
| | | padding-left: 12px; |
| | | padding-right: 12px; |
| | | margin-bottom: 24px; |
| | | .ant-card { |
| | | box-sizing: border-box; |
| | | margin: 0; |
| | | padding: 0; |
| | | color: rgba(0,0,0,.65); |
| | | font-size: 14px; |
| | | font-variant: tabular-nums; |
| | | line-height: 1.5; |
| | | list-style: none; |
| | | font-feature-settings: "tnum"; |
| | | position: relative; |
| | | background: #fff; |
| | | border-radius: 2px; |
| | | transition: all .3s; |
| | | .ant-card-body { |
| | | padding: 20px 24px 8px; |
| | | .antd-chart-card { |
| | | position: relative; |
| | | box-sizing: border-box; |
| | | .antd-chart-top { |
| | | position: relative; |
| | | width: 100%; |
| | | overflow: hidden; |
| | | box-sizing: border-box; |
| | | .antd-meta-wrap { |
| | | float: left; |
| | | box-sizing: border-box; |
| | | .antd-meta { |
| | | height: 22px; |
| | | color: rgba(0,0,0,.45); |
| | | font-size: 14px; |
| | | line-height: 22px; |
| | | .antd-action { |
| | | position: absolute; |
| | | top: 4px; |
| | | right: 0; |
| | | line-height: 1; |
| | | cursor: pointer; |
| | | } |
| | | } |
| | | .antd-total { |
| | | height: 38px; |
| | | margin-top: 4px; |
| | | margin-bottom: 0; |
| | | overflow: hidden; |
| | | color: rgba(0,0,0,.85); |
| | | font-size: 30px; |
| | | line-height: 38px; |
| | | white-space: nowrap; |
| | | text-overflow: ellipsis; |
| | | word-break: break-all; |
| | | } |
| | | } |
| | | } |
| | | .antd-chart-content { |
| | | position: relative; |
| | | height: 40px; |
| | | .antd-content-fixed { |
| | | position: absolute; |
| | | bottom: 0; |
| | | left: 0; |
| | | width: 100%; |
| | | .antd-trend-item { |
| | | display: inline-block; |
| | | font-size: 14px; |
| | | line-height: 22px; |
| | | .antd-trend-text { |
| | | margin-left: 5px; |
| | | } |
| | | .antd-trend-up { |
| | | color: #f5222d; |
| | | } |
| | | .antd-trend-down { |
| | | top: -1px; |
| | | color: #52c41a; |
| | | } |
| | | } |
| | | .mask { |
| | | position: absolute; |
| | | top: 0px; |
| | | left: 0px; |
| | | right: 0px; |
| | | bottom: 0px; |
| | | z-index: 1; |
| | | } |
| | | } |
| | | .ant-slider { |
| | | margin: 14px 0px 10px; |
| | | } |
| | | .ant-slider-track { |
| | | height: 7px; |
| | | background-color: #13C2C2; |
| | | } |
| | | .ant-slider-handle { |
| | | border-color: #13C2C2; |
| | | } |
| | | .orange { |
| | | .ant-slider-track { |
| | | background-color: orange; |
| | | } |
| | | .ant-slider-handle { |
| | | border-color: lightsalmon; |
| | | } |
| | | } |
| | | .primary { |
| | | .ant-slider-track { |
| | | background-color: #1890ff; |
| | | } |
| | | .ant-slider-handle { |
| | | border-color: #91d5ff; |
| | | } |
| | | } |
| | | .ant-slider-rail { |
| | | height: 7px; |
| | | } |
| | | } |
| | | .antd-chart-footer { |
| | | margin-top: 8px; |
| | | padding-top: 9px; |
| | | border-top: 1px solid #e8e8e8; |
| | | .antd-label { |
| | | font-size: 14px; |
| | | line-height: 22px; |
| | | margin-right: 10px; |
| | | } |
| | | .antd-trend-item { |
| | | display: inline-block; |
| | | font-size: 14px; |
| | | line-height: 22px; |
| | | .antd-trend-text { |
| | | margin-left: 5px; |
| | | } |
| | | .antd-trend-up { |
| | | color: #f5222d; |
| | | } |
| | | .antd-trend-down { |
| | | top: -1px; |
| | | color: #52c41a; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | .ant-tabs { |
| | | box-sizing: border-box; |
| | | margin: 0; |
| | | padding: 0; |
| | | color: rgba(0, 0, 0, 0.65); |
| | | font-size: 14px; |
| | | font-variant: tabular-nums; |
| | | line-height: 1.5; |
| | | list-style: none; |
| | | font-feature-settings: "tnum"; |
| | | position: relative; |
| | | background: #fff; |
| | | border-radius: 2px; |
| | | transition: all .3s; |
| | | .sale-trend { |
| | | min-height: 400px; |
| | | padding: 10px 20px; |
| | | margin-bottom: 20px; |
| | | } |
| | | .antd-sales-rank { |
| | | padding: 35px 32px 32px 72px; |
| | | .antd-ranking-title { |
| | | font-size: 16px; |
| | | } |
| | | .antd-ranking-list { |
| | | margin: 20px 0 0; |
| | | padding: 0; |
| | | list-style: none; |
| | | li { |
| | | display: flex; |
| | | align-items: center; |
| | | margin-top: 16px; |
| | | zoom: 1; |
| | | .antd-ranking-active { |
| | | display: inline-block; |
| | | width: 20px; |
| | | height: 20px; |
| | | margin-top: 1.5px; |
| | | margin-right: 16px; |
| | | font-weight: 600; |
| | | font-size: 12px; |
| | | line-height: 20px; |
| | | text-align: center; |
| | | color: #fff; |
| | | background-color: #314659; |
| | | border-radius: 20px; |
| | | } |
| | | .antd-ranking-number { |
| | | display: inline-block; |
| | | width: 20px; |
| | | height: 20px; |
| | | margin-top: 1.5px; |
| | | margin-right: 16px; |
| | | font-weight: 600; |
| | | font-size: 14px; |
| | | line-height: 20px; |
| | | text-align: center; |
| | | } |
| | | .antd-ranking-title { |
| | | flex: 1 1; |
| | | margin-right: 8px; |
| | | overflow: hidden; |
| | | white-space: nowrap; |
| | | text-overflow: ellipsis; |
| | | color: rgba(0,0,0,.65); |
| | | font-size: 14px; |
| | | line-height: 22px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import echarts from 'echarts/lib/echarts' |
| | | import 'echarts/lib/chart/bar' |
| | | import 'echarts/lib/component/tooltip' |
| | | // import 'echarts/lib/chart/line' |
| | | // import 'echarts/lib/component/title' |
| | | // import 'echarts/lib/component/legend' |
| | | // import 'echarts/lib/component/toolbox' |
| | | // import 'echarts/lib/component/markPoint' |
| | | // import 'echarts/lib/component/markLine' |
| | | import { Icon, Tabs, Slider } from 'antd' |
| | | import { notification, Spin } from 'antd' |
| | | |
| | | import Api from '@/api' |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import './index.scss' |
| | | |
| | | const { TabPane } = Tabs |
| | | const DefaultHome = asyncComponent(() => import('./defaulthome')) |
| | | const CustomPage = asyncComponent(() => import('@/tabviews/custom')) |
| | | |
| | | class Home extends Component { |
| | | static propTpyes = { |
| | | MenuNo: PropTypes.string, // 菜单参数 |
| | | MenuID: PropTypes.string, // 菜单Id |
| | | param: PropTypes.object // 菜单参数 |
| | | } |
| | | |
| | | state = {} |
| | | state = { |
| | | loading: true, |
| | | view: '' |
| | | } |
| | | |
| | | componentDidMount () { |
| | | let myChart = echarts.init(document.getElementById('home')) |
| | | // 绘制图表 |
| | | myChart.setOption({ |
| | | color: ['#1890ff'], |
| | | tooltip : { |
| | | trigger: 'axis', |
| | | axisPointer : { // 坐标轴指示器,坐标轴触发有效 |
| | | type : '' // 默认为直线,可选为:'line' | 'shadow' |
| | | let _param = { |
| | | func: 'sPC_Get_LongParam', |
| | | MenuID: this.props.MenuID |
| | | } |
| | | Api.getCacheConfig(_param).then(result => { |
| | | if (result.status) { |
| | | if (result.LongParam) { |
| | | this.setState({ |
| | | loading: false, |
| | | view: 'custom' |
| | | }) |
| | | } else { |
| | | this.setState({ |
| | | loading: false, |
| | | view: 'default' |
| | | }) |
| | | } |
| | | }, |
| | | grid: { |
| | | left: '3%', |
| | | right: '4%', |
| | | bottom: '3%', |
| | | containLabel: true |
| | | }, |
| | | xAxis : [ |
| | | { |
| | | type : 'category', |
| | | data : ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'], |
| | | axisTick: { |
| | | alignWithLabel: true |
| | | } |
| | | } |
| | | ], |
| | | yAxis : [ |
| | | { |
| | | type : 'value', |
| | | splitLine: { |
| | | show: true, |
| | | lineStyle: { |
| | | color: '#d9d9d9', |
| | | type: 'dashed' |
| | | } |
| | | } |
| | | } |
| | | ], |
| | | series : [ |
| | | { |
| | | name:'月维修数', |
| | | type:'bar', |
| | | barWidth: '30', |
| | | data:[30, 52, 200, 334, 390, 330, 220, 170, 220, 290, 350, 410, 440, 530] |
| | | } |
| | | ] |
| | | } else { |
| | | this.setState({ |
| | | loading: false, |
| | | view: 'default' |
| | | }) |
| | | notification.warning({ |
| | | top: 92, |
| | | message: result.message, |
| | | duration: 5 |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | render() { |
| | | return ( |
| | | <div className="home-view"> |
| | | <div className="ant-row-flex"> |
| | | <div className="ant-col ant-col-sm-6"> |
| | | <div className="ant-card"> |
| | | <div className="ant-card-body"> |
| | | <div className="antd-chart-card"> |
| | | <div className="antd-chart-top"> |
| | | <div className="antd-meta-wrap"> |
| | | <div className="antd-meta"> |
| | | <span> |
| | | <span>维修总数</span> |
| | | </span> |
| | | <span className="antd-action"> |
| | | <Icon type="info-circle-o" /> |
| | | </span> |
| | | </div> |
| | | <div className="antd-total"> |
| | | <span>100</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div className="antd-chart-content"> |
| | | <div className="antd-content-fixed"> |
| | | <div className="antd-trend-item" style={{marginRight: '16px'}}> |
| | | <span> |
| | | <span>周同比</span> |
| | | <span className="antd-trend-text">10%</span> |
| | | </span> |
| | | <span className="antd-trend-up"> |
| | | <Icon type="caret-up" /> |
| | | </span> |
| | | </div> |
| | | <div className="antd-trend-item"> |
| | | <span> |
| | | <span>日同比</span> |
| | | <span className="antd-trend-text">10%</span> |
| | | </span> |
| | | <span className="antd-trend-down"> |
| | | <Icon type="caret-down" /> |
| | | </span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div className="antd-chart-footer"> |
| | | <div className="antd-field"> |
| | | <span className="antd-label"> |
| | | <span>维修总数</span> |
| | | </span> |
| | | <span className="antd-number">100</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div className="ant-col ant-col-sm-6"> |
| | | <div className="ant-card"> |
| | | <div className="ant-card-body"> |
| | | <div className="antd-chart-card"> |
| | | <div className="antd-chart-top"> |
| | | <div className="antd-meta-wrap"> |
| | | <div className="antd-meta"> |
| | | <span> |
| | | <span>超时工单</span> |
| | | </span> |
| | | <span className="antd-action"> |
| | | <Icon type="info-circle-o" /> |
| | | </span> |
| | | </div> |
| | | <div className="antd-total"> |
| | | <span>100</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div className="antd-chart-content"> |
| | | <div className="antd-content-fixed orange"> |
| | | <Slider defaultValue={67} tipFormatter={null} /> |
| | | <div className="mask"></div> |
| | | </div> |
| | | </div> |
| | | <div className="antd-chart-footer"> |
| | | <div className="antd-field"> |
| | | <span className="antd-label"> |
| | | <span>超时工单</span> |
| | | </span> |
| | | <span className="antd-number">100</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div className="ant-col ant-col-sm-6"> |
| | | <div className="ant-card"> |
| | | <div className="ant-card-body"> |
| | | <div className="antd-chart-card"> |
| | | <div className="antd-chart-top"> |
| | | <div className="antd-meta-wrap"> |
| | | <div className="antd-meta"> |
| | | <span> |
| | | <span>关单</span> |
| | | </span> |
| | | <span className="antd-action"> |
| | | <Icon type="info-circle-o" /> |
| | | </span> |
| | | </div> |
| | | <div className="antd-total"> |
| | | <span>100</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div className="antd-chart-content"> |
| | | <div className="antd-content-fixed primary"> |
| | | <Slider defaultValue={77} tipFormatter={null} /> |
| | | <div className="mask"></div> |
| | | </div> |
| | | </div> |
| | | <div className="antd-chart-footer"> |
| | | <div className="antd-field"> |
| | | <span className="antd-label"> |
| | | <span>关单</span> |
| | | </span> |
| | | <span className="antd-number">100</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div className="ant-col ant-col-sm-6"> |
| | | <div className="ant-card"> |
| | | <div className="ant-card-body"> |
| | | <div className="antd-chart-card"> |
| | | <div className="antd-chart-top"> |
| | | <div className="antd-meta-wrap"> |
| | | <div className="antd-meta"> |
| | | <span> |
| | | <span>原件邮寄</span> |
| | | </span> |
| | | <span className="antd-action"> |
| | | <Icon type="info-circle-o" /> |
| | | </span> |
| | | </div> |
| | | <div className="antd-total"> |
| | | <span>100</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div className="antd-chart-content"> |
| | | <div className="antd-content-fixed"> |
| | | <Slider defaultValue={87} tipFormatter={null} /> |
| | | <div className="mask"></div> |
| | | </div> |
| | | </div> |
| | | <div className="antd-chart-footer"> |
| | | <div className="antd-trend-item" style={{marginRight: '16px'}}> |
| | | <span> |
| | | <span>周同比</span> |
| | | <span className="antd-trend-text">10%</span> |
| | | </span> |
| | | <span className="antd-trend-up"> |
| | | <Icon type="caret-up" /> |
| | | </span> |
| | | </div> |
| | | <div className="antd-trend-item"> |
| | | <span> |
| | | <span>日同比</span> |
| | | <span className="antd-trend-text">10%</span> |
| | | </span> |
| | | <span className="antd-trend-down"> |
| | | <Icon type="caret-down" /> |
| | | </span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <Tabs defaultActiveKey="1"> |
| | | <TabPane tab="维修总数" key="1"> |
| | | <div id="home" className="sale-trend ant-col ant-col-xs-16"></div> |
| | | <div className="ant-col ant-col-xs-8"> |
| | | <div className="antd-sales-rank"> |
| | | <h4 className="antd-ranking-title">产品排名</h4> |
| | | <ul className="antd-ranking-list"> |
| | | <li> |
| | | <span className="antd-ranking-active">1</span> |
| | | <span className="antd-ranking-title">KU699</span> |
| | | <span>723,234</span> |
| | | </li> |
| | | <li> |
| | | <span className="antd-ranking-active">2</span> |
| | | <span className="antd-ranking-title">KU110</span> |
| | | <span>683,434</span> |
| | | </li> |
| | | <li> |
| | | <span className="antd-ranking-active">3</span> |
| | | <span className="antd-ranking-title">KU110K</span> |
| | | <span>527,264</span> |
| | | </li> |
| | | <li> |
| | | <span className="antd-ranking-number">4</span> |
| | | <span className="antd-ranking-title">KU066.9</span> |
| | | <span>493,233</span> |
| | | </li> |
| | | <li> |
| | | <span className="antd-ranking-number">5</span> |
| | | <span className="antd-ranking-title">KU079</span> |
| | | <span>323,734</span> |
| | | </li> |
| | | <li> |
| | | <span className="antd-ranking-number">6</span> |
| | | <span className="antd-ranking-title">KU153</span> |
| | | <span>303,934</span> |
| | | </li> |
| | | <li> |
| | | <span className="antd-ranking-number">7</span> |
| | | <span className="antd-ranking-title">KU151</span> |
| | | <span>227,244</span> |
| | | </li> |
| | | <li> |
| | | <span className="antd-ranking-number">8</span> |
| | | <span className="antd-ranking-title">KU720</span> |
| | | <span>223,734</span> |
| | | </li> |
| | | </ul> |
| | | </div> |
| | | </div> |
| | | </TabPane> |
| | | </Tabs> |
| | | </div> |
| | | ) |
| | | const { loading, view } = this.state |
| | | |
| | | if (loading) { |
| | | return (<Spin className="home-box-spin" size="large" />) |
| | | } else if (view === 'custom') { |
| | | return (<CustomPage MenuID={this.props.MenuID}/>) |
| | | } else { |
| | | return (<DefaultHome />) |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | .home-view { |
| | | .home-box-spin { |
| | | position: relative; |
| | | width: 100%; |
| | | min-height: calc(100vh - 92px); |
| | | height: 100%; |
| | | background: #f0f2f5; |
| | | padding: 24px; |
| | | .ant-row-flex { |
| | | display: flex; |
| | | flex-flow: row wrap; |
| | | margin-left: -12px; |
| | | margin-right: -12px; |
| | | .ant-col { |
| | | padding-left: 12px; |
| | | padding-right: 12px; |
| | | margin-bottom: 24px; |
| | | .ant-card { |
| | | box-sizing: border-box; |
| | | margin: 0; |
| | | padding: 0; |
| | | color: rgba(0,0,0,.65); |
| | | font-size: 14px; |
| | | font-variant: tabular-nums; |
| | | line-height: 1.5; |
| | | list-style: none; |
| | | font-feature-settings: "tnum"; |
| | | position: relative; |
| | | background: #fff; |
| | | border-radius: 2px; |
| | | transition: all .3s; |
| | | .ant-card-body { |
| | | padding: 20px 24px 8px; |
| | | .antd-chart-card { |
| | | position: relative; |
| | | box-sizing: border-box; |
| | | .antd-chart-top { |
| | | position: relative; |
| | | width: 100%; |
| | | overflow: hidden; |
| | | box-sizing: border-box; |
| | | .antd-meta-wrap { |
| | | float: left; |
| | | box-sizing: border-box; |
| | | .antd-meta { |
| | | height: 22px; |
| | | color: rgba(0,0,0,.45); |
| | | font-size: 14px; |
| | | line-height: 22px; |
| | | .antd-action { |
| | | position: absolute; |
| | | top: 4px; |
| | | right: 0; |
| | | line-height: 1; |
| | | cursor: pointer; |
| | | } |
| | | } |
| | | .antd-total { |
| | | height: 38px; |
| | | margin-top: 4px; |
| | | margin-bottom: 0; |
| | | overflow: hidden; |
| | | color: rgba(0,0,0,.85); |
| | | font-size: 30px; |
| | | line-height: 38px; |
| | | white-space: nowrap; |
| | | text-overflow: ellipsis; |
| | | word-break: break-all; |
| | | } |
| | | } |
| | | } |
| | | .antd-chart-content { |
| | | position: relative; |
| | | height: 40px; |
| | | .antd-content-fixed { |
| | | position: absolute; |
| | | bottom: 0; |
| | | left: 0; |
| | | width: 100%; |
| | | .antd-trend-item { |
| | | display: inline-block; |
| | | font-size: 14px; |
| | | line-height: 22px; |
| | | .antd-trend-text { |
| | | margin-left: 5px; |
| | | } |
| | | .antd-trend-up { |
| | | color: #f5222d; |
| | | } |
| | | .antd-trend-down { |
| | | top: -1px; |
| | | color: #52c41a; |
| | | } |
| | | } |
| | | .mask { |
| | | position: absolute; |
| | | top: 0px; |
| | | left: 0px; |
| | | right: 0px; |
| | | bottom: 0px; |
| | | z-index: 1; |
| | | } |
| | | } |
| | | .ant-slider { |
| | | margin: 14px 0px 10px; |
| | | } |
| | | .ant-slider-track { |
| | | height: 7px; |
| | | background-color: #13C2C2; |
| | | } |
| | | .ant-slider-handle { |
| | | border-color: #13C2C2; |
| | | } |
| | | .orange { |
| | | .ant-slider-track { |
| | | background-color: orange; |
| | | } |
| | | .ant-slider-handle { |
| | | border-color: lightsalmon; |
| | | } |
| | | } |
| | | .primary { |
| | | .ant-slider-track { |
| | | background-color: #1890ff; |
| | | } |
| | | .ant-slider-handle { |
| | | border-color: #91d5ff; |
| | | } |
| | | } |
| | | .ant-slider-rail { |
| | | height: 7px; |
| | | } |
| | | } |
| | | .antd-chart-footer { |
| | | margin-top: 8px; |
| | | padding-top: 9px; |
| | | border-top: 1px solid #e8e8e8; |
| | | .antd-label { |
| | | font-size: 14px; |
| | | line-height: 22px; |
| | | margin-right: 10px; |
| | | } |
| | | .antd-trend-item { |
| | | display: inline-block; |
| | | font-size: 14px; |
| | | line-height: 22px; |
| | | .antd-trend-text { |
| | | margin-left: 5px; |
| | | } |
| | | .antd-trend-up { |
| | | color: #f5222d; |
| | | } |
| | | .antd-trend-down { |
| | | top: -1px; |
| | | color: #52c41a; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | .ant-tabs { |
| | | box-sizing: border-box; |
| | | margin: 0; |
| | | padding: 0; |
| | | color: rgba(0, 0, 0, 0.65); |
| | | font-size: 14px; |
| | | font-variant: tabular-nums; |
| | | line-height: 1.5; |
| | | list-style: none; |
| | | font-feature-settings: "tnum"; |
| | | position: relative; |
| | | background: #fff; |
| | | border-radius: 2px; |
| | | transition: all .3s; |
| | | .sale-trend { |
| | | height: 400px; |
| | | margin-bottom: 20px; |
| | | } |
| | | .antd-sales-rank { |
| | | padding: 35px 32px 32px 72px; |
| | | .antd-ranking-title { |
| | | font-size: 16px; |
| | | } |
| | | .antd-ranking-list { |
| | | margin: 20px 0 0; |
| | | padding: 0; |
| | | list-style: none; |
| | | li { |
| | | display: flex; |
| | | align-items: center; |
| | | margin-top: 16px; |
| | | zoom: 1; |
| | | .antd-ranking-active { |
| | | display: inline-block; |
| | | width: 20px; |
| | | height: 20px; |
| | | margin-top: 1.5px; |
| | | margin-right: 16px; |
| | | font-weight: 600; |
| | | font-size: 12px; |
| | | line-height: 20px; |
| | | text-align: center; |
| | | color: #fff; |
| | | background-color: #314659; |
| | | border-radius: 20px; |
| | | } |
| | | .antd-ranking-number { |
| | | display: inline-block; |
| | | width: 20px; |
| | | height: 20px; |
| | | margin-top: 1.5px; |
| | | margin-right: 16px; |
| | | font-weight: 600; |
| | | font-size: 14px; |
| | | line-height: 20px; |
| | | text-align: center; |
| | | } |
| | | .antd-ranking-title { |
| | | flex: 1 1; |
| | | margin-right: 8px; |
| | | overflow: hidden; |
| | | white-space: nowrap; |
| | | text-overflow: ellipsis; |
| | | color: rgba(0,0,0,.65); |
| | | font-size: 14px; |
| | | line-height: 22px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | left: 50%; |
| | | top: 30vh; |
| | | } |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { Button} from 'antd' |
| | | import { Button } from 'antd' |
| | | import './index.scss' |
| | | |
| | | class Preview extends Component { |
| | |
| | | closeCard(id) |
| | | } |
| | | |
| | | let _param = '' |
| | | if (card.type === 'CustomPage') { |
| | | _param = { |
| | | MenuType: 'custom', |
| | | MenuId: card.MenuID, |
| | | ParentId: card.ParentId, |
| | | MenuName: card.MenuName, |
| | | MenuNo: card.MenuNo |
| | | } |
| | | _param = window.btoa(window.encodeURIComponent(JSON.stringify(_param))) |
| | | } |
| | | |
| | | return ( |
| | | <div className="side-card" style={{ opacity }}> |
| | | <div ref={node => drag(drop(node))}> |
| | |
| | | </div> |
| | | {/* 自定义模板,在新页面编辑 */} |
| | | {!card.forbidden && card.type !== 'CustomPage' ? <Icon className="edit" type="edit" onClick={edit} /> : null} |
| | | {card.type === 'CustomPage' ? <a href={`#/menudesign/${card.MenuID}/${card.ParentId}/${card.MenuName}/${card.MenuNo}`} target="_blank" rel="noopener noreferrer"><Icon className="edit" type="edit" /></a> : null} |
| | | {card.type === 'CustomPage' ? <a href={`#/menudesign/${_param}`} target="_blank" rel="noopener noreferrer"><Icon className="edit" type="edit" /></a> : null} |
| | | <Icon className="close" type="close" onClick={close} /> |
| | | </div> |
| | | ) |
| | |
| | | |
| | | renderCell = (form) => { |
| | | const { getFieldDecorator } = form |
| | | const { |
| | | editing, |
| | | dataIndex, |
| | | title, |
| | | inputType, |
| | | record, |
| | | index, |
| | | children, |
| | | onSave, |
| | | ...restProps |
| | | } = this.props; |
| | | const { editing, dataIndex, title, record, children, className } = this.props |
| | | |
| | | return ( |
| | | <td {...restProps}> |
| | | <td className={className}> |
| | | {editing ? ( |
| | | <Form.Item style={{ margin: 0 }}> |
| | | {getFieldDecorator(dataIndex, { |
| | |
| | | |
| | | if (!hasBid) { // 表单中增加BID |
| | | _fields.unshift({ uuid: 'BID', field: 'BID', label: 'BID', type: 'text' }) |
| | | fieldArr.push('bid') |
| | | _declare.push(`@bid nvarchar(50)`) |
| | | _select.push(`@bid=''`) |
| | | |
| | | } |
| | | |
| | | let hasColumn = false |
| | |
| | | _loading = true |
| | | } |
| | | |
| | | if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql')) { |
| | | if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql') && this.scriptsForm.props.form.getFieldValue('sql') !== ' ') { |
| | | _loading = true |
| | | } else if (this.customForm && this.customForm.props.form.getFieldValue('sql')) { |
| | | } else if (this.customForm && this.customForm.props.form.getFieldValue('sql') && this.customForm.props.form.getFieldValue('sql') !== ' ') { |
| | | _loading = true |
| | | } |
| | | |
| | |
| | | import mainsubtable from '@/assets/img/mainsubtable.jpg' |
| | | import treepage from '@/assets/img/treepage.jpg' |
| | | import calendar from '@/assets/img/calendar.jpg' |
| | | // import customImg from '@/assets/img/custom.jpg' |
| | | import customImg from '@/assets/img/custom.jpg' |
| | | import rolemanage from '@/assets/img/rolemanage.jpg' |
| | | |
| | | const _dict = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS |
| | |
| | | baseconfig: '', |
| | | isSystem: true |
| | | }, |
| | | // { |
| | | // title: '自定义', |
| | | // type: 'CustomPage', |
| | | // url: customImg, |
| | | // baseconfig: '', |
| | | // isSystem: true |
| | | // }, |
| | | { |
| | | title: '自定义', |
| | | type: 'CustomPage', |
| | | url: customImg, |
| | | baseconfig: '', |
| | | isSystem: true |
| | | }, |
| | | { |
| | | title: '角色权限分配', |
| | | type: 'RolePermission', |
| | |
| | | class MenuDesign extends Component { |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | MenuId: this.props.match.params.MenuId, |
| | | MenuType: '', |
| | | MenuId: '', |
| | | ParentId: '', |
| | | MenuName: '', |
| | | MenuNo: '', |
| | | tableFields: [], |
| | | activeKey: 'basedata', |
| | | menuloading: false, |
| | | oriConfig: null, |
| | | openEdition: '', |
| | | config: null, |
| | | editElem: null |
| | | editElem: null, |
| | | } |
| | | |
| | | UNSAFE_componentWillMount() { |
| | | this.getMenuParam() |
| | | // this.testFunc() |
| | | try { |
| | | let param = JSON.parse(window.decodeURIComponent(window.atob(this.props.match.params.param))) |
| | | |
| | | this.setState({ |
| | | MenuType: param.MenuType, |
| | | MenuId: param.MenuId, |
| | | ParentId: param.ParentId || '', |
| | | MenuName: param.MenuName || '', |
| | | MenuNo: param.MenuNo || '', |
| | | }, () => { |
| | | this.getMenuParam() |
| | | }) |
| | | } catch { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '菜单信息解析错误!', |
| | | duration: 5 |
| | | }) |
| | | } |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | |
| | | } |
| | | |
| | | submitConfig = () => { |
| | | const { config, openEdition } = this.state |
| | | const { config, MenuType, openEdition } = this.state |
| | | |
| | | if (!config.MenuName || !config.MenuNo || !config.fstMenuId || !config.parentId) { |
| | | if (!config.MenuID) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请完善菜单基本信息!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (MenuType === 'custom' && (!config.MenuName || !config.MenuNo || !config.fstMenuId || !config.parentId)) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请完善菜单基本信息!', |
| | |
| | | |
| | | let param = { |
| | | func: 'sPC_TrdMenu_AddUpt', |
| | | FstID: _config.fstMenuId, |
| | | FstID: _config.fstMenuId || '', |
| | | SndID: _config.parentId, |
| | | ParentID: _config.parentId, |
| | | MenuID: _config.uuid, |
| | |
| | | } |
| | | |
| | | getMenuParam = () => { |
| | | const { MenuId, ParentId, MenuName, MenuNo } = this.state |
| | | |
| | | Api.getSystemConfig({ |
| | | func: 'sPC_Get_LongParam', |
| | | MenuID: this.props.match.params.MenuId |
| | | MenuID: MenuId |
| | | }).then(result => { |
| | | if (result.status) { |
| | | let config = null |
| | |
| | | if (!config) { |
| | | config = { |
| | | version: 1.0, |
| | | uuid: this.props.match.params.MenuId, |
| | | MenuID: this.props.match.params.MenuId, |
| | | parentId: this.props.match.params.ParentId, |
| | | uuid: MenuId, |
| | | MenuID: MenuId, |
| | | parentId: ParentId, |
| | | Template: 'CustomPage', |
| | | easyCode: '', |
| | | enabled: false, |
| | | MenuName: this.props.match.params.MenuName, |
| | | MenuNo: this.props.match.params.MenuNo, |
| | | MenuName: MenuName, |
| | | MenuNo: MenuNo, |
| | | tables: [], |
| | | components: [], |
| | | style: {backgroundColor: '#ffffff', backgroundImage: ''} |
| | | } |
| | | } else { |
| | | config.uuid = this.props.match.params.MenuId |
| | | config.MenuID = this.props.match.params.MenuId |
| | | config.uuid = MenuId |
| | | config.MenuID = MenuId |
| | | } |
| | | |
| | | this.setState({ |
| | |
| | | } |
| | | |
| | | verifyConfig = (show) => { |
| | | const { config } = this.state |
| | | const { config, MenuType } = this.state |
| | | let error = '' |
| | | |
| | | if (!config.MenuName || !config.MenuNo || !config.fstMenuId || !config.parentId) { |
| | | if (!config.MenuID) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请完善菜单基本信息!', |
| | | duration: 5 |
| | | }) |
| | | return 'false' |
| | | return |
| | | } else if (MenuType === 'custom' && (!config.MenuName || !config.MenuNo || !config.fstMenuId || !config.parentId)) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请完善菜单基本信息!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | config.components.forEach(item => { |
| | | if (!error && item.setting) { |
| | | if (item.setting.interType === 'system' && item.setting.execute !== 'false' && !item.setting.dataresource) { |
| | | error = `组件《${item.name}》未设置数据源` |
| | | error = `组件《${item.name}》未设置数据源!` |
| | | } else if (item.setting.interType === 'system' && item.setting.execute === 'false' && item.scripts.length === 0) { |
| | | error = `组件《${item.name}》未设置数据源` |
| | | error = `组件《${item.name}》未设置数据源!` |
| | | } else if (item.setting.interType && !item.setting.primaryKey) { |
| | | error = `组件《${item.name}》未设置主键` |
| | | error = `组件《${item.name}》未设置主键!` |
| | | } |
| | | } |
| | | if (!error && (item.type === 'bar' || item.type === 'line' || item.type === 'pie')) { |
| | | if (!item.plot.Xaxis) { |
| | | error = `组件《${item.name}》图表字段尚未设置!` |
| | | } |
| | | } |
| | | }) |
| | |
| | | } |
| | | |
| | | render () { |
| | | const { activeKey, dict, MenuId, config } = this.state |
| | | const { activeKey, MenuType, dict, MenuId, config, ParentId, MenuName, MenuNo } = this.state |
| | | |
| | | return ( |
| | | <ConfigProvider locale={_locale}> |
| | |
| | | {/* 基本信息 */} |
| | | <Panel header={dict['mob.basemsg']} key="basedata"> |
| | | {/* 菜单信息 */} |
| | | <MenuForm |
| | | {MenuType === 'custom' ? <MenuForm |
| | | dict={dict} |
| | | config={config} |
| | | MenuId={MenuId} |
| | | parentId={this.props.match.params.ParentId} |
| | | MenuName={this.props.match.params.MenuName} |
| | | MenuNo={this.props.match.params.MenuNo} |
| | | parentId={ParentId} |
| | | MenuName={MenuName} |
| | | MenuNo={MenuNo} |
| | | initMenuList={this.initMenuList} |
| | | updateConfig={this.updateConfig} |
| | | /> |
| | | /> : null} |
| | | {/* 表名添加 */} |
| | | {config ? <TableComponent config={config} updatetable={this.updatetable}/> : null} |
| | | </Panel> |