| | |
| | | const { TextArea } = Input |
| | | |
| | | const MKRadio = asyncComponent(() => import('./mkRadio')) |
| | | const MKTable = asyncComponent(() => import('./mkTable')) |
| | | const MKCheckbox = asyncComponent(() => import('./mkCheckbox')) |
| | | const StyleInput = asyncComponent(() => import('./styleInput')) |
| | | const MKFileUpload = asyncComponent(() => import('@/tabviews/zshare/fileupload')) |
| | |
| | | validator: (rule, value, callback) => this.handleConfirmPassword(rule, value, callback, item) |
| | | }] |
| | | } else if (item.type === 'textarea') { |
| | | let _rules = [ |
| | | item.rules = [ |
| | | { |
| | | required: item.required, |
| | | message: item.label + '不可为空!' |
| | | } |
| | | ] |
| | | item.rules = _rules |
| | | } else if (item.type === 'table') { |
| | | item.rules = [ |
| | | { |
| | | required: item.required, |
| | | message: '请添加' + item.label + '!' |
| | | } |
| | | ] |
| | | } else { |
| | | item.rules = [ |
| | | { |
| | |
| | | content = (<MkEditIcon allowClear={item.allowClear}/>) |
| | | } else if (item.type === 'source') { |
| | | content = (<SourceComponent type="" placement="right"/>) |
| | | } else if (item.type === 'table') { |
| | | content = (<MKTable columns={item.columns || []}/>) |
| | | } |
| | | |
| | | if (!content) return |
New file |
| | |
| | | import React, { Component } from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { fromJS } from 'immutable' |
| | | import { DndProvider, DragSource, DropTarget } from 'react-dnd' |
| | | import { Table, Input, InputNumber, Popconfirm, Form, Select, Radio, Cascader, notification, Typography, Button } from 'antd' |
| | | import { PlusOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons' |
| | | |
| | | import Utils from '@/utils/utils.js' |
| | | import ColorSketch from '@/mob/colorsketch' |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import './index.scss' |
| | | |
| | | const MkEditIcon = asyncComponent(() => import('@/components/mkIcon')) |
| | | const EditableContext = React.createContext() |
| | | let dragingIndex = -1 |
| | | const { Paragraph } = Typography |
| | | |
| | | class BodyRow extends React.Component { |
| | | render() { |
| | | const { isOver, moveAble, connectDragSource, connectDropTarget, moveRow, ...restProps } = this.props |
| | | |
| | | let { className } = restProps |
| | | if (isOver && moveAble) { |
| | | if (restProps.index > dragingIndex) { |
| | | className += ' drop-over-downward' |
| | | } |
| | | if (restProps.index < dragingIndex) { |
| | | className += ' drop-over-upward' |
| | | } |
| | | } |
| | | |
| | | if (moveAble) { |
| | | return connectDragSource( |
| | | connectDropTarget(<tr {...restProps} className={className} style={{ ...restProps.style, cursor: 'move' }} />), |
| | | ) |
| | | } else { |
| | | return (<tr {...restProps} className={className} style={restProps.style} />) |
| | | } |
| | | } |
| | | } |
| | | |
| | | const rowSource = { |
| | | beginDrag(props) { |
| | | dragingIndex = props.index |
| | | return { |
| | | index: props.index, |
| | | } |
| | | } |
| | | } |
| | | |
| | | const rowTarget = { |
| | | drop(props, monitor) { |
| | | const dragIndex = monitor.getItem().index |
| | | const hoverIndex = props.index |
| | | |
| | | if (dragIndex === hoverIndex) { |
| | | return |
| | | } |
| | | |
| | | props.moveRow(dragIndex, hoverIndex) |
| | | |
| | | monitor.getItem().index = hoverIndex |
| | | }, |
| | | } |
| | | |
| | | const DragableBodyRow = DropTarget('row', rowTarget, (connect, monitor) => ({ |
| | | connectDropTarget: connect.dropTarget(), |
| | | isOver: monitor.isOver(), |
| | | }))( |
| | | DragSource('row', rowSource, connect => ({ |
| | | connectDragSource: connect.dragSource(), |
| | | }))(BodyRow), |
| | | ) |
| | | |
| | | class EditableCell extends Component { |
| | | getInput = (form) => { |
| | | const { inputType, options, min, max, unlimit } = this.props |
| | | |
| | | if (inputType === 'number' && unlimit) { |
| | | return <InputNumber onPressEnter={() => this.getValue(form)} /> |
| | | } else if (inputType === 'number') { |
| | | return <InputNumber min={min} max={max} precision={0} onPressEnter={() => this.getValue(form)} /> |
| | | } else if (inputType === 'color') { |
| | | return <ColorSketch /> |
| | | } else if (inputType === 'icon') { |
| | | return <MkEditIcon allowClear/> |
| | | } else if (inputType === 'select') { |
| | | return ( |
| | | <Select> |
| | | {options.map((item, i) => (<Select.Option key={i} value={item.field || item.value}> {item.label || item.text} </Select.Option>))} |
| | | </Select> |
| | | ) |
| | | } else if (inputType === 'multiStr') { |
| | | return ( |
| | | <Select mode="multiple"> |
| | | {options.map((item, i) => (<Select.Option key={i} value={item.field || item.value}> {item.label || item.text} </Select.Option>))} |
| | | </Select> |
| | | ) |
| | | } else if (inputType === 'cascader') { |
| | | return ( |
| | | <Cascader options={options} placeholder=""/> |
| | | ) |
| | | } else if (inputType === 'radio') { |
| | | return ( |
| | | <Radio.Group> |
| | | {options.map((item, i) => (<Radio key={i} value={item.field || item.value}> {item.label || item.text} </Radio>))} |
| | | </Radio.Group> |
| | | ) |
| | | } else { |
| | | return <Input onPressEnter={() => this.getValue(form)}/> |
| | | } |
| | | } |
| | | |
| | | getValue = (form) => { |
| | | form.validateFields((error, row) => { |
| | | if (error) { |
| | | return |
| | | } |
| | | this.props.onSave(row) |
| | | }) |
| | | } |
| | | |
| | | renderCell = (form) => { |
| | | const { getFieldDecorator } = form |
| | | const { editing, dataIndex, title, record, children, className, required, inputType } = this.props |
| | | |
| | | return ( |
| | | <td className={className}> |
| | | {editing ? ( |
| | | <Form.Item style={{ margin: 0 }}> |
| | | {getFieldDecorator(dataIndex, { |
| | | rules: [ |
| | | { |
| | | required: required, |
| | | message: ['number', 'text', 'input'].includes(inputType) ? `请输入 ${title}!` : `请选择 ${title}!`, |
| | | } |
| | | ], |
| | | initialValue: inputType === 'multiStr' ? (record[dataIndex] ? record[dataIndex].split(',') : []) : record[dataIndex], |
| | | })(this.getInput(form))} |
| | | </Form.Item> |
| | | ) : ( |
| | | children |
| | | )} |
| | | </td> |
| | | ) |
| | | } |
| | | |
| | | render() { |
| | | return <EditableContext.Consumer>{this.renderCell}</EditableContext.Consumer> |
| | | } |
| | | } |
| | | |
| | | class EditTable extends Component { |
| | | static propTpyes = { |
| | | columns: PropTypes.array, // 显示列 |
| | | onChange: PropTypes.func // 数据变化 |
| | | } |
| | | |
| | | state = { |
| | | data: [], |
| | | editLine: null, |
| | | editingKey: '', |
| | | visible: false, |
| | | columns: [] |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | let columns = fromJS(this.props.columns).toJS() |
| | | |
| | | let operation = { |
| | | title: '操作', |
| | | dataIndex: 'operation', |
| | | width: '120px', |
| | | render: (text, record) => { |
| | | const { editingKey } = this.state |
| | | const editable = this.isEditing(record) |
| | | return editable ? ( |
| | | <div style={{textAlign: 'center', minWidth: '110px'}}> |
| | | <EditableContext.Consumer> |
| | | {form => ( |
| | | <span onClick={() => this.save(form)} style={{ marginRight: 8 , color: '#1890ff', cursor: 'pointer'}}> |
| | | 保存 |
| | | </span> |
| | | )} |
| | | </EditableContext.Consumer> |
| | | <span style={{ color: '#1890ff', cursor: 'pointer'}} onClick={() => this.cancel(record.uuid)}>取消</span> |
| | | </div> |
| | | ) : ( |
| | | <div className={'edit-operation-btn' + (editingKey !== '' ? ' disabled' : '')} style={{minWidth: '110px', whiteSpace: 'nowrap'}}> |
| | | <span className="primary" onClick={() => {editingKey === '' && this.edit(record)}}><EditOutlined /></span> |
| | | {editingKey === '' ? <Popconfirm |
| | | overlayClassName="popover-confirm" |
| | | title="确定删除吗?" |
| | | onConfirm={() => this.handleDelete(record.uuid) |
| | | }> |
| | | <span className="danger"><DeleteOutlined /></span> |
| | | </Popconfirm> : null} |
| | | {editingKey !== '' ? <span className="danger"><DeleteOutlined /></span> : null} |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | columns.push(operation) |
| | | |
| | | this.setState({ |
| | | data: fromJS(this.props.value || []).toJS(), |
| | | operation, |
| | | columns |
| | | }) |
| | | } |
| | | |
| | | // shouldComponentUpdate (nextProps, nextState) { |
| | | // return !is(fromJS(this.state), fromJS(nextState)) |
| | | // } |
| | | |
| | | isEditing = record => record.uuid === this.state.editingKey |
| | | |
| | | cancel = () => { |
| | | this.setState({ editingKey: '', data: this.state.data.filter(item => !item.isnew) }) |
| | | } |
| | | |
| | | handleDelete = (uuid) => { |
| | | const { data } = this.state |
| | | let _data = data.filter(item => uuid !== item.uuid) |
| | | |
| | | this.setState({ |
| | | data: _data |
| | | }, () => { |
| | | this.props.onChange(_data) |
| | | }) |
| | | } |
| | | |
| | | save(form) { |
| | | form.validateFields((error, row) => { |
| | | if (error) { |
| | | return; |
| | | } |
| | | this.execSave(row) |
| | | }) |
| | | } |
| | | |
| | | execSave = (row) => { |
| | | const { columns, editLine } = this.state |
| | | |
| | | let newData = [...this.state.data] |
| | | let record = {...editLine, ...row} |
| | | let index = newData.findIndex(item => record.uuid === item.uuid) |
| | | |
| | | if (index === -1) return |
| | | |
| | | let unique = true |
| | | columns.forEach(col => { |
| | | if (col.unique !== true || !unique) return |
| | | |
| | | let _index = newData.findIndex(item => record.uuid !== item.uuid && record[col.dataIndex] === item[col.dataIndex]) |
| | | |
| | | if (_index > -1) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: col.title + '不可重复!', |
| | | duration: 5 |
| | | }) |
| | | unique = false |
| | | } |
| | | }) |
| | | |
| | | if (!unique) return |
| | | |
| | | columns.forEach(col => { |
| | | if (!col.extends) return |
| | | |
| | | if (col.extends === 'Menu') { |
| | | let menu = record[col.dataIndex] |
| | | let fId = menu[0] || '' |
| | | let sId = menu[1] || '' |
| | | let tId = menu[2] || '' |
| | | let label = '' |
| | | |
| | | col.options.forEach(f => { |
| | | if (!fId || fId !== f.value) return |
| | | label = f.label |
| | | |
| | | f.children.forEach(s => { |
| | | if (!sId || sId !== s.value) return |
| | | label += ' / ' + s.label |
| | | |
| | | s.children.forEach(t => { |
| | | if (!tId || tId !== t.value) return |
| | | label += ' / ' + t.label |
| | | |
| | | record.MenuID = t.MenuID |
| | | record.MenuName = t.MenuName |
| | | record.MenuNo = t.MenuNo |
| | | record.tabType = t.type |
| | | record.label = label |
| | | }) |
| | | }) |
| | | }) |
| | | } else { |
| | | let key = record[col.dataIndex] |
| | | let option = col.options.filter(m => m.value === key)[0] |
| | | |
| | | if (option) { |
| | | col.extends.forEach(n => { |
| | | record[n.value] = option[n.key] |
| | | }) |
| | | } |
| | | } |
| | | }) |
| | | |
| | | delete record.isnew |
| | | |
| | | newData.splice(index, 1, record) |
| | | this.setState({ data: newData, editingKey: '', editLine: null }, () => { |
| | | this.props.onChange(newData) |
| | | }) |
| | | } |
| | | |
| | | edit(item) { |
| | | this.setState({ editLine: item, editingKey: item.uuid }) |
| | | } |
| | | |
| | | addline = () => { |
| | | let item = { |
| | | uuid: Utils.getuuid(), |
| | | isnew: true |
| | | } |
| | | |
| | | this.setState({ data: [...this.state.data, item], editingKey: '' }, () => { |
| | | this.setState({ editLine: item, editingKey: item.uuid }) |
| | | }) |
| | | } |
| | | |
| | | moveRow = (dragIndex, hoverIndex) => { |
| | | const { editingKey } = this.state |
| | | let _data = fromJS(this.state.data).toJS() |
| | | |
| | | if (editingKey) return |
| | | |
| | | _data.splice(hoverIndex, 0, ..._data.splice(dragIndex, 1)) |
| | | |
| | | this.setState({ |
| | | data: _data |
| | | }, () => { |
| | | this.props.onChange(_data) |
| | | }) |
| | | } |
| | | |
| | | render() { |
| | | let components = { |
| | | body: { |
| | | cell: EditableCell |
| | | } |
| | | } |
| | | |
| | | let moveprops = {} |
| | | components.body.row = DragableBodyRow |
| | | moveprops.moveAble = !this.state.editingKey |
| | | moveprops.moveRow = this.moveRow |
| | | |
| | | let columns = this.state.columns.map(col => { |
| | | if (col.copy) { |
| | | col.render = (text) => (<Paragraph copyable>{text}</Paragraph>) |
| | | } |
| | | if (!col.editable) return col |
| | | return { |
| | | ...col, |
| | | onCell: record => ({ |
| | | record, |
| | | inputType: col.inputType, |
| | | dataIndex: col.dataIndex, |
| | | options: col.options || [], |
| | | min: col.min || 0, |
| | | max: col.max || 500, |
| | | unlimit: col.unlimit, |
| | | required: col.required !== false ? true : false, |
| | | title: col.title, |
| | | editing: this.isEditing(record), |
| | | onSave: this.execSave, |
| | | }), |
| | | } |
| | | }) |
| | | |
| | | const data = this.state.data.map((item, index) => { |
| | | item.$index = index + 1 |
| | | |
| | | return item |
| | | }) |
| | | |
| | | return ( |
| | | <EditableContext.Provider value={this.props.form}> |
| | | <div className="modal-editable-table"> |
| | | <Button disabled={!!this.state.editingKey} type="link" onClick={this.addline}><PlusOutlined style={{}}/></Button> |
| | | <DndProvider> |
| | | <Table |
| | | bordered |
| | | rowKey="uuid" |
| | | size="middle" |
| | | components={components} |
| | | dataSource={data} |
| | | columns={columns} |
| | | rowClassName="editable-row" |
| | | pagination={false} |
| | | onRow={(record, index) => ({ |
| | | index, |
| | | ...moveprops |
| | | })} |
| | | /> |
| | | </DndProvider> |
| | | </div> |
| | | </EditableContext.Provider> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default Form.create()(EditTable) |
New file |
| | |
| | | .modal-editable-table { |
| | | position: relative; |
| | | margin-bottom: 5px; |
| | | |
| | | >.ant-btn { |
| | | position: absolute; |
| | | right: 0px; |
| | | top: -26px; |
| | | font-size: 18px; |
| | | color: #26C281; |
| | | z-index: 1; |
| | | height: 28px; |
| | | } |
| | | .editable-row { |
| | | .ant-form-explain { |
| | | position: absolute; |
| | | font-size: 12px; |
| | | margin-top: -4px; |
| | | } |
| | | .color-sketch-block { |
| | | width: 200px; |
| | | position: relative; |
| | | top: 8px; |
| | | } |
| | | .ant-select { |
| | | width: 100%; |
| | | } |
| | | > td { |
| | | padding: 14px 10px; |
| | | } |
| | | > td:last-child { |
| | | padding: 0px; |
| | | } |
| | | } |
| | | .mk-index { |
| | | text-align: center; |
| | | white-space: nowrap; |
| | | } |
| | | |
| | | thead tr th:last-child { |
| | | text-align: center; |
| | | } |
| | | .edit-operation-btn { |
| | | display: block; |
| | | text-align: center; |
| | | span { |
| | | margin-right: 10px; |
| | | cursor: pointer; |
| | | font-size: 16px; |
| | | padding: 5px; |
| | | } |
| | | .primary { |
| | | color: #1890ff; |
| | | } |
| | | .copy { |
| | | color: #26C281; |
| | | } |
| | | .danger { |
| | | color: #ff4d4f; |
| | | } |
| | | span:last-child { |
| | | margin-right: 0px; |
| | | } |
| | | } |
| | | .edit-operation-btn.disabled { |
| | | cursor: default; |
| | | span { |
| | | cursor: default; |
| | | } |
| | | .primary { |
| | | color: rgba(0, 0, 0, .25); |
| | | } |
| | | .danger { |
| | | color: rgba(0, 0, 0, .25); |
| | | } |
| | | .copy { |
| | | color: rgba(0, 0, 0, .25); |
| | | } |
| | | } |
| | | .ant-empty { |
| | | margin: 0; |
| | | } |
| | | tr.drop-over-downward td { |
| | | border-bottom: 2px dashed #1890ff; |
| | | } |
| | | tr.drop-over-upward td { |
| | | border-top: 2px dashed #1890ff; |
| | | } |
| | | .copy-control { |
| | | display: inline-block; |
| | | position: absolute; |
| | | right: 10px; |
| | | top: 2px; |
| | | |
| | | .anticon-copy { |
| | | margin-right: 7px; |
| | | color: #26C281; |
| | | } |
| | | .anticon-snippets { |
| | | color: purple; |
| | | } |
| | | .anticon-delete { |
| | | margin-left: 7px; |
| | | color: #ff4d4f; |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | let _val = fromJS(copycard).toJS() |
| | | |
| | | if (_val.control) { |
| | | _val.control = '' |
| | | |
| | | delete _val.controlField |
| | | delete _val.controlVal |
| | | } |
| | | |
| | | copycard.uuid = Utils.getuuid() |
| | | copycard.originCard = card |
| | | |
| | |
| | | |
| | | const NormalForm = asyncIconComponent(() => import('@/components/normalform')) |
| | | const CardCellComponent = asyncComponent(() => import('../cardcellcomponent')) |
| | | const CardMenus = asyncComponent(() => import('./menus-wrap')) |
| | | const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent')) |
| | | const PasteController = asyncIconComponent(() => import('@/components/paste')) |
| | | |
| | |
| | | } |
| | | }) |
| | | } |
| | | return getSettingForm(card.setting, cards.subtype, buttons, card.$cardType, cards.columns) |
| | | return getSettingForm(card.setting, cards.subtype, buttons, card.$cardType, cards.columns, card.menus) |
| | | } |
| | | |
| | | updateSetting = (res) => { |
| | |
| | | }) |
| | | } |
| | | |
| | | let _card = {...card, setting: res} |
| | | |
| | | if (res.menus) { |
| | | _card.menus = res.menus |
| | | |
| | | delete res.menus |
| | | } |
| | | |
| | | this.setState({ |
| | | card: {...card, setting: res} |
| | | card: _card |
| | | }) |
| | | |
| | | if (side === 'back' && res.type === 'simple') { |
| | | this.setState({ |
| | | side: 'front', |
| | | elements: fromJS(card.elements).toJS() |
| | | elements: fromJS(_card.elements).toJS() |
| | | }) |
| | | } |
| | | |
| | | this.props.updateElement({...card, setting: res}) |
| | | this.props.updateElement(_card) |
| | | } |
| | | |
| | | paste = (element, resolve) => { |
| | |
| | | return |
| | | } |
| | | MKEmitter.emit('changeEditMenu', {MenuID: card.setting.menu}) |
| | | } else if (card.setting.click === 'menus' && card.menus && card.menus.length > 0 && cards.subtype === 'datacard' && card.$cardType !== 'extendCard' && (appType === 'mob' || appType === 'pc')) { |
| | | } else if (card.setting.click === 'menus' && card.menus && card.menus.length > 0 && cards.subtype === 'datacard' && appType) { |
| | | this.setState({visible: true}) |
| | | } |
| | | } |
| | | |
| | | updateMenus = (res) => { |
| | | const { card } = this.state |
| | | |
| | | this.setState({ |
| | | card: {...card, menus: res} |
| | | }) |
| | | |
| | | this.props.updateElement({...card, menus: res}) |
| | | } |
| | | |
| | | render() { |
| | |
| | | <NormalForm title="卡片设置" width={800} update={this.updateSetting} getForms={this.getSettingForms}> |
| | | <EditOutlined className="edit" title="编辑"/> |
| | | </NormalForm> |
| | | {cards.subtype === 'datacard' && card.$cardType !== 'extendCard' && card.setting.click === 'menus' ? |
| | | <CardMenus card={card} updateMenus={this.updateMenus}/> : null} |
| | | <CopyComponent type="cardcell" card={card}/> |
| | | <PasteController options={['action', 'customCardElement']} updateConfig={this.paste} /> |
| | | <FontColorsOutlined className="style" title="调整样式" onClick={this.changeStyle} /> |
| | |
| | | /** |
| | | * @description Setting表单配置信息 |
| | | */ |
| | | export default function (setting, subtype, buttons = [], cardType, columns) { |
| | | export default function (setting, subtype, buttons = [], cardType, columns, menus = []) { |
| | | let appType = sessionStorage.getItem('appType') |
| | | let hasMenus = subtype === 'datacard' && cardType !== 'extendCard' |
| | | |
| | | let menulist = [] |
| | | let appmenulist = [] |
| | | |
| | | if (appType) { |
| | | appmenulist = sessionStorage.getItem('appMenus') |
| | | if (appmenulist) { |
| | | menulist = sessionStorage.getItem('appMenus') |
| | | if (menulist) { |
| | | try { |
| | | appmenulist = JSON.parse(appmenulist) |
| | | menulist = JSON.parse(menulist) |
| | | } catch (e) { |
| | | appmenulist = [] |
| | | menulist = [] |
| | | } |
| | | } else { |
| | | appmenulist = [] |
| | | menulist = [] |
| | | } |
| | | if (appType === 'mob' && (subtype === 'datacard' || subtype === 'propcard') && cardType !== 'extendCard') { // 数据卡可打开即时通信 |
| | | appmenulist.push({ |
| | | menulist.push({ |
| | | value: 'IM', label: '即时通信(系统页)' |
| | | }) |
| | | } |
| | |
| | | {field: 'joint', values: ['menu', 'link', 'menus']}, |
| | | {field: 'linkbtn', values: ['button']}, |
| | | {field: 'menuType', values: ['menus']}, |
| | | {field: 'menus', values: ['menus']}, |
| | | ] |
| | | }, |
| | | { |
| | |
| | | label: '关联菜单', |
| | | initval: setting.menu || (appType ? '' : []), |
| | | required: true, |
| | | options: appType ? appmenulist : menulist, |
| | | options: menulist, |
| | | }, |
| | | { |
| | | type: 'textarea', |
| | |
| | | {value: 'hover', label: '悬浮显示'}, |
| | | ], |
| | | forbid: appType === 'mob' |
| | | }, |
| | | { |
| | | type: 'table', |
| | | field: 'menus', |
| | | label: '菜单组', |
| | | initval: menus, |
| | | required: true, |
| | | span: 24, |
| | | columns: [ |
| | | { |
| | | title: '标识', |
| | | dataIndex: 'sign', |
| | | inputType: 'input', |
| | | editable: true, |
| | | unique: true, |
| | | required: false, |
| | | width: '35%' |
| | | }, |
| | | { |
| | | title: '菜单', |
| | | dataIndex: 'menu', |
| | | inputType: !appType ? 'cascader' : 'select', |
| | | editable: true, |
| | | required: true, |
| | | extends: !appType ? 'Menu' : [{key: 'label', value: 'label'}], |
| | | width: '35%', |
| | | render: (text, record) => record.label, |
| | | options: menulist |
| | | } |
| | | ] |
| | | } |
| | | ] |
| | | |
| | |
| | | |
| | | let _val = fromJS(copycard).toJS() |
| | | |
| | | if (_val.control) { |
| | | _val.control = '' |
| | | |
| | | delete _val.controlField |
| | | delete _val.controlVal |
| | | } |
| | | |
| | | copycard.uuid = Utils.getuuid() |
| | | copycard.originCard = card |
| | | |
| | |
| | | if (_card.loginWays.length === 2) { |
| | | _card.loginWays.push({type: 'app_scan', label: '扫码登录'}) |
| | | } |
| | | if (_card.wrap.link && _card.wrap.link === 'menu') { |
| | | _card.wrap.linkmenu = _card.uuid |
| | | } |
| | | this.setState({ |
| | | card: _card |
| | | }) |
| | |
| | | } |
| | | |
| | | getWrapForms = () => { |
| | | const { wrap } = this.state.card |
| | | const { card } = this.state |
| | | |
| | | return getWrapForm(wrap) |
| | | return getWrapForm(card.wrap) |
| | | } |
| | | |
| | | updateWrap = (res) => { |
| | |
| | | } trigger="hover"> |
| | | <ToolOutlined /> |
| | | </Popover> |
| | | <LoginForm loginWays={card.loginWays} wrap={card.wrap} menuId={card.uuid} /> |
| | | <LoginForm loginWays={card.loginWays} wrap={card.wrap} /> |
| | | </div> |
| | | ) |
| | | } |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Form, Input, Button, Checkbox } from 'antd' |
| | | import { Form, Input, Button, Checkbox, notification } from 'antd' |
| | | import { QrcodeOutlined, UserOutlined, LockOutlined } from '@ant-design/icons' |
| | | |
| | | import asyncElementComponent from '@/utils/asyncComponent' |
| | |
| | | |
| | | class LoginTabForm extends Component { |
| | | static propTpyes = { |
| | | menuId: PropTypes.string, |
| | | loginWays: PropTypes.array, |
| | | wrap: PropTypes.array, |
| | | } |
| | |
| | | } |
| | | |
| | | changeMenu = () => { |
| | | const { wrap, menuId } = this.props |
| | | const { wrap } = this.props |
| | | |
| | | if (!wrap.linkmenu) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请设置关联菜单!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | MKEmitter.emit('changeEditMenu', { |
| | | MenuID: wrap.link === 'linkmenu' ? wrap.linkmenu : menuId, |
| | | MenuID: wrap.linkmenu, |
| | | copyMenuId: '', |
| | | MenuNo: '', |
| | | MenuName: '' |
| | |
| | | ] |
| | | }, |
| | | { |
| | | type: 'select', |
| | | field: 'linkmenu', |
| | | label: '关联菜单', |
| | | initval: wrap.linkmenu || '', |
| | | required: true, |
| | | options: menulist |
| | | }, |
| | | { |
| | | type: 'select', // $验证码$ $mob$ $send_type$ |
| | | field: 'tempId', |
| | | label: '短信模板', |
| | | initval: wrap.tempId || '', |
| | | tooltip: '短信模板可在 云系统->应用服务->开发者中心->短信模板 处添加。', |
| | | required: true, |
| | | options: msgTemps |
| | | }, |
| | | { |
| | | type: 'number', |
| | | field: 'width', |
| | | label: '宽度', |
| | |
| | | required: false, |
| | | options: ['px', 'vh', 'vw', '%'] |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | field: 'link', |
| | | label: '链接', |
| | | initval: wrap.link || 'menu', |
| | | required: false, |
| | | options: [ |
| | | {value: 'menu', label: '菜单'}, |
| | | {value: 'linkmenu', label: '关联菜单'}, |
| | | ], |
| | | controlFields: [ |
| | | {field: 'linkmenu', values: ['linkmenu']} |
| | | ] |
| | | }, |
| | | { |
| | | type: 'select', |
| | | field: 'linkmenu', |
| | | label: '关联菜单', |
| | | initval: wrap.linkmenu || '', |
| | | required: true, |
| | | options: menulist |
| | | }, |
| | | { |
| | | type: 'select', // $验证码$ $mob$ $send_type$ |
| | | field: 'tempId', |
| | | label: '短信模板', |
| | | initval: wrap.tempId || '', |
| | | tooltip: '短信模板可在 云系统->应用服务->开发者中心->短信模板 处添加。', |
| | | required: true, |
| | | options: msgTemps |
| | | }, |
| | | // { |
| | | // type: 'radio', |
| | | // field: 'link', |
| | | // label: '链接', |
| | | // initval: wrap.link || 'menu', |
| | | // required: false, |
| | | // options: [ |
| | | // {value: 'menu', label: '菜单'}, |
| | | // {value: 'linkmenu', label: '关联菜单'}, |
| | | // ], |
| | | // controlFields: [ |
| | | // {field: 'linkmenu', values: ['linkmenu']} |
| | | // ] |
| | | // }, |
| | | { |
| | | type: 'radio', |
| | | field: 'shortcut', |
| | |
| | | } else if (item.subtype === 'propcard' && item.subcards.length === 0) { |
| | | error = `组件《${item.name}》中卡片不可为空!` |
| | | return |
| | | } else if (item.type === 'login' && !item.wrap.linkmenu && item.wrap.link !== 'menu') { |
| | | error = '登录组件未设置关联菜单!' |
| | | return |
| | | } |
| | | if (item.wrap && item.wrap.pagestyle === 'slide') { |
| | | swipes.push(item.name) |
| | |
| | | } else if (item.subtype === 'propcard' && item.subcards.length === 0) { |
| | | error = `组件《${item.name}》中卡片不可为空!` |
| | | return |
| | | } else if (item.type === 'login' && !item.wrap.linkmenu && item.wrap.link !== 'menu') { |
| | | error = '登录组件未设置关联菜单!' |
| | | return |
| | | } |
| | | |
| | | if (['propcard', 'brafteditor', 'sandbox', 'stepform', 'tabform'].includes(item.subtype) && item.wrap.datatype === 'static') return |