| | |
| | | const { Search } = Input |
| | | const CheckCard = asyncComponent(() => import('@/templates/modalconfig/checkCard')) |
| | | |
| | | const Card = ({ id, card, showField, moveCard, copyCard, findCard, editCard, delCard }) => { |
| | | const Card = ({ id, card, moveCard, copyCard, findCard, editCard, delCard }) => { |
| | | const originalIndex = findCard(id).index |
| | | const [{ isDragging }, drag] = useDrag({ |
| | | item: { type: 'search', id, originalIndex }, |
| | |
| | | wrapperCol = {{xs: { span: 24 }, sm: { span: 16 }}} |
| | | label={card.labelShow !== 'false' ? card.label : ''} |
| | | required={card.required === 'true'} |
| | | help={showField ? card.field + (card.datefield ? ', ' + card.datefield : '') : ''} |
| | | help={card.field + (card.datefield ? ', ' + card.datefield : '') + (card.advanced === 'true' ? '(高级搜索)' : '')} |
| | | > |
| | | {formItem} |
| | | </Form.Item> |
| | |
| | | import Card from './card' |
| | | import './index.scss' |
| | | |
| | | const Container = ({list, showField, handleList, handleMenu, deleteMenu }) => { |
| | | const Container = ({list, setting, handleList, handleMenu, deleteMenu }) => { |
| | | const [cards, setCards] = useState(list) |
| | | const moveCard = (id, atIndex) => { |
| | | const { card, index } = findCard(id) |
| | |
| | | drop() {} |
| | | }) |
| | | |
| | | const appType = sessionStorage.getItem('appType') |
| | | let labelwidth = setting.searchLwidth !== undefined ? setting.searchLwidth : 33.3 |
| | | let advanceType = setting.advanceType || 'modal' |
| | | |
| | | return ( |
| | | <div ref={drop} className="ant-row"> |
| | | {cards.length > 0 ? <Col key="preaction" className="action pre-action" span={6}> |
| | | {cards.map(card => { |
| | | let _ratio = card.ratio || 6 |
| | | if (card.advanced === 'true' && advanceType !== 'pulldown') { |
| | | _ratio = 6 |
| | | } |
| | | return ( |
| | | <Col className="mk-search-item-wrap" key={card.uuid} span={_ratio}> |
| | | <Card |
| | | id={`${card.uuid}`} |
| | | card={card} |
| | | moveCard={moveCard} |
| | | copyCard={copyCard} |
| | | editCard={editCard} |
| | | delCard={delCard} |
| | | findCard={findCard} |
| | | /> |
| | | </Col> |
| | | ) |
| | | })} |
| | | {cards.length > 0 ? <Col key="nextaction" className={'mk-search-item-wrap action' + (setting.show === 'false' ? ' hide-button' : '')} span={setting.searchRatio || 6}> |
| | | <div className="ant-row ant-form-item" style={{lineHeight: '40px', height: '55px', marginBottom: 0}}> |
| | | <div className="ant-col ant-form-item-label ant-col-xs-24 ant-col-sm-8"> |
| | | </div> |
| | | <div className="ant-col ant-form-item-control-wrapper ant-col-xs-24 ant-col-sm-16" style={{whiteSpace: 'nowrap'}}> |
| | | <div className="ant-col ant-form-item-label" style={{width: labelwidth + '%'}}></div> |
| | | <div className="ant-col ant-form-item-control-wrapper" style={{whiteSpace: 'nowrap'}}> |
| | | <Button type="primary">搜索</Button> |
| | | {appType !== 'mob' ? <Button style={{ marginLeft: 8 }}>重置</Button> : null} |
| | | <div style={{position: 'absolute', top: 0, bottom: 0, left: 0, right: 0}}></div> |
| | | </div> |
| | | </div> |
| | | </Col> : null} |
| | | {cards.map(card => ( |
| | | <Col key={card.uuid} span={card.ratio || 6}> |
| | | <Card |
| | | id={`${card.uuid}`} |
| | | card={card} |
| | | showField={showField} |
| | | moveCard={moveCard} |
| | | copyCard={copyCard} |
| | | editCard={editCard} |
| | | delCard={delCard} |
| | | findCard={findCard} |
| | | /> |
| | | </Col> |
| | | ))} |
| | | {cards.length > 0 ? <Col key="nextaction" className="action next-action" span={6}> |
| | | <div className="ant-row ant-form-item" style={{lineHeight: '40px', height: '55px', marginBottom: 0}}> |
| | | <div className="ant-col ant-form-item-label ant-col-xs-24 ant-col-sm-8"> |
| | | </div> |
| | | <div className="ant-col ant-form-item-control-wrapper ant-col-xs-24 ant-col-sm-16" style={{whiteSpace: 'nowrap'}}> |
| | | <Button type="primary">搜索</Button> |
| | | {appType !== 'mob' ? <Button style={{ marginLeft: 8 }}>重置</Button> : null} |
| | | <Button style={{ marginLeft: 8 }}>重置</Button> |
| | | <div style={{position: 'absolute', top: 0, bottom: 0, left: 0, right: 0}}></div> |
| | | </div> |
| | | </div> |
| | |
| | | let _style = resetStyle(card.style) |
| | | |
| | | return ( |
| | | <div className={`main-search-edit-list ${card.wrap.float} ${card.wrap.show || ''}`} onClick={this.clickComponent} id={card.uuid} style={_style}> |
| | | <div className={`main-search-edit-list ${card.wrap.float} ${showField ? 'show-field' : ''}`} onClick={this.clickComponent} id={card.uuid} style={_style}> |
| | | <FieldsComponent config={card} type="search" /> |
| | | <Switch checkedChildren={dict['model.switch.open']} size="small" unCheckedChildren={dict['model.switch.close']} defaultChecked={showField} onChange={this.onFieldChange} /> |
| | | <DragElement |
| | | list={card.search} |
| | | showField={showField} |
| | | setting={card.wrap} |
| | | handleList={this.handleList} |
| | | handleMenu={this.handleSearch} |
| | | deleteMenu={this.deleteElement} |
| | |
| | | padding: 0 12px!important; |
| | | } |
| | | } |
| | | >.ant-row:not(.ant-form-item) { |
| | | > .ant-col { |
| | | display: inline-block; |
| | | float: none; |
| | | vertical-align: top; |
| | | } |
| | | .mk-search-item-wrap { |
| | | display: inline-block; |
| | | float: none; |
| | | vertical-align: top; |
| | | } |
| | | .ant-row.ant-form-item .ant-col { |
| | | padding: 0; |
| | |
| | | width: 100%; |
| | | } |
| | | } |
| | | .mk-search-item-wrap.action { |
| | | .ant-form-item-label, .ant-form-item-control-wrapper { |
| | | display: inline-block; |
| | | } |
| | | } |
| | | .mk-search-item-wrap.action.hide-button { |
| | | display: none; |
| | | } |
| | | .ant-calendar-picker { |
| | | min-width: 100px!important; |
| | | width: 100%; |
| | |
| | | } |
| | | } |
| | | } |
| | | .main-search-edit-list:not(.right) { |
| | | .pre-action { |
| | | display: none!important; |
| | | } |
| | | } |
| | | |
| | | .main-search-edit-list.right { |
| | | .next-action { |
| | | display: none!important; |
| | | } |
| | | >.ant-row { |
| | | >.ant-col { |
| | | float: right; |
| | | } |
| | | text-align: right; |
| | | } |
| | | } |
| | | .main-search-edit-list.false { |
| | | >.ant-row { |
| | | >.ant-col.action { |
| | | display: none; |
| | | } |
| | | |
| | | .main-search-edit-list:not(.show-field) { |
| | | .ant-form-explain { |
| | | display: none; |
| | | } |
| | | } |
| | | |
| | | .main-search-edit-list::after { |
| | | display: block; |
| | | content: ' '; |
| | |
| | | required: true |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | field: 'advanceType', |
| | | label: '高级搜索', |
| | | initval: wrap.advanceType || 'modal', |
| | | required: false, |
| | | options: [ |
| | | {value: 'modal', label: '弹窗'}, |
| | | {value: 'drawer', label: '抽屉'}, |
| | | {value: 'pulldown', label: '下拉'} |
| | | ], |
| | | controlFields: [ |
| | | {field: 'advanceWidth', values: ['modal', 'drawer']}, |
| | | {field: 'drawerPlacement', values: ['drawer']} |
| | | ] |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | field: 'drawerPlacement', |
| | | label: '抽屉方向', |
| | | initval: wrap.drawerPlacement || 'right', |
| | | required: false, |
| | | options: [ |
| | | {value: 'right', label: '右侧'}, |
| | | {value: 'left', label: '左侧'}, |
| | | {value: 'top', label: '上侧'}, |
| | | {value: 'bottom', label: '下侧'} |
| | | ] |
| | | }, |
| | | { |
| | | type: 'number', |
| | | field: 'advanceWidth', |
| | | label: '高级搜索', |
| | | label: '弹窗宽度', |
| | | initval: wrap.advanceWidth || 1000, |
| | | tooltip: '高级搜索弹窗的宽度,注:当宽度值小于100时表示占窗口的百分比,大于100时表示宽度的绝对值。', |
| | | tooltip: '高级搜索弹窗的宽度,注:当宽度值小于100时表示占窗口的百分比,大于100时表示宽度的绝对值。当使用上下显示的抽屉时代表抽屉高度。', |
| | | min: 10, |
| | | max: 3000, |
| | | precision: 0, |
| | | required: false |
| | | }, |
| | | { |
| | | type: 'number', |
| | | field: 'searchRatio', |
| | | label: '按钮比例', |
| | | initval: wrap.searchRatio || 6, |
| | | tooltip: '搜索及重置按钮所占比例。栅格布局,每行等分为24列。', |
| | | min: 1, |
| | | max: 24, |
| | | precision: 0, |
| | | required: true |
| | | }, |
| | | { |
| | | type: 'number', |
| | | field: 'searchLwidth', |
| | | label: '按钮偏移', |
| | | initval: wrap.searchLwidth !== undefined ? wrap.searchLwidth : 33.3, |
| | | tooltip: '搜索按钮距左侧的百分比,参照搜索条件的名称宽度。', |
| | | min: 0, |
| | | max: 100, |
| | | precision: 10, |
| | | required: true |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | field: 'float', |
| | | label: '对齐', |
| | | initval: wrap.float || 'left', |
| | | tooltip: '右对齐时,隐藏搜索按钮。', |
| | | required: false, |
| | | options: [ |
| | | {value: 'left', label: '左对齐'}, |
| | |
| | | <Form.Item |
| | | labelCol={{style: {width: labelwidth + '%'}}} |
| | | wrapperCol={{style: {width: (100 - labelwidth) + '%'}}} |
| | | // labelCol={{xs: { span: 24 }, sm: { span: 8 }}} |
| | | // wrapperCol = {{xs: { span: 24 }, sm: { span: 16 }}} |
| | | label={card.labelShow !== 'false' ? card.label : ''} |
| | | required={card.required === 'true'} |
| | | > |
| | |
| | | {value: 'ghost', label: '透明'}, |
| | | ] |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | field: 'show', |
| | | label: '搜索按钮', |
| | | initval: wrap.show || 'true', |
| | | tooltip: '搜索条件存在时,可选择是否显示搜索按钮。', |
| | | required: false, |
| | | options: [ |
| | | {value: 'true', label: '显示'}, |
| | | {value: 'false', label: '隐藏'}, |
| | | ] |
| | | }, |
| | | // { |
| | | // type: 'radio', |
| | | // field: 'show', |
| | | // label: '搜索按钮', |
| | | // initval: wrap.show || 'true', |
| | | // tooltip: '搜索条件存在时,可选择是否显示搜索按钮。', |
| | | // required: false, |
| | | // options: [ |
| | | // {value: 'true', label: '显示'}, |
| | | // {value: 'false', label: '隐藏'}, |
| | | // ] |
| | | // }, |
| | | { |
| | | type: 'color', |
| | | field: 'borderColor', |
| | |
| | | // precision: 0, |
| | | // required: false |
| | | // }, |
| | | { |
| | | type: 'number', |
| | | field: 'advanceWidth', |
| | | label: '高级搜索', |
| | | initval: wrap.advanceWidth || 1000, |
| | | tooltip: '高级搜索弹窗的宽度,注:当宽度值小于100时表示占窗口的百分比,大于100时表示宽度的绝对值。', |
| | | min: 10, |
| | | max: 3000, |
| | | precision: 0, |
| | | required: false |
| | | }, |
| | | // { |
| | | // type: 'number', |
| | | // field: 'advanceWidth', |
| | | // label: '高级搜索', |
| | | // initval: wrap.advanceWidth || 1000, |
| | | // tooltip: '高级搜索弹窗的宽度,注:当宽度值小于100时表示占窗口的百分比,大于100时表示宽度的绝对值。', |
| | | // min: 10, |
| | | // max: 3000, |
| | | // precision: 0, |
| | | // required: false |
| | | // }, |
| | | { |
| | | type: 'radio', |
| | | field: 'permission', |
| | |
| | | {value: 'always', label: '数据加载'}, |
| | | ] |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | field: 'show', |
| | | label: '搜索按钮', |
| | | initval: wrap.show || 'true', |
| | | tooltip: '搜索条件存在时,可选择是否显示搜索按钮。', |
| | | required: false, |
| | | options: [ |
| | | {value: 'true', label: '显示'}, |
| | | {value: 'false', label: '隐藏'}, |
| | | ] |
| | | }, |
| | | // { |
| | | // type: 'radio', |
| | | // field: 'show', |
| | | // label: '搜索按钮', |
| | | // initval: wrap.show || 'true', |
| | | // tooltip: '搜索条件存在时,可选择是否显示搜索按钮。', |
| | | // required: false, |
| | | // options: [ |
| | | // {value: 'true', label: '显示'}, |
| | | // {value: 'false', label: '隐藏'}, |
| | | // ] |
| | | // }, |
| | | { |
| | | type: 'color', |
| | | field: 'borderColor', |
| | |
| | | // precision: 0, |
| | | // required: false |
| | | // }, |
| | | { |
| | | type: 'number', |
| | | field: 'advanceWidth', |
| | | label: '高级搜索', |
| | | initval: wrap.advanceWidth || 1000, |
| | | tooltip: '高级搜索弹窗的宽度,注:当宽度值小于100时表示占窗口的百分比,大于100时表示宽度的绝对值。', |
| | | min: 10, |
| | | max: 3000, |
| | | precision: 0, |
| | | required: false, |
| | | forbid: appType === 'mob' |
| | | }, |
| | | // { |
| | | // type: 'number', |
| | | // field: 'advanceWidth', |
| | | // label: '高级搜索', |
| | | // initval: wrap.advanceWidth || 1000, |
| | | // tooltip: '高级搜索弹窗的宽度,注:当宽度值小于100时表示占窗口的百分比,大于100时表示宽度的绝对值。', |
| | | // min: 10, |
| | | // max: 3000, |
| | | // precision: 0, |
| | | // required: false, |
| | | // forbid: appType === 'mob' |
| | | // }, |
| | | { |
| | | type: 'select', |
| | | field: 'doubleClick', |
| | |
| | | |
| | | if (content) { |
| | | fields.push( |
| | | <Col span={item.ratio || 6} key={index}> |
| | | <Col className="mk-search-col" span={item.ratio || 6} key={index}> |
| | | <Form.Item |
| | | labelCol={item.labelCol} |
| | | wrapperCol={item.wrapperCol} |
| | |
| | | .advance-search { |
| | | background: #ffffff; |
| | | margin-bottom: 35px; |
| | | |
| | | .mk-search-col { |
| | | display: inline-block; |
| | | float: none; |
| | | vertical-align: top; |
| | | } |
| | | .ant-form-item { |
| | | display: flex; |
| | | margin-bottom: 0px; |
| | | min-height: 60px; |
| | | min-height: 55px; |
| | | .ant-form-explain { |
| | | white-space: nowrap; |
| | | } |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Form, Row, Col, Button, notification, Modal } from 'antd' |
| | | import { CloseOutlined } from '@ant-design/icons' |
| | | import { fromJS } from 'immutable' |
| | | import { Form, Row, Col, Button, notification, Modal, Drawer } from 'antd' |
| | | import { CloseOutlined, DownOutlined } from '@ant-design/icons' |
| | | import moment from 'moment' |
| | | |
| | | import Api from '@/api' |
| | |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import asyncSpinComponent from '@/utils/asyncSpinComponent' |
| | | import Utils from '@/utils/utils.js' |
| | | import zhCN from '@/locales/zh-CN/main.js' |
| | | import enUS from '@/locales/en-US/main.js' |
| | | import MKInput from './mkInput' |
| | | import './index.scss' |
| | | |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | searchlist: null, // 搜索项 |
| | | reset: true, // 控制组合搜索项重置 |
| | | float: '', // 浮动 |
| | | showButton: true, // 是否显示搜索按钮 |
| | | showAdvanced: false, // 是否显示高级搜索 |
| | | searchStyle: null, // 搜索条件样式 |
| | | setting: {}, |
| | | advanceValues: [], // 高级搜索条件保存值 |
| | | visible: false, |
| | | adModelWidth: '1000px', |
| | | hasReqFields: false |
| | | } |
| | | |
| | |
| | | let mainItems = [] // 云端或单点数据 |
| | | let localItems = [] // 本地数据 |
| | | let deForms = [] // 测试系统,单个请求 |
| | | let float = '' |
| | | let showButton = true |
| | | let searchStyle = null |
| | | let advanceValues = [] |
| | | let showAdvanced = false |
| | | let adModelWidth = 1000 |
| | | let linkFields = {} |
| | | let record = {} |
| | | let hasReqFields = false |
| | | |
| | | if (setting && setting.advanceWidth) { |
| | | adModelWidth = setting.advanceWidth |
| | | } else if (config && config.wrap && config.wrap.advanceWidth) { |
| | | adModelWidth = config.wrap.advanceWidth |
| | | let forbid = false // header中不设置高级搜索 |
| | | let _setting = {showAdv: false} |
| | | |
| | | if (setting) { |
| | | _setting.show = setting.show !== 'false' |
| | | _setting.float = setting.float || 'left' |
| | | _setting.advanceType = setting.advanceType || 'modal' |
| | | _setting.advWidth = setting.advanceWidth || 1000 |
| | | _setting.placement = setting.drawerPlacement || 'right' |
| | | _setting.ratio = setting.searchRatio || 6 |
| | | _setting.labelwidth = setting.searchLwidth !== undefined ? setting.searchLwidth : 33.3 |
| | | _setting.style = null |
| | | } else if (config && config.wrap) { |
| | | _setting.show = config.wrap.show !== 'false' |
| | | _setting.advanceType = config.wrap.advanceType || 'modal' |
| | | _setting.advWidth = config.wrap.advanceWidth || 1000 |
| | | _setting.placement = config.wrap.drawerPlacement || 'right' |
| | | _setting.ratio = config.wrap.searchRatio || 6 |
| | | _setting.labelwidth = config.wrap.searchLwidth !== undefined ? config.wrap.searchLwidth : 33.3 |
| | | _setting.style = null |
| | | |
| | | if (config.type === 'search') { |
| | | _setting.float = config.wrap.float || 'left' |
| | | _setting.style = config.style |
| | | } else { |
| | | _setting.float = 'right' |
| | | _setting.show = false |
| | | forbid = true |
| | | } |
| | | } |
| | | |
| | | if (adModelWidth < 100) { |
| | | adModelWidth = adModelWidth + 'vw' |
| | | } else { |
| | | adModelWidth = adModelWidth + 'px' |
| | | _setting.labelCol = {style: {width: _setting.labelwidth + '%'}} |
| | | _setting.wrapperCol = {style: {width: (100 - _setting.labelwidth) + '%'}} |
| | | |
| | | if (_setting.advanceType === 'drawer') { |
| | | if (_setting.placement === 'top' || _setting.placement === 'bottom') { |
| | | _setting.advHeight = _setting.advWidth > 100 ? _setting.advWidth + 'px' : _setting.advWidth + 'vh' |
| | | _setting.advWidth = '100vw' |
| | | } else { |
| | | _setting.advWidth = _setting.advWidth > 100 ? _setting.advWidth + 'px' : _setting.advWidth + 'vw' |
| | | } |
| | | } else if (_setting.advanceType === 'modal') { |
| | | if (_setting.advWidth < 100) { |
| | | _setting.advWidth = _setting.advWidth + 'vw' |
| | | } else { |
| | | _setting.advWidth = _setting.advWidth + 'px' |
| | | } |
| | | } |
| | | |
| | | if (searchlist) { |
| | | if (setting && setting.show === 'false') { |
| | | showButton = false |
| | | } |
| | | _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.show !== 'false' |
| | | searchStyle = config.style |
| | | } else { |
| | | showButton = false |
| | | float = 'right' |
| | | } |
| | | } |
| | | |
| | | _searchlist.forEach(item => { |
| | | // if (item.type === 'link') { |
| | | if (item.linkField) { |
| | | linkFields[item.linkField] = linkFields[item.linkField] || [] |
| | | linkFields[item.linkField].push({field: item.field, uuid: item.uuid}) |
| | |
| | | hasReqFields = true |
| | | } |
| | | |
| | | if (showButton && item.advanced) { |
| | | showAdvanced = true |
| | | if (item.advanced && !forbid) { |
| | | _setting.showAdv = true |
| | | } else { |
| | | item.advanced = false |
| | | } |
| | |
| | | }) |
| | | |
| | | this.setState({ |
| | | float, |
| | | showButton, |
| | | searchStyle, |
| | | setting: _setting, |
| | | hasReqFields, |
| | | showAdvanced, |
| | | adModelWidth, |
| | | advanceValues, |
| | | searchlist: _list |
| | | }, () => { |
| | |
| | | this.improveSearch(mainItems, localItems) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | // 查询下拉菜单 |
| | |
| | | |
| | | getFields() { |
| | | const { getFieldDecorator } = this.props.form |
| | | const { dict, showButton, showAdvanced, float, visible } = this.state |
| | | const { visible, setting } = this.state |
| | | const fields = [] |
| | | let lastRadio = 6 |
| | | |
| | | this.state.searchlist.forEach((item, index) => { |
| | | if (item.hidden || item.advanced) return |
| | | if (item.hidden || (item.advanced && (setting.advanceType !== 'pulldown' || !visible))) return |
| | | |
| | | const _rules = [ |
| | | { |
| | |
| | | ] |
| | | |
| | | let content = null |
| | | let className = '' |
| | | let field = item.field |
| | | lastRadio = item.ratio || 6 |
| | | |
| | | if (item.type === 'text') { |
| | | content = (<MKInput config={item} onInputSubmit={this.handleSubmit} />) |
| | |
| | | field = item.datefield |
| | | content = <DateGroup position={index} config={item} onChange={(val, type) => this.dateGroupChange(val, type, item)} /> |
| | | } else if (item.type === 'checkcard') { |
| | | className = 'checkcard' |
| | | content = <MKCheckCard config={item} onChange={(val) => this.cardChange(val, item)} /> |
| | | } |
| | | |
| | | if (content) { |
| | | fields.push( |
| | | <Col span={item.ratio || 6} key={index}> |
| | | <Col className="mk-search-col" span={item.ratio || 6} key={index}> |
| | | <Form.Item |
| | | className={className} |
| | | label={item.labelShow !== 'false' ? item.label : ''} |
| | | labelCol={item.labelCol} |
| | | wrapperCol={item.wrapperCol} |
| | |
| | | } |
| | | }) |
| | | |
| | | if (showButton) { |
| | | let action = ( |
| | | <Col span={lastRadio < 6 ? 6 : lastRadio} style={{ whiteSpace: 'nowrap' }} className="search-button" key="actions"> |
| | | <Form.Item label={' '} colon={false} style={{ minHeight: '40px' }}> |
| | | <Button type="primary" onClick={this.handleSubmit}> |
| | | {dict['main.search']} |
| | | </Button> |
| | | <Button style={{ marginLeft: 8 }} onClick={this.handleReset}> |
| | | {dict['main.reset']} |
| | | </Button> |
| | | {showAdvanced && !visible ? <Button type="link" onClick={this.handleAdvance}> |
| | | 高级 |
| | | if (setting.show || setting.showAdv) { |
| | | fields.push( |
| | | <Col span={setting.searchRatio} style={{ whiteSpace: 'nowrap' }} className="mk-search-col search-button" key="actions"> |
| | | <Form.Item |
| | | label={' '} |
| | | colon={false} |
| | | labelCol={setting.labelCol} |
| | | wrapperCol={setting.wrapperCol} |
| | | > |
| | | {setting.show ? <Button type="primary" onClick={this.handleSubmit}> |
| | | 搜索 |
| | | </Button> : null} |
| | | {setting.show ? <Button style={{ marginLeft: 8 }} onClick={this.handleReset}> |
| | | 重置 |
| | | </Button> : null} |
| | | {setting.showAdv ? <Button className={visible ? 'visible' : ''} type="link" onClick={this.handleAdvance}> |
| | | 高级{setting.advanceType === 'pulldown' ? <DownOutlined /> : null} |
| | | </Button> : null} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | if (float === 'right') { |
| | | fields.unshift(action) |
| | | } else { |
| | | fields.push(action) |
| | | } |
| | | } |
| | | |
| | | return fields |
| | | } |
| | | |
| | | handleAdvance = () => { |
| | | this.setState({visible: true}) |
| | | const { setting, visible } = this.state |
| | | |
| | | if (setting.advanceType !== 'pulldown' && visible) { |
| | | return |
| | | } |
| | | |
| | | this.setState({visible: !visible}) |
| | | |
| | | if (setting.advanceType === 'pulldown') { |
| | | if (visible) { |
| | | let advanceValues = [] |
| | | this.state.searchlist.forEach(item => { |
| | | if (!item.advanced) return |
| | | |
| | | let val = this.record[item.field] |
| | | if (val || val === 0) { |
| | | if (item.precision === 'hour') { |
| | | if (/,/ig.test(val)) { |
| | | val = val.split(',').map(m => m + ':00').join(',') |
| | | } else { |
| | | val = val + ':00' |
| | | } |
| | | } |
| | | advanceValues.push({field: item.field, type: item.type, label: item.label, value: val}) |
| | | } |
| | | }) |
| | | this.setState({advanceValues}) |
| | | } else { |
| | | let list = this.state.searchlist.map(item => { |
| | | if (!item.advanced) return item |
| | | |
| | | item.initval = this.record[item.field] |
| | | |
| | | return item |
| | | }) |
| | | this.setState({searchlist: list}) |
| | | } |
| | | } |
| | | } |
| | | |
| | | handleSubmit = () => { |
| | |
| | | |
| | | notification.warning({ |
| | | top: 92, |
| | | message: this.state.dict['form.required.input'] + labels.join('、') + ' !', |
| | | message: '请输入' + labels.join('、') + ' !', |
| | | duration: 3 |
| | | }) |
| | | return |
| | |
| | | } |
| | | |
| | | render() { |
| | | const { float, searchStyle, visible, searchlist, showAdvanced, advanceValues, adModelWidth } = this.state |
| | | const { visible, searchlist, advanceValues, setting } = this.state |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | |
| | | |
| | | return ( |
| | | <> |
| | | <Form {...formItemLayout} className={`top-search ${float}`} style={searchStyle}> |
| | | <Form {...formItemLayout} className={`top-search mk-float-${setting.float}`} style={setting.style}> |
| | | <Row gutter={24}>{this.getFields()}</Row> |
| | | <Row gutter={24}> |
| | | {showAdvanced ? <div className="advanced-list"> |
| | | {advanceValues.length && (setting.advanceType !== 'pulldown' || (setting.advanceType === 'pulldown' && !visible)) ? <Row gutter={24}> |
| | | <div className="advanced-list"> |
| | | {advanceValues.map((item, index) => { |
| | | return ( |
| | | <div key={index}> |
| | |
| | | <CloseOutlined onClick={() => this.closeAdvanceForm(item)} /> |
| | | </div>) |
| | | })} |
| | | </div> : null} |
| | | </Row> |
| | | </div> |
| | | </Row> : null} |
| | | </Form> |
| | | <Modal |
| | | {setting.advanceType === 'modal' ? <Modal |
| | | title="高级搜索" |
| | | maskClosable={false} |
| | | visible={visible} |
| | | width={adModelWidth} |
| | | width={setting.advWidth} |
| | | closable={false} |
| | | footer={null} |
| | | destroyOnClose |
| | |
| | | advanceSubmit={this.handleOk} |
| | | handleClose={() => this.setState({visible: false})} |
| | | /> |
| | | </Modal> |
| | | </Modal> : null} |
| | | {setting.advanceType === 'drawer' ? <Drawer |
| | | title="高级搜索" |
| | | width={setting.advWidth} |
| | | height={setting.advHeight} |
| | | maskClosable={false} |
| | | onClose={() => this.setState({visible: false})} |
| | | visible={visible} |
| | | placement={setting.placement} |
| | | destroyOnClose |
| | | > |
| | | <MutilForm |
| | | searchlist={searchlist} |
| | | record={this.record} |
| | | advanceSubmit={this.handleOk} |
| | | handleClose={() => this.setState({visible: false})} |
| | | /> |
| | | </Drawer> : null} |
| | | </> |
| | | ) |
| | | } |
| | |
| | | .top-search { |
| | | background: #ffffff; |
| | | |
| | | .mk-search-col { |
| | | display: inline-block; |
| | | float: none; |
| | | vertical-align: top; |
| | | } |
| | | .ant-form-item { |
| | | display: flex; |
| | | margin-bottom: 0px; |
| | | min-height: 60px; |
| | | min-height: 55px; |
| | | .ant-form-explain { |
| | | white-space: nowrap; |
| | | } |
| | | } |
| | | .ant-form-item.checkcard { |
| | | .ant-form-item-control { |
| | | line-height: 1; |
| | | } |
| | | } |
| | | .ant-form-item-control-wrapper { |
| | |
| | | } |
| | | } |
| | | .search-button { |
| | | min-height: 60px; |
| | | min-height: 55px; |
| | | .ant-btn-link, .ant-btn-link:hover, .ant-btn-link:active{ |
| | | border-color: transparent; |
| | | span { |
| | |
| | | height: auto; |
| | | min-height: 28px; |
| | | } |
| | | .anticon-down { |
| | | transition: transform 0.3s; |
| | | // top: 3px!important; |
| | | margin-left: 2px; |
| | | } |
| | | .visible { |
| | | .anticon-down { |
| | | transform: rotate(180deg); |
| | | } |
| | | } |
| | | } |
| | | .advanced-list { |
| | | font-size: 13px; |
| | | padding: 0 12px; |
| | | padding: 2px 12px; |
| | | text-align: left; |
| | | > div { |
| | | display: inline-block; |
| | | margin-right: 10px; |
| | | border: 1px solid #dddddd; |
| | | padding: 0 4px 0 4px; |
| | | background: rgba(0, 0, 0, 0.02); |
| | | box-shadow: 0 0 2px #dddddd; |
| | | |
| | | .anticon-close { |
| | | margin-left: 5px; |
| | |
| | | margin-top: 3px; |
| | | } |
| | | } |
| | | .top-search.right { |
| | | .top-search.mk-float-right { |
| | | >.ant-row { |
| | | >.ant-col { |
| | | float: right; |
| | | } |
| | | text-align: right; |
| | | } |
| | | } |
| | |
| | | const { MonthPicker, WeekPicker, RangePicker } = DatePicker |
| | | const CheckCard = asyncComponent(() => import('@/templates/modalconfig/checkCard')) |
| | | |
| | | const Card = ({ id, card, showField, moveCard, copyCard, findCard, editCard, delCard }) => { |
| | | const Card = ({ id, card, moveCard, copyCard, findCard, editCard, delCard }) => { |
| | | const originalIndex = findCard(id).index |
| | | const [{ isDragging }, drag] = useDrag({ |
| | | item: { type: 'search', id, originalIndex }, |
| | |
| | | <CloseOutlined className="close" onClick={() => delCard(id)} /> |
| | | </div> |
| | | } trigger="hover"> |
| | | <div className={'page-card ' + (card.labelShow || '') + ' ' + type} style={{ opacity: opacity}}> |
| | | <div className={'page-card ' + (card.labelShow === 'false' ? 'label-hide ' : '') + type + (card.advanced === 'true' ? ' advanced' : '')} style={{ opacity: opacity}}> |
| | | <div ref={node => drag(drop(node))} onDoubleClick={() => editCard(id)}> |
| | | <Form.Item |
| | | labelCol={{style: {width: labelwidth + '%'}}} |
| | | wrapperCol={{style: {width: (100 - labelwidth) + '%'}}} |
| | | // labelCol={{xs: { span: 24 }, sm: { span: 8 }}} |
| | | // wrapperCol = {{xs: { span: 24 }, sm: { span: 16 }}} |
| | | label={card.labelShow !== 'false' ? card.label : ''} |
| | | required={card.required === 'true'} |
| | | help={showField ? card.field + (card.datefield ? ', ' + card.datefield : '') : ''} |
| | | help={(card.field || '') + (card.datefield ? ', ' + card.datefield : '') + (card.advanced === 'true' ? '(高级搜索)' : '')} |
| | | > |
| | | {formItem} |
| | | </Form.Item> |
| | |
| | | import { useDrop } from 'react-dnd' |
| | | import { is, fromJS } from 'immutable' |
| | | import update from 'immutability-helper' |
| | | import { Col, Button } from 'antd' |
| | | import { Col, Button, Popover } from 'antd' |
| | | import { EditOutlined } from '@ant-design/icons' |
| | | |
| | | import Utils from '@/utils/utils.js' |
| | | import Card from './card' |
| | | import './index.scss' |
| | | |
| | | const Container = ({list, show, showField, handleList, handleMenu, deleteMenu }) => { |
| | | const Container = ({list, setting, handleList, handleMenu, deleteMenu, handleSetting }) => { |
| | | const [cards, setCards] = useState(list) |
| | | const moveCard = (id, atIndex) => { |
| | | const { card, index } = findCard(id) |
| | |
| | | } |
| | | }) |
| | | |
| | | let radio = 6 |
| | | if (cards.length > 0) { |
| | | radio = cards[cards.length - 1].ratio || 6 |
| | | } |
| | | let radio = setting.searchRatio || 6 |
| | | let labelwidth = setting.searchLwidth !== undefined ? setting.searchLwidth : 33.3 |
| | | let advanceType = setting.advanceType || 'modal' |
| | | |
| | | return ( |
| | | <div ref={drop} className="ant-row"> |
| | | {cards.map(card => ( |
| | | <Col key={card.uuid} span={card.ratio || 6}> |
| | | <Card |
| | | id={`${card.uuid}`} |
| | | card={card} |
| | | showField={showField} |
| | | moveCard={moveCard} |
| | | copyCard={copyCard} |
| | | editCard={editCard} |
| | | delCard={delCard} |
| | | findCard={findCard} |
| | | /> |
| | | </Col> |
| | | ))} |
| | | {cards.length > 0 && show !== 'false' ? <Col key="action" className="action" span={radio < 6 ? 6 : radio}> |
| | | {cards.map(card => { |
| | | let _ratio = card.ratio || 6 |
| | | if (card.advanced === 'true' && advanceType !== 'pulldown') { |
| | | _ratio = 6 |
| | | } |
| | | return ( |
| | | <Col className="mk-search-item-wrap" key={card.uuid} span={_ratio}> |
| | | <Card |
| | | id={`${card.uuid}`} |
| | | card={card} |
| | | moveCard={moveCard} |
| | | copyCard={copyCard} |
| | | editCard={editCard} |
| | | delCard={delCard} |
| | | findCard={findCard} |
| | | /> |
| | | </Col> |
| | | ) |
| | | })} |
| | | {cards.length > 0 ? <Col className={'mk-search-item-wrap action ' + (setting.show === 'false' ? 'hide-button' : '')} key="action" span={radio}> |
| | | <div className="ant-row ant-form-item" style={{whiteSpace: 'nowrap', lineHeight: '40px', height: '55px', marginBottom: 0}}> |
| | | <div className="ant-col ant-form-item-label ant-col-xs-24 ant-col-sm-8"> |
| | | </div> |
| | | <div className="ant-col ant-form-item-control-wrapper ant-col-xs-24 ant-col-sm-16"> |
| | | <Button type="primary">搜索</Button> |
| | | <Button style={{ marginLeft: 8 }}>重置</Button> |
| | | <div style={{position: 'absolute', top: 0, bottom: 0, left: 0, right: 0}}></div> |
| | | </div> |
| | | <div className="ant-col ant-form-item-label" style={{width: labelwidth + '%'}}></div> |
| | | <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ |
| | | <div className="mk-popover-control"> |
| | | <EditOutlined className="edit" onClick={() => handleSetting()} /> |
| | | </div> |
| | | } trigger="hover"> |
| | | <div className="ant-col ant-form-item-control-wrapper"> |
| | | <Button type="primary">搜索</Button> |
| | | <Button style={{ marginLeft: 8 }}>重置</Button> |
| | | <div style={{position: 'absolute', top: 0, bottom: 0, left: 0, right: 0}}></div> |
| | | </div> |
| | | </Popover> |
| | | </div> |
| | | </Col> : null} |
| | | {cards.length === 0 ? |
| | |
| | | import { getSearchForm } from '@/templates/zshare/formconfig' |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import MKEmitter from '@/utils/events.js' |
| | | import SearchForm from './searchform' |
| | | import DragElement from './dragsearch' |
| | | import SearchForm from './searchform' |
| | | import SettingForm from './settingform' |
| | | import './index.scss' |
| | | |
| | | const { confirm } = Modal |
| | |
| | | |
| | | state = { |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | searchlist: null, // 搜索条件集 |
| | | sqlVerifing: false, // sql验证中 |
| | | visible: false, // 模态框控制 |
| | | searchlist: null, |
| | | sqlVerifing: false, |
| | | visible: false, |
| | | showField: false, |
| | | card: null // 编辑中元素 |
| | | setVisible: false, |
| | | card: null |
| | | } |
| | | |
| | | /** |
| | |
| | | }) |
| | | } |
| | | |
| | | handleSetting = () => { |
| | | this.setState({ |
| | | setVisible: true |
| | | }) |
| | | } |
| | | |
| | | settingSubmit = () => { |
| | | const { config } = this.props |
| | | |
| | | this.settingFormRef.handleConfirm().then(res => { |
| | | this.setState({ |
| | | setVisible: false |
| | | }) |
| | | this.props.updatesearch({...config, setting: {...config.setting, ...res}}) |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 组件销毁,清除state更新 |
| | |
| | | if (!is(fromJS(this.state), fromJS(nextState))) { |
| | | return true |
| | | } else if (this.props.config.wrap) { |
| | | return this.props.config.wrap.show !== nextProps.config.wrap.show |
| | | return !is(fromJS(nextProps.config.wrap), fromJS(this.props.config.wrap)) |
| | | } else { |
| | | return this.props.config.setting.show !== nextProps.config.setting.show |
| | | return !is(fromJS(nextProps.config.setting), fromJS(this.props.config.setting)) |
| | | } |
| | | } |
| | | |
| | | render() { |
| | | const { config } = this.props |
| | | const { dict, searchlist, visible, sqlVerifing, card, showField } = this.state |
| | | |
| | | let show = config.setting.show |
| | | if (config.wrap) { |
| | | show = config.wrap.show |
| | | } |
| | | const { dict, searchlist, visible, sqlVerifing, card, showField, setVisible } = this.state |
| | | |
| | | return ( |
| | | <div className={'model-table-search-list length' + searchlist.length}> |
| | | <div className={'model-table-search-list length' + searchlist.length + (showField ? ' show-field' : '')}> |
| | | <Tooltip placement="bottomLeft" overlayClassName="middle" title="在左侧工具栏《搜索》中,选择对应搜索框拖至此处添加;或点击按钮《添加搜索条件》批量添加,选择批量添加时,需提前选择使用表。"> |
| | | <QuestionCircleOutlined style={{color: '#c49f47', position: 'relative', left: '-15px', top: '5px'}} /> |
| | | </Tooltip> |
| | | <FieldsComponent config={{uuid: config.uuid, search: searchlist}} type="search" /> |
| | | <Switch checkedChildren={dict['model.switch.open']} unCheckedChildren={dict['model.switch.close']} defaultChecked={showField} onChange={this.onFieldChange} /> |
| | | <Switch className="switch-field-show" checkedChildren={dict['model.switch.open']} unCheckedChildren={dict['model.switch.close']} defaultChecked={showField} onChange={this.onFieldChange} /> |
| | | <DragElement |
| | | list={searchlist} |
| | | show={show} |
| | | showField={showField} |
| | | setting={config.wrap || config.setting} |
| | | handleList={this.handleList} |
| | | handleMenu={this.handleSearch} |
| | | deleteMenu={this.deleteElement} |
| | | handleSetting={this.handleSetting} |
| | | /> |
| | | {/* 编辑搜索条件 */} |
| | | <Modal |
| | |
| | | wrappedComponentRef={(inst) => this.searchFormRef = inst} |
| | | /> |
| | | </Modal> |
| | | <Modal |
| | | title={'搜索设置'} |
| | | visible={setVisible} |
| | | width={800} |
| | | maskClosable={false} |
| | | onOk={this.settingSubmit} |
| | | onCancel={() => this.setState({setVisible: false})} |
| | | destroyOnClose |
| | | > |
| | | <SettingForm |
| | | setting={config.wrap || config.setting} |
| | | inputSubmit={this.settingSubmit} |
| | | wrappedComponentRef={(inst) => this.settingFormRef = inst} |
| | | /> |
| | | </Modal> |
| | | </div> |
| | | ) |
| | | } |
| | |
| | | .quickly-add { |
| | | display: none; |
| | | } |
| | | >.ant-switch { |
| | | .switch-field-show { |
| | | position: absolute; |
| | | z-index: 1; |
| | | right: 20px; |
| | |
| | | padding: 0 12px!important; |
| | | } |
| | | } |
| | | |
| | | .ant-row.ant-form-item .ant-col { |
| | | padding: 0; |
| | | |
| | | .mk-search-item-wrap { |
| | | display: inline-block; |
| | | float: none; |
| | | vertical-align: top; |
| | | } |
| | | .mk-search-item-wrap.action { |
| | | .ant-form-item-label, .ant-form-item-control-wrapper { |
| | | display: inline-block; |
| | | } |
| | | } |
| | | .mk-search-item-wrap.action.hide-button { |
| | | span { |
| | | text-decoration: line-through #ff4d4f; |
| | | } |
| | | } |
| | | |
| | | .page-card { |
| | | position: relative; |
| | | background: #ffffff; |
| | |
| | | padding: 4px 20px 4px 5px; |
| | | font-size: 13px; |
| | | } |
| | | .check-card-edit-box { |
| | | .no-margin-bottom { |
| | | margin-bottom: 0px; |
| | | } |
| | | .card-cell { |
| | | padding: 4px 6px; |
| | | } |
| | | .card-color-cell { |
| | | min-height: 32px; |
| | | } |
| | | } |
| | | } |
| | | .ant-form-explain { |
| | | display: none; |
| | | } |
| | | } |
| | | >div::after { |
| | |
| | | z-index: 2; |
| | | } |
| | | } |
| | | .page-card.false { |
| | | .page-card.label-hide { |
| | | .ant-form-item-label { |
| | | display: none; |
| | | } |
| | |
| | | } |
| | | } |
| | | } |
| | | .page-card.advanced { |
| | | .ant-form-item-label label { |
| | | color: orange; |
| | | } |
| | | } |
| | | .ant-calendar-picker { |
| | | min-width: 100px!important; |
| | | width: 100%; |
| | |
| | | .check-card-edit-box { |
| | | margin-top: 5px!important; |
| | | } |
| | | } |
| | | .model-table-search-list.show-field { |
| | | .page-card { |
| | | .ant-form-explain { |
| | | display: block; |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { Form, Row, Col, Radio, Tooltip, InputNumber } from 'antd' |
| | | import { QuestionCircleOutlined } from '@ant-design/icons' |
| | | |
| | | // import './index.scss' |
| | | |
| | | class SettingForm extends Component { |
| | | static propTpyes = { |
| | | setting: PropTypes.object, |
| | | inputSubmit: PropTypes.func |
| | | } |
| | | |
| | | state = { |
| | | advanceType: '' |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { setting } = this.props |
| | | |
| | | this.setState({ |
| | | advanceType: setting.advanceType || 'modal' |
| | | }) |
| | | } |
| | | |
| | | handleConfirm = () => { |
| | | // 表单提交时检查输入值是否正确 |
| | | return new Promise((resolve, reject) => { |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | | if (!err) { |
| | | resolve(values) |
| | | } else { |
| | | reject(err) |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | render() { |
| | | const { setting } = this.props |
| | | const { getFieldDecorator } = this.props.form |
| | | const { advanceType } = this.state |
| | | |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 8 } |
| | | }, |
| | | wrapperCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 16 } |
| | | } |
| | | } |
| | | |
| | | return ( |
| | | <div className="model-table-datasource-setting-form-box"> |
| | | <Form {...formItemLayout} className="model-setting-form"> |
| | | <Row gutter={24}> |
| | | <Col span={12}> |
| | | <Form.Item label="搜索按钮"> |
| | | {getFieldDecorator('show', { |
| | | initialValue: setting.show || 'true' |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="true">显示</Radio> |
| | | <Radio value="false">隐藏</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="高级搜索的展开方式。"> |
| | | <QuestionCircleOutlined className="mk-form-tip" /> |
| | | 高级搜索 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('advanceType', { |
| | | initialValue: setting.advanceType || 'modal' |
| | | })( |
| | | <Radio.Group onChange={(e) => this.setState({advanceType: e.target.value})}> |
| | | <Radio value="modal">弹窗</Radio> |
| | | <Radio value="drawer">抽屉</Radio> |
| | | <Radio value="pulldown">下拉</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | {advanceType === 'drawer' ? <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="抽屉展开的方向。"> |
| | | <QuestionCircleOutlined className="mk-form-tip" /> |
| | | 抽屉方向 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('drawerPlacement', { |
| | | initialValue: setting.drawerPlacement || 'right' |
| | | })( |
| | | <Radio.Group style={{whiteSpace: 'nowrap'}}> |
| | | <Radio value="right">右侧</Radio> |
| | | <Radio value="left">左侧</Radio> |
| | | <Radio value="top">上侧</Radio> |
| | | <Radio value="bottom">下侧</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {advanceType !== 'pulldown' ? <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="高级搜索框的宽度,注:当宽度值小于100时表示占窗口的百分比,大于100时表示宽度的绝对值。当使用上下显示的抽屉时代表抽屉高度。"> |
| | | <QuestionCircleOutlined className="mk-form-tip" /> |
| | | 弹窗宽度 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('advanceWidth', { |
| | | initialValue: setting.advanceWidth || 1000 |
| | | })(<InputNumber min={10} max={3000} precision={0} onPressEnter={this.props.inputSubmit}/>)} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="搜索及重置按钮所占比例。栅格布局,每行等分为24列。"> |
| | | <QuestionCircleOutlined className="mk-form-tip" /> |
| | | 比例 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('searchRatio', { |
| | | initialValue: setting.searchRatio || 6, |
| | | })(<InputNumber min={1} max={24} precision={0} onPressEnter={this.props.inputSubmit}/>)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="搜索按钮距左侧的百分比,参照搜索条件的名称宽度。"> |
| | | <QuestionCircleOutlined className="mk-form-tip" /> |
| | | 按钮偏移 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('searchLwidth', { |
| | | initialValue: setting.searchLwidth !== undefined ? setting.searchLwidth : 33.3, |
| | | })(<InputNumber min={0} max={100} precision={1} onPressEnter={this.props.inputSubmit}/>)} |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | </Form> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default Form.create()(SettingForm) |
| | |
| | | }) |
| | | } |
| | | |
| | | res.show = config.setting.show || 'true' |
| | | res.advanceType = config.setting.advanceType || 'modal' |
| | | res.advanceWidth = config.setting.advanceWidth || 1000 |
| | | res.drawerPlacement = config.setting.drawerPlacement || 'right' |
| | | res.searchRatio = config.setting.searchRatio || 6 |
| | | res.searchLwidth = config.setting.searchLwidth !== undefined ? config.setting.searchLwidth : 33.3 |
| | | |
| | | this.setState({loading: false, visible: false}) |
| | | this.props.updateConfig({...config, ...res}) |
| | | |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { Form, Row, Col, Input, Radio, Tooltip, notification, InputNumber } from 'antd' |
| | | import { Form, Row, Col, Input, Radio, Tooltip, notification } from 'antd' |
| | | import { QuestionCircleOutlined } from '@ant-design/icons' |
| | | import moment from 'moment' |
| | | |
| | |
| | | </Radio.Group>)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={8}> |
| | | {/* <Col span={8}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="高级搜索弹窗的宽度,注:当宽度值小于100时表示占窗口的百分比,大于100时表示宽度的绝对值。"> |
| | | <QuestionCircleOutlined className="mk-form-tip" /> |
| | |
| | | initialValue: setting.advanceWidth || 1000 |
| | | })(<InputNumber min={10} max={3000} precision={0}/>)} |
| | | </Form.Item> |
| | | </Col> |
| | | </Col> */} |
| | | </Row> |
| | | </Form> |
| | | </div> |
| | |
| | | loading: true |
| | | }) |
| | | this.settingRef.handleConfirm().then(setting => { |
| | | let res = this.resetSetting(setting) |
| | | let res = this.resetSetting(setting, config.setting) |
| | | this.setState({ |
| | | visible: false, |
| | | loading: false |
| | |
| | | const { menu } = this.state |
| | | |
| | | this.settingRef.handleConfirm('loading').then(setting => { |
| | | let res = this.resetSetting(setting) |
| | | let res = this.resetSetting(setting, config.setting) |
| | | let _config = {...config, setting: res} |
| | | let newLText = Utils.formatOptions(FuncUtils.getTableFunc(setting, menu, _config)) // 创建存储过程sql |
| | | let DelText = Utils.formatOptions(FuncUtils.dropfunc(setting.innerFunc)) // 删除存储过程sql |
| | |
| | | const { menu } = this.state |
| | | |
| | | this.settingRef.handleConfirm('loading').then(setting => { |
| | | let res = this.resetSetting(setting) |
| | | let res = this.resetSetting(setting, config.setting) |
| | | let _config = {...config, setting: res} |
| | | let _menu = { |
| | | type: config.Template === 'CommonTable' ? 'main' : 'subtable', |
| | |
| | | }) |
| | | } |
| | | |
| | | resetSetting = (s) => { |
| | | resetSetting = (s, ori) => { |
| | | let setting = fromJS(s).toJS() |
| | | let maxScript = 0 |
| | | |
| | | setting.show = ori.show || 'true' |
| | | setting.advanceType = ori.advanceType || 'modal' |
| | | setting.advanceWidth = ori.advanceWidth || 1000 |
| | | setting.drawerPlacement = ori.drawerPlacement || 'right' |
| | | setting.searchRatio = ori.searchRatio || 6 |
| | | setting.searchLwidth = ori.searchLwidth !== undefined ? ori.searchLwidth : 33.3 |
| | | |
| | | if (window.GLOB.funcs && window.GLOB.funcs.length > 0) { |
| | | window.GLOB.funcs.forEach(m => { |
| | | let reg = new RegExp('\\$ex@' + m.func_code + '@ex\\$', 'ig') |
| | |
| | | </Radio.Group>)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | {/* <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="在搜索条件存在时,是否显示搜索和重置按钮。"> |
| | | <QuestionCircleOutlined className="mk-form-tip" /> |
| | |
| | | <Radio value="false">隐藏</Radio> |
| | | </Radio.Group>)} |
| | | </Form.Item> |
| | | </Col> |
| | | </Col> */} |
| | | {tableType !== '' ? <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="当按钮执行完成并返回主键值时,默认选中主键值对应行。注:在启用无人值守功能时无效。"> |
| | |
| | | })(<InputNumber min={1} max={500} precision={0} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | {/* <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="高级搜索弹窗的宽度,注:当宽度值小于100时表示占窗口的百分比,大于100时表示宽度的绝对值。"> |
| | | <QuestionCircleOutlined className="mk-form-tip" /> |
| | |
| | | initialValue: setting.advanceWidth || 1000 |
| | | })(<InputNumber min={10} max={3000} precision={0}/>)} |
| | | </Form.Item> |
| | | </Col> |
| | | </Col> */} |
| | | <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="双击表格中行,触发的按钮。"> |
| | |
| | | loading: false |
| | | }) |
| | | |
| | | res.show = config.setting.show || 'true' |
| | | res.advanceType = config.setting.advanceType || 'modal' |
| | | res.advanceWidth = config.setting.advanceWidth || 1000 |
| | | res.drawerPlacement = config.setting.drawerPlacement || 'right' |
| | | res.searchRatio = config.setting.searchRatio || 6 |
| | | res.searchLwidth = config.setting.searchLwidth !== undefined ? config.setting.searchLwidth : 33.3 |
| | | |
| | | this.props.updatesetting({...config, setting: res}) |
| | | |
| | | MKEmitter.emit('modalStatus', false) |
| | |
| | | key: 'advanced', |
| | | label: '高级搜索', |
| | | initVal: card.advanced || 'false', |
| | | tooltip: '在隐藏搜索按钮时,高级搜索无效。', |
| | | tooltip: '在高级搜索以模态框或抽屉展开时,搜索条件在开发界面占比为6,实际效果请在运行时查看。', |
| | | forbid: appType === 'mob', |
| | | options: [{ |
| | | value: 'true', |
| | |
| | | import React, {Component} from 'react' |
| | | import { connect } from 'react-redux' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Menu, notification } from 'antd' |
| | | import { EditOutlined } from '@ant-design/icons' |
| | | import { Menu, notification, Popover } from 'antd' |
| | | import { EditOutlined, CloseOutlined, SwapOutlined, PlusOutlined, UnlockOutlined, SettingOutlined } from '@ant-design/icons' |
| | | |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import { resetEditLevel, modifyMenuTree, modifyMainMenu } from '@/store/action' |
| | |
| | | this.props.resetEditLevel(false) |
| | | } |
| | | |
| | | editmenu = (cell) => { |
| | | if (cell.type === 'CustomPage') { |
| | | let _param = { |
| | | MenuType: 'custom', |
| | | MenuId: cell.MenuID, |
| | | ParentId: cell.ParentId, |
| | | MenuName: cell.MenuName, |
| | | MenuNo: cell.MenuNo |
| | | } |
| | | _param = window.btoa(window.encodeURIComponent(JSON.stringify(_param))) |
| | | window.open(`#/menudesign/${_param}`) |
| | | } else { |
| | | |
| | | } |
| | | } |
| | | |
| | | render () { |
| | | const { mainMenu } = this.props |
| | | const { mainMenu, editLevel } = this.props |
| | | |
| | | let isnew = false |
| | | |
| | | return ( |
| | | <aside className="mk-sys-side-menu ant-menu-dark mk-edit"> |
| | | {!(this.props.editLevel === 'level2' || this.props.editLevel === 'level3') && |
| | | {!(editLevel === 'level2' || editLevel === 'level3') && |
| | | <Menu openKeys={this.state.openKeys} onOpenChange={this.onOpenChange} mode="inline" theme="dark"> |
| | | {!this.props.editLevel && mainMenu ? <li className="sup-menu"><EditOutlined onClick={this.enterSubEdit} className="edit-check"/></li> : null} |
| | | {!editLevel && mainMenu ? <li className="sup-menu"><EditOutlined onClick={this.enterSubEdit} className="edit-check"/></li> : null} |
| | | {this.state.subMenulist && this.state.subMenulist.map((item, index) => { |
| | | return ( |
| | | <SubMenu |
| | | key={item.MenuID} |
| | | title={ |
| | | <span className={!this.props.editLevel && index === 0 ? 'edit-control' : ''}> |
| | | <span className={!editLevel && index === 0 ? 'edit-control' : ''}> |
| | | <MkIcon type={item.PageParam.Icon} /> |
| | | <span>{item.MenuName}</span> |
| | | </span> |
| | | } |
| | | > |
| | | {!this.props.editLevel ? <li className={'ant-menu-item ' + (item.children.length > 0 ? 'sub-menu' : '')}> |
| | | <EditOutlined onClick={(e) => {this.enterThrEdit(e, item)}} className="edit-check"/> |
| | | {!editLevel ? <li className={'ant-menu-item ' + (item.children.length > 0 ? 'sub-menu' : '')}> |
| | | {!isnew ? <EditOutlined onClick={(e) => {this.enterThrEdit(e, item)}} className="edit-check"/> : |
| | | <Popover overlayClassName="mk-popover-control-wrap mk-menu-control" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ |
| | | <div className="mk-popover-control"> |
| | | <PlusOutlined onClick={(e) => {this.enterThrEdit(e, item)}} className="mk-edit-menu"/> |
| | | <SwapOutlined onClick={(e) => {this.enterThrEdit(e, item)}} className="mk-edit-menu mk-swap"/> |
| | | <UnlockOutlined onClick={(e) => {this.enterThrEdit(e, item)}} className="mk-edit-menu"/> |
| | | </div> |
| | | } trigger="hover" placement="top"> |
| | | <SettingOutlined className="edit-check"/> |
| | | </Popover>} |
| | | </li> : null} |
| | | {item.children.map(cell => { |
| | | return ( |
| | | <Menu.Item key={cell.MenuID}> |
| | | <a href={cell.src} id={cell.MenuID} onClick={(e) => this.changemenu(e, cell)}>{cell.MenuName}</a> |
| | | {editLevel !== 'HS' && isnew ? |
| | | <Popover overlayClassName="mk-popover-control-wrap mk-menu-control" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ |
| | | <div className="mk-popover-control"> |
| | | <EditOutlined className="edit" onClick={() => this.editmenu(cell)} /> |
| | | <CloseOutlined className="close" onClick={() => {}} /> |
| | | </div> |
| | | } trigger="hover" placement="top"> |
| | | <span className="editable-menu-item">{cell.MenuName}</span> |
| | | </Popover> : |
| | | <a href={cell.src} id={cell.MenuID} onClick={(e) => this.changemenu(e, cell)}>{cell.MenuName}</a> |
| | | } |
| | | </Menu.Item> |
| | | ) |
| | | })} |
| | |
| | | ) |
| | | })} |
| | | </Menu>} |
| | | {this.props.editLevel === 'level2' ? |
| | | {editLevel === 'level2' ? |
| | | <EditSecMenu |
| | | menulist={this.state.subMenulist} |
| | | menuTree={this.props.menuTree} |
| | |
| | | exitEdit={this.exitEdit} |
| | | /> : null |
| | | } |
| | | {this.props.editLevel === 'level3' && this.state.editMenu ? |
| | | {editLevel === 'level3' && this.state.editMenu ? |
| | | <EditThdMenu |
| | | menulist={this.state.editMenu.children} |
| | | supMenuList={this.state.subMenulist} |
| | |
| | | a { |
| | | padding-left: 48px; |
| | | } |
| | | .editable-menu-item { |
| | | display: block; |
| | | padding-left: 48px; |
| | | } |
| | | } |
| | | .ant-menu-sub.ant-menu-inline { |
| | | position: relative; |
| | |
| | | color: #ffffff; |
| | | } |
| | | } |
| | | |
| | | .edit-control + .ant-menu-submenu-arrow { |
| | | display: none; |
| | | } |
| | |
| | | a { |
| | | cursor: pointer; |
| | | } |
| | | } |
| | | .mk-popover-control-wrap { |
| | | .mk-edit-menu { |
| | | font-size: 18px; |
| | | cursor: pointer; |
| | | padding: 10px 15px; |
| | | } |
| | | .anticon-plus.mk-edit-menu { |
| | | color: #26C281; |
| | | } |
| | | .mk-edit-menu.mk-swap { |
| | | color: #1890ff; |
| | | transform: rotate(90deg); |
| | | } |
| | | .anticon-unlock.mk-edit-menu { |
| | | color: orange; |
| | | } |
| | | } |
| | | .mk-menu-control.mk-popover-control-wrap { |
| | | padding-bottom: 0px; |
| | | } |