From fc55bf4131e3056a84ac7bae16540a4e714214b8 Mon Sep 17 00:00:00 2001 From: king <18310653075@163.com> Date: 星期四, 16 二月 2023 18:13:00 +0800 Subject: [PATCH] 2023-02-16 --- src/menu/components/card/double-data-card/options.jsx | 253 ++++++++ src/menu/components/card/doublecardcomponent/options.jsx | 142 ++++ src/tabviews/custom/components/module/voucher/index.jsx | 4 src/menu/datasource/verifycard/index.scss | 17 src/templates/modalconfig/settingform/index.jsx | 24 src/menu/datasource/verifycard/settingform/index.jsx | 2 src/menu/components/card/double-data-card/index.jsx | 643 ++++++++++++++++++++ src/menu/components/card/doublecardcomponent/index.scss | 64 ++ src/menu/components/card/doublecardcomponent/index.jsx | 308 +++++++++ src/menu/components/card/cardcomponent/index.jsx | 2 src/tabviews/zshare/actionList/printbutton/index.jsx | 46 + src/menu/datasource/index.jsx | 4 src/menu/menushell/card.jsx | 3 src/tabviews/zshare/actionList/normalbutton/index.jsx | 47 + src/menu/components/card/cardcomponent/options.jsx | 5 src/menu/components/card/double-data-card/index.scss | 141 ++++ src/menu/datasource/verifycard/index.jsx | 110 +++ src/menu/modulesource/option.jsx | 1 src/assets/css/main.scss | 6 19 files changed, 1,793 insertions(+), 29 deletions(-) diff --git a/src/assets/css/main.scss b/src/assets/css/main.scss index e5ada0e..6f5c18a 100644 --- a/src/assets/css/main.scss +++ b/src/assets/css/main.scss @@ -326,6 +326,12 @@ background: rgba(0, 0, 0, 0); } } +.moveable-modal { + overflow-x: hidden!important; + .ant-modal-header { + cursor: move; + } +} .ant-drawer { z-index: 1080!important; diff --git a/src/menu/components/card/cardcomponent/index.jsx b/src/menu/components/card/cardcomponent/index.jsx index 6bd283e..8509386 100644 --- a/src/menu/components/card/cardcomponent/index.jsx +++ b/src/menu/components/card/cardcomponent/index.jsx @@ -13,7 +13,7 @@ import './index.scss' const NormalForm = asyncIconComponent(() => import('@/components/normalform')) -const CardCellComponent = asyncComponent(() => import('../cardcellcomponent')) +const CardCellComponent = asyncComponent(() => import('@/menu/components/card/cardcellcomponent')) const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent')) const PasteController = asyncIconComponent(() => import('@/components/paste')) diff --git a/src/menu/components/card/cardcomponent/options.jsx b/src/menu/components/card/cardcomponent/options.jsx index dbcca49..02d46f2 100644 --- a/src/menu/components/card/cardcomponent/options.jsx +++ b/src/menu/components/card/cardcomponent/options.jsx @@ -73,7 +73,7 @@ controlFields: [ {field: 'transform', values: ['multi']}, ], - forbid: appType === 'mob' + forbid: appType === 'mob' || subtype === 'dualdatacard' }, { type: 'select', @@ -91,7 +91,8 @@ {value: 'opacity', label: '閫忔槑搴�'}, {value: 'rotateX', label: '绾靛悜灞曞紑'}, {value: 'rotateY', label: '妯悜灞曞紑'}, - ] + ], + forbid: appType === 'mob' || subtype === 'dualdatacard' }, { type: 'text', diff --git a/src/menu/components/card/double-data-card/index.jsx b/src/menu/components/card/double-data-card/index.jsx new file mode 100644 index 0000000..451e497 --- /dev/null +++ b/src/menu/components/card/double-data-card/index.jsx @@ -0,0 +1,643 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import { is, fromJS } from 'immutable' +import { Popover, Modal, Pagination, message } from 'antd' +import { PlusOutlined, PlusCircleOutlined, PlusSquareOutlined, EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined, DownOutlined } from '@ant-design/icons' + +import asyncComponent from '@/utils/asyncComponent' +import asyncIconComponent from '@/utils/asyncIconComponent' +import { resetStyle, getTables } from '@/utils/utils-custom.js' +import MKEmitter from '@/utils/events.js' +import Utils from '@/utils/utils.js' +import getWrapForm from './options' +import './index.scss' + +const SettingComponent = asyncIconComponent(() => import('@/menu/datasource')) +const NormalForm = asyncIconComponent(() => import('@/components/normalform')) +const CardComponent = asyncComponent(() => import('../cardcomponent')) +const DoubleCardComponent = asyncComponent(() => import('../doublecardcomponent')) +const MobPagination = asyncIconComponent(() => import('@/menu/components/share/mobPagination')) +const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent')) +const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent')) +const PasteComponent = asyncIconComponent(() => import('@/components/paste')) +const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader')) +const ClockComponent = asyncIconComponent(() => import('@/menu/components/share/clockcomponent')) +const ActionComponent = asyncComponent(() => import('@/menu/components/share/actioncomponent')) + +const { confirm } = Modal + +class DoubleDataCardEditComponent extends Component { + static propTpyes = { + card: PropTypes.object, + deletecomponent: PropTypes.func, + updateConfig: PropTypes.func, + } + + state = { + card: null, + appType: sessionStorage.getItem('appType'), + back: false + } + + UNSAFE_componentWillMount () { + const { card } = this.props + + if (card.isNew) { + let _card = { + uuid: card.uuid, + type: card.type, + format: 'array', // 缁勪欢灞炴�� - 鏁版嵁鏍煎紡 + pageable: true, // 缁勪欢灞炴�� - 鏄惁鍙垎椤� + switchable: true, // 缁勪欢灞炴�� - 鏁版嵁鏄惁鍙垏鎹� + width: card.width || 24, + name: card.name, + subtype: card.subtype, + setting: { interType: 'system' }, + wrap: { name: card.name, width: card.width || 24, title: '', pagestyle: 'page', cardType: '' }, + style: { marginLeft: '0px', marginRight: '0px', marginTop: '8px', marginBottom: '8px' }, + headerStyle: { fontSize: '16px', borderBottomWidth: '1px', borderBottomColor: '#e8e8e8' }, + columns: [], + subColumns: [], + scripts: [], + action: [], + search: [], + subcards: [{ + uuid: Utils.getuuid(), + setting: { width: 24}, + style: { + borderWidth: '1px', borderColor: '#e8e8e8', + paddingTop: '15px', paddingBottom: '15px', paddingLeft: '15px', paddingRight: '15px', + marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px' + }, + elements: [{ + uuid: Utils.getuuid(), + eleType: 'text', + datatype: 'static', + value: '寰幆鍖哄煙' + }], + backSetting: {}, + backStyle: { + borderLeftWidth: '1px', borderLeftColor: '#e8e8e8', + borderRightWidth: '1px', borderRightColor: '#e8e8e8', + borderBottomWidth: '1px', borderBottomColor: '#e8e8e8', + paddingTop: '15px', paddingBottom: '15px', paddingLeft: '15px', paddingRight: '15px' + }, + backElements: [{ + uuid: Utils.getuuid(), + eleType: 'text', + datatype: 'static', + value: '瀛愯〃鍖哄煙' + }] + }] + } + + if (card.config) { + let config = fromJS(card.config).toJS() + + _card.wrap = config.wrap + _card.wrap.name = card.name + _card.style = config.style + _card.headerStyle = config.headerStyle + + _card.setting = config.setting + _card.columns = config.columns + _card.scripts = config.scripts + + _card.subcards = config.subcards.map(scard => { + scard.uuid = Utils.getuuid() + scard.elements = scard.elements.map(elem => { + elem.uuid = Utils.getuuid() + return elem + }) + scard.backElements = scard.backElements.map(elem => { + elem.uuid = Utils.getuuid() + return elem + }) + return scard + }) + _card.action = config.action.map(col => { + col.uuid = Utils.getuuid() + return col + }) + _card.search = config.search.map(col => { + col.uuid = Utils.getuuid() + return col + }) + } + + this.updateComponent(_card) + } else { + let _card = fromJS(card).toJS() + + this.setState({ + card: _card + }) + } + } + + shouldComponentUpdate (nextProps, nextState) { + return !is(fromJS(this.state), fromJS(nextState)) + } + + /** + * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊锛屾竻闄ゅ揩鎹烽敭璁剧疆 + */ + componentWillUnmount () { + this.setState = () => { + return + } + } + + /** + * @description 鍗$墖琛屽灞備俊鎭洿鏂帮紙鏁版嵁婧愶紝鏍峰紡绛夛級 + */ + updateComponent = (card) => { + card.width = card.wrap.width + card.name = card.wrap.name + + if (window.GLOB.styling && card.errors) { // 鏍峰紡淇敼鏃朵笉鍋氱瓫鏌� + this.setState({ + card: card + }) + + this.props.updateConfig(card) + return + } + + card.errors = [] + let columns = card.columns.map(c => c.field) + + if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) { + card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'}) + } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) { + card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'}) + } else if (!card.setting.primaryKey) { + card.errors.push({ level: 0, detail: '鏈缃富閿紒'}) + } else if (!columns.includes(card.setting.primaryKey)) { + card.errors.push({ level: 0, detail: '涓婚敭宸插け鏁堬紒'}) + } else if (!card.setting.supModule) { + card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'}) + } + + if (card.errors.length === 0) { + card.$tables = getTables(card) + } + + card.action.forEach(cell => { + if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) { + if (!cell.modal || cell.modal.fields.length === 0) { + card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`}) + } + } + }) + + card.subcards.forEach((item, i) => { + let linkbtn = item.setting.linkbtn || '' + item.elements.forEach(cell => { + if (cell.eleType === 'button') { + if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) { + if (!cell.modal || cell.modal.fields.length === 0) { + card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`}) + } + } + if (linkbtn && linkbtn === cell.uuid) { + linkbtn = '' + } + } else if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) { + card.errors.push({ level: 1, detail: `鍗$墖涓姩鎬佸瓧娈碘��${cell.field}鈥濇棤鏁坄}) + } + }) + + item.backElements.forEach(cell => { + if (cell.eleType === 'button') { + if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) { + if (!cell.modal || cell.modal.fields.length === 0) { + card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`}) + } + } + if (linkbtn && linkbtn === cell.uuid) { + linkbtn = '' + } + } else if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) { + card.errors.push({ level: 1, detail: `鍗$墖涓姩鎬佸瓧娈碘��${cell.field}鈥濇棤鏁坄}) + } + }) + + if (linkbtn) { + card.errors.push({ level: 1, detail: `绗�${i + 1}寮犲崱鐗囦腑缁戝畾鎸夐挳宸插垹闄}) + } + }) + + this.setState({ + card: card + }) + + this.props.updateConfig(card) + } + + /** + * @description 鍗曚釜鍗$墖淇℃伅鏇存柊 + */ + updateCard = (cell, btn) => { + let card = fromJS(this.state.card).toJS() + + card.subcards = card.subcards.map(item => { + if (item.uuid === cell.uuid) return cell + return item + }) + + if (btn) { + card.action = card.action.filter(item => item.uuid !== btn.uuid) + } + + this.updateComponent(card) + } + + /** + * @description 鍗曚釜鍗$墖淇℃伅鏇存柊 + */ + deleteCard = (cell) => { + let card = fromJS(this.state.card).toJS() + let _this = this + + confirm({ + content: '纭畾鍒犻櫎鍗$墖鍚楋紵', + onOk() { + card.subcards = card.subcards.filter(item => item.uuid !== cell.uuid) + + _this.updateComponent(card) + }, + onCancel() {} + }) + } + + changeStyle = () => { + const { card } = this.state + + MKEmitter.emit('changeStyle', ['background', 'height', 'border', 'padding', 'margin', 'shadow', 'clear', 'minHeight'], card.style, this.getStyle) + } + + getStyle = (style) => { + let _card = {...this.state.card, style} + + this.updateComponent(_card) + } + + addSearch = (copy) => { + const { card } = this.state + + let newcard = {} + + if (copy) { + newcard = copy + newcard.focus = true + } else { + newcard.uuid = Utils.getuuid() + newcard.focus = true + + newcard.label = 'label' + newcard.type = 'select' + newcard.resourceType = '0' + newcard.options = [] + newcard.orderType = 'asc' + newcard.match = '=' + } + + // 娉ㄥ唽浜嬩欢-娣诲姞鎼滅储 + MKEmitter.emit('addSearch', card.uuid, newcard) + } + + addButton = (copy) => { + const { card } = this.state + + let newcard = {} + + if (copy) { + newcard = copy + newcard.focus = true + } else { + newcard.uuid = Utils.getuuid() + newcard.focus = true + + newcard.label = 'label' + newcard.Ot = 'requiredSgl' + newcard.OpenType = 'pop' + newcard.icon = '' + newcard.class = 'green' + newcard.intertype = card.setting.interType || 'system' + newcard.innerFunc = card.setting.innerFunc || '' + newcard.sysInterface = card.setting.sysInterface || '' + newcard.outerFunc = card.setting.outerFunc || '' + newcard.interface = card.setting.interface || '' + newcard.execSuccess = 'grid' + newcard.execError = 'never' + newcard.verify = null + newcard.show = 'button' + newcard.style = {marginRight: '15px'} + } + + // 娉ㄥ唽浜嬩欢-娣诲姞鎸夐挳 + MKEmitter.emit('addButton', card.uuid, newcard) + } + + setSubConfig = (item) => { + const { card, appType } = this.state + let btn = fromJS(item).toJS() + + if (btn.OpenType === 'pop' || btn.execMode === 'pop') { + if (!btn.modal) { + btn.modal = { + setting: { title: btn.label, width: appType === 'mob' ? 100 : 60, cols: '2', container: 'view', focus: '', finish: 'close', clickouter: 'unclose', display: 'modal' }, + tables: [], + groups: [], + fields: [] + } + } + MKEmitter.emit('changeModal', card, btn) + } else if (btn.OpenType === 'popview' && appType !== 'mob') { + MKEmitter.emit('changePopview', card, btn) + } + } + + addCard = (copy) => { + let card = fromJS(this.state.card).toJS() + let newcard = {} + + if (copy) { // 绮樿创 + newcard = copy + } else { + let height = card.subcards[0].style.height + if (height === 'auto') { + height = '100px' + } + + newcard = { + uuid: Utils.getuuid(), + $cardType: 'extendCard', + setting: { width: 24, click: ''}, + style: { + height, + borderWidth: '1px', borderColor: '#e8e8e8', + paddingTop: '15px', paddingBottom: '15px', paddingLeft: '15px', paddingRight: '15px', + marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px' + }, + backStyle: {}, + elements: [], + backElements: [] + } + } + + card.subcards.push(newcard) + + this.updateComponent(card) + } + + move = (item, direction) => { + let card = fromJS(this.state.card).toJS() + + let dragIndex = card.subcards.findIndex(c => c.uuid === item.uuid) + let hoverIndex = null + + if (direction === 'left') { + hoverIndex = dragIndex - 1 + } else { + hoverIndex = dragIndex + 1 + } + + if (hoverIndex === -1 || hoverIndex === card.subcards.length) return + + card.subcards.splice(hoverIndex, 0, ...card.subcards.splice(dragIndex, 1)) + + this.updateComponent(card) + } + + getWrapForms = () => { + const { card } = this.state + + return getWrapForm(card.wrap, card.columns, card.setting) + } + + updateWrap = (res) => { + const { card } = this.state + + let _card = {...card, wrap: res} + + if (res.supNodes) { + _card.supNodes = res.supNodes + _card.supNodes = _card.supNodes.map(item => { + item.componentId = item.nodes[item.nodes.length - 1] + return item + }) + + delete res.supNodes + } else { + delete _card.supNodes + } + + + if (res.layout === 'flex') { + _card.wrap.pagestyle = 'page' + } + + if (res.selStyle === 'tabs' && card.wrap.selStyle !== 'tabs') { + Object.keys(_card.style).forEach(key => { + if (/^border/.test(key)) { + delete _card.style[key] + } + }) + _card.style.borderBottomColor = '#eeeeee' + _card.style.borderBottomWidth = '1px' + _card.style.paddingBottom = '0px' + + _card.subcards.forEach(item => { + delete item.style.marginBottom + }) + + this.setState({card: {..._card, subcards: []}}, () => { + this.updateComponent(_card) + }) + } else { + this.updateComponent(_card) + } + } + + pasteComponent = (res, resolve) => { + const { card, appType } = this.state + + let type = res.copyType + delete res.copyType + + if (type === 'cardcell') { + res.uuid = Utils.getuuid() + res.setting = res.setting || {} + res.$cardType = 'extendCard' + res.setting.width = res.setting.width || 6 + + let mobtypes = ['pop', 'prompt', 'exec', 'innerpage', 'funcbutton'] + + let elements = [] + res.elements && res.elements.forEach(cell => { + // if (cell.datatype === 'dynamic') { + // cell.datatype = 'static' + // } + + if (cell.eleType !== 'button') { + cell.uuid = Utils.getuuid() + elements.push(cell) + } else if (appType === 'mob' && !mobtypes.includes(cell.OpenType)) { + return + } else { + cell.uuid = Utils.getuuid() + elements.push(cell) + } + }) + + res.elements = elements + + let backElements = [] + + if (appType !== 'mob') { + res.backElements && res.backElements.forEach(cell => { + // if (cell.datatype === 'dynamic') { + // cell.datatype = 'static' + // } + + if (cell.eleType !== 'button') { + cell.uuid = Utils.getuuid() + backElements.push(cell) + } else if (appType === 'mob' && !mobtypes.includes(cell.OpenType)) { + return + } else { + cell.uuid = Utils.getuuid() + backElements.push(cell) + } + }) + } + + res.backElements = backElements + + resolve({status: true}) + + this.addCard(res) + } else if (type === 'search' || type === 'form') { + if (appType === 'mob') { + resolve({status: false, message: '绉诲姩绔暟鎹崱涓嶆敮鎸佹坊鍔犳悳绱㈡潯浠躲��'}) + } else { + res.uuid = Utils.getuuid() + let keys = card.search.map(item => item.field.toLowerCase()) + + if (type === 'form') { + if (['number', 'switch', 'textarea', 'fileupload', 'hint', 'color', 'funcvar'].includes(res.type)) { + res.type = 'text' + } else if (res.type === 'radio') { + res.type = 'select' + } else if (res.type === 'checkbox') { + res.type = 'multiselect' + } else if (res.type === 'datetime') { + res.type = 'date' + } + } + + if (res.field && keys.includes(res.field.toLowerCase())) { + resolve({status: false, message: '鎼滅储瀛楁宸插瓨鍦紒'}) + return + } + + resolve({status: true}) + + this.addSearch(res) + } + } else if (type === 'action') { + if (appType === 'mob' && !['pop', 'prompt', 'exec', 'innerpage'].includes(res.OpenType)) { + resolve({status: false, message: '绉诲姩绔笉鏀寔姝ょ被鍨嬬殑鎸夐挳銆�'}) + } else { + resolve({status: true}) + + res.uuid = Utils.getuuid() + this.addButton(res) + } + } + } + + clickComponent = (e) => { + if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') { + e.stopPropagation() + MKEmitter.emit('clickComponent', this.state.card.uuid, null, (style) => { + let _card = {...this.state.card} + _card.style = {..._card.style, ...style} + + this.setState({ card: _card }) + this.props.updateConfig(_card) + }) + } + } + + render() { + const { card, appType } = this.state + + let _style = resetStyle(card.style) + + return ( + <div className={'menu-double-data-card-edit-box ' + appType} style={_style} onClick={this.clickComponent} id={card.uuid}> + <NormalHeader config={card} updateComponent={this.updateComponent}/> + <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ + <div className="mk-popover-control"> + <PlusOutlined className="plus" title="娣诲姞鍗$墖" onClick={() => this.addCard()}/> + {appType !== 'mob' ? <PlusCircleOutlined className="plus" title="娣诲姞鎼滅储" onClick={() => this.addSearch()}/> : null} + <PlusSquareOutlined className="plus" title="娣诲姞鎸夐挳" onClick={() => this.addButton()}/> + <NormalForm title="鏁版嵁鍗¤缃�" width={800} update={this.updateWrap} getForms={this.getWrapForms}> + <EditOutlined style={{color: '#1890ff'}} title="缂栬緫"/> + </NormalForm> + <CopyComponent type="datacard" card={card}/> + <PasteComponent options={['action', 'search', 'form', 'cardcell']} updateConfig={this.pasteComponent} /> + <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle}/> + <ClockComponent config={card} updateConfig={this.updateComponent}/> + <UserComponent config={card}/> + <DeleteOutlined className="close" title="鍒犻櫎缁勪欢" onClick={() => this.props.deletecomponent(card.uuid)} /> + <SettingComponent config={card} updateConfig={this.updateComponent} /> + </div> + } trigger="hover"> + <ToolOutlined /> + </Popover> + <ActionComponent config={card} setSubConfig={this.setSubConfig} updateaction={this.updateComponent}/> + <div className={'float-' + (card.wrap.cardFloat || 'left') + ' select-' + card.wrap.selStyle}> + {card.subcards.map(subcard => { + if (subcard.$cardType === 'extendCard') { + return (<CardComponent key={subcard.uuid} cards={card} card={subcard} move={this.move} updateElement={this.updateCard} deleteElement={this.deleteCard}/>) + } else { + return (<DoubleCardComponent key={subcard.uuid} cards={card} card={subcard} updateElement={this.updateCard}/>) + } + })} + </div> + <div style={{clear: 'both'}}></div> + {card.wrap.pagestyle === 'page' && card.setting.laypage === 'true' && appType !== 'mob' ? <Pagination total={85} size="small" showTotal={total => `鍏� ${total} 鏉} pageSize={20} defaultCurrent={1}/> : null} + {card.wrap.pagestyle === 'page' && card.setting.laypage === 'true' && appType === 'mob' ? <MobPagination /> : null} + {card.wrap.pagestyle === 'more' && card.setting.laypage === 'true' ? <div className="mk-more">鏌ョ湅鏇村<DownOutlined/></div> : null} + <div className="component-name"> + <div className="center"> + <div className="title" onDoubleClick={() => { + let oInput = document.createElement('input') + oInput.value = card.uuid + document.body.appendChild(oInput) + oInput.select() + document.execCommand('Copy') + document.body.removeChild(oInput) + message.success('澶嶅埗鎴愬姛銆�') + }}>{card.name}</div> + <div className="content"> + {card.errors && card.errors.map((err, index) => { + if (err.level === 0) { + return <span key={index} className="error">{err.detail}</span> + } else { + return <span key={index} className="waring">{err.detail}锛�</span> + } + })} + </div> + </div> + </div> + </div> + ) + } +} + +export default DoubleDataCardEditComponent \ No newline at end of file diff --git a/src/menu/components/card/double-data-card/index.scss b/src/menu/components/card/double-data-card/index.scss new file mode 100644 index 0000000..9a5313d --- /dev/null +++ b/src/menu/components/card/double-data-card/index.scss @@ -0,0 +1,141 @@ +.menu-double-data-card-edit-box { + position: relative; + box-sizing: border-box; + background: #ffffff; + background-position: center center; + background-repeat: no-repeat; + background-size: cover; + min-height: 20px; + overflow-y: auto; + + >.anticon-tool { + position: absolute; + z-index: 2; + font-size: 16px; + right: 1px; + top: 1px; + cursor: pointer; + padding: 5px; + background: rgba(255, 255, 255, 0.55); + } + + .card-item { + overflow: hidden; + position: relative; + background-color: #ffffff; + background-position: center center; + background-repeat: no-repeat; + background-size: cover; + min-height: 20px; + } + .card-item.hover:not(:hover) { + button { + opacity: 0; + transition: opacity 0.3s; + } + } + + .card-item:hover { + box-shadow: 0px 0px 2px #1890ff; + } + + .model-menu-card-cell-list .card-detail-row > .anticon-plus { + position: absolute; + right: -30px; + font-size: 16px; + } + .model-menu-action-list { + line-height: 40px; + .ant-row > .anticon-plus { + position: absolute; + right: -30px; + font-size: 16px; + } + } + .ant-pagination { + float: right; + margin: 10px; + } + + .model-menu-action-list { + .page-card { + line-height: 55px; + } + } + .normal-pagination { + .am-button::before { + display: none; + } + .am-button { + border: none; + font-size: 16px; + } + } + .float-center { + text-align: center; + >.ant-col { + display: inline-block; + float: none; + text-align: left; + vertical-align: top; + } + } + .float-right { + text-align: right; + >.ant-col { + display: inline-block; + float: none; + text-align: left; + vertical-align: top; + } + } + .select-tabs { + .card-item { + border-top: none!important; + border-left: none!important; + border-right: none!important; + border-radius: 0px!important; + border-bottom: 2px solid transparent!important; + } + } + .mk-more { + text-align: center; + line-height: 40px; + .anticon-down { + margin-left: 2px; + } + } +} + +.menu-double-data-card-edit-box::-webkit-scrollbar { + width: 7px; + height: 7px; +} +.menu-double-data-card-edit-box::-webkit-scrollbar-thumb { + border-radius: 5px; + box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13); + background: rgba(0, 0, 0, 0.13); +} +.menu-double-data-card-edit-box::-webkit-scrollbar-track { + box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05); + border-radius: 3px; + border: 1px solid rgba(0, 0, 0, 0.07); + background: rgba(0, 0, 0, 0); +} +.menu-double-data-card-edit-box::after { + display: block; + content: ' '; + clear: both; +} +.menu-double-data-card-edit-box.mob { + .model-menu-action-list { + .page-card { + line-height: 40px; + margin-top: 5px; + } + } +} +.menu-double-data-card-edit-box:hover { + z-index: 1; + box-shadow: 0px 0px 4px #1890ff; +} diff --git a/src/menu/components/card/double-data-card/options.jsx b/src/menu/components/card/double-data-card/options.jsx new file mode 100644 index 0000000..2a7fabe --- /dev/null +++ b/src/menu/components/card/double-data-card/options.jsx @@ -0,0 +1,253 @@ +/** + * @description Wrap琛ㄥ崟閰嶇疆淇℃伅 + */ +export default function (wrap, columns = [], setting) { + let appType = sessionStorage.getItem('appType') + let MenuType = '' + let menu = window.GLOB.customMenu + let laypage = setting && setting.laypage !== 'false' + + if (menu.parentId === 'BillPrintTemp') { + MenuType = 'billPrint' + } + + let roleList = sessionStorage.getItem('sysRoles') + + if (roleList) { + try { + roleList = JSON.parse(roleList) + } catch (e) { + roleList = [] + } + } else { + roleList = [] + } + + let menulist = [] + + if (appType === 'mob') { + menulist = sessionStorage.getItem('appMenus') + if (menulist) { + try { + menulist = JSON.parse(menulist) + } catch (e) { + menulist = [] + } + } else { + menulist = [] + } + } + + const cardWrapForm = [ + { + type: 'text', + field: 'title', + label: '鏍囬', + initval: wrap.title || '', + required: false + }, + { + type: 'text', + field: 'name', + label: '缁勪欢鍚嶇О', + initval: wrap.name || '', + tooltip: '鐢ㄤ簬缁勪欢闂寸殑鍖哄垎銆�', + required: true + }, + { + type: 'number', + field: 'width', + label: '瀹藉害', + initval: wrap.width || 24, + tooltip: '鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��', + min: 1, + max: 24, + precision: 0, + required: true + }, + { + type: 'radio', + field: 'layout', + label: '鍗$墖甯冨眬', + initval: wrap.layout || 'grid', + tooltip: appType === 'mob' ? '寮规�у竷灞�鏃讹紝婊戝姩鍔犺浇鏃犳晥' : '', + required: false, + options: [ + {value: 'grid', label: '鏍呮牸甯冨眬'}, + {value: 'flex', label: '寮规�у竷灞�'}, + ], + controlFields: [ + {field: 'printHeight', values: ['flex']}, + {field: 'cardFloat', values: ['grid']}, + ] + }, + { + type: 'radio', + field: 'pagestyle', + label: '鍒嗛〉椋庢牸', + initval: wrap.pagestyle || 'page', + tooltip: '鏁版嵁婧愰�夋嫨鍒嗛〉鏃舵湁鏁堛�傛敞锛氬脊鎬у竷灞�鏃跺浐瀹氫负椤电爜銆�', + required: false, + disabled: !laypage, + options: [ + {value: 'page', label: '椤电爜'}, + {value: 'slide', label: '婊戝姩鍔犺浇', forbid: appType !== 'mob' || sessionStorage.getItem('editMenuType') === 'popview'}, + {value: 'more', label: '鏌ョ湅鏇村'}, + ], + controlFields: [ + {field: 'slidetip', values: ['slide']}, + ], + }, + { + type: 'radio', + field: 'cardType', + label: '鏁版嵁閫夋嫨', + initval: wrap.cardType || '', + required: false, + options: [ + {value: '', label: '涓嶅彲閫�'}, + {value: 'radio', label: '鍗曢��'}, + {value: 'checkbox', label: '澶氶��'}, + ], + controlFields: [ + {field: 'selected', values: ['radio', 'checkbox']}, + {field: 'selStyle', values: ['radio', 'checkbox']}, + ], + }, + { + type: 'select', + field: 'selected', + label: '鏁版嵁閫変腑', + initval: wrap.selected || 'false', + tooltip: '鍒濆鍖栵細鏁版嵁鍔犺浇鏃堕�変腑棣栬鏁版嵁锛屼粎鎵ц涓�娆°�傛暟鎹姞杞斤細姣忔鏁版嵁鍔犺浇鏃跺潎閫変腑棣栬锛堝綋鎸夐挳鎵ц瀹屾垚骞惰繑鍥炰富閿�兼椂锛岄粯璁ら�変腑涓婚敭鍊煎搴旇锛夈�傞�変腑鏍囪锛氳繑鍥炴暟鎹腑瀛樺湪 selected 瀛楁锛屼笖鍊间负 true 鐨勬暟鎹閫変腑銆�', + required: false, + options: [ + {value: 'false', label: '鏃�'}, + {value: 'init', label: '鍒濆鍖�'}, + {value: 'always', label: '鏁版嵁鍔犺浇'}, + {value: 'sign', label: '閫変腑鏍囪'} + ], + }, + { + type: 'select', + field: 'selStyle', + label: '閫変腑椋庢牸', + initval: wrap.selStyle || 'active', + tooltip: '瀛樺湪杈规鏃讹紝杈规浼氫娇鐢ㄧ郴缁熻壊銆�', + required: false, + options: [ + {value: 'none', label: '鏃�'}, + {value: 'active', label: '澶栭槾褰�'}, + {value: 'backFont', label: '鑳屾櫙+鏂囧瓧'}, + {value: 'font', label: '鏂囧瓧'}, + {value: 'check', label: '鍕鹃�夛紙鍦嗘锛�'}, + {value: 'check square', label: '鍕鹃�夛紙鏂规锛�'} + ] + }, + { + type: 'radio', + field: 'cardFloat', + label: '瀵归綈鏂瑰紡', + initval: wrap.cardFloat || 'left', + tooltip: '璁剧疆鍗$墖鐨勫榻愭柟寮忋��', + required: false, + options: [ + {value: 'left', label: '宸﹀榻�'}, + {value: 'center', label: '灞呬腑'}, + {value: 'right', label: '鍙冲榻�'}, + ], + }, + { + type: 'radio', + field: 'parity', + label: '濂囧伓鑳屾櫙', + initval: wrap.parity || 'false', + tooltip: '鍋舵暟琛屼細娣诲姞鑳屾櫙鑹层��', + required: false, + options: [ + {value: 'false', label: '鏃�'}, + {value: 'true', label: '鏈�'}, + ], + }, + { + type: 'number', + field: 'printHeight', + label: '鎹㈢畻楂樺害', + initval: wrap.printHeight || '', + tooltip: '褰撳墠鏁版嵁鍗¢珮搴︾浉褰撲簬鍑犳潯鏁版嵁銆�', + required: false, + forbid: MenuType !== 'billPrint' + }, + { + type: 'radio', + field: 'empty', + label: '绌哄�奸殣钘�', + initval: wrap.empty || 'show', + tooltip: '褰撴煡璇㈡暟鎹负绌烘椂锛岄殣钘忚缁勪欢銆�', + required: false, + options: [ + {value: 'show', label: '鍚�'}, + {value: 'hidden', label: '鏄�'}, + ], + }, + { + type: 'select', + field: 'controlField', + label: '绂佺敤瀛楁', + initval: wrap.controlField || '', + tooltip: '鐢ㄤ簬鎺у埗琛屾暟鎹槸鍚﹀彲閫夋嫨銆�', + required: false, + allowClear: true, + options: columns, + controlFields: [ + {field: 'controlVal', notNull: true}, + ], + }, + { + type: 'text', + field: 'controlVal', + label: '绂佺敤鍊�', + initval: wrap.controlVal || '', + tooltip: '褰撳瓧娈靛�间笌绂佺敤鍊肩浉绛夋椂锛岃鏁版嵁浼氱鐢紝澶氫釜鍊肩敤閫楀彿鍒嗛殧銆�', + required: false + }, + { + type: 'radio', + field: 'permission', + label: '鏉冮檺楠岃瘉', + initval: wrap.permission || 'false', + required: false, + options: [ + {value: 'true', label: '鍚敤'}, + {value: 'false', label: '绂佺敤'}, + ], + forbid: !appType || sessionStorage.getItem('editMenuType') === 'popview' + }, + { + type: 'multiselect', + field: 'blacklist', + label: '榛戝悕鍗�', + initval: wrap.blacklist || [], + required: false, + options: roleList, + forbid: !!appType + }, + { + type: 'text', + field: 'slidetip', + label: '搴曢儴鎻愮ず', + initval: wrap.slidetip || wrap.slidetip === '' ? wrap.slidetip : '娌℃湁鏇村浜�', + tooltip: '婊戝姩鍔犺浇鑷冲簳閮ㄦ椂鐨勬彁绀轰俊鎭��', + required: false, + forbid: !laypage || appType !== 'mob' + }, + ] + + return cardWrapForm.filter(item => { + if (['pagestyle'].includes(item.field)) { + item.options = item.options.filter(option => !option.forbid) + } + + return !item.forbid + }) +} \ No newline at end of file diff --git a/src/menu/components/card/doublecardcomponent/index.jsx b/src/menu/components/card/doublecardcomponent/index.jsx new file mode 100644 index 0000000..6f1d02c --- /dev/null +++ b/src/menu/components/card/doublecardcomponent/index.jsx @@ -0,0 +1,308 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import { is, fromJS } from 'immutable' +import { Popover, Col } from 'antd' +import { PlusOutlined, PlusSquareOutlined, EditOutlined, ToolOutlined, FontColorsOutlined } from '@ant-design/icons' + +import asyncComponent from '@/utils/asyncComponent' +import asyncIconComponent from '@/utils/asyncIconComponent' +import { resetStyle } from '@/utils/utils-custom.js' +import getSettingForm from './options' +import Utils from '@/utils/utils.js' +import MKEmitter from '@/utils/events.js' +import './index.scss' + +const NormalForm = asyncIconComponent(() => import('@/components/normalform')) +const CardCellComponent = asyncComponent(() => import('@/menu/components/card/cardcellcomponent')) +const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent')) +const PasteController = asyncIconComponent(() => import('@/components/paste')) + +class DoubleCardBoxComponent extends Component { + static propTpyes = { + cards: PropTypes.object, // 鍗$墖琛岄厤缃俊鎭� + card: PropTypes.object, // 鍗$墖閰嶇疆淇℃伅 + updateElement: PropTypes.func // 鑿滃崟閰嶇疆鏇存柊 + } + + state = { + card: null, // 鍗$墖淇℃伅锛屽寘鎷鍙嶉潰 + appType: sessionStorage.getItem('appType'), + visible: false + } + + /** + * @description 鎼滅储鏉′欢鍒濆鍖� + */ + UNSAFE_componentWillMount () { + const { card } = this.props + + this.setState({ + card: fromJS(card).toJS() + }) + } + + shouldComponentUpdate (nextProps, nextState) { + const { cards } = this.props + + return !is(fromJS(cards), fromJS(nextProps.cards)) || !is(fromJS(this.state), fromJS(nextState)) + } + + /** + * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊锛屾竻闄ゅ揩鎹烽敭璁剧疆 + */ + componentWillUnmount () { + this.setState = () => { + return + } + } + + getStyle = (style) => { + const { card, side } = this.state + + let _card = fromJS(card).toJS() + if (side === 'back') { + _card.backStyle = style + } else { + _card.style = style + } + + this.setState({ + card: _card + }) + + this.props.updateElement(_card) + } + + updateCard = (elements, btn) => { + const { card, side } = this.state + + let _card = {} + + if (side === 'back') { + _card = {...card, backElements: elements} + } else { + _card = {...card, elements: elements} + } + + this.setState({ + card: _card + }) + + this.props.updateElement(_card, btn) + } + + changeSide = () => { + const { card } = this.props + const { side } = this.state + + let _side = '' + let _elements = null + if (side === 'front') { + _side = 'back' + } else { + _side = 'front' + } + + if (_side === 'front') { + _elements = fromJS(card.elements).toJS() + } else { + _elements = fromJS(card.backElements).toJS() + } + + this.setState({side: _side, elements: _elements}) + } + + addElement = () => { + const { card } = this.state + + let newcard = {} + newcard.uuid = Utils.getuuid() + newcard.focus = true + + newcard.eleType = 'text' + newcard.datatype = 'dynamic' + newcard.height = 1 + + // 娉ㄥ唽浜嬩欢-娣诲姞鍏冪礌 + MKEmitter.emit('cardAddElement', card.uuid, newcard) + } + + addButton = () => { + const { card } = this.state + + let newcard = {eleType: 'button', label: 'button', verify: null, show: 'link', sqlType: '', Ot: 'requiredSgl', OpenType: 'prompt', icon: '', class: 'primary', intertype: 'system', execSuccess: 'grid', execError: 'never', popClose: 'never'} + newcard.uuid = Utils.getuuid() + newcard.focus = true + + // 娉ㄥ唽浜嬩欢-娣诲姞鍏冪礌 + MKEmitter.emit('cardAddElement', card.uuid, newcard) + } + + changeStyle = () => { + const { card, side } = this.state + + let _style = null + let options = ['height', 'background', 'border', 'padding', 'margin', 'shadow'] + if (side === 'front') { + _style = card.style ? fromJS(card.style).toJS() : {} + } else if (side === 'back') { + _style = card.backStyle ? fromJS(card.backStyle).toJS() : {} + options = ['background', 'padding'] + } + + MKEmitter.emit('changeStyle', options, _style, this.getStyle) + } + + getSettingForms = () => { + const { cards } = this.props + const { card, appType } = this.state + + let buttons = [] + card.elements && card.elements.forEach(item => { + if (item.eleType === 'button') { + buttons.push({ + value: item.uuid, + label: item.label + }) + } + }) + if (appType !== 'mob' && card.backElements) { + card.backElements.forEach(item => { + if (item.eleType === 'button') { + buttons.push({ + value: item.uuid, + label: item.label + }) + } + }) + } + return getSettingForm(card.setting, cards.subtype, buttons, card.$cardType, cards.columns) + } + + updateSetting = (res) => { + const { card, side, appType } = this.state + + if (appType === '' && res.menu) { + let list = null + try { + list = JSON.parse(sessionStorage.getItem('thdMenuList')) || [] + } catch (e) { + list = [] + } + + let id = res.menu[res.menu.length - 1] + + list.forEach(item => { + if (item.MenuID === id) { + res.MenuID = id + res.MenuName = item.MenuName + res.MenuNo = item.MenuNo + res.tabType = item.type + } + }) + } + + let _card = {...card, setting: res} + + this.setState({ + card: _card + }) + + if (side === 'back' && res.type === 'simple') { + this.setState({ + side: 'front', + elements: fromJS(_card.elements).toJS() + }) + } + + this.props.updateElement(_card) + } + + paste = (element, resolve) => { + const { card } = this.state + + let _uuid = Utils.getuuid() + + if (element.copyType === 'action') { + element.eleType = 'button' + } + + element.uuid = _uuid + element.focus = true + + resolve({status: true}) + + // 娉ㄥ唽浜嬩欢-娣诲姞鍏冪礌 + MKEmitter.emit('cardAddElement', card.uuid, element) + } + + doubleClickCard = () => { + const { card } = this.state + + if (card.setting.click === 'menu' && card.setting.menu) { + MKEmitter.emit('changeEditMenu', {MenuID: card.setting.menu}) + } + } + + render() { + const { cards } = this.props + const { card } = this.state + + let _style = {...card.style} + let _backStyle = {...card.backStyle} + + _backStyle.marginLeft = _style.marginLeft + _backStyle.marginRight = _style.marginRight + _backStyle.marginBottom = _style.marginBottom + + delete _style.marginBottom + + _style = resetStyle(_style) + _backStyle = resetStyle(_backStyle) + + return ( + <Col span={card.setting.width || 24}> + <div className={'card-item ' + (card.setting.btnControl || '')} style={_style} onDoubleClick={(e) => {e.stopPropagation(); this.doubleClickCard()}} id={card.uuid}> + <div className="card-control" onDoubleClick={(e) => e.stopPropagation()}> + <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ + <div className="mk-popover-control"> + <PlusOutlined className="plus" title="娣诲姞鍏冪礌" onClick={this.addElement} /> + <PlusSquareOutlined className="plus" title="娣诲姞鎸夐挳" onClick={this.addButton} /> + <NormalForm title={'寰幆鍗$墖璁剧疆'} width={950} update={this.updateSetting} getForms={this.getSettingForms}> + <EditOutlined className="edit" title="缂栬緫"/> + </NormalForm> + <CopyComponent type="cardcell" card={card}/> + <PasteController options={['action', 'customCardElement']} updateConfig={this.paste} /> + <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} /> + </div> + } trigger="hover"> + <ToolOutlined /> + </Popover> + </div> + <CardCellComponent cards={cards} cardCell={card} side="" elements={card.elements} updateElement={this.updateCard}/> + </div> + <div className={'card-item ' + (card.setting.btnControl || '')} style={_backStyle} onDoubleClick={(e) => {e.stopPropagation(); this.doubleClickCard()}} id={card.uuid}> + <div className="card-control" onDoubleClick={(e) => e.stopPropagation()}> + <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ + <div className="mk-popover-control"> + <PlusOutlined className="plus" title="娣诲姞鍏冪礌" onClick={this.addElement} /> + <PlusSquareOutlined className="plus" title="娣诲姞鎸夐挳" onClick={this.addButton} /> + <NormalForm title={'寰幆瀛愬崱鐗囪缃�'} width={950} update={this.updateSetting} getForms={this.getSettingForms}> + <EditOutlined className="edit" title="缂栬緫"/> + </NormalForm> + <CopyComponent type="cardcell" card={card}/> + <PasteController options={['action', 'customCardElement']} updateConfig={this.paste} /> + <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} /> + </div> + } trigger="hover"> + <ToolOutlined /> + </Popover> + </div> + <CardCellComponent cards={cards} cardCell={card} side="" elements={card.backElements} updateElement={this.updateCard}/> + </div> + </Col> + ) + } +} + +export default DoubleCardBoxComponent \ No newline at end of file diff --git a/src/menu/components/card/doublecardcomponent/index.scss b/src/menu/components/card/doublecardcomponent/index.scss new file mode 100644 index 0000000..a32dfaa --- /dev/null +++ b/src/menu/components/card/doublecardcomponent/index.scss @@ -0,0 +1,64 @@ +.menus-detail-modal { + .ant-modal { + top: 70px; + } + .ant-modal-body { + min-height: 200px; + .menu-line { + display: flex; + div { + padding: 16px 16px; + border-top: 1px solid #e8e8e8; + border-left: 1px solid #e8e8e8; + word-break: break-all; + } + div:last-child { + border-right: 1px solid #e8e8e8; + } + .sort { + width: 10%; + text-align: center; + } + .sign { + width: 35%; + } + .name { + width: 35%; + } + .action { + width: 20%; + text-align: center; + span { + display: inline-block; + padding: 0 10px; + cursor: pointer; + color: #1890ff; + } + } + } + .menu-line:first-child { + background-color: #fafafa; + } + .menu-line:last-child { + div { + border-bottom: 1px solid #e8e8e8; + } + } + } +} + +.card-control { + position: absolute; + top: 0px; + left: 0px; + .anticon-tool { + position: absolute; + left: 1px; + top: 1px; + padding: 1px; + z-index: 2; + font-size: 16px; + cursor: pointer; + background: rgba(255, 255, 255, 0.55); + } +} diff --git a/src/menu/components/card/doublecardcomponent/options.jsx b/src/menu/components/card/doublecardcomponent/options.jsx new file mode 100644 index 0000000..be415f4 --- /dev/null +++ b/src/menu/components/card/doublecardcomponent/options.jsx @@ -0,0 +1,142 @@ +/** + * @description Setting琛ㄥ崟閰嶇疆淇℃伅 + */ +export default function (setting, subtype, buttons = [], cardType, columns) { + let appType = sessionStorage.getItem('appType') + let menulist = [] + + if (appType) { + menulist = sessionStorage.getItem('appMenus') + if (menulist) { + try { + menulist = JSON.parse(menulist) + } catch (e) { + menulist = [] + } + } else { + menulist = [] + } + } else { + menulist = sessionStorage.getItem('fstMenuList') + if (menulist) { + try { + menulist = JSON.parse(menulist) + } catch (e) { + menulist = [] + } + } else { + menulist = [] + } + } + + const cardSettingForm = [ + { + type: 'number', + field: 'width', + label: '鍗$墖瀹藉害', + initval: setting.width || 24, + tooltip: '鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��', + min: 1, + max: 24, + precision: 0, + required: true + }, + { + type: 'radio', + field: 'click', + label: '鐐瑰嚮浜嬩欢', + initval: setting.click || '', + required: false, + options: [ + {value: '', label: '鏃�'}, + {value: 'menu', label: '鑿滃崟'}, + {value: 'link', label: '閾炬帴'}, + {value: 'button', label: '鎸夐挳'} + ], + controlFields: [ + {field: 'menu', values: ['menu']}, + {field: 'linkurl', values: ['link']}, + {field: 'open', values: ['menu', 'link']}, + {field: 'joint', values: ['menu', 'link']}, + {field: 'linkbtn', values: ['button']}, + {field: 'clickType', values: ['button']}, + ] + }, + { + type: appType ? 'select' : 'cascader', + field: 'menu', + label: '鍏宠仈鑿滃崟', + initval: setting.menu || (appType ? '' : []), + required: true, + extendName: 'MenuNo', + options: menulist, + }, + { + type: 'textarea', + field: 'linkurl', + label: '閾炬帴', + initval: setting.linkurl || '', + required: true, + options: [], + span: 24 + }, + { + type: 'radio', + field: 'open', + label: '鎵撳紑鏂瑰紡', + initval: setting.open || 'blank', + required: false, + options: [ + {value: 'blank', label: appType !== 'mob' ? '鏂扮獥鍙�' : '鏂伴〉闈�'}, + {value: 'self', label: appType !== 'mob' ? '褰撳墠绐楀彛' : '褰撳墠椤甸潰'}, + ], + forbid: appType !== 'pc' && appType !== 'mob' + }, + { + type: 'radio', + field: 'joint', + label: '鍙傛暟鎷兼帴', + initval: setting.joint || 'true', + required: false, + options: [ + {value: 'true', label: '鏄�'}, + {value: 'false', label: '鍚�'}, + ], + }, + { + type: 'select', + field: 'linkbtn', + label: '鍏宠仈鎸夐挳', + initval: setting.linkbtn || '', + required: true, + options: buttons + }, + { + type: 'radio', + field: 'clickType', + label: '瑙﹀彂鏂瑰紡', + initval: setting.clickType || 'normal', + required: false, + options: [ + {value: 'normal', label: '鍗曞嚮'}, + {value: 'multi', label: '鍙屽嚮'}, + ], + forbid: appType === 'mob' + }, + { + type: 'radio', + field: 'btnControl', + label: '鎸夐挳鎺у埗', + initval: setting.btnControl || 'show', + tooltip: '鍙缃寜閽樉绀鸿鍒欙紝涓�鐩存樉绀烘垨榧犳爣鎮诞鏃舵樉绀恒��', + required: false, + options: [ + {value: 'show', label: '姝e父鏄剧ず'}, + {value: 'hover', label: '鎮诞鏄剧ず'}, + ], + forbid: appType === 'mob' + } + ] + + return cardSettingForm +} \ No newline at end of file diff --git a/src/menu/datasource/index.jsx b/src/menu/datasource/index.jsx index 52a1544..c40ff35 100644 --- a/src/menu/datasource/index.jsx +++ b/src/menu/datasource/index.jsx @@ -198,6 +198,10 @@ res.setting.maxScript = maxScript + if (config.subtype !== 'dualdatacard') { + delete res.subColumns + } + this.setState({loading: false, visible: false}) this.props.updateConfig({...config, ...res}) }, () => { diff --git a/src/menu/datasource/verifycard/index.jsx b/src/menu/datasource/verifycard/index.jsx index 4962810..0bf8108 100644 --- a/src/menu/datasource/verifycard/index.jsx +++ b/src/menu/datasource/verifycard/index.jsx @@ -32,6 +32,7 @@ state = { columns: [], + subColumns: [], activeKey: 'setting', loading: false, initsql: '', // sql楠岃瘉鏃跺彉閲忓0鏄庡強璧嬪�� @@ -197,6 +198,7 @@ this.setState({ scripts, columns: config.columns ? fromJS(config.columns).toJS() : [], + subColumns: config.subColumns ? fromJS(config.subColumns).toJS() : [], setting: _setting, median: _setting, searches: search, @@ -272,6 +274,26 @@ values.uuid = Utils.getuuid() this.setState({ columns: [...columns, values] }) + } + + subColumnChange = (values, resolve) => { + const { subColumns } = this.state + + let fields = subColumns.map(item => item.field.toLowerCase()) + if (fields.includes(values.field.toLowerCase())) { + notification.warning({ + top: 92, + message: '瀛楁宸插瓨鍦紒', + duration: 5 + }) + return + } + + resolve() + + values.uuid = Utils.getuuid() + + this.setState({ subColumns: [...subColumns, values] }) } deleteScript = (record) => { @@ -422,6 +444,23 @@ loading: false }) this.getdefaultSql() + } else if (activeKey === 'subcolumns') { + if (this.subdatasource && this.subdatasource.state.editingKey) { + notification.warning({ + top: 92, + message: '瀛楁鏈繚瀛橈紝璇蜂繚瀛樺悗鍒囨崲锛�', + duration: 5 + }) + this.setState({ + loading: false + }) + return + } + + this.setState({ + activeKey: val, + loading: false + }) } else if (activeKey === 'scripts') { let _loading = false if (this.scriptsForm && this.scriptsForm.state.editItem) { @@ -514,7 +553,7 @@ submitDataSource = () => { const { config, mainSearch } = this.props - const { activeKey, setting, columns, scripts } = this.state + const { activeKey, setting, columns, subColumns, scripts } = this.state return new Promise((resolve, reject) => { if (activeKey === 'setting') { @@ -536,7 +575,7 @@ defaultSearch: _search, setting: res }, () => { - this.sqlverify(() => { resolve({setting: res, columns, scripts }) }, reject, false) + this.sqlverify(() => { resolve({setting: res, columns, subColumns, scripts }) }, reject, false) }) }, () => { reject() @@ -551,7 +590,18 @@ reject() return } - this.sqlverify(() => { resolve({setting, columns, scripts }) }, reject, false) + this.sqlverify(() => { resolve({setting, columns, subColumns, scripts }) }, reject, false) + } else if (activeKey === 'subcolumns') { + if (this.subdatasource && this.subdatasource.state.editingKey) { + notification.warning({ + top: 92, + message: '瀛楁鏈繚瀛橈紝璇蜂繚瀛樺悗鎻愪氦锛�', + duration: 5 + }) + reject() + return + } + this.sqlverify(() => { resolve({setting, columns, subColumns, scripts }) }, reject, false) } else if (activeKey === 'scripts') { let _loading = false if (this.scriptsForm && this.scriptsForm.state.editItem) { @@ -570,7 +620,7 @@ return } - this.sqlverify(() => { resolve({setting, columns, scripts }) }, reject, false) + this.sqlverify(() => { resolve({setting, columns, subColumns, scripts }) }, reject, false) } }) } @@ -701,6 +751,12 @@ }) } + updateSubfields = (columns) => { + this.setState({ + subColumns: columns + }) + } + copyDatasource = () => { const { config } = this.props const { columns, scripts } = this.state @@ -823,6 +879,27 @@ message.success('澶嶅埗鎴愬姛銆�') } + copySubColumns = () => { + const { subColumns } = this.state + let m = [] + let n = [] + + subColumns.forEach(col => { + m.push(`${col.field}(${col.label})`) + n.push(col.field) + }) + + let oInput = document.createElement('input') + oInput.value = `/*${m.join(',')}*/ + ${n.join(',')}` + document.body.appendChild(oInput) + oInput.select() + document.execCommand('Copy') + document.body.removeChild(oInput) + + message.success('澶嶅埗鎴愬姛銆�') + } + /** * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊 */ @@ -834,7 +911,7 @@ render() { const { config } = this.props - const { columns, median, setting, scripts, colColumns, scriptsColumns, activeKey, loading, searches, defaultsql, visible, pvisible, reload, script, scriptValue } = this.state + const { columns, subColumns, median, setting, scripts, colColumns, scriptsColumns, activeKey, loading, searches, defaultsql, visible, pvisible, reload, script, scriptValue } = this.state return ( <div className="model-data-source-wrap"> @@ -844,8 +921,6 @@ <TabPane tab={ <span> 鏁版嵁婧� - {config.type !== 'interface' ? <CopyOutlined title="澶嶅埗鏁版嵁婧�" className="mk-copy-datasource" onClick={this.copyDatasource}/> : null} - {config.type !== 'interface' ? <SnippetsOutlined title="瀵煎叆鏁版嵁婧�" className="mk-paste-datasource" onClick={() => this.setState({pvisible: true})}/> : null} </span> } key="setting"> {!reload ? <SettingForm @@ -861,21 +936,38 @@ <span> 瀛楁闆� {columns.length ? <span className="count-tip">{columns.length}</span> : null} - <CopyOutlined title="浠ラ�楀彿鎷兼帴褰㈠紡澶嶅埗瀛楁" className="mk-copy-fields" onClick={this.copyColumns}/> </span> } key="columns"> <ColForm columnChange={this.columnChange}/> <FieldsComponent - config={{...config, columns}} + config={{columns}} type="fields" updatefield={this.updatefields} /> <EditTable actions={['edit', 'move', 'copy', 'del', 'clear']} type="datasourcefield" wrappedComponentRef={(inst) => this.datasource = inst} data={columns} columns={colColumns} onChange={(columns) => this.setState({columns})}/> </TabPane> : null} + {config.subtype === 'dualdatacard' ? <TabPane tab={ + <span> + 瀛愯〃瀛楁闆� + {subColumns.length ? <span className="count-tip">{subColumns.length}</span> : null} + </span> + } key="subcolumns"> + <ColForm columnChange={this.subColumnChange}/> + <FieldsComponent + config={{columns: subColumns}} + type="fields" + updatefield={this.updateSubfields} + /> + <EditTable actions={['edit', 'move', 'copy', 'del', 'clear']} type="datasourcefield" wrappedComponentRef={(inst) => this.subdatasource = inst} data={subColumns} columns={colColumns} onChange={(subColumns) => this.setState({subColumns})}/> + </TabPane> : null} <TabPane tab={ <span> 鑷畾涔夎剼鏈� {scripts.length ? <span className="count-tip">{scripts.length}</span> : null} + {config.type !== 'interface' && activeKey === 'setting' ? <CopyOutlined title="澶嶅埗鏁版嵁婧�" className="mk-copy-datasource" onClick={(e) => {e.stopPropagation();this.copyDatasource()}}/> : null} + {config.type !== 'interface' && activeKey === 'setting' ? <SnippetsOutlined title="瀵煎叆鏁版嵁婧�" className="mk-paste-datasource" onClick={(e) => {e.stopPropagation();this.setState({pvisible: true})}}/> : null} + {activeKey === 'columns' ? <CopyOutlined title="浠ラ�楀彿鎷兼帴褰㈠紡澶嶅埗瀛楁" className="mk-copy-fields" onClick={(e) => {e.stopPropagation();this.copyColumns()}}/> : null} + {activeKey === 'subcolumns' ? <CopyOutlined title="浠ラ�楀彿鎷兼帴褰㈠紡澶嶅埗瀛楁" className="mk-copy-fields" onClick={(e) => {e.stopPropagation();this.copySubColumns()}}/> : null} </span> } key="scripts" disabled={median.interType !== 'system'} id="mk-scripts-tabpane"> {scripts.length ? <BorderOutlined className="full-scripts" onClick={() => { diff --git a/src/menu/datasource/verifycard/index.scss b/src/menu/datasource/verifycard/index.scss index 7fcbe7e..b9bc0fe 100644 --- a/src/menu/datasource/verifycard/index.scss +++ b/src/menu/datasource/verifycard/index.scss @@ -14,9 +14,9 @@ cursor: pointer; z-index: 1; top: 19px; - right: -210px; + right: -50px; color: rgb(24, 144, 255); - display: none; + display: inline-block; opacity: 0.4; transition: opacity 0.2s; } @@ -25,9 +25,9 @@ cursor: pointer; z-index: 1; top: 19px; - right: -319px; + right: -50px; color: rgb(24, 144, 255); - display: none; + display: inline-block; opacity: 0.4; transition: opacity 0.2s; } @@ -36,19 +36,14 @@ cursor: pointer; z-index: 1; top: 19px; - right: -355px; + right: -90px; color:purple; - display: none; + display: inline-block; opacity: 0.4; transition: opacity 0.2s; } .mk-copy-fields:hover, .mk-copy-datasource:hover, .mk-paste-datasource:hover { opacity: 1; - } - .ant-tabs-tab-active { - .mk-copy-fields, .mk-copy-datasource, .mk-paste-datasource { - display: inline-block; - } } .count-tip { position: absolute; diff --git a/src/menu/datasource/verifycard/settingform/index.jsx b/src/menu/datasource/verifycard/settingform/index.jsx index ad9a2bd..d9be1cc 100644 --- a/src/menu/datasource/verifycard/settingform/index.jsx +++ b/src/menu/datasource/verifycard/settingform/index.jsx @@ -460,7 +460,7 @@ </Form.Item> </Col> : null} {/* 1銆佷笉鍒嗛〉涓斾笉瀛樺湪涓婄骇妯″潡 */} - {!['navbar', 'interface'].includes(config.type) && !['editable', 'basetable'].includes(config.subtype) && (!config.pageable || (config.pageable && setting.laypage === 'false')) && (setting.supModule.length === 0 || setting.supModule[0] === 'empty') && setting.interType === 'system' ? <Col span={8}> + {!['navbar', 'interface'].includes(config.type) && !['editable', 'basetable', 'dualdatacard'].includes(config.subtype) && (!config.pageable || (config.pageable && setting.laypage === 'false')) && (setting.supModule.length === 0 || setting.supModule[0] === 'empty') && setting.interType === 'system' ? <Col span={8}> <Form.Item label={ <Tooltip placement="topLeft" title={'鍒濆鍖栧姞杞芥椂锛屾槸鍚︿笌鍏朵粬缁勪欢涓�鍚屽姞杞芥暟鎹紝娉細浠呭湪浣跨敤绯荤粺鍑芥暟锛屼笖鍒濆鍖栧姞杞芥暟鎹椂鏈夋晥锛屽垎椤佃姹傛椂鏃犳晥銆�'}> <QuestionCircleOutlined className="mk-form-tip" /> diff --git a/src/menu/menushell/card.jsx b/src/menu/menushell/card.jsx index 5d9b196..467795d 100644 --- a/src/menu/menushell/card.jsx +++ b/src/menu/menushell/card.jsx @@ -11,6 +11,7 @@ const AntvScatter = asyncComponent(() => import('@/menu/components/chart/antv-scatter')) const AntvTabs = asyncComponent(() => import('@/menu/components/tabs/antv-tabs')) const DataCard = asyncComponent(() => import('@/menu/components/card/data-card')) +const DoubleDataCard = asyncComponent(() => import('@/menu/components/card/double-data-card')) const PropCard = asyncComponent(() => import('@/menu/components/card/prop-card')) const Balcony = asyncComponent(() => import('@/menu/components/card/balcony')) const NormalTree = asyncComponent(() => import('@/menu/components/tree/antd-tree')) @@ -78,6 +79,8 @@ return (<AntvBar card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) } else if (card.type === 'search') { return (<MainSearch card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) + } else if (card.type === 'card' && card.subtype === 'dualdatacard') { + return (<DoubleDataCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) } else if (card.type === 'pie') { return (<AntvPie card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) } else if (card.type === 'dashboard') { diff --git a/src/menu/modulesource/option.jsx b/src/menu/modulesource/option.jsx index 8273421..92437f0 100644 --- a/src/menu/modulesource/option.jsx +++ b/src/menu/modulesource/option.jsx @@ -40,6 +40,7 @@ { type: 'menu', url: card1, component: 'card', subtype: 'datacard', title: '鏁版嵁鍗�', width: 24 }, { type: 'menu', url: card2, component: 'card', subtype: 'propcard', title: '灞炴�у崱', width: 24 }, { type: 'menu', url: card2, component: 'balcony', subtype: 'balcony', title: '娴姩鍗�', width: 24}, + // { type: 'menu', url: card1, component: 'card', subtype: 'dualdatacard', title: '鍙岄噸鏁版嵁鍗�', width: 24 }, { type: 'menu', url: simpleform, component: 'form', subtype: 'simpleform', title: '琛ㄥ崟', width: 24, forbid: ['billPrint'] }, { type: 'menu', url: form, component: 'form', subtype: 'stepform', title: '琛ㄥ崟锛堝垎姝ワ級', width: 24, forbid: ['billPrint'] }, { type: 'menu', url: tabForm, component: 'form', subtype: 'tabform', title: '琛ㄥ崟锛坱ab椤碉級', width: 24, forbid: ['billPrint'] }, diff --git a/src/tabviews/custom/components/module/voucher/index.jsx b/src/tabviews/custom/components/module/voucher/index.jsx index a670376..aae840b 100644 --- a/src/tabviews/custom/components/module/voucher/index.jsx +++ b/src/tabviews/custom/components/module/voucher/index.jsx @@ -82,8 +82,8 @@ } } - config.wrap.type = 'checkVoucher' - BID = '20230214130744811P0K95RQ155KG0QIQOFV' + // config.wrap.type = 'checkVoucher' + // BID = '20230214130744811P0K95RQ155KG0QIQOFV' // config.wrap.type = 'checkTemp' // BID = '20230214174458780MFR8IA576ON4VKNOLVH' diff --git a/src/tabviews/zshare/actionList/normalbutton/index.jsx b/src/tabviews/zshare/actionList/normalbutton/index.jsx index 3a5c539..55028c5 100644 --- a/src/tabviews/zshare/actionList/normalbutton/index.jsx +++ b/src/tabviews/zshare/actionList/normalbutton/index.jsx @@ -2424,6 +2424,12 @@ this.setState({ visible: true }) + + if (btnconfig.setting.display === 'modal' && btnconfig.setting.moveable === 'true') { + setTimeout(() => { + this.setMove() + }, 100) + } } } else { Api.getCacheConfig({ @@ -2677,15 +2683,17 @@ width = btnconfig.setting.width > 100 ? btnconfig.setting.width : btnconfig.setting.width + '%' container = () => document.getElementById(btn.ContainerId) } + return ( <Modal title={title} maskClosable={clickouter} getContainer={container} - wrapClassName='action-modal' + wrapClassName={'action-modal' + (btnconfig.setting.moveable === 'true' ? ' moveable-modal modal-' + btn.uuid : '')} visible={visible} width={width} onOk={this.handleOk} + maskStyle={btnconfig.setting.moveable === 'true' ? {backgroundColor: 'rgba(0, 0, 0, 0.15)'} : null} confirmLoading={this.state.confirmLoading} onCancel={this.handleCancel} destroyOnClose @@ -2704,6 +2712,43 @@ } } + setMove = () => { + const { btn } = this.props + let wrap = document.getElementsByClassName('modal-' + btn.uuid)[0] + + if (!wrap) return + + let node = wrap.getElementsByClassName('ant-modal-header')[0] + + if (!node) return + + node.onmousedown = function(e) { + let orileft = 0 + let oritop = 0 + let oleft = e.clientX + let otop = e.clientY + + if (node.parentNode.style.left) { + orileft = parseFloat(node.parentNode.style.left) + } + if (node.parentNode.style.top) { + oritop = parseFloat(node.parentNode.style.top) + } + + document.onmousemove = function(e) { + let left = e.clientX - oleft + let top = e.clientY - otop + + node.parentNode.style.left = (orileft + left) + 'px' + node.parentNode.style.top = (oritop + top) + 'px' + } + } + + document.onmouseup = function() { + document.onmousemove = null + } + } + render() { const { btn } = this.props const { loadingNumber, loadingTotal, loading, disabled, hidden, check } = this.state diff --git a/src/tabviews/zshare/actionList/printbutton/index.jsx b/src/tabviews/zshare/actionList/printbutton/index.jsx index 9fa8f51..e98c0f6 100644 --- a/src/tabviews/zshare/actionList/printbutton/index.jsx +++ b/src/tabviews/zshare/actionList/printbutton/index.jsx @@ -2013,6 +2013,12 @@ this.setState({ visible: true }) + + if (btnconfig.setting.display === 'modal' && btnconfig.setting.moveable === 'true') { + setTimeout(() => { + this.setMove() + }, 100) + } } } else { Api.getCacheConfig({ @@ -2208,10 +2214,11 @@ title={title} maskClosable={clickouter} getContainer={container} - wrapClassName='action-modal' + wrapClassName={'action-modal' + (btnconfig.setting.moveable === 'true' ? ' moveable-modal modal-' + btn.uuid : '')} visible={this.state.visible} confirmLoading={this.state.confirmLoading} width={width} + maskStyle={btnconfig.setting.moveable === 'true' ? {backgroundColor: 'rgba(0, 0, 0, 0.15)'} : null} onOk={this.handleOk} onCancel={this.handleCancel} destroyOnClose @@ -2229,6 +2236,43 @@ ) } + setMove = () => { + const { btn } = this.props + let wrap = document.getElementsByClassName('modal-' + btn.uuid)[0] + + if (!wrap) return + + let node = wrap.getElementsByClassName('ant-modal-header')[0] + + if (!node) return + + node.onmousedown = function(e) { + let orileft = 0 + let oritop = 0 + let oleft = e.clientX + let otop = e.clientY + + if (node.parentNode.style.left) { + orileft = parseFloat(node.parentNode.style.left) + } + if (node.parentNode.style.top) { + oritop = parseFloat(node.parentNode.style.top) + } + + document.onmousemove = function(e) { + let left = e.clientX - oleft + let top = e.clientY - otop + + node.parentNode.style.left = (orileft + left) + 'px' + node.parentNode.style.top = (oritop + top) + 'px' + } + } + + document.onmouseup = function() { + document.onmousemove = null + } + } + render() { const { btn } = this.props const { loading, disabled, hidden } = this.state diff --git a/src/templates/modalconfig/settingform/index.jsx b/src/templates/modalconfig/settingform/index.jsx index e3b7b22..ab2adf7 100644 --- a/src/templates/modalconfig/settingform/index.jsx +++ b/src/templates/modalconfig/settingform/index.jsx @@ -111,7 +111,12 @@ </Form.Item> </Col> */} <Col span={24}> - <Form.Item label="鏄剧ず鏂瑰紡"> + <Form.Item label={ + <Tooltip placement="topLeft" title="鍙�夋嫨琛ㄥ崟鐨勬樉绀哄舰寮忥紝娉細鏍囩鎵撳嵃鎸夐挳锛屾殏涓嶆敮鎸佷互鎶藉眽鏄剧ず琛ㄥ崟銆�"> + <QuestionCircleOutlined className="mk-form-tip" /> + 鏄剧ず鏂瑰紡 + </Tooltip> + }> {getFieldDecorator('display', { initialValue: display || 'modal' })( @@ -335,6 +340,23 @@ )} </Form.Item> </Col> : null} + {!appType && display === 'modal' ? <Col span={12}> + <Form.Item label={ + <Tooltip placement="topLeft" title="鏄惁鍙嫋鎷界Щ鍔ㄦā鎬佹銆�"> + <QuestionCircleOutlined className="mk-form-tip" /> + 鍙Щ鍔� + </Tooltip> + }> + {getFieldDecorator('moveable', { + initialValue: config.setting.moveable || 'false' + })( + <Radio.Group> + <Radio value="false">鍚�</Radio> + <Radio value="true">鏄�</Radio> + </Radio.Group> + )} + </Form.Item> + </Col> : null} </Row> </Form> ) -- Gitblit v1.8.0