| | |
| | | </Col> : null} |
| | | {config.subtype !== 'tablecard' ? <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="鼠标悬浮于卡片上方时,卡片放大1.1倍。"> |
| | | <Tooltip placement="topLeft" title="鼠标悬浮于卡片上方时,卡片放大1.05倍。"> |
| | | <Icon type="question-circle" /> |
| | | 卡片放大 |
| | | </Tooltip> |
| | |
| | | import React from 'react' |
| | | import { useDrag, useDrop } from 'react-dnd' |
| | | import { Icon, Select, DatePicker, Input, Popover } from 'antd' |
| | | import { Icon, Select, DatePicker, Input, Popover, Form } from 'antd' |
| | | import moment from 'moment' |
| | | |
| | | import DateGroup from '../dategroup' |
| | |
| | | drop: ({ id: draggedId }) => { |
| | | if (!draggedId) return |
| | | if (draggedId !== id) { |
| | | const { index: originIndex } = findCard(draggedId) |
| | | if (originIndex === -1) return |
| | | |
| | | const { index: overIndex } = findCard(id) |
| | | moveCard(draggedId, overIndex) |
| | | } |
| | |
| | | } trigger="hover"> |
| | | <div className={'page-card ' + card.labelShow} style={{ opacity: opacity}}> |
| | | <div ref={node => drag(drop(node))}> |
| | | <div className="ant-row ant-form-item"> |
| | | <div className="ant-col ant-form-item-label ant-col-xs-24 ant-col-sm-8"> |
| | | <label className={card.required === 'true' ? 'ant-form-item-required' : ''} title={card.label}>{card.label}</label> |
| | | </div> |
| | | <div className="ant-col ant-form-item-control-wrapper ant-col-xs-24 ant-col-sm-16"> |
| | | {card.type === 'text' ? |
| | | <Input style={{marginTop: '4px'}} placeholder={card.labelShow === 'false' ? card.label : ''} value={card.initval} /> : null |
| | | } |
| | | {(card.type === 'multiselect' || card.type === 'select' || card.type === 'link') ? |
| | | <Select value={_defaultValue}></Select> : null |
| | | } |
| | | {card.type === 'date' ? |
| | | <DatePicker value={card.initval ? moment().subtract(card.initval, 'days') : null} /> : null |
| | | } |
| | | {card.type === 'dateweek' ? |
| | | <WeekPicker value={card.initval ? moment().subtract(card.initval * 7, 'days') : null} /> : null |
| | | } |
| | | {card.type === 'datemonth' ? |
| | | <MonthPicker value={card.initval ? moment().subtract(card.initval, 'month') : null} /> : null |
| | | } |
| | | {card.type === 'daterange' ? |
| | | <RangePicker |
| | | className="data-range" |
| | | placeholder={['BeginTime', 'EndTime']} |
| | | renderExtraFooter={() => 'extra footer'} |
| | | value={_defaultValue} |
| | | /> : null |
| | | } |
| | | {card.type === 'group' ? <DateGroup card={card} /> : null } |
| | | </div> |
| | | </div> |
| | | <Form.Item |
| | | labelCol={{xs: { span: 24 }, sm: { span: 8 }}} |
| | | wrapperCol = {{xs: { span: 24 }, sm: { span: 16 }}} |
| | | label={card.labelShow !== 'false' ? card.label : ''} |
| | | required={card.required === 'true'} |
| | | > |
| | | {card.type === 'text' ? |
| | | <Input style={{marginTop: '4px'}} placeholder={card.labelShow === 'false' ? card.label : ''} value={card.initval} /> : null |
| | | } |
| | | {(card.type === 'multiselect' || card.type === 'select' || card.type === 'link') ? |
| | | <Select value={_defaultValue}></Select> : null |
| | | } |
| | | {card.type === 'date' ? |
| | | <DatePicker value={card.initval ? moment().subtract(card.initval, 'days') : null} /> : null |
| | | } |
| | | {card.type === 'dateweek' ? |
| | | <WeekPicker value={card.initval ? moment().subtract(card.initval * 7, 'days') : null} /> : null |
| | | } |
| | | {card.type === 'datemonth' ? |
| | | <MonthPicker value={card.initval ? moment().subtract(card.initval, 'month') : null} /> : null |
| | | } |
| | | {card.type === 'daterange' ? |
| | | <RangePicker |
| | | className="data-range" |
| | | placeholder={['BeginTime', 'EndTime']} |
| | | renderExtraFooter={() => 'extra footer'} |
| | | value={_defaultValue} |
| | | /> : null |
| | | } |
| | | {card.type === 'group' ? <DateGroup card={card} /> : null } |
| | | </Form.Item> |
| | | </div> |
| | | </div> |
| | | </Popover> |
| | |
| | | width: 24, |
| | | name: card.name, |
| | | subtype: card.subtype, |
| | | wrap: { name: card.name, width: 24 }, |
| | | wrap: { name: card.name, width: 24, show: 'true', float: 'left' }, |
| | | style: { |
| | | marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px' |
| | | }, |
| | |
| | | border-radius: 2px; |
| | | padding-bottom: 15px; |
| | | .ant-form-item { |
| | | cursor: move; |
| | | display: flex; |
| | | position: relative; |
| | | margin-bottom: 0px; |
| | | .ant-form-item-label { |
| | | height: 40px; |
| | | label { |
| | | width: 100%; |
| | | cursor: move; |
| | | overflow: hidden; |
| | | display: inline-block; |
| | | text-overflow: ellipsis; |
| | | white-space: nowrap; |
| | | } |
| | | } |
| | | .ant-form-item-control-wrapper { |
| | | position: relative; |
| | | flex: 1 1; |
| | | .ant-select { |
| | | width: 100%; |
| | | margin-top: 4px; |
| | |
| | | font-size: 13px; |
| | | } |
| | | } |
| | | .ant-form-item-control-wrapper::after { |
| | | content: ''; |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | opacity: 0; |
| | | z-index: 2; |
| | | } |
| | | } |
| | | .ant-form-item::after { |
| | | display: block; |
| | | content: ' '; |
| | | clear: both; |
| | | } |
| | | >div::after { |
| | | display: block; |
| | | content: ' '; |
| | | position: absolute; |
| | | cursor: move; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | opacity: 0; |
| | | z-index: 2; |
| | | } |
| | | } |
| | | .page-card.false { |
| | | .ant-form-item-label { |
| | | display: none; |
| | | } |
| | | } |
| | | .page-card:hover { |
| | | .edit { |
| | | display: inline-block; |
| | | .ant-form-item-control-wrapper { |
| | | width: 100%; |
| | | } |
| | | } |
| | | .ant-calendar-picker { |
| | |
| | | import React from 'react' |
| | | import { useDrag, useDrop } from 'react-dnd' |
| | | import { Icon, Select, DatePicker, Input, Popover } from 'antd' |
| | | import { Icon, Select, DatePicker, Input, Popover, Form } from 'antd' |
| | | import moment from 'moment' |
| | | |
| | | import DateGroup from '../dategroup' |
| | |
| | | const [, drop] = useDrop({ |
| | | accept: 'search', |
| | | canDrop: () => true, |
| | | drop: () => {}, |
| | | hover({ id: draggedId }) { |
| | | drop: ({ id: draggedId }) => { |
| | | if (!draggedId || draggedId === id) return |
| | | |
| | | const { index: originIndex } = findCard(draggedId) |
| | |
| | | |
| | | const { index: overIndex } = findCard(id) |
| | | moveCard(draggedId, overIndex) |
| | | }, |
| | | } |
| | | }) |
| | | const opacity = isDragging ? 0 : 1 |
| | | |
| | |
| | | <Icon className="close" title="delete" type="close" onClick={() => delCard(id)} /> |
| | | </div> |
| | | } trigger="hover"> |
| | | <div className="page-card" style={{ opacity: opacity}}> |
| | | <div className={'page-card ' + (card.labelShow || '')} style={{ opacity: opacity}}> |
| | | <div ref={node => drag(drop(node))}> |
| | | <div className="ant-form-item"> |
| | | <Form.Item |
| | | labelCol={{xs: { span: 24 }, sm: { span: 8 }}} |
| | | wrapperCol = {{xs: { span: 24 }, sm: { span: 16 }}} |
| | | label={card.labelShow !== 'false' ? card.label : ''} |
| | | required={card.required === 'true'} |
| | | > |
| | | {card.type === 'text' ? |
| | | <Input placeholder={card.label} value={card.initval} /> : null |
| | | } |
| | |
| | | /> : null |
| | | } |
| | | {card.type === 'group' ? <DateGroup card={card} /> : null } |
| | | </div> |
| | | </Form.Item> |
| | | </div> |
| | | </div> |
| | | </Popover> |
| | |
| | | position: relative; |
| | | border-radius: 2px; |
| | | height: 45px; |
| | | padding-top: 8px; |
| | | .ant-form-item { |
| | | position: relative; |
| | | cursor: move; |
| | |
| | | } |
| | | } |
| | | .ant-form-item::after { |
| | | display: block; |
| | | content: ' '; |
| | | position: absolute; |
| | | top: 0; |
| | |
| | | z-index: 2; |
| | | } |
| | | } |
| | | .page-card.false { |
| | | .ant-form-item-label { |
| | | display: none; |
| | | } |
| | | .ant-form-item-control-wrapper { |
| | | width: 100%; |
| | | } |
| | | } |
| | | .ant-calendar-picker { |
| | | min-width: 100px!important; |
| | | width: 100%; |
| | |
| | | .box404 { |
| | | padding-top: 30px; |
| | | } |
| | | >.top-search { |
| | | padding: 0px 24px 5px; |
| | | border-bottom: 1px solid #efefef; |
| | | } |
| | | |
| | | .ant-modal-mask { |
| | | position: absolute; |
| | |
| | | .box404 { |
| | | padding-top: 30px; |
| | | } |
| | | >.top-search { |
| | | padding: 0px 24px 5px; |
| | | border-bottom: 1px solid #efefef; |
| | | } |
| | | .commontable-main-action { |
| | | min-height: 25px; |
| | | .button-list { |
| | |
| | | val = '' + val |
| | | } |
| | | |
| | | if (card.format === 'percent') { |
| | | if (card.format === 'percent' && (!card.postfix || card.postfix.indexOf('%') === -1)) { |
| | | val = val + '%' |
| | | } else if (card.format === 'thdSeparator') { |
| | | val = val.replace(/\d{1,3}(?=(\d{3})+(\.\d*)?$)/g, '$&,') |
| | |
| | | import { Spin, Empty, notification, Col, Pagination } from 'antd' |
| | | |
| | | import Api from '@/api' |
| | | import Utils from '@/utils/utils.js' |
| | | import UtilsDM from '@/utils/utils-datamanage.js' |
| | | import preImg from '@/assets/img/prev.png' |
| | | import nextImg from '@/assets/img/next.png' |
| | |
| | | |
| | | const CardItem = asyncComponent(() => import('../cardItem')) |
| | | const MainAction = asyncComponent(() => import('@/tabviews/zshare/actionList')) |
| | | const NormalHeader = asyncComponent(() => import('@/tabviews/custom/components/share/normalheader')) |
| | | |
| | | class DataCard extends Component { |
| | | static propTpyes = { |
| | |
| | | BID: '', // 上级ID |
| | | BData: '', // 上级行数据 |
| | | config: null, // 图表配置信息 |
| | | search: null, // 搜索条件 |
| | | pageIndex: 1, // 页码 |
| | | activeKey: '', // 选中卡 |
| | | selectKeys: [], // 多选时选中卡片 |
| | |
| | | BID: BID || '', |
| | | config: _config, |
| | | card: _card, |
| | | search: Utils.initMainSearch(_config.search), |
| | | arr_field: _config.columns.map(col => col.field).join(','), |
| | | }, () => { |
| | | if (_config.setting.sync !== 'true' && _config.setting.onload === 'true') { |
| | |
| | | |
| | | async loadData () { |
| | | const { mainSearch, menuType } = this.props |
| | | const { config, arr_field, pageIndex, BID } = this.state |
| | | const { config, arr_field, pageIndex, search, BID } = this.state |
| | | |
| | | if (config.setting.supModule && !BID) { // BID 不存在时,不做查询 |
| | | this.setState({ |
| | |
| | | return |
| | | } |
| | | |
| | | let searches = [] |
| | | let searches = fromJS(search).toJS() |
| | | if (mainSearch && mainSearch.length > 0) { // 主表搜索条件 |
| | | let keys = searches.map(item => item.key) |
| | | mainSearch.forEach(item => { |
| | |
| | | this.loadData() |
| | | }) |
| | | } |
| | | |
| | | refreshSearch = (list) => { |
| | | this.setState({ |
| | | search: list, |
| | | pageIndex: 1 |
| | | }, () => { |
| | | this.loadData() |
| | | }) |
| | | } |
| | | |
| | | changeCard = (index, item) => { |
| | | const { config, selectKeys, selectedData, activeKey } = this.state |
| | |
| | | <Spin /> |
| | | </div> : null |
| | | } |
| | | <NormalHeader config={config} BID={BID} menuType={this.props.menuType} refresh={this.refreshSearch} /> |
| | | {config.action && config.action.length > 0 ? |
| | | <MainAction |
| | | BID={BID} |
| | |
| | | >.ant-col:hover { |
| | | >.card-item-box { |
| | | z-index: 1; |
| | | transform: scale(1.1); |
| | | transform: scale(1.05); |
| | | } |
| | | } |
| | | } |
| | |
| | | import './index.scss' |
| | | |
| | | const CardItem = asyncComponent(() => import('../cardItem')) |
| | | const NormalHeader = asyncComponent(() => import('@/tabviews/custom/components/share/normalheader')) |
| | | |
| | | class DataCard extends Component { |
| | | static propTpyes = { |
| | |
| | | |
| | | let _data = {} |
| | | let _sync = false |
| | | |
| | | if (_config.setting && _config.wrap.datatype !== 'static') { |
| | | _sync = _config.setting.sync === 'true' |
| | | |
| | |
| | | _data = nextProps.data[config.dataName] |
| | | if (_data && Array.isArray(_data)) { |
| | | _data = _data[0] |
| | | } else { |
| | | _data = {} |
| | | } |
| | | } |
| | | |
| | | if (_data) { |
| | | _data.$$BID = BID || '' |
| | | } |
| | |
| | | <Spin /> |
| | | </div> : null |
| | | } |
| | | <NormalHeader config={config}/> |
| | | <div className={`card-row-list ${config.wrap.cardType || ''} ${config.wrap.scale || ''}`}> |
| | | {config.subcards.map((item, index) => ( |
| | | <Col className={activeKey === index ? 'active' : ''} key={index} span={item.setting.width || 6} offset={item.offset || 0} onClick={() => {this.changeCard(index, item)}}> |
| | |
| | | >.ant-col:hover { |
| | | >.card-item-box { |
| | | z-index: 1; |
| | | transform: scale(1.1); |
| | | transform: scale(1.05); |
| | | } |
| | | } |
| | | } |
| | |
| | | import { is, fromJS } from 'immutable' |
| | | import { Spin, notification, Col, Empty, Pagination } from 'antd' |
| | | |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import Api from '@/api' |
| | | import Utils from '@/utils/utils.js' |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import UtilsDM from '@/utils/utils-datamanage.js' |
| | | import MKEmitter from '@/utils/events.js' |
| | | import './index.scss' |
| | | |
| | | const CardCellComponent = asyncComponent(() => import('../cardcellList')) |
| | | const NormalHeader = asyncComponent(() => import('@/tabviews/custom/components/share/normalheader')) |
| | | |
| | | class TableCard extends Component { |
| | | static propTpyes = { |
| | |
| | | BID: '', // 上级ID |
| | | config: null, // 图表配置信息 |
| | | loading: false, // 数据加载状态 |
| | | search: null, // 搜索条件 |
| | | preIndex: 0, // 开始索引 |
| | | pageIndex: 1, // 页码 |
| | | total: 0, // 总数 |
| | | sync: false, // 是否统一请求数据 |
| | | data: null, // 数据 |
| | | title: '', // 标题 |
| | | showHeader: false // 存在标题、搜索 |
| | | } |
| | | |
| | | /** |
| | |
| | | }) |
| | | |
| | | this.setState({ |
| | | showHeader: showHeader, |
| | | title: _config.wrap.title, |
| | | sync: _sync, |
| | | BID: BID || '', |
| | | data: _data, |
| | | config: _config, |
| | | search: Utils.initMainSearch(_config.search), |
| | | arr_field: _config.columns.map(col => col.field).join(','), |
| | | }, () => { |
| | | if (_config.setting.sync !== 'true' && _config.setting.onload === 'true') { |
| | |
| | | |
| | | async loadData () { |
| | | const { mainSearch, menuType } = this.props |
| | | const { config, arr_field, pageIndex, BID } = this.state |
| | | const { config, arr_field, pageIndex, search, BID } = this.state |
| | | |
| | | if (config.setting.supModule && !BID) { // BID 不存在时,不做查询 |
| | | this.setState({ |
| | |
| | | return |
| | | } |
| | | |
| | | let searches = [] |
| | | let searches = fromJS(search).toJS() |
| | | if (mainSearch && mainSearch.length > 0) { // 主表搜索条件 |
| | | let keys = searches.map(item => item.key) |
| | | mainSearch.forEach(item => { |
| | |
| | | return line |
| | | } |
| | | |
| | | refreshSearch = (list) => { |
| | | this.setState({ |
| | | search: list, |
| | | pageIndex: 1 |
| | | }, () => { |
| | | this.loadData() |
| | | }) |
| | | } |
| | | |
| | | render() { |
| | | const { config, loading, data, title, showHeader, pageIndex, preIndex, total } = this.state |
| | | const { config, loading, data, BID, pageIndex, preIndex, total } = this.state |
| | | |
| | | return ( |
| | | <div className="custom-table-card-box" style={{...config.style, height: config.wrap.height}}> |
| | |
| | | <Spin /> |
| | | </div> : null |
| | | } |
| | | {showHeader ? <div className="table-header" style={config.headerStyle}> |
| | | <span className="table-title">{title}</span> |
| | | {/* <searchLine /> */} |
| | | </div> : null} |
| | | <NormalHeader config={config} BID={BID} menuType={this.props.menuType} refresh={this.refreshSearch} /> |
| | | {data && data.length > 0 ? <div className="card-row-list" style={{height: config.wrap.contentHeight}}> |
| | | {data.map((item, index) => this.getLines(item, preIndex + index + 1))} |
| | | </div> : null} |
| | |
| | | import Utils from '@/utils/utils.js' |
| | | import UtilsDM from '@/utils/utils-datamanage.js' |
| | | import { modifyTabview } from '@/store/action' |
| | | // import searchLine from '../../share/searchLine' |
| | | import MKEmitter from '@/utils/events.js' |
| | | import './index.scss' |
| | | |
| | | const NormalHeader = asyncComponent(() => import('@/tabviews/custom/components/share/normalheader')) |
| | | const ExcelOutButton = asyncComponent(() => import('@/tabviews/zshare/actionList/exceloutbutton')) |
| | | const ExcelInButton = asyncComponent(() => import('@/tabviews/zshare/actionList/excelInbutton')) |
| | | |
| | |
| | | loading: false, // 数据加载状态 |
| | | chartId: Utils.getuuid(), // 图表Id |
| | | transfield: {}, // 字段名称翻译 |
| | | title: '', // 组件标题 |
| | | sync: false, // 是否统一请求数据 |
| | | plot: null, // 图表设置 |
| | | data: null, // 数据 |
| | |
| | | chartData: [], // 图表数据 |
| | | chartFields: [], // 统计图表生成字段集 |
| | | selectFields: [], // 统计图表选择字段 |
| | | showHeader: false // 存在标题、搜索、或统计数据时显示 |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | |
| | | }) |
| | | } |
| | | |
| | | let showHeader = false |
| | | if (config.plot.title || _config.plot.datatype === 'statistics' || config.search.length > 0) { |
| | | showHeader = true |
| | | if (config.plot.title || config.search.length > 0) { |
| | | _config.plot.height = _config.plot.height - 80 |
| | | } else { |
| | | _config.plot.height = _config.plot.height - 30 |
| | |
| | | arr_field: _config.columns.map(col => col.field).join(','), |
| | | plot: _config.plot, |
| | | sync: _sync, |
| | | title: config.plot.title, |
| | | search: Utils.initMainSearch(config.search), |
| | | transfield, |
| | | showHeader |
| | | transfield |
| | | }, () => { |
| | | if (config.setting.sync !== 'true' && config.setting.onload === 'true') { |
| | | this.loadData() |
| | |
| | | }) |
| | | } |
| | | |
| | | refreshSearch = (list) => { |
| | | this.setState({search: list}, () => { |
| | | this.loadData() |
| | | }) |
| | | } |
| | | |
| | | render() { |
| | | const { showHeader, config, loading, title, plot, empty, chartFields, selectFields, BID } = this.state |
| | | const { config, loading, plot, empty, chartFields, selectFields, BID } = this.state |
| | | |
| | | return ( |
| | | <div className="custom-line-chart-plot-box" style={config.style}> |
| | |
| | | <Spin /> |
| | | </div> : null |
| | | } |
| | | {showHeader ? <div className="chart-header" style={config.headerStyle}> |
| | | <span className="chart-title">{title}</span> |
| | | {/* <searchLine /> */} |
| | | {plot.datatype === 'statistics' && chartFields.length > 0 ? <Select |
| | | mode="multiple" |
| | | showSearch |
| | | showArrow={true} |
| | | value={selectFields} |
| | | onChange={this.handleChange} |
| | | maxTagCount={0} |
| | | maxTagPlaceholder={(option) => <div className="type-label">{option.join('、')}</div>} |
| | | > |
| | | {chartFields.map((item, i) => <Select.Option key={i} value={item}>{item}</Select.Option>)} |
| | | </Select> : null} |
| | | </div> : null} |
| | | <NormalHeader config={config} BID={BID} menuType={this.props.menuType} refresh={this.refreshSearch} /> |
| | | <div className="canvas-wrap"> |
| | | <div className={'chart-action ' + (plot.title ? 'with-title' : '')}> |
| | | <div className="chart-action"> |
| | | {config.action.map(item => { |
| | | if (item.OpenType === 'excelOut') { |
| | | return ( |
| | |
| | | ) |
| | | } |
| | | })} |
| | | {plot.datatype === 'statistics' && chartFields.length > 0 ? <Select |
| | | mode="multiple" |
| | | showSearch |
| | | showArrow={true} |
| | | value={selectFields} |
| | | onChange={this.handleChange} |
| | | maxTagCount={0} |
| | | maxTagPlaceholder={(option) => <div className="type-label">{option.join('、')}</div>} |
| | | > |
| | | {chartFields.map((item, i) => <Select.Option key={i} value={item}>{item}</Select.Option>)} |
| | | </Select> : null} |
| | | </div> |
| | | <div className={'canvas' + (empty ? ' empty' : '')} id={this.state.chartId}></div> |
| | | </div> |
| | |
| | | .custom-line-chart-plot-box { |
| | | position: relative; |
| | | background: #ffffff; |
| | | background-position: center center; |
| | | background-repeat: no-repeat; |
| | | background-size: cover; |
| | | min-height: 100px; |
| | | |
| | | > .chart-header { |
| | | height: 45px; |
| | | // border-bottom: 1px solid #e8e8e8; |
| | | overflow: hidden; |
| | | |
| | | .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; |
| | |
| | | top: 2px; |
| | | right: 5px; |
| | | z-index: 1; |
| | | } |
| | | .chart-action.with-title { |
| | | top: 35px; |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | .loading-mask { |
| | | position: absolute; |
| | | left: 20px; |
| | | left: 0px; |
| | | top: 0; |
| | | right: 20px; |
| | | bottom: 30px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | text-align: justify; |
| | | right: 0px; |
| | | bottom: 0px; |
| | | z-index: 1; |
| | | |
| | | .ant-spin-blur { |
| | |
| | | opacity: 0.5; |
| | | background: #ffffff; |
| | | } |
| | | } |
| | | .chart-title + .loading-mask { |
| | | top: 40px; |
| | | } |
| | | > .ant-select { |
| | | width: 150px; |
| | |
| | | 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 { modifyTabview } from '@/store/action' |
| | | import { chartColors } from '@/utils/option.js' |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import UtilsDM from '@/utils/utils-datamanage.js' |
| | | import MKEmitter from '@/utils/events.js' |
| | | import './index.scss' |
| | | |
| | | const NormalHeader = asyncComponent(() => import('@/tabviews/custom/components/share/normalheader')) |
| | | |
| | | class PieChart extends Component { |
| | | static propTpyes = { |
| | |
| | | plot: null, // 图表设置 |
| | | data: null, // 数据 |
| | | search: null, // 搜索条件 |
| | | showHeader: false // 存在标题、搜索、或统计数据时显示 |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | |
| | | _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 |
| | |
| | | plot: _config.plot, |
| | | sync: _sync, |
| | | title: config.plot.title, |
| | | search: Utils.initMainSearch(config.search), |
| | | showHeader |
| | | search: Utils.initMainSearch(config.search) |
| | | }, () => { |
| | | if (config.setting.sync !== 'true' && config.setting.onload === 'true') { |
| | | this.loadData() |
| | |
| | | chart.render() |
| | | } |
| | | |
| | | refreshSearch = (list) => { |
| | | this.setState({search: list}, () => { |
| | | this.loadData() |
| | | }) |
| | | } |
| | | |
| | | render() { |
| | | const { showHeader, config, loading, title, empty } = this.state |
| | | const { config, loading, empty, BID } = this.state |
| | | |
| | | return ( |
| | | <div className="custom-pie-chart-plot-box" style={config.style}> |
| | |
| | | <Spin /> |
| | | </div> : null |
| | | } |
| | | {showHeader ? <div className="chart-header" style={config.headerStyle}> |
| | | <span className="chart-title">{title}</span> |
| | | {/* <searchLine /> */} |
| | | </div> : null} |
| | | <NormalHeader config={config} BID={BID} menuType={this.props.menuType} refresh={this.refreshSearch} /> |
| | | <div className="canvas-wrap"> |
| | | <div className={'canvas' + (empty ? ' empty' : '')} id={this.state.chartId}></div> |
| | | </div> |
| | |
| | | .custom-pie-chart-plot-box { |
| | | position: relative; |
| | | background: #ffffff; |
| | | background-position: center center; |
| | | background-repeat: no-repeat; |
| | | background-size: cover; |
| | | min-height: 100px; |
| | | |
| | | > .chart-header { |
| | | height: 45px; |
| | | // border-bottom: 1px solid #e8e8e8; |
| | | overflow: hidden; |
| | | |
| | | .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; |
| | |
| | | } |
| | | .loading-mask { |
| | | position: absolute; |
| | | left: 20px; |
| | | left: 0px; |
| | | top: 0; |
| | | right: 20px; |
| | | bottom: 30px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | text-align: justify; |
| | | right: 0px; |
| | | bottom: 0px; |
| | | z-index: 1; |
| | | |
| | | .ant-spin-blur { |
| | |
| | | opacity: 0.5; |
| | | background: #ffffff; |
| | | } |
| | | } |
| | | .chart-title + .loading-mask { |
| | | top: 40px; |
| | | } |
| | | > .ant-select { |
| | | width: 150px; |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import './index.scss' |
| | | |
| | | const SearchComponent = asyncComponent(() => import('@/tabviews/zshare/topSearch')) |
| | | |
| | | class NormalHeader extends Component { |
| | | static propTpyes = { |
| | | BID: PropTypes.any, // 上级主键值 |
| | | menuType: PropTypes.any, // 菜单类型 |
| | | config: PropTypes.object, // 配置信息 |
| | | refresh: PropTypes.func // 条件刷新 |
| | | } |
| | | |
| | | state = { |
| | | title: '', // 标题 |
| | | show: false, // 是否显示搜索 |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { config } = this.props |
| | | |
| | | this.setState({ |
| | | title: config.plot ? config.plot.title : config.wrap.title, |
| | | show: !['normaltable', 'propcard'].includes(config.subtype) && config.search && config.search.length > 0 |
| | | }) |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { return false } |
| | | |
| | | /** |
| | | * @description 组件销毁,清除state更新,清除快捷键设置 |
| | | */ |
| | | componentWillUnmount () { |
| | | this.setState = () => { |
| | | return |
| | | } |
| | | } |
| | | |
| | | render() { |
| | | const { config, menuType, BID } = this.props |
| | | const { title, show } = this.state |
| | | |
| | | if (!title && !show) return null |
| | | |
| | | return ( |
| | | <div className="normal-header" style={config.headerStyle}> |
| | | <span className="title">{title}</span> |
| | | {show ? <SearchComponent config={config} BID={BID} menuType={menuType} refreshdata={this.props.refresh}/> : null} |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default NormalHeader |
New file |
| | |
| | | .normal-header { |
| | | position: relative; |
| | | height: 45px; |
| | | padding-right: 8px; |
| | | border-bottom: 1px solid #e8e8e8; |
| | | overflow: hidden; |
| | | letter-spacing: 0px; |
| | | |
| | | .title { |
| | | text-decoration: inherit; |
| | | font-weight: inherit; |
| | | font-style: inherit; |
| | | float: left; |
| | | line-height: 45px; |
| | | margin-left: 10px; |
| | | position: relative; |
| | | z-index: 1; |
| | | } |
| | | .top-search { |
| | | background: transparent; |
| | | text-decoration: unset; |
| | | font-weight: normal; |
| | | font-style: normal; |
| | | letter-spacing: 0px; |
| | | >.ant-row { |
| | | >.ant-col { |
| | | height: 45px; |
| | | line-height: 45px; |
| | | .ant-input { |
| | | height: 28px; |
| | | } |
| | | .ant-select-selection { |
| | | height: 28px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | .normal-header.hidden { |
| | | display: none; |
| | | } |
| | |
| | | |
| | | // 通用组件 |
| | | const AntvBarAndLine = asyncComponent(() => import('@/tabviews/custom/components/chart/antv-bar-line')) |
| | | const MainSearch = asyncComponent(() => import('@/tabviews/custom/components/search/main-search')) |
| | | const MainSearch = asyncComponent(() => import('@/tabviews/zshare/topSearch')) |
| | | const AntvPie = asyncComponent(() => import('@/tabviews/custom/components/chart/antv-pie')) |
| | | const AntvTabs = asyncComponent(() => import('@/tabviews/custom/components/tabs/antv-tabs')) |
| | | const DataCard = asyncComponent(() => import('@/tabviews/custom/components/card/data-card')) |
| | |
| | | const MainSearch = asyncComponent(() => import('@/tabviews/zshare/topSearch')) |
| | | const MainAction = asyncComponent(() => import('@/tabviews/zshare/actionList')) |
| | | const MainTable = asyncComponent(() => import('@/tabviews/custom/components/share/normalTable')) |
| | | const NormalHeader = asyncComponent(() => import('@/tabviews/custom/components/share/normalheader')) |
| | | |
| | | class NormalTable extends Component { |
| | | static propTpyes = { |
| | |
| | | |
| | | return ( |
| | | <div className="custom-normal-table"> |
| | | <NormalHeader config={config}/> |
| | | {searchlist && searchlist.length ? |
| | | <MainSearch BID={BID} searchlist={searchlist} menuType={this.props.menuType} refreshdata={this.refreshbysearch}/> : null |
| | | } |
| | |
| | | .custom-normal-table { |
| | | position: relative; |
| | | |
| | | .normal-header { |
| | | margin-bottom: 10px; |
| | | } |
| | | .top-search { |
| | | padding: 0; |
| | | border-bottom: 1px solid #efefef; |
| | | } |
| | | >.button-list.toolbar-button { |
| | | padding: 0; |
| | |
| | | const DataCard = asyncComponent(() => import('./components/card/data-card')) |
| | | const PropCard = asyncComponent(() => import('./components/card/prop-card')) |
| | | const TableCard = asyncComponent(() => import('./components/card/table-card')) |
| | | const MainSearch = asyncComponent(() => import('./components/search/main-search')) |
| | | const MainSearch = asyncComponent(() => import('@/tabviews/zshare/topSearch')) |
| | | const NormalTable = asyncComponent(() => import('./components/table/normal-table')) |
| | | |
| | | class CustomPage extends Component { |
| | |
| | | position: relative; |
| | | min-height: 200px; |
| | | |
| | | > .top-search { |
| | | padding: 0 0px 10px; |
| | | >.top-search { |
| | | padding: 0px 0px 5px; |
| | | border-bottom: 1px solid #efefef; |
| | | } |
| | | .sub-action { |
| | | min-height: 25px; |
| | |
| | | position: relative; |
| | | min-height: 200px; |
| | | padding-top: 16px; |
| | | > .top-search { |
| | | padding: 0 0px 10px; |
| | | >.top-search { |
| | | padding: 0px 0px 5px; |
| | | border-bottom: 1px solid #efefef; |
| | | } |
| | | .box404 { |
| | | padding-top: 30px; |
| | |
| | | pattern: /^[^']*$/ig, |
| | | message: formRule.input.quotemsg |
| | | }] |
| | | |
| | | if (item.regular) { |
| | | if (item.regular === 'number') { |
| | | _rules = [{ |
| | | pattern: /^[0-9]*$/ig, |
| | | pattern: /^[0-9.]*$/ig, |
| | | message: formRule.input.numbermsg |
| | | }] |
| | | } else if (item.regular === 'letter') { |
| | |
| | | }] |
| | | } |
| | | } |
| | | |
| | | fields.push( |
| | | <Col span={_colspan} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | |
| | | </Tooltip> : item.label |
| | | }> |
| | | {getFieldDecorator(item.field, { |
| | | initialValue: item.initval, |
| | | initialValue: item.initval + '', |
| | | rules: [ |
| | | { |
| | | required: item.required === 'true', |
| | |
| | | import enUS from '@/locales/en-US/main.js' |
| | | import './index.scss' |
| | | |
| | | const {MonthPicker, WeekPicker, RangePicker} = DatePicker |
| | | const { MonthPicker, WeekPicker, RangePicker } = DatePicker |
| | | |
| | | class MainSearch extends Component { |
| | | static propTpyes = { |
| | | BID: PropTypes.any, // 父级Id,用于查询下拉选择项 |
| | | menuType: PropTypes.any, // 菜单权限,是否为HS |
| | | searchlist: PropTypes.array, // 搜索条件列表 |
| | | config: PropTypes.object, // 组件配置信息(自定义页面) |
| | | refreshdata: PropTypes.func // 刷新数据 |
| | | } |
| | | |
| | | state = { |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | match: null, // 搜索条件匹配规则 |
| | | style: null, // 搜索条件类型 |
| | | label: null, // 提示文字 |
| | | required: null, // 是否必填 |
| | | searchlist: null, // 搜索项 |
| | | groups: null, // 组合搜索项 |
| | | formId: Utils.getuuid() // 搜索表单Id |
| | | formId: '', // 搜索表单Id |
| | | match: null, // 搜索条件匹配规则 |
| | | style: null, // 搜索条件类型 |
| | | label: null, // 提示文字 |
| | | required: null, // 是否必填 |
| | | searchlist: null, // 搜索项 |
| | | groups: null, // 组合搜索项 |
| | | float: '', // 浮动 |
| | | showButton: true, // 是否显示搜索按钮 |
| | | searchStyle: null // 搜索条件样式 |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | let searchlist = fromJS(this.props.searchlist).toJS() |
| | | const { config, menuType, searchlist } = this.props |
| | | |
| | | let _searchlist = [] |
| | | let match = {} |
| | | let label = {} |
| | | let style = {} |
| | |
| | | let mainItems = [] // 云端或单点数据 |
| | | let localItems = [] // 本地数据 |
| | | let deForms = [] // 测试系统,单个请求 |
| | | let float = '' |
| | | let showButton = true |
| | | let searchStyle = null |
| | | let formId = Utils.getuuid() |
| | | |
| | | searchlist.forEach(item => { |
| | | if (searchlist) { |
| | | _searchlist = fromJS(searchlist).toJS() |
| | | } else if (config) { |
| | | _searchlist = fromJS(config.search).toJS() |
| | | if (config.type === 'search' && config.subtype === 'mainsearch') { |
| | | float = config.wrap.float |
| | | showButton = config.wrap.float === 'left' && config.wrap.show === 'true' |
| | | searchStyle = config.style |
| | | } else { |
| | | formId = '' |
| | | showButton = false |
| | | float = 'right' |
| | | } |
| | | } |
| | | |
| | | _searchlist.forEach(item => { |
| | | if (fieldMap.has(item.field)) { |
| | | item.field = item.field + '@tail@' |
| | | } |
| | |
| | | } |
| | | |
| | | // 测试系统单个请求 |
| | | if (this.props.menuType !== 'HS' && options.sysType === 'local' && !window.GLOB.systemType) { |
| | | if (menuType !== 'HS' && options.sysType === 'local' && !window.GLOB.systemType) { |
| | | deForms.push({ |
| | | ...item, |
| | | arr_field: _option.field, |
| | |
| | | }) |
| | | |
| | | this.setState({ |
| | | match: match, |
| | | label: label, |
| | | style: style, |
| | | required: required, |
| | | match, |
| | | label, |
| | | style, |
| | | float, |
| | | formId, |
| | | required, |
| | | showButton, |
| | | searchStyle, |
| | | searchlist: _list, |
| | | groups: _groups |
| | | }, () => { |
| | | if (this.props.menuType !== 'HS' && options.sysType === 'local' && !window.GLOB.systemType) { |
| | | if (menuType !== 'HS' && options.sysType === 'local' && !window.GLOB.systemType) { |
| | | this.improveSimpleSearch(deForms) |
| | | } else { |
| | | this.improveSearch(mainItems, localItems) |
| | |
| | | |
| | | getFields() { |
| | | const { getFieldDecorator } = this.props.form |
| | | const { dict } = this.state |
| | | const { dict, showButton, formId } = this.state |
| | | const fields = [] |
| | | |
| | | this.state.searchlist.forEach((item, index) => { |
| | |
| | | if (item.type === 'text') { // 文本搜索 |
| | | fields.push( |
| | | <Col span={item.ratio || 6} key={index}> |
| | | <Form.Item label={item.label}> |
| | | <Form.Item label={item.labelShow !== 'false' ? item.label : ''}> |
| | | {getFieldDecorator(item.field, { |
| | | initialValue: item.initval, |
| | | rules: [ |
| | |
| | | message: dict['form.required.input'] + item.label + '!' |
| | | } |
| | | ] |
| | | })(<Input placeholder="" autoComplete="off" />)} |
| | | })(<Input placeholder={item.labelShow === 'false' ? item.label : ''} autoComplete="off" onPressEnter={this.handleSearch} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'select') { // 下拉搜索 |
| | | fields.push( |
| | | <Col span={item.ratio || 6} key={index}> |
| | | <Form.Item label={item.label}> |
| | | <Form.Item label={item.labelShow !== 'false' ? item.label : ''}> |
| | | {getFieldDecorator(item.field, { |
| | | initialValue: item.initval, |
| | | rules: [ |
| | |
| | | showSearch |
| | | onChange={(value) => {this.selectChange(item, value)}} |
| | | filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} |
| | | getPopupContainer={() => document.getElementById(this.state.formId)} |
| | | getPopupContainer={() => formId ? document.getElementById(formId) : document.body} |
| | | > |
| | | {item.options.map((option, i) => |
| | | <Select.Option id={`${i}`} title={option.Text} key={`${i}`} value={option.Value}>{option.Text}</Select.Option> |
| | |
| | | let _initval = item.initval ? item.initval.split(',').filter(Boolean) : [] |
| | | fields.push( |
| | | <Col span={item.ratio || 6} key={index}> |
| | | <Form.Item label={item.label}> |
| | | <Form.Item label={item.labelShow !== 'false' ? item.label : ''}> |
| | | {getFieldDecorator(item.field, { |
| | | initialValue: _initval, |
| | | rules: [ |
| | |
| | | mode="multiple" |
| | | onChange={this.searchChange} |
| | | filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} |
| | | getPopupContainer={() => document.getElementById(this.state.formId)} |
| | | getPopupContainer={() => formId ? document.getElementById(formId) : document.body} |
| | | > |
| | | {item.options.map((option, i) => |
| | | <Select.Option id={`${i}`} title={option.Text} key={`${i}`} value={option.Value}>{option.Text}</Select.Option> |
| | |
| | | } else if (item.type === 'date') { // 时间搜索 |
| | | fields.push( |
| | | <Col span={item.ratio || 6} key={index}> |
| | | <Form.Item label={item.label}> |
| | | <Form.Item label={item.labelShow !== 'false' ? item.label : ''}> |
| | | {getFieldDecorator(item.field, { |
| | | initialValue: item.initval ? moment().subtract(item.initval, 'days') : null, |
| | | rules: [ |
| | |
| | | } |
| | | ] |
| | | })( |
| | | <DatePicker onChange={this.searchChange} getCalendarContainer={() => document.getElementById(this.state.formId)} /> |
| | | <DatePicker onChange={this.searchChange} getCalendarContainer={() => formId ? document.getElementById(formId) : document.body} /> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | |
| | | } else if (item.type === 'datemonth') { |
| | | fields.push( |
| | | <Col span={item.ratio || 6} key={index}> |
| | | <Form.Item label={item.label}> |
| | | <Form.Item label={item.labelShow !== 'false' ? item.label : ''}> |
| | | {getFieldDecorator(item.field, { |
| | | initialValue: item.initval ? moment().subtract(item.initval, 'month') : null, |
| | | rules: [ |
| | |
| | | } |
| | | ] |
| | | })( |
| | | <MonthPicker onChange={this.searchChange} getCalendarContainer={() => document.getElementById(this.state.formId)} /> |
| | | <MonthPicker onChange={this.searchChange} getCalendarContainer={() => formId ? document.getElementById(formId) : document.body} /> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | |
| | | } else if (item.type === 'dateweek') { |
| | | fields.push( |
| | | <Col span={item.ratio || 6} key={index}> |
| | | <Form.Item label={item.label}> |
| | | <Form.Item label={item.labelShow !== 'false' ? item.label : ''}> |
| | | {getFieldDecorator(item.field, { |
| | | initialValue: item.initval ? moment().subtract(item.initval * 7, 'days') : null, |
| | | rules: [ |
| | |
| | | } |
| | | ] |
| | | })( |
| | | <WeekPicker onChange={this.searchChange} getCalendarContainer={() => document.getElementById(this.state.formId)} /> |
| | | <WeekPicker onChange={this.searchChange} getCalendarContainer={() => formId ? document.getElementById(formId) : document.body} /> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | |
| | | |
| | | fields.push( |
| | | <Col className="daterange" span={item.ratio || 6} key={index}> |
| | | <Form.Item label={item.label}> |
| | | <Form.Item label={item.labelShow !== 'false' ? item.label : ''}> |
| | | {getFieldDecorator(item.field, |
| | | { |
| | | initialValue: _defaultValue, |
| | |
| | | placeholder={['开始日期', '结束日期']} |
| | | renderExtraFooter={() => 'extra footer'} |
| | | onChange={this.searchChange} |
| | | getCalendarContainer={() => document.getElementById(this.state.formId)} |
| | | getCalendarContainer={() => formId ? document.getElementById(formId) : document.body} |
| | | /> |
| | | )} |
| | | </Form.Item> |
| | |
| | | } else if (item.type === 'group') { |
| | | fields.push( |
| | | <Col span={item.ratio || 6} key={index}> |
| | | <Form.Item label={item.label} className={item.required === 'true' ? 'group-required' : ''}> |
| | | <Form.Item label={item.labelShow !== 'false' ? item.label : ''} className={item.required === 'true' ? 'group-required' : ''}> |
| | | <DateGroup ref={item.uuid} position={index} card={item} onGroupChange={this.searchChange} /> |
| | | </Form.Item> |
| | | </Col> |
| | |
| | | } |
| | | }) |
| | | |
| | | fields.push( |
| | | <Col span={6} style={{ whiteSpace: 'nowrap' }} key="actions"> |
| | | <Form.Item label={' '} colon={false} style={{ minHeight: '40px' }}> |
| | | <Button type="primary" htmlType="submit"> |
| | | {dict['main.search']} |
| | | </Button> |
| | | <Button style={{ marginLeft: 8 }} onClick={this.handleReset}> |
| | | {dict['main.reset']} |
| | | </Button> |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | if (showButton) { |
| | | fields.push( |
| | | <Col span={6} style={{ whiteSpace: 'nowrap' }} key="actions"> |
| | | <Form.Item label={' '} colon={false} style={{ minHeight: '40px' }}> |
| | | <Button type="primary" onClick={this.handleSearch}> |
| | | {dict['main.search']} |
| | | </Button> |
| | | <Button style={{ marginLeft: 8 }} onClick={this.handleReset}> |
| | | {dict['main.reset']} |
| | | </Button> |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } |
| | | |
| | | return fields |
| | | } |
| | |
| | | } |
| | | |
| | | render() { |
| | | const { float, searchStyle } = this.state |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | |
| | | } |
| | | |
| | | return ( |
| | | <Form {...formItemLayout} className="top-search" id={this.state.formId} onSubmit={this.handleSearch}> |
| | | <Form {...formItemLayout} className={`top-search ${float}`} style={searchStyle} id={this.state.formId}> |
| | | <Row gutter={24}>{this.getFields()}</Row> |
| | | </Form> |
| | | ) |
| | |
| | | .top-search { |
| | | padding: 0px 24px 10px; |
| | | border-bottom: 1px solid #efefef; |
| | | background: #ffffff; |
| | | .ant-form-item { |
| | | display: flex; |
| | | margin-bottom: 0px; |
| | |
| | | width: calc(100% - 100px); |
| | | } |
| | | .ant-form-item-label { |
| | | // width: 100px; |
| | | text-overflow: ellipsis; |
| | | } |
| | | .daterange .ant-calendar-picker-input { |
| | |
| | | content: '*'; |
| | | } |
| | | } |
| | | } |
| | | .top-search.right { |
| | | >.ant-row { |
| | | >.ant-col { |
| | | float: right; |
| | | } |
| | | } |
| | | } |
| | |
| | | import React from 'react' |
| | | import { useDrag, useDrop } from 'react-dnd' |
| | | import { Icon, Select, DatePicker, Input, Popover } from 'antd' |
| | | import { Icon, Select, DatePicker, Input, Popover, Form } from 'antd' |
| | | import moment from 'moment' |
| | | |
| | | import DateGroup from '../dategroup' |
| | |
| | | <Icon className="close" title="delete" type="close" onClick={() => delCard(id)} /> |
| | | </div> |
| | | } trigger="hover"> |
| | | <div className="page-card" style={{ opacity: opacity}}> |
| | | <div className={'page-card ' + (card.labelShow || '')} style={{ opacity: opacity}}> |
| | | <div ref={node => drag(drop(node))}> |
| | | <div className="ant-row ant-form-item"> |
| | | <div className="ant-col ant-form-item-label ant-col-xs-24 ant-col-sm-8"> |
| | | <label className={card.required === 'true' ? 'ant-form-item-required' : ''} title={card.label}>{card.label}</label> |
| | | </div> |
| | | <div className="ant-col ant-form-item-control-wrapper ant-col-xs-24 ant-col-sm-16"> |
| | | {card.type === 'text' ? |
| | | <Input style={{marginTop: '4px'}} value={card.initval} /> : null |
| | | } |
| | | {(card.type === 'multiselect' || card.type === 'select' || card.type === 'link') ? |
| | | <Select value={_defaultValue}></Select> : null |
| | | } |
| | | {card.type === 'date' ? |
| | | <DatePicker value={card.initval ? moment().subtract(card.initval, 'days') : null} /> : null |
| | | } |
| | | {card.type === 'dateweek' ? |
| | | <WeekPicker value={card.initval ? moment().subtract(card.initval * 7, 'days') : null} /> : null |
| | | } |
| | | {card.type === 'datemonth' ? |
| | | <MonthPicker value={card.initval ? moment().subtract(card.initval, 'month') : null} /> : null |
| | | } |
| | | {card.type === 'daterange' ? |
| | | <RangePicker |
| | | className="data-range" |
| | | placeholder={['BeginTime', 'EndTime']} |
| | | renderExtraFooter={() => 'extra footer'} |
| | | value={_defaultValue} |
| | | /> : null |
| | | } |
| | | {card.type === 'group' ? <DateGroup card={card} /> : null } |
| | | </div> |
| | | </div> |
| | | <Form.Item |
| | | labelCol={{xs: { span: 24 }, sm: { span: 8 }}} |
| | | wrapperCol = {{xs: { span: 24 }, sm: { span: 16 }}} |
| | | label={card.labelShow !== 'false' ? card.label : ''} |
| | | required={card.required === 'true'} |
| | | > |
| | | {card.type === 'text' ? |
| | | <Input style={{marginTop: '4px'}} value={card.initval} /> : null |
| | | } |
| | | {(card.type === 'multiselect' || card.type === 'select' || card.type === 'link') ? |
| | | <Select value={_defaultValue}></Select> : null |
| | | } |
| | | {card.type === 'date' ? |
| | | <DatePicker value={card.initval ? moment().subtract(card.initval, 'days') : null} /> : null |
| | | } |
| | | {card.type === 'dateweek' ? |
| | | <WeekPicker value={card.initval ? moment().subtract(card.initval * 7, 'days') : null} /> : null |
| | | } |
| | | {card.type === 'datemonth' ? |
| | | <MonthPicker value={card.initval ? moment().subtract(card.initval, 'month') : null} /> : null |
| | | } |
| | | {card.type === 'daterange' ? |
| | | <RangePicker |
| | | className="data-range" |
| | | placeholder={['BeginTime', 'EndTime']} |
| | | renderExtraFooter={() => 'extra footer'} |
| | | value={_defaultValue} |
| | | /> : null |
| | | } |
| | | {card.type === 'group' ? <DateGroup card={card} /> : null } |
| | | </Form.Item> |
| | | </div> |
| | | </div> |
| | | </Popover> |
| | |
| | | border-radius: 2px; |
| | | padding-bottom: 15px; |
| | | .ant-form-item { |
| | | cursor: move; |
| | | display: flex; |
| | | margin-bottom: 0px; |
| | | .ant-form-item-label { |
| | | height: 40px; |
| | | label { |
| | | width: 100%; |
| | | cursor: move; |
| | | overflow: hidden; |
| | | display: inline-block; |
| | | text-overflow: ellipsis; |
| | | white-space: nowrap; |
| | | } |
| | | } |
| | | .ant-form-item-control-wrapper { |
| | | flex: 1 1; |
| | | .ant-select { |
| | | width: 100%; |
| | | margin-top: 4px; |
| | | .ant-select-selection { |
| | | height: 32px; |
| | | } |
| | | } |
| | | .ant-calendar-picker { |
| | | margin-top: 4px; |
| | | } |
| | | |
| | | .data-range .ant-calendar-picker-input { |
| | | padding: 4px 20px 4px 5px; |
| | | font-size: 13px; |
| | | } |
| | | } |
| | | .ant-form-item-control-wrapper::after { |
| | | content: ''; |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | opacity: 0; |
| | | z-index: 2; |
| | | } |
| | | } |
| | | .edit { |
| | | >div::after { |
| | | display: block; |
| | | content: ' '; |
| | | position: absolute; |
| | | cursor: move; |
| | | top: 0; |
| | | left: 0; |
| | | top: 5px; |
| | | color: #1890ff; |
| | | cursor: pointer; |
| | | display: none; |
| | | } |
| | | .edit.copy { |
| | | left: 20px; |
| | | color: #26C281; |
| | | } |
| | | .edit.close { |
| | | left: 40px; |
| | | color: #ff4d4f; |
| | | right: 0; |
| | | bottom: 0; |
| | | opacity: 0; |
| | | z-index: 2; |
| | | } |
| | | } |
| | | .page-card:hover { |
| | | .edit { |
| | | display: inline-block; |
| | | .page-card.false { |
| | | .ant-form-item-label { |
| | | display: none; |
| | | } |
| | | .ant-form-item-control-wrapper { |
| | | width: 100%; |
| | | } |
| | | } |
| | | .ant-calendar-picker { |
| | |
| | | import Api from '@/api' |
| | | import Utils from '@/utils/utils.js' |
| | | import PasteForm from '@/templates/zshare/pasteform' |
| | | import ReplaceForm from '@/templates/zshare/replaceform' |
| | | import TransferForm from '@/templates/zshare/basetransferform' |
| | | import zhCN from '@/locales/zh-CN/model.js' |
| | | import enUS from '@/locales/en-US/model.js' |
| | |
| | | thawVisible: false, |
| | | thawbtnlist: null, |
| | | pasteVisible: false, |
| | | replaceVisible: false |
| | | } |
| | | |
| | | handleMenuClick = e => { |
| | |
| | | this.handleThaw() |
| | | } else if (e.key === 'paste') { |
| | | this.setState({pasteVisible: true}) |
| | | } else if (e.key === 'replace') { |
| | | this.setState({replaceVisible: true}) |
| | | } |
| | | } |
| | | |
| | |
| | | }) |
| | | } |
| | | |
| | | replaceSubmit = () => { |
| | | this.replaceFormRef.handleConfirm().then(res => { |
| | | this.props.refresh({ |
| | | type: 'replace', |
| | | ...res |
| | | }) |
| | | this.setState({ |
| | | replaceVisible: false |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | render() { |
| | | const { MenuID } = this.props |
| | | const { dict } = this.state |
| | |
| | | <Menu onClick={this.handleMenuClick}> |
| | | {MenuID ? <Menu.Item key="thaw"><Icon type="unlock" />{dict['header.form.thawbutton']}</Menu.Item> : null} |
| | | <Menu.Item key="paste"><Icon type="snippets" />{dict['header.form.paste']}</Menu.Item> |
| | | {/* <Menu.Item key="replace"><Icon type="retweet" />替换</Menu.Item> */} |
| | | </Menu> |
| | | ) |
| | | |
| | |
| | | <PasteForm |
| | | dict={dict} |
| | | wrappedComponentRef={(inst) => this.pasteFormRef = inst} |
| | | /> |
| | | </Modal> |
| | | {/* 替换 */} |
| | | <Modal |
| | | title={'替换'} |
| | | visible={this.state.replaceVisible} |
| | | width={600} |
| | | maskClosable={false} |
| | | onOk={this.replaceSubmit} |
| | | onCancel={() => {this.setState({replaceVisible: false})}} |
| | | destroyOnClose |
| | | > |
| | | <ReplaceForm |
| | | dict={dict} |
| | | inputSubmit={this.replaceSubmit} |
| | | wrappedComponentRef={(inst) => this.replaceFormRef = inst} |
| | | /> |
| | | </Modal> |
| | | </div> |
| | |
| | | |
| | | Api.getTouristMsg().then(result => { |
| | | if (result.status) { |
| | | if (!sessionStorage.getItem('UserID') && result.UserID) { |
| | | sessionStorage.setItem('UserID', result.UserID) |
| | | } |
| | | if (!sessionStorage.getItem('LoginUID') && result.LoginUID) { |
| | | sessionStorage.setItem('LoginUID', result.LoginUID) |
| | | } |
| | | result.UserID && sessionStorage.setItem('UserID', result.UserID) |
| | | result.LoginUID && sessionStorage.setItem('LoginUID', result.LoginUID) |
| | | |
| | | if (result.UserID && result.LoginUID) { |
| | | this.setState({touristLogin: true}) |