public/index.html | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
public/options.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/api/index.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/components/header/index.jsx | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/index.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/locales/en-US/login.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/locales/zh-CN/login.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/tabviews/zshare/normalTable/index.scss | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/login/index.jsx | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/login/index.scss | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/login/logincloudform.jsx | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/login/loginform.jsx | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
public/index.html
@@ -5,8 +5,8 @@ <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="theme-color" content="#000000" /> <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" /> <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo.png" /> <!-- <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" /> <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo.png" /> --> <script src="%PUBLIC_URL%/options.js"></script> <title></title> </head> public/options.js
@@ -3,15 +3,16 @@ appId: '201912040924165801464FF1788654BC5AC73', appkey: '20191106103859640976D6E924E464D029CF0', mainSystemApi: 'http://cloud.mk9h.cn/webapi/dostars', title: '', platTitle: '', platName: '', logo: '', favicon: '', loginlogo: '', mainlogo: '', bgImage: '', copyRight: '', icp: '', bgColor: '', ICP: '', lineColor: '', website: '', webSite: '', doclogo: '', style: '' } src/api/index.js
@@ -61,33 +61,17 @@ // axios.defaults.baseURL = 'http://127.0.0.1:8888' } } /** * @description 系统授权 */ systemauth (appId, timestamp) { return axios({ url: '/webapi/dostar', data: { rduri: 'http://minkesoft.com/mksepc/webapi/dostar', func: 'sEmpowerCloud_Get_LinkUrl', userid: '', AppID: appId, TimeStamp: timestamp } }) } /** * @description 登录系统 * @description 使用dostar接口,跳过验证 * @param {Object} param 查询及提交参数 */ loginsystem (username, password) { dostarInterface (param) { param.userid = '' return axios({ url: '/zh-CN/Home/LoginAndRedirect', data: { Username: username, Password: password } url: '/webapi/dostar', data: param }) } @@ -99,14 +83,16 @@ // func: 'webapi_login', UserName: username, Password: password, systemType: options.systemType, Type: 'X' } param.Password = Utils.formatOptions(param.Password) param.appkey = window.GLOB.appkey || '' if (isCloud && options.cloudLoginApi) { param.rduri = options.cloudLoginApi } else if (window.GLOB.mainSystemApi) { } else if (!isCloud && window.GLOB.mainSystemApi) { param.rduri = window.GLOB.mainSystemApi.replace(/\/webapi(.*)/, '/webapi/dologon') } src/components/header/index.jsx
@@ -20,7 +20,6 @@ import zhCN from '@/locales/zh-CN/header.js' import enUS from '@/locales/en-US/header.js' import Utils from '@/utils/utils.js' import logourl from '@/assets/img/main-logo.png' import avatar from '@/assets/img/avatar.jpg' import Resetpwd from './resetpwd' import LoginForm from './loginform' @@ -43,7 +42,7 @@ dict: (!localStorage.getItem('lang') || localStorage.getItem('lang') === 'zh-CN') ? zhCN : enUS, confirmLoading: false, userName: sessionStorage.getItem('User_Name'), logourl: window.GLOB.mainlogo || logourl, logourl: window.GLOB.mainlogo, loginVisible: false, loginLoading: false, avatar: avatar, src/index.js
@@ -24,7 +24,37 @@ window.GLOB = window.GLOB || {} document.title = window.GLOB.title || 'MinkeSoft' let _systemMsg = localStorage.getItem(window.location.href.split('#')[0] + 'system') if (_systemMsg) { try { _systemMsg = JSON.parse(window.decodeURIComponent(window.atob(_systemMsg))) window.GLOB.platTitle = _systemMsg.platTitle || window.GLOB.platTitle window.GLOB.platName = _systemMsg.platName || window.GLOB.platName window.GLOB.favicon = _systemMsg.favicon || window.GLOB.favicon window.GLOB.loginlogo = _systemMsg.loginlogo || window.GLOB.loginlogo window.GLOB.copyRight = _systemMsg.copyRight || window.GLOB.copyRight window.GLOB.ICP = _systemMsg.ICP || window.GLOB.ICP window.GLOB.mainlogo = _systemMsg.mainlogo || window.GLOB.mainlogo window.GLOB.doclogo = _systemMsg.doclogo || window.GLOB.doclogo window.GLOB.webSite = _systemMsg.webSite || window.GLOB.webSite if (window.GLOB.favicon) { let link = document.querySelector("link[rel*='icon']") || document.createElement('link') link.type = 'image/x-icon' link.rel = 'shortcut icon' link.href = window.GLOB.favicon document.getElementsByTagName('head')[0].appendChild(link) } } catch { console.warn('Parse Failure') } } document.title = window.GLOB.platTitle const option = { white: 'mk-white' src/locales/en-US/login.js
@@ -8,5 +8,6 @@ 'login.password.empty': 'Please input your Password!', 'login.remember': 'Remember me', 'login.submit': 'Log in', 'login.copyright': 'Copyrights by' 'login.copyright': 'Copyrights by', 'login.sync.cloud': '同步云端应用' } src/locales/zh-CN/login.js
@@ -8,5 +8,6 @@ 'login.password.empty': '请输入密码!', 'login.remember': '记住密码', 'login.submit': '登录', 'login.copyright': '所有相关版权归' 'login.copyright': '所有相关版权归', 'login.sync.cloud': '同步云端应用' } src/tabviews/zshare/normalTable/index.scss
@@ -123,6 +123,26 @@ background: lightcoral; } } .orange { .content { color: orange; } } .orangebg { .background { background: lightsalmon; } } .green { .content { color: green; } } .greenbg { .background { background: lightgreen; } } } .ant-table-tbody > tr > td .content { p { src/views/login/index.jsx
@@ -1,5 +1,5 @@ import React, {Component} from 'react' import { message } from 'antd' import { message, Modal } from 'antd' import md5 from 'md5' import moment from 'moment' import Api from '@/api' @@ -9,11 +9,10 @@ import Utils from '@/utils/utils.js' import asyncComponent from '@/utils/asyncComponent' import asyncLoadComponent from '@/utils/asyncLoadComponent' import logourl from '@/assets/img/login-logo.png' import loginbg from '@/assets/img/loginbg.jpg' import './index.scss' const LoginForm = asyncLoadComponent(() => import('./loginform')) const LoginCloudForm = asyncLoadComponent(() => import('./logincloudform')) const Action = asyncComponent(() => import('@/tabviews/zshare/actionList')) const iszhCN = !localStorage.getItem('lang') || localStorage.getItem('lang') === 'zh-CN' @@ -23,15 +22,17 @@ dict: iszhCN ? zhCN : enUS, isDisabled: false, auth: false, logo: window.GLOB.logo || logourl, bgImage: window.GLOB.bgImage || loginbg, platName: window.GLOB.platName || '明科商业智能开放平台', copyright: window.GLOB.copyRight || 'Copyright©2017 所有相关版权归 北京明科普华信息技术有限公司', ICP: window.GLOB.icp || 'ICP备案: 京ICP备12007830号', bgColor: window.GLOB.bgColor || '#000000', lineColor: window.GLOB.lineColor || '#1890ff', website: window.GLOB.website || (!window.GLOB.copyRight && 'http://minkesoft.com'), loaded: false loginlogo: window.GLOB.loginlogo, bgImage: window.GLOB.bgImage, platName: window.GLOB.platName, copyRight: window.GLOB.copyRight, ICP: window.GLOB.ICP, lineColor: window.GLOB.lineColor, webSite: window.GLOB.webSite, langList: [], loaded: false, syncApp: false, syncing: false } changelang (item) { @@ -67,7 +68,7 @@ sessionStorage.setItem('Full_Name', res.FullName) sessionStorage.setItem('avatar', res.icon || '') localStorage.setItem('lang', param.lang) localStorage.setItem('lang', param.lang || 'zh-CN') let _url = window.location.href.split('#')[0] @@ -83,6 +84,13 @@ } else { this.props.history.replace('/main') } } else if (res.ErrCode === 'Need_Get_Appkey' && options.systemType === 'SSO') { message.warning('应用尚未创建,请向云端同步应用!') this.setState({ isDisabled: false, syncApp: true }) } else { message.warning(res.message) this.setState({ @@ -100,7 +108,15 @@ } let str = md5('MK19' + _appId + timeStamp) Api.systemauth(_appId, timeStamp).then(res => { let param = { rduri: 'http://minkesoft.com/mksepc/webapi/dostar', func: 'sEmpowerCloud_Get_LinkUrl', AppID: _appId, TimeStamp: timeStamp } Api.dostarInterface(param).then(res => { if (res.status) { if (res.EPC === str) { let box = [] @@ -131,26 +147,137 @@ }) } // let link = document.querySelector("link[rel*='icon']") || document.createElement('link') // link.type = 'image/x-icon' // link.rel = 'shortcut icon' // link.href = 'http://www.stackoverflow.com/favicon.ico' // document.getElementsByTagName('head')[0].appendChild(link) // 获取系统信息 let _param = { func: 's_Get_style', Appkey: window.GLOB.appkey || '', TypeCharOne: 'PC', LText: `select '${window.GLOB.appkey}'`, } _param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000' _param.secretkey = Utils.encrypt(_param.LText, _param.timestamp) if (window.GLOB.mainSystemApi) { _param.rduri = window.GLOB.mainSystemApi.replace('dostars', 'dostar') } Api.dostarInterface(_param).then(res => { if (res.status) { let _url = window.location.href.split('#')[0] + 'system' let systemMsg = { favicon: res.titlelogo || '', platTitle: res.titleName || '', platName: res.SysName || '', bgImage: res.Banner || '', loginlogo: res.loginlogo || '', copyRight: res.CopyRightYear && res.CopyRightOrg ? `Copyright©${res.CopyRightYear} 所有相关版权归 ${res.CopyRightOrg}` : '', ICP: res.ICP || '', mainlogo: res.indexlogo || '', doclogo: res.doclogo || '', webSite: res.WebSite || '' } try { localStorage.setItem(_url, window.btoa(window.encodeURIComponent(JSON.stringify(systemMsg)))) } catch { localStorage.removeItem(_url) } this.setState({ langList: res.lang_data || [], ...systemMsg }) if (res.titlelogo && window.GLOB.favicon !== res.titlelogo) { let link = document.querySelector("link[rel*='icon']") || document.createElement('link') link.type = 'image/x-icon' link.rel = 'shortcut icon' link.href = res.titlelogo document.getElementsByTagName('head')[0].appendChild(link) } } else { message.warning(res.message) } }) } syncSubmit = () => { this.setState({ syncing: true }) let param = { func: 's_get_app_from_cloud', UserName: '', Password: '', systemType: options.systemType, Type: 'X', debug: 'Y' } param.appkey = window.GLOB.appkey || '' if (options.cloudServiceApi) { param.rduri = options.cloudServiceApi.replace('dostars', 'dostar') } this.logincloudRef.handleConfirm().then(result => { param.UserName = result.cloudusername param.Password = result.cloudpassword param.Password = Utils.formatOptions(param.Password) Api.dostarInterface(param).then(res => { if (res.status) { let _param = { func: 's_sDataDictb_TBBack', LTextOut: res.LTextOut, lid: res.Lid, Appkey: window.GLOB.appkey || '' } Api.dostarInterface(_param).then(response => { if (response.status) { message.success('应用创建成功。') this.setState({ syncing: false, syncApp: false }) } else { this.setState({ syncing: false }) message.warning(response.message) } }) } else { this.setState({ syncing: false }) message.warning(res.message) } }) }) } render () { const { lineColor, bgImage, loginlogo, copyRight, webSite, ICP } = this.state return ( <div className="login-container" style={{backgroundImage: 'url(' + this.state.bgImage + ')', backgroundColor: this.state.bgColor}}> <div className="logo" style={{borderColor: this.state.lineColor}}> <img src={this.state.logo} alt=""/> <div className="login-container" style={bgImage ? {backgroundImage: 'url(' + bgImage + ')'} : {}}> <div className="logo" style={lineColor ? {borderColor: lineColor} : {}}> {loginlogo ? <img src={loginlogo} alt=""/> : null} </div> <div className="login-middle" style={{borderColor: this.state.lineColor}}> <div className="login-middle" style={lineColor ? {borderColor: lineColor} : {}}> <LoginForm platName={this.state.platName} dict={this.state.dict} auth={this.state.auth} lang={this.state.selectedlang} langList={this.state.langList} isDisabled={this.state.isDisabled} changelang={(value) => this.changelang(value)} handleSubmit={() => this.handleSubmit()} @@ -159,12 +286,27 @@ /> </div> <div className="login-bottom"> {this.state.website ? <a target="blank" href={this.state.website} dangerouslySetInnerHTML={{ __html: this.state.copyright.replace(/\s/ig, ' ') }}></a> : <p dangerouslySetInnerHTML={{ __html: this.state.copyright.replace(/\s/ig, ' ') }}></p> {webSite && copyRight ? <a target="blank" href={webSite} dangerouslySetInnerHTML={{ __html: copyRight.replace(/\s/ig, ' ') }}></a> : <p dangerouslySetInnerHTML={{ __html: copyRight ? copyRight.replace(/\s/ig, ' ') : '' }}></p> } <p dangerouslySetInnerHTML={{ __html: this.state.ICP.replace(/\s/ig, ' ') }}></p> {ICP ? <p dangerouslySetInnerHTML={{ __html: ICP.replace(/\s/ig, ' ') }}></p> : null} </div> {/* 编辑状态登录 */} <Modal title={this.state.dict['login.sync.cloud']} okText={this.state.dict['login.auth.ok']} cancelText={this.state.dict['login.auth.cancel']} visible={this.state.syncApp} onOk={this.syncSubmit} className="sync-cloud-application" width={'430px'} confirmLoading={this.state.syncing} onCancel={() => {this.setState({ syncApp: false, syncing: false })}} destroyOnClose > <LoginCloudForm handleSubmit={() => this.syncSubmit()} wrappedComponentRef={(inst) => this.logincloudRef = inst}/> </Modal> {this.state.loaded ? <div style={{position: 'fixed', bottom: '-300px'}}> <Action BID="" src/views/login/index.scss
@@ -1,6 +1,7 @@ .login-container { height: 100vh; min-height: 600px; background-color: #000000; background-size: cover; background-repeat: no-repeat; background-position: center center; @@ -8,17 +9,18 @@ height: 100px; padding-top: 30px; line-height: 80px; border-bottom: 2px solid #06b4f7; border-bottom: 2px solid #1890ff; img { max-height: 100%; } } .login-middle { position: relative; height: calc(100vh - 194px); min-height: 420px; background-size: cover; background-position: center center; border-bottom: 2px solid #06b4f7; border-bottom: 2px solid #1890ff; .login-form { float: right; @@ -93,6 +95,11 @@ color: #1890ff; } } .login-sync-button { position: absolute; bottom: 10px; left: 20px; } } .login-bottom { text-align: center; @@ -113,6 +120,11 @@ border-color: #40a9ff; } } .sync-cloud-application { .ant-modal-body { min-height: 176px; } } .ant-message { top: 50px; z-index: 1080; src/views/login/logincloudform.jsx
New file @@ -0,0 +1,87 @@ import React, {Component} from 'react' import PropTypes from 'prop-types' import { Form, Icon, Input } from 'antd' import zhCN from '@/locales/zh-CN/login.js' import enUS from '@/locales/en-US/login.js' import './index.scss' class HeaderLoginForm extends Component { static propTpyes = { handleSubmit: PropTypes.func } state = { dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS } handleConfirm = () => { // 表单提交时检查输入值是否正确 return new Promise((resolve, reject) => { this.props.form.validateFieldsAndScroll((err, values) => { if (!err) { resolve(values) } else { reject(err) } }) }) } handleSubmit = (e, key) => { e.preventDefault() if (e.target.value) { if (!this.props.form.getFieldValue(key)) { const input = document.getElementById(key) if (input) { input.focus() } return } this.props.handleSubmit() } else { this.handleConfirm() } } componentDidMount () { const input = document.getElementById('username') if (input) { input.focus() } } render() { const { getFieldDecorator } = this.props.form return ( <Form style={{margin: '0px 10px'}}> <Form.Item> {getFieldDecorator('cloudusername', { rules: [{ required: true, message: this.state.dict['login.username.empty'] }], initialValue: '', })( <Input prefix={<Icon type="user" style={{ color: 'rgba(0,0,0,.25)' }} />} placeholder={this.state.dict['login.username']} autoComplete="off" onPressEnter={(e) => {this.handleSubmit(e, 'cloudpassword')}} /> )} </Form.Item> <Form.Item> {getFieldDecorator('cloudpassword', { initialValue: '', rules: [ { required: true, message: this.state.dict['login.password.empty'], } ] })(<Input.Password onPressEnter={(e) => {this.handleSubmit(e, 'cloudusername')}} placeholder={this.state.dict['login.password']} prefix={<Icon type="lock" style={{ color: 'rgba(0,0,0,.25)' }} />} />)} </Form.Item> </Form> ) } } export default Form.create()(HeaderLoginForm) src/views/login/loginform.jsx
@@ -14,6 +14,7 @@ dict: PropTypes.object, auth: PropTypes.bool, lang: PropTypes.string, langList: PropTypes.array, platName: PropTypes.string } @@ -135,7 +136,7 @@ initialValue: true, })(<Checkbox>{this.props.dict['login.remember']}</Checkbox>)} </Form.Item> <Form.Item className="minline right"> {this.props.langList && this.props.langList.length > 0 ? <Form.Item className="minline right"> {getFieldDecorator('lang', { initialValue: this.props.lang, })( @@ -143,11 +144,12 @@ onChange={(value) => {this.changelang(value)}} getPopupContainer={() => document.getElementById('login-form')} > <Select.Option value="zh-CN">中文简体</Select.Option> <Select.Option value="en-US">English</Select.Option> {this.props.langList.map((item, index) => { return <Select.Option key={index} value={item.Lang}>{item.LangName}</Select.Option> })} </Select> )} </Form.Item> </Form.Item> : null} <Form.Item className="btn-login"> <Button type="primary" htmlType="submit" className="login-form-button" disabled={this.props.isDisabled} loading={this.props.isDisabled}> {this.props.dict['login.submit']}