src/assets/css/main.scss | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/tabviews/custom/components/chart/antv-G6/index.jsx | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/tabviews/zshare/topSearch/index.jsx | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/tabviews/zshare/topSearch/mkCheckCard/index.jsx | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/tabviews/zshare/topSearch/mkCheckCard/index.scss | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/templates/sharecomponent/searchcomponent/searchform/index.jsx | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/templates/zshare/formconfig.jsx | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/templates/zshare/modalform/datatable/index.jsx | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/templates/zshare/modalform/fieldtable/index.jsx | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/utils/utils.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/assets/css/main.scss
@@ -513,4 +513,10 @@ .ant-col.ant-col-0 { display: inline-block; } .ant-dropdown { .ant-dropdown-menu-item:hover, .ant-dropdown-menu-submenu-title:hover { background-color: var(--mk-sys-color1); } } src/tabviews/custom/components/chart/antv-G6/index.jsx
@@ -814,6 +814,8 @@ } data = [] mkgraph = null selectedId = '' UNSAFE_componentWillMount () { const { config, data, initdata } = this.props @@ -1183,10 +1185,20 @@ _options.push(_item) }) root.nodeNumber = 0 root = this.getTree(root, _options, root) root.children = root.children || [] if (root.selectedItem) { let option = {...root.selectedItem} setTimeout(() => { MKEmitter.emit('resetSelectLine', config.uuid, option.id, option) }, 20) delete root.selectedItem } else { this.selectedId = '' } if (plot.subtype === 'mindmap') { root.type = 'dice-mind-map-root' @@ -1255,6 +1267,12 @@ options = options.filter(option => { if (option.$parentId === parent.id) { delete option.$parentId if (this.selectedId && option.id === this.selectedId) { root.selectedItem = {...option} option.selected = true } parent.children.push(option) root.nodeNumber++ @@ -1278,19 +1296,22 @@ } handleData = () => { let _element = document.getElementById(this.state.chartId) if (_element) { _element.innerHTML = '' } const { config } = this.state setTimeout(() => { MKEmitter.emit('resetSelectLine', config.uuid, '', '') if (this.mkgraph) { this.mkgraph.clear() this.resetrender() } else { this.viewrender() }, 100) } } viewrender = () => { const { plot } = this.state this.selectedId = '' if (this.data.length === 0) { this.setState({empty: true}) } else { @@ -1302,6 +1323,44 @@ this.indentrender() } else if (plot.subtype === 'kapmap') { this.kapmaprender() } } } resetrender = () => { const { plot } = this.state if (this.data.length === 0) { this.setState({empty: true}) this.selectedId = '' } else { this.setState({empty: false}) const data = this.getdata() if (plot.subtype === 'mindmap') { this.mkgraph.data(data) this.mkgraph.render() const width = this.wrap.scrollWidth - 30 if (plot.collapsed === 'true' && plot.dirField) { this.mkgraph.zoomTo(1, { x: width / 2, y: plot.height / 2 }) } else if (plot.collapsed === 'true' || data.nodeNumber < 5) { this.mkgraph.zoomTo(1, { x: 0, y: plot.height / 2 }) } } else if (plot.subtype === 'indentTree') { this.mkgraph.data(dataIndTransform(data)) this.mkgraph.render() } else if (plot.subtype === 'kapmap') { this.mkgraph.data(data) this.mkgraph.render() this.mkgraph.fitView() if (plot.collapsed === 'true' || data.nodeNumber < 5) { this.mkgraph.zoomTo(1, { x: 0, y: plot.height / 2 }) } } } } @@ -1364,6 +1423,8 @@ if (plot.collapsed === 'true' || data.nodeNumber < 5) { graph.zoomTo(1, { x: 0, y: plot.height / 2 }) } this.mkgraph = graph } indentrender = () => { @@ -1425,6 +1486,8 @@ tree.data(dataIndTransform(data)) tree.render() this.mkgraph = tree } /** @@ -1487,6 +1550,8 @@ } else if (plot.collapsed === 'true' || data.nodeNumber < 5) { tree.zoomTo(1, { x: 0, y: plot.height / 2 }) } this.mkgraph = tree } handleClick = (data = null) => { @@ -1555,7 +1620,13 @@ MKEmitter.emit('modifyTabs', newtab, true) } else { MKEmitter.emit('resetSelectLine', config.uuid, (data ? data.$$uuid : ''), data) if (data) { this.selectedId = data.$$uuid || '' MKEmitter.emit('resetSelectLine', config.uuid, data.$$uuid || '', data) } else { this.selectedId = '' MKEmitter.emit('resetSelectLine', config.uuid, '', '') } } } src/tabviews/zshare/topSearch/index.jsx
@@ -15,7 +15,7 @@ import './index.scss' const MutilForm = asyncSpinComponent(() => import('./advanceform')) const MKCheckCard = asyncComponent(() => import('@/tabviews/zshare/mutilform/mkCheckCard')) const MKCheckCard = asyncComponent(() => import('./mkCheckCard')) const MKCheck = asyncComponent(() => import('@/tabviews/zshare/mutilform/mkCheck')) const MKSwitch = asyncComponent(() => import('@/tabviews/zshare/mutilform/mkSwitch')) const MKSelect = asyncComponent(() => import('./mkSelect')) @@ -156,6 +156,9 @@ // 数据源查询语句 if (item.resourceType === '1' && item.dataSource) { if (item.multiple === 'dropdown') { item.parentField = 'pid' } let _option = Utils.getSelectQueryOptions(item) if (window.GLOB.debugger === true || (window.debugger === true && options.sysType !== 'cloud')) { @@ -178,6 +181,10 @@ } } item.oriOptions = fromJS(item.options).toJS() if (item.type === 'checkcard' && item.multiple === 'dropdown' && item.resourceType === '0') { this.resetCheckcard(item) } } fieldMap.set(item.field, item) @@ -223,6 +230,37 @@ this.improveSearch(mainItems, localItems) } }) } resetCheckcard = (item) => { let _options = [] let _others = [] item.oriOptions.forEach(op => { if (op.pid === item.mark) { _options.push(op) } else { _others.push(op) } }) _options = _options.map(op => { op.children = [] _others = _others.filter(cell => { if (cell.pid === op.$value) { op.children.push(cell) return false } return true }) op.subIds = op.children.map(cell => cell.$value) return op }) item.oriOptions = _options item.options = _options } // 查询下拉菜单 @@ -432,6 +470,10 @@ }) item.oriOptions = [...item.oriOptions, ...options] if (item.type === 'checkcard' && item.multiple === 'dropdown') { this.resetCheckcard(item) } } if (item.linkField) { src/tabviews/zshare/topSearch/mkCheckCard/index.jsx
New file @@ -0,0 +1,336 @@ import React, {Component} from 'react' import PropTypes from 'prop-types' import { is, fromJS } from 'immutable' import { Col, Row, Dropdown, Menu } from 'antd' import { CheckOutlined } from '@ant-design/icons' import MKEmitter from '@/utils/events.js' import './index.scss' class MKCheckCard extends Component { static propTpyes = { config: PropTypes.object, onChange: PropTypes.func } state = { selectKeys: null, config: null, options: [] } UNSAFE_componentWillMount() { let config = fromJS(this.props.config).toJS() let selectKeys = config.initval let initlength = 0 if (config.multiple === 'true') { selectKeys = config.initval ? config.initval.split(',') : [] initlength = selectKeys.length selectKeys = this.filterVals(config.options, selectKeys) } if (!config.selectStyle && config.backgroundColor) { config.selectStyle = 'custom' } else if (!config.selectStyle) { config.selectStyle = 'background' } if (config.display === 'picture' && !config.picratio) { // 兼容旧数据 config.picratio = config.ratio || '1:1' } config.selectClass = ` mk-${config.selectStyle} ` config.fields = config.fields || [] this.setState({ config: config, options: fromJS(config.options).toJS(), selectKeys: selectKeys }, () => { if (config.multiple === 'true' && selectKeys.length < initlength) { this.props.onChange(selectKeys.join(',')) } }) } componentDidMount () { const { config } = this.state if (config.linkField) { MKEmitter.addListener('mkFP', this.mkFormHandle) } } shouldComponentUpdate (nextProps, nextState) { return !is(fromJS(this.state), fromJS(nextState)) } UNSAFE_componentWillReceiveProps (nextProps) { const { config, selectKeys } = this.state if (!is(fromJS(config.oriOptions), fromJS(nextProps.config.oriOptions))) { if (config.multiple === 'true') { let keys = this.filterVals(nextProps.config.options, fromJS(selectKeys).toJS()) if (keys.length < selectKeys.length) { this.setState({ selectKeys: keys }, () => { this.props.onChange(keys.join(',')) }) } } this.setState({ config: {...config, oriOptions: nextProps.config.oriOptions}, options: fromJS(nextProps.config.options).toJS() }) } } componentWillUnmount () { this.setState = () => { return } MKEmitter.removeListener('mkFP', this.mkFormHandle) } filterVals = (options, vals) => { if (options.length === 0 || vals.length === 0) return vals let ops = options.map(item => item.$value) vals = vals.filter(val => ops.includes(val)) return vals } mkFormHandle = (uuid, parentId, level) => { if (uuid !== this.state.config.uuid) return const { config } = this.state let options = config.oriOptions.filter(option => option.ParentID === parentId) if (config.multiple === 'true') { this.setState({ options, selectKeys: [] }) this.props.onChange('') } else { let _option = options[0] ? options[0] : null let val = _option ? _option.$value : '' this.setState({ options, selectKeys: val }) let other = {} if (config.subFields && _option) { config.subFields.forEach((n, i) => { other[n.field] = _option[n.field] setTimeout(() => { MKEmitter.emit('mkFC', 'input', n.uuid, _option[n.field]) }, i * 5) }) } this.props.onChange(val, other) if (level < 7 && config.linkFields) { config.linkFields.forEach((m, i) => { setTimeout(() => { MKEmitter.emit('mkFP', m.uuid, val, level + 1) }, (i + 1) * 70) }) } } } changeCard = (item) => { const { selectKeys, config } = this.state if (config.multiple === 'true') { let keys = [] if (selectKeys.includes(item.$value)) { keys = selectKeys.filter(key => key !== item.$value) } else { keys = [...selectKeys, item.$value] } this.setState({ selectKeys: keys }, () => { this.props.onChange(keys.join(',')) }) } else if (selectKeys !== item.$value) { let other = {} config.subFields && config.subFields.forEach((n, i) => { other[n.field] = item[n.field] setTimeout(() => { MKEmitter.emit('mkFC', 'input', n.uuid, item[n.field]) }, i * 5) }) config.linkFields && config.linkFields.forEach((m, i) => { setTimeout(() => { MKEmitter.emit('mkFP', m.uuid, item.$value, 0) }, (i + 1) * 100) }) this.setState({ selectKeys: item.$value }, () => { this.props.onChange(item.$value, other) }) } else { let other = {} config.linkFields && config.linkFields.forEach((m, i) => { setTimeout(() => { MKEmitter.emit('mkFP', m.uuid, '', 0) }, (i + 1) * 100) }) this.setState({ selectKeys: '' }, () => { this.props.onChange('', other) }) } } getCards = () => { const { selectKeys, options, config } = this.state const { display, width, fields, picratio, multiple, backgroundColor, selectStyle, selectClass } = config if (options.length === 0) { return null } else if (display === 'color') { return options.map(item => { let _active = false if (multiple === 'true') { _active = selectKeys.includes(item.$value) } else { _active = selectKeys === item.$value } return <Col span={width} key={item.key}> <div className={'card-color-cell' + (_active ? ' active' : '')} style={{background: item.$color}} onClick={() => this.changeCard(item)}> {fields.map(col => { return <span className="content-line" key={col.key} style={{color: col.color, fontSize: col.fontSize + 'px', height: col.fontSize * 1.5 + 'px', textAlign: col.align}}>{item[col.field]}</span> })} <CheckOutlined /> </div> </Col> }) } else if (display === 'picture') { let paddingTop = '100%' if (picratio === '4:3') { paddingTop = '75%' } else if (picratio === '3:2') { paddingTop = '66.7%' } else if (picratio === '16:9') { paddingTop = '56.25%' } return options.map(item => { let _active = false if (multiple === 'true') { _active = selectKeys.includes(item.$value) } else { _active = selectKeys === item.$value } return <Col span={width} key={item.key}> <div className={'card-pic-cell ' + (_active ? 'active' : '')} onClick={() => this.changeCard(item)} style={{paddingTop, backgroundImage: `url(${item.$url})`}}> <div className="content-wrap"> <div className="content-center"> {fields.map(col => { return <span className="content-line" key={col.key} style={{color: col.color, fontSize: col.fontSize + 'px', height: col.fontSize * 1.5 + 'px', textAlign: col.align}}>{item[col.field]}</span> })} </div> <CheckOutlined /> </div> </div> </Col> }) } else { let _style = selectStyle === 'custom' ? {backgroundColor} : null if (multiple === 'dropdown') { return options.map(item => { if (item.children.length) { return <Col span={width} key={item.key}> <Dropdown overlayClassName="mk-search-card" overlay={ <Menu> {item.children.map((cell, index) => (<Menu.Item className={selectKeys === cell.$value ? ' active' : ''} key={index} onClick={() => this.changeCard(cell)}>{cell[fields[0].field]}</Menu.Item>))} </Menu>} placement="bottomCenter" > <div className={'card-cell' + (selectKeys && (selectKeys === item.$value || item.subIds.includes(selectKeys)) ? ' active' : '') + selectClass} onClick={() => this.changeCard(item)}> <div className="bg-mask" style={_style}></div> {fields.map(col => { return <span className="content-line" key={col.key} style={{color: col.color, fontSize: col.fontSize + 'px', height: col.fontSize * 1.5 + 'px', textAlign: col.align}}>{item[col.field]}</span> })} </div> </Dropdown> </Col> } else { return <Col span={width} key={item.key}> <div className={'card-cell' + (selectKeys === item.$value ? ' active' : '') + selectClass} onClick={() => this.changeCard(item)}> <div className="bg-mask" style={_style}></div> {fields.map(col => { return <span className="content-line" key={col.key} style={{color: col.color, fontSize: col.fontSize + 'px', height: col.fontSize * 1.5 + 'px', textAlign: col.align}}>{item[col.field]}</span> })} </div> </Col> } }) } else { return options.map(item => { let _active = false if (multiple === 'true') { _active = selectKeys.includes(item.$value) } else { _active = selectKeys === item.$value } return <Col span={width} key={item.key}> <div className={'card-cell' + (_active ? ' active' : '') + selectClass} onClick={() => this.changeCard(item)}> <div className="bg-mask" style={_style}></div> {fields.map(col => { return <span className="content-line" key={col.key} style={{color: col.color, fontSize: col.fontSize + 'px', height: col.fontSize * 1.5 + 'px', textAlign: col.align}}>{item[col.field]}</span> })} </div> </Col> }) } } } render() { const { config, options } = this.state let extend = '' if (options.length * config.width > 24) { extend += ' mutile-line' } if (config.border === 'hide') { extend += ' border-hide' } return ( <div className={'check-card-form-wrap ' + extend}> <Row gutter={12}>{this.getCards()}</Row> </div> ) } } export default MKCheckCard src/tabviews/zshare/topSearch/mkCheckCard/index.scss
New file @@ -0,0 +1,185 @@ .check-card-form-wrap { margin-top: 5px; .card-cell { position: relative; border: 1px solid #bcbcbc; background: #ffffff; border-radius: 4px; padding: 4px 6px; margin-bottom: 2px; line-height: 1.5; transition: all 0.3s; cursor: pointer; .bg-mask { position: absolute; top: 0; left: 0; right: 0; bottom: 0; opacity: 0.6; border-radius: 4px; background-color: transparent; transition: opacity 0.3s; } } .content-line { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; position: relative; z-index: 1; line-height: 1.5; } .card-cell.mk-background.active { border-color: var(--mk-sys-color); background: var(--mk-sys-color); span { color: #ffffff!important; } } .card-cell.mk-background.active::after { content: ' '; position: absolute; display: table; border: 2px solid #ffffff; border-top: 0; border-left: 0; bottom: 0; right: 10px; width: 6px; height: 12px; transform: rotate(45deg) scale(1) translate(-50%, -50%); } .card-cell.mk-font.active { border-color: var(--mk-sys-color); span { color: var(--mk-sys-color)!important; } } .card-cell.mk-custom { border-color: transparent; } .card-cell.mk-custom.active { .bg-mask { opacity: 1; } } .card-pic-cell { position: relative; border: 1px solid #e8e8e8; border-radius: 4px; background-size: cover; background-position: center; margin-bottom: 2px; line-height: 1.5; cursor: pointer; transition: all 0.3s; .content-wrap { position: absolute; top: 6px; left: 6px; right: 6px; bottom: 6px; .content-center { position: relative; top: 50%; transform: translate(0px, -50%); } } .anticon-check { display: none; position: absolute; color: #ffffff; border-radius: 20px; padding: 3px; width: 18px; height: 18px; font-size: 12px; right: -2px; bottom: -2px; background: var(--mk-sys-color); } } .card-color-cell { position: relative; border: 1px solid transparent; border-radius: 4px; padding: 4px 6px; margin-bottom: 2px; min-height: 32px; cursor: pointer; .anticon-check { display: none; position: absolute; color: #ffffff; border-radius: 20px; padding: 3px; width: 18px; height: 18px; font-size: 12px; right: 0px; bottom: 0px; background: var(--mk-sys-color); } } .card-pic-cell.active, .card-color-cell.active { .anticon-check { display: inline-block; } } } .check-card-form-wrap.mutile-line { .card-cell { margin-bottom: 12px; } .card-pic-cell { margin-bottom: 12px; } .card-color-cell { margin-bottom: 12px; } } .check-card-form-wrap { .card-cell.mk-background:hover { border-color: var(--mk-sys-color); background: var(--mk-sys-color); span { color: #ffffff!important; } } .card-cell.mk-font:hover { border-color: var(--mk-sys-color); span { color: var(--mk-sys-color)!important; } } .card-cell.mk-custom:not(.active):hover { .bg-mask { opacity: 0.8; } } .card-pic-cell:hover { border-color: var(--mk-sys-color); box-shadow: 0px 0px 4px var(--mk-sys-color); } } .check-card-form-wrap.border-hide { .card-cell { border: 0px; } } .mk-search-card { .ant-dropdown-menu-item.active { color: var(--mk-sys-color); } } src/templates/sharecomponent/searchcomponent/searchform/index.jsx
@@ -119,11 +119,7 @@ } state = { openType: null, // 搜索条件显示类型 resourceType: null, // 下拉搜索时,选项来源类型 formlist: null, // 表单 cFields: [], textTooltip: '字段名可以使用逗号分隔,进行综合搜索', formlist: null } record = {} @@ -213,6 +209,9 @@ } if (this.record.selectStyle === 'custom') { shows.push('backgroundColor') } if (this.record.multiple === 'dropdown') { shows.push('mark') } } shows.push('linkField') @@ -487,7 +486,7 @@ <Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit} /> </AutoComplete> } else { content = <Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit} /> content = <Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit} onChange={(e) => {this.optionChange(item.key, e.target.value)}}/> } } else if (item.type === 'number') { rules = [ @@ -554,7 +553,7 @@ if (this.record.linkField) { type = 'link' } content = <DataTable type={type} display={this.record.display} linkSubFields={[]} transfield={{}} fields={this.record.fields || []} onChange={this.changeOptions}/> content = <DataTable type={type} multiple={this.record.multiple} display={this.record.display} linkSubFields={[]} transfield={{}} fields={this.record.fields || []} onChange={this.changeOptions}/> } } else if (item.type === 'fields') { span = 24 @@ -665,10 +664,15 @@ values.options = [] } } else if (values.type === 'checkcard') { if (values.multiple === 'dropdown' && values.display !== 'text') { values.multiple = 'false' } if (values.resourceType === '0') { values.options = values.options || [] values.options = values.options.map(m => { m.ParentID = m.ParentID || '' m.pid = m.pid || '' return m }) src/templates/zshare/formconfig.jsx
@@ -386,6 +386,30 @@ }) } let muloptions = [{ value: 'false', text: '单选' }, { value: 'true', text: '多选' }, { value: 'dropdown', text: '下拉菜单' }] if (appType !== '') { muloptions = [{ value: 'false', text: '单选' }, { value: 'true', text: '多选' }] if (card.multiple === 'dropdown') { card.multiple = 'false' } } return [ { type: 'text', @@ -573,14 +597,9 @@ key: 'multiple', label: '选择形式', initVal: card.multiple || 'false', tooltip: appType === '' ? '使用下拉菜单时,选项会依据 pid 组织数据的上下级关系,二级选项会下拉展示。注:1、显示为文本时有效;2、使用数据源请返回 pid 字段。' : '', required: true, options: [{ value: 'false', text: '单选' }, { value: 'true', text: '多选' }] options: muloptions }, { type: 'select', @@ -900,6 +919,14 @@ required: true }, { type: 'text', key: 'mark', label: '顶级标识', initVal: card.mark || '', tooltip: 'pid与顶级标识相同时,视为顶级节点。', required: false }, { type: 'multiselect', key: 'blacklist', label: '黑名单', src/templates/zshare/modalform/datatable/index.jsx
@@ -174,6 +174,7 @@ !is(fromJS(this.props.fields), fromJS(nextProps.fields)) || !is(fromJS(this.props.linkSubFields), fromJS(nextProps.linkSubFields)) || this.props.display !== nextProps.display || (nextProps.multiple && this.props.multiple !== nextProps.multiple) || this.props.type !== nextProps.type ) { this.setState({editingKey: ''}, () => { @@ -185,9 +186,9 @@ } getCloumns = () => { const { display, fields, linkSubFields, transfield, type } = this.props const { display, fields, linkSubFields, transfield, type, multiple } = this.props let columns = [] let keys = ['ParentID'] let keys = ['ParentID', 'pid'] if (display === 'picture') { columns.push({ @@ -241,6 +242,14 @@ editable: true, }) if (multiple === 'dropdown' && display === 'text') { columns.unshift({ title: 'pid', dataIndex: 'pid', editable: true, }) } if (type === 'link') { columns.unshift({ title: 'ParentID', src/templates/zshare/modalform/fieldtable/index.jsx
@@ -127,6 +127,26 @@ this.setState({loading: false}) }) return } else if (fields.filter(f => f.toLowerCase() === 'parentid').length > 0) { notification.warning({ top: 92, message: '字段名不可使用parentid!', duration: 5 }) this.setState({loading: true}, () => { this.setState({loading: false}) }) return } else if (fields.filter(f => f.toLowerCase() === 'pid').length > 0) { notification.warning({ top: 92, message: '字段名不可使用pid!', duration: 5 }) this.setState({loading: true}, () => { this.setState({loading: false}) }) return } this.setState({ data }, () => { src/utils/utils.js
@@ -800,6 +800,8 @@ arrfield.push(item.urlField) } else if (item.colorField) { arrfield.push(item.colorField) } else if (item.parentField) { arrfield.push(item.parentField) } }