| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | // import { fromJS } from 'immutable' |
| | | import { Form, Row, Col, Tooltip, Icon, Cascader } from 'antd' |
| | | import { fromJS } from 'immutable' |
| | | import { Form, Row, Col, Tooltip, Icon, Cascader, Input } from 'antd' |
| | | |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import MKEInput from './mkInput' |
| | | import MKNumberInput from './mkNumberInput' |
| | | import MKSelect from './mkSelect' |
| | | import './index.scss' |
| | | |
| | | const { TextArea } = Input |
| | | |
| | | const MKRadio = asyncComponent(() => import('./mkRadio')) |
| | | const StyleInput = asyncComponent(() => import('./styleInput')) |
| | |
| | | } |
| | | |
| | | item.hidden = false |
| | | |
| | | if (item.forbid) { |
| | | item.hidden = true |
| | | } |
| | | if (item.options) { |
| | | item.oriOptions = fromJS(item.options).toJS() |
| | | } |
| | | |
| | | if (item.type === 'text') { |
| | | let _rules = [{ |
| | |
| | | }) |
| | | |
| | | formlist = formlist.map(cell => { |
| | | return fieldMap.get(cell.field) || cell |
| | | let item = fieldMap.get(cell.field) |
| | | |
| | | if (item.linkField) { |
| | | let supInitVal = fieldMap.get(item.linkField).initval || '' |
| | | |
| | | item.options = item.oriOptions.filter(option => option.ParentID === supInitVal) |
| | | } |
| | | |
| | | return item |
| | | }) |
| | | |
| | | this.record = record |
| | |
| | | const fields = [] |
| | | |
| | | formlist.forEach((item, index) => { |
| | | if (item.hidden) return |
| | | if (item.hidden || item.forbid) return |
| | | |
| | | let content = null |
| | | let label = item.tooltip ? <Tooltip placement="topLeft" title={item.tooltip}><Icon type="question-circle" />{item.label}</Tooltip> : item.label |
| | |
| | | content = (<MKFileUpload config={item} onChange={(val) => this.recordChange({[item.field]: val})} />) |
| | | } else if (item.type === 'cascader') { |
| | | content = (<Cascader options={item.options} expandTrigger="hover" placeholder="" />) |
| | | } else if (item.type === 'textarea') { |
| | | content = (<TextArea rows={item.rows || 2} placeholder=""/>) |
| | | } |
| | | |
| | | if (!content) return |
| | |
| | | .ant-form-item { |
| | | display: flex; |
| | | } |
| | | .ant-form-item.checkcard { |
| | | margin-bottom: 10px; |
| | | .ant-form-item-control { |
| | | line-height: 1.5; |
| | | } |
| | | } |
| | | .ant-form-item.hint { |
| | | margin-bottom: 0px; |
| | | .message { |
| | | margin-top: 9px; |
| | | line-height: 1.5; |
| | | color: rgba(0, 0, 0, 0.85); |
| | | } |
| | | } |
| | | |
| | | .ant-form-item-control-wrapper { |
| | | flex: 1; |
| | | } |
| | |
| | | white-space: nowrap; |
| | | width: 33.3%; |
| | | } |
| | | >.ant-row.cols2 .ant-col-24 { |
| | | .ant-form-item { |
| | | .ant-form-item-label { |
| | | width: 16%; |
| | | } |
| | | } |
| | | } |
| | | >.ant-row.cols3 .ant-col-24 { |
| | | .ant-form-item { |
| | | .ant-form-item-label { |
| | | width: 10.5%; |
| | | } |
| | | } |
| | | } |
| | | >.ant-row.cols4 .ant-col-24 { |
| | | .ant-form-item { |
| | | .ant-form-item-label { |
| | | width: 7.5%; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .ant-input-number { |
| | | width: 100%; |
| | | } |
| | |
| | | min-width: 100px; |
| | | } |
| | | } |
| | | .normal-braft-editor { |
| | | border: 1px solid #d9d9d9; |
| | | border-radius: 4px; |
| | | overflow-x: hidden; |
| | | } |
| | | p { |
| | | color: #1890ff; |
| | | font-size: 15px; |
| | | padding-left: 10px; |
| | | border-bottom: 1px solid #e9e9e9; |
| | | } |
| | | .ant-input-disabled { |
| | | color: rgba(0, 0, 0, 0.65)!important; |
| | | cursor: default!important; |
| | | } |
| | | |
| | | .ant-input-number-input { |
| | | color: rgba(0, 0, 0, 0.65)!important; |
| | | cursor: default!important; |
| | | } |
| | | .ant-select-disabled { |
| | | color: rgba(0, 0, 0, 0.65)!important; |
| | | .ant-select-selection--multiple .ant-select-selection__choice { |
| | | color: rgba(0, 0, 0, 0.65)!important; |
| | | .ant-col-12 + .ant-col-24 { |
| | | .ant-form-item-label { |
| | | width: 16%; |
| | | } |
| | | } |
| | | } |
| | |
| | | const { value, options } = this.state |
| | | |
| | | return ( |
| | | <Radio.Group value={value} onChange={this.onChange}> |
| | | <Radio.Group style={{whiteSpace: 'nowrap'}} value={value} onChange={this.onChange}> |
| | | {options.map(option => <Radio key={option.value} value={option.value}>{option.label}</Radio>)} |
| | | </Radio.Group> |
| | | ) |
| | |
| | | import { resetStyle } from '@/utils/utils-custom.js' |
| | | import MKEmitter from '@/utils/events.js' |
| | | import Utils from '@/utils/utils.js' |
| | | import MenuUtils from '@/utils/utils-custom.js' |
| | | import { balconyWrapForm } from './options' |
| | | import getWrapForm from './options' |
| | | import zhCN from '@/locales/zh-CN/model.js' |
| | | import enUS from '@/locales/en-US/model.js' |
| | | import './index.scss' |
| | |
| | | getWrapForms = () => { |
| | | const { wrap } = this.state.card |
| | | |
| | | let modules = MenuUtils.getLinkModules(fromJS(window.GLOB.customMenu).toJS().components) || [] |
| | | let supmodules = MenuUtils.getSupModules(fromJS(window.GLOB.customMenu).toJS().components, '') || [] |
| | | let roleList = sessionStorage.getItem('sysRoles') |
| | | |
| | | if (roleList) { |
| | | try { |
| | | roleList = JSON.parse(roleList) |
| | | } catch { |
| | | roleList = [] |
| | | } |
| | | } else { |
| | | roleList = [] |
| | | } |
| | | |
| | | return fromJS(balconyWrapForm).toJS().map(item => { |
| | | item.initval = wrap[item.field] || item.initval |
| | | |
| | | if (item.field === 'blacklist') { |
| | | item.options = roleList |
| | | } else if (item.field === 'syncModule') { |
| | | item.options = modules |
| | | } else if (item.field === 'supModule') { |
| | | item.options = supmodules |
| | | } |
| | | |
| | | return item |
| | | }) |
| | | return getWrapForm(wrap) |
| | | } |
| | | |
| | | updateWrap = (res) => { |
| | |
| | | import { fromJS } from 'immutable' |
| | | import MenuUtils from '@/utils/utils-custom.js' |
| | | |
| | | /** |
| | | * @description Wrap表单配置信息 |
| | | */ |
| | | export const balconyWrapForm = [ |
| | | export default function (wrap) { |
| | | let modules = MenuUtils.getLinkModules(fromJS(window.GLOB.customMenu).toJS().components) || [] |
| | | let supmodules = MenuUtils.getSupModules(fromJS(window.GLOB.customMenu).toJS().components, '') || [] |
| | | let roleList = sessionStorage.getItem('sysRoles') |
| | | |
| | | if (roleList) { |
| | | try { |
| | | roleList = JSON.parse(roleList) |
| | | } catch { |
| | | roleList = [] |
| | | } |
| | | } else { |
| | | roleList = [] |
| | | } |
| | | |
| | | const balconyWrapForm = [ |
| | | { |
| | | type: 'text', |
| | | field: 'name', |
| | | label: '组件名称', |
| | | initval: '', |
| | | initval: wrap.name || '', |
| | | tooltip: '用于组件间的区分。', |
| | | required: true |
| | | }, |
| | |
| | | type: 'number', |
| | | field: 'width', |
| | | label: '宽度', |
| | | initval: '', |
| | | initval: wrap.width || 24, |
| | | tooltip: '栅格布局,每行等分为24列。', |
| | | min: 1, |
| | | max: 24, |
| | |
| | | type: 'radio', |
| | | field: 'datatype', |
| | | label: '数据来源', |
| | | initval: '', |
| | | initval: wrap.datatype || 'static', |
| | | tooltip: '选择静态值,无需配置数据源。', |
| | | required: false, |
| | | options: [ |
| | |
| | | type: 'radio', |
| | | field: 'linkType', |
| | | label: '受控类型', |
| | | initval: 'static', |
| | | initval: wrap.linkType || 'static', |
| | | tooltip: '组件与其他组件之间的控制类型,独立表示与其他没有关联。', |
| | | required: false, |
| | | options: [ |
| | |
| | | type: 'cascader', |
| | | field: 'supModule', |
| | | label: '上级组件', |
| | | initval: '', |
| | | initval: wrap.supModule || '', |
| | | required: true, |
| | | options: [] |
| | | options: supmodules |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | field: 'supControl', |
| | | label: '显示控制', |
| | | tooltip: '当前组件在主表选中行时显示,还是始终显示。', |
| | | initval: 'show', |
| | | initval: wrap.supControl || 'show', |
| | | required: false, |
| | | options: [ |
| | | {value: 'hidden', label: '选行'}, |
| | |
| | | type: 'cascader', |
| | | field: 'syncModule', |
| | | label: '同步组件', |
| | | initval: '', |
| | | initval: wrap.syncModule || '', |
| | | required: true, |
| | | options: [] |
| | | options: modules |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | field: 'checkAll', |
| | | label: '全选', |
| | | initval: 'hidden', |
| | | initval: wrap.checkAll || 'hidden', |
| | | tooltip: '当同步组件可多选时,设置全选有效。', |
| | | required: false, |
| | | options: [ |
| | |
| | | type: 'radio', |
| | | field: 'position', |
| | | label: '位置', |
| | | initval: 'relative', |
| | | initval: wrap.position || 'relative', |
| | | tooltip: '使用固定定位时,请在测试环境中查看定位效果。', |
| | | required: false, |
| | | options: [ |
| | |
| | | type: 'styleInput', |
| | | field: 'top', |
| | | label: '距上', |
| | | initval: '', |
| | | initval: wrap.top || '', |
| | | required: false |
| | | }, |
| | | { |
| | | type: 'styleInput', |
| | | field: 'right', |
| | | label: '距右', |
| | | initval: '', |
| | | initval: wrap.right || '', |
| | | required: false |
| | | }, |
| | | { |
| | | type: 'styleInput', |
| | | field: 'bottom', |
| | | label: '距下', |
| | | initval: '', |
| | | initval: wrap.bottom || '', |
| | | required: false |
| | | }, |
| | | { |
| | | type: 'styleInput', |
| | | field: 'left', |
| | | label: '距左', |
| | | initval: '', |
| | | initval: wrap.left || '', |
| | | required: false |
| | | }, |
| | | { |
| | | type: 'styleInput', |
| | | field: 'realwidth', |
| | | label: '实际宽度', |
| | | initval: '', |
| | | initval: wrap.realwidth || '', |
| | | required: false |
| | | }, |
| | | { |
| | | type: 'select', |
| | | field: 'transform', |
| | | label: '变换', |
| | | initval: '', |
| | | initval: wrap.transform || '', |
| | | required: false, |
| | | options: [ |
| | | {value: 'translateY(-50%)', label: '上移50%'}, |
| | |
| | | type: 'multiselect', |
| | | field: 'blacklist', |
| | | label: '黑名单', |
| | | initval: '', |
| | | initval: wrap.blacklist || '', |
| | | required: false, |
| | | options: [] |
| | | options: roleList |
| | | }, |
| | | ] |
| | | |
| | | return balconyWrapForm |
| | | } |
| | |
| | | if (appMenus) { |
| | | try { |
| | | appMenus = JSON.parse(appMenus) |
| | | appMenus = appMenus.map(item => ({value: item.MenuID, text: item.MenuName})) |
| | | } catch { |
| | | appMenus = [] |
| | | } |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Modal, Popover, Icon, Switch, Col } from 'antd' |
| | | import { Popover, Icon, Switch, Col } from 'antd' |
| | | |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import asyncIconComponent from '@/utils/asyncIconComponent' |
| | | import zhCN from '@/locales/zh-CN/model.js' |
| | | import enUS from '@/locales/en-US/model.js' |
| | | import SettingForm from './settingform' |
| | | 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('../cardcellcomponent')) |
| | | const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent')) |
| | | const PasteComponent = asyncIconComponent(() => import('./pastecomponent')) |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | card: null, // 卡片信息,包括正反面 |
| | | formlist: null, // 设置表单信息 |
| | | elements: null, // 编辑组 |
| | | visible: false, // 模态框控制 |
| | | settingVisible: false, |
| | | side: 'front' |
| | | } |
| | | |
| | |
| | | MKEmitter.emit('changeStyle', [cards.uuid, card.uuid], options, _style) |
| | | } |
| | | |
| | | settingSubmit = () => { |
| | | getSettingForms = () => { |
| | | const { cards } = this.props |
| | | const { setting } = this.state.card |
| | | |
| | | return getSettingForm(setting, cards.subtype === 'propcard') |
| | | } |
| | | |
| | | updateSetting = (res) => { |
| | | const { card, side } = this.state |
| | | |
| | | this.settingRef.handleConfirm().then(res => { |
| | | if (res.appmenu) { |
| | | res.menu = res.appmenu |
| | | delete res.appmenu |
| | | } |
| | | |
| | | this.setState({ |
| | | settingVisible: false, |
| | | card: {...card, setting: res} |
| | | }) |
| | | |
| | |
| | | } |
| | | |
| | | this.props.updateElement({...card, setting: res}) |
| | | }) |
| | | } |
| | | |
| | | clickComponent = (e) => { |
| | |
| | | |
| | | render() { |
| | | const { cards, offset } = this.props |
| | | const { card, elements, side, settingVisible, dict } = this.state |
| | | const { card, elements, side } = this.state |
| | | |
| | | let _style = {...card.style} |
| | | |
| | |
| | | <div className="mk-popover-control"> |
| | | <Icon className="plus" title="添加元素" onClick={this.addElement} type="plus" /> |
| | | <Icon className="plus" title="添加按钮" onClick={this.addButton} type="plus-square" /> |
| | | <Icon className="edit" title="编辑" type="edit" onClick={() => this.setState({settingVisible: true})} /> |
| | | <NormalForm title="卡片设置" width={800} update={this.updateSetting} getForms={this.getSettingForms}> |
| | | <Icon type="edit" className="edit" title="编辑"/> |
| | | </NormalForm> |
| | | <CopyComponent type="cardcell" card={card}/> |
| | | <PasteComponent elements={elements} options={['action', 'customCardElement']} updateConfig={(list) => this.updateCard(list, 'paste')} /> |
| | | <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" /> |
| | |
| | | </Popover> |
| | | </div> |
| | | </div> |
| | | <Modal |
| | | wrapClassName="popview-modal" |
| | | title={'卡片设置'} |
| | | visible={settingVisible} |
| | | width={800} |
| | | maskClosable={false} |
| | | okText={dict['model.submit']} |
| | | onOk={this.settingSubmit} |
| | | onCancel={() => { this.setState({ settingVisible: false }) }} |
| | | destroyOnClose |
| | | > |
| | | <SettingForm |
| | | dict={dict} |
| | | cards={cards} |
| | | setting={card.setting} |
| | | inputSubmit={this.settingSubmit} |
| | | wrappedComponentRef={(inst) => this.settingRef = inst} |
| | | /> |
| | | </Modal> |
| | | </Col> |
| | | ) |
| | | } |
New file |
| | |
| | | /** |
| | | * @description Setting表单配置信息 |
| | | */ |
| | | export default function (setting, hasPrimaryKey) { |
| | | let appType = sessionStorage.getItem('appType') |
| | | |
| | | let menulist = [] |
| | | let appmenulist = [] |
| | | |
| | | if (appType) { |
| | | appmenulist = sessionStorage.getItem('appMenus') |
| | | if (appmenulist) { |
| | | try { |
| | | appmenulist = JSON.parse(appmenulist) |
| | | } catch { |
| | | appmenulist = [] |
| | | } |
| | | } else { |
| | | appmenulist = [] |
| | | } |
| | | } else { |
| | | menulist = sessionStorage.getItem('fstMenuList') |
| | | if (menulist) { |
| | | try { |
| | | menulist = JSON.parse(menulist) |
| | | } catch { |
| | | 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: 'type', |
| | | label: '卡片类型', |
| | | initval: setting.type || 'simple', |
| | | tooltip: '选择复式卡时,可配置鼠标悬浮时的显示信息。', |
| | | required: false, |
| | | options: [ |
| | | {value: 'simple', label: '单卡'}, |
| | | {value: 'multi', label: '复式卡'}, |
| | | ], |
| | | controlFields: [ |
| | | {field: 'transform', values: ['multi']}, |
| | | ], |
| | | forbid: appType === 'mob' |
| | | }, |
| | | { |
| | | type: 'select', |
| | | field: 'transform', |
| | | label: '过渡效果', |
| | | initval: setting.transform || 'up', |
| | | tooltip: '复式卡片鼠标悬浮信息的动画效果。', |
| | | required: false, |
| | | options: [ |
| | | {value: 'up', label: '向上滑动'}, |
| | | {value: 'down', label: '向下滑动'}, |
| | | {value: 'left', label: '向左滑动'}, |
| | | {value: 'right', label: '向右滑动'}, |
| | | {value: 'scale', label: '缩放'}, |
| | | {value: 'opacity', label: '透明度'}, |
| | | {value: 'rotateX', label: '纵向展开'}, |
| | | {value: 'rotateY', label: '横向展开'}, |
| | | ] |
| | | }, |
| | | { |
| | | type: 'text', |
| | | field: 'primaryId', |
| | | label: '主键值', |
| | | initval: setting.primaryId || '', |
| | | tooltip: '卡片点击时,向其他组件传递的ID值。', |
| | | required: false, |
| | | forbid: !hasPrimaryKey |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | field: 'click', |
| | | label: '点击事件', |
| | | initval: setting.click || '', |
| | | tooltip: '当选择触发按钮时,只有当卡片中只存在一个按钮时有效。', |
| | | required: false, |
| | | options: [ |
| | | {value: '', label: '无'}, |
| | | {value: 'menu', label: '菜单'}, |
| | | {value: 'link', label: '链接'}, |
| | | {value: 'button', label: '按钮'}, |
| | | ], |
| | | controlFields: [ |
| | | {field: 'menu', values: ['menu']}, |
| | | {field: 'appmenu', values: ['menu']}, |
| | | {field: 'linkurl', values: ['link']}, |
| | | {field: 'open', values: ['menu', 'link']}, |
| | | {field: 'joint', values: ['menu', 'link']}, |
| | | ] |
| | | }, |
| | | { |
| | | type: 'cascader', |
| | | field: 'menu', |
| | | label: '菜单', |
| | | initval: setting.menu || [], |
| | | required: true, |
| | | options: menulist, |
| | | forbid: !!appType |
| | | }, |
| | | { |
| | | type: 'select', |
| | | field: 'appmenu', |
| | | label: '关联菜单', |
| | | initval: setting.menu || '', |
| | | required: true, |
| | | options: appmenulist, |
| | | forbid: !appType |
| | | }, |
| | | { |
| | | 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: '新窗口'}, |
| | | {value: 'self', label: '当前窗口'}, |
| | | ], |
| | | forbid: appType !== 'pc' |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | field: 'joint', |
| | | label: '参数拼接', |
| | | initval: setting.joint || 'true', |
| | | required: false, |
| | | options: [ |
| | | {value: 'true', label: '是'}, |
| | | {value: 'false', label: '否'}, |
| | | ], |
| | | }, |
| | | ] |
| | | |
| | | return cardSettingForm |
| | | } |
| | |
| | | if (appMenus) { |
| | | try { |
| | | appMenus = JSON.parse(appMenus) |
| | | appMenus = appMenus.map(item => ({value: item.MenuID, text: item.MenuName})) |
| | | } catch { |
| | | appMenus = [] |
| | | } |
| | |
| | | appIndeList = appIndeList.map(item => (item.keys_type !== 'index' ? item.keys_id : '')).join(',') |
| | | |
| | | let menus = res.menus.filter(item => appIndeList.indexOf(item.MenuID) === -1) |
| | | menus = menus.map(item => { |
| | | item.value = item.MenuID |
| | | item.label = item.MenuName |
| | | return item |
| | | }) |
| | | sessionStorage.setItem('appMenus', JSON.stringify(menus)) |
| | | }) |
| | | } |
| | |
| | | appIndeList = appIndeList.map(item => (item.keys_type !== 'index' ? item.keys_id : '')).join(',') |
| | | |
| | | let menus = res.menus.filter(item => appIndeList.indexOf(item.MenuID) === -1) |
| | | menus = menus.map(item => { |
| | | item.value = item.MenuID |
| | | item.label = item.MenuName |
| | | return item |
| | | }) |
| | | sessionStorage.setItem('appMenus', JSON.stringify(menus)) |
| | | }) |
| | | } |