From df565b506ddb2bed918befceefddcd529eb58782 Mon Sep 17 00:00:00 2001 From: king <18310653075@163.com> Date: 星期一, 17 八月 2020 00:18:17 +0800 Subject: [PATCH] 2020-08-17 --- src/components/tabview/index.jsx | 7 src/templates/calendarconfig/calcomponent/calendarform/index.jsx | 19 + src/tabviews/zshare/actionList/tabbutton/index.jsx | 5 src/templates/calendarconfig/index.scss | 28 - src/tabviews/zshare/calendar/index.jsx | 72 ++-- src/templates/calendarconfig/calcomponent/index.scss | 1 src/tabviews/calendar/index.scss | 58 +++ src/templates/calendarconfig/index.jsx | 35 + src/tabviews/calendar/index.jsx | 647 ++++++++++++++++++++++++++++++++++++++ src/templates/calendarconfig/tabcomponent/index.scss | 1 src/templates/sharecomponent/datasourcecomponent/verifycard/customscript/index.jsx | 2 src/tabviews/zshare/mutilform/index.jsx | 2 src/components/404/index.scss | 5 src/tabviews/zshare/actionList/index.jsx | 3 src/tabviews/subtabtable/index.jsx | 14 src/templates/calendarconfig/source.jsx | 3 src/templates/sharecomponent/datasourcecomponent/verifycard/settingform/index.jsx | 6 src/utils/option.js | 18 src/tabviews/zshare/calendar/index.scss | 35 + 19 files changed, 866 insertions(+), 95 deletions(-) diff --git a/src/components/404/index.scss b/src/components/404/index.scss index d853ab0..b8e9a30 100644 --- a/src/components/404/index.scss +++ b/src/components/404/index.scss @@ -1,4 +1,9 @@ .box404 { max-height: calc(100vh - 110px); text-align: center; +} +.ant-tabs-tabpane { + >.box404 { + padding-top: 40px; + } } \ No newline at end of file diff --git a/src/components/tabview/index.jsx b/src/components/tabview/index.jsx index 15e2679..7079a93 100644 --- a/src/components/tabview/index.jsx +++ b/src/components/tabview/index.jsx @@ -19,6 +19,7 @@ const Home = asyncComponent(() => import('@/tabviews/home')) const CommonTable = asyncComponent(() => import('@/tabviews/commontable')) +const CalendarPage = asyncComponent(() => import('@/tabviews/calendar')) const TreePage = asyncComponent(() => import('@/tabviews/treepage')) const VerupTable = asyncComponent(() => import('@/tabviews/verupmanage')) const ScriptTable = asyncComponent(() => import('@/tabviews/scriptmanage')) @@ -105,6 +106,8 @@ return (<CommonTable MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID} param={view.param}/>) } else if (view.type === 'TreePage') { return (<TreePage MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID} param={view.param}/>) + } else if (view.type === 'CalendarPage') { + return (<CalendarPage MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID} param={view.param}/>) } else if (view.type === 'VerupTable') { return (<VerupTable MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID}/>) } else if (view.type === 'ScriptTable') { @@ -210,7 +213,7 @@ <Tabs.TabPane tab={ <span className="tab-control"> - {['CommonTable', 'FormTab', 'TreePage'].includes(view.type) ? + {['CommonTable', 'FormTab', 'TreePage', 'CalendarPage'].includes(view.type) ? <Icon type="redo" onClick={(e) => {this.refreshTabview(e, view)}}/> : null } <span className="tab-name" onClick={(e) => {this.changeTab(e, view)}}> @@ -224,7 +227,7 @@ key={view.MenuID} > {this.selectcomponent(view)} - {options.sysType !== 'cloud' && !['CommonTable', 'TreePage', 'ManageTable'].includes(view.type) ? + {options.sysType !== 'cloud' && !['CommonTable', 'TreePage', 'ManageTable', 'CalendarPage'].includes(view.type) ? <Button icon="copy" shape="circle" diff --git a/src/tabviews/calendar/index.jsx b/src/tabviews/calendar/index.jsx new file mode 100644 index 0000000..c059ce8 --- /dev/null +++ b/src/tabviews/calendar/index.jsx @@ -0,0 +1,647 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import {connect} from 'react-redux' +import { is, fromJS } from 'immutable' +import { notification, Spin, Modal, Button, message, Tree, Typography } from 'antd' +import moment from 'moment' + +import Api from '@/api' +import options from '@/store/options.js' +import zhCN from '@/locales/zh-CN/main.js' +import enUS from '@/locales/en-US/main.js' +import Utils from '@/utils/utils.js' +import asyncSpinComponent from '@/utils/asyncSpinComponent' +import { refreshTabView } from '@/store/action' + +import MainSearch from '@/tabviews/zshare/topSearch' +import NotFount from '@/components/404' +import './index.scss' + +// 閫氱敤缁勪欢 +const CalendarComponent = asyncSpinComponent(() => import('@/tabviews/zshare/calendar')) +const SubTabTable = asyncSpinComponent(() => import('@/tabviews/subtabtable')) + +const { TreeNode } = Tree +const { Paragraph } = Typography + +class NormalTable extends Component { + static propTpyes = { + param: PropTypes.any, // 鍏朵粬椤甸潰浼犻�掔殑鎼滅储鏉′欢绛夊弬鏁� + MenuID: PropTypes.string, // 鑿滃崟Id + MenuNo: PropTypes.string, // 鑿滃崟鍙傛暟 + MenuName: PropTypes.string // 鑿滃崟鍚嶇О + } + + state = { + dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, + ContainerId: Utils.getuuid(), // 鑿滃崟澶栧眰html Id + BID: null, // 椤甸潰璺宠浆鏃舵惡甯D + loadingview: true, // 椤甸潰鍔犺浇涓� + viewlost: false, // 椤甸潰涓㈠け锛�1銆佹湭鑾峰彇鍒伴厤缃�-椤甸潰涓㈠け锛�2銆侀〉闈㈡湭鍚敤 + lostmsg: '', // 椤甸潰涓㈠け鏃剁殑鎻愮ず淇℃伅 + config: {}, // 椤甸潰閰嶇疆淇℃伅锛屽寘鎷寜閽�佹悳绱€�佹樉绀哄垪銆佹爣绛剧瓑 + userConfig: null, // 鐢ㄦ埛鑷畾涔夎缃� + searchlist: null, // 鎼滅储鏉′欢 + arr_field: '', // 浣跨敤 sPC_Get_TableData 鏃剁殑鏌ヨ瀛楁闆� + setting: null, // 椤甸潰鍏ㄥ眬璁剧疆锛氭暟鎹簮銆佹寜閽強鏄剧ず鍒楀浐瀹氥�佷富閿瓑 + data: null, // 鍒楄〃鏁版嵁闆� + loading: false, // 鍒楄〃鏁版嵁鍔犺浇涓� + search: '', // 鎼滅储鏉′欢鏁扮粍锛屼娇鐢ㄦ椂闇�鍒嗗満鏅鐞� + visible: false, // 鏍囩椤垫帶鍒� + triggerTime: '', // 鐐瑰嚮鏃堕棿 + treevisible: false, // 鑿滃崟缁撴瀯鏍戝脊妗嗘樉绀洪殣钘忔帶鍒� + calendarYear: moment().format('YYYY') // 鏃ュ巻骞翠唤 + } + + /** + * @description 鑾峰彇椤甸潰閰嶇疆淇℃伅 + */ + async loadconfig () { + const { permAction, param } = this.props + + let _param = { + func: 'sPC_Get_LongParam', + MenuID: this.props.MenuID + } + let result = await Api.getCacheConfig(_param) + + if (result.status) { + let config = '' + let userConfig = null + let _curUserConfig = '' + + try { // 閰嶇疆淇℃伅瑙f瀽 + config = JSON.parse(window.decodeURIComponent(window.atob(result.LongParam))) + } catch (e) { + console.warn('Parse Failure') + config = '' + } + + // HS涓嶄娇鐢ㄨ嚜瀹氫箟璁剧疆 + if (result.LongParamUser && this.props.menuType !== 'HS') { + try { // 閰嶇疆淇℃伅瑙f瀽 + userConfig = JSON.parse(window.decodeURIComponent(window.atob(result.LongParamUser))) + _curUserConfig = userConfig[this.props.MenuID] + } catch (e) { + console.warn('Parse Failure') + userConfig = null + } + } + + // 椤甸潰閰嶇疆瑙f瀽閿欒鏃舵彁绀� + if (!config) { + this.setState({ + loadingview: false, + viewlost: true + }) + return + } + + // 椤甸潰鏈惎鐢ㄦ椂锛屾樉绀烘湭鍚敤椤甸潰 + if (!config.enabled) { + this.setState({ + loadingview: false, + viewlost: true, + lostmsg: this.state.dict['main.view.unenabled'] + }) + return + } + + // 鏉冮檺杩囨护 + if (this.props.menuType !== 'HS') { + if (config.tab && !permAction[config.tab.linkTab]) { + config.tab = null + } + } + + // 瀛楁鏉冮檺榛戝悕鍗� + config.search = config.search.map(item => { + item.oriInitval = item.initval + if (['text', 'select', 'link'].includes(item.type) && param) { + if (param.searchkey === item.field) { + item.initval = param.searchval + } else if (param.BID && item.field === 'BID') { + item.initval = param.BID + } + } + + if (!item.blacklist || item.blacklist.length === 0) return item + + let _black = item.blacklist.filter(v => { + return this.props.permRoles.indexOf(v) !== -1 + }) + + if (_black.length > 0) { + item.Hide = 'true' + } + + return item + }) + + if (_curUserConfig) { + config.setting = {...config.setting, ..._curUserConfig.setting} + config.easyCode = _curUserConfig.easyCode || config.easyCode || '' + } + + // 閫忚瀛楁澶勭悊锛屽垵濮嬪寲澶勭悊 + let valid = true + config.search = config.search.map(item => { + item.oriInitval = item.initval + if (['text', 'select', 'link'].includes(item.type) && param) { + if (param.searchkey === item.field) { + item.initval = param.searchval + } else if (param.BID && item.field === 'BID') { + item.initval = param.BID + } + } + + if (item.required === 'true' && !item.initval) { + valid = false + } + + return item + }) + + this.setState({ + BID: param && param.BID ? param.BID : '', + loadingview: false, + config: config, + userConfig: userConfig, + setting: config.setting, + searchlist: config.search, + arr_field: config.columns.map(item => item.field).join(','), + search: Utils.initMainSearch(config.search) // 鎼滅储鏉′欢鍒濆鍖栵紙鍚湁鏃堕棿鏍煎紡锛岄渶瑕佽浆鍖栵級 + }, () => { + if (config.setting.onload !== 'false' && valid) { // 鍒濆鍖栧彲鍔犺浇 + this.loadmaindata() + } + }) + } else { + this.setState({ + loadingview: false, + viewlost: true + }) + notification.warning({ + top: 92, + message: result.message, + duration: 5 + }) + } + } + + /** + * @description 涓昏〃鏁版嵁鍔犺浇 + */ + async loadmaindata () { + const { setting, search, BID } = this.state + let param = '' + let requireFields = search.filter(item => item.required && (!item.value || item.value.length === 0)) + + if (requireFields.length > 0) { + let labels = requireFields.map(item => item.label) + labels = Array.from(new Set(labels)) + + notification.warning({ + top: 92, + message: this.state.dict['form.required.input'] + labels.join('銆�') + ' !', + duration: 3 + }) + return + } + + this.setState({ + loading: true + }) + + if (setting.interType !== 'inner' || (setting.interType === 'inner' && setting.innerFunc)) { + param = this.getCustomParam() + } else { + param = this.getDefaultParam() + } + + if (BID) { + param.BID = BID + } + // 鏁版嵁绠$悊鏉冮檺 + if (this.props.dataManager) { + param.dataM = 'Y' + } + + let result = await Api.genericInterface(param) + if (result.status) { + this.setState({ + data: result.data.map((item, index) => { + item.key = index + return item + }), + loading: false + }) + } else { + this.setState({ + loading: false + }) + notification.error({ + top: 92, + message: result.message, + duration: 10 + }) + } + } + + /** + * @description 鑾峰彇鐢ㄦ埛鑷畾涔夊瓨鍌ㄨ繃绋嬩紶鍙� + */ + getCustomParam = () => { + const { search, setting, calendarYear, config } = this.state + + let _search = Utils.formatCustomMainSearch(search) + + let param = { + ..._search + } + + if (config.calendar.refresh === 'true') { + param.calendarDate = calendarYear + } + + if (setting.interType === 'inner') { + param.func = setting.innerFunc + } else { + if (this.props.menuType === 'HS') { + if (setting.sysInterface === 'true' && options.cloudServiceApi) { + param.rduri = options.cloudServiceApi + } else if (setting.sysInterface !== 'true') { + param.rduri = setting.interface + } + } else { + if (setting.sysInterface === 'true' && window.GLOB.mainSystemApi) { + param.rduri = window.GLOB.mainSystemApi + } else if (setting.sysInterface !== 'true') { + param.rduri = setting.interface + } + } + + if (setting.outerFunc) { + param.func = setting.outerFunc + } + } + + return param + } + + /** + * @description 鑾峰彇绯荤粺瀛樺偍杩囩▼ sPC_Get_TableData 鐨勫弬鏁� + */ + getDefaultParam = () => { + const { arr_field, search, setting, config, calendarYear } = this.state + + let _search = Utils.joinMainSearchkey(search) + + _search = _search ? 'where ' + _search : '' + + let param = { + func: 'sPC_Get_TableData', + obj_name: 'data', + arr_field: arr_field, + custom_script: setting.customScript || '', + default_sql: setting.default || 'true' + } + + let _dataresource = setting.dataresource + + if (/\s/.test(_dataresource)) { + _dataresource = '(' + _dataresource + ') tb' + } + + if (this.props.dataManager) { // 鏁版嵁鏉冮檺 + _dataresource = _dataresource.replace(/\$@/ig, '/*') + _dataresource = _dataresource.replace(/@\$/ig, '*/') + param.custom_script = param.custom_script.replace(/\$@/ig, '/*') + param.custom_script = param.custom_script.replace(/@\$/ig, '*/') + } else { + _dataresource = _dataresource.replace(/@\$|\$@/ig, '') + param.custom_script = param.custom_script.replace(/@\$|\$@/ig, '') + } + + let regoptions = null + if (setting.queryType === 'statistics' || param.custom_script) { + let allSearch = Utils.getAllSearchOptions(search) + + regoptions = allSearch.map(item => { + return { + reg: new RegExp('@' + item.key + '@', 'ig'), + value: `'${item.value}'` + } + }) + } + + if (config.calendar.refresh === 'true' && regoptions) { + regoptions.push({ + reg: new RegExp('@calendarDate@', 'ig'), + value: `${calendarYear}-01-01 00:00:00.000` + }) + regoptions.push({ + reg: new RegExp('@calendarDate1@', 'ig'), + value: `${calendarYear}-12-31 23:59:59.999` + }) + } + + if (setting.queryType === 'statistics' && setting.default !== 'false') { // 缁熻鏁版嵁婧愶紝鍐呭鏇挎崲 + regoptions.forEach(item => { + _dataresource = _dataresource.replace(item.reg, item.value) + }) + _search = '' + } + + let LText = '' + + if (setting.default !== 'false') { + LText = `select ${arr_field} from ${_dataresource} ${_search}` + } + + if (param.custom_script) { + regoptions.forEach(item => { + param.custom_script = param.custom_script.replace(item.reg, item.value) + }) + + if (LText) { + LText += ` + aaa: + if @ErrorCode!='' + insert into tmp_err_retmsg (ID, ErrorCode, retmsg, CreateUserID) select @time_id@,@ErrorCode, @retmsg,@UserID@ + ` + } else { + param.custom_script += ` + aaa: + if @ErrorCode!='' + insert into tmp_err_retmsg (ID, ErrorCode, retmsg, CreateUserID) select @time_id@,@ErrorCode, @retmsg,@UserID@ + ` + } + } + + // 娴嬭瘯绯荤粺鎵撳嵃鏌ヨ璇彞 + if (options.sysType === 'local' && !window.GLOB.systemType) { + param.custom_script && console.log(`${LText ? '' : '/*涓嶆墽琛岄粯璁ql*/\n'}${param.custom_script}`) + LText && console.log(LText) + } + + param.custom_script = Utils.formatOptions(param.custom_script) + param.LText = Utils.formatOptions(LText) + param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000' + param.secretkey = Utils.encrypt(param.LText, param.timestamp) + param.DateCount = '' + + if (this.props.menuType === 'HS') { // 浜戠鏁版嵁楠岃瘉 + param.open_key = Utils.encrypt(param.secretkey, param.timestamp, true) + } + + return param + } + + /** + * @description 鎼滅储鏉′欢鏀瑰彉鏃讹紝閲嶇疆琛ㄦ牸鏁版嵁 + * 鍚湁鍒濆涓嶅姞杞界殑椤甸潰锛屼慨鏀硅缃� + */ + refreshbysearch = (searches) => { + const { setting } = this.state + + if (setting.onload === 'false') { + this.setState({ + search: searches, + setting: {...setting, onload: 'true'} + }, () => { + this.loadmaindata() + }) + } else { + this.setState({ + search: searches + }, () => { + this.loadmaindata() + }) + } + } + + + /** + * @description 椤甸潰鍒锋柊锛岄噸鏂拌幏鍙栭厤缃� + */ + reloadview = () => { + this.setState({ loadingview: true, viewlost: false, lostmsg: '', data: null, loading: false, search: '' + }, () => { + this.loadconfig() + }) + } + + + handleviewconfig = (e) => { + e.stopPropagation() + + const { MenuNo } = this.props + const { config } = this.state + + if (config && config.funcs && config.funcs.length > 0) { + this.setState({ + treevisible: true + }) + } else { + let oInput = document.createElement('input') + oInput.value = MenuNo || '' + document.body.appendChild(oInput) + oInput.select() + document.execCommand('Copy') + document.body.removeChild(oInput) + message.success(this.state.dict['main.copy.success']) + } + } + + getTreeNode = (data) => { + let _type = { + view: '椤甸潰', + btn: '鎸夐挳', + tab: '鏍囩' + } + + return data.map(item => { + let _title = _type[item.subtype] + let _others = [] + + _others.push( + (item.menuNo ? item.menuNo + '(鑿滃崟鍙傛暟)' : ''), + (item.tableName ? item.tableName + '(琛ㄥ悕) ' : ''), + (item.innerFunc ? item.innerFunc + '(鍐呴儴鍑芥暟) ' : ''), + (item.outerFunc ? item.outerFunc + '(澶栭儴鍑芥暟)' : '') + ) + _others = _others.filter(Boolean) + _others = _others.join('銆�') + + if (item.label) { + _title = _title + '(' + item.label + ')' + } + if (_others) { + _title = _title + ': ' + _others + } + + if (item.subfuncs && item.subfuncs.length > 0) { + return ( + <TreeNode title={_title} key={item.uuid} dataRef={item} selectable={false}> + {this.getTreeNode(item.subfuncs)} + </TreeNode> + ) + } + return <TreeNode key={item.uuid} title={_title} isLeaf selectable={false} /> + }) + } + + UNSAFE_componentWillMount () { + // 缁勪欢鍔犺浇鏃讹紝鑾峰彇鑿滃崟鏁版嵁 + this.loadconfig() + } + + UNSAFE_componentWillReceiveProps(nextProps) { + if (nextProps.refreshTab && nextProps.refreshTab.MenuID === this.props.MenuID) { + if (nextProps.refreshTab.position === 'grid') { + this.loadmaindata() + } else if (nextProps.refreshTab.position === 'view') { + this.reloadview() + } + this.props.refreshTabView('') + } else if (nextProps.param && !is(fromJS(this.props.param), fromJS(nextProps.param))) { + let search = this.state.search.map(item => { + if (item.type === 'text' && item.key === nextProps.param.searchkey) { + item.value = nextProps.param.searchval + } + return item + }) + this.refreshbysearch(search) + } + } + + shouldComponentUpdate (nextProps, nextState) { + return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState)) + } + + /** + * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊锛屾竻闄ゅ揩鎹烽敭璁剧疆 + */ + componentWillUnmount () { + this.setState = () => { + return + } + } + + changeDate = (value) => { + this.setState({calendarYear: value}, () => { + this.loadmaindata() + }) + } + + triggerDate = (item) => { + const { config } = this.state + let time = '' + + if (!config.tab) return + + if (item.time.length === 6) { + time = item.time.substr(0, 4) + '-' + item.time.substr(4, 2) + } else { + time = item.time.substr(0, 4) + '-' + item.time.substr(4, 2) + '-' + item.time.substr(6, 2) + } + + this.setState({ + visible: true, + triggerTime: time + }) + } + + closeTab = () => { + this.setState({ + visible: false, + triggerTime: '' + }) + } + + render() { + const { BID, searchlist, loadingview, viewlost, config, loading, data } = this.state + + return ( + <div className="calendar-page" id={this.state.ContainerId}> + {loadingview && <Spin size="large" />} + {searchlist && searchlist.length > 0 ? + <MainSearch + BID={BID} + dict={this.state.dict} + searchlist={searchlist} + menuType={this.props.menuType} + dataManager={this.props.dataManager} + refreshdata={this.refreshbysearch} + /> : null + } + {config && config.calendar ? <CalendarComponent calendar={config.calendar} loading={loading} data={data} triggerDate={this.triggerDate} changeDate={this.changeDate}/> : null} + {options.sysType !== 'cloud' ? <Button + icon="copy" + shape="circle" + className="common-table-copy" + onClick={this.handleviewconfig} + /> : null} + <Modal + className="menu-tree-modal" + title={'鑿滃崟缁撴瀯鏍�'} + width={'650px'} + maskClosable={false} + visible={this.state.treevisible} + onCancel={() => this.setState({treevisible: false})} + footer={[ + <Button key="close" onClick={() => this.setState({treevisible: false})}>{this.state.dict['main.close']}</Button> + ]} + destroyOnClose + > + <div className="menu-header"> + <span>鑿滃崟鍚嶇О锛歿this.props.MenuName}</span> + <span>鑿滃崟鍙傛暟锛歿<Paragraph copyable>{this.props.MenuNo}</Paragraph>}</span> + </div> + {this.state.treevisible ? <Tree defaultExpandAll showLine={true}> + {this.getTreeNode(config.funcs)} + </Tree> : null} + </Modal> + <Modal + title={config.tab ? config.tab.label : ''} + width={'80vw'} + maskClosable={false} + visible={this.state.visible} + onCancel={this.closeTab} + footer={[ + <Button key="close" onClick={this.closeTab}>{this.state.dict['main.close']}</Button> + ]} + destroyOnClose + > + {config.tab ? <SubTabTable + SupMenuID={this.props.MenuID} + MenuID={config.tab.linkTab} + refreshSupView={this.loadmaindata} + closeModalView={this.closeTab} + /> : null} + </Modal> + {viewlost ? <NotFount msg={this.state.lostmsg} /> : null} + </div> + ) + } +} + +const mapStateToProps = (state) => { + return { + menuType: state.editLevel, + tabviews: state.tabviews, + refreshTab: state.refreshTab, + permAction: state.permAction, + permRoles: state.permRoles, + dataManager: state.dataManager + } +} + +const mapDispatchToProps = (dispatch) => { + return { + refreshTabView: (refreshTab) => dispatch(refreshTabView(refreshTab)) + } +} + +export default connect(mapStateToProps, mapDispatchToProps)(NormalTable) \ No newline at end of file diff --git a/src/tabviews/calendar/index.scss b/src/tabviews/calendar/index.scss new file mode 100644 index 0000000..b35d19b --- /dev/null +++ b/src/tabviews/calendar/index.scss @@ -0,0 +1,58 @@ +.calendar-page { + position: relative; + min-height: calc(100vh - 94px); + padding-top: 16px; + padding-bottom: 80px; + .box404 { + padding-top: 30px; + } + + .ant-modal-mask { + position: absolute; + } + .ant-modal-wrap { + position: absolute; + } + .action-modal .ant-modal { + top: 40px; + max-width: 95%; + .ant-modal-body { + max-height: calc(100vh - 265px); + } + } + > .ant-spin { + position: absolute; + z-index: 10; + left: calc(50% - 22px); + top: calc(50vh - 70px); + } + + .common-table-copy { + position: fixed; + z-index: 2; + bottom: 65px; + right: 30px; + width: 40px; + height: 40px; + } +} + +.menu-tree-modal { + .ant-modal-body { + min-height: 300px; + .menu-header { + text-align: center; + span { + font-weight: 600; + margin-right: 20px; + } + .ant-typography { + font-weight: 600; + display: inline-block; + } + } + .ant-tree li .ant-tree-node-content-wrapper { + cursor: default; + } + } +} diff --git a/src/tabviews/subtabtable/index.jsx b/src/tabviews/subtabtable/index.jsx index 7575104..a8bb511 100644 --- a/src/tabviews/subtabtable/index.jsx +++ b/src/tabviews/subtabtable/index.jsx @@ -26,11 +26,13 @@ class SubTabModalTable extends Component { static propTpyes = { + type: PropTypes.any, // 绫诲瀷锛宑alendar闇�鐗规畩澶勭悊 BID: PropTypes.string, // 涓婄骇鏁版嵁ID BData: PropTypes.any, // 涓婄骇鏁版嵁 MenuID: PropTypes.string, // 鑿滃崟Id SupMenuID: PropTypes.string, // 涓婄骇鑿滃崟Id - refreshSupView: PropTypes.any // 鍒锋柊涓婄骇鑿滃崟 + refreshSupView: PropTypes.any, // 鍒锋柊涓婄骇鑿滃崟 + closeModalView: PropTypes.any // 鍏抽棴妯℃�佹 } state = { @@ -62,7 +64,7 @@ * @description 鑾峰彇椤甸潰閰嶇疆淇℃伅 */ async loadconfig () { - const { permAction } = this.props + const { permAction, type } = this.props let param = { func: 'sPC_Get_LongParam', @@ -135,7 +137,11 @@ } // 浠呮敮鎸乪xec銆乸rompt銆乸op 涓夌绫诲瀷鎸夐挳 - config.action = config.action.filter(item => ['exec', 'prompt', 'pop'].includes(item.OpenType)) + if (type === 'calendar') { + config.action = config.action.filter(item => ['exec', 'prompt', 'pop', 'tab'].includes(item.OpenType)) + } else { + config.action = config.action.filter(item => ['exec', 'prompt', 'pop'].includes(item.OpenType)) + } // 鏉冮檺杩囨护 if (this.props.menuType !== 'HS') { @@ -589,6 +595,8 @@ } else if (position === 'view') { this.reloadview() this.props.refreshSupView() + } else if (position === 'trigger') { // 鏃ュ巻瀛愯〃瑙﹀彂鏍囩鐐瑰嚮浜嬩欢 + this.props.closeModalView && this.props.closeModalView() } } diff --git a/src/tabviews/zshare/actionList/index.jsx b/src/tabviews/zshare/actionList/index.jsx index 8a70ac9..47cdba2 100644 --- a/src/tabviews/zshare/actionList/index.jsx +++ b/src/tabviews/zshare/actionList/index.jsx @@ -67,6 +67,8 @@ if (!unclose) { this.setState({running: false}) } + } else if (type === 'trigger') { // 鏃ュ巻涓殑鏂版爣绛鹃〉瑙﹀彂浜嬩欢 + this.props.refreshdata('trigger') } } @@ -139,6 +141,7 @@ setting={setting} selectedData={selectedData} triggerBtn={this.state.triggerBtn} + updateStatus={this.updateStatus} /> ) } else if (item.OpenType === 'innerpage' || item.OpenType === 'outerpage') { diff --git a/src/tabviews/zshare/actionList/tabbutton/index.jsx b/src/tabviews/zshare/actionList/tabbutton/index.jsx index acfd936..8f4935b 100644 --- a/src/tabviews/zshare/actionList/tabbutton/index.jsx +++ b/src/tabviews/zshare/actionList/tabbutton/index.jsx @@ -17,6 +17,7 @@ selectedData: PropTypes.any, // 瀛愯〃涓�夋嫨鏁版嵁 setting: PropTypes.any, // 椤甸潰閫氱敤璁剧疆 triggerBtn: PropTypes.any, + updateStatus: PropTypes.any } state = { @@ -131,6 +132,10 @@ tabs.splice(index + 1, 0, newtab) } + if (this.props.updateStatus) { + this.props.updateStatus('trigger') + } + this.props.modifyTabview(tabs) } diff --git a/src/tabviews/zshare/calendar/index.jsx b/src/tabviews/zshare/calendar/index.jsx index 6616507..8ac9028 100644 --- a/src/tabviews/zshare/calendar/index.jsx +++ b/src/tabviews/zshare/calendar/index.jsx @@ -1,10 +1,9 @@ import React, {Component} from 'react' import PropTypes from 'prop-types' import { is, fromJS } from 'immutable' -import { Select, Radio, Row, Col, Popover, Badge } from 'antd' +import { Select, Radio, Row, Col, Popover, Badge, Spin } from 'antd' import moment from 'moment' -// import Utils from '@/utils/utils.js' import './index.scss' const { Option } = Select @@ -13,6 +12,8 @@ static propTpyes = { data: PropTypes.any, // 浜嬩欢鏁版嵁 calendar: PropTypes.any, + changeDate: PropTypes.func, + triggerDate: PropTypes.func, loading: false } @@ -63,7 +64,7 @@ UNSAFE_componentWillReceiveProps(nextProps) { if (!is(fromJS(this.props.data), fromJS(nextProps.data))) { - let datelist = this.mountdata(this.state.datelist, nextProps.data) + let datelist = this.mountdata(this.state.datelist, nextProps.data || []) let monthlist = null if (this.state.levels.includes('month')) { @@ -89,18 +90,8 @@ const { calendar } = this.props let datalist = [] - let levels = { - black: 1, - red: 2, - orange: 3, - yellow: 4, - green: 5, - lightgreen: 6, - cyan: 7, - blue: 8, - purple: 9, - white: 10 - } + let levels = { red: 1, orange: 2, yellow: 3, green: 4, cyan: 5, blue: 6, purple: 7, gray: 8 } + let colors = { red: '#d0021b', orange: '#f5a623', yellow: '#f8e71c', green: '#7ed321', cyan: '#50e3c2', blue: '#1890ff', purple: '#bd10e0', gray: '#9b9b9b' } data.forEach(item => { let startTime = item[calendar.startfield] @@ -112,7 +103,7 @@ if (!item[calendar.remarkfield]) return datalist.push({ - color: color, + color: colors[color] || '', level: color && levels[color] ? levels[color] : 100, remark: item[calendar.remarkfield], startMonth: startTime.substr(0, 4) + startTime.substr(5, 2), @@ -129,16 +120,14 @@ datalist.sort((a, b) => a.level - b.level) let styles = [ - {background: 'black', color: '#ffffff'}, - {background: 'red', color: '#ffffff'}, - {background: 'orange', color: '#ffffff'}, - {background: 'yellow', color: 'rgba(0,0,0,.65)'}, - {background: 'green', color: '#ffffff'}, - {background: 'lightgreen', color: 'rgba(0,0,0,.65)'}, - {background: 'cyan', color: 'rgba(0,0,0,.65)'}, - {background: 'blue', color: '#ffffff'}, - {background: 'purple', color: '#ffffff'}, - {background: 'white', color: 'rgba(0,0,0,.65)'}, + {background: '#d0021b', color: '#ffffff'}, + {background: '#f5a623', color: '#ffffff'}, + {background: '#f8e71c', color: '#ffffff'}, + {background: '#7ed321', color: '#ffffff'}, + {background: '#50e3c2', color: '#ffffff'}, + {background: '#1890ff', color: '#ffffff'}, + {background: '#bd10e0', color: '#ffffff'}, + {background: '#9b9b9b', color: '#ffffff'}, ] return datelist.map(month => { @@ -147,6 +136,9 @@ month.subData.push(item) } }) + if (month.subData[0]) { + month.style = styles[month.subData[0].level - 1] || null + } month.sublist = month.sublist.map(week => { week.sublist = week.sublist.map(day => { if (!day) return null @@ -221,6 +213,7 @@ } yearChange = (value) => { + const { calendar, data } = this.props const { levels, selectMonth } = this.state let datelist = this.getDateList(value) let monthlist = null @@ -228,10 +221,14 @@ if (levels.includes('month')) { monthlist = datelist.filter(item => item.month === selectMonth)[0] } + + if (calendar.refresh !== 'true') { + datelist = this.mountdata(datelist, data) - this.setState({ selectYear: value, datelist, monthlist }) + this.setState({ selectYear: value, datelist, monthlist }) + } else { + this.setState({ selectYear: value, datelist, monthlist }) - if (this.props.changeDate) { this.props.changeDate(value) } } @@ -246,16 +243,19 @@ } triggerDay = (item) => { - + if (this.props.triggerDate) { + this.props.triggerDate(item) + } } render() { const { loading } = this.props const { level, selectMonth, selectYear, yearlist, levels, datelist, monthlist } = this.state const _levelName = {day: '鏃�', month: '鏈�', year: '骞�'} - console.log(loading) + return ( <div className="mk-calendar"> + {loading ? <div className="loading-data"><Spin /></div> : null} <div className="mk-calendar-control"> <Select value={selectYear} onChange={this.yearChange}> {yearlist.map(item => (<Option key={item} value={item}>{item}骞�</Option>))} @@ -341,8 +341,8 @@ </div> <ul className="content"> {d.subData.map((data, index) => ( - <li key={index} className="message" title={data.remark}> - <Badge color={data.color} text={data.remark} /> + <li key={index} className="message"> + <Badge color={d.style ? (data.color === d.style.background ? '#ffffff' : data.color) : data.color} text={data.remark} /> </li> ))} </ul> @@ -357,14 +357,14 @@ {level === 'year' && monthlist ? <Row className="year-calendar"> {datelist.map(item => ( <Col span={8} key={item.month}> - <div className="year-wrap"> - <div className="header"> + <div className="year-wrap" style={item.style || null} onClick={() => this.triggerDay(item)}> + <div className="header" style={item.style ? null : {color: '#1890ff'}}> {item.label} </div> <ul className="content"> {item.subData.map((data, index) => ( - <li key={index} className="message" title={data.remark}> - <Badge color={data.color} text={data.remark} /> + <li key={index} className="message"> + <Badge color={item.style ? (data.color === item.style.background ? '#ffffff' : data.color) : data.color} text={`${data.remark}(${data.startTime} ~ ${data.endTime})`}/> </li> ))} </ul> diff --git a/src/tabviews/zshare/calendar/index.scss b/src/tabviews/zshare/calendar/index.scss index a3a0122..4a4e725 100644 --- a/src/tabviews/zshare/calendar/index.scss +++ b/src/tabviews/zshare/calendar/index.scss @@ -1,7 +1,23 @@ .mk-calendar { + position: relative; width: 100%; padding: 20px; + .loading-data { + position: absolute; + top: 0; + left: 20px; + right: 20px; + bottom: 0; + z-index: 2; + opacity: 0.5; + background: #ffffff; + .ant-spin-spinning { + position: absolute; + left: 50%; + top: 270px; + } + } .mk-calendar-control { text-align: right; .ant-select { @@ -69,8 +85,10 @@ .month-wrap { cursor: pointer; height: 120px; - width: 100%; + width: calc(100% - 2px); transition: background 0.1s; + margin-bottom: 2px; + box-shadow: 0px 0px 1px #f7f7f7; .header { text-align: center; font-size: 16px; @@ -97,8 +115,8 @@ } .content::-webkit-scrollbar-thumb { border-radius: 5px; - box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.09); - background: rgba(0, 0, 0, 0.09); + box-shadow: inset 0 0 5px rgba(255, 255, 255, 0.7); + background: rgba(255, 255, 255, 0.7); } .content::-webkit-scrollbar-track { box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05); @@ -117,17 +135,22 @@ } .year-calendar { .year-wrap { + width: calc(100% - 2px); cursor: pointer; transition: background 0.1s; + box-shadow: 0px 0px 1px #f7f7f7; .header { text-align: center; font-size: 16px; - color: #1890ff; } .content { padding: 5px 15px 10px; height: 110px; overflow-y: auto; + margin-bottom: 2px; + .ant-badge-status-text { + color: inherit; + } .message { width: 100%; white-space: nowrap; @@ -140,8 +163,8 @@ } .content::-webkit-scrollbar-thumb { border-radius: 5px; - box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.09); - background: rgba(0, 0, 0, 0.09); + box-shadow: inset 0 0 5px rgba(255, 255, 255, 0.7); + background: rgba(255, 255, 255, 0.7); } .content::-webkit-scrollbar-track { box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05); diff --git a/src/tabviews/zshare/mutilform/index.jsx b/src/tabviews/zshare/mutilform/index.jsx index 5046aa5..e55e72c 100644 --- a/src/tabviews/zshare/mutilform/index.jsx +++ b/src/tabviews/zshare/mutilform/index.jsx @@ -579,7 +579,7 @@ })( <Select onChange={(value, option) => {this.selectChange(item, value, option)}} disabled={item.readonly === 'true'}> {calendarColors.map(option => - <Select.Option key={option.name} style={{background: option.name, color: option.value}} value={option.name}>{option.name}</Select.Option> + <Select.Option key={option.name} style={{background: option.value, color: '#ffffff'}} value={option.name}>{option.name}</Select.Option> )} </Select> )} diff --git a/src/templates/calendarconfig/calcomponent/calendarform/index.jsx b/src/templates/calendarconfig/calcomponent/calendarform/index.jsx index 5f3e05b..5a25c6a 100644 --- a/src/templates/calendarconfig/calcomponent/calendarform/index.jsx +++ b/src/templates/calendarconfig/calcomponent/calendarform/index.jsx @@ -1,6 +1,6 @@ import React, {Component} from 'react' import PropTypes from 'prop-types' -import { Form, Row, Col, Select, Checkbox } from 'antd' +import { Form, Row, Col, Select, Checkbox, Tooltip, Icon, Radio } from 'antd' import './index.scss' class MainTab extends Component { @@ -130,6 +130,23 @@ )} </Form.Item> </Col> + <Col span={24}> + <Form.Item label={ + <Tooltip placement="topLeft" title="寮�鍚悗锛屼娇鐢ㄧ郴缁熷嚱鏁版椂浼氳嚜鍔ㄦ浛鎹㈡暟鎹簮鍙婅嚜瀹氫箟鑴氭湰涓殑calendarDate涓巆alendarDate1锛屽叾鍊煎垎鍒负閫夋嫨骞翠唤鐨勫紑濮嬪拰缁撴潫鏃堕棿锛屼娇鐢ㄨ嚜瀹氫箟鍑芥暟鏃讹紝浼氬鍔燾alendarDate浼犲弬锛屽叾鍊间负閫夋嫨骞翠唤銆�"> + <Icon type="question-circle" /> + 鏁版嵁鍒锋柊 + </Tooltip> + }> + {getFieldDecorator('refresh', { + initialValue: calendar.refresh || 'false', + })( + <Radio.Group> + <Radio key="true" value="true">寮�鍚�</Radio> + <Radio key="false" value="false">鍏抽棴</Radio> + </Radio.Group> + )} + </Form.Item> + </Col> </Row> </Form> ) diff --git a/src/templates/calendarconfig/calcomponent/index.scss b/src/templates/calendarconfig/calcomponent/index.scss index c1425e5..5065e8f 100644 --- a/src/templates/calendarconfig/calcomponent/index.scss +++ b/src/templates/calendarconfig/calcomponent/index.scss @@ -2,6 +2,7 @@ position: absolute; right: 0; top: 0; + z-index: 2; >.anticon-edit { font-size: 18px; padding: 5px; diff --git a/src/templates/calendarconfig/index.jsx b/src/templates/calendarconfig/index.jsx index dd221d5..7edfa86 100644 --- a/src/templates/calendarconfig/index.jsx +++ b/src/templates/calendarconfig/index.jsx @@ -94,6 +94,12 @@ }) } + if (_config.type === 'user') { + if (_config.tab) { + _config.tab.linkTab = '' + } + } + this.setState({ openEdition: menu.open_edition || '', optionLibs: optionLibs, @@ -120,10 +126,10 @@ {color: 'orange', remark: '绯荤粺寮傚父锛岃鍙婃椂澶勭悊锛�'}, {color: 'yellow', remark: '鎮ㄧ殑璁㈠崟寮傚父锛岃鑱旂郴瀹㈡湇锛�'}, {color: 'green', remark: '鎮ㄧ殑璁㈠崟宸插畬鎴愩��'}, - {color: 'lightgreen', remark: '娑堟伅宸插彂閫侊紝璇峰強鏃舵煡鏀躲��'}, {color: 'cyan', remark: '鎮ㄦ湁涓�鏉℃柊鐨勬秷鎭��'}, {color: 'blue', remark: '浠诲姟鏈畬鎴愶紝璇锋敞鎰忓悗缁伐浣溿��'}, - {color: 'purple', remark: '鎮ㄦ湁鏂扮殑浠诲姟绛夊緟澶勭悊锛�'} + {color: 'purple', remark: '鎮ㄦ湁鏂扮殑浠诲姟绛夊緟澶勭悊锛�'}, + {color: 'gray', remark: '鎮ㄦ湁涓�灏佹湭璇婚偖浠躲��'} ] let mockdata = [] @@ -269,6 +275,12 @@ this.menuformRef.handleConfirm().then(res => { if (config.isAdd) { config.search = config.search.filter(item => !item.origin) + } + + if (config.type === 'user') { // 浣跨敤宸叉湁鑿滃崟鏃讹紝榛樿娣诲姞鍏宠仈鏍囩id + if (config.tab && !config.tab.linkTab) { + config.tab.linkTab = Utils.getuuid() + } } let _LongParam = '' @@ -682,15 +694,26 @@ */ verifyconfig = (config) => { let hasKey = false - let chartcols = [] + let cols = [] config.columns.forEach(col => { if (col.field) { - chartcols.push(col.field) + cols.push(col.field) } if (config.setting.primaryKey === col.field) { hasKey = true } }) + + let calvaild = true + if (!cols.includes(config.calendar.startfield)) { + calvaild = false + } else if (!cols.includes(config.calendar.endfield)) { + calvaild = false + } else if (!cols.includes(config.calendar.colorfield)) { + calvaild = false + } else if (!cols.includes(config.calendar.remarkfield)) { + calvaild = false + } if (config.setting.interType === 'inner' && !config.setting.innerFunc && config.setting.default !== 'false' && !config.setting.dataresource) { return '鑿滃崟灏氭湭璁剧疆鏁版嵁婧愶紝涓嶅彲鍚敤锛�' @@ -698,6 +721,8 @@ return '鑿滃崟灏氭湭璁剧疆涓婚敭锛屼笉鍙惎鐢紒' } else if (!hasKey) { return '鏄剧ず鍒椾腑涓嶅瓨鍦ㄤ富閿瓧娈碉紝涓嶅彲鍚敤锛�' + } else if (!calvaild) { + return '鏃ュ巻鍏宠仈瀛楁鏈缃紝涓嶅彲鍚敤锛�' } else { return true } @@ -778,7 +803,7 @@ const { activeKey, config, tabviews, mockdata, mockloading } = this.state return ( - <div className="model-subtable-board"> + <div className="model-calendar-board"> <DndProvider backend={HTML5Backend}> {/* 宸ュ叿鏍� */} <div className="tools"> diff --git a/src/templates/calendarconfig/index.scss b/src/templates/calendarconfig/index.scss index 4f1d62f..1628a90 100644 --- a/src/templates/calendarconfig/index.scss +++ b/src/templates/calendarconfig/index.scss @@ -1,4 +1,4 @@ -.model-subtable-board { +.model-calendar-board { position: fixed; z-index: 1070; padding-top: 48px; @@ -50,16 +50,7 @@ } } } - .config-btn { - position: relative; - - .config-btn-title { - margin-top: 20px; - margin-bottom: 10px; - color: #1890ff; - border-bottom: 1px solid #e8e8e8; - } - } + .ant-list { margin-top: 20px; .ant-list-item { @@ -159,21 +150,6 @@ position: relative; padding: 0; - .chart-view { - margin-bottom: 70px; - - .chart-title { - position: relative; - color: rgba(0, 0, 0, 0.65); - font-weight: 400; - font-size: 16px; - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; - margin: 0 20px; - padding: 10px 5px 5px; - } - } > .anticon-setting { position: absolute; font-size: 18px; diff --git a/src/templates/calendarconfig/source.jsx b/src/templates/calendarconfig/source.jsx index 3a9328e..a166193 100644 --- a/src/templates/calendarconfig/source.jsx +++ b/src/templates/calendarconfig/source.jsx @@ -32,7 +32,8 @@ startfield: '', endfield: '', colorfield: '', - remarkfield: '' + remarkfield: '', + refresh: 'false' }, search: [ { diff --git a/src/templates/calendarconfig/tabcomponent/index.scss b/src/templates/calendarconfig/tabcomponent/index.scss index 821081e..7658ec6 100644 --- a/src/templates/calendarconfig/tabcomponent/index.scss +++ b/src/templates/calendarconfig/tabcomponent/index.scss @@ -1,6 +1,7 @@ .model-calendar-tab { position: absolute; top: 0; + z-index: 2; >.anticon-plus { position: absolute; font-size: 18px; diff --git a/src/templates/sharecomponent/datasourcecomponent/verifycard/customscript/index.jsx b/src/templates/sharecomponent/datasourcecomponent/verifycard/customscript/index.jsx index 7b822fd..996e2ff 100644 --- a/src/templates/sharecomponent/datasourcecomponent/verifycard/customscript/index.jsx +++ b/src/templates/sharecomponent/datasourcecomponent/verifycard/customscript/index.jsx @@ -185,7 +185,7 @@ </Col> <Col span={24} className="sqlfield"> <Form.Item label={'鍙敤瀛楁'}> - id, bid, loginuid, sessionuid, userid, appkey, time_id{usefulFields ? ', ' + usefulFields : ''} + id, bid, loginuid, sessionuid, userid, appkey, time_id, calendarDate, calendarDate1{usefulFields ? ', ' + usefulFields : ''} </Form.Item> </Col> <Col span={10}> diff --git a/src/templates/sharecomponent/datasourcecomponent/verifycard/settingform/index.jsx b/src/templates/sharecomponent/datasourcecomponent/verifycard/settingform/index.jsx index 11e4b7f..bac9dbf 100644 --- a/src/templates/sharecomponent/datasourcecomponent/verifycard/settingform/index.jsx +++ b/src/templates/sharecomponent/datasourcecomponent/verifycard/settingform/index.jsx @@ -236,10 +236,10 @@ {getFieldDecorator('primaryKey', { initialValue: setting.primaryKey || '' })( - <Select onChange={(value) => {this.selectChange('primaryKey', value)}}> + <Select> {columns.map((option, i) => - <Select.Option key={i} value={option.value}> - {option.text} + <Select.Option key={i} value={option.field}> + {option.label} </Select.Option> )} </Select> diff --git a/src/utils/option.js b/src/utils/option.js index 45f2ff8..75e5645 100644 --- a/src/utils/option.js +++ b/src/utils/option.js @@ -309,16 +309,14 @@ }] export const calendarColors = [ - {name: 'black', value: '#ffffff'}, - {name: 'red', value: '#ffffff'}, - {name: 'orange', value: '#ffffff'}, - {name: 'yellow', value: 'rgba(0,0,0,.65)'}, - {name: 'green', value: '#ffffff'}, - {name: 'lightgreen', value: 'rgba(0,0,0,.65)'}, - {name: 'cyan', value: 'rgba(0,0,0,.65)'}, - {name: 'blue', value: '#ffffff'}, - {name: 'purple', value: '#ffffff'}, - {name: 'white', value: 'rgba(0,0,0,.65)'} + {name: 'red', value: '#d0021b'}, + {name: 'orange', value: '#f5a623'}, + {name: 'yellow', value: '#f8e71c'}, + {name: 'green', value: '#7ed321'}, + {name: 'cyan', value: '#50e3c2'}, + {name: 'blue', value: '#1890ff'}, + {name: 'purple', value: '#bd10e0'}, + {name: 'gray', value: '#9b9b9b'}, ] // 鏄剧ず鍒楁爣璁拌壊绯� -- Gitblit v1.8.0