25个文件已修改
10个文件已添加
4个文件已删除
| | |
| | | } |
| | | } |
| | | }, |
| | | "adler-32": { |
| | | "version": "1.2.0", |
| | | "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.2.0.tgz", |
| | | "integrity": "sha1-aj5r8KY5ALoVZSgIyxXGgT0aXyU=", |
| | | "requires": { |
| | | "exit-on-epipe": "1.0.1", |
| | | "printj": "1.1.2" |
| | | } |
| | | }, |
| | | "agentframework": { |
| | | "version": "0.9.22", |
| | | "resolved": "https://registry.npmjs.org/agentframework/-/agentframework-0.9.22.tgz", |
| | |
| | | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", |
| | | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" |
| | | }, |
| | | "cfb": { |
| | | "version": "1.1.3", |
| | | "resolved": "https://registry.npmjs.org/cfb/-/cfb-1.1.3.tgz", |
| | | "integrity": "sha512-joXBW0nMuwV9no7UTMiyVJnQL6XIU3ThXVjFUDHgl9MpILPOomyfaGqC290VELZ48bbQKZXnQ81UT5HouTxHsw==", |
| | | "requires": { |
| | | "adler-32": "1.2.0", |
| | | "commander": "2.20.0", |
| | | "crc-32": "1.2.0", |
| | | "printj": "1.1.2" |
| | | } |
| | | }, |
| | | "chalk": { |
| | | "version": "2.4.2", |
| | | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", |
| | |
| | | "version": "1.1.0", |
| | | "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", |
| | | "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" |
| | | }, |
| | | "codepage": { |
| | | "version": "1.14.0", |
| | | "resolved": "https://registry.npmjs.org/codepage/-/codepage-1.14.0.tgz", |
| | | "integrity": "sha1-jL4lSBMjVZ19MHVxsP/5HnodL5k=", |
| | | "requires": { |
| | | "commander": "2.14.1", |
| | | "exit-on-epipe": "1.0.1" |
| | | }, |
| | | "dependencies": { |
| | | "commander": { |
| | | "version": "2.14.1", |
| | | "resolved": "https://registry.npmjs.org/commander/-/commander-2.14.1.tgz", |
| | | "integrity": "sha512-+YR16o3rK53SmWHU3rEM3tPAh2rwb1yPcQX5irVn7mb0gXbwuCCrnkbV5+PBfETdfg1vui07nM6PCG1zndcjQw==" |
| | | } |
| | | } |
| | | }, |
| | | "collection-visit": { |
| | | "version": "1.0.0", |
| | |
| | | "is-directory": "0.3.1", |
| | | "js-yaml": "3.13.1", |
| | | "parse-json": "4.0.0" |
| | | } |
| | | }, |
| | | "crc-32": { |
| | | "version": "1.2.0", |
| | | "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.0.tgz", |
| | | "integrity": "sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==", |
| | | "requires": { |
| | | "exit-on-epipe": "1.0.1", |
| | | "printj": "1.1.2" |
| | | } |
| | | }, |
| | | "create-ecdh": { |
| | |
| | | "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", |
| | | "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=" |
| | | }, |
| | | "exit-on-epipe": { |
| | | "version": "1.0.1", |
| | | "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", |
| | | "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==" |
| | | }, |
| | | "expand-brackets": { |
| | | "version": "2.1.4", |
| | | "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", |
| | |
| | | "version": "0.1.2", |
| | | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", |
| | | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" |
| | | }, |
| | | "frac": { |
| | | "version": "1.1.2", |
| | | "resolved": "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz", |
| | | "integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==" |
| | | }, |
| | | "fragment-cache": { |
| | | "version": "0.2.1", |
| | |
| | | } |
| | | } |
| | | }, |
| | | "printj": { |
| | | "version": "1.1.2", |
| | | "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz", |
| | | "integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==" |
| | | }, |
| | | "private": { |
| | | "version": "0.1.8", |
| | | "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", |
| | |
| | | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", |
| | | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" |
| | | }, |
| | | "ssf": { |
| | | "version": "0.10.2", |
| | | "resolved": "https://registry.npmjs.org/ssf/-/ssf-0.10.2.tgz", |
| | | "integrity": "sha512-rDhAPm9WyIsY8eZEKyE8Qsotb3j/wBdvMWBUsOhJdfhKGLfQidRjiBUV0y/MkyCLiXQ38FG6LWW/VYUtqlIDZQ==", |
| | | "requires": { |
| | | "frac": "1.1.2" |
| | | } |
| | | }, |
| | | "sshpk": { |
| | | "version": "1.16.1", |
| | | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", |
| | |
| | | "async-limiter": "1.0.1" |
| | | } |
| | | }, |
| | | "xlsx": { |
| | | "version": "0.15.5", |
| | | "resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.15.5.tgz", |
| | | "integrity": "sha512-iWyTqe6UGTkp3XQOeeKPEBcZvmBfzIo3hDIVDfhGIEoTGVIq2JWEk6tIx0F+oKUje3pfZUx4V1W+P6892AB8kQ==", |
| | | "requires": { |
| | | "adler-32": "1.2.0", |
| | | "cfb": "1.1.3", |
| | | "codepage": "1.14.0", |
| | | "commander": "2.17.1", |
| | | "crc-32": "1.2.0", |
| | | "exit-on-epipe": "1.0.1", |
| | | "ssf": "0.10.2" |
| | | }, |
| | | "dependencies": { |
| | | "commander": { |
| | | "version": "2.17.1", |
| | | "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", |
| | | "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==" |
| | | } |
| | | } |
| | | }, |
| | | "xml-name-validator": { |
| | | "version": "3.0.0", |
| | | "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", |
| | |
| | | "webpack": "4.39.1", |
| | | "webpack-dev-server": "3.2.1", |
| | | "webpack-manifest-plugin": "2.0.4", |
| | | "workbox-webpack-plugin": "4.3.1" |
| | | "workbox-webpack-plugin": "4.3.1", |
| | | "xlsx": "^0.15.5" |
| | | }, |
| | | "scripts": { |
| | | "dev": "set PORT=3001 && node scripts/start.js", |
| | |
| | | 'main.action.primarykey.repetition': 'There are multiple primary keys!', |
| | | 'main.action.primarykey.repetitionbid': 'There are multiple BID!', |
| | | 'main.column.operation': '操作', |
| | | 'main.excel.line': '行', |
| | | 'main.excel.column': '列', |
| | | 'main.excel.includekey': '含有关键字', |
| | | 'main.excel.content.emptyerror': '内容不可为空', |
| | | 'main.excel.content.typeerror': '内容应为数值', |
| | | 'main.excel.content.interror': '内容应为整数', |
| | | 'main.excel.content.floaterror': '内容应为浮点数', |
| | | 'main.excel.content.floatIntover': '整数位超出范围', |
| | | 'main.excel.content.floatPointover': '小数位超出范围', |
| | | 'main.excel.content.maxlimit': '内容超长', |
| | | 'main.excel.content.limitmin': '小于最小值', |
| | | 'main.excel.content.limitmax': '大于最大值', |
| | | 'form.required.input': 'Please input ', |
| | | 'form.required.select': 'Please select ' |
| | | } |
| | |
| | | 'main.action.primarykey.repetitionbid': '存在多个BID!', |
| | | 'main.column.operation': '操作', |
| | | 'main.view.unenabled': '抱歉,你访问的页面未启用,请联系管理员。', |
| | | 'main.excel.line': '行', |
| | | 'main.excel.column': '列', |
| | | 'main.excel.includekey': '含有关键字', |
| | | 'main.excel.content.emptyerror': '内容不可为空', |
| | | 'main.excel.content.typeerror': '内容应为数值', |
| | | 'main.excel.content.interror': '内容应为整数', |
| | | 'main.excel.content.floaterror': '内容应为浮点数', |
| | | 'main.excel.content.floatIntover': '整数位超出范围', |
| | | 'main.excel.content.floatPointover': '小数位超出范围', |
| | | 'main.excel.content.maxlimit': '内容超长', |
| | | 'main.excel.content.limitmin': '小于最小值', |
| | | 'main.excel.content.limitmax': '大于最大值', |
| | | 'form.required.input': '请输入', |
| | | 'form.required.select': '请选择' |
| | | } |
| | |
| | | import './index.scss' |
| | | |
| | | const SubTabTable = asyncComponent(() => import('@/tabviews/subtabtable')) |
| | | const FormTab = asyncComponent(() => import('@/tabviews/formtab')) |
| | | const { TabPane } = Tabs |
| | | |
| | | class NormalTable extends Component { |
| | |
| | | state = { |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | ContainerId: Utils.getuuid(), // 菜单外层html Id |
| | | view: 'commontable', // 当前页面默认为主表 |
| | | loadingview: true, // 页面加载中 |
| | | viewlost: false, // 页面丢失:1、未获取到配置-页面丢失;2、页面未启用 |
| | | lostmsg: '', // 页面丢失时的提示信息 |
| | |
| | | */ |
| | | reloadview = () => { |
| | | this.setState({ |
| | | view: 'commontable', |
| | | loadingview: true, |
| | | viewlost: false, |
| | | lostmsg: '', |
| | |
| | | tabs.splice(index + 1, 0, newtab) |
| | | |
| | | this.props.modifyTabview(tabs) |
| | | } else if (btn.OpenType === 'blank') { |
| | | this.setState({ |
| | | view: 'formtab', |
| | | tabBtn: btn, |
| | | tabParam: { |
| | | btn: btn, |
| | | data: data, |
| | | arr_field: this.state.arr_field |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | render() { |
| | | const { setting, searchlist, actions, columns, loadingview, viewlost, setsingle, pickup, isLinkMain, config } = this.state |
| | | const { view, setting, searchlist, actions, columns, loadingview, viewlost, setsingle, pickup, isLinkMain, config } = this.state |
| | | |
| | | return ( |
| | | <div className={'commontable ' + (isLinkMain ? 'pick-control' : '')} id={this.state.ContainerId}> |
| | | {loadingview && <Spin size="large" />} |
| | | {searchlist && searchlist.length > 0 ? |
| | | <MainSearch |
| | | dict={this.state.dict} |
| | | searchlist={searchlist} |
| | | refreshdata={this.refreshbysearch} |
| | | /> : null |
| | | } |
| | | {actions && setting.onload !== 'false' ? |
| | | <MainAction |
| | | ref="mainButton" |
| | | BID="" |
| | | type="main" |
| | | setting={setting} |
| | | actions={actions} |
| | | dict={this.state.dict} |
| | | MenuID={this.props.MenuID} |
| | | logcolumns={this.state.logcolumns} |
| | | ContainerId={this.state.ContainerId} |
| | | refreshdata={this.refreshbyaction} |
| | | triggerPopview={this.triggerPopview} |
| | | gettableselected={this.gettableselected} |
| | | /> : null |
| | | } |
| | | {columns && setting.onload !== 'false' ? |
| | | <div className="main-table-box"> |
| | | {isLinkMain ? |
| | | <div className="pickchange"> |
| | | {setting.tableType === 'checkbox' ? <Switch title="单选切换" checkedChildren="单" unCheckedChildren="多" defaultChecked={setsingle} onChange={this.checkChange} /> : null} |
| | | {this.state.BIDs.mainTable && (setting.tableType === 'radio' || setsingle) ? <Switch title="收起" checkedChildren="开" unCheckedChildren="关" defaultChecked={pickup} onChange={this.pickupChange} /> : null} |
| | | </div> : null |
| | | } |
| | | <MainTable |
| | | ref="mainTable" |
| | | pickup={pickup} |
| | | setting={setting} |
| | | columns={columns} |
| | | setsingle={setsingle} |
| | | <div> |
| | | {view === 'commontable' ? <div className={'commontable ' + (isLinkMain ? 'pick-control' : '')} id={this.state.ContainerId}> |
| | | {loadingview && <Spin size="large" />} |
| | | {searchlist && searchlist.length > 0 ? |
| | | <MainSearch |
| | | dict={this.state.dict} |
| | | data={this.state.data} |
| | | total={this.state.total} |
| | | searchlist={searchlist} |
| | | refreshdata={this.refreshbysearch} |
| | | /> : null |
| | | } |
| | | {actions && setting.onload !== 'false' ? |
| | | <MainAction |
| | | ref="mainButton" |
| | | BID="" |
| | | type="main" |
| | | setting={setting} |
| | | actions={actions} |
| | | dict={this.state.dict} |
| | | MenuID={this.props.MenuID} |
| | | loading={this.state.loading} |
| | | refreshdata={this.refreshbytable} |
| | | buttonTrigger={this.buttonTrigger} |
| | | handleTableId={this.handleTableId} |
| | | /> |
| | | </div> : null |
| | | } |
| | | {setting && setting.onload !== 'false' && |
| | | config.tabgroups.map(group => { |
| | | if (config[group].length === 0) return null |
| | | logcolumns={this.state.logcolumns} |
| | | ContainerId={this.state.ContainerId} |
| | | refreshdata={this.refreshbyaction} |
| | | triggerPopview={this.triggerPopview} |
| | | gettableselected={this.gettableselected} |
| | | /> : null |
| | | } |
| | | {columns && setting.onload !== 'false' ? |
| | | <div className="main-table-box"> |
| | | {isLinkMain ? |
| | | <div className="pickchange"> |
| | | {setting.tableType === 'checkbox' ? <Switch title="单选切换" checkedChildren="单" unCheckedChildren="多" defaultChecked={setsingle} onChange={this.checkChange} /> : null} |
| | | {this.state.BIDs.mainTable && (setting.tableType === 'radio' || setsingle) ? <Switch title="收起" checkedChildren="开" unCheckedChildren="关" defaultChecked={pickup} onChange={this.pickupChange} /> : null} |
| | | </div> : null |
| | | } |
| | | <MainTable |
| | | ref="mainTable" |
| | | pickup={pickup} |
| | | setting={setting} |
| | | columns={columns} |
| | | setsingle={setsingle} |
| | | dict={this.state.dict} |
| | | data={this.state.data} |
| | | total={this.state.total} |
| | | MenuID={this.props.MenuID} |
| | | loading={this.state.loading} |
| | | refreshdata={this.refreshbytable} |
| | | buttonTrigger={this.buttonTrigger} |
| | | handleTableId={this.handleTableId} |
| | | /> |
| | | </div> : null |
| | | } |
| | | {setting && setting.onload !== 'false' && |
| | | config.tabgroups.map(group => { |
| | | if (config[group].length === 0) return null |
| | | |
| | | return ( |
| | | <Tabs defaultActiveKey="0" key={group}> |
| | | {config[group].map((_tab, index) => { |
| | | return ( |
| | | <TabPane tab={ |
| | | <span> |
| | | {_tab.icon ? <Icon type={_tab.icon} /> : null} |
| | | {_tab.label} |
| | | </span> |
| | | } key={`${index}`}> |
| | | {_tab.type === 'SubTable' ? |
| | | <SubTable |
| | | Tab={_tab} |
| | | MenuID={_tab.linkTab} |
| | | SupMenuID={this.props.MenuID} |
| | | ContainerId={this.state.ContainerId} |
| | | BID={this.state.BIDs[_tab.supMenu] || ''} |
| | | BData={this.state.BIDs[_tab.supMenu + 'data'] || ''} |
| | | handleTableId={this.handleTableId} |
| | | handleMainTable={this.handleMainTable} |
| | | /> : null} |
| | | </TabPane> |
| | | ) |
| | | })} |
| | | </Tabs> |
| | | ) |
| | | }) |
| | | } |
| | | <Modal |
| | | className="popview-modal" |
| | | title={this.state.popAction.label} |
| | | width={'80vw'} |
| | | maskClosable={false} |
| | | visible={this.state.visible} |
| | | onCancel={this.popclose} |
| | | footer={[ |
| | | <Button key="cancel" onClick={this.popclose}>{this.state.dict['main.close']}</Button> |
| | | ]} |
| | | destroyOnClose |
| | | > |
| | | {<SubTabTable |
| | | BID={''} |
| | | SupMenuID={this.props.MenuID} |
| | | MenuID={this.state.popAction.linkTab} |
| | | BData={this.state.BIDs['mainTabledata'] || ''} |
| | | ContainerId={this.state.ContainerId} |
| | | ID={this.state.popData ? this.state.popData[setting.primaryKey] : ''} |
| | | refreshSupView={this.reloadtable} |
| | | />} |
| | | </Modal> |
| | | <BackTop> |
| | | <div className="ant-back-top"> |
| | | <div className="ant-back-top-content"> |
| | | <div className="ant-back-top-icon"></div> |
| | | return ( |
| | | <Tabs defaultActiveKey="0" key={group}> |
| | | {config[group].map((_tab, index) => { |
| | | return ( |
| | | <TabPane tab={ |
| | | <span> |
| | | {_tab.icon ? <Icon type={_tab.icon} /> : null} |
| | | {_tab.label} |
| | | </span> |
| | | } key={`${index}`}> |
| | | {_tab.type === 'SubTable' ? |
| | | <SubTable |
| | | Tab={_tab} |
| | | MenuID={_tab.linkTab} |
| | | SupMenuID={this.props.MenuID} |
| | | ContainerId={this.state.ContainerId} |
| | | BID={this.state.BIDs[_tab.supMenu] || ''} |
| | | BData={this.state.BIDs[_tab.supMenu + 'data'] || ''} |
| | | handleTableId={this.handleTableId} |
| | | handleMainTable={this.handleMainTable} |
| | | /> : null} |
| | | </TabPane> |
| | | ) |
| | | })} |
| | | </Tabs> |
| | | ) |
| | | }) |
| | | } |
| | | <Modal |
| | | className="popview-modal" |
| | | title={this.state.popAction.label} |
| | | width={'80vw'} |
| | | maskClosable={false} |
| | | visible={this.state.visible} |
| | | onCancel={this.popclose} |
| | | footer={[ |
| | | <Button key="cancel" onClick={this.popclose}>{this.state.dict['main.close']}</Button> |
| | | ]} |
| | | destroyOnClose |
| | | > |
| | | {<SubTabTable |
| | | BID={''} |
| | | SupMenuID={this.props.MenuID} |
| | | MenuID={this.state.popAction.linkTab} |
| | | BData={this.state.BIDs['mainTabledata'] || ''} |
| | | ContainerId={this.state.ContainerId} |
| | | ID={this.state.popData ? this.state.popData[setting.primaryKey] : ''} |
| | | refreshSupView={this.reloadtable} |
| | | />} |
| | | </Modal> |
| | | <BackTop> |
| | | <div className="ant-back-top"> |
| | | <div className="ant-back-top-content"> |
| | | <div className="ant-back-top-icon"></div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </BackTop> |
| | | {viewlost ? <NotFount msg={this.state.lostmsg} /> : null} |
| | | </BackTop> |
| | | {viewlost ? <NotFount msg={this.state.lostmsg} /> : null} |
| | | </div> : null} |
| | | {view === 'formtab' ? <FormTab MenuID={this.state.tabBtn.uuid} param={this.state.tabParam}/> : null} |
| | | </div> |
| | | ) |
| | | } |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import moment from 'moment' |
| | | import { Button, Modal, notification, Spin, message } from 'antd' |
| | | import { Button, Modal, notification, message } from 'antd' |
| | | import Utils from '@/utils/utils.js' |
| | | import Api from '@/api' |
| | | import './index.scss' |
| | |
| | | |
| | | class MainAction extends Component { |
| | | static propTpyes = { |
| | | BData: PropTypes.any, // 主表数据 |
| | | type: PropTypes.string, // 判断当前为主表(main)、子表(sub)、子表标签(subtab) |
| | | MenuID: PropTypes.string, // 菜单ID |
| | | actions: PropTypes.array, // 按钮组 |
| | | logcolumns: PropTypes.array, // 日志中显示列 |
| | | logcolumns: PropTypes.array, // 显示列 |
| | | dict: PropTypes.object, // 字典项 |
| | | data: PropTypes.any, // 数据 |
| | | setting: PropTypes.any, // 页面通用设置 |
| | | triggerPopview: PropTypes.func // 弹窗标签页触发 |
| | | refreshdata: PropTypes.func, // 执行完成后数据刷新 |
| | | } |
| | | |
| | | state = { |
| | | visible: false, |
| | | formdata: null, |
| | | tabledata: null, |
| | | confirmLoading: false, |
| | | loadingUuid: '', |
| | | btnloading: false |
| | | loadingUuid: '' |
| | | } |
| | | |
| | | /** |
| | | * @description 触发按钮操作 |
| | | */ |
| | | actionTrigger = (item, record) => { |
| | | const { setting } = this.props |
| | | actionTrigger = (item) => { |
| | | const { data } = this.props |
| | | |
| | | let _this = this |
| | | let data = this.props.gettableselected() || [] |
| | | |
| | | if (item.Ot !== 'notRequired' && data.length === 0) { |
| | | // 需要选择行时,校验数据 |
| | | notification.warning({ |
| | | top: 92, |
| | | message: this.props.dict['main.action.confirm.selectline'], |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } else if (item.Ot === 'requiredSgl' && data.length !== 1) { |
| | | // 需要选择单行时,校验数据 |
| | | notification.warning({ |
| | | top: 92, |
| | | message: this.props.dict['main.action.confirm.selectSingleLine'], |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } else if (item.Ot !== 'notRequired' && !setting.primaryKey) { |
| | | // 需要选择行时,校验是否设置主键 |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '未设置主键!', |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | if (item.OpenType === 'prompt') { |
| | | confirm({ |
| | |
| | | this.setState({loadingUuid: item.uuid}) |
| | | this.execSubmit(item, data, () => { |
| | | this.setState({loadingUuid: ''}) |
| | | }) |
| | | } else if (item.OpenType === 'pop') { |
| | | this.setState({ |
| | | tabledata: data, |
| | | btnloading: true |
| | | }) |
| | | } else { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '完善中。。。', |
| | | duration: 10 |
| | | }) |
| | | } |
| | | } |
| | |
| | | } else if (res && res.ErrCode === '-1') { // 完成后不提示 |
| | | |
| | | } |
| | | |
| | | if (btn.OpenType === 'pop' && btn.setting && btn.setting.finish !== 'unclose') { |
| | | this.setState({ |
| | | visible: false |
| | | }) |
| | | } |
| | | |
| | | this.props.refreshdata(btn, 'success') |
| | | } |
| | |
| | | |
| | | |
| | | render() { |
| | | const { loadingUuid, btnloading } = this.state |
| | | const { loadingUuid } = this.state |
| | | |
| | | return ( |
| | | <div className="button-list toolbar-button"> |
| | | <div className="button-list formtab-button"> |
| | | {this.props.actions.map((item, index) => { |
| | | if (loadingUuid === item.uuid) { |
| | | return ( |
| | |
| | | ) |
| | | } |
| | | })} |
| | | <Button |
| | | className={'mk-btn'} |
| | | // icon={item.icon} |
| | | onClick={() => {this.actionTrigger()}} |
| | | >确定</Button> |
| | | <Button |
| | | className={'mk-btn'} |
| | | // icon={item.icon} |
| | | onClick={() => {this.actionTrigger()}} |
| | | >返回</Button> |
| | | {btnloading && <Spin size="large" />} |
| | | </div> |
| | | ) |
| | | } |
| | |
| | | .button-list.toolbar-button { |
| | | padding: 10px 20px 5px; |
| | | .button-list.formtab-button { |
| | | padding: 20px 20px 10px; |
| | | background: #ffffff; |
| | | button { |
| | | min-width: 65px; |
| | |
| | | top: calc(50vh - 70px); |
| | | } |
| | | } |
| | | // 设置模态框样式,规定最大最小高度,重置滚动条 |
| | | .action-modal { |
| | | .ant-modal { |
| | | max-width: 95vw; |
| | | } |
| | | .ant-modal-body { |
| | | max-height: calc(100vh - 235px); |
| | | min-height: 150px; |
| | | overflow-y: auto; |
| | | padding-bottom: 35px; |
| | | } |
| | | .ant-modal-body::-webkit-scrollbar { |
| | | width: 10px; |
| | | height: 10px; |
| | | } |
| | | .ant-modal-body::-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); |
| | | } |
| | | .ant-modal-body::-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); |
| | | } |
| | | } |
| | |
| | | |
| | | class NormalTable extends Component { |
| | | static propTpyes = { |
| | | MenuNo: PropTypes.string, // 菜单参数 |
| | | MenuName: PropTypes.string, // 菜单参数 |
| | | // MenuNo: PropTypes.string, // 菜单参数 |
| | | // MenuName: PropTypes.string, // 菜单参数 |
| | | MenuID: PropTypes.string, // 菜单Id |
| | | param: PropTypes.any // 主表传递参数 |
| | | } |
| | |
| | | } |
| | | |
| | | let _arrField = [] // 字段集 |
| | | |
| | | console.log(this.props.param) |
| | | if (this.props.param && this.props.param.arr_field) { |
| | | _arrField = this.props.param.arr_field |
| | | } else { |
| | |
| | | let _isCustomData = false |
| | | |
| | | if (this.props.param && this.props.param.data) { |
| | | _data = this.props.param.data |
| | | _data = this.props.param.data[0] || null |
| | | } |
| | | |
| | | if ((config.setting.interType === 'inner' && config.setting.innerFunc) || (config.setting.interType === 'outer' && config.setting.interface)) { |
| | |
| | | setting={setting} |
| | | actions={actions} |
| | | dict={this.state.dict} |
| | | data={this.state.data} |
| | | MenuID={this.props.MenuID} |
| | | logcolumns={[]} |
| | | refreshdata={this.refreshbyaction} |
| | |
| | | import moment from 'moment' |
| | | import { Button, Affix, Modal, notification, Spin, message } from 'antd' |
| | | import MutilForm from '@/tabviews/tableshare/mutilform' |
| | | import ExcelIn from '../excelin' |
| | | import Utils from '@/utils/utils.js' |
| | | import Api from '@/api' |
| | | import './index.scss' |
| | |
| | | |
| | | class MainAction extends Component { |
| | | static propTpyes = { |
| | | BID: PropTypes.string, // 主表ID |
| | | BData: PropTypes.any, // 主表数据 |
| | | Tab: PropTypes.any, // 如果当前元素为标签时,tab为标签信息 |
| | | type: PropTypes.string, // 判断当前为主表(main)、子表(sub)、子表标签(subtab) |
| | | MenuID: PropTypes.string, // 菜单ID |
| | | actions: PropTypes.array, // 按钮组 |
| | | logcolumns: PropTypes.array, // 日志中显示列 |
| | | dict: PropTypes.object, // 字典项 |
| | | setting: PropTypes.any, // 页面通用设置 |
| | | ContainerId: PropTypes.any, // tab页面ID,用于弹窗控制 |
| | | triggerPopview: PropTypes.func // 弹窗标签页触发 |
| | | BID: PropTypes.string, // 主表ID |
| | | BData: PropTypes.any, // 主表数据 |
| | | Tab: PropTypes.any, // 如果当前元素为标签时,tab为标签信息 |
| | | type: PropTypes.string, // 判断当前为主表(main)、子表(sub)、子表标签(subtab) |
| | | MenuID: PropTypes.string, // 菜单ID |
| | | actions: PropTypes.array, // 按钮组 |
| | | logcolumns: PropTypes.array, // 日志中显示列 |
| | | dict: PropTypes.object, // 字典项 |
| | | setting: PropTypes.any, // 页面通用设置 |
| | | ContainerId: PropTypes.any, // tab页面ID,用于弹窗控制 |
| | | refreshdata: PropTypes.func, // 执行完成后数据刷新 |
| | | triggerPopview: PropTypes.func, // 弹窗标签页触发 |
| | | gettableselected: PropTypes.func // 获取表格中数据 |
| | | } |
| | | |
| | | state = { |
| | |
| | | } else if (item.OpenType === 'excelOut') { |
| | | this.setState({loadingUuid: item.uuid}) |
| | | this.refreshdata(item, 'excelOut') |
| | | } else if (item.OpenType === 'excelIn') { |
| | | if (item.verify && item.verify.sheet && item.verify.columns && item.verify.columns.length > 0) { |
| | | this.refs.excelIn.exceltrigger(item) |
| | | } else { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: 'excel导入验证信息未设置!', |
| | | duration: 10 |
| | | }) |
| | | } |
| | | } else if (item.OpenType === 'popview' && this.props.type !== 'subtab') { |
| | | this.props.triggerPopview(item, data) |
| | | } else if (item.OpenType === 'popview' && this.props.type === 'subtab') { |
| | |
| | | * 5、通知主列表刷新 |
| | | */ |
| | | execSuccess = (btn, res) => { |
| | | if (btn.OpenType === 'excelOut') { // 导出excel |
| | | if (btn.OpenType === 'excelOut' || btn.OpenType === 'excelIn') { // 导出excel |
| | | this.setState({ |
| | | loadingUuid: '' |
| | | }) |
| | |
| | | message.error(res.message || res.ErrMesg) |
| | | } |
| | | |
| | | if (btn.OpenType === 'excelOut') { |
| | | if (btn.OpenType === 'excelOut' || btn.OpenType === 'excelIn') { |
| | | this.setState({ |
| | | loadingUuid: '' |
| | | }) |
| | |
| | | }) |
| | | } |
| | | |
| | | getexceldata = (data, btn, errors) => { |
| | | if (errors && errors.length > 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: errors.join(',') + '表头设置错误!', |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } |
| | | if (!data || data.length === 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '未获取到excel数据!', |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let result = Utils.getExcelInSql(btn, data, this.props.dict) |
| | | if (result.errors) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: result.errors, |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } |
| | | if (!btn.innerFunc) { |
| | | let param = { // 系统存储过程 |
| | | func: 'sPC_TableData_InUpDe', |
| | | BID: this.props.BID |
| | | } |
| | | |
| | | param.LText = Utils.formatOptions(result.sql) |
| | | param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000' |
| | | param.secretkey = Utils.encrypt(param.LText, param.timestamp) |
| | | |
| | | this.setState({loadingUuid: btn.uuid}) |
| | | |
| | | Api.genericInterface(param).then((res) => { |
| | | if (res.status) { |
| | | this.execSuccess(btn, res) |
| | | } else { |
| | | this.execError(res, btn) |
| | | } |
| | | }) |
| | | } else { |
| | | let param = { // 自定义存储过程 |
| | | func: btn.innerFunc, |
| | | BID: this.props.BID |
| | | } |
| | | |
| | | param.LText = Utils.formatOptions(result.sql) |
| | | param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000' |
| | | param.secretkey = Utils.encrypt(param.LText, param.timestamp) |
| | | |
| | | this.setState({loadingUuid: btn.uuid}) |
| | | |
| | | Api.genericInterface(param).then((res) => { |
| | | if (res.status) { |
| | | this.execSuccess(btn, res) |
| | | } else { |
| | | this.execError(res, btn) |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @description 模态框(表单),确认 |
| | | */ |
| | |
| | | })} |
| | | {this.getModels()} |
| | | {btnloading && <Spin size="large" />} |
| | | <ExcelIn MenuID={this.props.MenuID} returndata={this.getexceldata} ref="excelIn" /> |
| | | </div> |
| | | </Affix> |
| | | ) |
| | |
| | | })} |
| | | {this.getModels()} |
| | | {btnloading && <Spin size="large" />} |
| | | <ExcelIn MenuID={this.props.MenuID} returndata={this.getexceldata} ref="excelIn" /> |
| | | </div> |
| | | ) |
| | | } |
| | |
| | | .button-list.toolbar-button { |
| | | position: relative; |
| | | padding: 10px 20px 5px; |
| | | background: #ffffff; |
| | | button { |
| | | min-width: 65px; |
| | | margin-right: 15px; |
| | | margin-bottom: 10px; |
| | | overflow: hidden; |
| | | } |
| | | .ant-spin { |
| | | position: fixed; |
New file |
| | |
| | | import React, { Component } from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { notification } from 'antd' |
| | | import * as XLSX from 'xlsx' |
| | | import Utils from '@/utils/utils.js' |
| | | import './index.scss' |
| | | |
| | | class ExcelIn extends Component { |
| | | static propTpyes = { |
| | | MenuID: PropTypes.string, // 菜单ID |
| | | returndata: PropTypes.func // 菜单ID |
| | | } |
| | | |
| | | state = { |
| | | excelbtn: null, |
| | | excelId: Utils.getuuid() |
| | | } |
| | | |
| | | exceltrigger = (item) => { |
| | | const { excelId } = this.state |
| | | this.setState({ |
| | | excelbtn: item |
| | | }) |
| | | |
| | | let _excelInput = document.getElementById(excelId + this.props.MenuID) |
| | | |
| | | if (_excelInput) { |
| | | _excelInput.click() |
| | | } |
| | | } |
| | | onImportExcel = file => { |
| | | const { excelbtn } = this.state |
| | | |
| | | let columns = excelbtn.verify.columns.map(option => option.Column) |
| | | let range = excelbtn.verify.range || 0 |
| | | |
| | | // excel数据处理 |
| | | const { files } = file.target |
| | | const fileReader = new FileReader() |
| | | |
| | | fileReader.onload = event => { |
| | | try { |
| | | const { result } = event.target |
| | | // 以二进制流方式读取得到整份excel表格对象 |
| | | const workbook = XLSX.read(result, { type: 'binary' }) |
| | | |
| | | let errors = [] |
| | | if (range === 1) { |
| | | workbook.SheetNames.forEach(sheetname => { |
| | | if (workbook.Sheets.hasOwnProperty(sheetname)) { |
| | | let header = XLSX.utils.sheet_to_json(workbook.Sheets[sheetname], {header: columns})[0] |
| | | |
| | | if (!header) { |
| | | errors.push(sheetname) |
| | | } else { |
| | | let iserror = false |
| | | excelbtn.verify.columns.forEach(op => { |
| | | if (header[op.Column] !== op.Text) { |
| | | iserror = true |
| | | } |
| | | }) |
| | | |
| | | if (iserror) { |
| | | errors.push(sheetname) |
| | | } |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | let data = [] |
| | | |
| | | workbook.SheetNames.forEach(sheetname => { |
| | | if (workbook.Sheets.hasOwnProperty(sheetname)) { |
| | | data = data.concat(XLSX.utils.sheet_to_json(workbook.Sheets[sheetname], {header: columns, range: (range)})) |
| | | } |
| | | }) |
| | | |
| | | // 最终获取到并且格式化后的 json 数据 |
| | | this.props.returndata(data, excelbtn, errors) |
| | | this.setState({ |
| | | excelId: '' |
| | | }, () => { |
| | | this.setState({ |
| | | excelId: Utils.getuuid() |
| | | }) |
| | | }) |
| | | } catch (e) { |
| | | this.setState({ |
| | | excelId: '' |
| | | }, () => { |
| | | this.setState({ |
| | | excelId: Utils.getuuid() |
| | | }) |
| | | }) |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '文件解析错误,请检查文件格式!', |
| | | duration: 10 |
| | | }) |
| | | } |
| | | } |
| | | |
| | | // 以二进制方式打开文件 |
| | | fileReader.readAsBinaryString(files[0]) |
| | | } |
| | | |
| | | render() { |
| | | return ( |
| | | <span> |
| | | {this.state.excelId ? <input className="excel-in-input" id={this.state.excelId + this.props.MenuID} type='file' accept='.xlsx, .xls' onChange={this.onImportExcel} /> : null} |
| | | </span> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default ExcelIn |
New file |
| | |
| | | .excel-in-input { |
| | | position: absolute; |
| | | opacity: 0; |
| | | z-index: -1; |
| | | } |
| | |
| | | _options = ['label', 'Ot', 'OpenType', 'icon', 'class', 'position', 'tabTemplate'] |
| | | } else if (_opentype === 'popview') { // 模态框标签页 |
| | | _options = ['label', 'Ot', 'OpenType', 'icon', 'class', 'position', 'tabType', 'linkTab', 'popClose'] |
| | | } else if (_opentype === 'excelIn' || _opentype === 'excelOut') { // 导入导出 |
| | | } else if (_opentype === 'excelOut') { // 导入导出 |
| | | if (_intertype === 'outer') { |
| | | _options = ['label', 'OpenType', 'intertype', 'innerFunc', 'sysInterface', 'interface', 'outerFunc', 'callbackFunc', 'icon', 'class', 'execSuccess', 'execError', 'method'] |
| | | } else { |
| | | _options = ['label', 'OpenType', 'intertype', 'innerFunc', 'icon', 'class', 'execSuccess', 'execError'] |
| | | } |
| | | } else if (_opentype === 'excelIn') { // 导入导出 |
| | | _options = ['label', 'OpenType', 'intertype', 'innerFunc', 'icon', 'class', 'execSuccess', 'execError'] |
| | | } else { |
| | | if (_intertype === 'outer') { |
| | | _options = ['label', 'position', 'OpenType', 'intertype', 'innerFunc', 'sysInterface', 'interface', 'outerFunc', 'callbackFunc', 'Ot', 'icon', 'class', 'execSuccess', 'execError', 'method'] |
| | |
| | | if (!initTab) { |
| | | item.initVal = '' |
| | | } |
| | | } else if (item.key === 'intertype' && _opentype === 'excelIn') { |
| | | item.initVal = 'inner' |
| | | item.readonly = true |
| | | } |
| | | item.hidden = !_options.includes(item.key) |
| | | return item |
| | |
| | | _options = ['label', 'Ot', 'OpenType', 'icon', 'class', 'position', 'tabTemplate'] |
| | | } else if (value === 'popview') { |
| | | _options = ['label', 'Ot', 'OpenType', 'icon', 'class', 'position', 'tabType', 'linkTab', 'popClose'] |
| | | } else if (value === 'excelIn' || value === 'excelOut') { |
| | | } else if (value === 'excelOut') { |
| | | if (this.state.interType === 'outer') { |
| | | _options = ['label', 'OpenType', 'intertype', 'innerFunc', 'sysInterface', 'interface', 'outerFunc', 'callbackFunc', 'icon', 'class', 'execSuccess', 'execError', 'method'] |
| | | } else { |
| | | _options = ['label', 'OpenType', 'intertype', 'innerFunc', 'icon', 'class', 'execSuccess', 'execError'] |
| | | } |
| | | } else if (value === 'excelIn') { |
| | | _options = ['label', 'OpenType', 'intertype', 'innerFunc', 'icon', 'class', 'execSuccess', 'execError'] |
| | | } else { |
| | | if (this.state.interType === 'inner') { |
| | | _options = ['label', 'position', 'OpenType', 'intertype', 'innerFunc', 'Ot', 'icon', 'class', 'execSuccess', 'execError', 'sql', 'sqlType'] |
| | |
| | | |
| | | if (item.hidden) return item |
| | | |
| | | if (item.key === 'intertype') { |
| | | if (item.key === 'intertype' && value === 'excelIn') { |
| | | _fieldval.intertype = 'inner' |
| | | item.readonly = true |
| | | } else if (item.key === 'intertype' && value !== 'excelIn') { |
| | | _fieldval.intertype = this.state.interType |
| | | item.readonly = false |
| | | } else if (item.key === 'Ot') { |
| | | if (value === 'innerpage' || this.state.position === 'grid') { |
| | | item.options = this.state.reqOptionSgl |
| | |
| | | } |
| | | |
| | | onChange = (e, key) => { |
| | | const { openType } = this.state |
| | | let value = e.target.value |
| | | if (key === 'intertype') { |
| | | let _options = null |
| | | if (value === 'inner') { |
| | | _options = ['label', 'position', 'OpenType', 'intertype', 'innerFunc', 'Ot', 'icon', 'class', 'execSuccess', 'execError', 'sql', 'sqlType'] |
| | | if (openType === 'excelOut') { |
| | | if (value === 'outer') { |
| | | _options = ['label', 'OpenType', 'intertype', 'innerFunc', 'sysInterface', 'interface', 'outerFunc', 'callbackFunc', 'icon', 'class', 'execSuccess', 'execError', 'method'] |
| | | } else { |
| | | _options = ['label', 'OpenType', 'intertype', 'innerFunc', 'icon', 'class', 'execSuccess', 'execError'] |
| | | } |
| | | } else if (openType === 'excelIn') { |
| | | if (value === 'outer') { |
| | | _options = ['label', 'OpenType', 'intertype', 'innerFunc', 'sysInterface', 'interface', 'outerFunc', 'callbackFunc', 'icon', 'class', 'execSuccess', 'execError', 'method'] |
| | | } else { |
| | | _options = ['label', 'OpenType', 'intertype', 'innerFunc', 'icon', 'class', 'execSuccess', 'execError'] |
| | | } |
| | | } else { |
| | | _options = ['label', 'position', 'OpenType', 'intertype', 'innerFunc', 'Ot', 'icon', 'class', 'execSuccess', 'execError', 'sysInterface', 'interface', 'outerFunc', 'callbackFunc', 'method'] |
| | | if (value === 'inner') { |
| | | _options = ['label', 'position', 'OpenType', 'intertype', 'innerFunc', 'Ot', 'icon', 'class', 'execSuccess', 'execError', 'sql', 'sqlType'] |
| | | } else { |
| | | _options = ['label', 'position', 'OpenType', 'intertype', 'innerFunc', 'Ot', 'icon', 'class', 'execSuccess', 'execError', 'sysInterface', 'interface', 'outerFunc', 'callbackFunc', 'method'] |
| | | } |
| | | } |
| | | |
| | | this.setState({ |
| | |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'number') { // 文本搜索 |
| | | } else if (item.type === 'number') { |
| | | fields.push( |
| | | <Col span={12} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | |
| | | </Tooltip> : item.label |
| | | }> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal |
| | | })(<InputNumber min={1} max={10000} precision={0} />)} |
| | | initialValue: item.initVal, |
| | | rules: [ |
| | | { |
| | | required: item.readonly ? false : !!item.required, |
| | | message: this.props.dict['form.required.input'] + item.label + '!' |
| | | } |
| | | ] |
| | | })(<InputNumber min={0} max={10000} precision={0} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | |
| | | } |
| | | ] |
| | | })( |
| | | <Radio.Group onChange={(e) => {this.onChange(e, item.key)}}> |
| | | <Radio.Group onChange={(e) => {this.onChange(e, item.key)}} disabled={item.readonly}> |
| | | { |
| | | item.options.map(option => { |
| | | return ( |
| | |
| | | values.uuid = this.props.card.uuid |
| | | values.verify = this.props.card.verify || null |
| | | |
| | | if (values.OpenType === 'excelIn' || values.OpenType === 'excelOut') { |
| | | if (values.OpenType === 'excelIn') { |
| | | values.position = 'toolbar' |
| | | values.Ot = 'notRequired' |
| | | } else if (values.OpenType === 'excelOut') { |
| | | values.position = 'toolbar' |
| | | values.Ot = 'notRequired' |
| | | } else if (values.OpenType === 'popview' && !values.linkTab) { // 没有关联标签(新建时),创建新标签Id |
| | |
| | | import GridBtnForm from '@/templates/tableshare/gridbtnform' |
| | | import EditCard from '@/templates/tableshare/editcard' |
| | | import VerifyCard from '@/templates/tableshare/verifycard' |
| | | import VerifyCardExcelIn from '@/templates/tableshare/verifycardexcelin' |
| | | import MenuForm from '@/templates/tableshare/menuform' |
| | | import TabDragElement from '@/templates/tableshare/tabdragelement' |
| | | import SourceElement from '@/templates/tableshare/dragelement/source' |
| | |
| | | componentDidMount () { |
| | | let param = { |
| | | func: 'sPC_Get_SelectedList', |
| | | LText: 'select TbName ,Remark from sDataDictionary where IsKey!=\'\' and Deleted =0', |
| | | // LText: 'select TbName ,Remark from sDataDictionary where IsKey!=\'\' and Deleted =0', |
| | | LText: 'select TbName,Remark from (select TbName,Remark from sDataDictb where appkey= @appkey@ and Deleted=0 union select a.TbName,Remark from (select TbName,Remark from sDataDictb where appkey= \'\' and Deleted=0 ) a left join (select TbName from sDataDictb where appkey= @appkey@ and Deleted=0 ) b on a.TbName=b.TbName where b.TbName is null ) t', |
| | | obj_name: 'data', |
| | | arr_field: 'TbName,Remark' |
| | | } |
| | |
| | | const { card } = this.state |
| | | let config = JSON.parse(JSON.stringify(this.state.config)) |
| | | let _verify = this.verifyRef.state.verify |
| | | |
| | | if (card.OpenType !== 'excelIn') { |
| | | if (_verify.default === 'false' && _verify.scripts.length === 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '不执行默认sql时,必须设置自定义脚本!', |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } |
| | | } else if (card.OpenType === 'excelIn') { |
| | | let cols = _verify.columns.map(col => col.Column) |
| | | cols = Array.from(new Set(cols)) |
| | | |
| | | if (!_verify.sheet) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请设置导入表名!', |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } else if (_verify.columns.length === 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请设置Excel列字段!', |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } else if (_verify.columns.length > cols.length) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: 'Excel列字段名,不可重复!', |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } else if (_verify.range === 1) { |
| | | let tEmptys = _verify.columns.filter(op => !op.Text) |
| | | if (tEmptys.length > 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '忽略首行时,会使用Text值校验Excel首行内容,Text值与Excel表首行内容相同,且均不可为空!', |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } |
| | | } |
| | | } |
| | | |
| | | config.action = config.action.map(item => { |
| | | if (item.uuid === card.uuid) { |
| | |
| | | <Modal |
| | | title={modaltype === 'actionEdit' ? this.state.dict['header.modal.action.edit'] : this.state.dict['header.modal.action.copy']} |
| | | visible={modaltype === 'actionEdit' || modaltype === 'actionCopy'} |
| | | width={700} |
| | | width={800} |
| | | onCancel={this.editModalCancel} |
| | | footer={[ |
| | | modaltype === 'actionEdit' ? <Button key="delete" className="mk-btn mk-purple" onClick={this.creatFunc} loading={this.state.funcLoading}>{this.state.dict['header.menu.func.create']}</Button> : null, |
| | |
| | | onCancel={() => { this.setState({ profileVisible: false }) }} |
| | | destroyOnClose |
| | | > |
| | | <VerifyCard card={this.state.card} columns={this.state.config.columns} wrappedComponentRef={(inst) => this.verifyRef = inst} dict={this.state.dict} /> |
| | | {this.state.card && this.state.card.OpenType !== 'excelIn' ? |
| | | <VerifyCard |
| | | card={this.state.card} |
| | | dict={this.state.dict} |
| | | columns={this.state.config.columns} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> : null |
| | | } |
| | | {this.state.card && this.state.card.OpenType === 'excelIn' ? |
| | | <VerifyCardExcelIn |
| | | card={this.state.card} |
| | | dict={this.state.dict} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> : null |
| | | } |
| | | </Modal> |
| | | {/* 设置全局配置及列表数据源 */} |
| | | <Modal |
| | |
| | | import Utils from '@/utils/utils.js' |
| | | import { getModalForm, getActionForm } from '@/templates/tableshare/formconfig' |
| | | |
| | | import ModalForm from '@/templates/ushare/modalform' |
| | | import ActionForm from './actionform' |
| | | import SettingForm from './settingform' |
| | | import ModalForm from './modalform' |
| | | // import ModalForm from './modalform' |
| | | import DragElement from './dragelement' |
| | | import GroupForm from './groupform' |
| | | import TabForm from '@/templates/tableshare/tabform' |
| | |
| | | componentDidMount () { |
| | | let param = { |
| | | func: 'sPC_Get_SelectedList', |
| | | LText: 'select TbName ,Remark from sDataDictionary where IsKey!=\'\' and Deleted =0', |
| | | // LText: 'select TbName ,Remark from sDataDictionary where IsKey!=\'\' and Deleted =0', |
| | | LText: 'select TbName,Remark from (select TbName,Remark from sDataDictb where appkey= @appkey@ and Deleted=0 union select a.TbName,Remark from (select TbName,Remark from sDataDictb where appkey= \'\' and Deleted=0 ) a left join (select TbName from sDataDictb where appkey= @appkey@ and Deleted=0 ) b on a.TbName=b.TbName where b.TbName is null ) t', |
| | | obj_name: 'data', |
| | | arr_field: 'TbName,Remark' |
| | | } |
| | |
| | | func: 'sPC_Button_AddUpt', |
| | | Type: 60, // 添加按钮表单页下的按钮 |
| | | ParentID: menu.MenuID, |
| | | MenuNo: res.menuNo, |
| | | MenuNo: menu.MenuNo, |
| | | Template: menu.PageParam.Template || '', |
| | | PageParam: '', |
| | | LongParam: '', |
| | |
| | | import { formRule } from '@/utils/option.js' |
| | | import './index.scss' |
| | | |
| | | // const { TextArea } = Input |
| | | const { TextArea } = Input |
| | | |
| | | class SettingForm extends Component { |
| | | static propTpyes = { |
| | |
| | | } |
| | | |
| | | render() { |
| | | const { dict, usefulFields } = this.props |
| | | const { dict, usefulFields, menu } = this.props |
| | | const { getFieldDecorator } = this.props.form |
| | | const { interType, columns, selectTabs, setting } = this.state |
| | | |
| | |
| | | })(<Input placeholder="" autoComplete="off" />)} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {/* {interType !== 'outer' ? <Col span={24}> |
| | | {interType !== 'outer' ? <Col span={24}> |
| | | <Form.Item help={'数据ID:' + menu.MenuID} label={ |
| | | <Tooltip placement="topLeft" title="使用系统函数时,需填写数据源,自定义函数时,可忽略。"> |
| | | <Icon type="question-circle" /> |
| | |
| | | initialValue: setting.dataresource |
| | | })(<TextArea rows={4} />)} |
| | | </Form.Item> |
| | | </Col> : null} */} |
| | | </Col> : null} |
| | | {interType === 'outer' ? <Col span={12}> |
| | | <Form.Item label={dict['header.form.outerFunc']}> |
| | | {getFieldDecorator('outerFunc', { |
| | |
| | | componentDidMount () { |
| | | let param = { |
| | | func: 'sPC_Get_SelectedList', |
| | | LText: 'select TbName ,Remark from sDataDictionary where IsKey!=\'\' and Deleted =0', |
| | | // LText: 'select TbName ,Remark from sDataDictionary where IsKey!=\'\' and Deleted =0', |
| | | LText: 'select TbName,Remark from (select TbName,Remark from sDataDictb where appkey= @appkey@ and Deleted=0 union select a.TbName,Remark from (select TbName,Remark from sDataDictb where appkey= \'\' and Deleted=0 ) a left join (select TbName from sDataDictb where appkey= @appkey@ and Deleted=0 ) b on a.TbName=b.TbName where b.TbName is null ) t', |
| | | obj_name: 'data', |
| | | arr_field: 'TbName,Remark' |
| | | } |
| | |
| | | import GridBtnForm from '@/templates/tableshare/gridbtnform' |
| | | import EditCard from '@/templates/tableshare/editcard' |
| | | import VerifyCard from '@/templates/tableshare/verifycard' |
| | | import VerifyCardExcelIn from '@/templates/tableshare/verifycardexcelin' |
| | | import MenuForm from '@/templates/tableshare/menuform' |
| | | import SourceElement from '@/templates/tableshare/dragelement/source' |
| | | import Source from './source' |
| | |
| | | componentDidMount () { |
| | | let param = { |
| | | func: 'sPC_Get_SelectedList', |
| | | LText: 'select TbName ,Remark from sDataDictionary where IsKey!=\'\' and Deleted =0', |
| | | // LText: 'select TbName ,Remark from sDataDictionary where IsKey!=\'\' and Deleted =0', |
| | | LText: 'select TbName,Remark from (select TbName,Remark from sDataDictb where appkey= @appkey@ and Deleted=0 union select a.TbName,Remark from (select TbName,Remark from sDataDictb where appkey= \'\' and Deleted=0 ) a left join (select TbName from sDataDictb where appkey= @appkey@ and Deleted=0 ) b on a.TbName=b.TbName where b.TbName is null ) t', |
| | | obj_name: 'data', |
| | | arr_field: 'TbName,Remark' |
| | | } |
| | |
| | | let config = JSON.parse(JSON.stringify(this.state.config)) |
| | | let _verify = this.verifyRef.state.verify |
| | | |
| | | if (card.OpenType !== 'excelIn') { |
| | | if (_verify.default === 'false' && _verify.scripts.length === 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '不执行默认sql时,必须设置自定义脚本!', |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } |
| | | } else if (card.OpenType === 'excelIn') { |
| | | let cols = _verify.columns.map(col => col.Column) |
| | | cols = Array.from(new Set(cols)) |
| | | |
| | | if (!_verify.sheet) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请设置导入表名!', |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } else if (_verify.columns.length === 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请设置Excel列字段!', |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } else if (_verify.columns.length > cols.length) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: 'Excel列字段名,不可重复!', |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } else if (_verify.range === 1) { |
| | | let tEmptys = _verify.columns.filter(op => !op.Text) |
| | | if (tEmptys.length > 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '忽略首行时,会使用Text值校验Excel首行内容,Text值与Excel表首行内容相同,且均不可为空!', |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } |
| | | } |
| | | } |
| | | |
| | | config.action = config.action.map(item => { |
| | | if (item.uuid === card.uuid) { |
| | | item.verify = _verify |
| | |
| | | onCancel={() => { this.setState({ profileVisible: false }) }} |
| | | destroyOnClose |
| | | > |
| | | <VerifyCard floor="subtable" card={this.state.card} columns={this.state.config.columns} wrappedComponentRef={(inst) => this.verifyRef = inst} dict={this.state.dict} /> |
| | | {this.state.card && this.state.card.OpenType !== 'excelIn' ? |
| | | <VerifyCard |
| | | floor="subtable" |
| | | card={this.state.card} |
| | | dict={this.state.dict} |
| | | columns={this.state.config.columns} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> : null |
| | | } |
| | | {this.state.card && this.state.card.OpenType === 'excelIn' ? |
| | | <VerifyCardExcelIn |
| | | card={this.state.card} |
| | | dict={this.state.dict} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> : null |
| | | } |
| | | </Modal> |
| | | {/* 设置全局配置及列表数据源 */} |
| | | <Modal |
| | |
| | | <Icon className="edit" title="编辑" type="edit" onClick={edit} /> |
| | | <Icon className="edit close" title="删除" type="close" onClick={del} /> |
| | | {type === 'action' ? <Icon className="edit copy" title="复制" type="copy" onClick={copy} /> : null} |
| | | {type === 'action' && ['pop', 'prompt', 'exec'].includes(card.OpenType) && card.intertype === 'inner' && !card.innerFunc ? |
| | | {type === 'action' && ['pop', 'prompt', 'exec', 'excelIn'].includes(card.OpenType) && card.intertype === 'inner' && !card.innerFunc ? |
| | | <Icon className="edit profile" title="校验规则" type="profile" onClick={profile} /> : null |
| | | } |
| | | </div> |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import { Table, Input, Button, Popconfirm, Form, Icon, InputNumber, Select } from 'antd' |
| | | import Utils from '@/utils/utils.js' |
| | | import './index.scss' |
| | | |
| | | const EditableContext = React.createContext() |
| | | |
| | | const EditableRow = ({ form, index, ...props }) => ( |
| | | <EditableContext.Provider value={form}> |
| | | <tr {...props} /> |
| | | </EditableContext.Provider> |
| | | ) |
| | | |
| | | const EditableFormRow = Form.create()(EditableRow) |
| | | |
| | | class EditableCell extends Component { |
| | | state = { |
| | | editing: false |
| | | } |
| | | |
| | | toggleEdit = () => { |
| | | const editing = !this.state.editing |
| | | |
| | | this.setState({ editing }, () => { |
| | | if (editing && this.input && this.input.select) { |
| | | this.input.select() |
| | | } else if (editing && this.input && this.input.focus) { |
| | | this.input.focus() |
| | | } |
| | | }) |
| | | } |
| | | |
| | | save = e => { |
| | | const { record, handleSave } = this.props |
| | | this.form.validateFields((error, values) => { |
| | | handleSave({ ...record, ...values }) |
| | | if (error && error[e.currentTarget.id]) { |
| | | return |
| | | } |
| | | this.toggleEdit() |
| | | }) |
| | | } |
| | | |
| | | typeChange = (key, val) => { |
| | | const { record, handleSave } = this.props |
| | | |
| | | handleSave({ ...record, ...{[key]: val} }) |
| | | |
| | | this.toggleEdit() |
| | | } |
| | | |
| | | renderCell = form => { |
| | | this.form = form |
| | | const { children, dataIndex, record } = this.props |
| | | const { editing } = this.state |
| | | |
| | | return editing ? ( |
| | | <div> |
| | | {dataIndex === 'Column' || dataIndex === 'Text' ? <Form.Item style={{ margin: 0 }}> |
| | | {form.getFieldDecorator(dataIndex, { |
| | | initialValue: record[dataIndex], |
| | | rules: [ |
| | | { |
| | | required: dataIndex === 'Column', |
| | | message: 'NOT NULL.', |
| | | }, |
| | | ] |
| | | })(<Input ref={node => (this.input = node)} autoComplete="off" onPressEnter={this.save} onBlur={this.save} />)} |
| | | </Form.Item> : null} |
| | | {dataIndex === 'min' || dataIndex === 'max' ? <Form.Item style={{ margin: 0 }}> |
| | | {form.getFieldDecorator(dataIndex, { |
| | | initialValue: record[dataIndex] |
| | | })(<InputNumber ref={node => (this.input = node)} autoComplete="off" onPressEnter={this.save} onBlur={this.save} />)} |
| | | </Form.Item> : null} |
| | | {dataIndex === 'required' ? <Form.Item style={{ margin: 0 }}> |
| | | {form.getFieldDecorator(dataIndex, { |
| | | initialValue: record[dataIndex] || 'false' |
| | | })( |
| | | <Select |
| | | onChange={(value) => {this.typeChange(dataIndex, value)}} |
| | | onBlur={(value) => {this.typeChange(dataIndex, value)}} |
| | | defaultOpen={true} |
| | | > |
| | | <Select.Option value='false'>否</Select.Option> |
| | | <Select.Option value='true'>是</Select.Option> |
| | | </Select> |
| | | )} |
| | | </Form.Item> : null} |
| | | {dataIndex === 'type' ? <Form.Item style={{ margin: 0 }}> |
| | | {form.getFieldDecorator(dataIndex, { |
| | | initialValue: record[dataIndex] || 'text' |
| | | })( |
| | | <Select |
| | | onChange={(value) => {this.typeChange(dataIndex, value)}} |
| | | onBlur={(value) => {this.typeChange(dataIndex, value)}} |
| | | defaultOpen={true} |
| | | > |
| | | <Select.Option value='text'>文本</Select.Option> |
| | | <Select.Option value='number'>数值</Select.Option> |
| | | </Select> |
| | | )} |
| | | </Form.Item> : null} |
| | | </div> |
| | | ) : ( |
| | | <div |
| | | className="editable-cell-value-wrap" |
| | | onClick={this.toggleEdit} |
| | | > |
| | | {children} |
| | | </div> |
| | | ) |
| | | } |
| | | |
| | | render() { |
| | | const { |
| | | editable, |
| | | dataIndex, |
| | | title, |
| | | record, |
| | | index, |
| | | handleSave, |
| | | children, |
| | | ...restProps |
| | | } = this.props |
| | | return ( |
| | | <td {...restProps}> |
| | | {editable ? ( |
| | | <EditableContext.Consumer style={{padding: 0}}>{this.renderCell}</EditableContext.Consumer> |
| | | ) : ( |
| | | children |
| | | )} |
| | | </td> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | class EditTable extends Component { |
| | | constructor(props) { |
| | | super(props) |
| | | |
| | | let columns = [ |
| | | { |
| | | title: 'Column', |
| | | dataIndex: 'Column', |
| | | width: '15%', |
| | | editable: true |
| | | }, |
| | | { |
| | | title: 'Text', |
| | | dataIndex: 'Text', |
| | | width: '18%', |
| | | editable: true |
| | | }, |
| | | { |
| | | title: '是否必填', |
| | | dataIndex: 'required', |
| | | width: '12%', |
| | | editable: true, |
| | | render: (text, record) => record.required === 'true' ? '是' : '否' |
| | | }, |
| | | { |
| | | title: '类型', |
| | | dataIndex: 'type', |
| | | width: '12%', |
| | | editable: true, |
| | | render: (text, record) => record.type === 'number' ? '数值' : '文本' |
| | | }, |
| | | { |
| | | title: '最小值', |
| | | dataIndex: 'min', |
| | | width: '13%', |
| | | editable: true |
| | | }, |
| | | { |
| | | title: '最大值', |
| | | dataIndex: 'max', |
| | | width: '13%', |
| | | editable: true |
| | | }, |
| | | { |
| | | title: '操作', |
| | | align: 'center', |
| | | dataIndex: 'operation', |
| | | render: (text, record) => |
| | | this.state.dataSource.length >= 1 ? ( |
| | | <div> |
| | | <span className="operation-btn" title={props.dict['header.form.up']} onClick={() => this.handleUpDown(record, 'up')} style={{color: '#1890ff'}}><Icon type="arrow-up" /></span> |
| | | <span className="operation-btn" title={props.dict['header.form.down']} onClick={() => this.handleUpDown(record, 'down')} style={{color: '#ff4d4f'}}><Icon type="arrow-down" /></span> |
| | | <Popconfirm |
| | | title={props.dict['header.form.query.delete']} |
| | | okText={props.dict['header.confirm']} |
| | | cancelText={props.dict['header.cancel']} |
| | | onConfirm={() => this.handleDelete(record.key) |
| | | }> |
| | | <span style={{color: '#1890ff', cursor: 'pointer'}}><Icon type="delete" /></span> |
| | | </Popconfirm> |
| | | </div> |
| | | ) : null, |
| | | } |
| | | ] |
| | | |
| | | this.state = { |
| | | columns: columns, |
| | | dataSource: props.data |
| | | } |
| | | } |
| | | |
| | | handleUpDown = (record, direction) => { |
| | | const { dataSource } = this.state |
| | | let index = 0 |
| | | |
| | | let _data = dataSource.filter((item, i) => { |
| | | if (item.key === record.key) { |
| | | index = i |
| | | } |
| | | |
| | | return item.key !== record.key |
| | | }) |
| | | if ((index === 0 && direction === 'up') || (index === dataSource.length - 1 && direction === 'down')) { |
| | | return |
| | | } |
| | | |
| | | if (direction === 'up') { |
| | | _data.splice(index - 1, 0, record) |
| | | } else { |
| | | _data.splice(index + 1, 0, record) |
| | | } |
| | | |
| | | this.setState({ |
| | | dataSource: _data |
| | | }) |
| | | } |
| | | |
| | | handleDelete = key => { |
| | | const dataSource = [...this.state.dataSource] |
| | | this.setState({ dataSource: dataSource.filter(item => item.key !== key) }) |
| | | } |
| | | |
| | | handleAdd = () => { |
| | | const { dataSource } = this.state |
| | | const newData = { |
| | | key: Utils.getuuid(), |
| | | Column: '', |
| | | Text: '' |
| | | } |
| | | |
| | | this.setState({ |
| | | dataSource: [...dataSource, newData] |
| | | }) |
| | | } |
| | | |
| | | handleSave = row => { |
| | | const newData = [...this.state.dataSource] |
| | | const index = newData.findIndex(item => row.key === item.key) |
| | | const item = newData[index] |
| | | newData.splice(index, 1, { |
| | | ...item, |
| | | ...row |
| | | }) |
| | | this.setState({ dataSource: newData }) |
| | | } |
| | | |
| | | render() { |
| | | const { dataSource } = this.state |
| | | const components = { |
| | | body: { |
| | | row: EditableFormRow, |
| | | cell: EditableCell |
| | | } |
| | | } |
| | | const columns = this.state.columns.map(col => { |
| | | if (!col.editable) { |
| | | return col |
| | | } |
| | | return { |
| | | ...col, |
| | | onCell: record => ({ |
| | | record, |
| | | editable: col.editable, |
| | | dataIndex: col.dataIndex, |
| | | title: col.title, |
| | | handleSave: this.handleSave, |
| | | }) |
| | | } |
| | | }) |
| | | return ( |
| | | <div className="common-excel-edit-table"> |
| | | <Button onClick={this.handleAdd} type="primary" className="add-row"> |
| | | 添加 |
| | | </Button> |
| | | <Table |
| | | components={components} |
| | | rowClassName={() => 'editable-row'} |
| | | bordered |
| | | dataSource={dataSource} |
| | | columns={columns} |
| | | pagination={false} |
| | | /> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default EditTable |
New file |
| | |
| | | .common-excel-edit-table { |
| | | margin-top: 30px; |
| | | margin-left: -23px; |
| | | margin-bottom: 15px; |
| | | .add-row { |
| | | position: absolute; |
| | | z-index: 1; |
| | | right: 12px; |
| | | top: -10px; |
| | | } |
| | | .ant-table-thead > tr > th { |
| | | padding: 10px 0px; |
| | | text-align: center; |
| | | } |
| | | .ant-table-tbody > tr > td { |
| | | padding: 0px 5px; |
| | | .ant-input-number-input { |
| | | padding: 0 3px; |
| | | } |
| | | .ant-input { |
| | | padding: 0 3px; |
| | | } |
| | | } |
| | | .editable-cell-value-wrap { |
| | | cursor: pointer; |
| | | height: 40px; |
| | | width: 200px; |
| | | display: table-cell; |
| | | vertical-align: middle; |
| | | word-wrap: break-word; |
| | | word-break: break-word; |
| | | .ant-input { |
| | | height: 30px; |
| | | } |
| | | } |
| | | .ant-form-item-control-wrapper { |
| | | width: 100%; |
| | | } |
| | | .ant-table-placeholder { |
| | | padding: 5px 16px; |
| | | .ant-empty-normal { |
| | | margin: 0; |
| | | } |
| | | } |
| | | .operation-btn { |
| | | margin-right: 10px; |
| | | cursor: pointer; |
| | | } |
| | | } |
| | |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } else if (/--/ig.test(values.sql)) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '自定义sql语句中,不可出现字符 -- ,注释请用 /*内容*/', |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | |
| | | this.props.customChange(values) |
| | | this.setState({ |
| | | editItem: null |
| | |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } else if (/--/ig.test(values.sql)) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '自定义sql语句中,不可出现字符 -- ,注释请用 /*内容*/', |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | this.props.scriptsChange(values) |
| | |
| | | |
| | | this.setState({ |
| | | verify: { |
| | | ..._verify, |
| | | default: _verify.default || 'true', |
| | | invalid: _verify.invalid || 'false', |
| | | uniques: _verify.uniques || [], |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { Form, Row, Col, Select, Button, Input, InputNumber } from 'antd' |
| | | import './index.scss' |
| | | |
| | | |
| | | class UniqueForm extends Component { |
| | | static propTpyes = { |
| | | dict: PropTypes.object, // 字典项 |
| | | range: PropTypes.any, // 字典项 |
| | | columnChange: PropTypes.func // 修改函数 |
| | | } |
| | | |
| | | state = { |
| | | editItem: null, // 编辑元素 |
| | | type: 'Nvarchar(50)' |
| | | } |
| | | |
| | | edit = (record) => { |
| | | this.setState({ |
| | | editItem: record, |
| | | type: record.type || 'Nvarchar(50)' |
| | | }, () => { |
| | | if (!/^Nvarchar/.test(record.type)) { |
| | | this.props.form.setFieldsValue({ |
| | | min: record.min, |
| | | max: record.max |
| | | }) |
| | | } |
| | | }) |
| | | |
| | | this.props.form.setFieldsValue({ |
| | | Column: record.Column, |
| | | Text: record.Text, |
| | | required: record.required, |
| | | type: record.type |
| | | }) |
| | | } |
| | | |
| | | typeChange = (val) => { |
| | | this.setState({ |
| | | type: val |
| | | }) |
| | | } |
| | | |
| | | |
| | | handleConfirm = () => { |
| | | // 表单提交时检查输入值是否正确 |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | | if (!err) { |
| | | values.uuid = this.state.editItem ? this.state.editItem.uuid : '' |
| | | |
| | | this.props.columnChange(values) |
| | | this.setState({ |
| | | editItem: null |
| | | }) |
| | | this.props.form.setFieldsValue({ |
| | | Column: '', |
| | | Text: '', |
| | | required: 'false', |
| | | type: 'Nvarchar(50)' |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | render() { |
| | | const { getFieldDecorator } = this.props.form |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 8 } |
| | | }, |
| | | wrapperCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 16 } |
| | | } |
| | | } |
| | | |
| | | let haslimit = !/^Nvarchar/.test(this.state.type) |
| | | |
| | | return ( |
| | | <Form {...formItemLayout} className="verify-form"> |
| | | <Row gutter={24}> |
| | | <Col span={7}> |
| | | <Form.Item label={'Column'}> |
| | | {getFieldDecorator('Column', { |
| | | initialValue: '', |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: this.props.dict['form.required.input'] + 'Column!' |
| | | } |
| | | ] |
| | | })(<Input placeholder="" autoComplete="off" />)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={7}> |
| | | <Form.Item label={'Text'}> |
| | | {getFieldDecorator('Text', { |
| | | initialValue: '', |
| | | rules: [ |
| | | { |
| | | required: this.props.range === 1, |
| | | message: this.props.dict['form.required.input'] + 'Text!' |
| | | } |
| | | ] |
| | | })(<Input placeholder="" autoComplete="off" />)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={7}> |
| | | <Form.Item label={'是否必填'}> |
| | | {getFieldDecorator('required', { |
| | | initialValue: 'false' |
| | | })( |
| | | <Select> |
| | | <Select.Option value="false"> 否 </Select.Option> |
| | | <Select.Option value="true"> 是 </Select.Option> |
| | | </Select> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={3} className="add"> |
| | | <Button onClick={this.handleConfirm} type="primary" className="add-row"> |
| | | 确定 |
| | | </Button> |
| | | </Col> |
| | | <Col span={7}> |
| | | <Form.Item label={'类型'}> |
| | | {getFieldDecorator('type', { |
| | | initialValue: 'Nvarchar(50)' |
| | | })( |
| | | <Select onChange={this.typeChange}> |
| | | <Select.Option value="Nvarchar(10)"> Nvarchar(10) </Select.Option> |
| | | <Select.Option value="Nvarchar(20)"> Nvarchar(20) </Select.Option> |
| | | <Select.Option value="Nvarchar(50)"> Nvarchar(50) </Select.Option> |
| | | <Select.Option value="Nvarchar(100)"> Nvarchar(100) </Select.Option> |
| | | <Select.Option value="Nvarchar(512)"> Nvarchar(512) </Select.Option> |
| | | <Select.Option value="Int"> Int </Select.Option> |
| | | <Select.Option value="Decimal(18,0)"> Decimal(18,0) </Select.Option> |
| | | <Select.Option value="Decimal(18,2)"> Decimal(18,2) </Select.Option> |
| | | <Select.Option value="Decimal(18,4)"> Decimal(18,4) </Select.Option> |
| | | <Select.Option value="Decimal(18,6)"> Decimal(18,6) </Select.Option> |
| | | </Select> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | {haslimit ? <Col span={7}> |
| | | <Form.Item label={'最小值'}> |
| | | {getFieldDecorator('min', { |
| | | initialValue: '' |
| | | })(<InputNumber />)} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {haslimit ? <Col span={7}> |
| | | <Form.Item label={'最大值'}> |
| | | {getFieldDecorator('max', { |
| | | initialValue: '' |
| | | })(<InputNumber />)} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | </Row> |
| | | </Form> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default Form.create()(UniqueForm) |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { Form, Row, Col, Input, Button, notification } from 'antd' |
| | | import './index.scss' |
| | | |
| | | const { TextArea } = Input |
| | | |
| | | class CustomForm extends Component { |
| | | static propTpyes = { |
| | | dict: PropTypes.object, // 字典项 |
| | | usefulfields: PropTypes.string, // 可用字段 |
| | | scriptsChange: PropTypes.func // 表单 |
| | | } |
| | | |
| | | state = { |
| | | editItem: null |
| | | } |
| | | |
| | | edit = (record) => { |
| | | this.setState({ |
| | | editItem: record |
| | | }) |
| | | |
| | | this.props.form.setFieldsValue({ |
| | | sql: record.sql |
| | | }) |
| | | } |
| | | |
| | | |
| | | handleConfirm = () => { |
| | | // 表单提交时检查输入值是否正确 |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | | if (!err) { |
| | | values.uuid = this.state.editItem ? this.state.editItem.uuid : '' |
| | | |
| | | let _quot = values.sql.match(/'{1}/g) |
| | | let _lparen = values.sql.match(/\({1}/g) |
| | | let _rparen = values.sql.match(/\){1}/g) |
| | | |
| | | _quot = _quot ? _quot.length : 0 |
| | | _lparen = _lparen ? _lparen.length : 0 |
| | | _rparen = _rparen ? _rparen.length : 0 |
| | | |
| | | if (_quot % 2 !== 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: 'sql中\'必须成对出现', |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } else if (_lparen !== _rparen) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: 'sql中()必须成对出现', |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } else if (/--/ig.test(values.sql)) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '自定义sql语句中,不可出现字符 -- ,注释请用 /*内容*/', |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | this.props.scriptsChange(values) |
| | | this.setState({ |
| | | editItem: null |
| | | }) |
| | | this.props.form.setFieldsValue({ |
| | | sql: '' |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | render() { |
| | | const { usefulfields } = this.props |
| | | const { getFieldDecorator } = this.props.form |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 8 } |
| | | }, |
| | | wrapperCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 16 } |
| | | } |
| | | } |
| | | |
| | | let _fields = usefulfields.map(item => item.Column).join(', ') |
| | | |
| | | return ( |
| | | <Form {...formItemLayout} className="verify-form" id="verifycard2"> |
| | | <Row gutter={24}> |
| | | {_fields ? <Col span={21} className="sqlfield"> |
| | | <Form.Item label={'可用字段'}> |
| | | {_fields} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | <Col span={21} className="sql"> |
| | | <Form.Item label={'sql'}> |
| | | {getFieldDecorator('sql', { |
| | | initialValue: '', |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: this.props.dict['form.required.input'] + 'sql!' |
| | | } |
| | | ] |
| | | })(<TextArea rows={15} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={3} className="add"> |
| | | <Button onClick={this.handleConfirm} type="primary" className="add-row"> |
| | | 确定 |
| | | </Button> |
| | | </Col> |
| | | </Row> |
| | | </Form> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default Form.create()(CustomForm) |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { Form, Tabs, Row, Col, Input, Button, Table, Popconfirm, Icon, notification, Modal, message, InputNumber } from 'antd' |
| | | import { formRule } from '@/utils/option.js' |
| | | |
| | | import Utils from '@/utils/utils.js' |
| | | |
| | | import ColumnForm from './columnform' |
| | | import CustomScript from './customscript' |
| | | import './index.scss' |
| | | |
| | | const { TabPane } = Tabs |
| | | |
| | | class VerifyCard extends Component { |
| | | static propTpyes = { |
| | | dict: PropTypes.object, // 字典项 |
| | | card: PropTypes.object, |
| | | } |
| | | |
| | | state = { |
| | | verify: {}, |
| | | excelColumns: [ |
| | | { |
| | | title: 'Column', |
| | | dataIndex: 'Column', |
| | | width: '16%', |
| | | editable: true |
| | | }, |
| | | { |
| | | title: 'Text', |
| | | dataIndex: 'Text', |
| | | width: '19%', |
| | | editable: true |
| | | }, |
| | | { |
| | | title: '是否必填', |
| | | dataIndex: 'required', |
| | | width: '12%', |
| | | editable: true, |
| | | render: (text, record) => record.required === 'true' ? '是' : '否' |
| | | }, |
| | | { |
| | | title: '类型', |
| | | dataIndex: 'type', |
| | | width: '12%', |
| | | editable: true |
| | | }, |
| | | { |
| | | title: '最小值', |
| | | dataIndex: 'min', |
| | | width: '12%', |
| | | editable: true |
| | | }, |
| | | { |
| | | title: '最大值', |
| | | dataIndex: 'max', |
| | | width: '12%', |
| | | editable: true |
| | | }, |
| | | { |
| | | title: '操作', |
| | | align: 'center', |
| | | dataIndex: 'operation', |
| | | render: (text, record) => |
| | | ( |
| | | <div> |
| | | <span className="operation-btn" title={this.props.dict['header.edit']} onClick={() => this.handleEdit(record, 'columns')} style={{color: '#1890ff'}}><Icon type="edit" /></span> |
| | | <span className="operation-btn" title={this.props.dict['header.form.up']} onClick={() => this.handleUpDown(record, 'columns', 'up')} style={{color: '#1890ff'}}><Icon type="arrow-up" /></span> |
| | | <span className="operation-btn" title={this.props.dict['header.form.down']} onClick={() => this.handleUpDown(record, 'columns', 'down')} style={{color: '#ff4d4f'}}><Icon type="arrow-down" /></span> |
| | | <Popconfirm |
| | | title={this.props.dict['header.form.query.delete']} |
| | | okText={this.props.dict['header.confirm']} |
| | | cancelText={this.props.dict['header.cancel']} |
| | | onConfirm={() => this.handleDelete(record, 'columns') |
| | | }> |
| | | <span style={{color: '#1890ff', cursor: 'pointer'}}><Icon type="delete" /></span> |
| | | </Popconfirm> |
| | | </div> |
| | | ) |
| | | } |
| | | ], |
| | | scriptsColumns: [ |
| | | { |
| | | title: 'SQL', |
| | | dataIndex: 'sql', |
| | | width: '70%' |
| | | }, |
| | | { |
| | | title: '状态', |
| | | dataIndex: 'status', |
| | | width: '10%', |
| | | render: (text, record) => record.status === 'false' ? |
| | | ( |
| | | <div> |
| | | {this.props.dict['header.form.status.forbidden']} |
| | | <Icon style={{marginLeft: '5px'}} type="stop" theme="twoTone" twoToneColor="#ff4d4f" /> |
| | | </div> |
| | | ) : |
| | | ( |
| | | <div> |
| | | {this.props.dict['header.form.status.open']} |
| | | <Icon style={{marginLeft: '5px'}} type="check-circle" theme="twoTone" twoToneColor="#52c41a" /> |
| | | </div> |
| | | ) |
| | | }, |
| | | { |
| | | title: '操作', |
| | | align: 'center', |
| | | width: '20%', |
| | | dataIndex: 'operation', |
| | | render: (text, record) => |
| | | (<div> |
| | | <span className="operation-btn" title={this.props.dict['header.edit']} onClick={() => this.handleEdit(record, 'scripts')} style={{color: '#1890ff'}}><Icon type="edit" /></span> |
| | | <span className="operation-btn" title={this.props.dict['header.form.up']} onClick={() => this.handleUpDown(record, 'scripts', 'up')} style={{color: '#1890ff'}}><Icon type="arrow-up" /></span> |
| | | <span className="operation-btn" title={this.props.dict['header.form.down']} onClick={() => this.handleUpDown(record, 'scripts', 'down')} style={{color: '#ff4d4f'}}><Icon type="arrow-down" /></span> |
| | | <span className="operation-btn" title={this.props.dict['header.form.status.change']} onClick={() => this.handleStatus(record, 'scripts')} style={{color: '#8E44AD'}}><Icon type="swap" /></span> |
| | | <Popconfirm |
| | | title={this.props.dict['header.form.query.delete']} |
| | | okText={this.props.dict['header.confirm']} |
| | | cancelText={this.props.dict['header.cancel']} |
| | | onConfirm={() => this.handleDelete(record, 'scripts') |
| | | }> |
| | | <span className="operation-btn" style={{color: '#ff4d4f'}}><Icon type="delete" /></span> |
| | | </Popconfirm> |
| | | </div>) |
| | | } |
| | | ] |
| | | } |
| | | |
| | | UNSAFE_componentWillMount() { |
| | | let _verify = this.props.card.verify || {} |
| | | |
| | | this.setState({ |
| | | verify: { |
| | | ..._verify, |
| | | sheet: _verify.sheet || '', |
| | | range: _verify.range || 0, |
| | | columns: _verify.columns || [], |
| | | scripts: _verify.scripts || [] |
| | | } |
| | | }) |
| | | } |
| | | |
| | | columnChange = (values) => { |
| | | let verify = JSON.parse(JSON.stringify(this.state.verify)) |
| | | |
| | | if (values.uuid) { |
| | | verify.columns = verify.columns.map(item => { |
| | | if (item.uuid === values.uuid) { |
| | | return values |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | } else { |
| | | values.uuid = Utils.getuuid() |
| | | verify.columns.push(values) |
| | | } |
| | | |
| | | this.setState({ |
| | | verify: verify |
| | | }) |
| | | } |
| | | |
| | | scriptsChange = (values) => { |
| | | let verify = JSON.parse(JSON.stringify(this.state.verify)) |
| | | |
| | | if (values.uuid) { |
| | | verify.scripts = verify.scripts.map(item => { |
| | | if (item.uuid === values.uuid) { |
| | | return values |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | } else { |
| | | values.uuid = Utils.getuuid() |
| | | verify.scripts.push(values) |
| | | } |
| | | |
| | | this.setState({ |
| | | verify: verify |
| | | }) |
| | | } |
| | | |
| | | handleDelete = (record, type) => { |
| | | const { verify } = this.state |
| | | |
| | | if (type === 'columns') { |
| | | verify.columns = verify.columns.filter(item => item.uuid !== record.uuid) |
| | | } else if (type === 'scripts') { |
| | | verify.scripts = verify.scripts.filter(item => item.uuid !== record.uuid) |
| | | } |
| | | this.setState({ verify: verify }) |
| | | } |
| | | |
| | | handleEdit = (record, type) => { |
| | | if (type === 'columns') { |
| | | this.columnForm.edit(record) |
| | | } else if (type === 'scripts') { |
| | | this.scriptsForm.edit(record) |
| | | } |
| | | |
| | | let node = document.getElementById('verify-excel-box-tab').parentNode |
| | | |
| | | if (node && node.scrollTop) { |
| | | node.scrollTop = 0 |
| | | } |
| | | } |
| | | |
| | | handleStatus = (record, type) => { |
| | | let verify = JSON.parse(JSON.stringify(this.state.verify)) |
| | | record.status = record.status === 'false' ? 'true' : 'false' |
| | | |
| | | if (type === 'scripts') { |
| | | verify.scripts = verify.scripts.map(item => { |
| | | if (item.uuid === record.uuid) { |
| | | return record |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | } |
| | | |
| | | this.setState({ |
| | | verify: verify |
| | | }) |
| | | } |
| | | |
| | | handleUpDown = (record, type, direction) => { |
| | | let verify = JSON.parse(JSON.stringify(this.state.verify)) |
| | | let index = 0 |
| | | |
| | | if (type === 'columns') { |
| | | verify.columns = verify.columns.filter((item, i) => { |
| | | if (item.uuid === record.uuid) { |
| | | index = i |
| | | } |
| | | |
| | | return item.uuid !== record.uuid |
| | | }) |
| | | if ((index === 0 && direction === 'up') || (index === verify.columns.length && direction === 'down')) { |
| | | return |
| | | } |
| | | |
| | | if (direction === 'up') { |
| | | verify.columns.splice(index - 1, 0, record) |
| | | } else { |
| | | verify.columns.splice(index + 1, 0, record) |
| | | } |
| | | } else if (type === 'scripts') { |
| | | verify.scripts = verify.scripts.filter((item, i) => { |
| | | if (item.uuid === record.uuid) { |
| | | index = i |
| | | } |
| | | |
| | | return item.uuid !== record.uuid |
| | | }) |
| | | if ((index === 0 && direction === 'up') || (index === verify.scripts.length && direction === 'down')) { |
| | | return |
| | | } |
| | | |
| | | if (direction === 'up') { |
| | | verify.scripts.splice(index - 1, 0, record) |
| | | } else { |
| | | verify.scripts.splice(index + 1, 0, record) |
| | | } |
| | | } |
| | | |
| | | this.setState({ |
| | | verify: verify |
| | | }) |
| | | } |
| | | |
| | | sheetChange = (e) => { |
| | | const { verify } = this.state |
| | | |
| | | this.setState({}, () => { |
| | | this.props.form.validateFields(['sheet'], (errors, values) => { |
| | | if (!errors) { |
| | | this.setState({ |
| | | verify: { |
| | | ...verify, |
| | | ...values |
| | | } |
| | | }) |
| | | } else { |
| | | this.setState({ |
| | | verify: { |
| | | ...verify, |
| | | sheet: '' |
| | | } |
| | | }) |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | rangeChange = (value) => { |
| | | const { verify } = this.state |
| | | |
| | | this.setState({ |
| | | verify: { |
| | | ...verify, |
| | | range: value || 0 |
| | | } |
| | | }) |
| | | } |
| | | |
| | | showError = (errorType) => { |
| | | if (errorType === 'S') { |
| | | notification.success({ |
| | | top: 92, |
| | | message: '执行成功!', |
| | | duration: 2 |
| | | }) |
| | | } else if (errorType === 'F') { |
| | | notification.error({ |
| | | className: 'notification-custom-error', |
| | | top: 92, |
| | | message: '执行失败!', |
| | | duration: 15 |
| | | }) |
| | | } else if (errorType === 'N') { |
| | | notification.error({ |
| | | top: 92, |
| | | message: '执行失败!', |
| | | duration: 15 |
| | | }) |
| | | } else if (errorType === 'E') { |
| | | Modal.error({ |
| | | title: '执行失败!' |
| | | }) |
| | | } else if (errorType === 'NM') { |
| | | message.error('执行失败!') |
| | | } |
| | | } |
| | | |
| | | timeChange = (val, type) => { |
| | | const { verify } = this.state |
| | | |
| | | this.setState({ |
| | | verify: {...verify, [type]: val} |
| | | }) |
| | | } |
| | | |
| | | render() { |
| | | const { getFieldDecorator } = this.props.form |
| | | const { verify, excelColumns, scriptsColumns } = this.state |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 8 } |
| | | }, |
| | | wrapperCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 16 } |
| | | } |
| | | } |
| | | |
| | | return ( |
| | | <div id="verify-excel-box-tab"> |
| | | <Tabs defaultActiveKey="1" className="verify-card-box" onChange={this.tabchange}> |
| | | <TabPane tab="基础验证" key="1"> |
| | | <Form {...formItemLayout}> |
| | | <Row gutter={24}> |
| | | <Col span={8}> |
| | | <Form.Item label={this.props.dict['header.form.tablename']}> |
| | | {getFieldDecorator('sheet', { |
| | | initialValue: verify.sheet || '', |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: this.props.dict['form.required.input'] + this.props.dict['header.form.tablename'] + '!' |
| | | }, |
| | | { |
| | | pattern: formRule.table.pattern, |
| | | message: formRule.table.message |
| | | }, { |
| | | max: formRule.table.max, |
| | | message: formRule.table.maxMessage |
| | | } |
| | | ] |
| | | })(<Input placeholder="" autoComplete="off" onChange={this.sheetChange} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={8}> |
| | | <Form.Item label={'忽略行'}> |
| | | <InputNumber min={0} max={100} precision={0} defaultValue={0} onChange={this.rangeChange} /> |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | </Form> |
| | | </TabPane> |
| | | <TabPane tab="Excel列设置" key="2x"> |
| | | <ColumnForm |
| | | dict={this.props.dict} |
| | | range={verify.range} |
| | | columnChange={this.columnChange} |
| | | wrappedComponentRef={(inst) => this.columnForm = inst} |
| | | /> |
| | | <Table |
| | | bordered |
| | | rowKey="uuid" |
| | | className="custom-table" |
| | | dataSource={verify.columns} |
| | | columns={excelColumns} |
| | | pagination={false} |
| | | /> |
| | | </TabPane> |
| | | <TabPane tab="自定义脚本" key="6"> |
| | | <CustomScript |
| | | usefulfields={verify.columns} |
| | | dict={this.props.dict} |
| | | scriptsChange={this.scriptsChange} |
| | | wrappedComponentRef={(inst) => this.scriptsForm = inst} |
| | | /> |
| | | <Table |
| | | bordered |
| | | rowKey="uuid" |
| | | className="custom-table" |
| | | dataSource={verify.scripts} |
| | | columns={scriptsColumns} |
| | | pagination={false} |
| | | /> |
| | | </TabPane> |
| | | <TabPane tab="信息提示" key="7"> |
| | | <Form {...formItemLayout}> |
| | | <Row gutter={24}> |
| | | <Col offset={6} span={6}> |
| | | <Form.Item label={'提示编码'}> |
| | | <span className="errorval"> S </span> |
| | | <Button onClick={() => {this.showError('S')}} type="primary" size="small"> |
| | | 查看 |
| | | </Button> |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={8}> |
| | | <Form.Item label={'停留时间'}> |
| | | <InputNumber defaultValue={2} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'stime')}} /> |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | <Row gutter={24}> |
| | | <Col offset={6} span={6}> |
| | | <Form.Item label={'提示编码'}> |
| | | <span className="errorval"> -1 </span> |
| | | 不提示 |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | <Row gutter={24}> |
| | | <Col offset={6} span={6}> |
| | | <Form.Item label={'提示编码'}> |
| | | <span className="errorval"> N </span> |
| | | <Button onClick={() => {this.showError('N')}} type="primary" size="small"> |
| | | 查看 |
| | | </Button> |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={8}> |
| | | <Form.Item label={'停留时间'}> |
| | | <InputNumber defaultValue={15} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'ntime')}} /> |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | <Row gutter={24}> |
| | | <Col offset={6} span={6}> |
| | | <Form.Item label={'提示编码'}> |
| | | <span className="errorval"> F </span> |
| | | <Button onClick={() => {this.showError('F')}} type="primary" size="small"> |
| | | 查看 |
| | | </Button> |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={8}> |
| | | <Form.Item label={'停留时间'}> |
| | | <InputNumber defaultValue={15} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'ftime')}} /> |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | <Row gutter={24}> |
| | | <Col offset={6} span={6}> |
| | | <Form.Item label={'提示编码'}> |
| | | <span className="errorval"> E </span> |
| | | <Button onClick={() => {this.showError('E')}} type="primary" size="small"> |
| | | 查看 |
| | | </Button> |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | <Row gutter={24}> |
| | | <Col offset={6} span={6}> |
| | | <Form.Item label={'提示编码'}> |
| | | <span className="errorval"> NM </span> |
| | | <Button onClick={() => {this.showError('NM')}} type="primary" size="small"> |
| | | 查看 |
| | | </Button> |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | </Form> |
| | | </TabPane> |
| | | </Tabs> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default Form.create()(VerifyCard) |
New file |
| | |
| | | .verify-card-box { |
| | | .ant-tabs-nav-scroll { |
| | | text-align: center; |
| | | } |
| | | .ant-tabs-content { |
| | | min-height: 40vh; |
| | | } |
| | | table tr td { |
| | | word-wrap: break-word; |
| | | word-break: break-word; |
| | | } |
| | | .ant-input-number { |
| | | width: 100%; |
| | | } |
| | | .verify-form { |
| | | .sql { |
| | | .ant-col-sm-8 { |
| | | width: 10.5%; |
| | | } |
| | | .ant-col-sm-16 { |
| | | width: 89.5%; |
| | | padding-top: 4px; |
| | | } |
| | | } |
| | | .sqlfield { |
| | | .ant-form-item { |
| | | margin-bottom: 5px; |
| | | } |
| | | .ant-col-sm-8 { |
| | | width: 10.5%; |
| | | } |
| | | .ant-col-sm-16 { |
| | | width: 89.5%; |
| | | } |
| | | } |
| | | .add { |
| | | padding-top: 4px; |
| | | } |
| | | } |
| | | .custom-table .ant-empty { |
| | | margin: 20px 8px!important; |
| | | } |
| | | .errorval { |
| | | display: inline-block; |
| | | width: 30px; |
| | | } |
| | | .operation-btn { |
| | | display: inline-block; |
| | | font-size: 16px; |
| | | padding: 0 5px; |
| | | cursor: pointer; |
| | | } |
| | | } |
| | |
| | | toggleEdit = () => { |
| | | const editing = !this.state.editing |
| | | this.setState({ editing }, () => { |
| | | if (editing) { |
| | | if (editing && this.input && this.input.select) { |
| | | this.input.select() |
| | | } else if (editing && this.input && this.input.focus) { |
| | | this.input.focus() |
| | | } |
| | | }) |
| | |
| | | |
| | | if (props.type === 'link') { |
| | | _width = '27%' |
| | | } else { |
| | | } else if (props.type === 'select') { |
| | | _width = Math.floor(80 / (props.linkSubFields.length + 2)) + '%' |
| | | fields = props.linkSubFields.map(field => { |
| | | return { |
| | |
| | | dataIndex: 'operation', |
| | | render: (text, record) => |
| | | this.state.dataSource.length >= 1 ? ( |
| | | <Popconfirm title="Sure to delete?" onConfirm={() => this.handleDelete(record.key)}> |
| | | <span style={{color: '#1890ff', cursor: 'pointer'}}><Icon type="delete" /></span> |
| | | </Popconfirm> |
| | | <div> |
| | | <span className="operation-btn" title={props.dict['header.form.up']} onClick={() => this.handleUpDown(record, 'up')} style={{color: '#1890ff'}}><Icon type="arrow-up" /></span> |
| | | <span className="operation-btn" title={props.dict['header.form.down']} onClick={() => this.handleUpDown(record, 'down')} style={{color: '#ff4d4f'}}><Icon type="arrow-down" /></span> |
| | | <Popconfirm |
| | | title={props.dict['header.form.query.delete']} |
| | | okText={props.dict['header.confirm']} |
| | | cancelText={props.dict['header.cancel']} |
| | | onConfirm={() => this.handleDelete(record.key) |
| | | }> |
| | | <span style={{color: '#1890ff', cursor: 'pointer'}}><Icon type="delete" /></span> |
| | | </Popconfirm> |
| | | </div> |
| | | ) : null, |
| | | } |
| | | ] |
| | |
| | | type: props.type, |
| | | linkSubFields: props.linkSubFields |
| | | } |
| | | } |
| | | |
| | | handleUpDown = (record, direction) => { |
| | | const { dataSource } = this.state |
| | | let index = 0 |
| | | |
| | | let _data = dataSource.filter((item, i) => { |
| | | if (item.key === record.key) { |
| | | index = i |
| | | } |
| | | |
| | | return item.key !== record.key |
| | | }) |
| | | if ((index === 0 && direction === 'up') || (index === dataSource.length - 1 && direction === 'down')) { |
| | | return |
| | | } |
| | | |
| | | if (direction === 'up') { |
| | | _data.splice(index - 1, 0, record) |
| | | } else { |
| | | _data.splice(index + 1, 0, record) |
| | | } |
| | | |
| | | this.setState({ |
| | | dataSource: _data |
| | | }) |
| | | } |
| | | |
| | | handleDelete = key => { |
| | |
| | | let dataSource = JSON.parse(JSON.stringify(this.state.dataSource)) |
| | | let _width = '40%' |
| | | let fields = [] |
| | | |
| | | console.log(linkSubFields) |
| | | if (type === 'select' && linkSubFields.length > this.state.linkSubFields) { |
| | | let addcol = linkSubFields[linkSubFields.length - 1] |
| | | dataSource = dataSource.map(data => { |
| | | data[addcol.field] = data.Text |
| | | return data |
| | | }) |
| | | console.log(addcol) |
| | | } |
| | | // console.log(linkSubFields) |
| | | // console.log(type) |
| | | // console.log(dataSource) |
| | | |
| | | if (type === 'link') { |
| | | _width = '27%' |
| | | } else { |
| | | } else if (type === 'select') { |
| | | _width = Math.floor(80 / (linkSubFields.length + 2)) + '%' |
| | | fields = linkSubFields.map(field => { |
| | | return { |
| | |
| | | } |
| | | }) |
| | | } |
| | | |
| | | console.log(fields) |
| | | |
| | | let columns = [ |
| | | { |
| | |
| | | dataIndex: 'operation', |
| | | render: (text, record) => |
| | | this.state.dataSource.length >= 1 ? ( |
| | | <Popconfirm title="Sure to delete?" onConfirm={() => this.handleDelete(record.key)}> |
| | | <span style={{color: '#1890ff', cursor: 'pointer'}}><Icon type="delete" /></span> |
| | | </Popconfirm> |
| | | <div> |
| | | <span className="operation-btn" title={this.props.dict['header.form.up']} onClick={() => this.handleUpDown(record, 'up')} style={{color: '#1890ff'}}><Icon type="arrow-up" /></span> |
| | | <span className="operation-btn" title={this.props.dict['header.form.down']} onClick={() => this.handleUpDown(record, 'down')} style={{color: '#ff4d4f'}}><Icon type="arrow-down" /></span> |
| | | <Popconfirm |
| | | title={this.props.dict['header.form.query.delete']} |
| | | okText={this.props.dict['header.confirm']} |
| | | cancelText={this.props.dict['header.cancel']} |
| | | onConfirm={() => this.handleDelete(record.key) |
| | | }> |
| | | <span style={{color: '#1890ff', cursor: 'pointer'}}><Icon type="delete" /></span> |
| | | </Popconfirm> |
| | | </div> |
| | | ) : null, |
| | | } |
| | | ] |
| | |
| | | } |
| | | |
| | | UNSAFE_componentWillReceiveProps (nextProps) { |
| | | if (this.props.type !== nextProps.type) { |
| | | this.resetColumn(nextProps.type) |
| | | } else if (!is(fromJS(this.props.linkSubFields), fromJS(nextProps.linkSubFields))) { |
| | | this.resetColumn(this.props.type, nextProps.linkSubFields) |
| | | if (!is(fromJS(this.props.linkSubFields), fromJS(nextProps.linkSubFields)) || this.props.type !== nextProps.type) { |
| | | this.resetColumn(nextProps.type, nextProps.linkSubFields) |
| | | } |
| | | } |
| | | |
| | |
| | | margin: 0; |
| | | } |
| | | } |
| | | .operation-btn { |
| | | margin-right: 10px; |
| | | cursor: pointer; |
| | | } |
| | | } |
| | |
| | | multiselectChange = (key, value, options) => { |
| | | if (key === 'linkSubField') { |
| | | let arr = [] |
| | | let linkSubFields = options.filter(option => { |
| | | let linkSubField = {} |
| | | options.forEach(option => { |
| | | if (!['Value', 'Text'].includes(option.field) && value.includes(option.field) && !arr.includes(option.field)) { |
| | | arr.push(option.field) |
| | | return true |
| | | } else { |
| | | return false |
| | | linkSubField[option.field] = option |
| | | } |
| | | }) |
| | | |
| | | let linkSubFields = [] |
| | | value.forEach(item => { |
| | | if (linkSubField[item]) { |
| | | linkSubFields.push(linkSubField[item]) |
| | | } |
| | | }) |
| | | |
| | |
| | | } else if (item.type === 'options') { |
| | | fields.push( |
| | | <Col span={20} offset={4} key={index}> |
| | | <EditTable data={item.initVal} type={this.state.openType} linkSubFields={this.state.linkSubFields} ref="editTable"/> |
| | | <EditTable data={item.initVal} dict={this.props.dict} type={this.state.openType} linkSubFields={this.state.linkSubFields} ref="editTable"/> |
| | | </Col> |
| | | ) |
| | | } |
| | |
| | | innerPattern: '[0-9a-zA-Z_]*', |
| | | innerMessage: '内部函数名称只允许包含数字、字母和下划线,且以指定字符开始。' |
| | | }, |
| | | table: { // 函数名 |
| | | max: 100, |
| | | pattern: /^[0-9a-zA-Z_]*$/, |
| | | message: '表名只允许包含数字、字母和下划线。', |
| | | maxMessage: '表名不超过100个字符。' |
| | | }, |
| | | textarea: { |
| | | max: 1024, |
| | | message: '长文本最多1024个字符。' |
| | |
| | | } |
| | | |
| | | /** |
| | | * @description 获取excel导入参数 |
| | | * @return {String} btn 按钮 |
| | | * @return {String} data excel数据 |
| | | */ |
| | | static getExcelInSql (item, data, dict) { |
| | | let btn = item.verify |
| | | let keys = ['delete', 'drop', 'insert', 'truncate', 'update'] |
| | | |
| | | let errors = [] |
| | | let _topline = btn.range || 0 |
| | | let _Ltext = data.map((item, lindex) => { |
| | | let vals = btn.columns.map((col, cindex) => { |
| | | let val = item[col.Column] !== undefined ? item[col.Column] : '' |
| | | let _position = (_topline + lindex + 1) + dict['main.excel.line'] + ' ' + (cindex + 1) + dict['main.excel.column'] + ' ' |
| | | |
| | | if (/^Nvarchar/ig.test(col.type)) { |
| | | if (typeof(val) === 'number') { |
| | | val = val.toString() |
| | | } |
| | | |
| | | val = val.replace(/(^\s*$)|\t*|\v*/ig, '') |
| | | |
| | | let limitlen = col.type.match(/\d+/)[0] |
| | | |
| | | if (!val && col.required === 'true') { // 必填校验 |
| | | let _error = _position + dict['main.excel.content.emptyerror'] |
| | | errors.push(_error) |
| | | } else if (val.length > limitlen) { // 长度校验 |
| | | let _error = _position + dict['main.excel.content.maxlimit'] |
| | | errors.push(_error) |
| | | } else { // 关键字校验 |
| | | keys.forEach(key => { |
| | | let _patten = new RegExp('(^' + key + '\\s+)|(\\s+' + key + '\\s+)', 'ig') |
| | | if (_patten.test(val)) { |
| | | let _error = _position + dict['main.excel.includekey'] + key |
| | | errors.push(_error) |
| | | } |
| | | }) |
| | | } |
| | | } else if (/^int/ig.test(col.type)) { |
| | | if (typeof(val) !== 'number' || parseInt(val) < parseFloat(val)) { // 检验是否为整数 |
| | | let _error = _position + dict['main.excel.content.interror'] |
| | | errors.push(_error) |
| | | } else if ((col.min || col.min === 0) && val < col.min) { // 最小值检验 |
| | | let _error = _position + dict['main.excel.content.limitmin'] |
| | | errors.push(_error) |
| | | } else if ((col.max || col.max === 0) && val > col.max) { // 最大值检验 |
| | | let _error = _position + dict['main.excel.content.limitmax'] |
| | | errors.push(_error) |
| | | } |
| | | } else if (/^Decimal/ig.test(col.type)) { |
| | | let _val = val + '' |
| | | _val = _val.split('.') |
| | | let limitlen = col.type.match(/\d+/ig)[1] |
| | | |
| | | if (typeof(val) !== 'number') { // 检验是否为浮点数 |
| | | let _error = _position + dict['main.excel.content.floaterror'] |
| | | errors.push(_error) |
| | | } else if (_val[0].length > 18) { // 检验整数位 |
| | | let _error = _position + dict['main.excel.content.floatIntover'] |
| | | errors.push(_error) |
| | | } else if (_val[1] && _val[1].length > limitlen) { // 最小值检验 |
| | | let _error = _position + dict['main.excel.content.floatPointover'] |
| | | errors.push(_error) |
| | | } else if ((col.min || col.min === 0) && val < col.min) { // 最小值检验 |
| | | let _error = _position + dict['main.excel.content.limitmin'] |
| | | errors.push(_error) |
| | | } else if ((col.max || col.max === 0) && val > col.max) { // 最大值检验 |
| | | let _error = _position + dict['main.excel.content.limitmax'] |
| | | errors.push(_error) |
| | | } |
| | | } |
| | | |
| | | return `'${val}' as ${col.Column}` |
| | | }) |
| | | |
| | | if (!item.innerFunc) { |
| | | vals.push(`@upid+'${this.getuuid()}' as jskey`) |
| | | } |
| | | |
| | | return `Select ${vals.join(',')}` |
| | | }) |
| | | |
| | | _Ltext = _Ltext.join(' Union all ') |
| | | |
| | | let _sql = '' |
| | | |
| | | if (!item.innerFunc) { |
| | | let declarefields = [] |
| | | let fields = [] |
| | | let timestamp = new Date().getTime() |
| | | |
| | | btn.columns.forEach(col => { |
| | | declarefields.push(`${col.Column} ${col.type}`) |
| | | fields.push(col.Column) |
| | | }) |
| | | |
| | | fields = fields.join(',') |
| | | |
| | | _sql = `declare @${btn.sheet} table (${declarefields.join(',')},jskey nvarchar(50) ) |
| | | Declare @UserName nvarchar(50),@FullName nvarchar(50) ,@upid nvarchar(50) |
| | | select @UserName=UserName,@FullName=FullName from SUsers where UID=@UserID@ |
| | | |
| | | set @upid='${timestamp}' |
| | | |
| | | Insert into @${btn.sheet} (${fields},jskey) |
| | | ${_Ltext} |
| | | |
| | | Insert into ${btn.sheet} (${fields},createuserid,createuser,createstaff,bid,upid) |
| | | Select ${fields},@userid@,@username,@fullname,@BID@,@upid From @${btn.sheet} |
| | | |
| | | Delete @${btn.sheet}` |
| | | |
| | | } else { |
| | | _sql = _Ltext |
| | | } |
| | | |
| | | console.log(_sql) |
| | | return { |
| | | sql: _sql, |
| | | errors: errors.join('; ') |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @description 使用系统函数时(sPC_TableData_InUpDe ),生成sql语句 |
| | | * @return {String} type 执行类型 |
| | | * @return {String} table 表名 |
| | |
| | | ` |
| | | } |
| | | |
| | | // 添加时主键为空 |
| | | if (btn.sqlType === 'insert') { |
| | | primaryId = '' |
| | | } |
| | | // 添加时主键为空 改为前台生成 |
| | | // if (btn.sqlType === 'insert') { |
| | | // primaryId = '' |
| | | // } |
| | | |
| | | // 去除禁用的验证 |
| | | if (verify.contrasts) { |
| | |
| | | } |
| | | }) |
| | | |
| | | if (!keys.includes(primaryKey)) { |
| | | keys.push(primaryKey) |
| | | values.push('\'' + primaryId + '\'') |
| | | } |
| | | if (!keys.includes('createuserid')) { |
| | | keys.push('createuserid') |
| | | values.push('@userid@') |