| | |
| | | * @description 获取系统版本信息,启用或更新websql |
| | | */ |
| | | getAppVersion (_resolve, _reject) { |
| | | let appVersion = {} |
| | | if (!window.GLOB.WebSql && !window.GLOB.IndexDB) { |
| | | return Promise.reject() |
| | | } |
| | |
| | | if (window.GLOB.WebSql) { |
| | | return new Promise((resolve, reject) => { |
| | | CacheUtils.getWebSqlVersion().then(msg => { |
| | | appVersion.oldVersion = msg.version || '' |
| | | let modifydate = msg.createDate || curTime |
| | | if (modifydate.indexOf('Invalid date') > -1) { |
| | | modifydate = curTime |
| | |
| | | return |
| | | } |
| | | let clear = false |
| | | let version = res.app_version || '1.00' |
| | | appVersion.newVersion = version |
| | | appVersion.oldVersion = appVersion.oldVersion || version |
| | | let version = '1.00' |
| | | |
| | | if (res.menu_data && res.menu_data.length > 0) { |
| | | res.menu_data.forEach(mid => { |
| | |
| | | CacheUtils.createWebSqlversion(version, curTime) |
| | | } |
| | | |
| | | resolve(appVersion) |
| | | resolve() |
| | | }) |
| | | }, () => { |
| | | reject() |
| | |
| | | } else { |
| | | return new Promise((resolve, reject) => { |
| | | CacheUtils.getIndexDBVersion().then(msg => { |
| | | appVersion.oldVersion = msg.version || '' |
| | | let modifydate = msg.createDate || curTime |
| | | if (modifydate.indexOf('Invalid date') > -1) { |
| | | modifydate = curTime |
| | |
| | | return |
| | | } |
| | | let clear = false |
| | | let version = res.app_version || '1.00' |
| | | appVersion.newVersion = version |
| | | appVersion.oldVersion = appVersion.oldVersion || version |
| | | let version = '1.00' |
| | | |
| | | if (res.menu_data && res.menu_data.length > 0) { |
| | | res.menu_data.forEach(mid => { |
| | |
| | | } |
| | | } |
| | | |
| | | CacheUtils.updateIndexDBversion({version: appVersion.oldVersion, createDate: curTime}) |
| | | CacheUtils.updateIndexDBversion({version: version, createDate: curTime}) |
| | | |
| | | resolve(appVersion) |
| | | resolve() |
| | | }) |
| | | }, () => { |
| | | reject() |
| | |
| | | /** |
| | | * @description 更新系统版本信息,清空配置信息 |
| | | */ |
| | | updateAppVersion (newVersion) { |
| | | updateAppVersion () { |
| | | let curTime = moment().format('YYYY-MM-DD HH:mm:ss') + '.000' |
| | | CacheUtils.clearWebSqlConfig() |
| | | CacheUtils.updateWebSqlversion(newVersion, curTime) |
| | | CacheUtils.updateWebSqlversion('1.00', curTime) |
| | | CacheUtils.clearIndexDBConfig() |
| | | CacheUtils.updateIndexDBversion({version: newVersion, createDate: curTime}) |
| | | CacheUtils.updateIndexDBversion({version: '1.00', createDate: curTime}) |
| | | } |
| | | |
| | | /** |
| | |
| | | import {connect} from 'react-redux' |
| | | import { is, fromJS } from 'immutable' |
| | | import moment from 'moment' |
| | | import { Dropdown, Menu, Icon, Modal, Form, notification, Switch, Input, Badge } from 'antd' |
| | | import { Dropdown, Menu, Icon, Modal, Form, notification, Switch, Input } from 'antd' |
| | | |
| | | import { |
| | | toggleCollapse, |
| | |
| | | import enUS from '@/locales/en-US/main.js' |
| | | import Utils from '@/utils/utils.js' |
| | | import avatar from '@/assets/img/avatar.jpg' |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import Resetpwd from './resetpwd' |
| | | import LoginForm from './loginform' |
| | | import './index.scss' |
| | | |
| | | const { confirm } = Modal |
| | | const { Search } = Input |
| | | const VersionsUp = asyncComponent(() => import('./versions')) |
| | | |
| | | class Header extends Component { |
| | | static propTpyes = { |
| | |
| | | systems: [], |
| | | searchkey: '', |
| | | thdMenuList: [], |
| | | oriVersion: '', |
| | | newVersion: '', |
| | | debug: sessionStorage.getItem('debug') === 'true', |
| | | navBar: ['linkage_navigation', 'linkage', 'menu_board', 'menu_board_navigation'].includes(window.GLOB.navBar) ? 'topmenu' : '', |
| | | menuType: window.GLOB.navBar |
| | |
| | | componentDidMount () { |
| | | // 获取系统的版本信息,延时查询 |
| | | setTimeout(() => { |
| | | Api.getAppVersion().then(res => { |
| | | this.setState({ |
| | | oriVersion: res.oldVersion, |
| | | newVersion: res.newVersion |
| | | }) |
| | | }, () => {}) |
| | | Api.getAppVersion().then(() => {}, () => {}) |
| | | }, 1000) |
| | | } |
| | | |
| | |
| | | this.setState = () => { |
| | | return |
| | | } |
| | | } |
| | | |
| | | verup = () => { |
| | | const { oriVersion, newVersion } = this.state |
| | | const _this = this |
| | | |
| | | confirm({ |
| | | title: this.state.dict['main.verup'], |
| | | content: `最新版本${newVersion},当前版本${oriVersion}`, |
| | | onOk() { |
| | | return new Promise(resolve => { |
| | | if (!window.GLOB.WebSql) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '升级失败,请刷新页面重试!', |
| | | duration: 2 |
| | | }) |
| | | resolve() |
| | | } else { |
| | | Api.updateAppVersion(newVersion) |
| | | notification.success({ |
| | | top: 92, |
| | | message: '升级成功!', |
| | | duration: 2 |
| | | }) |
| | | _this.setState({oriVersion: newVersion}) |
| | | resolve() |
| | | } |
| | | }) |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } |
| | | |
| | | gotoDoc = () => { |
| | |
| | | |
| | | render () { |
| | | const { mainMenu, collapse } = this.props |
| | | const { thdMenuList, searchkey, oriVersion, newVersion, debug, menulist, navBar, menuType } = this.state |
| | | const { thdMenuList, searchkey, debug, menulist, navBar, menuType } = this.state |
| | | |
| | | const menu = ( |
| | | <Menu className="header-dropdown"> |
| | |
| | | ))} |
| | | </Menu.SubMenu> : null} |
| | | <Menu.Item key="doc" onClick={this.gotoDoc}>{this.state.dict['main.doc']}</Menu.Item> |
| | | {oriVersion ? <Menu.Item key="verup" onClick={this.verup}> |
| | | <Badge dot={oriVersion !== newVersion}>{this.state.dict['main.verup']}</Badge> |
| | | </Menu.Item> : null} |
| | | <Menu.Item style={{padding: 0}} key="verup"> |
| | | <VersionsUp debug={debug} /> |
| | | </Menu.Item> |
| | | <Menu.Item key="logout" onClick={this.logout}>{this.state.dict['main.logout']}</Menu.Item> |
| | | </Menu> |
| | | ) |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Modal, notification, Timeline, Icon, Button } from 'antd' |
| | | import moment from 'moment' |
| | | import md5 from 'md5' |
| | | |
| | | // import SettingForm from './settingform' |
| | | import Api from '@/api' |
| | | import options from '@/store/options.js' |
| | | import Utils from '@/utils/utils.js' |
| | | import './index.scss' |
| | | |
| | | const { confirm } = Modal |
| | | |
| | | class DataSource extends Component { |
| | | static propTpyes = { |
| | | debug: PropTypes.any |
| | | } |
| | | |
| | | state = { |
| | | visible: false, |
| | | versions: null, |
| | | version: null, |
| | | error: false |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | verup = () => { |
| | | const { debug } = this.props |
| | | |
| | | if (!debug || options.sysType === 'cloud') { |
| | | confirm({ |
| | | title: '版本升级', |
| | | content: '重新加载应用信息', |
| | | onOk() { |
| | | return new Promise(resolve => { |
| | | if (!window.GLOB.WebSql && !window.GLOB.IndexDB) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '升级失败,请刷新页面重试!', |
| | | duration: 2 |
| | | }) |
| | | resolve() |
| | | } else { |
| | | Api.updateAppVersion() |
| | | setTimeout(() => { |
| | | notification.success({ |
| | | top: 92, |
| | | message: '升级成功!', |
| | | duration: 2 |
| | | }) |
| | | resolve() |
| | | }, 1000) |
| | | } |
| | | }) |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } else { |
| | | Api.updateAppVersion() |
| | | |
| | | if (!sessionStorage.getItem('CloudUserID') || !sessionStorage.getItem('CloudLoginUID')) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请登录开发机!', |
| | | duration: 2 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let _param = { |
| | | func: 's_get_sversions_sys', |
| | | } |
| | | |
| | | Api.getSystemConfig(_param).then(result => { |
| | | if (!result.status) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: result.message, |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let edition_int = '' |
| | | if (options.sysType === 'SSO') { |
| | | edition_int = result.edition_int_sso |
| | | } else if (options.sysType === 'local' && window.GLOB.systemType !== 'production') { |
| | | edition_int = result.edition_int_local |
| | | } else { |
| | | if (result.edition_int_sso < result.edition_int_local) { |
| | | edition_int = result.edition_int_sso |
| | | } else { |
| | | edition_int = result.edition_int_local |
| | | } |
| | | } |
| | | if (edition_int === '') { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '未查询到更新版本信息!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let _rduri = window.atob('aHR0cHM6Ly9lcGMubWs5aC5$mkjbi93ZWJhcGkvZG9zdGFycw=='.replace(/\$mk/ig, '')) |
| | | let _id = window.atob('YmgwYmFwYWJ0ZDQ1ZXBz$mkZ3JhNzlzZWdiY2g2YzFpYms='.replace(/\$mk/ig, '')) |
| | | let sysType = options.sysType.toLowerCase() |
| | | |
| | | if (window.GLOB.systemType === 'production') { |
| | | sysType = '' |
| | | } |
| | | |
| | | let param = { |
| | | func: 's_get_sversions_sys_epc', |
| | | appkey: window.GLOB.appkey, |
| | | userid: _id, |
| | | LoginUID: _id, |
| | | edition_int: edition_int, |
| | | sys_type: sysType, |
| | | nonc: Utils.getuuid() |
| | | } |
| | | |
| | | let keys = Object.keys(param).sort() |
| | | let values = '' |
| | | keys.forEach(key => { |
| | | values += key + param[key] |
| | | }) |
| | | param.sign = md5(values) |
| | | param.t = new Date().getTime() |
| | | |
| | | Api.directRequest(_rduri + '/s_get_sversions_sys_epc', 'post', param, 'true').then(res => { |
| | | if (!res.status) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: res.message, |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (!res.data || res.data.length === 0) { |
| | | notification.success({ |
| | | top: 92, |
| | | message: '已经是最新的版本了。', |
| | | duration: 2 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | res.data = res.data.map((item, i) => { |
| | | item.status = i === 0 ? 'loading' : 'waiting' |
| | | item.index = i |
| | | return item |
| | | }) |
| | | this.setState({versions: res.data, version: res.data[0], visible: true}, () => { |
| | | this.queryScript() |
| | | }) |
| | | }) |
| | | }) |
| | | } |
| | | } |
| | | |
| | | queryScript = () => { |
| | | const { version } = this.state |
| | | |
| | | let _param = { |
| | | func: 's_get_sVersiondetail_Up', |
| | | VersionName: version.id, |
| | | BID: '' |
| | | } |
| | | |
| | | Api.getCloudConfig(_param).then(res => { |
| | | delete res.message |
| | | delete res.status |
| | | |
| | | res.func = 's_sVersion_Local_add' |
| | | res.VersionName = version.id |
| | | |
| | | Api.getLocalConfig(res).then(result => { |
| | | if (!result.status) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: result.message, |
| | | duration: 5 |
| | | }) |
| | | this.execError() |
| | | return |
| | | } else if (!result.vid) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '当前应用需要升级系统接口,请联系管理员!', |
| | | duration: 5 |
| | | }) |
| | | this.execError() |
| | | return |
| | | } |
| | | |
| | | this.setState({version: {...version, BID: result.vid}}) |
| | | |
| | | let sql = `select ID,KeyWords,Remark,TypeName,Sort,SrcID from (select * from sVersionDetail_Local where BID='${result.vid}' and deleted=0 and status=0 ) tmptable order by Sort` |
| | | |
| | | let param = { |
| | | func: 'sPC_Get_TableData', |
| | | obj_name: 'data', |
| | | arr_field: 'ID,KeyWords,Remark,TypeName,Sort,SrcID', |
| | | BID: '', |
| | | } |
| | | |
| | | param.LText = Utils.formatOptions(sql) |
| | | param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') |
| | | param.secretkey = Utils.encrypt(param.LText, param.timestamp) |
| | | param.DateCount = '' |
| | | |
| | | Api.getLocalConfig(param).then(response => { |
| | | if (!response.status) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: response.message, |
| | | duration: 5 |
| | | }) |
| | | this.execError() |
| | | return |
| | | } else if (!response.data || response.data.length === 0) { |
| | | this.next() |
| | | } else { |
| | | this.loopRequest(response.data) |
| | | } |
| | | }, () => { this.execError() }) |
| | | }, () => { this.execError() }) |
| | | }, () => { this.execError() }) |
| | | } |
| | | |
| | | loopRequest = (scripts) => { |
| | | const { version } = this.state |
| | | |
| | | if (!version) return |
| | | |
| | | let script = scripts.shift() |
| | | let param = { |
| | | func: 's_get_sVersionDetail_Ltext', |
| | | SrcID: script.SrcID, |
| | | ID: script.ID, |
| | | BID: version.BID |
| | | } |
| | | |
| | | let ssoParam = { |
| | | func: 's_sDataDictb_TBBack', |
| | | SrcID: script.SrcID, |
| | | ID: script.ID, |
| | | BID: version.BID |
| | | } |
| | | |
| | | let localParam = { |
| | | func: 's_sDataDictb_TBBack', |
| | | SrcID: script.SrcID, |
| | | ID: script.ID, |
| | | BID: version.BID |
| | | } |
| | | |
| | | Api.getCloudConfig(param).then(res => { |
| | | delete res.message |
| | | delete res.status |
| | | |
| | | localParam = {...localParam, ...res} |
| | | |
| | | if (res.LTextOut) { |
| | | localParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') |
| | | localParam.secretkey = Utils.encrypt(localParam.LTextOut, localParam.timestamp) |
| | | localParam.open_key = Utils.encryptOpenKey(localParam.secretkey, localParam.timestamp) |
| | | } |
| | | |
| | | if (res.UpType === 'SSO' && window.GLOB.mainSystemApi) { |
| | | ssoParam = {...ssoParam, ...res} |
| | | delete ssoParam.UpType |
| | | |
| | | ssoParam.rduri = window.GLOB.mainSystemApi |
| | | |
| | | if (res.LTextOut) { |
| | | ssoParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') |
| | | ssoParam.secretkey = Utils.encrypt(ssoParam.LTextOut, ssoParam.timestamp) |
| | | ssoParam.open_key = Utils.encryptOpenKey(ssoParam.secretkey, ssoParam.timestamp) |
| | | } |
| | | } else { |
| | | delete localParam.UpType |
| | | ssoParam = null |
| | | } |
| | | |
| | | this.execLocal(localParam, ssoParam, scripts) |
| | | }, () => { |
| | | this.execError() |
| | | }) |
| | | } |
| | | |
| | | execSso = (ssoParam, scripts) => { |
| | | Api.getLocalConfig(ssoParam).then(res => { |
| | | if (!res.status) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: res.message, |
| | | duration: 5 |
| | | }) |
| | | this.execWarning() |
| | | this.setState({}, () => { |
| | | if (scripts.length === 0) { |
| | | this.next() |
| | | } else { |
| | | this.loopRequest(scripts) |
| | | } |
| | | }) |
| | | } else { |
| | | if (scripts.length === 0) { |
| | | this.next() |
| | | } else { |
| | | this.loopRequest(scripts) |
| | | } |
| | | } |
| | | }, () => { |
| | | this.execError() |
| | | }) |
| | | } |
| | | |
| | | execLocal = (localParam, ssoParam, scripts) => { |
| | | Api.getLocalConfig(localParam).then(res => { |
| | | if (!res.status) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: res.message, |
| | | duration: 5 |
| | | }) |
| | | this.execWarning() |
| | | this.setState({}, () => { |
| | | if (scripts.length === 0) { |
| | | this.next() |
| | | } else { |
| | | this.loopRequest(scripts) |
| | | } |
| | | }) |
| | | } else if (ssoParam) { |
| | | this.execSso(ssoParam, scripts) |
| | | } else { |
| | | if (scripts.length === 0) { |
| | | this.next() |
| | | } else { |
| | | this.loopRequest(scripts) |
| | | } |
| | | } |
| | | }, () => { |
| | | this.execError() |
| | | }) |
| | | } |
| | | |
| | | execWarning = () => { |
| | | const { version } = this.state |
| | | |
| | | if (!version) return |
| | | |
| | | this.setState({version: {...version, warning: true}}) |
| | | } |
| | | |
| | | execError = () => { |
| | | const { version } = this.state |
| | | |
| | | if (!version) return |
| | | |
| | | this.setState({error: true, versions: this.state.versions.map(item => { |
| | | if (version.id === item.id) { |
| | | item.status = 'error' |
| | | } |
| | | return item |
| | | })}) |
| | | } |
| | | |
| | | next = () => { |
| | | const { version, versions } = this.state |
| | | |
| | | if (!version || !versions) return |
| | | |
| | | let sql = `declare @Vid nvarchar(50) set @Vid='' select top 1 @Vid=id from sVersionDetail_Local where BID='${version.BID}' and Status =10 if @Vid='' begin delete sVersion_Local where id ='${version.BID}' delete sVersionDetail_Local where bid ='${version.BID}' end else begin update sVersion_Local set deleted=1,Modifydate=getdate(),ModifyUserID=@UserID@ where id ='${version.BID}' end` |
| | | |
| | | let param = { |
| | | func: 'sPC_TableData_InUpDe', |
| | | exec_type: 'y', |
| | | ID: version.BID |
| | | } |
| | | |
| | | param.LText = Utils.formatOptions(sql) |
| | | param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') |
| | | param.secretkey = Utils.encrypt('', param.timestamp) |
| | | |
| | | Api.getLocalConfig(param).then(response => { |
| | | if (!response.status) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: response.message, |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | }) |
| | | |
| | | let nextver = versions[version.index + 1] |
| | | let _versions = versions.map(item => { |
| | | if (version.id === item.id) { |
| | | item.status = 'done' |
| | | item.warning = version.warning === true |
| | | } |
| | | return item |
| | | }) |
| | | |
| | | if (nextver) { |
| | | this.setState({ |
| | | version: nextver, |
| | | versions: _versions |
| | | }, () => { |
| | | this.queryScript() |
| | | }) |
| | | } else { |
| | | this.setState({ |
| | | version: null, |
| | | versions: _versions |
| | | }) |
| | | notification.success({ |
| | | top: 92, |
| | | message: '升级已完成。', |
| | | duration: 3 |
| | | }) |
| | | } |
| | | } |
| | | |
| | | stop = () => { |
| | | this.setState({ |
| | | version: null, |
| | | versions: null, |
| | | visible: false, |
| | | error: false |
| | | }) |
| | | } |
| | | |
| | | skip = () => { |
| | | const { version, versions } = this.state |
| | | |
| | | let nextver = versions[version.index + 1] |
| | | |
| | | this.setState({ |
| | | version: nextver, |
| | | error: false |
| | | }, () => { |
| | | this.queryScript() |
| | | }) |
| | | } |
| | | |
| | | reset = () => { |
| | | const { version } = this.state |
| | | |
| | | this.setState({versions: this.state.versions.map(item => { |
| | | if (version.id === item.id) { |
| | | item.status = 'loading' |
| | | } |
| | | return item |
| | | }), error: false}, () => { |
| | | this.queryScript() |
| | | }) |
| | | } |
| | | |
| | | render () { |
| | | const { visible, versions, error, version } = this.state |
| | | |
| | | return ( |
| | | <> |
| | | <div style={{padding: '5px 25px'}} onClick={this.verup}>版本升级</div> |
| | | <Modal |
| | | wrapClassName="version-up-modal" |
| | | title="应用升级" |
| | | visible={visible} |
| | | width={800} |
| | | closable={false} |
| | | maskClosable={false} |
| | | footer={[ |
| | | error && version && versions && versions.length > (version.index + 1) ? <Button key="close" onClick={this.skip}>跳过</Button> : null, |
| | | error && version ? <Button key="close" onClick={this.reset}>重新执行</Button> : null, |
| | | <Button key="close" onClick={this.stop}>关闭</Button>, |
| | | ]} |
| | | destroyOnClose |
| | | > |
| | | {versions ? <Timeline> |
| | | {versions.map(item => { |
| | | let icon = <Icon type="clock-circle-o" style={{ fontSize: '16px' }} /> |
| | | if (item.status === 'loading') { |
| | | icon = <Icon type="sync" spin style={{ fontSize: '16px' }} /> |
| | | } else if (item.status === 'done') { |
| | | if (item.warning) { |
| | | icon = <Icon type="warning" style={{ fontSize: '16px', color: 'orange' }}/> |
| | | } else { |
| | | icon = <Icon type="check-circle" style={{ fontSize: '16px', color: '#52c41a' }} /> |
| | | } |
| | | } |
| | | return ( |
| | | <Timeline.Item key={item.id} dot={icon}>{item.ProgramName}</Timeline.Item> |
| | | ) |
| | | })} |
| | | </Timeline> : null} |
| | | </Modal> |
| | | </> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default DataSource |
New file |
| | |
| | | .version-up-modal { |
| | | .ant-modal-body { |
| | | padding: 24px 50px; |
| | | min-height: 200px; |
| | | max-height: calc(100vh - 210px); |
| | | overflow-y: auto; |
| | | .ant-timeline-item-content { |
| | | height: 21px; |
| | | white-space: nowrap; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | } |
| | | .ant-timeline-item-head-custom { |
| | | padding: 1px; |
| | | } |
| | | } |
| | | .ant-modal-body::-webkit-scrollbar { |
| | | width: 7px; |
| | | } |
| | | .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); |
| | | } |
| | | } |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { Form, Row, Col, Input, InputNumber, Tooltip, Icon, Radio } from 'antd' |
| | | |
| | | import './index.scss' |
| | | |
| | | class SettingForm extends Component { |
| | | static propTpyes = { |
| | | dict: PropTypes.object, // 字典项 |
| | | wrap: PropTypes.object, // 数据源配置 |
| | | inputSubmit: PropTypes.func // 回车事件 |
| | | } |
| | | |
| | | state = {} |
| | | |
| | | handleConfirm = () => { |
| | | // 表单提交时检查输入值是否正确 |
| | | return new Promise((resolve, reject) => { |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | | if (!err) { |
| | | resolve(values) |
| | | } else { |
| | | reject(err) |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | handleSubmit = (e) => { |
| | | e.preventDefault() |
| | | |
| | | if (this.props.inputSubmit) { |
| | | this.props.inputSubmit() |
| | | } |
| | | } |
| | | |
| | | render() { |
| | | const { wrap } = this.props |
| | | const { getFieldDecorator } = this.props.form |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 8 } |
| | | }, |
| | | wrapperCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 16 } |
| | | } |
| | | } |
| | | |
| | | return ( |
| | | <div className="model-menu-setting-form"> |
| | | <Form {...formItemLayout}> |
| | | <Row gutter={24}> |
| | | <Col span={12}> |
| | | <Form.Item label="导航栏名称"> |
| | | {getFieldDecorator('name', { |
| | | initialValue: wrap.name, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: this.props.dict['form.required.input'] + '导航栏名称!' |
| | | } |
| | | ] |
| | | })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label="菜单参数"> |
| | | {getFieldDecorator('MenuNo', { |
| | | initialValue: wrap.MenuNo, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: this.props.dict['form.required.input'] + '菜单参数!' |
| | | } |
| | | ] |
| | | })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="选择静态值,无需配置数据源。"> |
| | | <Icon type="question-circle" /> |
| | | 数据来源 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('datatype', { |
| | | initialValue: wrap.datatype || 'static' |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="dynamic">动态</Radio> |
| | | <Radio value="static">静态</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label="高度"> |
| | | {getFieldDecorator('height', { |
| | | initialValue: wrap.height || 50, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: this.props.dict['form.required.input'] + '高度!' |
| | | } |
| | | ] |
| | | })(<InputNumber min={30} max={200} precision={0} onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | </Form> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default Form.create()(SettingForm) |
New file |
| | |
| | | .model-menu-setting-form { |
| | | position: relative; |
| | | |
| | | .anticon-question-circle { |
| | | color: #c49f47; |
| | | margin-right: 3px; |
| | | } |
| | | .ant-input-number { |
| | | width: 100%; |
| | | } |
| | | } |
| | |
| | | // options: appMenus |
| | | // }, |
| | | { |
| | | type: 'select', |
| | | key: 'linkurl', |
| | | label: '链接地址', |
| | | initVal: card.linkurl || '', |
| | | required: true, |
| | | options: [] |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'joint', |
| | | label: Formdict['model.form.paramJoint'], |
| | |
| | | value: 'false', |
| | | text: Formdict['model.false'] |
| | | }] |
| | | }, |
| | | { |
| | | type: 'select', |
| | | key: 'linkurl', |
| | | label: '链接地址', |
| | | initVal: card.linkurl || '', |
| | | required: true, |
| | | options: [] |
| | | }, |
| | | { |
| | | type: 'textarea', |
| | |
| | | width: card.width || 24, |
| | | search: [ |
| | | { origin: true, uuid: Utils.getuuid(), label: 'label', type: 'text', match: 'like' }, |
| | | { origin: true, uuid: Utils.getuuid(), label: 'label', type: 'select', match: 'equal' }, |
| | | { origin: true, uuid: Utils.getuuid(), label: 'label', type: 'date', match: 'greater' } |
| | | { origin: true, uuid: Utils.getuuid(), label: 'label', type: 'select', match: 'equal' } |
| | | ], |
| | | action: [ |
| | | { origin: true, uuid: Utils.getuuid(), label: '添加', intertype: 'system', OpenType: 'pop', icon: 'plus', class: 'green', style: {color: 'rgb(255, 255, 255)', background: 'rgb(38, 194, 129)', marginRight: '15px'} }, |
| | |
| | | item.uuid = MenuUtils.getuuid() |
| | | item.setting.name = item.setting.name + MenuUtils.getdataName().toUpperCase().substr(-4) |
| | | item.name = item.setting.name |
| | | if (appType !== 'mob') { |
| | | item.components = item.components.filter(cell => cell.type !== 'menubar') |
| | | } |
| | | |
| | | item.components = item.components.map(cell => { |
| | | cell.floor = item.floor |
| | | cell.tabId = item.tabId || '' |
| | |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | width: auto!important; |
| | | height: auto!important; |
| | | canvas { |
| | | width: 100%!important; |
| | | height: 100%!important; |
| | |
| | | |
| | | verifySubmit = () => { |
| | | this.verifyRef.handleConfirm().then(res => { |
| | | |
| | | |
| | | let parMenuId = sessionStorage.getItem('kei_no') + sessionStorage.getItem('typename') + sessionStorage.getItem('lang') |
| | | let menuId = Utils.getuuid() |
| | | |
| | | if (res.MenuId) { |
| | | let appMenus = sessionStorage.getItem('appMenus') |
| | | if (appMenus) { |
| | | try { |
| | | appMenus = JSON.parse(appMenus) |
| | | } catch (e) { |
| | | appMenus = [] |
| | | } |
| | | } else { |
| | | appMenus = [] |
| | | } |
| | | if (appMenus.findIndex(item => item.MenuID === res.MenuId) > -1) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '当前菜单已存在!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | menuId = res.MenuId |
| | | } |
| | | |
| | | this.setState({ |
| | | loading: true |
| | | }) |
| | | |
| | | let parMenuId = sessionStorage.getItem('kei_no') + sessionStorage.getItem('typename') + sessionStorage.getItem('lang') |
| | | let menuId = Utils.getuuid() |
| | | let config = { |
| | | version: 1.0, |
| | | uuid: menuId, |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { Form, Row, Col, Select, Input } from 'antd' |
| | | import { Form, Row, Col, Select, Input, Tooltip, Icon } from 'antd' |
| | | |
| | | import './index.scss' |
| | | |
| | |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={20}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="自定义菜单ID值。"> |
| | | <Icon type="question-circle" style={{color: '#c49f47', marginRight: '3px'}}/> |
| | | 菜单ID |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('MenuId', { |
| | | initialValue: '', |
| | | rules: [{ |
| | | pattern: /^[0-9a-zA-Z]*$/ig, |
| | | message: '菜单ID只允许包含数字或字母(大小写)' |
| | | }, { |
| | | min: 20, |
| | | message: '菜单ID最短为20个字符' |
| | | }, { |
| | | max: 40, |
| | | message: '菜单ID最长为40个字符' |
| | | }] |
| | | })(<Input placeholder="" autoComplete="off" />)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={20}> |
| | | <Form.Item label="复制菜单"> |
| | | {getFieldDecorator('copymenuId', { |
| | | initialValue: '' |
| | |
| | | .model-menu-setting-form { |
| | | position: relative; |
| | | |
| | | .anticon-question-circle { |
| | | color: #c49f47; |
| | | margin-right: 3px; |
| | | } |
| | | .ant-input-number { |
| | | width: 100%; |
| | | } |
| | | } |
| | |
| | | .custom-normal-table { |
| | | position: relative; |
| | | background-color: #fff; |
| | | |
| | | .normal-header { |
| | | margin-bottom: 10px; |
| | |
| | | ] |
| | | } |
| | | }, |
| | | {OpenType:"prompt",Ot:"notRequired",callbackFunc:"",position:"toolbar",sysInterface:"true",execSuccess:"grid",label:"更新版本",intertype:"outer",execError:"never",class:"primary", |
| | | icon:"",interface:"http://cloud.mk9h.cn/webapi/dostars",innerFunc:"",uuid:"15926364942911efnal5pv6r92if2vr2",outerFunc:"s_app_version_upt"} |
| | | // {OpenType:"prompt",Ot:"notRequired",callbackFunc:"",position:"toolbar",sysInterface:"true",execSuccess:"grid",label:"更新版本",intertype:"outer",execError:"never",class:"primary", |
| | | // icon:"",interface:"http://cloud.mk9h.cn/webapi/dostars",innerFunc:"",uuid:"15926364942911efnal5pv6r92if2vr2",outerFunc:"s_app_version_upt"} |
| | | ], |
| | | columns:[ |
| | | {label:'ID',field:'ID',type:'text',Align:'left',Hide:'true',IsSort:'true',Width:120,prefix:'',postfix:'',matchVal:'',color:'',fieldlength:50,uuid:'1581736658674f11dg01sqdneu8bbn2q'}, |
| | |
| | | }] |
| | | }, |
| | | { |
| | | type: 'text', |
| | | key: 'disableField', |
| | | label: '禁用·字段', |
| | | initVal: card.disableField || '', |
| | | tooltip: '设置禁用字段,且字段值为true时,选项不可选。', |
| | | required: false, |
| | | readonly: false |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'multiple', |
| | | label: '可多选', |
| | |
| | | if (resourceType === '0') { // 自定义资源 |
| | | _options.push('options') |
| | | } else if (resourceType === '1') { // 数据源 |
| | | _options.push('dataSource', 'valueField', 'valueText', 'orderBy', 'orderType', 'database') |
| | | _options.push('dataSource', 'valueField', 'valueText', 'orderBy', 'orderType', 'disableField', 'database') |
| | | } |
| | | } else if (type === 'checkcard') { |
| | | if (display === 'picture') { |
| | | if (resourceType === '0') { // 自定义资源 |
| | | _options.push('options', 'ratio') |
| | | } else if (resourceType === '1') { // 数据源 |
| | | _options.push('dataSource', 'cardValField', 'urlField', 'orderBy', 'orderType', 'database', 'ratio') |
| | | _options.push('dataSource', 'cardValField', 'urlField', 'orderBy', 'orderType', 'disableField', 'database', 'ratio') |
| | | } |
| | | } else { |
| | | if (resourceType === '0') { // 自定义资源 |
| | | _options.push('options', 'fields', 'backgroundColor') |
| | | } else if (resourceType === '1') { // 数据源 |
| | | _options.push('dataSource', 'cardValField', 'fields', 'orderBy', 'orderType', 'database', 'backgroundColor') |
| | | _options.push('dataSource', 'cardValField', 'fields', 'orderBy', 'orderType', 'disableField', 'database', 'backgroundColor') |
| | | } |
| | | } |
| | | |
| | |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | width: auto!important; |
| | | height: auto!important; |
| | | canvas { |
| | | width: 100%!important; |
| | | height: 100%!important; |
| | |
| | | import { is, fromJS } from 'immutable' |
| | | import moment from 'moment' |
| | | import HTML5Backend from 'react-dnd-html5-backend' |
| | | import { ConfigProvider, notification, Modal, Collapse, Card, Switch, Button } from 'antd' |
| | | import { ConfigProvider, notification, Modal, Collapse, Card, Switch, Button, Typography } from 'antd' |
| | | import html2canvas from 'html2canvas' |
| | | |
| | | import Api from '@/api' |
| | |
| | | |
| | | const { Panel } = Collapse |
| | | const { confirm } = Modal |
| | | const { Paragraph } = Typography |
| | | const _locale = sessionStorage.getItem('lang') !== 'en-US' ? antdZhCN : antdEnUS |
| | | |
| | | const MenuForm = asyncComponent(() => import('./menuform')) |
| | |
| | | /> : null} |
| | | {/* 表名添加 */} |
| | | {config ? <TableComponent config={config} updatetable={this.updateConfig}/> : null} |
| | | <Paragraph style={{padding: '15px 0px 0px 18px'}} copyable={{ text: MenuId }}>菜单ID</Paragraph> |
| | | </Panel> |
| | | {/* 组件添加 */} |
| | | <Panel header={dict['mob.component']} key="component"> |
| | |
| | | import { is, fromJS } from 'immutable' |
| | | import moment from 'moment' |
| | | import HTML5Backend from 'react-dnd-html5-backend' |
| | | import { ConfigProvider, notification, Modal, Collapse, Switch, Button, message, Spin, Icon } from 'antd' |
| | | import { ConfigProvider, notification, Modal, Collapse, Switch, Button, message, Spin, Icon, Typography } from 'antd' |
| | | |
| | | import Api from '@/api' |
| | | import Utils, { setGLOBFuncs } from '@/utils/utils.js' |
| | |
| | | |
| | | const { Panel } = Collapse |
| | | const { confirm } = Modal |
| | | const { Paragraph } = Typography |
| | | |
| | | const Header = asyncComponent(() => import('@/mob/header')) |
| | | const MenuForm = asyncComponent(() => import('./menuform')) |
| | |
| | | {config ? <UrlFieldComponent config={config} updateConfig={this.updateConfig}/> : null} |
| | | {/* 表名添加 */} |
| | | {config ? <TableComponent config={config} updatetable={this.updateConfig}/> : null} |
| | | <Paragraph style={{padding: '15px 0px 0px 18px'}} copyable={{ text: MenuId }}>菜单ID</Paragraph> |
| | | </Panel> |
| | | {/* 组件添加 */} |
| | | <Panel header={dict['mob.component']} key="component"> |
| | |
| | | import { is, fromJS } from 'immutable' |
| | | import moment from 'moment' |
| | | import HTML5Backend from 'react-dnd-html5-backend' |
| | | import { ConfigProvider, notification, Modal, Collapse, Switch, Button, Icon, message, Spin } from 'antd' |
| | | import { ConfigProvider, notification, Modal, Collapse, Switch, Button, Icon, message, Spin, Typography } from 'antd' |
| | | |
| | | import Api from '@/api' |
| | | import Utils, { setGLOBFuncs } from '@/utils/utils.js' |
| | |
| | | |
| | | const { Panel } = Collapse |
| | | const { confirm } = Modal |
| | | const { Paragraph } = Typography |
| | | |
| | | const MenuForm = asyncComponent(() => import('./menuform')) |
| | | const Transfer = asyncComponent(() => import('@/pc/transfer')) |
| | |
| | | {config ? <UrlFieldComponent config={config} updateConfig={this.updateConfig}/> : null} |
| | | {/* 表名添加 */} |
| | | {config ? <TableComponent config={config} updatetable={this.updateConfig}/> : null} |
| | | <Paragraph style={{padding: '15px 0px 0px 18px'}} copyable={{ text: MenuId }}>菜单ID</Paragraph> |
| | | </Panel> |
| | | {/* 组件添加 */} |
| | | <Panel header={dict['mob.component']} key="component"> |