Commit df7457e1 authored by 崔佳豪's avatar 崔佳豪

merge: merge master

parents c65adbef 4a90b76b
Pipeline #64497 passed with stages
# Don't check auto-generated stuff into git
coverage
build
node_modules
stats.json
.umi
.umi-production
......@@ -12,5 +12,10 @@ npm-debug.log
src/umi
.vscode
civbase
# dependencies
node_modules
npm-debug.log*
yarn-error.log
package-lock.json
yarn.lock
\ No newline at end of file
variables:
TARGET_REPO_2021: "G:/CIV_CI/CivWebPublish2021_CIVWeb5/CivWebPublish2021/"
TARGET_REPO_Solution: "G:/CIV_CI/PandaSolution/civbase/"
TEMP_DIR: "G:/CIV_CI/tempV1/civbase/"
GIT_STRATEGY: 'fetch'
GIT_CHECKOUT: 'false'
......@@ -10,17 +11,34 @@ before_script:
- 'git config core.autocrlf false'
stages:
- refresh
- install
- package
- pushSolution
- push2021
- push
refresh:
stage: refresh
tags:
- civ_base
script:
- git reset --hard
- git pull origin master
- npm run update:wisdom
# - 'git add . ; git commit --allow-empty -m "auto refresh civbase."'
# - 'git push origin master'
only:
refs:
- master
variables:
- $NPM_INSTALL == "true"
when: manual
install:
stage: install
tags:
- civ_base
script:
- git reset --hard
- git pull origin master
- npm run init
#cache:
......@@ -42,7 +60,7 @@ package:
- echo "${CI_PROJECT_DIR}"
- git pull origin master
#- npm run init
- npm run build --releasepath=../PublishTemp
- npm run build --releasepath=G:\\CIV_CI\\tempV1
#cache:
# key: ${CI_COMMIT_REF_SLUG}
# paths:
......@@ -58,18 +76,18 @@ pushSolution:
GIT_STRATEGY: none
tags:
- civ_base
stage: pushSolution
stage: push
script:
- 'cd "${TARGET_REPO_Solution}"'
- 'git reset --hard head'
- 'git clean -fd'
- 'git remote set-url origin "https://${GIT_ACCESS_USER}:${GIT_ACCESS_PASSWORD}@g.civnet.cn:8443/PandaSolution/civbase.git"'
- 'git pull origin test'
- 'git pull origin master'
- 'git rm -rf --ignore-unmatch "${TARGET_REPO_Solution}"'
- 'robocopy "${CI_PROJECT_DIR}/../PublishTemp/civbase" "${TARGET_REPO_Solution}" /S ;
- 'robocopy "${TEMP_DIR}/" "${TARGET_REPO_Solution}" /S ;
IF ((${LASTEXITCODE} -le 8)) {cmd /c "exit /b 0"}'
- 'git add . ; git commit --allow-empty -m "auto package civbase."'
- 'git push origin test'
- 'git push origin master'
only:
refs:
- master
......@@ -79,7 +97,7 @@ pushSolution:
push2021:
variables:
GIT_STRATEGY: none
stage: push2021
stage: push
tags:
- civ_base
script:
......@@ -87,14 +105,12 @@ push2021:
- 'git reset --hard head'
- 'git clean -fd'
- 'git remote set-url origin "https://${GIT_ACCESS_USER}:${GIT_ACCESS_PASSWORD}@g.civnet.cn:8443/CivPublish/CivWebPublish2021.git"'
#- 'git pull origin map --allow-unrelated-histories'
- 'git pull origin map'
- 'git rm -rf "${TARGET_REPO_2021}/civbase"'
- 'robocopy "${CI_PROJECT_DIR}/../PublishTemp/civbase" "${TARGET_REPO_2021}/civbase" /S ;
- 'robocopy "${TEMP_DIR}/" "${TARGET_REPO_2021}/civbase" /S ;
IF ((${LASTEXITCODE} -le 8)) {cmd /c "exit /b 0"}'
- 'git add . ; git reset HEAD Web.config CityInterface/Web.config CityWebFW/Web.config ; git commit --allow-empty -m "auto package civbase."'
- 'git push origin map'
only:
- master
when: on_success
......
......@@ -53,6 +53,23 @@ module.exports = {
cssLoader: {
modules: {
getLocalIdent: (context, _, localName) => {
if (/@wisdom-cesium/.test(context.resourcePath)) {
const matchRule = slash(context.resourcePath).match(/@wisdom-cesium\/(krpano)(.*).less$/)
if (matchRule && matchRule[2]) {
if (/rc-slider/.test(matchRule[0])) {
return localName
}
const className = matchRule[2].
split('/')
.map(a => a.replace(/([A-Z])/g, '-$1'))
.map(a => a.toLowerCase()).join('-')
return `panda-krpano-${className}-${localName}`.replace(/--/g, '-')
}
return localName
}
if (
context.resourcePath.includes('node_modules') ||
context.resourcePath.includes('ant.design.pro.less') ||
......
/* eslint-disable */
// const proxyURL = process.env.NODE_ENV !== 'production' ? 'http://192.168.10.150:8777' : window.location.origin;
// const proxyURL = 'https://work.panda-water.cn';
const proxyURL = 'http://192.168.10.179:8095';
const proxyURL = 'http://192.168.12.3:8082';
// const proxyURL = 'https://panda-water.cn'
module.exports = {
......
const rm = require('rimraf');
const path = require('path');
const webpack = require('webpack');
const chalk = require('chalk');
const ora = require('ora')
const ora = require('ora');
const pkg = require('../../package.json');
const webpackConfig = require('./webpack.prod.babel')
const webpackConfig = require('./webpack.prod.babel');
const argv = require('../../server/argv');
const spinner = ora('building for production...');
const { printFileSizes } = require('./buildDevUtil');
......
const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
function findFile(dir, findStr) {
if (!fs.existsSync(dir)) return false;
fs.readdirSync(dir).forEach(fileName => {
findStr.forEach(module => {
if (fileName.indexOf(module.dir) !== -1) {
module.component.forEach(compo => {
execSync(`npm uninstall ${compo}`);
execSync(`npm install ${compo} --registry=https://g.civnet.cn:4873`);
});
}
});
});
}
findFile(path.resolve(process.cwd(), 'node_modules'), [
{ dir: '@wisdom-utils', component: ['@wisdom-utils/components', '@wisdom-utils/runtime', '@wisdom-utils/utils'] },
]);
......@@ -19,6 +19,8 @@
"analyze": "cross-env ANALYZE=1 npm run build",
"npmcheckversion": "node ./internals/scripts/npmcheckversion.js",
"preinstall": "yarn run npmcheckversion && npx force-resolutions",
"update:wisdom": "npm install --registry=https://g.civnet.cn:4873 && npm run refresh",
"refresh": "node ./internals/webpack/install.js --registry=https://g.civnet.cn:4873",
"build": "cross-env NODE_ENV=production node --max_old_space_size=4096 internals/webpack/build.js",
"build:clean": "rimraf ./build",
"openapi": "cross-env NODE_ENV=development yarn server/openapi/run.js",
......@@ -88,7 +90,8 @@
],
"resolutions": {
"babel-core": "7.0.0-bridge.0",
"webpack": "^5.70.0"
"webpack": "^5.70.0",
"antd": "4.21.2"
},
"dependencies": {
"@amap/amap-jsapi-loader": "^1.0.1",
......@@ -103,16 +106,17 @@
"@babel/polyfill": "7.4.3",
"@babel/runtime": "^7.10.5",
"@esri/calcite-colors": "6.0.3",
"@wisdom-cesium/cesium": "^1.1.0",
"@wisdom-cesium/cesium": "^1.1.6",
"@wisdom-cesium/krpano": "^1.0.29-2",
"@wisdom-components/basictable": "^1.5.16",
"@wisdom-components/empty": "^1.4.1",
"@wisdom-map/amap": "1.1.0-beta.38",
"@wisdom-map/arcgismap": "1.4.0-39",
"@wisdom-map/basemap": "1.1.0-10",
"@wisdom-map/amap": "1.1.0-beta.42",
"@wisdom-map/arcgismap": "1.4.0-88",
"@wisdom-map/basemap": "1.1.0-18",
"@wisdom-map/util": "^1.0.28-0",
"@wisdom-utils/components": "0.1.262",
"@wisdom-utils/runtime": "0.0.32",
"@wisdom-utils/utils": "0.1.302",
"@wisdom-utils/components": "0.1.283",
"@wisdom-utils/runtime": "0.0.38",
"@wisdom-utils/utils": "0.1.323",
"animate.css": "^4.1.1",
"antd": "4.21.2",
"compression": "1.7.4",
......
{
"loginTemplate" : [
{
"title": "Dark"
},
{
"title": "Water"
},
{
"title": "信息化"
},
{
"title": "能源-定额平台"
},
{
"title": "节水主题一"
}
]
}
\ No newline at end of file
......@@ -14,6 +14,7 @@ instanceRequest.transformRequestURL = function(url) {
'/CityInterface/rest/services.svc/GetConfig',
'/PandaOMS/OMS/HostManager/GetGateWay',
'/PandaCore/Identity/AuthorizationToken',
'/PandaEnergy/WaterSaving/download',
'/PandaOMS/OMS/WebSite/GetConfig',
];
if (excludeURL.includes(url)) {
......
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
......@@ -16,61 +16,66 @@ const formItemLayout = {
* 云平台上判断是否是默认密码
* 如果是默认密码,强制要求修改密码
*/
let info = '666';
let infoPre = 'panda';
const ValidContainer = props => {
const [needChangePassword, setNeedChangePassword] = useState(false);
const [form] = Form.useForm();
// eslint-disable-next-line react/no-this-in-sfc
let rules = localStorage.getItem('password_pwdRegex') ? localStorage.getItem('password_pwdRegex') : '';
const check = localStorage.getItem('password_token');
const rulesTip = localStorage.getItem('password_pwdRegexTip') ? localStorage.getItem('password_pwdRegexTip') : '';
const accessToken = localStorage.getItem('access_token') ? localStorage.getItem('access_token') : '';
let reg;
try {
reg = new RegExp(rules);
} catch (error) {
rules = '';
reg = new RegExp(rules);
}
useEffect(() => {
if (window.location.origin.replace(/^(http|https):\/\//, '') !== 'panda-water.cn') return;
// if (window.location.origin.replace(/^(http|https):\/\//, '') !== 'panda-water.cn') return;
const { global } = props;
const tk = global.token;
// eslint-disable-next-line no-eval
if (tk) {
appService.validDefaultPWD({
ignoreSite: true,
token: tk
}).then(res => {
if(res.code === 0) {
const { data } = res;
setNeedChangePassword(data.valid);
info = data.info;
}
}).catch(err => {
})
if (rules !== '' && check && check === accessToken) {
setNeedChangePassword(true);
}
}
}, []);
const handleOK = (e) => {
const handleOK = e => {
e.stopPropagation();
form
.validateFields()
.then((res) => {
.then(res => {
const params = {
password: `${infoPre}${info}`, // 拼接默认密码
newpassword: res.newPwd,
token: window.globalConfig.token,
ignoreSite: true,
}
password: res.oldPwd, // 拼接默认密码
newpassword: res.newPwd,
token: window.globalConfig.token,
ignoreSite: true,
};
appService
.changePassword(params)
.then((res) => {
// eslint-disable-next-line no-shadow
.then(res => {
if (res.success) {
message.success(globalHeader['component.account.password.update.success']);
setTimeout(() => {
// setNeedChangePassword(false);
props.logout();
setNeedChangePassword(false);
// props.logout();
}, 300);
} else {
message.error(globalHeader['component.account.oldpassword.errorMessage']);
}
})
.catch((error) => {
.catch(error => {
message.error(globalHeader['component.account.password.update.fail']);
});
}).catch((error) => {
console.log(error)
})
.catch(error => {
console.log(error);
});
}
};
return (
<>
{props.children}
......@@ -87,10 +92,23 @@ const ValidContainer = props => {
// zIndex={2000}
>
<div className={styles['info-label']}>
<ExclamationCircleFilled style={{color: '#FCAC0F', fontSize: '16px'}}/>
<span>用户首次登录之前必须修改密码</span>
<ExclamationCircleFilled style={{ color: '#FCAC0F', fontSize: '16px' }} />
<span>用户首次登录之前必须修改密码</span>
</div>
<Form labelAlign="left" {...formItemLayout} form={form}>
<Form.Item
name="oldPwd"
label="原密码"
rules={[
{
required: true,
message: '请输入原始密码',
},
]}
hasFeedback
>
<Input.Password />
</Form.Item>
<Form.Item
name="newPwd"
label="新密码"
......@@ -100,16 +118,9 @@ const ValidContainer = props => {
message: '请输入新密码',
},
{
pattern: /^(?![0-9]+$)(?![a-zA-Z]+$)[a-zA-Z0-9_]{8,16}$/,
message: '密码需为8-16个数字、字符和下划线',
pattern: reg,
message: rulesTip,
},
({ getFieldValue }) => ({
validator(rule, value) {
if(value === `${infoPre}${props?.global?.userInfo?.loginName ?? info}` || value === 'panda666')
return Promise.reject('密码规则不允许');
return Promise.resolve();
},
})
]}
hasFeedback
>
......@@ -127,13 +138,13 @@ const ValidContainer = props => {
},
({ getFieldValue }) => ({
validator(rule, value) {
if (!/^(?![0-9]+$)(?![a-zA-Z]+$)[a-zA-Z0-9_]{8,16}$/.test(value))
return Promise.reject('密码需为8-16个数字、字符和下划线');
if (value === `${infoPre}${props?.global?.userInfo?.loginName ?? info}` || value === 'panda666')
return Promise.reject('密码规则不允许');
if (!reg.test(value))
// eslint-disable-next-line prefer-promise-reject-errors
return Promise.reject(rulesTip);
if (!value || getFieldValue('newPwd') === value) {
return Promise.resolve();
}
// eslint-disable-next-line prefer-promise-reject-errors
return Promise.reject('确认密码与新密码输入不一致');
},
}),
......
......@@ -3,81 +3,65 @@ import React, { Component, useMemo, useState } from 'react';
import { Button, Form, Input, Modal, notification, Pagination } from 'antd';
import { connect } from 'react-redux';
import { FormattedMessage } from '@wisdom-utils/components';
import { history } from '@wisdom-utils/runtime';
import { findPathByWidget, isJSON } from '@wisdom-utils/components/lib/AppLayout/helpers';
import Notifier from '../../layouts/AppLayout/notifier/notice';
import NoticeIcon from '../../layouts/AppLayout/notifier';
import { ERR_OK, MESSAGE_TYPE, NEW_MESSAGE } from '../../layouts/AppLayout/notifier/constants';
import { findPathByWidget, isJSON } from '@wisdom-utils/components/lib/AppLayout/helpers';
import service from '../../api/service/notification';
import { actionCreators } from '../../containers/App/store';
import isProd from '../../utils/env';
// import NoticeIcon from '../NoticeIcon';
import styles from './index.less';
import { history } from '@wisdom-utils/runtime';
const { TextArea } = Input;
const PlatformModal = ({ platformVisible, handleClosePlatform, handlerMointer, messages = [] }) => {
const [pageIndex, setPageIndex] = useState(1);
const message = useMemo(() => {
return messages[pageIndex-1];
}, [messages, pageIndex]);
const message = useMemo(() => messages[pageIndex - 1], [messages, pageIndex]);
return (
<Modal
title={<FormattedMessage id='component.noticeIcon.modal.alarm.title'/>}
title={<FormattedMessage id="component.noticeIcon.modal.alarm.title" />}
maskClosable={false}
mask={false}
maskStyle={{ pointerEvents: 'none'}}
maskStyle={{ pointerEvents: 'none' }}
visible={platformVisible}
zIndex={5000}
wrapClassName={styles.platformModalWrap}
className={styles.platformModal}
footer={<Pagination
simple
total={messages.length}
pageSize={1}
pageIndex={pageIndex}
showSizeChanger={false}
onChange={(page, pageSize) => setPageIndex(page)}
/>}
footer={
<Pagination
simple
total={messages.length}
pageSize={1}
pageIndex={pageIndex}
showSizeChanger={false}
onChange={(page, pageSize) => setPageIndex(page)}
/>
}
onCancel={() => handleClosePlatform()}
centered
>
<div className={styles.alarmContent}>
{/* eslint-disable-next-line jsx-a11y/alt-text */}
<img
src="https://panda-water.com/web4/assets/images/message/报警图标.svg"
alt=""
/>
<img src="https://panda-water.com/web4/assets/images/message/报警图标.svg" alt="" />
<div className={styles.content}>
<div className={styles['content-top']}>
<a
onClick={event =>
handlerMointer(event, message, true,)
}
>
<a onClick={event => handlerMointer(event, message, true)}>
{message && message.infoContent && message.infoContent.title}
</a>
<span
title={<FormattedMessage id='component.noticeIcon.messsage.statused'/>}
onClick={event =>
handlerMointer(event, message, false,)
}
/>
<span title="点击标为已读" onClick={event => handlerMointer(event, message, false)} />
</div>
<div className={styles['content-mid']}>
<b>
{message && message.infoContent && message.infoContent.alarmType}
</b>
<b>{message && message.infoContent && message.infoContent.alarmType}</b>
{`|${message && message.infoContent && message.infoContent.alarmContent}`}
</div>
<div className={styles['content-bottom']}>
<p>
报警值:
<b>
{message && message.infoContent && message.infoContent.alarmValue}
</b>
<b>{message && message.infoContent && message.infoContent.alarmValue}</b>
{' / '}
预设值:
{message && message.infoContent && message.infoContent.alarmThreshold}
......@@ -87,9 +71,8 @@ const PlatformModal = ({ platformVisible, handleClosePlatform, handlerMointer, m
</div>
</div>
</Modal>
)
}
);
};
/* eslint-disable */
class NoticeIconView extends Component {
......@@ -252,7 +235,7 @@ class NoticeIconView extends Component {
renderNotifierFooter = () => {
const toNotifications = e => {
e.stopPropagation();
history.push && history.push('/system/notifications')
history.push && history.push('/civbase/system/notifications')
}
return (
<div className={styles.notificationFoter}>
......@@ -361,7 +344,7 @@ class NoticeIconView extends Component {
params._source = '消息通知';
params._target = message.webPath;
sessionStorage.setItem('routerParams', JSON.stringify(params));
window.history.pushState(params, '', `/civbase/${targetMenuPath}`);
window.history.pushState(params, '', `/civbase/${targetMenuPath}?v=${Date.now()}`);
}
render() {
......@@ -389,7 +372,7 @@ class NoticeIconView extends Component {
/>
</NoticeIcon>
{
this.state.platformVisible && (
this.state.platformVisible && this.platformMessages.length > 0 && (
<PlatformModal
platformVisible={this.state.platformVisible}
handleClosePlatform={this.handleClosePlatform}
......
import React , {useEffect} from 'react';
import React, { useEffect } from 'react';
import { Helmet } from 'react-helmet';
import { connect } from 'react-redux';
......@@ -16,20 +16,28 @@ const config = require('../../../config/config');
const App = props => {
useEffect(() => {
event.emit('loading' , props.loading);
}, [props.loading])
event.emit('loading', props.loading);
}, [props.loading]);
const metaSecurity = /https/.test(window.location.protocol) ? (
<meta httpEquiv='Content-Security-Policy' content='upgrade-insecure-requests' />
<meta httpEquiv="Content-Security-Policy" content="upgrade-insecure-requests" />
) : null;
return (
<>
<Helmet title={`${(props.global && props.global.title) || defaultSetting.title}`}>
<title>{`${(props.global && props.global.title) || defaultSetting.title}`}</title>
<link rel='shortcut icon'
href={`${window.location.origin}/web4/${props.global && props.global.shortcutIcon}`} />
{/* <link rel='shortcut icon'
href={`${window.location.origin}/web4/${props.global && props.global.shortcutIcon}`} /> */}
<link
rel="shortcut icon"
href={
props.global && props.global.shortcutIcon
? `${window.location.origin}/civweb4/${props.global.shortcutIcon}`
: defaultSetting.logo
}
/>
{metaSecurity}
<meta name='description' content={`${(props.global && props.global.title) || defaultSetting.title}`} />
<meta name="description" content={`${(props.global && props.global.title) || defaultSetting.title}`} />
</Helmet>
<Router basename={config.base || pkg.name.toLocaleLowerCase() || ''}>
<Switch>
......@@ -45,7 +53,7 @@ const App = props => {
</Router>
</>
);
}
};
const mapStateToProps = state => ({
global: state.getIn(['global', 'globalConfig']),
......
......@@ -216,6 +216,9 @@ export function logout(data) {
path: '/',
});
localStorage.removeItem('access_token');
localStorage.removeItem('password_token');
localStorage.removeItem('password_pwdRegex');
localStorage.removeItem('password_pwdRegexTip');
// eslint-disable-next-line no-undef,no-restricted-globals
createStoreage.remove(`__PANDA_STORE__${location.hostname}`);
// eslint-disable-next-line no-undef,no-restricted-globals
......@@ -233,9 +236,9 @@ export function logout(data) {
if (products) {
Object.keys(products).forEach(item => {
window[products[item]] &&
window[products[item]] &&
window[products[item]].unmount &&
window[products[item]].unmount({ store });
window[products[item]] &&
window[products[item]].unmount &&
window[products[item]].unmount({ store });
});
}
......
......@@ -25,7 +25,7 @@ const getIOT = () =>
class AvatarDropdown extends React.Component {
/* eslint-disable no-unused-vars */
constructor(props) {
super(props);
let {
......@@ -41,7 +41,16 @@ class AvatarDropdown extends React.Component {
popVisible: false,
path: null,
action: API.UPLOAD_FILE_URL,
rulesTip: localStorage.getItem('password_pwdRegexTip'),
reg: ''
};
let rules = localStorage.getItem('password_pwdRegex');
try {
this.state.reg = new RegExp(rules);
} catch (error) {
rules = '';
this.state.reg = new RegExp(rules);
}
}
loginout = (event) => {
// eslint-disable-next-line no-undef
......@@ -424,8 +433,8 @@ class AvatarDropdown extends React.Component {
message: '请输入新密码',
},
{
pattern: /^(?![0-9]+$)(?![a-zA-Z]+$)[a-zA-Z0-9!@#$%^&*_]{8,16}$/,
message: '密码字符长度为8-16个字符',
pattern: this.state.reg,
message: this.state.rulesTip,
},
]}
hasFeedback
......
......@@ -3,7 +3,7 @@ import _, { isEmpty, isString } from 'lodash';
import MqttClient from 'mqtt-client';
import { isJSON } from '@wisdom-utils/components/lib/AppLayout/helpers/index';
import { api } from './api';
import { replaceSpeak, generatedId, parseContentToJSON } from './utils';
import { replaceSpeak, generatedId } from './utils';
import { postInformationStatus } from './api/service';
import {
DEFAULT_KEEPLIVE,
......@@ -248,9 +248,7 @@ class Notifier {
mqttConfig.NginxStart = self._siteConfig.NginxStart = data.NginxStart;
mqttConfig.mqtt_mess.TcpIP = self._siteConfig.TcpIP = self._siteConfig.mqtt_mess.TcpIP =
window.location.hostname;
mqttConfig.mqtt_mess.TcpPort = self._siteConfig.TcpPort = self._siteConfig.mqtt_mess.TcpPort = parseInt(
window.location.port,
);
mqttConfig.mqtt_mess.TcpPort = self._siteConfig.TcpPort = self._siteConfig.mqtt_mess.TcpPort = parseInt(window.location.port) || 443;
mqttConfig.mqtt_path = self._siteConfig.mqtt_path = '/ws/';
} else {
mqttConfig.nginxStart = data.NginxStart;
......
......@@ -35,6 +35,7 @@ import {
store,
event
} from '@wisdom-utils/utils';
import { Storeage as Store } from '@wisdom-utils/utils/lib/helpers';
import { waterMark } from '../utils/mark';
import layoutStyles from './BasicLayout.less';
......@@ -246,6 +247,8 @@ const transformFloatMenu = (routes, homepage) => {
};
const Layout = (props) => {
const currentProduct = new Store(`__global__recent_productIndex__micro_${window.location.hostname}`);
const menuState = sessionStorage.getItem('menuState') || 'open';
const [cityData, setCityData] = useState({});
const [siteLoading, setSiteLoading] = useState(false);
const [siteAction, setSiteAction] = useState(() => new Site(props, setSiteLoading));
......@@ -392,6 +395,16 @@ const Layout = (props) => {
};
}, []);
if(props.global && props.global.userInfo){
if(!props.global.userInfo.site){
props.global.userInfo.site = '';
}
}
return (
<SecurityLayout {...props}>
<BasicLayout
......@@ -410,7 +423,7 @@ const Layout = (props) => {
// onLoadingChange: (loading) => setMenuLoading(loading)
}}
logo={logo}
topMenuActiveKey={props.currentMenuIndex}
topMenuActiveKey={currentProduct.get('currentMenuIndex') || 0}
rightContentRender={() => <RightContent />}
onPageChange={() => {
// if(!props.global.token) {
......
......@@ -5,9 +5,7 @@ import { appService } from '@/api';
import { SERVICE_INTERFACE_SUCCESS_CODE } from '@/constants';
import PandaBootPage from './panda';
const system_item_name = '引导页模板'; // 系统配置项名称
const systemItemName = '引导页模板'; // 系统配置项名称
const BootPageTemplate = {
default: PandaBootPage,
......@@ -25,12 +23,12 @@ const BootPage = props => {
useEffect(() => {
appService
.sysConfiguration({
moduleName: system_item_name,
moduleName: systemItemName,
ignoreSite: true,
})
.then(res => {
const { code, data } = res;
if (code != SERVICE_INTERFACE_SUCCESS_CODE) {
if (code !== SERVICE_INTERFACE_SUCCESS_CODE) {
notification.error({ message: '提示', duration: 3, description: '系统引导页配置错误' });
setInfo({ first: false, loading: false, error: true });
return;
......
/* eslint-disable global-require */
// 云平台引导页
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import React, { useCallback, useEffect, useMemo, useState, useRef } from 'react';
import { Space, Spin, Progress } from 'antd';
import classNames from 'classnames';
......@@ -31,7 +32,10 @@ const industries = [
// let loginAction = null;
const BootPage = props => {
const dataRef = useRef();
const process = useRef();
const [Industries] = useState(props.global.userInfo.Industries);
const [percentBottom, setPercentBottom] = useState(-40);
const [percentNum, setPercentNum] = useState(0);
const [currentType, setCurrentType] = useState('');
// const [loadding, setLoadding] = useState(false);
......@@ -39,28 +43,44 @@ const BootPage = props => {
const [scale, setScale] = useState(1);
const [loginAction, setAction] = useState(() => new LoginAction(props));
const [num] = useState(Industries.filter(item => !!industries.find(d => d.type === item)).length);
// const history = useHistory();
useDocumentTitle(
{ title: defaultSetting.title, id: '', pageName: '行业切换' },
props.global.title || defaultSetting.title,
);
useEffect(() => {
dataRef.current = percentNum;
}, [percentNum]);
// eslint-disable-next-line no-shadow
const handlePage = (event, type, loginAction) => {
setPercentNum(Math.ceil(Math.random() * 50));
let count = 1;
setPercentBottom(-40 + Math.ceil(Math.random() * 8 * count));
setPercentNum(Math.ceil(Math.random() * 10));
setCurrentType(type);
//
// event.persist();
// event.preventDefault();
process.current = setInterval(() => {
setTimeout(() => {
const perBottom = -40 + 8 * count + Math.ceil(Math.random() * 8);
const perNum = 10 * count + Math.ceil(Math.random() * 10);
if (perNum >= 80 || dataRef.current >= 80 || count === 10) {
return clearInterval(process.current);
}
setPercentBottom(perBottom);
setPercentNum(perNum);
count += 1;
}, 0);
}, 3000);
// 新增熊猫新产品引导页
if (type === '熊猫新产品') {
setTimeout(() => {
setPercentBottom(40);
setPercentNum(100);
clearInterval(process.current);
setTimeout(() => {
window.history.pushState('', null, `/cloud/introduction/newproducts`);
props.history.push('/cloud/introduction/newproducts');
// window.history.pushState('', null, `/cloud/introduction/newproducts`);
}, 500);
});
......@@ -76,7 +96,7 @@ const BootPage = props => {
props.instance && props.instance.updateConfig(config);
// props.instance && props.instance.getUserInfoAndConfig('', true, type);
loginAction && loginAction.getUserInfoAndConfig('', true, type);
}
};
useEffect(() => {
// eslint-disable-next-line no-use-before-define
......@@ -93,8 +113,9 @@ const BootPage = props => {
window.addEventListener('resize', handleResize);
const handleToggleIndustry = event => {
setPercentBottom(38);
setPercentNum(98);
clearInterval(process.current);
setTimeout(() => {
props.history.push(`/?client=${props.global.client}`);
}, 1000);
......@@ -112,13 +133,12 @@ const BootPage = props => {
};
}, [loginAction.events, props, currentType]);
useEffect(() => {
window.share.event.on('visible', ret => {
setTimeout(() => {
setPercentBottom(40);
setPercentNum(100);
clearInterval(process.current);
setTimeout(() => {
window.history.pushState(null, '', ret);
}, 500);
......@@ -136,7 +156,6 @@ const BootPage = props => {
// ? props.global.userInfo.Industries.filter(item => !!industries.find(d => d.type === item)).length
// : 0`
useEffect(() => {
appService
.getUserInfo({
......@@ -147,12 +166,12 @@ const BootPage = props => {
})
.then(res => {
const roles = res?.data?.roles ?? [];
const _hasRole = roles && Array.isArray(roles) && roles.filter(r => r.name == '客户运维管理员').length;
// eslint-disable-next-line no-underscore-dangle
const _hasRole = roles && Array.isArray(roles) && roles.filter(r => r.name === '客户运维管理员').length;
setHasRole(!!_hasRole);
});
}, [props.global.token]);
return (
<div className={styles.bootPage}>
<div className={styles.bootPageMain}>
......@@ -177,17 +196,18 @@ const BootPage = props => {
left: '300px',
bottom: '105px',
opacity: 1,
width: num === 5 ? 960 : num === 9 || num === 10 ? 1600 : 1280,
width: num === 5 ? 960 : num === 9 || num === 10 ? 1600 : 1280,
}}
>
{industries.map(
item =>
props.global &&
Industries.indexOf(item.type) > -1 &&
<li
props.global &&
Industries.indexOf(item.type) > -1 && (
<li
className={styles.bootPageLi}
key={item.type}
onClick={event => handlePage(event, item.type, loginAction)}>
onClick={event => handlePage(event, item.type, loginAction)}
>
<div className={styles.bootPageList}>
<div className={styles.listMain}>
<img src={require(`@/assets/bootPage/${item.type}.png`)} alt="" />
......@@ -196,16 +216,31 @@ const BootPage = props => {
</div>
</div>
{currentType === item.type && (
<Progress
style={{ width: '98%' }}
strokeColor={item.color}
percent={percentNum}
status="active"
format={percent => <span style={{ color: '#fff' }}>{percent}%</span>}
className={styles.bootProgress}
/>
<div className={styles.bootProgress}>
<div className={styles.inner} style={{ bottom: percentBottom }}>
<svg
className={styles.wave}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
viewBox="0 24 150 68"
preserveAspectRatio="none"
>
<defs>
<path
id="gentle-wave"
d="M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z"
/>
</defs>
<g className={styles.parallax}>
<use xlinkHref="#gentle-wave" x="50" y="0" fill={item.color} opacity="0.1" />
<use xlinkHref="#gentle-wave" x="50" y="-1" fill={item.color} opacity="0.2" />
</g>
</svg>
</div>
</div>
)}
</li>
),
)}
</ul>
</section>
......
@import '~antd/es/style/themes/default.less';
@-webkit-keyframes move {
0% {
-webkit-transform: translate(-90px,0%);
transform: translate(-90px,0%);
}
100% {
-webkit-transform: translate(85px,0%);
transform: translate(85px,0%);
}
}
@keyframes move {
0% {
-webkit-transform: translate(-90px,0%);
transform: translate(-90px,0%);
}
100% {
-webkit-transform: translate(85px,0%);
transform: translate(85px,0%);
}
}
.bootPage {
width: 100%;
height: 100%;
......@@ -65,6 +87,15 @@
width: 298px;
height: 268.8px;
margin: 10px;
&:hover {
.listMain {
transform: scale(1.1);
}
.bootProgress {
transform: scale(1.1);
bottom: -10px;
}
}
.bootPageList {
width: 100%;
height: 100%;
......@@ -77,12 +108,6 @@
font-size: 24px;
cursor: pointer;
position: relative;
&:hover {
.listMain {
transform: scale(1.1);
}
}
span {
margin-top: 20px;
font-weight: 500;
......@@ -171,8 +196,38 @@
}
.bootProgress {
transition: all .2s ease-out;
position: absolute;
bottom: -5px;
height: 80px;
margin: 0;
width: 100%;
border-radius: 0 0 14% 14%;
overflow: hidden;
bottom: 0px;
}
.bootProgress .inner{
transition: all .2s ease-out;
position: absolute;
height: 100%;
width: 100%;
bottom: 10%;
}
.bootProgress .wave {
display: block;
width: 100%;
height: 10em;
max-height: 100vh;
margin: 0;
}
.bootProgress .wave .parallax>use {
animation: move 2s linear infinite;
}
.bootProgress .wave .parallax>use:nth-child(2) {
animation-delay: -0.1s;
}
}
......
......@@ -2,20 +2,22 @@ import React from 'react';
import classnames from 'classnames';
import styles from './index.less';
import cover from './images/default.png';
import tagHot from './images/hot.png';
import tagNew from './images/new.png';
import desc from './images/副标题.png';
import descActive from './images/副标题_active.png';
import { chunk } from 'lodash-es';
const assetPath = `${window.location.origin}/PandaWorkFlow/WorkFlow/AccountManage/DownloadFiles`;
const tags = {
'New': tagNew,
'Hot': tagHot,
}
const Card = ({onCardClick, ...props}) => {
const { config } = props;
if(config['副标题'].indexOf('\\n') === -1){
config['副标题'] = config['副标题'] + '\\n';
}
if(config['系统特点'].indexOf(',') === -1){
config['系统特点'] = config['系统特点'] + ',';
}
return (
<div className={styles.card} onClick={e => onCardClick(e, props)}>
<div className={classnames(styles['card-title'], styles['nowrap-text'])}>
......@@ -34,17 +36,37 @@ const Card = ({onCardClick, ...props}) => {
}
</div>
<div className={classnames(styles['card-info'])}>
<div className={classnames(styles['card-desc'], styles.default)}><span>{config && config['副标题']}</span></div>
<div className={classnames(styles['card-tags'])}>
<div className={classnames(styles['card-desc'])}>
{
config && config['系统特点'] && config['系统特点'].split(',').map((item, index) => {
return <div className={classnames(styles['card-tag'])} key={index}>
<i className={classnames(styles['card-tag-icon'])} />
{item}
</div>
})
config && config['副标题'] && config && config['副标题'].split("\\n").map((item, index) => {
return <div key={index}>{item}</div>
})
}
</div>
<div className={classnames(styles['card-tags'])}>
<div className={classnames(styles['card-list'])}>
{
config && config['系统特点'] && chunk(config['系统特点'].split(',') , 2).map((item, index) => {
return <div key={index} className={classnames(styles['card-list-content'])}>
{
item.map((child, key) => {
return <div className={classnames(styles['card-tag'])}
style={{
height: config['系统特点'].split(',').length <= 6 ? 44 : 40,
lineHeight: config['系统特点'].split(',').length <= 6 ? '44px' : '40px',
marginTop: config['系统特点'].split(',').length <= 8 ? 10 : 0
}} key={key + index}>
<i className={classnames(styles['card-tag-icon'])} />
{child}
</div>
})
}
</div>
})
}
</div>
</div>
</div>
</div>
</div>
......
......@@ -31,6 +31,7 @@ const NewProducts = props => {
const [time, setTime] = useState(moment().format('YYYY-MM-DD HH:mm:ss'))
const ref = useRef();
// 计时器
useEffect(() => {
setInterval(() => {
setTime(moment().format('YYYY-MM-DD HH:mm:ss'))
......@@ -152,7 +153,9 @@ const NewProducts = props => {
<div className={classnames(styles['page-time'])}>
<span>{time}</span>
<img src={icon} onClick={() => {
window.history.pushState('', null, `/industry`);
window.history.go(-1);
// window.history.pushState('', null, `/industry`);
// props.history.push(`/industry`);
}} className={classnames(styles.pageIcon)} alt='退出' />
</div>
......
......@@ -23,7 +23,7 @@
position: relative;
overflow: hidden;
background-position: center;
background-size: 100% 100%;
background-size: cover;
background-repeat: no-repeat;
background-image: url('./images/bg.png');
font-size: 20px;
......@@ -46,7 +46,7 @@
text-shadow: 0 11px 15px rgba(0, 18, 44, 0.48);
text-align: center;
background-image: url('./images/标题.png');
background-size: cover;
background-size: 100% 100%;
background-repeat: no-repeat;
font-family: "zihun";
}
......@@ -141,17 +141,17 @@
flex-wrap: wrap;
gap: 1em;
margin: 0 auto;
width: 40em;
width: 42em;
&[num="2"],
&[num="4"] {
width: (40em * 2 + 1em);
width: (42em * 2 + 1em);
}
&[num="3"],
&[num="5"],
&[num="6"] {
width: (40em * 3 + 2em);
width: (42em * 3 + 2em);
}
&[num="1"],
......@@ -169,16 +169,15 @@
width: 49%;
height: 24rem;
background-image: url('./images/框.png');
background-size: contain;
background-position: center;
.card-title {
position: relative;
margin-top: 0.75rem;
left: 5%;
margin-top: 0.5rem;
left: 4%;
font-size: 1.5rem;
font-weight: 400;
color: #000000;
color: #262626;
font-family: "zihun";
}
.back {
......@@ -186,7 +185,7 @@
position: absolute;
left: 0;
bottom: 0;
padding: 0.5rem;
padding: 1rem;
background: linear-gradient(#fff, rgb(147,219,246));
width: 100%;
overflow: hidden;
......@@ -201,11 +200,13 @@
}
.card-desc{
display: flex;
padding: 1rem;
text-align: center;
//display: flex;
font-size: 1rem;
background-position-x: -.5rem;
align-items: center;
justify-content: center;
//align-items: center;
//justify-content: center;
height: 5rem;
padding-left: 0.5rem;
padding-right: 0.5rem;
......@@ -228,12 +229,15 @@
background-image: url(./images/副标题_active.png);
color: #000000;
}
.card-title{
color: #000;
}
}
.card-content{
position: relative;
left: 1rem;
padding: 1rem;
padding: 1rem 1rem 1rem 2.2rem;
&::after{
content: "";
......@@ -244,40 +248,61 @@
.card-img {
position: relative;
float: left;
width: 60%;
height: 17.5rem;
img{
width: 100%;
height: 100%;
height: 17.9rem;
}
}
.card-info {
float: left;
width: 36%;
width: 33%;
}
.card-tags {
padding: 0.5rem 1rem;
.card-tag{
float: left;
width: 50%;
height: 35px;
line-height: 35px;
font-size: 0.88rem;
font-family: Microsoft YaHei;
font-weight: 400;
color: #FFFFFF;
.card-tag-icon {
display: inline-block;
margin-right: .5rem;
width: 5px;
height: 5px;
background: #E1F4FD;
opacity: 0.53
position: relative;
padding: 0 1rem;
height: 12rem;
.card-list {
.card-list-content {
border-bottom: 1px solid #2781A8;
&::after{
content: "";
display: block;
clear: both;
}
&:last-child {
border-bottom: none;
}
.card-tag{
float: left;
width: 50%;
height: 35px;
line-height: 35px;
font-size: 0.88rem;
font-family: Microsoft YaHei;
font-weight: 400;
color: #FFFFFF;
.card-tag-icon {
display: inline-block;
margin-right: .5rem;
width: 5px;
height: 5px;
background: #E1F4FD;
opacity: 0.53;
-webkit-transform:rotate(45deg) ; //Webkit / Safari / Chrome
-moz-transform:rotate(45deg) ; //Firefox
-ms-transform:rotate(45deg) ; //Internet Explorer
-o-transform:rotate(45deg) ; //Opera
transform:rotate(45deg) ;
}
}
}
}
}
......@@ -306,6 +331,18 @@
height: 21rem;
}
.card-content{
.card-img {
img{
height: 9rem !important;
}
}
}
.card-info {
width: 50% !important;
}
.panel {
font-size: 14px;
}
......
import React from 'react';
import SecurityLayout from '../../../layouts/SecurityLayout';
const HocContainer = Component => props => (
<SecurityLayout>
<Component {...props} />
</SecurityLayout>
);
export default HocContainer;
import React, { memo, useEffect, useRef } from 'react';
import { FullscreenExitOutlined, FullscreenOutlined } from '@ant-design/icons';
import Iframe from 'react-iframe';
import Empty from '@wisdom-components/empty';
import styles from './index.less';
import Hoc from './HocContainer';
import useFullScreen from './useFullScreen';
const TabWidget = props => {
const params = Object.assign({}, props.params, {
fullscreen: !(props.params !== undefined && props.params.fullscreen === 'true'),
});
const { linkUrl, fullscreen } = params;
const [ref, isFullscreen, handleFullScreen, handleExitFullScreen] = useFullScreen(fullscreen);
return (
<div className={styles['tab-iframe']} ref={ref}>
<div className={styles['oper-wrap']}>
<div className={styles['oper-btn']}>
{isFullscreen ? (
<FullscreenExitOutlined className={styles['btn-fullscreen_exit']} onClick={handleExitFullScreen} />
) : (
<FullscreenOutlined className={styles['btn-fullscreen']} onClick={handleFullScreen} />
)}
</div>
</div>
{linkUrl ? (
<Iframe
url={linkUrl}
width="100%"
height="100%"
display="block"
position="relative"
styles={{ border: 'none' }}
/>
) : (
<Empty description="配置url链接才能显示哦!" />
)}
</div>
);
};
export default memo(Hoc(TabWidget));
.tab-iframe {
width: 100%;
height: 100%;
position: relative;
overflow: hidden;
iframe {
border: none;
}
.oper-wrap {
top: 0;
right: 0;
width: 100px;
height: 100px;
position: absolute;
z-index: 2;
.oper-btn {
cursor: pointer;
color: #FFF;
position: absolute;
top: 10px;
right: -100%;
transition: right ease-in-out 0.8s;
}
&:hover {
.oper-btn {
right: 20px;
}
}
}
}
\ No newline at end of file
import { useState, useEffect, useCallback, useRef } from 'react';
const useFullScreen = needFullscreen => {
const [isFullscreen, setIsFullscreen] = useState(!!document.fullscreenElement);
const ref = useRef();
useEffect(() => {
const handleToggleFullScreen = () => {
setIsFullscreen(!!document.fullscreenElement);
};
document.addEventListener('fullscreenchange', handleToggleFullScreen);
return () => {
document.removeEventListener('fullscreenchange', handleToggleFullScreen);
};
}, []);
const handleFullScreen = useCallback(() => {
ref.current?.requestFullscreen();
}, []);
const handleExitFullScreen = useCallback(() => {
document.exitFullscreen();
}, []);
useEffect(() => {
needFullscreen && handleFullScreen();
}, [handleFullScreen, needFullscreen]);
return [ref, isFullscreen, handleFullScreen, handleExitFullScreen];
};
export default useFullScreen;
import {Preview} from '@wisdom-cesium/krpano'
const Krpano = props => {
const {projectName} = props
return (<div
style={{
position : "relative",
width : "100%",
height : "100%"
}}
>
<Preview projectName = {projectName}/>
</div>)
}
export default Krpano
\ No newline at end of file
import 'kit_logger';
import React, {
useCallback,
useEffect,
useState,
} from 'react';
import {
Button,
Form,
Input,
message,
} from 'antd';
import React, { useCallback, useEffect, useState } from 'react';
import { Button, Form, Input, message } from 'antd';
import omit from 'omit.js';
import { useIntl } from '@wisdom-utils/components';
......@@ -26,12 +17,7 @@ import ItemMap from './map';
const FormItem = Form.Item;
// eslint-disable-next-line no-undef
const Logger = logger('loginForm');
const getFormItemOptions = ({
onChange,
defaultValue,
customProps = {},
rules,
}) => {
const getFormItemOptions = ({ onChange, defaultValue, customProps = {}, rules }) => {
const options = {
rules: rules || customProps.rules,
};
......@@ -78,7 +64,7 @@ const LoginItem = props => {
}
})
.catch(error => {
message.error(intl.formatMessage({id: 'pages.login.phoneLogin.errorCodeMessage'}));
message.error(intl.formatMessage({ id: 'pages.login.phoneLogin.errorCodeMessage' }));
});
}, []);
......@@ -98,7 +84,7 @@ const LoginItem = props => {
}, 1000);
}
return () => clearInterval(interval);
}, [timing]);
}, [props, timing]);
if (!name) {
return null;
......@@ -114,7 +100,7 @@ const LoginItem = props => {
return Promise.resolve();
}
// eslint-disable-next-line prefer-promise-reject-errors
return Promise.reject(intl.formatMessage({id: 'pages.login.phoneLogin.errorMessage'}));
return Promise.reject(intl.formatMessage({ id: 'pages.login.phoneLogin.errorMessage' }));
};
// eslint-disable-next-line no-shadow
const rules = [
......@@ -126,7 +112,7 @@ const LoginItem = props => {
delete options.rules;
return (
<FormItem shouldUpdate style={{marginBottom: '14px'}}>
<FormItem shouldUpdate style={{ marginBottom: '14px' }}>
{({ getFieldValue, validateFields }) => (
<>
<FormItem name={name} {...options} rules={rules}>
......@@ -147,8 +133,8 @@ const LoginItem = props => {
}}
>
{timing
? `${intl.formatMessage({id: 'pages.login.phoneLogin.sendCationCode'})}(${count})`
: intl.formatMessage({id: 'pages.login.phoneLogin.getVerificationCode'})}
? `${intl.formatMessage({ id: 'pages.login.phoneLogin.sendCationCode' })}(${count})`
: intl.formatMessage({ id: 'pages.login.phoneLogin.getVerificationCode' })}
</Button>
</>
)}
......@@ -156,6 +142,13 @@ const LoginItem = props => {
);
}
if (type === 'Password') {
return (
<FormItem name={name} {...options}>
<Input.Password {...customProps} {...otherProps} />
</FormItem>
);
}
return (
<FormItem name={name} {...options}>
<Input {...customProps} {...otherProps} />
......@@ -169,15 +162,7 @@ Object.keys(ItemMap).forEach(key => {
const item = ItemMap[key];
LoginItems[key] = props => (
<LoginContext.Consumer>
{context => (
<LoginItem
customProps={item.props}
rules={item.rules}
{...props}
type={key}
{...context}
/>
)}
{context => <LoginItem customProps={item.props} rules={item.rules} {...props} type={key} {...context} />}
</LoginContext.Consumer>
);
});
......
......@@ -5,6 +5,8 @@ import {
MailOutlined,
MobileOutlined,
UserOutlined,
EyeInvisibleOutlined,
EyeTwoTone,
} from '@ant-design/icons';
import styles from './index.less';
......@@ -27,9 +29,7 @@ export default {
NewYearPassword: {
props: {
size: 'large',
prefix: (
<LockOutlined className={styles.prefixIcon} twoToneColor="#ff9600" />
),
prefix: <LockOutlined className={styles.prefixIcon} twoToneColor="#ff9600" />,
type: 'password',
id: 'password',
placeholder: '888888',
......@@ -45,6 +45,7 @@ export default {
props: {
size: 'large',
prefix: <LockOutlined className={styles.prefixIcon} />,
iconRender: visible => (visible ? <EyeTwoTone /> : <EyeInvisibleOutlined />),
type: 'password',
id: 'password',
placeholder: '888888',
......@@ -90,9 +91,7 @@ export default {
NewYearMobile: {
props: {
size: 'large',
prefix: (
<MobileOutlined className={styles.prefixIcon} twoToneColor="#ff9600" />
),
prefix: <MobileOutlined className={styles.prefixIcon} twoToneColor="#ff9600" />,
placeholder: 'mobile number',
id: 'mobile',
},
......@@ -110,9 +109,7 @@ export default {
NewYearCaptcha: {
props: {
size: 'large',
prefix: (
<MailOutlined className={styles.prefixIcon} twoToneColor="#ff9600" />
),
prefix: <MailOutlined className={styles.prefixIcon} twoToneColor="#ff9600" />,
placeholder: '请输入短信验证码',
},
rules: [
......
......@@ -6,7 +6,7 @@ const WxLogin = props => {
: props.self_redirect === !1 && (self_redirect = 'false');
let url = `https://open.weixin.qq.com/connect/qrconnect?appid=${
props.appid
}&scope=${props.scope}&redirect_uri=${props.redirect_uri}&state=${
}&scope=${props.scope}&redirect_uri=${props.redirect_uri.replace('#/', '')}&state=${
props.state
// eslint-disable-next-line camelcase
}&login_type=jssdk&self_redirect=${self_redirect}&styletype=${props.styletype ||
......
......@@ -24,6 +24,7 @@ import XinganLogin from './template/project/xingan';
import ErlianhaoteLogin from './template/project/erlianhaote';
import YixianLogin from './template/project/yixian';
import LixianLogin from './template/project/lixian';
import PanoramaLogin from './template/panorama';
import { AppInitState } from '../../../render';
const LoginTemplate = {
'新春 - 智联.html': NewYear,
......@@ -44,6 +45,7 @@ const LoginTemplate = {
'项目 - 二连浩特.html': ErlianhaoteLogin,
'项目 - 易县.html': YixianLogin,
'项目 - 蠡县.html': LixianLogin,
'全景图.html': PanoramaLogin,
default: BaseLogin,
};
/* eslint-disable */
......@@ -63,6 +65,9 @@ export default (props) => {
template=arr[0]
loginParams =arr[1].split('&')
}
if(template.indexOf('.html') == -1){
template += '.html';
}
const RenderComponent = LoginTemplate[template] ? LoginTemplate[template]: LoginTemplate['default'];
return <RenderComponent {...props} loginParams={loginParams}/>
};
......
This diff is collapsed.
......@@ -8,10 +8,7 @@ import LoginAction from './login';
import { defaultApp } from '../../../micro';
const Login = forwardRef((props, _ref) => {
const history = useHistory();
const [action, setAction] = useState(
() =>
new LoginAction(Object.assign({}, props, { history }), () => {}, false),
);
const [action, setAction] = useState(() => new LoginAction(Object.assign({}, props, { history }), () => {}, false));
const [redirect] = useState(() => {
const param = params.getParams('redirect')?.replaceAll(';', '&');
return param ? decodeURIComponent(escape(param)) : null;
......@@ -21,11 +18,12 @@ const Login = forwardRef((props, _ref) => {
const hasLogin = useRef();
useEffect(() => {
action.globalConfig = props.global;
// eslint-disable-next-line no-prototype-builtins
if (props.global && props.global.hasOwnProperty('products') && hasLogin.current !== true) {
hasLogin.current = true;
action.init();
}
}, [action.globalConfig, props.global]);
}, [action, action.globalConfig, props.global]);
useEffect(() => {
action &&
......@@ -35,17 +33,15 @@ const Login = forwardRef((props, _ref) => {
// homepage: params.getParams('redirect')
// }));
// props.history.push('/' + params.getParams('redirect'))
props.history.push(
`/?client=${props.global.client}`,
);
props.history.push(`/?client=${props.global.client}`);
// window.share.event.emit('triggerMicro', props.global);
// initMicroApps();
defaultApp(redirect);
});
return () => {
action && action.events && action.events.removeAllListeners('loginSuccess');
}
}, [action, props.global.client, props.global.generateType, props.history]);
return () => {
action && action.events && action.events.removeAllListeners('loginSuccess');
};
}, [action, props.global.client, props.global.generateType, props.history, redirect]);
return <div>{props.children}</div>;
});
......
......@@ -3,12 +3,14 @@ import 'kit_utils/lib/format';
import React, { forwardRef, useEffect, useRef, useState } from 'react';
import { Modal } from 'antd';
// eslint-disable-next-line import/no-unresolved
import classNames from 'classnames';
import { dom } from '@wisdom-utils/utils/lib/helpers';
import { Helmet, HelmetProvider } from 'react-helmet-async';
import { connect } from 'react-redux';
import { useHistory } from '@wisdom-utils/runtime';
import { actionCreators } from '@/containers/App/store';
import Cookies from 'js-cookie';
import defaultSetting from '../../../../../config/defaultSetting';
import LoginAction from '../login';
import styles from '../style.less';
......@@ -32,11 +34,11 @@ const Login = forwardRef((props, _ref) => {
const [type, setType] = useState('Account');
const [visible, setVisible] = useState(false);
const history = useHistory();
const [action, setAction] = useState(
() =>
new LoginAction(Object.assign({}, props, { history }), setVisible, false),
);
const [action, setAction] = useState(() => new LoginAction(Object.assign({}, props, { history }), setVisible, false));
const [showVideo, setShowVideo] = useState(false);
let { ddCode } = props.global;
const loginMode = Cookies.get('loginMode') || null;
if (loginMode && loginMode === 'iotWechat') ddCode = null;
// useEffect(() => {
// action.globalConfig = props.global;
// }, [props.global]);
......@@ -116,22 +118,27 @@ const Login = forwardRef((props, _ref) => {
}, []);
useEffect(() => {
if (videoRef && videoRef.current) {
videoRef.current.addEventListener('ended', function() {
dom.removeClass(loginRef.current, styles.caseHide);
dom.addClass(loginRef.current, styles.loginTimeShow);
videoTimeout = setTimeout(() => {
dom.removeClass(timeRef.current, styles.caseHide);
dom.addClass(timeRef.current, 'animate__fadeIn');
dom.removeClass(loginFormRef.current, styles.caseHide);
dom.addClass(loginFormRef.current, 'animate__fadeInUp');
dom.removeClass(footerRef.current, styles.caseHide);
dom.addClass(footerRef.current, 'animate__slideInUp');
dom.removeClass(titleRef.current, styles.caseHide);
dom.addClass(titleRef.current, 'animte__fadeInUp');
}, 500);
if(ddCode && loginMode === 'qywx') {
setShowVideo(false);
} else {
setShowVideo(true);
setTimeout(() => {
if (videoRef && videoRef.current) {
videoRef.current.addEventListener('ended', function() {
dom.removeClass(loginRef.current, styles.caseHide);
dom.addClass(loginRef.current, styles.loginTimeShow);
videoTimeout = setTimeout(() => {
dom.removeClass(timeRef.current, styles.caseHide);
dom.addClass(timeRef.current, 'animate__fadeIn');
dom.removeClass(loginFormRef.current, styles.caseHide);
dom.addClass(loginFormRef.current, 'animate__fadeInUp');
dom.removeClass(footerRef.current, styles.caseHide);
dom.addClass(footerRef.current, 'animate__slideInUp');
dom.removeClass(titleRef.current, styles.caseHide);
dom.addClass(titleRef.current, 'animte__fadeInUp');
}, 500);
});
}
});
}
......@@ -178,14 +185,14 @@ const Login = forwardRef((props, _ref) => {
<meta name="description" content={props.global.title || defaultSetting.title} />
</Helmet>
<div className={styles.main}>
<video
{showVideo && <video
src={require("../../../../assets/videos/beforPage.mp4") }
className={styles.videLayer}
autoPlay="autoPlay"
muted
playsInline="playsinline"
ref={videoRef}
/>
/>}
<div className={styles.inner}>
<div
className={classNames(styles.loginTime, styles.caseHide)}
......
import React, { useEffect, useState } from 'react';
import { encode } from 'js-base64';
import Cookies from 'js-cookie';
import { LOGIN_WAY } from '@/constants';
import { WECOM_APPID, AGENTID_CLOUD } from '@/constants';
import { LOGIN_WAY, WECOM_APPID, AGENTID_CLOUD } from '@/constants';
import styles from './index.less';
const useWeCom = props => {
......@@ -32,11 +31,11 @@ const useIOTQRCode = () => {
const redirectURI = function() {
let redirectUri = window.location.href;
if(redirectUri.indexOf('loginWay') > -1) return redirectUri;
if(redirectUri.indexOf('?') > -1) redirectUri += `&loginWay=${LOGIN_WAY.WeCom}`;
if (redirectUri.indexOf('loginWay') > -1) return redirectUri;
if (redirectUri.indexOf('?') > -1) redirectUri += `&loginWay=${LOGIN_WAY.WeCom}`;
else redirectUri += `?loginWay=${LOGIN_WAY.WeCom}`;
return redirectUri;
}
};
const props = Object.assign(
{},
{
......@@ -49,9 +48,7 @@ const useIOTQRCode = () => {
},
);
useWeCom(props);
return (
<div id="wxlogin_container" className={styles.wxlogin_container}></div>
);
return <div id="wxlogin_container" className={styles.wxlogin_container} />;
};
export default useIOTQRCode;
......@@ -16,7 +16,7 @@ import useRenderQcode from '../../js/useRenderQcode';
import Account from '../../js/useAccount';
import IotComponent from '../../js/useIOTComponent';
import CloudForm from './cloudForm';
import { initMicroApps } from '../../../../../micro';
import { defaultApp } from '../../../../../micro';
import useTime from '../../js/useTime';
const isRQcodeFunc = loginFunc => {
......@@ -25,8 +25,10 @@ const isRQcodeFunc = loginFunc => {
};
const loginFuncImg = loginFunc => {
if (isRQcodeFunc(loginFunc)) {
// eslint-disable-next-line global-require
return require('@/assets/images/login/cloud/func_pwd.png');
}
// eslint-disable-next-line global-require
return require('@/assets/images/login/cloud/func_rqcode.png');
};
......@@ -48,7 +50,10 @@ const Login = forwardRef((props, _ref) => {
const [visible, setVisible] = useState(false);
const history = useHistory();
const [action, setAction] = useState(() => new LoginAction(Object.assign({}, props, { history }), setVisible, true));
const [showVideo, setShowVideo] = useState(false);
let { ddCode } = props.global;
const loginMode = Cookies.get('loginMode') || null;
if (loginMode && loginMode === 'iotWechat') ddCode = null;
const handleSubmit = values => {
/* eslint-disable */
action &&
......@@ -70,7 +75,8 @@ const Login = forwardRef((props, _ref) => {
props.updateCurrentIndex && props.updateCurrentIndex(0);
props.history.push(`/?client=${props.global.client}`);
// window.share.event.emit('triggerMicro', props.global);
initMicroApps();
// initMicroApps();
defaultApp();
});
action &&
action.events.on('loginError', event => {
......@@ -92,28 +98,34 @@ const Login = forwardRef((props, _ref) => {
let videoTimeout = null;
useEffect(() => {
if (videoRef && videoRef.current) {
videoRef.current.addEventListener('ended', function() {
dom.removeClass(loginRef.current, styles.caseHide);
dom.addClass(loginRef.current, styles.loginTimeShow);
videoTimeout = setTimeout(() => {
dom.removeClass(timeRef.current, styles.caseHide);
dom.addClass(timeRef.current, 'animate__fadeIn');
dom.removeClass(loginFormRef.current, styles.caseHide);
dom.addClass(loginFormRef.current, 'animate__fadeInUp');
dom.removeClass(footerRef.current, styles.caseHide);
dom.addClass(footerRef.current, 'animate__slideInUp');
dom.removeClass(titleRef.current, styles.caseHide);
dom.addClass(titleRef.current, 'animte__fadeInUp');
}, 500);
if(ddCode && loginMode === 'qywx') {
setShowVideo(false);
} else {
setShowVideo(true);
setTimeout(() => {
if (videoRef && videoRef.current) {
videoRef.current.addEventListener('ended', function() {
dom.removeClass(loginRef.current, styles.caseHide);
dom.addClass(loginRef.current, styles.loginTimeShow);
videoTimeout = setTimeout(() => {
dom.removeClass(timeRef.current, styles.caseHide);
dom.addClass(timeRef.current, 'animate__fadeIn');
dom.removeClass(loginFormRef.current, styles.caseHide);
dom.addClass(loginFormRef.current, 'animate__fadeInUp');
dom.removeClass(footerRef.current, styles.caseHide);
dom.addClass(footerRef.current, 'animate__slideInUp');
dom.removeClass(titleRef.current, styles.caseHide);
dom.addClass(titleRef.current, 'animte__fadeInUp');
}, 500);
});
}
});
}
return () => {
videoTimeout && clearTimeout(videoTimeout);
videoRef.current.removeEventListener('ended', () => {});
videoRef.current && videoRef.current.removeEventListener('ended', () => {});
};
}, [videoRef]);
useEffect(() => {
......@@ -164,14 +176,17 @@ const Login = forwardRef((props, _ref) => {
<meta name="description" content={props.global.title || defaultSetting.title} />
</Helmet>
<div className={styles.main}>
<video
src={require('@/assets/videos/beforPage.mp4')}
className={styles.videLayer}
autoPlay="autoPlay"
muted
playsInline="playsinline"
ref={videoRef}
/>
{
showVideo && <video
src={require('@/assets/videos/beforPage.mp4')}
className={styles.videLayer}
autoPlay="autoPlay"
muted
playsInline="playsinline"
ref={videoRef}
/>
}
{/* main content */}
<div className={styles.inner}>
<div className={classNames(styles.loginTime, styles.caseHide)} ref={loginRef}>
......
......@@ -55,10 +55,11 @@ const FormLogin = props => (
]}
/>
<div className={styles.checkbox_wrap}>
<Checkbox checked={props.autoLogin} onChange={e => props.setAutoLogin(e.target.checked)}>
{'记住密码'}
</Checkbox>
<a href="#">忘记密码?</a>
{ // <Checkbox checked={props.autoLogin} onChange={e => props.setAutoLogin(e.target.checked)}>
// {'记住密码'}
// </Checkbox>
// <a href="#">忘记密码?</a>
}
</div>
<Submit loading={props.submitting}>{useIntl().formatMessage({ id: 'pages.login.submit' })}</Submit>
</Form>
......
......@@ -16,9 +16,12 @@ import LoginAction from '../../login';
import styles from './index.less';
import { defaultApp } from '@/micro';
import { log } from 'kit_utils';
let big='广州大.png'
let bigNew=''
class HuaNongLogin extends Component {
constructor(props) {
super(props);
console.log(props);
this.state = {
time: '16:00',
week: '星期一',
......@@ -33,6 +36,17 @@ class HuaNongLogin extends Component {
};
this.fromRef = React.createRef();
this.sliVerify = React.createRef();
props.loginParams.map(v=>{
let item= v.split('=')
if(item.length>0){
if(item[0]=='big'){
big=item[1]
}
if(item[0]=='bigNew'){
bigNew=item[1]
}
}
})
}
handleSubmit = values => {
const { action, type, autoLogin } = this.state;
......@@ -52,7 +66,7 @@ class HuaNongLogin extends Component {
setTimeout(()=>{
appService
. getInOnLine({
UserID: globalConfig.userInfo.oid,
UserID: globalConfig.userInfo.oid||globalConfig.userInfo.OID,
SatrtDate: this.getNowDate(),
Port: location.port,
Oid:this._createGuid(),
......@@ -61,7 +75,7 @@ class HuaNongLogin extends Component {
window.gzTime= setInterval(()=>{
appService
. getInOnLine({
UserID: globalConfig.userInfo.oid,
UserID: globalConfig.userInfo.oid||globalConfig.userInfo.OID,
SatrtDate: this.getNowDate(),
Port: location.port,
Oid:this._createGuid(),
......@@ -193,7 +207,7 @@ _createGuid() {
.toUpperCase();
}
componentDidMount() {
console.log(this.props);
console.log(this.props,this.props.global.logo,this.props.global.transformDevAssetsBaseURL('assets/images/广州/背景.png'));
console.log(this);
this.onActinoChange(this.state.action);
this.getCurrentTime(this.showTime);
......@@ -215,12 +229,13 @@ _createGuid() {
this.clearTime();
}
render() {
return (
<HelmetProvider>
<div className={styles.quota}>
<div className={styles.quota} style={{'background': `url(${bigNew?this.props.global.transformDevAssetsBaseURL(bigNew):require("@/assets/images/login/节水/"+big)}) no-repeat`}}>
<div className={styles.head}>
<div className={styles.title}>
<img src={this.props.global && this.props.global.transformDevAssetsBaseURL && this.props.global.transformDevAssetsBaseURL(this.props.global.logo)} alt="" />
<img className={styles.imgs} src={this.props.global && this.props.global.transformDevAssetsBaseURL && this.props.global.transformDevAssetsBaseURL(this.props.global.logo)} alt="" />
{/* <img src={require('@/assets/images/login/能源-定额/华农logo.png')} alt="" /> */}
<span>{this.props.global.title || this.state.title}</span>
</div>
......
......@@ -15,9 +15,10 @@
position: relative;
width: 100%;
height: 100%;
background: url('@/assets/images/login/节水/广州大.png') no-repeat;
// background: url('@/assets/images/login/节水/广州大.png') no-repeat;
background-size: cover;
background-size:100% 100%;
background-attachment:fixed;
.head {
position: absolute;
top: 0;
......@@ -34,6 +35,11 @@
text-shadow: 0px 0px 2px rgba(2, 49, 21, 0.51);
line-height: 66px;
}
.imgs{
width: 44px;
margin-bottom: 7px;
margin-right: 10px;
}
.time_and_date {
padding-right: 50px;
display: flex;
......@@ -112,6 +118,9 @@
.panda-console-base-input-affix-wrapper:focus, .panda-console-base-input-affix-wrapper-focused {
box-shadow: none;
}
.panda-console-base-form-item{
margin-bottom: 46px;
}
.panda-console-base-input-affix-wrapper {
color: #0599F4;
background: none;
......
/*
* @Author: 634665781 634665781@qq.com
* @Date: 2022-08-15 15:16:26
* @LastEditors: 634665781 634665781@qq.com
* @LastEditTime: 2022-11-04 10:41:23
* @FilePath: \CivWeb\src\pages\user\login\template\energy_JS2\FormLogin.js
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
/*
* @Author: 634665781 634665781@qq.com
* @Date: 2022-08-15 15:16:26
* @LastEditors: 634665781 634665781@qq.com
* @LastEditTime: 2022-11-04 10:12:29
* @FilePath: \CivWeb\src\pages\user\login\template\energy_JS2\FormLogin.js
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
/* eslint-disable */
import { Checkbox } from 'antd';
import React from 'react';
......@@ -55,10 +71,11 @@ const FormLogin = props => (
]}
/>
<div className={styles.checkbox_wrap}>
<Checkbox checked={props.autoLogin} onChange={e => props.setAutoLogin(e.target.checked)}>
{'记住密码'}
</Checkbox>
<Checkbox checked={props.autoLogin} onChange={e => props.setAutoLogin(e.target.checked)}>
{'记住密码'}
</Checkbox>
<a href="#">忘记密码?</a>
</div>
<Submit loading={props.submitting}>{useIntl().formatMessage({ id: 'pages.login.submit' })}</Submit>
</Form>
......
......@@ -17,6 +17,7 @@ import styles from './index.less';
import { defaultApp } from '@/micro';
import { log } from 'kit_utils';
let smallBg='建桥图片.jpg'
let smallBgNew=''
class HuaNongLogin extends Component {
constructor(props) {
super(props);
......@@ -42,6 +43,9 @@ class HuaNongLogin extends Component {
if(item[0]=='smallBg'){
smallBg=item[1]
}
if(item[0]=='smallBgNew'){
smallBgNew=item[1]
}
}
})
......@@ -189,6 +193,7 @@ _createGuid() {
.toUpperCase();
}
componentDidMount() {
console.log(this.props.global.logo);
this.onActinoChange(this.state.action);
this.getCurrentTime(this.showTime);
/* request(urlUtils.getUrl(
......@@ -228,7 +233,7 @@ _createGuid() {
</div>
<div className={styles.wrap_content}>
< div>
<img className={styles.from_img} src={require(`@/assets/images/login/节水/${smallBg}`)} alt="" />
<img className={styles.from_img} src={smallBgNew?this.props.global.transformDevAssetsBaseURL(smallBgNew): require(`@/assets/images/login/节水/${smallBg}`) } alt="" />
<div className={styles.from}>
<div className={styles.slogan}>
<div className={styles.slogan_back} />
......
import BaseLogin from "../baseLogin"
import TieShanLogin from "../project/tieshan"
import { useState , useEffect } from "react"
const LoginTemplate = {
"铁山" : TieShanLogin,
default : BaseLogin
}
const Panorama = props => {
const {loginParams , ...reset} = props
const [params, setParams] = useState({})
useEffect(() => {
if(!loginParams) {
setParams({})
} else {
const params = {}
loginParams.map(data => {
const [key , value] = data.split("=")
params[key] = value
})
setParams(params)
}
}, [loginParams]);
const LoginCompontnt = params['projectName'] && LoginTemplate[params['项目']] ? LoginTemplate[params['项目']] :
params['projectName'] ? LoginTemplate["default"] : LoginTemplate['default']
return (<LoginCompontnt {...reset} loginParams = {params}/>)
}
export default Panorama
\ No newline at end of file
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
import styles from './index.less'
import React, { forwardRef, useEffect, useRef, useState } from 'react';
import LoginAction from '../../../login';
import Account from '../../../js/useAccount';
import moment from 'moment';
import classnames from 'classnames';
import { Modal, Popover } from 'antd';
import { Helmet, HelmetProvider } from 'react-helmet-async';
import { connect } from 'react-redux';
import { useHistory, withRouter } from '@wisdom-utils/runtime';
import { actionCreators } from '@/containers/App/store';
import defaultSetting from '../../../../../../../config/defaultSetting';
import { defaultApp } from '../../../../../../micro';
import logo from './images/logo.png'
import titleImage1 from './images/涓涓清泉.png'
import titleImage2 from './images/润泽万家.png'
import Krpano from '../../../components/Krpano';
const TieShanLogin = forwardRef((props, _ref) => {
const sliVerify = useRef();
const loginFormRef = useRef();
const formRef = useRef(null);
const [status, setStatus] = useState('normal');
const [autoLogin, setAutoLogin] = useState(false);
const [submitting, setSubmitting] = useState(false);
const [type, setType] = useState('Account');
const [visible, setVisible] = useState(false);
const history = useHistory();
const [dateObj, setDateObj] = useState({});
const { projectName } = props.loginParams
const [action, setAction] = useState(
() =>
new LoginAction(Object.assign({}, props, { history }), setVisible, false),
);
const handleSubmit = values => {
/* eslint-disable */
action &&
(type === 'Account'
? action.loginHandler(
values.userName,
values.password,
null,
autoLogin,
sliVerify,
)
: type === 'Mobile'
? action.phoneLoginFormHandler(values.mobile, values.captcha)
: null);
setSubmitting(true);
props.updateCurrentIndex && props.updateCurrentIndex(-1);
};
useEffect(() => {
// if (props.loginMode === LOGIN_WAY.WeChart) {
action &&
action.events.on('loginSuccess', event => {
setSubmitting(false);
props.updateCurrentIndex && props.updateCurrentIndex(0);
props.history.push(`/?client=${props.global.client}`);
// window.share.event.emit('triggerMicro', props.global);
// initMicroApps();
defaultApp();
});
action &&
action.events.on('loginError', event => {
setVisible(false);
setSubmitting(false);
});
action &&
action.events.on('loginVisible', status => {
setVisible(status);
});
// }
return () => {
action && action.events && action.events.removeAllListeners('loginSuccess');
action && action.events && action.events.removeAllListeners('loginError');
action && action.events && action.events.removeAllListeners('loginVisible');
}
}, [props.loginMode]);
useEffect(() => {
setSubmitting(false);
}, [visible]);
const renderPlatform = () => {
const template = props.global.loginTemplate;
const params = {
fromRef: formRef,
type,
setType,
status,
submitting,
autoLogin,
setAutoLogin,
action,
onSubmit: handleSubmit,
loginMode: props.loginMode,
updateLoginMode: props.updateLoginMode,
welcome: null,
};
return <Account {...params} />;
};
const handleWeek = () => {
const weekOfDay = Number(moment().format('E'));
let weekDayName = ''
switch (weekOfDay) {
case 1:
weekDayName = '周一'
break
case 2:
weekDayName = '周二'
break
case 3:
weekDayName = '周三'
break
case 4:
weekDayName = '周四'
break
case 5:
weekDayName = '周五'
break
case 6:
weekDayName = '周六'
break
case 0:
weekDayName = '周日'
break
default:
weekDayName = ''
}
return weekDayName
}
useEffect(() => {
const timer = setInterval(() => {
setDateObj({
curTime: moment().format('HH:mm:ss'),
week: handleWeek(),
date: moment().format('YYYY/MM/DD')
});
}, 1000);
return () => {
clearInterval(timer);
};
}, [])
return (
<HelmetProvider>
<Helmet>
<title>{props.global.title || defaultSetting.title}</title>
<meta name="description" content={props.global.title || defaultSetting.title} />
</Helmet>
<div className={styles.tieshanLogin}>
<div className={styles['inner-wrapper']}>
{/* <div className={styles['left-imgbox']}></div> */}
<div className={styles['inner-center']}>
<div className={styles['welcome-title']}>
{/* <img src={loginTitlePng} alt="login-title" /> */}
<div className={styles['welcome-slogan']}>
<img src={titleImage1} />
</div>
<span className={styles['welcome-split']}></span>
<div className={styles['welcome-slogan']}>
<img src={titleImage2} />
</div>
</div>
<div className={classnames(styles['inner-bg'], styles['login-part'])} ref={loginFormRef}>
{renderPlatform()}
</div>
</div>
</div>
<div className={styles['login-header-wrapper']}>
<div className={styles['login-header']}>
<div className={styles['left-title']}>
<div>
<img src={logo} />
</div>
<div className={styles['cn-title']}>铁山原水供水调度管理平台</div>
</div>
<div className={styles['right-timebox']}>
<div className={styles['curr-time']}>{dateObj.curTime}</div>
<div className={styles['curr-week-date']}>
<div className={styles['curr-week']}>{dateObj.week}</div>
<div className={styles['curr-date']}>{dateObj.date}</div>
</div>
</div>
</div>
</div>
<div className={styles['krpano']}>
<Krpano projectName={projectName} />
</div>
<Modal centered visible={visible} width={340} footer={null} closable={false} bodyStyle={{ padding: '15px' }}>
<div ref={sliVerify} />
</Modal>
</div>
</HelmetProvider>
)
})
const mapStateToProps = state => ({
global: state.getIn(['global', 'globalConfig']),
loginMode: state.getIn(['global', 'loginMode']),
});
const mapDispatchToProps = dispatch => ({
updateConfig(config) {
dispatch(actionCreators.getConfig(config));
},
createContext(data) {
dispatch(actionCreators.createContext(data));
},
updateLoginMode(mode) {
dispatch(actionCreators.changeLoginMode(mode));
},
updateCurrentIndex(index) {
dispatch(actionCreators.updateCurrentIndex(index));
},
});
export default connect(
mapStateToProps,
mapDispatchToProps,
)(withRouter(TieShanLogin));
\ No newline at end of file
.tieshanLogin {
width: 100%;
height: 100%;
position: relative;
min-height: 7.0rem;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
.inner-bg {
width: 100%;
height: 100%;
&>div {
width: 70%;
margin: 0 auto;
}
}
.inner-bg .title {
font-size: 27px;
font-weight: bold;
color: rgba(255, 255, 255, 1);
letter-spacing: 2px;
}
.form-control:focus {
border-color: #66afe9;
outline: 0;
-webkit-box-shadow: none;
box-shadow: none;
}
.inner-wrapper {
// width: 800px;
// height: 400px;
display: flex;
justify-content: center;
align-items: center;
border-radius: 10px;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
z-index: 100;
// bottom: 20%;
// top: 46%;
// right: 0;
// transform: translateY(-50%);
}
.inner-center {
position: relative;
width: 400px;
// height: 316px;
background: rgba(255, 255, 255, 0.9);
border: 1px solid #FFFFFF;
box-shadow: 0px 15px 15px 3px rgba(140, 142, 145, 0.52);
border-radius: 15px;
}
.welcome-title {
width: 100%;
height: 68px;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
flex-wrap: nowrap;
background: linear-gradient(#0061E4, #00CEFA);
margin-bottom: 24px;
border-top-left-radius: 15px;
border-top-right-radius: 15px;
background-color: rgba(255, 255, 255, .9);
.welcome-split {
height: 30px;
width: 1px;
background-color: #eee;
margin: 0 20px;
}
.welcome-slogan {
vertical-align: middle;
margin-top: 3px;
}
// line-height: 68px;
// font-size: 24px;
// font-family: PingFang SC;
// font-weight: bold;
// color: #000000;
// opacity: 0.85;
// text-align: center;
}
.formgroup2 {
display: flex;
align-items: center;
display: flex;
margin: 0px 5.5%;
margin-bottom: 10%;
align-items: center;
margin-bottom: 40px;
}
.APPcodeBox {
width: 100%;
display: flex;
flex-flow: column;
align-items: center;
cursor: pointer;
position: relative;
}
.APPCtext {
font-size: 14px;
font-family: Microsoft YaHei;
font-weight: 400;
color: #000000;
line-height: 30px;
opacity: 0.75;
}
.login-header-wrapper {
width: 100%;
position: absolute;
top: 0;
background: linear-gradient(to bottom ,rgba(56,158,239, 1), rgba(56,158,239, 0));
height: 100px;
z-index: 100;
.login-header {
position: relative;
width: 100%;
padding: 0 38px;
display: flex;
justify-content: space-between;
align-items: center;
.left-title {
display: flex;
justify-content: flex-start;
align-items: center;
.cn-title {
font-size: 26px;
font-family: Microsoft YaHei;
font-weight: 400;
color: #FFFFFF;
margin-left: 10px;
}
.en-title {
font-size: 12px;
font-family: Microsoft YaHei;
font-weight: 400;
color: #FFFFFF;
opacity: 0.65;
}
}
.right-timebox {
display: flex;
justify-content: center;
align-items: center;
height: 60px;
.curr-time {
width: 140px;
font-size: 36px;
font-family: Microsoft YaHei;
font-weight: 300;
color: #FFFFFF;
}
.curr-week-date {
margin-left: 10px;
.curr-week {
font-size: 16px;
font-family: Microsoft YaHei;
font-weight: 400;
color: #FFFFFF;
}
.curr-date {
font-size: 14px;
font-family: Microsoft YaHei;
font-weight: 400;
color: #FFFFFF;
}
}
}
}
}
.copyright {
position: absolute;
bottom: 7%;
width: 100%;
margin: 0 auto;
font-size: 12px;
font-family: Microsoft YaHei;
font-weight: 400;
color: #F1F6FD;
text-align: center;
}
.qrcode-box {
position: absolute;
bottom: 0;
right: -35px;
width: 35px;
height: 35px;
background: #FFFFFF;
opacity: 0.8;
cursor: pointer;
}
.krpano {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
}
\ No newline at end of file
This diff is collapsed.
......@@ -11,6 +11,7 @@ import Iframe from '../pages/iframe';
import Login from '../pages/user/login';
import NoSecret from '../pages/user/login/noSecret';
import Notifications from '../pages/system/notifications';
import TabIframe from '../pages/system/iframe/TabWidget';
export const dyRoutes = (routes, layout, theme) => {
// eslint-disable-next-line no-shadow
......@@ -87,6 +88,15 @@ export const dyRoutes = (routes, layout, theme) => {
loading: LoadingComponent,
}),
},
{
path: '/',
render: ({ routeConfig }) => {
const { path } = routeConfig || {};
if (/system\/iframe\/tabWidget/.test(path)) {
return <TabIframe { ...routeConfig }/>
}
}
}
],
},
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment