| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { fromJS } from 'immutable' |
| | | import { Form, Tabs, Popconfirm, notification, Modal, Typography, Spin, message } from 'antd' |
| | | import { StopOutlined, CheckCircleOutlined, EditOutlined, SwapOutlined, DeleteOutlined, CopyOutlined } from '@ant-design/icons' |
| | | import { Form, Tabs, Popconfirm, notification, Modal, Typography, Spin, message, Button, Input, Switch } from 'antd' |
| | | import { StopOutlined, CheckCircleOutlined, TableOutlined, EditOutlined, SwapOutlined, DeleteOutlined, CopyOutlined, BorderOutlined, SnippetsOutlined } from '@ant-design/icons' |
| | | import moment from 'moment' |
| | | |
| | | import Api from '@/api' |
| | | import Utils from '@/utils/utils.js' |
| | | |
| | | import { formatSearch, joinMainSearchkey } from '@/utils/utils-custom.js' |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import ColForm from './columnform' |
| | | import CustomScriptsForm from './customscript' |
| | | import SettingForm from './settingform' |
| | | import PasteForm from '@/templates/zshare/pasteform' |
| | | import SettingUtils from './utils' |
| | | import MKEmitter from '@/utils/events.js' |
| | | import MinView from '@/assets/img/minview.png' |
| | | import './index.scss' |
| | | |
| | | const { TabPane } = Tabs |
| | | const { Paragraph } = Typography |
| | | const { Search } = Input |
| | | const { confirm } = Modal |
| | | |
| | | const ExcelOut = asyncComponent(() => import('./excelout')) |
| | | const CodeMirror = asyncComponent(() => import('@/templates/zshare/codemirror')) |
| | | const FieldsComponent = asyncComponent(() => import('@/templates/sharecomponent/fieldscomponent')) |
| | | const EditTable = asyncComponent(() => import('@/templates/zshare/editTable')) |
| | | |
| | | class VerifyCard extends Component { |
| | | static propTpyes = { |
| | | dict: PropTypes.object, // 字典项 |
| | | config: PropTypes.object, // 组件配置信息 |
| | | config: PropTypes.object, |
| | | updRecord: PropTypes.func |
| | | } |
| | | |
| | | state = { |
| | | columns: [], |
| | | debugId: '', |
| | | subColumns: [], |
| | | activeKey: 'setting', |
| | | loading: false, |
| | | initsql: '', // sql验证时变量声明及赋值 |
| | | skip: false, |
| | | colLoading: false, |
| | | searchKey: '', |
| | | usefulfields: '', |
| | | defaultsql: '', // 默认Sql |
| | | defaultSearch: '', |
| | | defaultsql: '', |
| | | systemScripts: [], |
| | | median: {}, |
| | | visible: false, |
| | | editLineId: '', |
| | | pvisible: false, |
| | | reload: false, |
| | | script: null, |
| | | oriConfig: null, |
| | | scriptValue: '', |
| | | cols: null, |
| | | hasMainSearch: false, |
| | | colColumns: [ |
| | | { |
| | | title: '名称', |
| | | dataIndex: 'label', |
| | | inputType: 'input', |
| | | editable: true, |
| | | searchable: true, |
| | | copy: true, |
| | | width: '28%' |
| | | }, |
| | | { |
| | |
| | | inputType: 'input', |
| | | editable: true, |
| | | unique: true, |
| | | strict: true, |
| | | searchable: true, |
| | | copy: true, |
| | | rules: [{ |
| | | pattern: /^[\u4E00-\u9FA50-9a-zA-Z_]*$/ig, |
| | | message: '字段名只允许包含数字、字母、汉字以及_' |
| | | }], |
| | | width: '28%' |
| | | }, |
| | | { |
| | |
| | | { value: 'Nvarchar(20)', text: 'Nvarchar(20)' }, |
| | | { value: 'Nvarchar(50)', text: 'Nvarchar(50)' }, |
| | | { value: 'Nvarchar(100)', text: 'Nvarchar(100)' }, |
| | | { value: 'Nvarchar(256)', text: 'Nvarchar(256)' }, |
| | | { value: 'Nvarchar(512)', text: 'Nvarchar(512)' }, |
| | | { value: 'Nvarchar(1024)', text: 'Nvarchar(1024)' }, |
| | | { value: 'Nvarchar(2048)', text: 'Nvarchar(2048)' }, |
| | | { value: 'Nvarchar(4000)', text: 'Nvarchar(4000)' }, |
| | | { value: 'Nvarchar(max)', text: 'Nvarchar(max)' }, |
| | | { value: 'Int', text: 'Int' }, |
| | | { value: 'Decimal(18,0)', text: 'Decimal(18,0)' }, |
| | |
| | | { value: 'datetime', text: 'datetime' }, |
| | | ], |
| | | editable: true, |
| | | copy: true, |
| | | width: '25%', |
| | | } |
| | | ], |
| | |
| | | { |
| | | title: 'SQL', |
| | | dataIndex: 'sql', |
| | | width: '72%', |
| | | width: '65%', |
| | | render: (text) => { |
| | | let title = text.match(/^\s*\/\*.+\*\//) |
| | | title = title && title[0] ? title[0] : '' |
| | |
| | | } |
| | | }, |
| | | { |
| | | title: '执行位置', |
| | | dataIndex: 'position', |
| | | width: '10%', |
| | | render: (text, record) => { |
| | | if (record.position === 'back') { |
| | | return <span style={{color: '#1890ff'}}>后置</span> |
| | | } else { |
| | | return <span style={{color: '#26C281'}}>前置</span> |
| | | } |
| | | } |
| | | }, |
| | | { |
| | | title: '状态', |
| | | dataIndex: 'status', |
| | | width: '13%', |
| | | width: '10%', |
| | | render: (text, record) => record.status === 'false' ? |
| | | ( |
| | | <div style={{color: '#ff4d4f'}}> |
| | | {this.props.dict['model.status.forbidden']} |
| | | 禁用 |
| | | <StopOutlined style={{marginLeft: '5px'}} /> |
| | | </div> |
| | | ) : |
| | | ( |
| | | <div style={{color: '#26C281'}}> |
| | | {this.props.dict['model.status.open']} |
| | | 启用 |
| | | <CheckCircleOutlined style={{marginLeft: '5px'}}/> |
| | | </div> |
| | | ) |
| | |
| | | dataIndex: 'operation', |
| | | render: (text, record) => |
| | | (<div style={{textAlign: 'center'}}> |
| | | <span className="operation-btn" title={this.props.dict['model.edit']} onClick={() => this.handleEdit(record)} style={{color: '#1890ff'}}><EditOutlined /></span> |
| | | <span className="operation-btn" title={this.props.dict['model.status.change']} onClick={() => this.handleStatus(record)} style={{color: '#8E44AD'}}><SwapOutlined /></span> |
| | | <span className="operation-btn" title="编辑" onClick={() => this.handleEdit(record)} style={{color: '#1890ff'}}><EditOutlined /></span> |
| | | <span className="operation-btn" title="状态切换" onClick={() => this.handleStatus(record)} style={{color: '#8E44AD'}}><SwapOutlined /></span> |
| | | <Popconfirm |
| | | overlayClassName="popover-confirm" |
| | | title={this.props.dict['model.query.delete']} |
| | | title="确定删除吗?" |
| | | onConfirm={() => this.deleteScript(record) |
| | | }> |
| | | <span className="operation-btn" style={{color: '#ff4d4f'}}><DeleteOutlined /></span> |
| | | </Popconfirm> |
| | | <span className="anticon operation-btn" style={{color: '#4D6BFE'}} onClick={() => { |
| | | if (record.sql) { |
| | | sessionStorage.setItem('deepseek_sql', `对以下sql server脚本,编写注释,不能用--,只能用/**/ ,@bid@是上级组件id,@id@是当前行数据id,@userid@为当前登录用户id,所有字段不要用..来省略,不要增加过多的回车改变原有格式,这样会影响代码的可读性,如果代码太长一条回复不完,就回复多条信息完成\n${record.sql}`) |
| | | |
| | | window.open('#/ai') |
| | | |
| | | setTimeout(() => { |
| | | sessionStorage.removeItem('deepseek_sql') |
| | | }, 0) |
| | | } |
| | | }}> |
| | | <svg viewBox="0 0 1391 1024" width="20px" fill="currentColor"> |
| | | <path d="M1361.92 83.136c-14.272-7.04-20.416 6.272-28.736 12.992-2.816 2.24-5.248 5.12-7.68 7.68-20.8 22.336-45.056 36.864-76.8 35.136-46.464-2.56-86.08 12.032-121.152 47.616-7.552-43.904-32.256-70.08-69.888-86.912-19.712-8.768-39.68-17.472-53.376-36.48-9.664-13.44-12.288-28.48-17.216-43.264-3.008-8.96-6.08-18.112-16.32-19.712-11.2-1.728-15.552 7.68-19.968 15.424-17.536 32.128-24.32 67.52-23.68 103.296 1.6 80.448 35.52 144.576 103.04 190.144 7.68 5.312 9.6 10.56 7.168 18.176-4.608 15.68-10.048 30.976-14.912 46.592-3.072 10.112-7.68 12.352-18.304 8a308.224 308.224 0 0 1-97.28-66.176c-48-46.4-91.392-97.664-145.472-137.792a655.36 655.36 0 0 0-38.528-26.432c-55.232-53.76 7.232-97.792 21.632-103.04 15.104-5.376 5.312-24.128-43.52-23.936C652.032 24.704 607.36 41.024 550.4 62.72a156.8 156.8 0 0 1-26.048 7.68 542.016 542.016 0 0 0-161.408-5.696c-105.6 11.904-189.888 61.824-251.904 147.2C36.608 314.24 19.072 430.848 40.512 552.32c22.528 128 87.808 234.048 188.16 316.992 104 85.888 223.808 128 360.512 120 82.944-4.864 175.424-16 279.68-104.32 26.368 13.056 53.888 18.24 99.712 22.272 35.2 3.328 69.184-1.792 95.424-7.232 41.216-8.704 38.4-46.848 23.424-53.888-120.576-56.32-94.208-33.408-118.272-51.84 61.376-72.768 153.792-148.224 189.952-392.768 2.816-19.392 0.384-31.552 0-47.36-0.256-9.536 1.92-13.312 12.8-14.4a231.04 231.04 0 0 0 86.592-26.56c78.272-42.88 109.696-113.024 117.184-197.184 1.088-12.928-0.256-26.24-13.76-32.96z m-681.408 757.76c-116.928-92.096-173.696-122.368-197.12-120.96-21.888 1.152-17.984 26.304-13.184 42.624 5.12 16.128 11.648 27.328 20.8 41.408 6.464 9.408 10.752 23.424-6.272 33.92-37.76 23.424-103.232-7.872-106.24-9.472-76.288-44.8-140.032-104.192-184.96-185.344-43.264-78.08-68.48-161.92-72.576-251.328-1.152-21.632 5.184-29.312 26.688-33.152a265.6 265.6 0 0 1 85.696-2.24c119.296 17.472 220.928 71.04 306.048 155.52 48.768 48.32 85.504 105.92 123.392 162.176 40.256 59.776 83.648 116.672 138.88 163.392 19.392 16.32 35.072 28.8 49.92 37.952-44.928 5.056-119.872 6.08-171.008-34.496z m56.064-361.024a17.152 17.152 0 1 1 2.752 9.6 16.896 16.896 0 0 1-2.752-9.664z m174.08 89.472a102.72 102.72 0 0 1-33.024 8.96 70.528 70.528 0 0 1-44.736-14.272c-15.296-12.8-26.176-19.968-30.848-42.496a99.264 99.264 0 0 1 0.832-32.96c4.032-18.368-0.384-30.08-13.248-40.768-10.624-8.768-23.872-11.072-38.592-11.072a31.168 31.168 0 0 1-14.272-4.416c-6.144-3.072-11.136-10.752-6.336-20.16 1.536-3.008 8.96-10.304 10.752-11.712 19.84-11.328 42.88-7.68 64.192 0.896 19.712 8.064 34.56 22.848 56 43.776 21.952 25.28 25.792 32.384 38.4 51.328 9.856 14.848 18.816 30.208 24.96 47.616 3.776 10.88-1.152 19.776-14.08 25.28z"></path> |
| | | </svg> |
| | | </span> |
| | | </div>) |
| | | } |
| | | ] |
| | |
| | | let _setting = fromJS(config.setting).toJS() |
| | | let scripts = config.scripts ? fromJS(config.scripts).toJS() : [] |
| | | |
| | | if (window.GLOB.funcs && window.GLOB.funcs.length > 0) { |
| | | window.GLOB.funcs.forEach(m => { |
| | | let reg = new RegExp(`\\/\\*\\$ex@${m.func_code}-begin\\*\\/[\\s\\S]+\\/\\*@ex\\$-end\\*\\/`, 'ig') |
| | | if (_setting.dataresource) { |
| | | _setting.dataresource = _setting.dataresource.replace(reg, `$ex@${m.func_code}@ex$`) |
| | | } |
| | | scripts && scripts.forEach(item => { |
| | | item.sql = item.sql.replace(reg, `$ex@${m.func_code}@ex$`) |
| | | }) |
| | | }) |
| | | // if (window.GLOB.funcs && window.GLOB.funcs.length > 0) { |
| | | // window.GLOB.funcs.forEach(m => { |
| | | // let reg = new RegExp(`\\/\\*\\$ex@${m.func_code}-begin\\*\\/[\\s\\S]+\\/\\*@ex\\$-end\\*\\/`, 'ig') |
| | | // if (_setting.dataresource) { |
| | | // _setting.dataresource = _setting.dataresource.replace(reg, `$ex@${m.func_code}@ex$`) |
| | | // } |
| | | // scripts && scripts.forEach(item => { |
| | | // item.sql = item.sql.replace(reg, `$ex@${m.func_code}@ex$`) |
| | | // }) |
| | | // }) |
| | | // } |
| | | |
| | | let columns = config.columns ? fromJS(config.columns).toJS() : [] |
| | | let subColumns = config.subColumns ? fromJS(config.subColumns).toJS() : [] |
| | | |
| | | if (!config.fixedCol) { |
| | | columns.reverse() |
| | | } |
| | | |
| | | let _search = this.formatSearch(search) |
| | | _search = Utils.joinMainSearchkey(_search) |
| | | |
| | | _search = _search.replace(/@\$@/ig, '') |
| | | _search = _search ? 'where ' + _search : '' |
| | | subColumns.reverse() |
| | | |
| | | columns.forEach(col => { |
| | | if (!col.datatype) return |
| | | if (/^nvarchar/.test(col.datatype)) { |
| | | col.datatype = col.datatype.replace(/^nvarchar/, 'Nvarchar') |
| | | } else if (/^decimal/.test(col.datatype)) { |
| | | col.datatype = col.datatype.replace(/^decimal/, 'Decimal') |
| | | } else if (/^int/.test(col.datatype)) { |
| | | col.datatype = col.datatype.replace(/^int/, 'Int') |
| | | } |
| | | }) |
| | | subColumns.forEach(col => { |
| | | if (!col.datatype) return |
| | | if (/^nvarchar/.test(col.datatype)) { |
| | | col.datatype = col.datatype.replace(/^nvarchar/, 'Nvarchar') |
| | | } else if (/^decimal/.test(col.datatype)) { |
| | | col.datatype = col.datatype.replace(/^decimal/, 'Decimal') |
| | | } else if (/^int/.test(col.datatype)) { |
| | | col.datatype = col.datatype.replace(/^int/, 'Int') |
| | | } |
| | | }) |
| | | |
| | | this.setState({ |
| | | scripts, |
| | | columns: config.columns ? fromJS(config.columns).toJS() : [], |
| | | columns: columns, |
| | | subColumns: subColumns, |
| | | setting: _setting, |
| | | searches: search, |
| | | defaultSearch: _search |
| | | median: _setting, |
| | | searches: formatSearch(search), |
| | | searchKey: '', |
| | | debugId: _setting.debugId || '', |
| | | hasMainSearch: mainSearch && mainSearch.length > 0, |
| | | oriConfig: fromJS({ |
| | | scripts, |
| | | columns: columns, |
| | | subColumns: subColumns, |
| | | setting: _setting |
| | | }).toJS() |
| | | }) |
| | | |
| | | this.getsysScript() |
| | | } |
| | | |
| | | getsysScript = () => { |
| | | if (sessionStorage.getItem('mk_sys_scripts')) { |
| | | this.setState({ |
| | | systemScripts: JSON.parse(sessionStorage.getItem('mk_sys_scripts')) |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let _scriptSql = `Select distinct func+Remark as funcname,longparam, s.Sort from s_custom_script s inner join (select OpenID from sapp where ID=@Appkey@) p on s.openid = case when s.appkey='' then s.openid else p.OpenID end order by s.Sort` |
| | | |
| | | _scriptSql = Utils.formatOptions(_scriptSql) |
| | | _scriptSql = Utils.formatOptions(_scriptSql, 'x') |
| | | |
| | | let _sParam = { |
| | | func: 'sPC_Get_SelectedList', |
| | | LText: _scriptSql, |
| | | obj_name: 'data', |
| | | arr_field: 'funcname,longparam' |
| | | arr_field: 'funcname,longparam', |
| | | exec_type: 'x' |
| | | } |
| | | |
| | | _sParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') |
| | | _sParam.secretkey = Utils.encrypt(_sParam.LText, _sParam.timestamp) |
| | | |
| | | _sParam.secretkey = Utils.encrypt('', _sParam.timestamp) |
| | | _sParam.open_key = Utils.encryptOpenKey(_sParam.secretkey, _sParam.timestamp) // 云端数据验证 |
| | | |
| | | Api.getSystemConfig(_sParam).then(res => { |
| | | Api.getCloudConfig(_sParam).then(res => { |
| | | if (res.status) { |
| | | let _scripts = [] |
| | | |
| | | res.data.forEach(item => { |
| | | let _item = { |
| | | let _scripts = res.data.map(item => { |
| | | return { |
| | | name: item.funcname, |
| | | value: window.decodeURIComponent(window.atob(item.longparam)) |
| | | } |
| | | |
| | | _scripts.push(_item) |
| | | }) |
| | | |
| | | sessionStorage.setItem('mk_sys_scripts', JSON.stringify(_scripts)) |
| | | |
| | | this.setState({ |
| | | systemScripts: _scripts |
| | |
| | | }) |
| | | } |
| | | |
| | | columnChange = (values) => { |
| | | columnChange = (values, resolve) => { |
| | | const { columns } = this.state |
| | | |
| | | let fields = columns.map(item => item.field.toLowerCase()) |
| | |
| | | return |
| | | } |
| | | |
| | | resolve() |
| | | |
| | | values.uuid = Utils.getuuid() |
| | | |
| | | this.setState({ columns: [...columns, values] }) |
| | | this.setState({ columns: [values, ...columns] }) |
| | | } |
| | | |
| | | subColumnChange = (values, resolve) => { |
| | | const { subColumns } = this.state |
| | | |
| | | let fields = subColumns.map(item => item.field.toLowerCase()) |
| | | if (fields.includes(values.field.toLowerCase())) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '字段已存在!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | resolve() |
| | | |
| | | values.uuid = Utils.getuuid() |
| | | |
| | | this.setState({ subColumns: [values, ...subColumns] }) |
| | | } |
| | | |
| | | deleteScript = (record) => { |
| | | this.setState({ scripts: this.state.scripts.filter(item => item.uuid !== record.uuid) }) |
| | | const { script, scripts } = this.state |
| | | |
| | | if (script && script.uuid === record.uuid) { |
| | | this.setState({script: null}) |
| | | } |
| | | |
| | | this.setState({ scripts: scripts.filter(item => item.uuid !== record.uuid) }) |
| | | } |
| | | |
| | | handleEdit = (record) => { |
| | | this.scriptsForm.edit(record) |
| | | |
| | | let node = document.getElementById('model-data-source-wrap').parentNode |
| | | // let node = document.getElementById('mk-scripts-tabpane').parentNode |
| | | let node = document.getElementById('mk-scripts-tabpane') |
| | | |
| | | if (node && node.scrollTop) { |
| | | let inter = Math.ceil(node.scrollTop / 10) |
| | |
| | | if (values.uuid) { |
| | | scripts = scripts.map(item => { |
| | | if (item.uuid === values.uuid) { |
| | | values.$index = item.$index || '' |
| | | return values |
| | | } else { |
| | | return item |
| | |
| | | } |
| | | |
| | | return new Promise((resolve, reject) => { |
| | | this.sqlverify(resolve, reject, false, scripts) |
| | | this.sqlverify(resolve, reject, 'script', scripts) |
| | | }) |
| | | } |
| | | |
| | |
| | | } else { |
| | | values.uuid = Utils.getuuid() |
| | | scripts.push(values) |
| | | MKEmitter.emit('editLineId', values.uuid) |
| | | } |
| | | |
| | | this.setState({ scripts }) |
| | |
| | | search = [...search, ...mainSearch] |
| | | } |
| | | |
| | | let _search = this.formatSearch(search) |
| | | _search = Utils.joinMainSearchkey(_search) |
| | | |
| | | _search = _search.replace(/@\$@/ig, '') |
| | | _search = _search ? 'where ' + _search : '' |
| | | |
| | | this.setState({ |
| | | searches: search, |
| | | defaultSearch: _search, |
| | | searches: formatSearch(search), |
| | | setting: res |
| | | }, () => { |
| | | this.sqlverify(() => { // 验证成功 |
| | |
| | | loading: false |
| | | }) |
| | | this.getdefaultSql() |
| | | }, true) |
| | | }, 'change') |
| | | }) |
| | | }, () => { |
| | | this.setState({loading: false}) |
| | | }) |
| | | } else if (activeKey === 'columns') { |
| | | this.setState({ |
| | | activeKey: val, |
| | | loading: false |
| | | }) |
| | | this.getdefaultSql() |
| | | } else if (activeKey === 'scripts') { |
| | | let _loading = false |
| | | if (this.scriptsForm && this.scriptsForm.state.editItem) { |
| | | _loading = true |
| | | } else if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql') && !/^\s+$/.test(this.scriptsForm.props.form.getFieldValue('sql'))) { |
| | | _loading = true |
| | | } |
| | | |
| | | if (_loading) { |
| | | if (this.datasource && this.datasource.state.editingKey) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '存在未保存脚本,请点击确定保存,或点击取消放弃修改!', |
| | | message: '字段未保存,请保存后切换!', |
| | | duration: 5 |
| | | }) |
| | | this.setState({ |
| | |
| | | activeKey: val, |
| | | loading: false |
| | | }) |
| | | this.getdefaultSql() |
| | | } else if (activeKey === 'subcolumns') { |
| | | if (this.subdatasource && this.subdatasource.state.editingKey) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '字段未保存,请保存后切换!', |
| | | duration: 5 |
| | | }) |
| | | this.setState({ |
| | | loading: false |
| | | }) |
| | | return |
| | | } |
| | | |
| | | this.setState({ |
| | | activeKey: val, |
| | | loading: false |
| | | }) |
| | | } else if (activeKey === 'scripts') { |
| | | let _loading = false |
| | | if (this.scriptsForm && this.scriptsForm.state.editItem) { |
| | | _loading = true |
| | | } else if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql') && !/^\s+$/.test(this.scriptsForm.props.form.getFieldValue('sql'))) { |
| | | _loading = true |
| | | } |
| | | |
| | | if (_loading) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '存在未保存脚本!', |
| | | duration: 5 |
| | | }) |
| | | } |
| | | |
| | | this.setState({ |
| | | activeKey: val, |
| | | loading: false |
| | | }) |
| | | } |
| | | } |
| | | |
| | | getdefaultSql = () => { |
| | | const { columns, setting, defaultSearch } = this.state |
| | | const { columns, setting, searches } = this.state |
| | | let defaultsql = '' |
| | | let arr_field = columns.map(col => col.field).join(',') |
| | | |
| | | let _search = joinMainSearchkey(searches) |
| | | |
| | | if (setting.dataresource) { |
| | | let _dataresource = setting.dataresource |
| | |
| | | _dataresource = '(' + _dataresource + ') tb' |
| | | } |
| | | |
| | | defaultsql = `select top @pageSize@ ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by @orderBy@) as rows from ${_dataresource} ${defaultSearch}) tmptable where rows > (@pageSize@ * (@pageIndex@ - 1)) order by tmptable.rows` |
| | | defaultsql = `select top @pageSize@ ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by @orderBy@) as rows from ${_dataresource} ${_search}) tmptable where rows > (@pageSize@ * (@pageIndex@ - 1)) order by tmptable.rows` |
| | | } |
| | | |
| | | this.setState({defaultsql}) |
| | | } |
| | | |
| | | /** |
| | | * @description 获取全部搜索条件 |
| | | * @param {Array} searches 搜索条件数组 |
| | | */ |
| | | formatSearch (searches) { |
| | | if (!searches) return [] |
| | | |
| | | let newsearches = [] |
| | | searches.forEach(search => { |
| | | if (!search.field) return |
| | | |
| | | let item = { |
| | | key: search.field, |
| | | match: search.match, |
| | | type: search.type, |
| | | label: search.label, |
| | | value: search.initval, |
| | | required: search.required === 'true' |
| | | } |
| | | if (item.type === 'group') { |
| | | item.key = search.datefield |
| | | item.type = 'daterange' |
| | | item.match = 'between' |
| | | item.value = [moment().format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')].join(',') |
| | | |
| | | newsearches.push(item) |
| | | return |
| | | } else if (item.type === 'date') { |
| | | item.value = moment().format('YYYY-MM-DD') |
| | | } else if (item.type === 'datemonth') { |
| | | item.value = moment().format('YYYY-MM') |
| | | } else if (item.type === 'dateweek') { |
| | | item.value = moment().format('YYYY-MM-DD') |
| | | } else if (item.type === 'daterange') { |
| | | item.value = [moment().format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')].join(',') |
| | | } else if (item.type === 'range') { |
| | | |
| | | } else if (item.type === 'multiselect' || (item.type === 'checkcard' && search.multiple === 'true')) { |
| | | item.type = 'multi' |
| | | item.value = '@$@' |
| | | } else { |
| | | item.value = '@$@' |
| | | } |
| | | newsearches.push(item) |
| | | }) |
| | | |
| | | return newsearches |
| | | } |
| | | |
| | | submitDataSource = () => { |
| | | const { config, mainSearch } = this.props |
| | | const { activeKey, setting, columns, scripts } = this.state |
| | | const { activeKey, setting, columns, subColumns, scripts, cols, median, searches } = this.state |
| | | |
| | | if (config.subtype === 'dualdatacard') { |
| | | let arr = columns.map(col => col.field.toLowerCase()) |
| | | let _arr = [] |
| | | subColumns.forEach(col => { |
| | | if (arr.includes(col.field.toLowerCase())) { |
| | | _arr.push(col.field) |
| | | } |
| | | }) |
| | | |
| | | if (_arr.length > 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '子表中字段' + _arr.join('、') + '与主表字段重复!', |
| | | duration: 5 |
| | | }) |
| | | return Promise.reject() |
| | | } |
| | | } else if (config.subtype === 'editable') { |
| | | let _arr = [] |
| | | columns.forEach(col => { |
| | | let key = col.field.toLowerCase() |
| | | if (['jskey', 'data_type', 'bid'].includes(key)) { |
| | | _arr.push(col.field) |
| | | } |
| | | }) |
| | | |
| | | if (_arr.length > 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '字段集中不可使用' + _arr.join('、') + '!注:此字段为提交时的系统字段。', |
| | | duration: 5 |
| | | }) |
| | | return Promise.reject() |
| | | } |
| | | } |
| | | |
| | | if (median.interType === 'system') { |
| | | let _loading = false |
| | | if (this.scriptsForm && this.scriptsForm.state.editItem) { |
| | | _loading = true |
| | | } else if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql') && !/^\s+$/.test(this.scriptsForm.props.form.getFieldValue('sql'))) { |
| | | _loading = true |
| | | } |
| | | |
| | | if (_loading) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '存在未保存脚本,请点击确定保存,或点击取消放弃修改!', |
| | | duration: 5 |
| | | }) |
| | | this.setState({activeKey: 'scripts'}) |
| | | return Promise.reject() |
| | | } |
| | | } |
| | | |
| | | return new Promise((resolve, reject) => { |
| | | if (activeKey === 'setting') { |
| | |
| | | if (res.useMSearch === 'true') { // 使用主搜索条件 |
| | | search = [...search, ...mainSearch] |
| | | } |
| | | |
| | | let _search = this.formatSearch(search) |
| | | _search = Utils.joinMainSearchkey(_search) |
| | | |
| | | _search = _search.replace(/@\$@/ig, '') |
| | | _search = _search ? 'where ' + _search : '' |
| | | let _searches = formatSearch(search) |
| | | |
| | | this.setState({ |
| | | searches: search, |
| | | defaultSearch: _search, |
| | | searches: _searches, |
| | | setting: res |
| | | }, () => { |
| | | this.sqlverify(() => { resolve({setting: res, columns, scripts }) }, reject, false) |
| | | this.sqlverify(() => { resolve({setting: res, columns, subColumns, scripts, cols, searches: _searches }) }, reject, 'submit') |
| | | }) |
| | | }, () => { |
| | | reject() |
| | | }) |
| | | } else if (activeKey === 'columns') { |
| | | this.sqlverify(() => { resolve({setting, columns, scripts }) }, reject, false) |
| | | } else if (activeKey === 'scripts') { |
| | | let _loading = false |
| | | if (this.scriptsForm && this.scriptsForm.state.editItem) { |
| | | _loading = true |
| | | } else if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql') && !/^\s+$/.test(this.scriptsForm.props.form.getFieldValue('sql'))) { |
| | | _loading = true |
| | | } |
| | | |
| | | if (_loading) { |
| | | if (this.datasource && this.datasource.state.editingKey) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '存在未保存脚本,请点击确定保存,或点击取消放弃修改!', |
| | | message: '字段未保存,请保存后提交!', |
| | | duration: 5 |
| | | }) |
| | | reject() |
| | | return |
| | | } |
| | | |
| | | this.sqlverify(() => { resolve({setting, columns, scripts }) }, reject, false) |
| | | this.sqlverify(() => { resolve({setting, columns, subColumns, scripts, cols, searches }) }, reject, 'submit') |
| | | } else if (activeKey === 'subcolumns') { |
| | | if (this.subdatasource && this.subdatasource.state.editingKey) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '字段未保存,请保存后提交!', |
| | | duration: 5 |
| | | }) |
| | | reject() |
| | | return |
| | | } |
| | | this.sqlverify(() => { resolve({setting, columns, subColumns, scripts, cols, searches }) }, reject, 'submit') |
| | | } else if (activeKey === 'scripts') { |
| | | this.sqlverify(() => { resolve({setting, columns, subColumns, scripts, cols, searches }) }, reject, 'submit') |
| | | } |
| | | }) |
| | | } |
| | | |
| | | sqlverify = (resolve, reject, change = false, testScripts) => { |
| | | const { columns, setting, scripts, searches, defaultSearch } = this.state |
| | | closeDataSource = (callback) => { |
| | | const { setting, columns, subColumns, scripts, oriConfig } = this.state |
| | | |
| | | let line = scripts.map(item => item.sql).join('') |
| | | line += columns.map(item => item.field + item.datatype).join('') |
| | | line += subColumns.map(item => item.field + item.datatype).join('') |
| | | line += setting.interType + (setting.dataresource || '') + (setting.order || '') + (setting.primaryKey || '') |
| | | |
| | | let _line = oriConfig.scripts.map(item => item.sql).join('') |
| | | _line += oriConfig.columns.map(item => item.field + item.datatype).join('') |
| | | _line += oriConfig.subColumns.map(item => item.field + item.datatype).join('') |
| | | _line += oriConfig.setting.interType + (oriConfig.setting.dataresource || '') + (oriConfig.setting.order || '') + (oriConfig.setting.primaryKey || '') |
| | | |
| | | if (line !== _line) { |
| | | confirm({ |
| | | content: '数据源已修改,确定取消吗?', |
| | | onOk() { |
| | | callback() |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } else { |
| | | callback() |
| | | } |
| | | } |
| | | |
| | | sqlverify = (resolve, reject, type, testScripts) => { |
| | | const { config } = this.props |
| | | const { columns, setting, scripts, searches, debugId, subColumns } = this.state |
| | | |
| | | let _scripts = scripts.filter(item => item.status !== 'false') |
| | | |
| | | if (testScripts) { |
| | | _scripts = testScripts.filter(item => item.status !== 'false') |
| | | } |
| | | if (!change && setting.interType === 'system' && setting.execute === 'false' && _scripts.length === 0) { |
| | | if (type !== 'change' && setting.interType === 'system' && setting.execute === 'false' && _scripts.length === 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '不执行默认sql时,请添加自定义脚本!', |
| | |
| | | return |
| | | } |
| | | |
| | | if ((setting.interType === 'system' && setting.execute !== 'false') || _scripts.length > 0) { |
| | | let r = SettingUtils.getDebugSql(setting, _scripts, columns, searches, defaultSearch) |
| | | if (type === 'submit' && config.subtype === 'dualdatacard' && setting.subdata === 'sub_data_string' && !columns.find(col => col.field === 'sub_data_string')) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '主表字段集中需添加 sub_data_string 字段!', |
| | | duration: 5 |
| | | }) |
| | | reject() |
| | | return |
| | | } |
| | | |
| | | if (r.error) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: r.error, |
| | | duration: 5 |
| | | if (type === 'change' && columns.length === 0) { |
| | | reject() |
| | | return |
| | | } |
| | | |
| | | if ((setting.interType === 'system' && setting.execute !== 'false') || _scripts.length > 0) { |
| | | let _columns = columns |
| | | if (config.subtype === 'dualdatacard' && setting.subdata !== 'sub_data_string') { |
| | | _columns = [...columns, ...subColumns] |
| | | } |
| | | |
| | | let r = SettingUtils.getDebugSql(setting, _scripts, _columns, searches, config.subtype, config.hasExtend) |
| | | |
| | | if (type === 'submit' && r.custompage && setting.queryType !== 'statistics') { |
| | | Modal.info({ |
| | | title: '数据源或自定义脚本中使用了自定义分页,查询类型请使用统计!', |
| | | }) |
| | | reject() |
| | | return |
| | | } |
| | | if (r.custompage && setting.laypage === 'true' && _columns.findIndex(col => col.field === 'mk_total') === -1) { |
| | | if (config.subtype !== 'basetable') { |
| | | const that = this |
| | | Modal.confirm({ |
| | | title: `数据源或自定义脚本中使用自定义分页排序时,字段集中需要添加 mk_total。`, |
| | | okText: '知道了', |
| | | cancelText: '添加', |
| | | onOk: () => { |
| | | reject() |
| | | }, |
| | | onCancel() { |
| | | let item = { |
| | | field: 'mk_total', |
| | | label: 'mk_total', |
| | | datatype: 'Int', |
| | | uuid: Utils.getuuid() |
| | | } |
| | | |
| | | let param = { |
| | | func: 's_debug_sql', |
| | | exec_type: 'y', |
| | | LText: r.sql |
| | | } |
| | | param.LText = Utils.formatOptions(param.LText) |
| | | param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') |
| | | param.secretkey = Utils.encrypt('', param.timestamp) |
| | | |
| | | let sumParam = null |
| | | if (r.sumSql) { |
| | | sumParam = { |
| | | func: 's_debug_sql', |
| | | exec_type: 'y', |
| | | LText: r.sumSql |
| | | that.setState({ columns: [item, ...columns] }) |
| | | reject() |
| | | } |
| | | }) |
| | | return |
| | | } else { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '数据源或自定义脚本中使用自定义分页排序时,请在显示列中添加 mk_total。', |
| | | duration: 5 |
| | | }) |
| | | } |
| | | sumParam.LText = Utils.formatOptions(sumParam.LText) |
| | | sumParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') |
| | | sumParam.secretkey = Utils.encrypt('', sumParam.timestamp) |
| | | } |
| | | |
| | | Api.getLocalConfig(param).then(result => { |
| | | if (result.status) { |
| | | if (sumParam) { |
| | | Api.getLocalConfig(sumParam).then(res => { |
| | | if (res.status) { |
| | | resolve() |
| | | } else { |
| | | reject() |
| | | Modal.error({ |
| | | title: res.message |
| | | |
| | | if (debugId === r.debugId) { |
| | | resolve() |
| | | return |
| | | } |
| | | |
| | | if (r.errors) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: r.errors, |
| | | duration: 5 |
| | | }) |
| | | } |
| | | |
| | | Api.sDebug(r.sql).then(result => { |
| | | if (result.status || result.ErrCode === '-2') { |
| | | this.setState({debugId: r.debugId}, () => { |
| | | resolve() |
| | | }) |
| | | } else { |
| | | if (/列名\s*'[a-zA-Z0-9_-]+'\s*无效/.test(result.message)) { |
| | | let tail = '' |
| | | let type = '' |
| | | if (setting.execute !== 'false' && setting.queryType !== 'statistics') { |
| | | searches.forEach(item => { |
| | | if (item.forbid) return |
| | | item.key.split(',').forEach(field => { |
| | | if (new RegExp(`'${field}'`).test(result.message)) { |
| | | tail = field |
| | | type = '搜索条件' |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | if (!tail && setting.order) { |
| | | let keys = setting.order.replace(/\s+(asc|desc)/ig, '').replace(/\s+/g, '') |
| | | keys.split(',').forEach(field => { |
| | | if (new RegExp(`'${field}'`).test(result.message)) { |
| | | tail = field |
| | | type = '排序' |
| | | } |
| | | }) |
| | | } |
| | | |
| | | if (!tail) { |
| | | columns.forEach(item => { |
| | | if (new RegExp(`'${item.field}'`).test(result.message)) { |
| | | tail = item.field |
| | | if (config.subtype === 'basetable') { |
| | | type = '显示列' |
| | | } else { |
| | | type = '字段集' |
| | | } |
| | | } |
| | | }) |
| | | if (!tail && config.subtype === 'dualdatacard') { |
| | | subColumns.forEach(item => { |
| | | if (new RegExp(`'${item.field}'`).test(result.message)) { |
| | | tail = item.field |
| | | type = '子表字段集' |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | |
| | | if (tail) { |
| | | result.message = result.message.replace(/ROLLBACK TRANSACTION 请求没有对应的 BEGIN TRANSACTION。/, '') |
| | | result.message = <>{result.message}<span style={{color: 'red'}}>注:{type}中存在字段{tail}</span></> |
| | | } |
| | | } |
| | | if (type === 'submit') { |
| | | Modal.confirm({ |
| | | title: result.message, |
| | | okText: '知道了', |
| | | cancelText: '强制保存', |
| | | onOk: () => { |
| | | reject() |
| | | }, |
| | | onCancel() { |
| | | resolve() |
| | | } |
| | | }) |
| | | } else { |
| | | resolve() |
| | | reject() |
| | | Modal.error({ |
| | | title: result.message, |
| | | okText: '知道了' |
| | | }) |
| | | } |
| | | } else { |
| | | reject() |
| | | Modal.error({ |
| | | title: result.message |
| | | }) |
| | | } |
| | | }) |
| | | } else { |
| | | resolve() |
| | | } |
| | | } |
| | | |
| | | triggerConfirm = () => { |
| | | const { script, scriptValue, scripts, skip } = this.state |
| | | let _scripts = fromJS(scripts).toJS() |
| | | |
| | | if (!scriptValue) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请输入sql!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let editLineId = '' |
| | | if (script) { |
| | | editLineId = script.uuid |
| | | _scripts = _scripts.map(item => { |
| | | if (script.uuid === item.uuid) { |
| | | item.sql = scriptValue |
| | | } |
| | | return item |
| | | }) |
| | | } else { |
| | | let _script = { |
| | | uuid: Utils.getuuid(), |
| | | sql: scriptValue, |
| | | $index: _scripts.length + 1, |
| | | status: 'true' |
| | | } |
| | | |
| | | editLineId = _script.uuid |
| | | _scripts.push(_script) |
| | | } |
| | | |
| | | if (skip) { |
| | | this.setState({scripts: _scripts, script: null, scriptValue: '', editLineId}) |
| | | } else { |
| | | this.setState({loading: true, editLineId}) |
| | | |
| | | this.sqlverify(() => {this.setState({scripts: _scripts, script: null, scriptValue: '', loading: false})}, () => {this.setState({loading: false})}, 'script', _scripts) |
| | | } |
| | | } |
| | | |
| | |
| | | }) |
| | | } |
| | | |
| | | updateSubfields = (columns) => { |
| | | this.setState({ |
| | | subColumns: columns |
| | | }) |
| | | } |
| | | |
| | | copyDatasource = () => { |
| | | const { config } = this.props |
| | | const { columns, subColumns, scripts } = this.state |
| | | |
| | | this.settingForm.handleConfirm().then(res => { |
| | | delete res.supModule |
| | | res.name = config.name |
| | | |
| | | let source = { |
| | | key: 'interface', |
| | | type: 'line', |
| | | data: {setting: res, columns, subColumns, scripts, pageable: false, format: 'array', name: res.name, status: 'false', type: 'interface', uuid: '' } |
| | | } |
| | | |
| | | try { |
| | | source = window.btoa(window.encodeURIComponent(JSON.stringify(source))) |
| | | } catch (e) { |
| | | console.warn('Stringify Failure') |
| | | source = '' |
| | | } |
| | | |
| | | if (source) { |
| | | let oInput = document.createElement('input') |
| | | oInput.value = source |
| | | document.body.appendChild(oInput) |
| | | oInput.select() |
| | | document.execCommand('Copy') |
| | | document.body.removeChild(oInput) |
| | | message.success('复制成功。') |
| | | } |
| | | }) |
| | | } |
| | | |
| | | pasteSubmit = () => { |
| | | const { config } = this.props |
| | | const { setting } = this.state |
| | | |
| | | this.pasteFormRef.handleConfirm().then(res => { |
| | | if (res.key !== 'interface') { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '配置类型错误!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (res.type !== 'line') { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请粘贴单项数据源!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | if (setting.supModule) { |
| | | res.data.setting.supModule = setting.supModule |
| | | } |
| | | |
| | | if (config.subtype !== 'basetable') { |
| | | let subColumns = [] |
| | | |
| | | if (config.subtype === 'dualdatacard' && res.data.subColumns) { |
| | | subColumns = res.data.subColumns.map(col => { |
| | | col.uuid = Utils.getuuid() |
| | | return col |
| | | }) |
| | | } |
| | | |
| | | this.setState({ |
| | | scripts: res.data.scripts.map(col => { |
| | | col.uuid = Utils.getuuid() |
| | | return col |
| | | }), |
| | | columns: res.data.columns.map(col => { |
| | | col.uuid = Utils.getuuid() |
| | | return col |
| | | }), |
| | | subColumns: subColumns, |
| | | setting: res.data.setting, |
| | | median: res.data.setting, |
| | | reload: true, |
| | | pvisible: false |
| | | }, () => { |
| | | this.setState({reload: false}) |
| | | }) |
| | | } else { |
| | | this.setState({ |
| | | scripts: res.data.scripts.map(col => { |
| | | col.uuid = Utils.getuuid() |
| | | return col |
| | | }), |
| | | setting: res.data.setting, |
| | | median: res.data.setting, |
| | | reload: true, |
| | | pvisible: false |
| | | }, () => { |
| | | this.setState({reload: false}) |
| | | }) |
| | | } |
| | | |
| | | this.props.updRecord({...res.data.setting}) |
| | | }) |
| | | } |
| | | |
| | | updateStatus = (res) => { |
| | | this.setState({median: {...res}}) |
| | | this.props.updRecord({...res}) |
| | | } |
| | | |
| | | copyColumns = () => { |
| | | const { columns } = this.state |
| | | const { config } = this.props |
| | | const { columns, subColumns, setting } = this.state |
| | | |
| | | let _columns = columns |
| | | let m = [] |
| | | let n = [] |
| | | let s = [] |
| | | |
| | | if (subColumns && subColumns.length) { |
| | | _columns = [...columns, ...subColumns] |
| | | } |
| | | |
| | | _columns.forEach(col => { |
| | | m.unshift(`${col.field} ${col.datatype}`) |
| | | n.unshift(col.field) |
| | | if (/decimal|int/ig.test(col.datatype)) { |
| | | s.unshift(`${Math.round(Math.random() * 10)} as ${col.field}`) |
| | | } else if (/datetime/.test(col.datatype)) { |
| | | s.unshift(`'${moment().format('YYYY-MM-DD HH:mm:ss')}' as ${col.field}`) |
| | | } else if (/date/.test(col.datatype)) { |
| | | s.unshift(`'${moment().format('YYYY-MM-DD')}' as ${col.field}`) |
| | | } else { |
| | | s.unshift(`'${col.label}' as ${col.field}`) |
| | | } |
| | | }) |
| | | |
| | | if (window.debugger) { |
| | | window.mkInfo('select ' + s.join(', ')) |
| | | } |
| | | |
| | | let extend = '' |
| | | if (config.hasExtend) { |
| | | extend = [] |
| | | let mapCol = (cols) => { |
| | | cols.forEach(col => { |
| | | if (col.type === 'extend') { |
| | | let datatype = 'Nvarchar(50)' |
| | | _columns.forEach(c => { |
| | | if (c.field === col.field) { |
| | | datatype = c.datatype |
| | | } |
| | | }) |
| | | for (let i = 1; i < col.quota; i++) { |
| | | extend.push(`${col.field}${i} ${datatype}`) |
| | | } |
| | | } else if (col.type === 'colspan' && col.subcols) { |
| | | mapCol(col.subcols) |
| | | } |
| | | }) |
| | | } |
| | | mapCol(config.cols) |
| | | extend = ` |
| | | /* 扩展列字段 */ |
| | | /* ${extend.join(',')} */ |
| | | ` |
| | | } |
| | | |
| | | let oInput = document.createElement('input') |
| | | oInput.value = `create table #${setting.tableName || 'tb'} |
| | | (${m.join(',')},sort_id INT IDENTITY(1,1)) |
| | | insert into #${setting.tableName || 'tb'} |
| | | (${n.join(',')}) |
| | | select ${n.join(',')} |
| | | from ${setting.dataresource ? `(${setting.dataresource.replace(/\n/g, ' ')}) tb` : setting.tableName || 'tb'} |
| | | order by @orderBy@ |
| | | |
| | | declare @mk_total int |
| | | set @mk_total = 0 |
| | | |
| | | select @mk_total = count(1) from #${setting.tableName || 'tb'} |
| | | declare @pageIndex_top int |
| | | set @pageIndex_top=(@pageIndex@-1)*@pageSize@ |
| | | |
| | | if @mk_total > @pageIndex@*@pageSize@ |
| | | delete #${setting.tableName || 'tb'} where sort_id > @pageIndex@*@pageSize@ |
| | | |
| | | if @pageIndex_top > 0 |
| | | delete #${setting.tableName || 'tb'} where sort_id <= @pageIndex_top |
| | | |
| | | drop table #${setting.tableName || 'tb'}${extend} |
| | | |
| | | select top 99999 @mk_total as mk_total, * from #${setting.tableName || 'tb'} order by sort_id` |
| | | |
| | | document.body.appendChild(oInput) |
| | | oInput.select() |
| | | document.execCommand('Copy') |
| | | document.body.removeChild(oInput) |
| | | |
| | | message.success('复制成功。') |
| | | } |
| | | |
| | | copySubColumns = () => { |
| | | const { subColumns } = this.state |
| | | let m = [] |
| | | let n = [] |
| | | |
| | | columns.forEach(col => { |
| | | m.push(`${col.field}(${col.label})`) |
| | | subColumns.forEach(col => { |
| | | m.push(`${col.field} ${col.datatype}`) |
| | | n.push(col.field) |
| | | }) |
| | | |
| | |
| | | message.success('复制成功。') |
| | | } |
| | | |
| | | addProcess = () => { |
| | | const { config } = this.props |
| | | const { columns } = this.state |
| | | |
| | | let fields = [] |
| | | let cols = [] |
| | | let _cols = columns.map(item => item.field.toLowerCase()) |
| | | |
| | | if (!_cols.includes('remark_w')) { |
| | | fields.push({ uuid: Utils.getuuid(), label: '备注', field: 'remark_w', datatype: 'Nvarchar(50)', fieldlength: 50, type: 'text' }) |
| | | cols.push({ uuid: Utils.getuuid(), Width: 120, label: '备注', field: 'remark_w', type: 'text', Hide: 'false', IsSort: 'false', fieldlength: 50 }) |
| | | } |
| | | if (!_cols.includes('statusname_w')) { |
| | | fields.push({ uuid: Utils.getuuid(), label: '状态', field: 'statusname_w', datatype: 'Nvarchar(50)', fieldlength: 50, type: 'text' }) |
| | | cols.push({ uuid: Utils.getuuid(), Width: 120, label: '状态', field: 'statusname_w', type: 'text', Hide: 'false', IsSort: 'false', fieldlength: 50 }) |
| | | } |
| | | if (!_cols.includes('works_flow_detail_id')) { |
| | | fields.push({ uuid: Utils.getuuid(), label: '流程节点ID', field: 'works_flow_detail_id', datatype: 'Nvarchar(50)', fieldlength: 50, type: 'text' }) |
| | | cols.push({ uuid: Utils.getuuid(), Width: 120, label: '流程节点ID', field: 'works_flow_detail_id', type: 'text', Hide: 'false', IsSort: 'false', fieldlength: 50 }) |
| | | } |
| | | if (!_cols.includes('works_flow_param')) { |
| | | fields.push({ uuid: Utils.getuuid(), label: '流程参数', field: 'works_flow_param', datatype: 'Nvarchar(512)', fieldlength: 512, type: 'text' }) |
| | | cols.push({ uuid: Utils.getuuid(), Width: 120, label: '流程参数', field: 'works_flow_param', type: 'text', Hide: 'true', IsSort: 'false', fieldlength: 512 }) |
| | | } |
| | | |
| | | if (fields.length === 0) return |
| | | |
| | | const that = this |
| | | |
| | | if (config.subtype !== 'basetable') { |
| | | cols = null |
| | | } |
| | | |
| | | confirm({ |
| | | content: cols ? '显示列中是否添加工作流字段?' : '字段集中是否添加工作流字段?', |
| | | onOk() { |
| | | that.setState({ |
| | | cols: cols, |
| | | columns: [...fields, ...columns] |
| | | }) |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } |
| | | |
| | | updateColumns = (tableName) => { |
| | | const { config } = this.props |
| | | const { colLoading, columns } = this.state |
| | | |
| | | if (colLoading || columns.length > 0) return |
| | | |
| | | if (config.subtype === 'basetable') return |
| | | |
| | | let param = {func: 'sPC_Get_FieldName', TBName: tableName} |
| | | if (window.GLOB.cloudServiceApi) { // 且存在云端地址 |
| | | param.rduri = window.GLOB.cloudServiceApi |
| | | param.userid = sessionStorage.getItem('CloudUserID') || '' |
| | | param.LoginUID = sessionStorage.getItem('CloudLoginUID') || '' |
| | | } |
| | | |
| | | this.setState({colLoading: true}) |
| | | |
| | | Api.getSystemCacheConfig(param).then(result => { |
| | | this.setState({colLoading: false}) |
| | | if (!result.status) return |
| | | |
| | | let fields = [] |
| | | result.FDName.forEach(item => { |
| | | if (item.f_type !== 0) return |
| | | |
| | | if (/nvarchar|int|decimal/ig.test(item.FieldType) || item.FieldType === 'date' || item.FieldType === 'datetime') { |
| | | fields.unshift({ |
| | | uuid: Utils.getuuid(), |
| | | label: item.FieldDec, |
| | | field: item.FieldName, |
| | | datatype: item.FieldType.toLowerCase() |
| | | }) |
| | | } |
| | | }) |
| | | |
| | | if (fields.length === 0) return |
| | | |
| | | this.setState({columns: fields}) |
| | | }, () => { |
| | | this.setState({colLoading: false}) |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 组件销毁,清除state更新 |
| | | */ |
| | |
| | | |
| | | render() { |
| | | const { config } = this.props |
| | | const { columns, setting, scripts, colColumns, scriptsColumns, activeKey, loading, searches, defaultsql } = this.state |
| | | const { columns, subColumns, median, skip, setting, scripts, colColumns, scriptsColumns, activeKey, loading, searches, defaultsql, visible, pvisible, reload, script, scriptValue, searchKey, editLineId, hasMainSearch } = this.state |
| | | |
| | | return ( |
| | | <div id="model-data-source-wrap"> |
| | | <div className="model-data-source-wrap"> |
| | | {config.name ? <div className="mk-com-name">{config.name} - 数据源</div> : null} |
| | | {loading && <Spin size="large" />} |
| | | <Tabs activeKey={activeKey} className="data-source-card-box" onChange={this.changeTab}> |
| | | <TabPane tab="数据源" key="setting"> |
| | | <SettingForm |
| | | dict={this.props.dict} |
| | | <TabPane tab={ |
| | | <span> |
| | | 数据源 |
| | | </span> |
| | | } key="setting"> |
| | | {!reload ? <SettingForm |
| | | config={config} |
| | | columns={columns} |
| | | subColumns={subColumns} |
| | | setting={setting} |
| | | scripts={scripts} |
| | | hasMainSearch={hasMainSearch} |
| | | updateStatus={this.updateStatus} |
| | | updateColumns={this.updateColumns} |
| | | addProcess={this.addProcess} |
| | | wrappedComponentRef={(inst) => this.settingForm = inst} |
| | | /> |
| | | /> : null} |
| | | </TabPane> |
| | | <TabPane tab="字段集" key="columns"> |
| | | <ColForm dict={this.props.dict} columnChange={this.columnChange}/> |
| | | {!['basetable', 'invoice', 'invTable'].includes(config.subtype) ? <TabPane tab={ |
| | | <span> |
| | | 字段集 |
| | | {columns.length ? <span className="count-tip">{columns.length}</span> : null} |
| | | </span> |
| | | } key="columns"> |
| | | <ColForm columnChange={this.columnChange}/> |
| | | <FieldsComponent |
| | | config={{...config, columns}} |
| | | config={{columns}} |
| | | type="fields" |
| | | updatefield={this.updatefields} |
| | | /> |
| | | <CopyOutlined title="以逗号拼接形式复制字段" onClick={this.copyColumns} style={{position: 'absolute', cursor: 'pointer', zIndex: 1, top: '-35px', right: '0px', color: '#1890ff'}} /> |
| | | <EditTable actions={['edit', 'move', 'copy', 'del', 'clear']} type="datasourcefield" data={columns} columns={colColumns} onChange={(columns) => this.setState({columns})}/> |
| | | </TabPane> |
| | | <ExcelOut data={columns} setting={setting}/> |
| | | <EditTable actions={['edit', 'move', 'copy', 'del', 'clear']} searchKey={searchKey} type="datasourcefield" wrappedComponentRef={(inst) => this.datasource = inst} data={columns} columns={colColumns} onChange={(columns) => this.setState({columns})}/> |
| | | </TabPane> : <TabPane tab={ |
| | | <span> |
| | | 字段集<TableOutlined style={{marginLeft: '5px', fontSize: '12px'}} /> |
| | | {columns.length ? <span className="count-tip">{columns.length}</span> : null} |
| | | </span> |
| | | } key="columns"> |
| | | <div className="base-table-columns"></div> |
| | | <ExcelOut data={columns} setting={setting}/> |
| | | <EditTable actions={[]} searchKey={searchKey} type="datasourcefield" data={columns} columns={colColumns}/> |
| | | </TabPane>} |
| | | {config.subtype === 'dualdatacard' ? <TabPane tab={ |
| | | <span> |
| | | 子表字段集 |
| | | {subColumns.length ? <span className="count-tip">{subColumns.length}</span> : null} |
| | | </span> |
| | | } key="subcolumns"> |
| | | <ColForm columnChange={this.subColumnChange}/> |
| | | <FieldsComponent |
| | | config={{columns: subColumns}} |
| | | type="fields" |
| | | updatefield={this.updateSubfields} |
| | | /> |
| | | <ExcelOut data={subColumns} setting={setting}/> |
| | | <EditTable actions={['edit', 'move', 'copy', 'del', 'clear']} searchKey={searchKey} type="datasourcefield" wrappedComponentRef={(inst) => this.subdatasource = inst} data={subColumns} columns={colColumns} onChange={(subColumns) => this.setState({subColumns})}/> |
| | | </TabPane> : null} |
| | | <TabPane tab={ |
| | | <span> |
| | | 自定义脚本 |
| | | {scripts.length ? <span className="count-tip">{scripts.length}</span> : null} |
| | | {activeKey === 'setting' ? <CopyOutlined title="复制数据源" className="mk-copy-datasource" onClick={(e) => {e.stopPropagation();this.copyDatasource()}}/> : null} |
| | | {activeKey === 'setting' ? <SnippetsOutlined title="导入数据源" className="mk-paste-datasource" onClick={(e) => {e.stopPropagation();this.setState({pvisible: true})}}/> : null} |
| | | {activeKey === 'columns' ? <CopyOutlined title="以逗号拼接形式复制字段" className="mk-copy-fields" onClick={(e) => {e.stopPropagation();this.copyColumns()}}/> : null} |
| | | {activeKey === 'subcolumns' ? <CopyOutlined title="以逗号拼接形式复制字段" className="mk-copy-fields" onClick={(e) => {e.stopPropagation();this.copySubColumns()}}/> : null} |
| | | {activeKey === 'subcolumns' || activeKey === 'columns' ? <span onClick={(e) => {e.stopPropagation()}}><Search className="mk-search-fields" defaultValue={searchKey} allowClear onSearch={(val, e) => {e.stopPropagation();this.setState({searchKey: val})}} /></span> : null} |
| | | </span> |
| | | } key="scripts"> |
| | | } key="scripts" disabled={median.interType !== 'system'} id="mk-scripts-tabpane"> |
| | | {scripts.length ? <BorderOutlined className="full-scripts" onClick={() => { |
| | | if (this.scriptsForm && (this.scriptsForm.state.editItem || (this.scriptsForm.props.form.getFieldValue('sql') && !/^\s+$/.test(this.scriptsForm.props.form.getFieldValue('sql'))))) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请保存自定义脚本!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | this.setState({visible: true, skip: false, script: null, scriptValue: '', editLineId: ''}) |
| | | }}/> : null} |
| | | <CustomScriptsForm |
| | | type={config.type} |
| | | hasExtend={config.hasExtend} |
| | | setting={setting} |
| | | searches={searches} |
| | | defaultsql={defaultsql} |
| | | initsql={this.state.initsql} |
| | | dict={this.props.dict} |
| | | customScripts={scripts} |
| | | systemScripts={this.state.systemScripts} |
| | | scriptsChange={this.scriptsChange} |
| | | scriptSubmit={this.scriptSubmit} |
| | | addProcess={this.addProcess} |
| | | wrappedComponentRef={(inst) => this.scriptsForm = inst} |
| | | /> |
| | | <EditTable actions={['move']} data={scripts} columns={scriptsColumns} onChange={this.changeScripts}/> |
| | | </TabPane> |
| | | </Tabs> |
| | | <Modal |
| | | wrapClassName="model-custom-view-scripts-modal" |
| | | title="自定义脚本" |
| | | visible={visible} |
| | | width={'95vw'} |
| | | maskClosable={false} |
| | | destroyOnClose |
| | | > |
| | | <img className="unfull-scripts" src={MinView} onClick={() => this.setState({visible: false, script: null})} alt=""/> |
| | | <div className="script-table-wrap"> |
| | | {scripts.map(item => { |
| | | let title = item.sql.match(/^\s*\/\*.+\*\//) |
| | | title = title && title[0] ? title[0] : '' |
| | | let _text = title ? item.sql.replace(title, '') : item.sql |
| | | |
| | | if (item.status === 'false') { |
| | | return ( |
| | | <div className="script-item" key={item.uuid}> |
| | | <div style={{cursor: 'not-allowed'}}> |
| | | {title ? <div style={{color: '#a50', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis'}}>{title}</div> : null} |
| | | <Paragraph copyable={{ text: item.sql }} ellipsis={{ rows: 4 }}>{_text}</Paragraph> |
| | | <div> |
| | | <span style={{color: '#ff4d4f', marginLeft: '20px'}}> |
| | | 禁用 |
| | | <StopOutlined style={{marginLeft: '5px'}} /> |
| | | </span> |
| | | </div> |
| | | </div> |
| | | <div style={{height: '24px'}}></div> |
| | | </div> |
| | | ) |
| | | } else { |
| | | let sign = '' |
| | | if (script && script.uuid === item.uuid) { |
| | | sign = 'active' |
| | | } else if (editLineId === item.uuid) { |
| | | sign = 'edited' |
| | | } |
| | | return ( |
| | | <div className={'script-item ' + sign} key={item.uuid}> |
| | | <div style={{cursor: 'pointer'}} onClick={() => { |
| | | this.setState({script: item, scriptValue: item.sql}) |
| | | }}> |
| | | {title ? <div style={{color: '#a50', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis'}}>{title}</div> : null} |
| | | <Paragraph copyable={{ text: item.sql }} ellipsis={{ rows: 4 }}>{_text}</Paragraph> |
| | | <div> |
| | | <span style={{color: '#26C281', marginLeft: '20px'}}> |
| | | 启用 |
| | | <CheckCircleOutlined style={{marginLeft: '5px'}}/> |
| | | </span> |
| | | </div> |
| | | </div> |
| | | <div style={{textAlign: 'right'}}> |
| | | <span className="operation-btn" onClick={() => this.handleStatus(item)} style={{color: '#8E44AD'}}><SwapOutlined /></span> |
| | | <Popconfirm |
| | | overlayClassName="popover-confirm" |
| | | title="确定删除吗?" |
| | | onConfirm={() => this.deleteScript(item) |
| | | }> |
| | | <span className="operation-btn" style={{color: '#ff4d4f'}}><DeleteOutlined /></span> |
| | | </Popconfirm> |
| | | </div> |
| | | </div> |
| | | ) |
| | | } |
| | | })} |
| | | </div> |
| | | <div className="script-button"> |
| | | <Button onClick={this.triggerConfirm} loading={this.state.loading} className="mk-green" style={{marginBottom: 15, marginLeft: 40}}> |
| | | {script ? '保存' : '添加'} |
| | | </Button> |
| | | <Button onClick={() => {this.setState({script: null, scriptValue: ''})}} style={{marginBottom: 15, marginLeft: 10}}> |
| | | 取消 |
| | | </Button> |
| | | <span style={{paddingLeft: '20px', fontSize: '12px'}}> |
| | | 强制保存: |
| | | <Switch checked={skip} size="small" onChange={() => this.setState({skip: !skip})}/> |
| | | </span> |
| | | </div> |
| | | <CodeMirror value={scriptValue} onChange={(val) => {this.setState({scriptValue: val})}}></CodeMirror> |
| | | </Modal> |
| | | <Modal |
| | | title="粘贴" |
| | | visible={pvisible} |
| | | width={600} |
| | | maskClosable={false} |
| | | onOk={this.pasteSubmit} |
| | | onCancel={() => {this.setState({pvisible: false})}} |
| | | destroyOnClose |
| | | > |
| | | <PasteForm wrappedComponentRef={(inst) => this.pasteFormRef = inst} inputSubmit={this.pasteSubmit}/> |
| | | </Modal> |
| | | </div> |
| | | ) |
| | | } |