| | |
| | | /*背景色*/ |
| | | html, body { |
| | | width: 100%; |
| | | font-size: 10px; |
| | | font-size: 14px; |
| | | } |
| | | #root { |
| | | height: 100%; |
| | |
| | | line-height: 48px; |
| | | li { |
| | | float: left; |
| | | font-size: 1.8rem; |
| | | font-size: 1.3rem; |
| | | cursor: pointer; |
| | | span { |
| | | padding: 0 10px; |
| | |
| | | } |
| | | span { |
| | | color: #ffffff; |
| | | font-size: 1.3rem; |
| | | font-size: 0.95rem; |
| | | .username { |
| | | display: inline-block; |
| | | height: 30px; |
| | |
| | | background: #06b4f7; |
| | | } |
| | | .ant-menu-inline .ant-menu-item { |
| | | font-size: 1.5rem; |
| | | font-size: 1.1rem; |
| | | } |
| | | .ant-menu-dark.ant-menu-inline .ant-menu-submenu-title { |
| | | margin: 0; |
| | |
| | | import { is, fromJS } from 'immutable' |
| | | import {Tabs, Icon, Button, ConfigProvider, message} from 'antd' |
| | | import {modifyTabview, toggleIsiframe} from '@/store/action' |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | // import asyncComponent from '@/utils/asyncComponent' |
| | | import asyncComponent from '@/utils/asyncLoadComponent' |
| | | import NotFount from '@/components/404' |
| | | import enUS from 'antd/es/locale/en_US' |
| | | import zhCN from 'antd/es/locale/zh_CN' |
| | |
| | | 'header.menu.openType.newWindow': 'A new window', |
| | | 'header.menu.newpage.service': 'Customer Service', |
| | | 'header.menu.func.create': '创建存储过程', |
| | | 'header.menu.tab': '标签页', |
| | | 'header.menu.tab.subtable': '子表', |
| | | 'header.form.search.placeholder': 'Please add search criteria', |
| | | 'header.form.modal.placeholder': 'Please add the form', |
| | | 'header.form.action.placeholder': 'Please add buttons', |
| | | 'header.form.tab.placeholder': '请添加标签页', |
| | | 'header.form.column.placeholder': 'Please add columns', |
| | | 'header.form.column.source': 'Columns', |
| | | 'header.form.column.target': '已添加', |
| | |
| | | 'header.form.pageTemplate': '页面模板', |
| | | 'header.form.type': 'Type', |
| | | 'header.form.text': 'Text', |
| | | 'header.form.description': '描述', |
| | | 'header.form.textarea': '多行文本', |
| | | 'header.form.picture': '图片', |
| | | 'header.form.number': '数字', |
| | |
| | | 'header.menu.openType.newWindow': '新窗口', |
| | | 'header.menu.newpage.service': '客服', |
| | | 'header.menu.func.create': '创建存储过程', |
| | | 'header.menu.tab': '标签页', |
| | | 'header.menu.tab.subtable': '子表', |
| | | 'header.form.search.placeholder': '请添加搜索条件', |
| | | 'header.form.modal.placeholder': '请添加表单', |
| | | 'header.form.action.placeholder': '请添加按钮', |
| | | 'header.form.tab.placeholder': '请添加标签页', |
| | | 'header.form.column.placeholder': '请添加显示列', |
| | | 'header.form.column.source': '显示列', |
| | | 'header.form.column.target': '已添加', |
| | |
| | | 'header.form.pageTemplate': '页面模板', |
| | | 'header.form.type': '类型', |
| | | 'header.form.text': '文本', |
| | | 'header.form.description': '描述', |
| | | 'header.form.textarea': '多行文本', |
| | | 'header.form.picture': '图片', |
| | | 'header.form.number': '数字', |
| | |
| | | import React, {Component} from 'react' |
| | | import {HashRouter, Switch, Route, Redirect} from 'react-router-dom' |
| | | import moment from 'moment' |
| | | import md5 from 'md5' |
| | | import moment from 'moment' |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | const main = asyncComponent(() => import('@/views/main')) |
| | | const login = asyncComponent(() => import('@/views/login')) |
| | | import asyncLoadComponent from '@/utils/asyncLoadComponent' |
| | | |
| | | const main = asyncLoadComponent(() => import('@/views/main')) |
| | | const login = asyncLoadComponent(() => import('@/views/login')) |
| | | const NotFound = asyncComponent(() => import('@/views/404')) |
| | | |
| | | const routers = [ |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { BackTop, notification} from 'antd' |
| | | import { BackTop, notification, Spin} from 'antd' |
| | | import moment from 'moment' |
| | | import Api from '@/api' |
| | | import MainSearch from './mainSearch' |
| | | import MainAction from './mainAction' |
| | | import MainTable from './mainTable' |
| | | import NotFount from '@/components/404' |
| | | import Loading from '@/components/loading' |
| | | import zhCN from '@/locales/zh-CN/main.js' |
| | | import enUS from '@/locales/en-US/main.js' |
| | | import Utils from '@/utils/utils.js' |
| | |
| | | const { arr_field, pageIndex, pageSize, orderColumn, orderType, search, setting } = this.state |
| | | |
| | | let _search = Utils.joinMainSearchkey(search) |
| | | _search = _search ? 'where (' + _search + ')' : '' |
| | | _search = _search ? 'where ' + _search : '' |
| | | |
| | | let param = { |
| | | func: 'sPC_Get_TableData', |
| | |
| | | |
| | | let LText = `select top ${pageSize} ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by ${orderBy}) as rows from ${setting.dataresource} ${_search}) tmptable where rows > ${pageSize * (pageIndex - 1)} order by tmptable.rows` |
| | | let DateCount = `select count(1) as total from ${setting.dataresource} ${_search}` |
| | | |
| | | console.log(LText) |
| | | param.LText = Utils.formatOptions(LText) |
| | | param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000' |
| | | param.secretkey = Utils.encrypt(param.LText, param.timestamp) |
| | |
| | | let orderBy = orderColumn ? (orderColumn + ' ' + orderType) : setting.order |
| | | |
| | | let LText = `select ${_arr_label_field} from (select ${arr_field} ,ROW_NUMBER() over(order by ${orderBy}) as rows from ${setting.dataresource} ${_search}) tmptable order by tmptable.rows` |
| | | |
| | | console.log(LText) |
| | | param.LText = Utils.formatOptions(LText) |
| | | param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000' |
| | | param.secretkey = Utils.encrypt(param.LText, param.timestamp) |
| | |
| | | |
| | | return ( |
| | | <div className="commontable" id={'commontable' + this.props.MenuID}> |
| | | {loadingview && <Loading />} |
| | | {loadingview && <Spin size="large" />} |
| | | {searchlist && searchlist.length > 0 ? |
| | | <MainSearch |
| | | refreshdata={this.refreshbysearch} |
| | |
| | | top: 40px; |
| | | max-width: 95%; |
| | | .ant-modal-body { |
| | | max-height: calc(100vh - 250px); |
| | | max-height: calc(100vh - 265px); |
| | | } |
| | | } |
| | | > .ant-spin { |
| | | position: fixed; |
| | | left: calc(50vw - 22px); |
| | | top: calc(50vh - 70px); |
| | | } |
| | | } |
| | | .ant-back-top { |
| | | bottom: 30px; |
| | |
| | | formlist: formlist |
| | | }, () => { |
| | | if (action.setting && action.setting.focus) { |
| | | let _item = document.getElementById(action.setting.focus) |
| | | if (_item) { |
| | | _item.select() |
| | | try { |
| | | let _form = document.getElementById('main-form-box') |
| | | let _item = _form.getElementsByTagName('input') |
| | | _item = [..._item] |
| | | _item.forEach(input => { |
| | | if (!input || input.id !== action.setting.focus) return |
| | | input.select() |
| | | }) |
| | | } catch { |
| | | console.warn('表单获取失败!') |
| | | } |
| | | } |
| | | }) |
| | |
| | | <Col span={24 / cols} key={index}> |
| | | <Form.Item label={item.label}> |
| | | {getFieldDecorator(item.field, { |
| | | initialValue: item.initval || 'text', |
| | | initialValue: item.initval || '', |
| | | rules: [ |
| | | { |
| | | required: item.required === 'true', |
| | |
| | | } |
| | | } |
| | | return ( |
| | | <Form {...formItemLayout} className="ant-advanced-search-form main-form-field" id="form-box"> |
| | | <Form {...formItemLayout} className="ant-advanced-search-form main-form-field" id="main-form-box"> |
| | | <Row gutter={24}>{this.getFields()}</Row> |
| | | </Form> |
| | | ) |
| | |
| | | .common-source-item { |
| | | display: block; |
| | | box-shadow: 0px 0px 2px #bcbcbc; |
| | | padding: 0.5rem 1rem; |
| | | padding: 0.4rem 0.7rem; |
| | | background-color: white; |
| | | margin: 0px 0px 10px; |
| | | cursor: move; |
| | |
| | | form: 'form', |
| | | search: 'search', |
| | | action: 'action', |
| | | columns: 'columns' |
| | | columns: 'columns', |
| | | tab: 'tab' |
| | | } |
| | |
| | | import { Button, Card, Modal, Collapse, notification, Spin, Select, List, Icon, Empty, Switch, Tooltip } from 'antd' |
| | | import moment from 'moment' |
| | | import DragElement from './dragelement' |
| | | import TabDragElement from './tabdragelement' |
| | | import SourceElement from './dragelement/source' |
| | | import Api from '@/api' |
| | | import TabForm from './tabform' |
| | | import SearchForm from './searchform' |
| | | import ActionForm from './actionform' |
| | | import ColumnForm from './columnform' |
| | |
| | | dict: CommonDict, // 字典 |
| | | config: null, // 页面配置 |
| | | visible: false, // 搜索条件、按钮、显示列,模态框显示控制 |
| | | modalTitle: '', // 模态框的标题 |
| | | tableVisible: false, // 数据表字段模态框 |
| | | addType: '', // 添加类型-搜索条件或显示列 |
| | | tableColumns: [], // 表格显示列 |
| | |
| | | searchloading: false, // 搜索条件加载中 |
| | | actionloading: false, // 按钮加载中 |
| | | columnsloading: false, // 显示列加载中 |
| | | tabloading: false, // 标签页加载中 |
| | | menuloading: false, // 菜单保存中 |
| | | menucloseloading: false, // 菜单关闭时,选择保存 |
| | | loading: false, // 加载中,页面spin |
| | |
| | | return item |
| | | }) |
| | | } |
| | | |
| | | _config.tabs = _config.tabs || [] |
| | | _config.subtabs = _config.subtabs || [] |
| | | |
| | | this.setState({ |
| | | originActions: _oriActions, |
| | |
| | | this.handleAction(card) |
| | | } else if (type === 'columns') { |
| | | this.handleColumn(card) |
| | | } else if (type === 'tabs' || type === 'subtabs') { |
| | | this.handleTab(card) |
| | | } |
| | | }) |
| | | } else { |
| | |
| | | this.setState({ |
| | | visible: true, |
| | | formtemp: 'search', |
| | | modalTitle: '编辑-搜索条件', |
| | | card: card, |
| | | formlist: [ |
| | | { |
| | |
| | | }) |
| | | } |
| | | |
| | | handleAction = (card) => { |
| | | handleAction = (card, type) => { |
| | | let ableField = this.props.permFuncField.join(', ') |
| | | this.setState({ |
| | | visible: true, |
| | | formtemp: 'action', |
| | | modalTitle: type === 'copy' ? '复制-按钮' : '编辑-按钮', |
| | | card: card, |
| | | formlist: [ |
| | | { |
| | |
| | | this.setState({ |
| | | visible: true, |
| | | formtemp: 'columns', |
| | | modalTitle: '编辑-显示列', |
| | | card: card, |
| | | formlist: [ |
| | | { |
| | |
| | | } |
| | | } |
| | | |
| | | handleTab = (card) => { |
| | | this.setState({ |
| | | visible: true, |
| | | formtemp: 'tabs', |
| | | modalTitle: '编辑-标签页', |
| | | card: card, |
| | | formlist: [ |
| | | { |
| | | type: 'text', |
| | | key: 'label', |
| | | label: this.state.dict['header.form.name'], |
| | | initVal: card.label || '', |
| | | required: true |
| | | }, |
| | | { |
| | | type: 'select', |
| | | key: 'type', |
| | | label: this.state.dict['header.form.type'], |
| | | initVal: card.type || '', |
| | | required: true, |
| | | options: [{ |
| | | value: 'SubTable', |
| | | text: this.state.dict['header.menu.tab.subtable'] |
| | | }] |
| | | }, |
| | | { |
| | | type: 'select', |
| | | key: 'linkId', |
| | | label: '关联标签', |
| | | initVal: card.linkId || '', |
| | | required: true, |
| | | options: [{ |
| | | value: 'table', |
| | | text: 'table' |
| | | }, { |
| | | value: 'bar-chart', |
| | | text: 'bar-chart' |
| | | }, { |
| | | value: 'pie-chart', |
| | | text: 'pie-chart' |
| | | }, { |
| | | value: 'line-chart', |
| | | text: 'line-chart' |
| | | }] |
| | | }, |
| | | { |
| | | type: 'select', |
| | | key: 'icon', |
| | | label: this.state.dict['header.menu.icon'], |
| | | initVal: card.icon || '', |
| | | required: false, |
| | | options: [{ |
| | | value: '', |
| | | text: this.state.dict['header.form.empty'] |
| | | }, { |
| | | value: 'table', |
| | | text: 'table' |
| | | }, { |
| | | value: 'bar-chart', |
| | | text: 'bar-chart' |
| | | }, { |
| | | value: 'pie-chart', |
| | | text: 'pie-chart' |
| | | }, { |
| | | value: 'line-chart', |
| | | text: 'line-chart' |
| | | }] |
| | | }, |
| | | { |
| | | type: 'text', |
| | | key: 'description', |
| | | label: this.state.dict['header.form.description'], |
| | | initVal: card.description || '', |
| | | required: false |
| | | } |
| | | ] |
| | | }) |
| | | } |
| | | |
| | | handleGridBtn = () => { |
| | | this.setState({ |
| | | visible: true, |
| | | formtemp: 'gridbtn' |
| | | formtemp: 'gridbtn', |
| | | modalTitle: '编辑-操作列', |
| | | }) |
| | | } |
| | | |
| | |
| | | searchloading: true, |
| | | actionloading: true, |
| | | columnsloading: true, |
| | | tabloading: true, |
| | | visible: false |
| | | }, () => { |
| | | this.setState({ |
| | | searchloading: false, |
| | | actionloading: false, |
| | | columnsloading: false |
| | | columnsloading: false, |
| | | tabloading: false |
| | | }) |
| | | }) |
| | | }) |
| | |
| | | return true |
| | | } |
| | | }) |
| | | |
| | | let refreshtype = element.type + 'loading' |
| | | |
| | | if (/^tab/.test(refreshtype)) { |
| | | refreshtype = 'tabloading' |
| | | } |
| | | |
| | | _this.setState({ |
| | | config: _config, |
| | | delActions: [..._this.state.delActions, element.card.uuid], |
| | | [element.type + 'loading']: true |
| | | [refreshtype]: true |
| | | }, () => { |
| | | _this.setState({ |
| | | [element.type + 'loading']: false |
| | | [refreshtype]: false |
| | | }) |
| | | }) |
| | | }, |
| | |
| | | } |
| | | if (config.columns[0] && config.columns[0].origin) { |
| | | config.columns = config.columns.filter(item => !item.origin) |
| | | } |
| | | if (config.tabs[0] && config.tabs[0].origin) { |
| | | config.tabs = config.tabs.filter(item => !item.origin) |
| | | } |
| | | if (config.subtabs[0] && config.subtabs[0].origin) { |
| | | config.subtabs = config.subtabs.filter(item => !item.origin) |
| | | } |
| | | |
| | | let _LongParam = '' |
| | |
| | | if ( |
| | | (config.search[0] && config.search[0].origin) || |
| | | (config.action[0] && config.action[0].origin) || |
| | | (config.columns[0] && config.columns[0].origin) |
| | | (config.columns[0] && config.columns[0].origin) || |
| | | (config.tabs[0] && config.tabs[0].origin) || |
| | | (config.subtabs[0] && config.subtabs[0].origin) |
| | | ) { |
| | | isAdd = true |
| | | } |
| | |
| | | if ( |
| | | (config.search[0] && config.search[0].origin) || |
| | | (config.action[0] && config.action[0].origin) || |
| | | (config.columns[0] && config.columns[0].origin) |
| | | (config.columns[0] && config.columns[0].origin) || |
| | | (config.tabs[0] && config.tabs[0].origin) || |
| | | (config.subtabs[0] && config.subtabs[0].origin) |
| | | ) { |
| | | isAdd = true |
| | | } |
| | |
| | | </div> |
| | | <Button type="primary" block onClick={() => this.queryField('columns')}>{this.state.dict['header.menu.column.add']}</Button> |
| | | </Panel> |
| | | <Panel header={this.state.dict['header.menu.tab']} key="4"> |
| | | <div className="search-element"> |
| | | {Source.tabItems.map((item, index) => { |
| | | return (<SourceElement key={index} content={item}/>) |
| | | })} |
| | | </div> |
| | | </Panel> |
| | | </Collapse> |
| | | </div> |
| | | <div className="setting"> |
| | |
| | | </Tooltip> |
| | | {!this.state.searchloading ? |
| | | <DragElement |
| | | list={this.state.config.search} |
| | | type="search" |
| | | placeholder={this.state.dict['header.form.search.placeholder']} |
| | | list={this.state.config.search} |
| | | handleList={this.handleList} |
| | | handleMenu={this.handleSearch} |
| | | deleteMenu={this.deleteElement} |
| | | placeholder={this.state.dict['header.form.search.placeholder']} |
| | | /> : null |
| | | } |
| | | </div> |
| | |
| | | </Tooltip> |
| | | {!this.state.actionloading ? |
| | | <DragElement |
| | | list={this.state.config.action} |
| | | type="action" |
| | | placeholder={this.state.dict['header.form.action.placeholder']} |
| | | list={this.state.config.action} |
| | | handleList={this.handleList} |
| | | handleMenu={this.handleAction} |
| | | copyElement={this.handleAction} |
| | | copyElement={(val) => this.handleAction(val, 'copy')} |
| | | deleteMenu={this.deleteElement} |
| | | placeholder={this.state.dict['header.form.action.placeholder']} |
| | | /> : null |
| | | } |
| | | </div> |
| | |
| | | <Switch checkedChildren="开" unCheckedChildren="关" defaultChecked={this.state.showColumnName} onChange={this.onColumnNameChange} /> |
| | | {!this.state.columnsloading ? |
| | | <DragElement |
| | | type="columns" |
| | | list={this.state.config.columns} |
| | | setting={this.state.config.setting} |
| | | gridBtn={this.state.config.gridBtn} |
| | | type="columns" |
| | | placeholder={this.state.dict['header.form.column.placeholder']} |
| | | handleList={this.handleList} |
| | | handleMenu={this.handleColumn} |
| | | deleteMenu={this.deleteElement} |
| | | handleGridBtn={this.handleGridBtn} |
| | | showfield={this.state.showColumnName} |
| | | placeholder={this.state.dict['header.form.column.placeholder']} |
| | | /> : null |
| | | } |
| | | </div> |
| | | <div className="tab-list"> |
| | | <Tooltip placement="bottomLeft" overlayClassName="middle" title="在左侧工具栏《标签页》中,选择对应类型的标签页拖至此处添加。"> |
| | | <Icon type="question-circle" /> |
| | | </Tooltip> |
| | | {/* {this.state.config.tabs.length > 0 ? <Icon type="setting" onClick={this.changeSetting} /> : null} */} |
| | | {!this.state.tabloading ? |
| | | <TabDragElement |
| | | type="tabs" |
| | | list={this.state.config.tabs} |
| | | setting={this.state.config.setting} |
| | | handleList={this.handleList} |
| | | handleMenu={this.handleTab} |
| | | deleteMenu={this.deleteElement} |
| | | placeholder={this.state.dict['header.form.tab.placeholder']} |
| | | /> : null |
| | | } |
| | | </div> |
| | |
| | | </DndProvider> |
| | | {/* 编辑搜索条件、按钮、显示列 */} |
| | | <Modal |
| | | title={this.state.dict['header.edit']} |
| | | title={this.state.modalTitle} |
| | | visible={this.state.visible} |
| | | width={700} |
| | | onCancel={() => { this.setState({ visible: false }) }} |
| | | // onOk={this.handleSubmit} |
| | | footer={[ |
| | | this.state.formtemp === 'action' ? |
| | | <Button key="delete" className="mk-btn mk-purple" onClick={this.creatFunc} loading={this.state.funcLoading}>{this.state.dict['header.menu.func.create']}</Button> : null, |
| | |
| | | wrappedComponentRef={(inst) => this.formRef = inst} |
| | | /> : null |
| | | } |
| | | {this.state.formtemp === 'tabs' ? |
| | | <TabForm |
| | | type="tabs" |
| | | dict={this.state.dict} |
| | | card={this.state.card} |
| | | formlist={this.state.formlist} |
| | | wrappedComponentRef={(inst) => this.formRef = inst} |
| | | /> : null |
| | | } |
| | | </Modal> |
| | | {/* 根据字段名添加显示列及搜索条件 */} |
| | | <Modal |
| | |
| | | } |
| | | } |
| | | } |
| | | .tab-list { |
| | | position: relative; |
| | | padding: 30px 20px 0px; |
| | | .ant-switch { |
| | | position: absolute; |
| | | right: 20px; |
| | | top: 20px; |
| | | } |
| | | > .ant-row { |
| | | min-height: 47px; |
| | | .page-card { |
| | | position: relative; |
| | | padding: 0px; |
| | | > div { |
| | | padding: 12px 0px 0px; |
| | | cursor: move; |
| | | } |
| | | } |
| | | .ant-tabs-tab { |
| | | .edit { |
| | | position: absolute; |
| | | left: 0; |
| | | top: 0px; |
| | | color: #1890ff; |
| | | cursor: pointer; |
| | | display: none; |
| | | } |
| | | .edit.close { |
| | | left: 20px; |
| | | color: #ff4d4f; |
| | | } |
| | | } |
| | | .ant-tabs-bar { |
| | | min-height: 55px; |
| | | } |
| | | .ant-tabs-tab:hover { |
| | | .edit { |
| | | display: inline-block; |
| | | } |
| | | } |
| | | } |
| | | > .anticon-setting { |
| | | position: absolute; |
| | | font-size: 18px; |
| | | right: 15px; |
| | | top: 30px; |
| | | } |
| | | } |
| | | > .anticon-setting { |
| | | position: absolute; |
| | | font-size: 16px; |
| | | right: 10px; |
| | | font-size: 18px; |
| | | right: 15px; |
| | | top: 10px; |
| | | } |
| | | } |
| | |
| | | style: 'button', |
| | | show: 'horizontal', |
| | | Width: 120 |
| | | } |
| | | }, |
| | | tabs: [ |
| | | { |
| | | origin: true, |
| | | uuid: Utils.getuuid(), |
| | | label: 'tab1', |
| | | icon: '', |
| | | type: 'SubTable', |
| | | linkId: '', |
| | | description: '' |
| | | }, |
| | | { |
| | | origin: true, |
| | | uuid: Utils.getuuid(), |
| | | label: 'tab2', |
| | | icon: '', |
| | | type: 'SubTable', |
| | | linkId: '', |
| | | description: '' |
| | | } |
| | | ], |
| | | subtabs: [] |
| | | } |
| | | |
| | | searchItems = [ |
| | |
| | | url: '' |
| | | } |
| | | ] |
| | | |
| | | tabItems = [ |
| | | { |
| | | type: 'tabs', |
| | | label: CommonDict['header.menu.tab.subtable'], |
| | | subType: 'SubTable', |
| | | } |
| | | ] |
| | | } |
| | | |
| | | export default new CommonTableBaseData() |
New file |
| | |
| | | import React from 'react' |
| | | import { useDrag, useDrop } from 'react-dnd' |
| | | import { Icon } from 'antd' |
| | | import './index.scss' |
| | | |
| | | const Card = ({ id, type, card, moveCard, findCard, editCard, delCard, hasDrop }) => { |
| | | const originalIndex = findCard(id).index |
| | | const [{ isDragging }, drag] = useDrag({ |
| | | item: { type: type, id, originalIndex }, |
| | | collect: monitor => ({ |
| | | isDragging: monitor.isDragging(), |
| | | }), |
| | | }) |
| | | const [, drop] = useDrop({ |
| | | accept: type, |
| | | canDrop: () => true, |
| | | drop: (item) => { |
| | | if (!item.hasOwnProperty('originalIndex')) { |
| | | hasDrop(card) |
| | | } |
| | | }, |
| | | hover({ id: draggedId }) { |
| | | if (!draggedId) return |
| | | if (draggedId !== id) { |
| | | const { index: overIndex } = findCard(id) |
| | | moveCard(draggedId, overIndex) |
| | | } |
| | | }, |
| | | }) |
| | | const opacity = isDragging ? 0 : 1 |
| | | |
| | | return ( |
| | | <div className="page-card" style={{ opacity: opacity}}> |
| | | <div ref={node => drag(drop(node))}> |
| | | {card.icon ? <Icon type={card.icon} /> : null} |
| | | {card.label} |
| | | </div> |
| | | </div> |
| | | ) |
| | | } |
| | | export default Card |
New file |
| | |
| | | import React, { useState } from 'react' |
| | | import { useDrop } from 'react-dnd' |
| | | import update from 'immutability-helper' |
| | | import { Tabs, Icon } from 'antd' |
| | | import Utils from '@/utils/utils.js' |
| | | import Card from './card' |
| | | import './index.scss' |
| | | |
| | | const { TabPane } = Tabs |
| | | |
| | | const Container = ({list, type, setting, placeholder, handleList, handleMenu, deleteMenu }) => { |
| | | let target = null |
| | | const [cards, setCards] = useState(list) |
| | | const moveCard = (id, atIndex) => { |
| | | const { card, index } = findCard(id) |
| | | const _cards = update(cards, { $splice: [[index, 1], [atIndex, 0, card]] }) |
| | | setCards(_cards) |
| | | handleList(type, _cards) |
| | | } |
| | | |
| | | const findCard = id => { |
| | | const card = cards.filter(c => `${c.uuid}` === id)[0] |
| | | return { |
| | | card, |
| | | index: cards.indexOf(card), |
| | | } |
| | | } |
| | | |
| | | const hasDrop = (item) => { |
| | | target = item |
| | | } |
| | | |
| | | const [, drop] = useDrop({ |
| | | accept: type, |
| | | drop(item) { |
| | | if (item.hasOwnProperty('originalIndex')) { |
| | | return |
| | | } |
| | | |
| | | let newcard = {} |
| | | |
| | | newcard.uuid = Utils.getuuid() |
| | | newcard.label = 'tab' |
| | | newcard.icon = '' |
| | | newcard.type = item.subType |
| | | newcard.linkId = '' |
| | | newcard.description = '' |
| | | |
| | | let targetId = cards.length > 0 ? cards[cards.length - 1].uuid : 0 |
| | | if (target) { |
| | | targetId = target.uuid |
| | | } |
| | | |
| | | const { index: overIndex } = findCard(`${targetId}`) |
| | | let targetIndex = overIndex |
| | | if (!target) { |
| | | targetIndex++ |
| | | } |
| | | if (targetIndex < 0) { |
| | | targetIndex = 0 |
| | | } |
| | | |
| | | const _cards = update(cards, { $splice: [[targetIndex, 0, newcard]] }) |
| | | setCards(_cards) |
| | | handleList(type, _cards, newcard) |
| | | target = null |
| | | } |
| | | }) |
| | | |
| | | const edit = (card) => { |
| | | handleMenu(card) |
| | | } |
| | | |
| | | const del = (card) => { |
| | | deleteMenu({card: card, type: type}) |
| | | } |
| | | |
| | | return ( |
| | | <div ref={drop} className="ant-row"> |
| | | <Tabs defaultActiveKey="0" tabPosition="top"> |
| | | {cards.map((card, index) => ( |
| | | <TabPane tab={ |
| | | <div key={card.uuid}> |
| | | <Card |
| | | key={card.uuid} |
| | | id={`${card.uuid}`} |
| | | type={type} |
| | | card={card} |
| | | moveCard={moveCard} |
| | | findCard={findCard} |
| | | hasDrop={hasDrop} |
| | | /> |
| | | <Icon className="edit" type="edit" onClick={() => edit(card)} /> |
| | | <Icon className="edit close" type="close" onClick={() => del(card)} /> |
| | | </div> |
| | | } key={`${index}`}> |
| | | {card.description} |
| | | </TabPane> |
| | | ))} |
| | | </Tabs> |
| | | {cards.length === 0 ? |
| | | <div className="commontab-drawarea-placeholder"> |
| | | {placeholder} |
| | | </div> : null |
| | | } |
| | | </div> |
| | | ) |
| | | } |
| | | export default Container |
New file |
| | |
| | | .common-source-item { |
| | | display: block; |
| | | box-shadow: 0px 0px 2px #bcbcbc; |
| | | padding: 0.4rem 0.7rem; |
| | | background-color: white; |
| | | margin: 0px 0px 10px; |
| | | cursor: move; |
| | | border-radius: 4px; |
| | | } |
| | | .commontab-drawarea-placeholder { |
| | | position: absolute; |
| | | top: 25px; |
| | | left: calc(50% - 50px); |
| | | color: #bcbcbc; |
| | | } |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { Form, Row, Col, Input, Select, Icon } from 'antd' |
| | | import './index.scss' |
| | | |
| | | |
| | | class MainTab extends Component { |
| | | static propTpyes = { |
| | | type: PropTypes.string, // 类型 |
| | | dict: PropTypes.object, // 字典项 |
| | | formlist: PropTypes.any, // 表单 |
| | | card: PropTypes.object // 标签页信息 |
| | | } |
| | | |
| | | state = { |
| | | formlist: null // 表单 |
| | | } |
| | | |
| | | /** |
| | | * @description 表单预处理 |
| | | */ |
| | | UNSAFE_componentWillMount () { |
| | | const { formlist } = this.props |
| | | let type = formlist.filter(cell => cell.key === 'type')[0].initVal |
| | | console.log(type) |
| | | |
| | | this.setState({ |
| | | formlist: formlist |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 标签页类型切换 |
| | | */ |
| | | openTypeChange = (key, value) => { |
| | | console.log(value) |
| | | // if (key === 'type') { |
| | | // console.log(value) |
| | | |
| | | // this.setState({ |
| | | // formlist: this.state.formlist.map(form => { |
| | | // return form |
| | | // }) |
| | | // }, () => { |
| | | // this.setState({ |
| | | // formlist: this.state.formlist.map(form => { |
| | | // return form |
| | | // }) |
| | | // }) |
| | | // }) |
| | | // } |
| | | } |
| | | |
| | | getFields() { |
| | | const { getFieldDecorator } = this.props.form |
| | | const fields = [] |
| | | |
| | | this.state.formlist.forEach((item, index) => { |
| | | if (item.hidden) return |
| | | |
| | | if (item.type === 'text') { // 文本搜索 |
| | | fields.push( |
| | | <Col span={12} key={index}> |
| | | <Form.Item label={item.label}> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal, |
| | | rules: [ |
| | | { |
| | | required: !!item.required, |
| | | message: this.props.dict['form.required.input'] + item.label + '!' |
| | | } |
| | | ] |
| | | })(<Input placeholder="" autoComplete="off" disabled={item.readonly} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'select') { // 下拉搜索 |
| | | fields.push( |
| | | <Col span={12} key={index}> |
| | | <Form.Item label={item.label}> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal, |
| | | rules: [ |
| | | { |
| | | required: !!item.required, |
| | | message: this.props.dict['form.required.select'] + item.label + '!' |
| | | } |
| | | ] |
| | | })( |
| | | <Select |
| | | showSearch |
| | | filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} |
| | | onChange={(value) => {this.openTypeChange(item.key, value)}} |
| | | > |
| | | {item.options.map((option, i) => |
| | | <Select.Option id={`${i}`} title={option.text} key={`${i}`} value={option.value}> |
| | | {item.key === 'icon' && i !== 0 ? <Icon type={option.text} /> : option.text} |
| | | </Select.Option> |
| | | )} |
| | | </Select> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } |
| | | }) |
| | | |
| | | return fields |
| | | } |
| | | |
| | | handleConfirm = () => { |
| | | // 表单提交时检查输入值是否正确 |
| | | return new Promise((resolve, reject) => { |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | | if (!err) { |
| | | |
| | | values.uuid = this.props.card.uuid |
| | | |
| | | resolve({ |
| | | type: this.props.type, |
| | | values |
| | | }) |
| | | } else { |
| | | reject(err) |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | render() { |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 8 } |
| | | }, |
| | | wrapperCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 16 } |
| | | } |
| | | } |
| | | return ( |
| | | <Form {...formItemLayout} className="ant-advanced-search-form commontable-tab-form"> |
| | | <Row gutter={24}>{this.getFields()}</Row> |
| | | </Form> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default Form.create()(MainTab) |
New file |
| | |
| | | .ant-advanced-search-form.commontable-tab-form { |
| | | min-height: 180px; |
| | | } |
| | |
| | | .modal-source-item { |
| | | display: block; |
| | | box-shadow: 0px 0px 2px #bcbcbc; |
| | | padding: 0.5rem 1rem; |
| | | padding: 0.4rem 0.7rem; |
| | | background-color: white; |
| | | margin: 0px 0px 10px; |
| | | cursor: move; |
| | |
| | | <Col span={12}> |
| | | <Form.Item label="挂载对象"> |
| | | {getFieldDecorator('container', { |
| | | initialValue: config.setting.container || 'view' |
| | | initialValue: config.setting.container || 'tab' |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="view">页面</Radio> |
| | |
| | | title: '', |
| | | width: 60, |
| | | cols: '2', |
| | | container: 'view', |
| | | container: 'tab', |
| | | focus: '', |
| | | finish: 'close', |
| | | clickouter: 'unclose' |
| | |
| | | item.value = item.value ? [moment().subtract(item.value * 7, 'days').startOf('week').format('YYYY-MM-DD'), |
| | | moment().subtract(item.value * 7, 'days').endOf('week').format('YYYY-MM-DD')] : '' |
| | | } else if (item.type === 'daterange') { |
| | | item.value = item.value ? [moment().subtract(item.value, 'days').format('YYYY-MM-DD'), |
| | | moment().subtract(item.value === 1 ? 1 : 0, 'days').format('YYYY-MM-DD')] : '' |
| | | let _val = item.value |
| | | if (_val) { |
| | | try { |
| | | _val = JSON.parse(_val) |
| | | } catch { |
| | | _val = '' |
| | | } |
| | | } |
| | | item.value = _val ? [moment().subtract(_val[0], 'days').format('YYYY-MM-DD'), |
| | | moment().subtract(_val[1], 'days').format('YYYY-MM-DD')] : '' |
| | | } |
| | | newsearches.push(item) |
| | | }) |
| | |
| | | @PageSize nvarchar(50)='', |
| | | @OrderCol nvarchar(50)='', |
| | | @OrderType nvarchar(50)='', |
| | | @exceltype nvarchar(50)='', |
| | | @sEPTMenuNo nvarchar(50)='${menu.MenuNo}', |
| | | @lang nvarchar(50)='', |
| | | @debug nvarchar(50)='', |
| | |
| | | BEGIN TRAN |
| | | /*具体业务操作*/ |
| | | |
| | | /* |
| | | /* |
| | | select top 10 * from sProcExcep order by id desc |
| | | |
| | | declare @UserName nvarchar(50),@FullName nvarchar(50) |
| | |
| | | RAISERROR(@ErrorMessage, /*-- Message text.*/ |
| | | @ErrorSeverity, /*-- Severity.*/ |
| | | @ErrorState /*-- State.*/ |
| | | ); |
| | | ); |
| | | END CATCH |
| | | |
| | | GOTO_RETURN: |
| | |
| | | BEGIN TRAN |
| | | /*具体业务操作*/ |
| | | |
| | | /* |
| | | /* |
| | | select top 10 * from sProcExcep order by id desc |
| | | |
| | | declare @UserName nvarchar(50),@FullName nvarchar(50) |
| | |
| | | RAISERROR(@ErrorMessage, /*-- Message text.*/ |
| | | @ErrorSeverity, /*-- Severity.*/ |
| | | @ErrorState /*-- State.*/ |
| | | ); |
| | | ); |
| | | END CATCH |
| | | |
| | | GOTO_RETURN: |