Commit 66112172 authored by 徐乐's avatar 徐乐

Merge branch 'dev' of https://g.civnet.cn:8443/ReactWeb5/CivWeb into dev

parents a0f1a1bf 54f8c4bc
......@@ -107,13 +107,13 @@
"@babel/polyfill": "7.4.3",
"@babel/runtime": "^7.10.5",
"@esri/calcite-colors": "6.0.3",
"@wisdom-cesium/cesium": "^1.1.33",
"@wisdom-cesium/krpano": "1.0.29-52",
"@wisdom-cesium/cesium": "^1.1.35",
"@wisdom-cesium/krpano": "1.0.29-60",
"@wisdom-components/basictable": "^1.5.16",
"@wisdom-components/empty": "^1.4.1",
"@wisdom-map/amap": "1.1.0-beta.56",
"@wisdom-map/arcgismap": "1.4.0-164",
"@wisdom-map/basemap": "1.1.0-24",
"@wisdom-map/arcgismap": "1.4.0-185",
"@wisdom-map/basemap": "1.1.0-29",
"@wisdom-map/util": "^1.0.28-0",
"@wisdom-utils/components": "0.1.319",
"@wisdom-utils/runtime": "0.0.46",
......@@ -156,6 +156,7 @@
"react-infinite-scroll-component": "^6.1.0",
"react-intl": "^3.12.1",
"react-redux": "7.0.2",
"react-reveal": "^1.2.2",
"react-router-config": "^5.1.1",
"react-router-dom": "6.3.0",
"react-use": "^15.3.4",
......@@ -166,7 +167,8 @@
"reselect": "4.0.0",
"sanitize.css": "8.0.0",
"sha1": "^1.1.1",
"styled-components": "4.2.0"
"styled-components": "4.2.0",
"swiper": "6.8.4"
},
"devDependencies": {
"@babel/cli": "7.4.3",
......
import { jsonp, request } from '@wisdom-utils/utils';
import * as constants from '../../constants';
/**
* 兼容老接口
*/
const transformGateWay = url => {
if (!/^(cityinterface|CityInterface|CityServer)/) {
return url.replace(/GeteWay/, '');
}
};
export const API = {
AUTHORIZATION_TOKEN: '/PandaCore/Identity/AuthorizationToken', // 授权验证,不需要走网关加前缀
......@@ -45,8 +37,11 @@ export const API = {
GET_InOnLine: '/PandaEnergy/GZshuiwuju/GuangZhou/InOnLine', // 广州登陆接口
GET_UserMobile: '/PandaEnergy/GZshuiwuju/SingleLogin/SingleLoginByAccess_token', // 获取登录手机号
GET_JIANGXI_MANAGE: '/PandaWorkFlow/WorkFlow/JiangXiManage/Login', // 江西登录接口
GET_INTEGRATION_CONFIG: '/PandaCore/GCK/IntegrationAuth/GetIntegrationConfig', // 获取集成站点数据
GET_YANSHI_AUTHORITY: '/PandaCore/GCK/Demonstrate/GetYanshiAuthority', // 获取当前用户开始演示模式的所有菜单ID
IS_OPEN_YANSHI: '/PandaCore/GCK/Demonstrate/IsOpenYanshi', // 获取是否开启演示模式服务
GET_WEB_CONFIG: '/PandaOMS/OMS/GetIntegratedLoginbyName',
GET_WEB_TICKET: '/PandaOMS/OMS/GetTicketByToken',
};
const services = {
......@@ -95,19 +90,16 @@ const services = {
method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_HTTP,
},
getWebSiteConfig: {
url: API.GET_WEB_SITE_CONFIG,
method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_HTTP,
},
getUserInfo: {
url: API.GET_USER_INFO,
method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_HTTP,
},
getOA: {
url: API.GET_OA,
method: constants.REQUEST_METHOD_GET,
......@@ -126,31 +118,26 @@ const services = {
method: constants.REQUEST_METHOD_POST,
type: constants.REQUEST_HTTP,
},
getCity: {
url: API.GET_CITY,
method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_HTTP,
},
generateTokenQuick: {
url: API.GENERATE_TOKEN_CHANGE,
method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_HTTP,
},
getAllGroupsInfoForUser: {
url: API.GET_ALL_GROUPS_INFO_FORUSER,
method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_HTTP,
},
getWeather: {
url: API.GET_WEATHER,
method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_HTTP,
},
sendMessVerificationCode: {
url: API.SEND_MESSAGE_CODE,
method: constants.REQUEST_METHOD_GET,
......@@ -212,6 +199,26 @@ const services = {
method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_HTTP,
},
getYanshiAuthority: {
url: API.GET_YANSHI_AUTHORITY,
method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_HTTP,
},
isOpenYanshi: {
url: API.IS_OPEN_YANSHI,
method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_HTTP,
},
getIntegratedLoginbyName: {
url: API.GET_WEB_CONFIG,
method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_HTTP,
},
getTicketByToken: {
url: API.GET_WEB_TICKET,
method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_HTTP,
},
};
export const searchAutoCity = keywords => {
......
This diff is collapsed.
This diff is collapsed.
......@@ -5,12 +5,14 @@ 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 classNames from 'classnames';
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 service from '../../api/service/notification';
import { actionCreators } from '../../containers/App/store';
import isProd from '../../utils/env';
import { getMessageTypeIcon } from '../../layouts/AppLayout/notifier/utils';
// import NoticeIcon from '../NoticeIcon';
import styles from './index.less';
......@@ -19,17 +21,27 @@ const { TextArea } = Input;
const PlatformModal = ({ platformVisible, handleClosePlatform, handlerMointer, messages = [] }) => {
const [pageIndex, setPageIndex] = useState(1);
const message = useMemo(() => messages[pageIndex - 1], [messages, pageIndex]);
const isAlarm = message.infoClasses === MESSAGE_TYPE.ALARM_TYPE;
const defaultIcon = isAlarm
? 'https://panda-water.com/web4/assets/images/message/报警图标.svg'
: getMessageTypeIcon(message);
const icon = message.webIcon ? `${window.location.origin}/${message.webIcon}` : defaultIcon;
return (
<Modal
title={<FormattedMessage id="component.noticeIcon.modal.alarm.title" />}
title={
isAlarm ? (
<FormattedMessage id="component.noticeIcon.modal.alarm.title" />
) : (
<FormattedMessage id="component.noticeIcon.model.system.title" />
)
}
maskClosable={false}
mask={false}
maskStyle={{ pointerEvents: 'none' }}
visible={platformVisible}
zIndex={5000}
wrapClassName={styles.platformModalWrap}
className={styles.platformModal}
className={classNames(styles.platformModal, !isAlarm && styles.platformModalDefault)}
footer={
<Pagination
simple
......@@ -45,7 +57,7 @@ const PlatformModal = ({ platformVisible, handleClosePlatform, handlerMointer, m
>
<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={icon} alt="" />
<div className={styles.content}>
<div className={styles['content-top']}>
<a onClick={event => handlerMointer(event, message, true)}>
......@@ -53,20 +65,27 @@ const PlatformModal = ({ platformVisible, handleClosePlatform, handlerMointer, m
</a>
<span title="点击标为已读" onClick={event => handlerMointer(event, message, false)} />
</div>
<div className={styles['content-mid']}>
<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>
{' / '}
预设值:
{message && message.infoContent && message.infoContent.alarmThreshold}
</p>
</div>
{isAlarm ? (
<>
<div className={styles['content-mid']}>
<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>
{' / '}
预设值:
{message && message.infoContent && message.infoContent.alarmThreshold}
</p>
</div>
</>
) : (
<div className={styles['content-bottom']}>
<p>{message && message.infoContent && message.infoContent.content}</p>
</div>
)}
<p className={styles['message-time']}>{message && message.time}</p>
</div>
</div>
......@@ -110,7 +129,7 @@ class NoticeIconView extends Component {
}
get platformMessages() {
return this.state.noticeData.filter(item => item.infoLevel === '4' && item.infoClasses === 'alarmType');
return this.state.noticeData.filter(item => item.infoLevel === '4');
}
async componentDidMount() {
......
......@@ -376,6 +376,13 @@
}
}
}
.platformModalDefault {
:global {
.@{ant-prefix}-modal-header {
background: var(--panda-console-base-header-bg-color);
}
}
}
.videoPopup {
:global(.@{ant-prefix}-modal-content) {
height: 520px;
......
......@@ -15,7 +15,8 @@ class Message {
defaultContent,
webIcon,
title,
infoClasses
infoClasses,
webVoice
} = message) {
this.id = id;
this.infoContent = infoContent;
......@@ -30,6 +31,7 @@ class Message {
this.title = title; // 消息标题
this.defaultContent = defaultContent;
this.infoClasses = infoClasses;
this.webVoice = webVoice;
}
}
......@@ -68,6 +70,7 @@ export const createMessageFromHis = (hisMessage, options = {}) => {
dateTime: hisMessage.hisCreateTime,
infoLevel: hisMessage.infoLevel,
webConfig: hisMessage.web_config,
webVoice: hisMessage.webVoice,
webPath: hisMessage.web_path,
messType: hisMessage.messType,
defaultContent: (_.isString(hisMessage.defaultContent) && hisMessage.defaultContent.replace(new RegExp(/ /g), "").length > 0) ? hisMessage.defaultContent : null,
......@@ -109,6 +112,7 @@ export const createMessageFromReal = (realMesssage, options = {}) => {
dateTime: realMesssage.createTime,
webConfig: realMesssage.web_config,
webPath: realMesssage.web_path,
webVoice: realMesssage.webVoice,
messType: realMesssage.messType || realMesssage.MessType,
defaultContent: (_.isString(realMesssage.defaultContent) && realMesssage.defaultContent.replace(new RegExp(/ /g), "").length > 0) ? realMesssage.defaultContent : null,
webIcon: (_.isString(realMesssage.webIcon) && realMesssage.webIcon.replace(new RegExp(/ /g), "").length > 0) ? realMesssage.webIcon : null,
......
......@@ -425,7 +425,8 @@ class Notifier {
*/
speakMessage = message => {
if (!message) return;
const { version } = message;
const { version, webVoice } = message;
if(webVoice) return this.speakWebVoice(message);
if(version === '3.0') return this.speakDefault(message);
switch(message.infoType) {
case 'SCADA报警':
......@@ -447,6 +448,7 @@ class Notifier {
speakAlarm = message => {
const device =
message?.infoContent?.title
?.replace(/_/g, ',')
?.split(' ')
?.splice(1)
?.join(' ') ?? ''; // 报警设备:“【阈值报警】 二供泵房 | 光谷物联港”
......@@ -488,9 +490,15 @@ class Notifier {
this.speak(msg);
};
speakDefault = message => {
let msg = `${message.title},${message.title}: ${message.infoContent ?? ''}`
let msg = replaceSpeak(`${message.title},${message.title}: ${message.infoContent ?? ''}`)
this.speak(msg);
};
speakWebVoice = message => {
const { webVoice } = message;
if(typeof webVoice === "string") {
this.speak(replaceSpeak(webVoice.replace(/_/g, ',')));
}
}
speak = msg => {
if (!this.speakState) return;
this.speakState.text = msg;
......@@ -513,11 +521,7 @@ class Notifier {
this.renderPopVideo(message); // 显示视频弹窗
return;
}
if (message.infoLevel === PLATFORM_LEVEL && message.infoClasses === MESSAGE_TYPE.ALARM_TYPE) {
this.renderPopPlatform(message); // 显示报警弹窗
return;
}
if (message.version === '3.0' && message.infoLevel === PLATFORM_LEVEL) {
if (message.infoLevel === PLATFORM_LEVEL) {
this.renderPopPlatform(message); // 显示报警弹窗
return;
}
......
......@@ -548,6 +548,7 @@ const Layout = props => {
loading: menuLoading,
// onLoadingChange: (loading) => setMenuLoading(loading)
}}
hideFeedback={props.global.hideFeedback}
logo={logo}
topMenuActiveKey={Number(sessionStorage.getItem(currentProduct)) || 0}
rightContentRender={() => <RightContent />}
......
......@@ -399,10 +399,11 @@ class Site {
config.widgets = [];
config.allWidgets = [];
config.userInfo = window?.globalConfig?.transformUserInfo?.(res.data) ?? res.data;
window.globalConfig = config;
// 重置网关配置
// eslint-disable-next-line prettier/prettier, no-undef
const hasGateWay = !gatewayRes || !gatewayRes.data ? false : _.isString(gatewayRes.data) ? JSON.parse(gatewayRes.data) : (typeof gatewayRes.data === 'boolean' ? gatewayRes.data : false);
config.hasGateWay = hasGateWay;
config.apiGatewayDomain = `${window.location.origin}${hasGateWay ? '/PandaCore/GateWay' : ''}`;
if (hasGateWay) {
appService
.authorizationToken({
......@@ -411,14 +412,17 @@ class Site {
})
.then(tokenRes => {
const accessToken = tokenRes.data?.access_token ?? null;
config.access_token = accessToken;
localStorage.setItem('access_token', accessToken);
this.writeCookie(token, site, onChangeVisible, actionRef, accessToken);
})
.catch(err => {
this.setLoading(false);
config.access_token = null;
this.writeCookie(token, site, onChangeVisible, actionRef, null);
});
} else {
config.access_token = null;
localStorage.setItem('access_token', null);
this.writeCookie(token, site, onChangeVisible, actionRef, null);
}
......
......@@ -261,10 +261,9 @@ export const initMicroApps = (url) => {
start(Configuration);
runAfterFirstMounted(() => {
event.emit('loading', false);
const time = micro.length > 3 ? 3000 : 500;
setTimeout(() => {
prefetchApps(micro);
}, time)
}, 5000)
Logger.info('[MainApp] first app mounted');
});
addGlobalUncaughtErrorHandler(event => {
......
......@@ -27,6 +27,8 @@
.page {
position: relative;
height: 100%;
display: flex;
flex-direction: column;
.pageTitle {
margin-bottom: 18px;
......@@ -41,6 +43,7 @@
background-size: 100% 100%;
background-repeat: no-repeat;
font-family: "zihun";
flex: none;
}
.page-time {
......@@ -97,6 +100,8 @@
min-height: 396px;
width: 100%;
position: relative;
flex: 1;
overflow-y: auto;
}
.cus-arrow {
......@@ -133,16 +138,20 @@
margin: 0 auto;
width: 42em;
&[num="2"],
&[num="4"] {
&:not(&[num="1"]) {
width: (42em * 2 + 1em);
}
&[num="3"],
&[num="5"],
&[num="6"] {
width: (42em * 3 + 2em);
}
// &[num="2"],
// &[num="4"] {
// width: (42em * 2 + 1em);
// }
// &[num="3"],
// &[num="5"],
// &[num="6"] {
// width: (42em * 3 + 2em);
// }
&[num="1"],
&[num="2"],
......@@ -387,16 +396,19 @@
gap: 1.5em;
width: 44em;
&[num="2"],
&[num="4"] {
&:not(&[num="1"]) {
width: (44em * 2 + 2em);
}
// &[num="2"],
// &[num="4"] {
// width: (44em * 2 + 2em);
// }
&[num="3"],
&[num="5"],
&[num="6"] {
width: (44em * 3 + 3em);
}
// &[num="3"],
// &[num="5"],
// &[num="6"] {
// width: (44em * 3 + 3em);
// }
&[num="1"],
&[num="2"],
......@@ -475,16 +487,20 @@
gap: 1.5em;
width: 54em;
&[num="2"],
&[num="4"] {
&:not(&[num="1"]) {
width: (54em * 2 + 2em);
}
&[num="3"],
&[num="5"],
&[num="6"] {
width: (54em * 3 + 8em);
}
// &[num="2"],
// &[num="4"] {
// width: (54em * 2 + 2em);
// }
// &[num="3"],
// &[num="5"],
// &[num="6"] {
// width: (54em * 3 + 8em);
// }
&[num="1"],
&[num="2"],
......
/* eslint-disable no-lonely-if */
import React, { useEffect, useRef, useState } from 'react';
import Iframe from 'react-iframe';
import { appService } from '@/api';
import Empty from '@wisdom-components/empty';
import axios from 'axios';
import { Message, Spin, notification } from 'antd';
import styles from './index.less';
const IntegratedLogin = props => {
const { sysName } = props.params;
const [linkUrl, setLinkUrl] = useState('');
const [loading, setLoading] = useState(false);
const ticketData = useRef();
const getTicket = () => {
appService.getTicketByToken({ token: window.globalConfig.token }).then(res => {
if (res.code === 0) {
ticketData.current = res.data;
} else {
notification.error({
message: '提示',
duration: 3,
description: res.msg,
});
}
});
};
// 外网通不通判断
const ping = () => {
fetch('https://www.google.com')
.then(response => {
if (response.ok) {
return true;
}
return false;
})
.catch(error => {
return false;
});
};
const getUrlParam = url => {
let arrObj = url.split('?');
let params = Object.create(null);
if (arrObj.length > 1) {
arrObj = arrObj[1].split('&');
arrObj.forEach(item => {
item = item.split('=');
params[item[0]] = item[1];
});
}
return params;
};
const getSiteConfig = () => {
if (linkUrl) {
return;
}
let ticket = '';
setLoading(true);
appService
.getIntegratedLoginbyName({ sysName })
.then(res => {
if (res.code === 0) {
if (res.data.AccountParam[0].value === 1) {
ticket = ticketData.current;
}
const parma = res.data.AccountParam[0].value === 1 ? ticket : window.globalConfig.token;
if (res.data.siteType === 1) {
// 集成SaaS平台
const userId = window.globalConfig.userInfo.OID;
axios({
method: 'get',
url: `${window.location.origin}${res.data.serviceUrl}?userId=${userId}`,
}).then(resData => {
const url = resData.data.data;
if (res.data.target === 1) {
window.open(url);
} else {
setLinkUrl(url);
}
});
} else {
// 第三方接入
const pingState = ping;
let url = '';
// 外网通
if (pingState) {
if (res.data.InternetAddress) {
url = res.data.InternetAddress;
} else {
url = res.data.IntranetAddress;
}
} else {
if (res.data.IntranetAddress) {
url = res.data.IntranetAddress;
} else {
Message.error('请配置内网地址');
url = res.data.InternetAddress;
return;
}
}
if (url) {
const params = getUrlParam(url);
if (JSON.stringify(params) === '{}') {
url = `${url}?${res.data.AccountParam[0].key}=${parma}`;
} else {
url = `${url}&${res.data.AccountParam[0].key}=${parma}`;
}
}
if (res.data.target === 1) {
window.open(url);
} else {
setLinkUrl(url);
}
}
setLoading(false);
} else {
setLoading(false);
notification.error({
message: '提示',
duration: 3,
description: res.msg,
});
}
})
.catch(error => {});
};
useEffect(() => {
getTicket();
getSiteConfig();
}, []);
return (
<div className={styles.IntegratedLogin}>
{linkUrl !== '' ? (
<Iframe
url={linkUrl}
width="100%"
height="100%"
display="block"
position="relative"
styles={{ border: 'none' }}
/>
) : (
<Spin Spin={loading} tip="加载中..." style={{ width: '100%', height: '100%', marginTop: '300px' }} />
)}
</div>
);
};
export default IntegratedLogin;
......@@ -8,7 +8,6 @@
border: none;
}
.oper-wrap {
top: 0;
right: 0;
......@@ -19,13 +18,13 @@
.oper-btn {
cursor: pointer;
color: #FFF;
color: #fff;
position: absolute;
top: 10px;
right: 15px;
transition: right ease-in-out 0.8s;
}
.btn-fullscreen_exit {
display: block;
width: 1.2rem;
......@@ -40,5 +39,8 @@
}
}
}
}
\ No newline at end of file
}
.IntegratedLogin {
width: 100%;
height: 100%;
}
/*
* @Author: 634665781 634665781@qq.com
* @Date: 2022-07-08 14:28:01
* @LastEditors: Please set LastEditors
* @LastEditTime: 2023-08-22 11:36:58
* @LastEditors: 634665781 634665781@qq.com
* @LastEditTime: 2023-08-23 17:56:41
* @FilePath: \CivWeb\src\pages\user\login\index.js
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
......@@ -33,9 +33,10 @@ import DazuLogin from './template/project/dazu';
import WeixinLogin from './template/project/weixin';
import PanoramaLogin from './template/panorama';
import JiangXi from './template/project/jiangxi';
import JiangXiNew from './template/project/jiangxiNew';
import Queshan from './template/project/queshan';
import Queshansl from './template/project/queshansl';
import PiZhouLogin from './template/project/pizhou';
import { AppInitState } from '../../../render';
const LoginTemplate = {
'新春.html': baseLoginNewYear,
......@@ -64,8 +65,10 @@ const LoginTemplate = {
'项目 - 威信.html': WeixinLogin,
'全景图.html': PanoramaLogin,
'项目 - 江西.html': JiangXi,
'项目 - 江西轮播.html': JiangXiNew,
'项目 - 长水机场.html': ChangShuiJiChang,
'项目 - 确山.html': Queshan,
'项目 - 确山水利.html': Queshansl,
'项目 - 邳州.html': PiZhouLogin,
default: BaseLogin,
};
......
This diff is collapsed.
......@@ -23,8 +23,8 @@ const Login = forwardRef((props, _ref) => {
const param = params.getParams('token')?.replaceAll(';', '&');
return param ? decodeURIComponent(escape(param)) : null;
});
const [authCode] = useState(() => {
const param = params.getParams('authCode')?.replaceAll(';', '&');
const [site] = useState(() => {
const param = params.getParams('site')?.replaceAll(';', '&');
return param ? decodeURIComponent(escape(param)) : null;
});
// 需要在 GetGateWay 和 GetConfig 之后再执行登录。避免信息错落乱
......@@ -70,7 +70,7 @@ const Login = forwardRef((props, _ref) => {
action.transformLoginHander(res, false);
});
} else {
action.init();
action.init(site);
}
}
}, [action, action.globalConfig, props.global]);
......
import { Checkbox } from 'antd';
import React, { useRef } from 'react';
import { useIntl } from '@wisdom-utils/components';
import LoginForm from './LoginForm';
import LoginMessage from '../../../js/loginMessage';
/* eslint-disable */
const { UserName, Password, Submit } = LoginForm;
const useAccount = props => {
const formRef = useRef(null);
return (
<LoginForm onSubmit={props.onSubmit} welcome={props.welcome} ref={formRef} form={props.form}>
{props.status === 'error' && props.type === 'account' && !props.submitting && (
<LoginMessage
content={useIntl().formatMessage({
id: 'pages.login.accountLogin.errorMessage',
})}
/>
)}
<UserName
name="userName"
placeholder={useIntl().formatMessage({
id: 'pages.login.username.placeholder',
})}
rules={[
{
required: true,
message: useIntl().formatMessage({
id: 'pages.login.username.required',
}),
},
]}
/>
<Password
name="password"
placeholder={useIntl().formatMessage({
id: 'pages.login.password.placeholder',
})}
rules={[
{
required: true,
message: useIntl().formatMessage({
id: 'pages.login.password.required',
}),
},
]}
/>
<div>
<Checkbox checked={props.autoLogin} onChange={e => props.setAutoLogin(e.target.checked)}>
{useIntl().formatMessage({ id: 'pages.login.rememberMe' })}
</Checkbox>
</div>
<Submit loading={props.submitting}>{useIntl().formatMessage({ id: 'pages.login.submit' })}</Submit>
</LoginForm>
);
};
export default useAccount;
import React, { forwardRef, useImperativeHandle, useEffect } from 'react';
import { Form } from 'antd';
import classNames from 'classnames';
import { useIntl } from '@wisdom-utils/components';
import styles from '../../../components/Login/index.less';
import LoginContext from '../../../components/Login/LoginContext';
import LoginItem from '../../../components/Login/LoginItem';
import LoginSubmit from '../../../components/Login/LoginSubmit';
const Login = (props, ref) => {
const intl = useIntl();
const { className } = props;
const otherChildren = [];
React.Children.forEach(props.children, child => {
if (!child) {
return;
}
otherChildren.push(child);
});
return (
<LoginContext.Provider value={{}}>
<div className={classNames(className, styles.login)}>
{props.welcome === void 0 ? (
<div className={styles.desc}>{intl.formatMessage({ id: 'pages.login.welcome' })}</div>
) : (
props.welcome
)}
<Form
form={props.form}
onFinish={values => {
if (props.onSubmit) {
props.onSubmit(values);
}
}}
>
{props.children}
</Form>
</div>
</LoginContext.Provider>
);
};
Login.Submit = LoginSubmit;
Login.UserName = LoginItem.UserName;
Login.Password = LoginItem.Password;
Login.NewYearPassword = LoginItem.NewYearPassword;
Login.Mobile = LoginItem.Mobile;
Login.Captcha = LoginItem.Captcha;
Login.NewYearMobile = LoginItem.NewYearMobile;
Login.NewYearCaptcha = LoginItem.NewYearCaptcha;
export default Login;
import React, { forwardRef, useEffect, useRef, useState } from 'react';
import { Modal, Popover } from 'antd';
import { Modal, Popover, Form, Tooltip } from 'antd';
import { Helmet, HelmetProvider } from 'react-helmet-async';
import { connect } from 'react-redux';
import { useHistory, withRouter } from '@wisdom-utils/runtime';
......@@ -12,6 +12,7 @@ import defaultSetting from '../../../../../../../config/defaultSetting';
import LoginAction from '../../../login';
import styles from './index.less';
import Account from '../../../js/useAccount';
import FormLogin from './Account';
import { defaultApp } from '../../../../../../micro';
import logoPng from './images/8.png';
import qrcodePng from './images/1.png';
......@@ -26,6 +27,7 @@ const PopOvercontent = () => {
};
const Login = forwardRef((props, _ref) => {
const [form] = Form.useForm();
const sliVerify = useRef();
const loginFormRef = useRef();
const formRef = useRef(null);
......@@ -38,12 +40,12 @@ const Login = forwardRef((props, _ref) => {
const history = useHistory();
const [action, setAction] = useState(() => new LoginAction(Object.assign({}, props, { history }), setVisible, false));
const [dateObj, setDateObj] = useState({});
const [loginType, setLoginType] = useState('4a平台');
const [loginType, setLoginType] = useState('OA账号');
const handleSubmit = values => {
/* eslint-disable */
action &&
(type === 'Account'
? loginType === '4a平台'
? loginType === 'OA账号'
? action.loginHandlerJiangXi(values.userName, values.password, null, autoLogin, sliVerify)
: action.loginHandler(values.userName, values.password, null, autoLogin, sliVerify)
: type === 'Mobile'
......@@ -87,6 +89,7 @@ const Login = forwardRef((props, _ref) => {
const renderPlatform = () => {
const template = props.global.loginTemplate;
const params = {
form: form,
fromRef: formRef,
type,
setType,
......@@ -100,7 +103,8 @@ const Login = forwardRef((props, _ref) => {
updateLoginMode: props.updateLoginMode,
welcome: null,
};
return <Account {...params} />;
// return <Account {...params} />;
return <FormLogin {...params} />;
};
/* eslint-disable */
......@@ -150,6 +154,10 @@ const Login = forwardRef((props, _ref) => {
const toLink = () => {
window.open('http://gis.panda-water.cn/jiangxi/index.html');
};
const tabChange = key => {
form.resetFields();
setLoginType(key);
};
return (
<HelmetProvider>
<Helmet>
......@@ -159,22 +167,30 @@ const Login = forwardRef((props, _ref) => {
<div className={classnames(styles.lvchenglogin, 'lvcheng')}>
<div className={styles['inner-wrapper']}>
<div className={styles['title-image-box']}>
<img src={logoPng} alt="" className={styles['title-image']} />
<span className={styles['title-name']}>江西省水务集团有限公司 - 智慧水务平台</span>
<img
src={
props.global &&
props.global.transformDevAssetsBaseURL &&
props.global.transformDevAssetsBaseURL(props.global.logo)
}
alt=""
className={styles['title-image']}
/>
<span className={styles['title-name']}>{props.global.title}</span>
</div>
<div className={styles['inner-center']}>
<div className={styles['welcome-title']}>
<div
className={classnames(styles.tabItem, { [styles.tabActive]: loginType === '4a平台' })}
onClick={() => setLoginType('4a平台')}
className={classnames(styles.tabItem, { [styles.tabActive]: loginType === 'OA账号' })}
onClick={() => tabChange('OA账号')}
>
4a平台
OA账号
</div>
<div
className={classnames(styles.tabItem, { [styles.tabActive]: loginType === '熊猫平台' })}
onClick={() => setLoginType('熊猫平台')}
className={classnames(styles.tabItem, { [styles.tabActive]: loginType === '平台账号' })}
onClick={() => tabChange('平台账号')}
>
熊猫平台
平台账号
</div>
</div>
<div className={classnames(styles['inner-bg'], styles['login-part'])} ref={loginFormRef}>
......@@ -198,10 +214,13 @@ const Login = forwardRef((props, _ref) => {
</div>
</div>
</div>
<div className={styles.linkBox} onClick={toLink}>
<img src={require('./images/9.png')} alt="" />
APP下载
</div>
<Tooltip title="打开网站下载">
<div className={styles.linkBox} onClick={toLink}>
<img src={require('./images/9.png')} alt="" />
APP下载
</div>
</Tooltip>
<Modal centered visible={visible} width={340} footer={null} closable={false} bodyStyle={{ padding: '15px' }}>
<div ref={sliVerify} />
</Modal>
......
.lvchenglogin {
width: 100%;
height: 100%;
......@@ -44,13 +43,12 @@
}
.title-image {
width: 59px;
width: 75px;
margin-right: 20px;
}
.title-name {
font-size: 36px;
font-weight: 400;
color: #FFFFFF;
text-shadow: 0px 1px 5px rgba(6, 27, 54, 0.8);
......
import { Checkbox } from 'antd';
import React, { useRef } from 'react';
import { useIntl } from '@wisdom-utils/components';
import LoginForm from './LoginForm';
import LoginMessage from '../../../js/loginMessage';
/* eslint-disable */
const { UserName, Password, Submit } = LoginForm;
const useAccount = props => {
const formRef = useRef(null);
return (
<LoginForm onSubmit={props.onSubmit} welcome={props.welcome} ref={formRef} form={props.form}>
{props.status === 'error' && props.type === 'account' && !props.submitting && (
<LoginMessage
content={useIntl().formatMessage({
id: 'pages.login.accountLogin.errorMessage',
})}
/>
)}
<UserName
name="userName"
placeholder={useIntl().formatMessage({
id: 'pages.login.username.placeholder',
})}
rules={[
{
required: true,
message: useIntl().formatMessage({
id: 'pages.login.username.required',
}),
},
]}
/>
<Password
name="password"
placeholder={useIntl().formatMessage({
id: 'pages.login.password.placeholder',
})}
rules={[
{
required: true,
message: useIntl().formatMessage({
id: 'pages.login.password.required',
}),
},
]}
/>
<div>
<Checkbox checked={props.autoLogin} onChange={e => props.setAutoLogin(e.target.checked)}>
{useIntl().formatMessage({ id: 'pages.login.rememberMe' })}
</Checkbox>
</div>
<Submit loading={props.submitting}>{useIntl().formatMessage({ id: 'pages.login.submit' })}</Submit>
</LoginForm>
);
};
export default useAccount;
import React, { forwardRef, useImperativeHandle, useEffect } from 'react';
import { Form } from 'antd';
import classNames from 'classnames';
import { useIntl } from '@wisdom-utils/components';
import styles from '../../../components/Login/index.less';
import LoginContext from '../../../components/Login/LoginContext';
import LoginItem from '../../../components/Login/LoginItem';
import LoginSubmit from '../../../components/Login/LoginSubmit';
const Login = (props, ref) => {
const intl = useIntl();
const { className } = props;
const otherChildren = [];
React.Children.forEach(props.children, child => {
if (!child) {
return;
}
otherChildren.push(child);
});
return (
<LoginContext.Provider value={{}}>
<div className={classNames(className, styles.login)}>
{props.welcome === void 0 ? (
<div className={styles.desc}>{intl.formatMessage({ id: 'pages.login.welcome' })}</div>
) : (
props.welcome
)}
<Form
form={props.form}
onFinish={values => {
if (props.onSubmit) {
props.onSubmit(values);
}
}}
>
{props.children}
</Form>
</div>
</LoginContext.Provider>
);
};
Login.Submit = LoginSubmit;
Login.UserName = LoginItem.UserName;
Login.Password = LoginItem.Password;
Login.NewYearPassword = LoginItem.NewYearPassword;
Login.Mobile = LoginItem.Mobile;
Login.Captcha = LoginItem.Captcha;
Login.NewYearMobile = LoginItem.NewYearMobile;
Login.NewYearCaptcha = LoginItem.NewYearCaptcha;
export default Login;
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.
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.
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.
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.
This diff is collapsed.
@font-face {
font-family: PingFang SC;
src: url('@/assets/fonts/PingFang.ttf');
}
.lvchenglogin {
width: 100%;
height: 100%;
background-size: 100% 100%;
background-clip: border-box;
position: relative;
min-height: 7.0rem;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
.lbt{
width: 100vw;
height:108px;
background-color: rgba(0,0,0,0.4);
// border: 1px solid #000000;
/// opacity: 0.6;
position: absolute;
/* top: 10px; */
bottom: 89px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 70px;
}
.divImgAll{
width: calc(100% - 44px);
// width: calc(100% - 200px);
// display: flex;
.divT{
// width: 60px;
// height: 60px;
// background-color: white;
margin: 0px 30px;
cursor: 'pointer'
}
}
.inner-bg {
width: 100%;
// height: 100%;
&>div {
width: 70%;
margin: 0 auto;
}
}
.inner-wrapper {
position: relative;
width: 100%;
// height: 380px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border-radius: 10px;
margin-top: -100px;
// margin-bottom: 100px;
}
.title-image-box {
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 160px;
font-size: 44px;
font-family: Alibaba PuHuiTi;
font-weight: 500;
color: #FFFFFF;
line-height: 91px;
// text-shadow: 0px 1px 5px rgba(6,27,54,0.8);
}
.title-image {
width: 75px;
margin-right: 20px;
}
.title-name {
font-size: 36px;
font-family: PingFang SC;
font-weight: 500;
color: #000000;
text-shadow: 0px 1px 5px rgba(6, 27, 54, 0.8);
letter-spacing: 2px;
font-family: Alibaba PuHuiTi;
font-weight: 500;
color: #FFFFFF;
line-height: 91px;
text-shadow: 0px 1px 5px rgba(6,27,54,0.8);
}
.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-center {
position: relative;
width: 600px;
// height: 316px;
// background: rgba(255,255,255, 0.3);
// border: 1px solid #FFFFFF;
// box-shadow: 0px 15px 15px 3px rgba(140,142,145,0.52);
border-radius: 10px;
background: rgba(255, 255, 255, 0.5);
border-radius: 15px 15px 15px 15px;
box-shadow: 0px 6px 18px 0px rgb(25 61 79 / 35%);
padding: 20px 0;
top: -57px;
height: 360px;
padding-top: 10px;
}
.welcome-title {
width: 100%;
height: 50px;
// background: linear-gradient(0deg, rgba(9, 128, 238, 1) 0%, rgba(0, 182, 251, 1) 100%);
border-radius: 10px 10px 0 0;
padding: 16px;
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 25px;
.tabItem {
padding: 5px 15px;
cursor: pointer;
text-align: center;
font-size: 20px;
font-weight: bold;
// color: white;
color: #838383;
margin-left: 15px;
}
.tabActive {
border-bottom: 3px solid #1E77D3;
color: #080A10;
}
}
.welcome-img {
width: 480px;
}
.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 {
width: 100%;
position: absolute;
top: 0;
height: 90px;
padding: 0 70px;
display: flex;
justify-content: flex-end;
align-items: center;
// box-shadow: 0px 1px 3px 0px rgba(235, 235, 235, 0.55);
.left-title {
display: flex;
justify-content: center;
align-items: center;
.cn-title {
font-size: 28px;
font-family: PingFang SC;
font-weight: 400;
color: #FFFFFF;
}
.logo-png {
width: 54px;
margin-right: 20px;
}
}
.right-timebox {
display: flex;
justify-content: center;
align-items: center;
height: 60px;
.curr-time {
width: 154px;
font-size: 36px;
// font-family: Microsoft YaHei;
font-weight: 300;
color:white;
font-family: Alibaba PuHuiTi;
font-weight: 500;
color: #FFFFFF;
// line-height: 91px;
text-shadow: 0px 1px 5px rgba(6,27,54,0.8);
}
.curr-week-date {
margin-left: 10px;
.curr-week {
font-size: 16px;
// font-family: Microsoft YaHei;
font-weight: 400;
color:white;
color:white;
font-family: Alibaba PuHuiTi;
font-weight: 500;
color: #FFFFFF;
// line-height: 91px;
text-shadow: 0px 1px 5px rgba(6,27,54,0.8);
}
.curr-date {
font-size: 14px;
// font-family: Microsoft YaHei;
font-weight: 400;
color:white;
color:white;
font-family: Alibaba PuHuiTi;
font-weight: 500;
color: #FFFFFF;
// line-height: 91px;
text-shadow: 0px 1px 5px rgba(6,27,54,0.8);
}
}
}
}
.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: -23px;
width: 23px;
height: 23px;
background: #FFFFFF;
opacity: 0.8;
cursor: pointer;
}
.linkBox {
position: absolute;
flex-direction: column;
align-items: center;
left: 50%;
transform: translateX(-50%);
bottom: 100px;
color: #108CEE;
font-size: 15px;
cursor: pointer;
top: 307px;
img {
width: 35px;
margin-bottom: 5px;
}
}
}
:global {
.popover-style {
.@{ant-prefix}-popover-inner-content {
display: flex;
justify-content: center;
align-items: center;
}
.@{ant-prefix}-popover-title {
display: flex;
justify-content: center;
align-items: center;
}
}
}
@keyframes waving {
from {
top: 0;
}
to {
top: 10px;
}
}
@keyframes waving2 {
from {
left: 0;
}
to {
left: -9999px;
}
}
.CarouselRipples {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 1;
}
& :global {
.CarouselRipples:before {
content: '';
display: inline-block;
vertical-align: middle;
height: 100%;
}
}
\ 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 React, { forwardRef, useEffect, useRef, useState } from 'react';
import { Modal } 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 QRCode from 'qrcode.react';
import classnames from 'classnames';
import moment from 'moment';
import defaultSetting from '../../../../../../../config/defaultSetting';
import LoginAction from '../../../login';
import styles from './index.less';
import Account from '../../../js/useAccount';
import { defaultApp } from '../../../../../../micro';
import imagelogo from './images/logo@2x.png';
const renderQRCode = () => {
const qrcodes = window.globalConfig && window.globalConfig.qrcode;
console.log('qrcodes', qrcodes);
if (qrcodes) {
return (
<div>
<QRCode value={qrcodes} />
<p>扫码下载APP</p>
</div>
);
}
return <span>手持APP下载未配置</span>;
};
const Login = 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 [action, setAction] = useState(() => new LoginAction(Object.assign({}, props, { history }), setVisible, false));
const [dateObj, setDateObj] = useState({});
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(() => {
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} />;
};
/* eslint-disable */
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={classnames(styles.login, 'WXlogin')}>
<div className={styles['inner-wrapper']}>
<div className={styles['left-imgbox']}></div>
<div className={styles['inner-center']}>
<div className={styles['welcome-title']}></div>
<div className={classnames(styles['inner-bg'], styles['login-part'])} ref={loginFormRef}>
{renderPlatform()}
</div>
{/* <div className={styles.WXqrcodeBox}>
<p className={styles.WXimg}></p>
<div className={styles.WXbigImg}>{renderQRCode()}</div>
</div> */}
</div>
</div>
<div className={styles['login-header']}>
<div className={styles['left-title']}>
{/* <p className={styles.WXlogoImg}></p> */}
<img className={styles.WXlogoImg} src={imagelogo} ></img>
{/* <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>
<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(Login));
:global {
.WXlogin {
.@{ant-prefix}-input-affix-wrapper {
border: none;
border-bottom: 1px solid #D1DCEB;
}
.@{ant-prefix}-input-prefix {
margin-right: 16px;
}
.panda-console-basesrc-pages-user-login-components-login-index-prefixIcon {
font-size: 18px;
}
.panda-console-basesrc-pages-user-login-components-login-index-submit {
border-radius: 20px;
width: 200px;
margin-top: 30px;
}
.panda-console-base-form-item-control-input-content {
text-align: center;
}
}
}
.login {
width: 100%;
height: 100%;
background: url('./images/登陆背景图.png') no-repeat center;
background-size: 100% 100%;
background-clip: border-box;
position: relative;
min-height: 7.0rem;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
}
.login .inner-bg {
width: 100%;
height: 50%;
&>div {
width: 70%;
margin: 0 auto;
}
}
.inner-wrapper {
width: 1100px;
height: 650px;
display: flex;
justify-content: center;
align-items: center;
border-radius: 10px;
background: url('./images/登录框@2x.png') no-repeat center;
background-size: 100% 100%;
background-clip: border-box;
margin-top: 50px;
// position: absolute;
// top: 46%;
// right: 0;
// transform: translateY(-50%);
}
.left-imgbox {
width: 700px;
height: 100%;
}
// .img-wrapper {
// width: 388px;
// height: 134px;
// background: url('./images/1.png') no-repeat center;
// background-size: 100% 100%;
// margin-bottom: 48px;
// }
.login .inner-bg img[role="logo"] {
height: 40px;
}
.login .inner-bg .title {
font-size: 27px;
font-weight: bold;
color: rgba(255, 255, 255, 1);
letter-spacing: 2px;
}
@keyframes waving {
from {
top: 0;
}
to {
top: 10px;
}
}
@keyframes waving2 {
from {
left: 0;
}
to {
left: -9999px;
}
}
.form-control:focus {
border-color: #66afe9;
outline: 0;
-webkit-box-shadow: none;
box-shadow: none;
}
.inner-center {
width: 400px;
height: 82%;
background-color: #ffffff;
display: flex;
flex-flow: column;
align-items: center;
border-radius: 0 10px 10px 0;
position: relative;
}
.WXqrcodeBox {
position: absolute;
background: rgba(255, 255, 255, 0.5);
border-radius: 0px 5px 5px 0px;
padding: 7px;
bottom: 20px;
right: -36px;
}
.WXqrcodeBox:hover {
right: -142px;
}
.WXqrcodeBox:hover .WXimg {
display: none;
}
.WXqrcodeBox:hover .WXbigImg {
display: block;
}
.welcome-title {
width: 113px;
height: 113px;
line-height: 115px;
font-size: 21px;
font-family: Microsoft YaHei;
font-weight: 400;
color: #000000;
opacity: 0.85;
background: url('./images/logo.png');
background-size: 100%;
background-repeat: no-repeat;
margin: 80px 0 30px 0;
}
.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;
}
.APPcodeBox:hover .APPCtext {
color: #1685FF;
}
.APPcodeBox:hover .APPCimg {
display: flex;
}
.APPCimg .codeCase {
text-align: center;
padding-top: 32px;
}
.WXlogoImg {
width: 575px;
// height: 40px;
// background: url('./images/logo@2x.png') no-repeat center;
// background-size: 100% 100%;
// margin: 0 10px 0 0;
}
.login-header {
width: 100%;
position: absolute;
top: 10px;
padding: 0 38px;
display: flex;
justify-content: space-between;
align-items: center;
.left-title {
display: flex;
align-items: center;
.cn-title {
font-size: 26px;
font-family: Microsoft YaHei;
font-weight: 400;
color: #FFFFFF;
text-shadow: 0px 2px 2px rgb(6 15 49 / 33%);
}
}
.right-timebox {
display: flex;
justify-content: center;
align-items: center;
height: 60px;
.curr-time {
width: 150px;
font-size: 36px;
font-family: Microsoft YaHei;
font-weight: 400;
color: white;
}
.curr-week-date {
margin-left: 10px;
.curr-week {
font-size: 16px;
font-family: Microsoft YaHei;
font-weight: 400;
color: white;
}
.curr-date {
font-size: 14px;
font-family: Microsoft YaHei;
font-weight: 400;
color: white;
}
}
}
}
\ No newline at end of file
This diff is collapsed.
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