import React, {Component} from 'react'
|
import PropTypes from 'prop-types'
|
import { fromJS } from 'immutable'
|
import { Form, Icon, notification, Modal, Spin, Tabs, Table, Popconfirm, Typography } from 'antd'
|
import moment from 'moment'
|
|
import Api from '@/api'
|
import Utils from '@/utils/utils.js'
|
import SettingUtils from './utils.jsx'
|
import CustomScript from './customscript'
|
import DataSource from './datasource'
|
import './index.scss'
|
|
const { TabPane } = Tabs
|
const { Paragraph } = Typography
|
|
class SettingForm extends Component {
|
static propTpyes = {
|
type: PropTypes.string, // 菜单类型
|
dict: PropTypes.object, // 字典项
|
menu: PropTypes.object, // 菜单信息
|
config: PropTypes.object, // 页面配置信息
|
permFuncField: PropTypes.array, // 自定义函数可用字段
|
search: PropTypes.array, // 搜索条件
|
inputSubmit: PropTypes.any // 回车提交事件
|
}
|
|
state = {
|
formlist: [],
|
btnloading: false,
|
activeKey: 'setting',
|
search: '',
|
arr_field: '',
|
regoptions: [],
|
setting: null,
|
view: 'normal',
|
defaultSql: '',
|
systemScripts: [],
|
scriptsColumns: [
|
{
|
title: 'SQL',
|
dataIndex: 'sql',
|
width: '70%',
|
render: (text) => (
|
<Paragraph copyable ellipsis={{ rows: 5, expandable: true }}>{text}</Paragraph>
|
)
|
},
|
{
|
title: '状态',
|
dataIndex: 'status',
|
width: '10%',
|
render: (text, record) => record.status === 'false' ?
|
(
|
<div>
|
{this.props.dict['model.status.forbidden']}
|
<Icon style={{marginLeft: '5px'}} type="stop" theme="twoTone" twoToneColor="#ff4d4f" />
|
</div>
|
) :
|
(
|
<div>
|
{this.props.dict['model.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['model.edit']} onClick={() => this.handleEdit(record)} style={{color: '#1890ff'}}><Icon type="edit" /></span>
|
<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>
|
<span className="operation-btn" title={this.props.dict['header.form.status.change']} onClick={() => this.handleStatus(record)} style={{color: '#8E44AD'}}><Icon type="swap" /></span>
|
<Popconfirm
|
overlayClassName="popover-confirm"
|
title={this.props.dict['model.query.delete']}
|
onConfirm={() => this.handleDelete(record)
|
}>
|
<span className="operation-btn" style={{color: '#ff4d4f'}}><Icon type="delete" /></span>
|
</Popconfirm>
|
</div>)
|
}
|
]
|
}
|
|
UNSAFE_componentWillMount() {
|
const { config, search } = this.props
|
|
let _setting = fromJS(config.setting).toJS()
|
let _scripts = _setting.scripts || []
|
|
_setting.default = _setting.default || 'true' // 默认sql
|
_setting.sysInterface = _setting.sysInterface || 'false' // 是否为系统接口
|
_setting.interface = _setting.sysInterface === 'true' ? (window.GLOB.mainSystemApi || '') : (_setting.interface || '')
|
|
if (_setting.interType === 'inner' && !_setting.innerFunc) { // 修改已有数据
|
_setting.interType = 'system'
|
}
|
|
// 显示列字段,用于查询
|
let columns = []
|
let arr_field = []
|
config.columns.forEach(col => {
|
if (col.field) {
|
columns.push({
|
value: col.field,
|
text: col.label
|
})
|
arr_field.push(col.field)
|
}
|
if (col.nameField) { // 链接的名称字段
|
arr_field.push(col.nameField)
|
}
|
})
|
|
if (_setting.primaryKey && !arr_field.includes(_setting.primaryKey)) {
|
_setting.primaryKey = ''
|
}
|
if (!_setting.primaryKey && arr_field.length > 0) {
|
arr_field.forEach(field => {
|
if (field.toLowerCase() === 'id') {
|
_setting.primaryKey = field
|
}
|
})
|
}
|
|
// 搜索条件,正则替换
|
let allSearch = Utils.initMainSearch(search)
|
allSearch = Utils.getAllSearchOptions(allSearch)
|
|
// 搜索的where条件
|
let _search = this.formatSearch(search)
|
_search = Utils.joinMainSearchkey(_search)
|
|
_search = _search.replace(/@\$@/ig, '')
|
_search = _search ? 'where ' + _search : ''
|
|
this.setState({
|
setting: _setting,
|
search: _search,
|
arr_field: arr_field.join(','),
|
regoptions: allSearch,
|
columns: columns,
|
scripts: _scripts
|
})
|
}
|
|
componentDidMount () {
|
this.getsysScript()
|
}
|
|
getsysScript = () => {
|
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)
|
|
let _sParam = {
|
func: 'sPC_Get_SelectedList',
|
LText: _scriptSql,
|
obj_name: 'data',
|
arr_field: 'funcname,longparam'
|
}
|
|
_sParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
|
_sParam.secretkey = Utils.encrypt(_sParam.LText, _sParam.timestamp)
|
_sParam.open_key = Utils.encryptOpenKey(_sParam.secretkey, _sParam.timestamp) // 云端数据验证
|
|
Api.getSystemConfig(_sParam).then(res => {
|
if (res.status) {
|
let _scripts = res.data.map(item => {
|
let _item = {
|
name: item.funcname,
|
value: Utils.UnformatOptions(item.longparam)
|
}
|
return _item
|
})
|
|
this.setState({
|
systemScripts: _scripts
|
})
|
} else {
|
notification.warning({
|
top: 92,
|
message: res.message,
|
duration: 5
|
})
|
}
|
})
|
}
|
|
handleConfirm = (trigger) => {
|
const { activeKey, setting, scripts } = this.state
|
|
if (trigger) {
|
this.setState({loading: true})
|
}
|
|
// 表单提交时检查输入值是否正确
|
if (activeKey === 'setting') {
|
return new Promise((resolve, reject) => {
|
this.settingForm.handleConfirm().then(res => {
|
if (res.interType === 'system' && res.default === 'false' && scripts.length === 0) {
|
notification.warning({
|
top: 92,
|
message: '不执行默认sql时,请添加自定义脚本!',
|
duration: 5
|
})
|
reject()
|
return
|
}
|
|
this.setState({
|
setting: res
|
}, () => {
|
this.sqlverify(() => {
|
this.setState({loading: false})
|
resolve({...res, scripts})
|
}, () => {
|
this.setState({loading: false})
|
reject()
|
}, true)
|
})
|
}, () => {
|
this.setState({loading: false})
|
})
|
})
|
} else {
|
return new Promise((resolve, reject) => {
|
let _loading = false
|
if (this.scriptsForm && this.scriptsForm.state.editItem) {
|
_loading = true
|
} else if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql')) {
|
_loading = true
|
}
|
|
if (_loading) {
|
notification.warning({
|
top: 92,
|
message: '存在未保存脚本,请点击确定保存,或点击取消放弃修改!',
|
duration: 5
|
})
|
this.setState({loading: false})
|
reject()
|
} else if (setting.interType === 'system' && setting.default === 'false' && scripts.length === 0) {
|
notification.warning({
|
top: 92,
|
message: '不执行默认sql时,请添加自定义脚本!',
|
duration: 5
|
})
|
this.setState({loading: false})
|
reject()
|
} else {
|
this.sqlverify(() => {
|
this.setState({loading: false})
|
resolve({...setting, scripts})
|
}, () => {
|
this.setState({loading: false})
|
reject()
|
}, true)
|
}
|
})
|
}
|
}
|
|
getCustomScript = (setting) => {
|
let _customScript = ''
|
if (setting.scripts && setting.scripts.length > 0) {
|
setting.scripts.forEach(item => {
|
if (item.status === 'false') return
|
_customScript += `
|
${item.sql}
|
`
|
})
|
}
|
|
if (_customScript) {
|
_customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000) select @ErrorCode='',@retmsg =''
|
${_customScript}
|
`
|
}
|
|
return _customScript
|
}
|
|
sqlverify = (_resolve, _reject, force) => {
|
const { setting, scripts, arr_field, regoptions, search } = this.state
|
|
if (setting.interType !== 'system') { // 不使用系统接口时,不需要sql验证
|
_resolve()
|
}
|
if (force || (setting.interType === 'system' && setting.default !== 'false')) {
|
let param = {
|
func: 's_debug_sql',
|
LText: SettingUtils.getDebugSql(setting, scripts, arr_field, regoptions, search)
|
}
|
param.LText = Utils.formatOptions(param.LText)
|
param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
|
param.secretkey = Utils.encrypt(param.LText, param.timestamp)
|
|
Api.getLocalConfig(param).then(result => {
|
if (result.status) {
|
_resolve()
|
} else {
|
_reject()
|
Modal.error({
|
title: result.message
|
})
|
}
|
})
|
} else {
|
_resolve()
|
}
|
}
|
|
/**
|
* @description 获取全部搜索条件
|
* @param {Array} searches 搜索条件数组
|
*/
|
formatSearch (searches) {
|
if (!searches || searches.length === 0) return []
|
|
let newsearches = []
|
searches.forEach(search => {
|
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') {
|
let copy = fromJS(item).toJS()
|
copy.key = search.datefield
|
|
item.value = search.initval && search.initval[0] ? search.initval[0] : '@$@'
|
item.match = '='
|
|
copy.type = 'daterange'
|
copy.match = 'between'
|
copy.value = [moment().format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')]
|
|
if (search.transfer === 'true') {
|
newsearches.push(item)
|
}
|
newsearches.push(copy)
|
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().startOf('week').format('YYYY-MM-DD'), moment().endOf('week').format('YYYY-MM-DD')]
|
} else if (item.type === 'daterange') {
|
item.value = [moment().format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')]
|
} else if (item.type === 'multiselect') {
|
item.value = ['@$@']
|
} else {
|
item.value = '@$@'
|
}
|
newsearches.push(item)
|
})
|
|
return newsearches
|
}
|
|
handleSubmit = (e) => {
|
e.preventDefault()
|
|
if (this.props.inputSubmit) {
|
this.props.inputSubmit()
|
}
|
}
|
|
handleEdit = (record) => {
|
this.scriptsForm.edit(record)
|
|
this.scrolltop()
|
}
|
|
scrolltop = () => {
|
let node = document.getElementById('model-table-setting-form-box').parentNode
|
|
if (node && node.scrollTop) {
|
let inter = Math.ceil(node.scrollTop / 10)
|
|
let timer = setInterval(() => {
|
if (node.scrollTop - inter > 0) {
|
node.scrollTop = node.scrollTop - inter
|
} else {
|
node.scrollTop = 0
|
clearInterval(timer)
|
}
|
}, 10)
|
}
|
}
|
|
handleUpDown = (record, direction) => {
|
let scripts = fromJS(this.state.scripts).toJS()
|
let index = 0
|
|
scripts = scripts.filter((item, i) => {
|
if (item.uuid === record.uuid) {
|
index = i
|
}
|
|
return item.uuid !== record.uuid
|
})
|
if ((index === 0 && direction === 'up') || (index === scripts.length && direction === 'down')) {
|
return
|
}
|
|
if (direction === 'up') {
|
scripts.splice(index - 1, 0, record)
|
} else {
|
scripts.splice(index + 1, 0, record)
|
}
|
|
this.setState({scripts})
|
}
|
|
handleStatus = (record) => {
|
let scripts = fromJS(this.state.scripts).toJS()
|
record.status = record.status === 'false' ? 'true' : 'false'
|
|
scripts = scripts.map(item => {
|
if (item.uuid === record.uuid) {
|
return record
|
} else {
|
return item
|
}
|
})
|
|
this.setState({scripts})
|
}
|
|
handleDelete = (record) => {
|
let scripts = fromJS(this.state.scripts).toJS()
|
scripts = scripts.filter(item => item.uuid !== record.uuid)
|
|
this.setState({ scripts })
|
}
|
|
scriptsChange = (values) => {
|
let scripts = fromJS(this.state.scripts).toJS()
|
|
if (values.uuid) {
|
scripts = scripts.map(item => {
|
if (item.uuid === values.uuid) {
|
return values
|
} else {
|
return item
|
}
|
})
|
} else {
|
values.uuid = Utils.getuuid()
|
scripts.push(values)
|
}
|
|
this.setState({scripts})
|
}
|
|
changeTab = (val) => {
|
const { activeKey, search, arr_field } = this.state
|
|
if (activeKey === 'setting') {
|
this.setState({loading: true})
|
|
let _defaultSql = ''
|
this.settingForm.handleConfirm().then(res => {
|
if (res.interType !== 'system') {
|
notification.warning({
|
top: 92,
|
message: '使用系统接口时,才可以设置自定义脚本!',
|
duration: 5
|
})
|
this.setState({loading: false})
|
return
|
}
|
|
this.setState({
|
setting: res
|
}, () => {
|
if (res.dataresource) {
|
let _dataresource = res.dataresource
|
|
if (/\s/.test(_dataresource)) {
|
_dataresource = '(' + _dataresource + ') tb'
|
}
|
|
_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.sqlverify(() => { // 验证成功
|
this.setState({
|
activeKey: val,
|
defaultSql: _defaultSql,
|
loading: false
|
})
|
}, () => { // 验证失败
|
this.setState({
|
loading: false
|
})
|
})
|
})
|
}, () => {
|
this.setState({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')) {
|
_loading = true
|
}
|
|
if (_loading) {
|
notification.warning({
|
top: 92,
|
message: '存在未保存脚本,请点击确定保存,或点击取消放弃修改!',
|
duration: 5
|
})
|
return
|
}
|
|
this.setState({
|
activeKey: val
|
})
|
}
|
}
|
|
render() {
|
const { type, menu, dict, permFuncField } = this.props
|
const { loading, activeKey, setting, scriptsColumns, systemScripts, arr_field, defaultSql, regoptions, search, columns, scripts } = this.state
|
|
return (
|
<div className="model-table-setting-form-box" id="model-table-setting-form-box">
|
{loading && <Spin size="large" />}
|
<Tabs activeKey={activeKey} className="verify-card-box" onChange={this.changeTab}>
|
<TabPane tab="数据源" key="setting">
|
<DataSource
|
type={type}
|
menu={menu}
|
dict={dict}
|
columns={columns}
|
setting={setting}
|
scripts={scripts}
|
permFuncField={permFuncField}
|
wrappedComponentRef={(inst) => this.settingForm = inst}
|
/>
|
</TabPane>
|
<TabPane tab="自定义脚本" key="scripts">
|
<CustomScript
|
type={type}
|
dict={dict}
|
swhere={search}
|
setting={setting}
|
scripts={scripts}
|
arr_field={arr_field}
|
defaultSql={defaultSql}
|
regoptions={regoptions}
|
searches={this.props.search}
|
systemScripts={systemScripts}
|
scriptsChange={this.scriptsChange}
|
wrappedComponentRef={(inst) => this.scriptsForm = inst}
|
/>
|
<Table
|
bordered
|
rowKey="uuid"
|
className="custom-table"
|
dataSource={scripts}
|
columns={scriptsColumns}
|
pagination={false}
|
/>
|
</TabPane>
|
</Tabs>
|
</div>
|
)
|
}
|
}
|
|
export default Form.create()(SettingForm)
|