Commit 6f7cb50e authored by 程恺文's avatar 程恺文
parents 0dac1009 74c00cba
Pipeline #67124 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
......@@ -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') ||
......
......@@ -106,16 +106,17 @@
"@babel/polyfill": "7.4.3",
"@babel/runtime": "^7.10.5",
"@esri/calcite-colors": "6.0.3",
"@wisdom-cesium/cesium": "^1.1.4",
"@wisdom-cesium/cesium": "^1.1.6",
"@wisdom-cesium/krpano": "1.0.29-20",
"@wisdom-components/basictable": "^1.5.16",
"@wisdom-components/empty": "^1.4.1",
"@wisdom-map/amap": "1.1.0-beta.42",
"@wisdom-map/arcgismap": "1.4.0-84",
"@wisdom-map/basemap": "1.1.0-17",
"@wisdom-map/amap": "1.1.0-beta.47",
"@wisdom-map/arcgismap": "1.4.0-120",
"@wisdom-map/basemap": "1.1.0-21",
"@wisdom-map/util": "^1.0.28-0",
"@wisdom-utils/components": "0.1.279",
"@wisdom-utils/runtime": "0.0.32",
"@wisdom-utils/utils": "0.1.319",
"@wisdom-utils/components": "0.1.287",
"@wisdom-utils/runtime": "0.0.38",
"@wisdom-utils/utils": "0.1.327",
"animate.css": "^4.1.1",
"antd": "4.21.2",
"compression": "1.7.4",
......@@ -142,6 +143,7 @@
"qiankun": "^2.4.6",
"qrcode.react": "^1.0.0",
"rc-cascader": "^2.3.2",
"rc-queue-anim": "^2.0.0",
"react": "17.0.2",
"react-activation": "^0.9.9",
"react-dom": "17.0.2",
......
......@@ -14,6 +14,9 @@
},
{
"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)) {
......
import { request } from '@wisdom-utils/utils';
import * as constants from '../../constants';
const API = {
GET_INFORMATION:
'/PandaCore/GCK/Message/GetInformationInfo',
GET_MQTT_SITE_CODE:
'/PandaOMS/OMS/HostManager/GetEmqtConfig',
GET_ALL_INFORMATION_INFO:
'/PandaCore/GCK/Message/GetAllInformationInfo',
POST_INFORMATION_STATUS:
'/PandaCore/GCK/Message/PostInformationStatus',
POST_ADD_OPTIONS:
'/CityInterface/rest/services/WisdomUnion.svc/CustomerManage/AddOption',
GET_CURRENT_INFO_TYPE:
'/PandaCore/GCK/Message/GetCurrentInfoType',
GET_INFORMATION: '/PandaCore/GCK/Message/GetInformationInfo',
GET_INFORMATION_THREE: '/PandaOMS/OMS/MessageConfig/GetInformationInfo',
GET_MQTT_SITE_CODE: '/PandaOMS/OMS/HostManager/GetHostConfig',
GET_ALL_INFORMATION_INFO: '/PandaCore/GCK/Message/GetAllInformationInfo',
GET_ALL_INFORMATION_INFO_THREE: '/PandaOMS/OMS/MessageConfig/GetAllInformationInfo',
POST_INFORMATION_STATUS: '/PandaCore/GCK/Message/PostInformationStatus',
POST_ADD_OPTIONS: '/CityInterface/rest/services/WisdomUnion.svc/CustomerManage/AddOption',
GET_CURRENT_INFO_TYPE: '/PandaCore/GCK/Message/GetCurrentInfoType',
};
const notificationService = {
......@@ -23,7 +19,8 @@ const notificationService = {
type: constants.REQUEST_HTTP,
},
getInformationInfo: {
url: API.GET_INFORMATION,
url: () =>
window?.globalConfig?.mqtt_mess?.MessageLevel === '3.0' ? API.GET_INFORMATION_THREE : API.GET_INFORMATION,
method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_HTTP,
},
......@@ -33,7 +30,10 @@ const notificationService = {
type: constants.REQUEST_HTTP,
},
getAllInformationInfo: {
url: API.GET_ALL_INFORMATION_INFO,
url: () =>
window?.globalConfig?.mqtt_mess?.MessageLevel === '3.0'
? API.GET_ALL_INFORMATION_INFO_THREE
: API.GET_ALL_INFORMATION_INFO,
method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_HTTP,
},
......@@ -49,5 +49,4 @@ const notificationService = {
},
};
export default notificationService;
This diff was suppressed by a .gitattributes entry.
......@@ -23,6 +23,7 @@ const ValidContainer = props => {
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);
......@@ -36,7 +37,7 @@ const ValidContainer = props => {
const tk = global.token;
// eslint-disable-next-line no-eval
if (tk) {
if (check && check === true) {
if (rules !== '' && check && check === accessToken) {
setNeedChangePassword(true);
}
}
......
......@@ -314,7 +314,7 @@ class NoticeIconView extends Component {
this.renderSysPlatform(message);
};
handlerUnknowDetail = message => {
handlerUnknowDetail = (message, type) => {
// 需要有跳转路径
if (!message.webPath)
return notification.info({ message: '提示', duration: 3, description: '未配置跳转路径' });
......@@ -343,8 +343,11 @@ class NoticeIconView extends Component {
}
params._source = '消息通知';
params._target = message.webPath;
if (type) {
if (/civweb4/.test(targetMenuPath)) return true;
}
sessionStorage.setItem('routerParams', JSON.stringify(params));
window.history.pushState(params, '', `/civbase/${targetMenuPath}`);
window.history.pushState(params, '', `/civbase/${targetMenuPath}?v=${Date.now()}`);
}
render() {
......
import React, {
useRef,
useState,
} from 'react';
import React, { useRef, useState } from 'react';
import {
message,
Popover,
} from 'antd';
import { message, Popover } from 'antd';
import _ from 'lodash';
import { connect } from 'react-redux';
import Icon from '@ant-design/icons';
import {
AvatarDropdown as Avatar,
useIntl,
} from '@wisdom-utils/components';
import { AvatarDropdown as Avatar, useIntl } from '@wisdom-utils/components';
import HeaderSearch from '@wisdom-utils/components/lib/layout/components/HeaderSearch';
import { useHistory } from '@wisdom-utils/runtime';
......@@ -112,7 +103,7 @@ const GlobalHeaderRight = props => {
const handleFeedback = event => {
event.stopPropagation();
window.open(`https://mis.panda-water.cn/feedback/?site_code="${props.global.get('userInfo.site')}`);
window.open(`https://work.panda-water.cn/feedback/?site_code=${props.global.get('userInfo.site')}`);
}
const handlerFavitor = event => {
......
......@@ -18,7 +18,6 @@ const App = props => {
useEffect(() => {
event.emit('loading', props.loading);
}, [props.loading]);
const metaSecurity = /https/.test(window.location.protocol) ? (
<meta httpEquiv="Content-Security-Policy" content="upgrade-insecure-requests" />
) : null;
......
import { fromJS } from 'immutable';
import Cookies from 'js-cookie';
import { AppConfig, store, event, Storage, helpers } from '@wisdom-utils/utils';
import { Storeage as Store } from '@wisdom-utils/utils/lib/helpers';
import { params, Storeage as Store } from '@wisdom-utils/utils/lib/helpers';
import defaultSetting from '@wisdom-utils/components/lib/AppLayout/layouts/defaultSettings';
import _ from 'lodash';
import memoized from 'nano-memoize';
......@@ -42,7 +42,11 @@ const proxy = require('../../../../config/proxy');
const keywordStorage = new Storage(`__global_search_keywords__micro_${window.location.hostname}`);
const recentVisitedStorage = new Storage(`__global_recent_visited__micro_${window.location.hostname}`);
const recentProductStorage = new Storage(`__global__recent_product__micro_${window.location.hostname}`);
const currentProduct = new Store(`__global__recent_productIndex__micro_${window.location.hostname}`);
const currentProduct = new Store(
`__global__recent_productIndex__micro_${window.location.hostname}_${params.getParams('client') ||
sessionStorage.getItem('client') ||
'city'}`,
);
Cookies.set('loginMode', Cookies.get('loginMode') || 'pdw');
export const initialState = fromJS({
globalConfig: {},
......
......@@ -7,7 +7,9 @@ body,
height: 100%;
overflow: hidden;
}
#app {
background: transparent!important;
}
* {
margin: 0;
padding: 0;
......
......@@ -2,14 +2,16 @@ import { request } from '@wisdom-utils/utils';
import * as constants from '@wisdom-utils/components/lib/AppLayout/helpers/constants';
const API = {
GET_INFORMATION: '/PandaCore/GCK/Message/GetInformationInfo',
GET_MQTT_SITE_CODE: '/PandaOMS/OMS/HostManager/GetEmqtConfig',
GET_INFORMATION_THREE: '/PandaOMS/OMS/MessageConfig/GetInformationInfo',
GET_MQTT_SITE_CODE: '/PandaOMS/OMS/HostManager/GetHostConfig',
POST_INFORMATION_STATUS: '/PandaCore/GCK/Message/PostInformationStatus',
POST_ADD_OPTIONS: '/CityInterface/rest/services/WisdomUnion.svc/CustomerManage/AddOption',
};
const services = {
getInformationInfo: {
url: API.GET_INFORMATION,
url: () =>
window?.globalConfig?.mqtt_mess?.MessageLevel === '3.0' ? API.GET_INFORMATION_THREE : API.GET_INFORMATION,
method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_HTTP,
},
......@@ -30,7 +32,7 @@ const services = {
},
};
export const postInformationStatus = (param) =>
export const postInformationStatus = param =>
request({
url: API.POST_INFORMATION_STATUS,
method: constants.REQUEST_METHOD_GET,
......
......@@ -4,8 +4,7 @@ export const API = {
IOT_CHANGE_PASSWORD: 'CityInterface/rest/services/OMS.svc/U_UpdatePasswordQuickGCK',
FILE_DOWNLOAD: '/cityinterface/rest/services/filedownload.svc/download',
UPDATE_AVATAR: '/CityInterface/rest/services/OMs.svc/U_EditUser',
UPLOAD_FILE_URL:
'/cityinterface/rest/services/filedownload.svc/uploadfile/个人信息/{path}/{filename}',
UPLOAD_FILE_URL: '/cityinterface/rest/services/filedownload.svc/uploadfile/个人信息/{path}/{filename}',
AVATAR_FILE_URL: '/cityinterface/rest/services/filedownload.svc/download',
GET_VERSION: '/CityInterface/rest/services/OMs.svc/U_GetVersion',
};
......
......@@ -17,7 +17,6 @@ export const MESSAGE_TYPE = {
export const NEW_MESSAGE = 'NEW_MESSAGE';
export const USERNAME = 'mao2080';
export const PASSWORD = '123';
export const PLATFORM_LEVEL = '4';
......
import React from 'react';
import { Badge, Button, ConfigProvider } from 'antd';
// eslint-disable-next-line import/no-unresolved
import classNames from 'classnames';
import useMergeValue from 'use-merge-value';
......@@ -40,8 +41,8 @@ const messageSvg = () => (
/>
</svg>
);
const BellOutlined = (props) => <Icon component={messageSvg} {...props} />;
const NoticeIcon = (props) => {
const BellOutlined = props => <Icon component={messageSvg} {...props} />;
const NoticeIcon = props => {
const { getPrefixCls } = React.useContext(ConfigProvider.ConfigContext);
const prefixCls = props.prefixCls || getPrefixCls();
const btnPrefixCls = `${prefixCls}-head-notifier-button`;
......@@ -54,14 +55,12 @@ const NoticeIcon = (props) => {
}
const panes = [];
React.Children.forEach(children, (child) => {
React.Children.forEach(children, child => {
if (!child) {
return;
}
const { list, title } = child.props;
panes.push(
<NoticeList {...child.props} data={list} key={child} title={title} config={props.config} />,
);
panes.push(<NoticeList {...child.props} data={list} key={child} title={title} config={props.config} />);
});
const childProps = panes.length === 1 ? panes[0].props : { list: [] };
return (
......@@ -72,7 +71,9 @@ const NoticeIcon = (props) => {
type="link"
onClick={() => (childProps.list.length > 0 ? confirmRead(true) : null)}
disabled={childProps.list.length === 0}
>全部标记已读</Button>
>
全部标记已读
</Button>
</div>
{panes}
{renderFooter && renderFooter()}
......
import React from 'react';
import { List, Spin, ConfigProvider } from 'antd';
// eslint-disable-next-line import/no-unresolved
import classNames from 'classnames';
import './style/list.less';
import { Alarm, Case, Notice, Unknown } from './templates';
......@@ -11,10 +12,7 @@ const Empty = ({ emptyText, ...props }) => {
const prefixCls = props.prefixCls || getPrefixCls();
return (
<div className={`${prefixCls}-notFound`}>
<img
src="https://gw.alipayobjects.com/zos/rmsportal/sAuJeJzSKbUmHfBQRzmZ.svg"
alt="not found"
/>
<img src="https://gw.alipayobjects.com/zos/rmsportal/sAuJeJzSKbUmHfBQRzmZ.svg" alt="not found" />
<div>{emptyText}</div>
</div>
);
......@@ -113,11 +111,11 @@ class NoticeList extends React.Component {
switch (item.infoClasses) {
case MESSAGE_TYPE.ALARM_TYPE:
messageTemplate = (
<Alarm message={item} confirmRead={this.confirmRead} config={this.props.config} />
<Alarm message={item} confirmRead={this.confirmRead} config={this.props.config} handlerUnknowDetail={this.handlerUnknowDetail} />
);
break;
case MESSAGE_TYPE.CASE_TYPE:
messageTemplate = <Case message={item} confirmRead={this.confirmRead} />;
messageTemplate = <Case message={item} confirmRead={this.confirmRead} handlerUnknowDetail={this.handlerUnknowDetail} />;
break;
case MESSAGE_TYPE.SYS_TYPE:
messageTemplate = (
......
......@@ -12,6 +12,9 @@ class Message {
webConfig,
webPath,
messType,
defaultContent,
webIcon,
title,
infoClasses
} = message) {
this.id = id;
......@@ -23,6 +26,9 @@ class Message {
this.webConfig = webConfig;
this.webPath = webPath;
this.messType = messType; // 方案名称 - 大类型下细类型
this.webIcon = webIcon; // 消息图标
this.title = title; // 消息标题
this.defaultContent = defaultContent;
this.infoClasses = infoClasses;
}
}
......@@ -64,6 +70,9 @@ export const createMessageFromHis = (hisMessage, options = {}) => {
webConfig: hisMessage.web_config,
webPath: hisMessage.web_path,
messType: hisMessage.messType,
defaultContent: (_.isString(hisMessage.defaultContent) && hisMessage.defaultContent.replace(new RegExp(/ /g), "").length > 0) ? hisMessage.defaultContent : null,
webIcon: (_.isString(hisMessage.webIcon) && hisMessage.webIcon.replace(new RegExp(/ /g), "").length > 0) ? hisMessage.webIcon : null,
title: (_.isString(hisMessage.title) && hisMessage.title.replace(new RegExp(/ /g), "").length > 0) ? hisMessage.title : null,
infoClasses,
};
return createMessage(template);
......@@ -90,9 +99,9 @@ export const createMessageFromReal = (realMesssage, options = {}) => {
// 2.0 消息
infoContent = JSON.parse(realMesssage.content || '{}');
}
const template = {
id: realMesssage.infoId,
id: realMesssage.infoId || realMesssage.ID,
infoContent,
time,
infoType: realMesssage.infoType,
......@@ -100,7 +109,10 @@ export const createMessageFromReal = (realMesssage, options = {}) => {
dateTime: realMesssage.createTime,
webConfig: realMesssage.web_config,
webPath: realMesssage.web_path,
messType: realMesssage.messType,
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,
title: (_.isString(realMesssage.title) && realMesssage.title.replace(new RegExp(/ /g), "").length > 0) ? realMesssage.title : null,
infoClasses,
}
......
......@@ -351,6 +351,8 @@ class Notifier {
}
} catch (e) {
Logger.error(`收到消息处理异常:${e.message}`);
} finally {
window?.share?.event?.emit?.('event:messageArrived', buffer);
}
}
......@@ -449,8 +451,8 @@ class Notifier {
const alarmType = message?.infoContent?.alarmType; // 报警类型:“状态报警”
const content = message?.infoContent?.alarmContent; // 报警内容:“出水超压报警”
const alarmValue = message?.infoContent?.alarmValue ?? ''; // 报警值
let msg = `紧急报警:${device},${alarmType},${content},报警值:${isString(alarmValue) ? replaceSpeak(alarmValue) :'' },请注意!!!`;
const level = message?.infoLevel !== '1' ? '紧急报警,紧急报警,紧急报警:' : ''
let msg = `${level}${device},${alarmType},${content},报警值:${isString(alarmValue) ? replaceSpeak(alarmValue) :'' },请注意!!!`;
this.speak(msg);
};
speakCase = message => {
......@@ -473,12 +475,13 @@ class Notifier {
};
speakOther = message => {
// 类型区分‘全员公告’ 还是 ‘个人消息’
const type = isEmpty(message.tousers) || parseMessage.tousers === '' ? '公告' : '消息';
const type = message.title ?? (isEmpty(message.tousers) || parseMessage.tousers === '' ? '公告' : '消息');
// 构建语音消息内容
const { infoContent, time } = message;
let content = replaceSpeak((infoContent?.content ?? '').replace(/\\n/g, ','));
let msg = `您有新的${type}${content.substring(0, content.lastIndexOf(',')).replace(':', ',')} 时间:${time}`;
let content = replaceSpeak((infoContent?.content ?? message.defaultContent ?? '').replace(/\\n/g, ','));
const text = content.substring(0, content.lastIndexOf(',')).replace(':', ',');
let msg = `您有新的${type}${text !== '' ? text : content} 时间:${time}`;
this.speak(msg);
};
......
import React from 'react';
import _ from 'lodash';
// eslint-disable-next-line import/no-unresolved
import classNames from 'classnames';
import { findPathByWidget, isJSON } from '@wisdom-utils/components/lib/AppLayout/helpers';
import '../styles/common.less';
import './index.less';
import { ConfigProvider } from 'antd';
import { getMessageTypeIcon } from '../../utils';
/* eslint-disable */
export class AlarmContent {
constructor({
......@@ -26,7 +28,7 @@ export class AlarmContent {
}
}
const Alarm = ({ message, confirmRead, config }) => {
const Alarm = ({ message, confirmRead, config, handlerUnknowDetail }) => {
const { getPrefixCls } = React.useContext(ConfigProvider.ConfigContext);
const prefixCls = getPrefixCls();
......@@ -39,20 +41,22 @@ const Alarm = ({ message, confirmRead, config }) => {
const alarmThreshold = message?.infoContent?.alarmThreshold;
const goPath = (item) => {
if(handlerUnknowDetail && handlerUnknowDetail(message, 'alarm')) {
const widgetID = 'widget_city_综合运营_管网监控_实时监控_报警监控';
const webPath = 'product/scada/AlertMonitoring/AlertMonitoring';
const widget = findPathByWidget(
'productex/water/IOTMonitor/RealTimeAlarm/RealTimeAlarm',
config.widgets,
'',
'url',
);
window.share.event.emit('listenerMointer', {
widgetId: widgetID,
label: '实时报警',
url: widget.url || webPath,
});
}
confirmRead(false, [message.id]);
const widgetID = 'widget_city_综合运营_管网监控_实时监控_报警监控';
const webPath = 'product/scada/AlertMonitoring/AlertMonitoring';
const widget = findPathByWidget(
'productex/water/IOTMonitor/RealTimeAlarm/RealTimeAlarm',
config.widgets,
'',
'url',
);
window.share.event.emit('listenerMointer', {
widgetId: widgetID,
label: '实时报警',
url: widget.url || webPath,
});
};
......@@ -62,6 +66,7 @@ const Alarm = ({ message, confirmRead, config }) => {
className={classNames(`${prefixCls}-notifier-message_scada`, `${prefixCls}-notifier-message-container`)}
title="点击查看详情"
onClick={() => goPath(message)}
style={{ backgroundImage: `url(${getMessageTypeIcon(message)})` }}
>
<div className={`${prefixCls}-notifier-message-title`}>
<span>{alarmType}</span>
......
import React from 'react';
import { ConfigProvider } from 'antd';
// eslint-disable-next-line import/no-unresolved
import classNames from 'classnames';
import '../styles/common.less';
import './index.less';
import { getMessageTypeIcon } from '../../utils';
// "caseType":"待办工单","flowName":"维修处理流程","nodeName":"审核关单","content":"请迅速到现场处理","time":"2020-11-03 09:11:12"
export class CaseContent {
......@@ -17,7 +19,7 @@ export class CaseContent {
}
}
const Case = ({ message, confirmRead }) => {
const Case = ({ message, confirmRead, handlerUnknowDetail }) => {
const { getPrefixCls } = React.useContext(ConfigProvider.ConfigContext);
const prefixCls = getPrefixCls();
const caseType = message?.infoContent?.caseType;
......@@ -27,34 +29,36 @@ const Case = ({ message, confirmRead }) => {
const content = message?.infoContent?.content;
const goPath = item => {
confirmRead(false, [message.id]);
const messageType = item.messType;
let label = '';
let widgetID = '';
switch (messageType) {
case '任务派发':
label = '任务派发';
widgetID = 'widget_city_综合运营_二供管理_维修管理_工单办理';
break;
case '任务驳回':
label = '任务驳回';
widgetID = 'widget_city_综合运营_二供管理_维修管理_工单办理';
// eslint-disable-next-line no-underscore-dangle,no-case-declarations
let _tab;
// eslint-disable-next-line prefer-const
_tab = '任务驳回';
break;
default:
label = '工单办理';
widgetID = 'widget_city_综合运营_二供管理_维修管理_工单办理';
break;
if (handlerUnknowDetail && handlerUnknowDetail(message, 'case')) {
const messageType = item.messType;
let label = '';
let widgetID = '';
switch (messageType) {
case '任务派发':
label = '任务派发';
widgetID = 'widget_city_综合运营_二供管理_维修管理_工单办理';
break;
case '任务驳回':
label = '任务驳回';
widgetID = 'widget_city_综合运营_二供管理_维修管理_工单办理';
// eslint-disable-next-line no-underscore-dangle,no-case-declarations
let _tab;
// eslint-disable-next-line prefer-const
_tab = '任务驳回';
break;
default:
label = '工单办理';
widgetID = 'widget_city_综合运营_二供管理_维修管理_工单办理';
break;
}
const webPath = item.webPath || 'product/maintenance/CaseManage/CaseDoingBox/StardCaseDoingBoxView|isDelay=1';
window.share.event.emit('listenerMointer', {
widgetId: widgetID,
label,
url: webPath,
});
}
const webPath = item.webPath || 'product/maintenance/CaseManage/CaseDoingBox/StardCaseDoingBoxView|isDelay=1';
window.share.event.emit('listenerMointer', {
widgetId: widgetID,
label,
url: webPath,
});
confirmRead(false, [message.id]);
};
return (
......@@ -62,6 +66,7 @@ const Case = ({ message, confirmRead }) => {
className={classNames(`${prefixCls}-notifier-message_case`, `${prefixCls}-notifier-message-container`)}
title="点击查看详情"
onClick={() => goPath(message)}
style={{ backgroundImage: `url(${getMessageTypeIcon(message)})` }}
>
<div className={`${prefixCls}-notifier-message-title`}>
<span>{caseType}</span>
......@@ -72,7 +77,9 @@ const Case = ({ message, confirmRead }) => {
e.stopPropagation();
confirmRead(false, [message.id]);
}}
// eslint-disable-next-line global-require
src={require('../../images/oper/ok_line.png')}
alt=""
/>
</div>
<div className={`${prefixCls}-notifier-message-content`}>
......
import React from 'react';
import { ConfigProvider } from 'antd';
// eslint-disable-next-line import/no-unresolved
import classNames from 'classnames';
import '../styles/common.less';
import './index.less';
import './index.less';
import { getMessageTypeIcon } from '../../utils';
export class NoticeContent {
// eslint-disable-next-line no-undef
......@@ -15,7 +16,6 @@ export class NoticeContent {
}
}
const Notice = ({ message, confirmRead, config, handlerSysDetail }) => {
const { getPrefixCls } = React.useContext(ConfigProvider.ConfigContext);
const prefixCls = getPrefixCls();
......@@ -25,26 +25,31 @@ const Notice = ({ message, confirmRead, config, handlerSysDetail }) => {
const noticeContent = message?.infoContent?.noticeContent ?? '';
// const remark = message?.infoContent?.remark;
const goPath = (item) => {
const goPath = item => {
confirmRead(false, [message.id]);
handlerSysDetail && handlerSysDetail(message);
};
return (
<div
className={classNames(`${prefixCls}-notifier-message_notice`, `${prefixCls}-notifier-message-container`)}
title="点击查看详情"
onClick={() => goPath(message)}
style={{ backgroundImage: `url(${getMessageTypeIcon(message)})` }}
>
<div className={`${prefixCls}-notifier-message-title`}>
<span>{noticeType}{noticeTitle ? `:${noticeTitle}` : ''}</span>
<span>
{noticeType}
{noticeTitle ? `:${noticeTitle}` : ''}
</span>
<img
className={`${prefixCls}-notifier-message-confirm`}
title="点击标为已读"
onClick={(e) => {
onClick={e => {
e.stopPropagation();
confirmRead(false, [message.id]);
}}
// eslint-disable-next-line global-require
src={require('../../images/oper/ok_line.png')}
alt=""
/>
......@@ -52,7 +57,7 @@ const Notice = ({ message, confirmRead, config, handlerSysDetail }) => {
<div className={`${prefixCls}-notifier-message-content`}>
<p>{noticeContent}</p>
</div>
<p className={`${prefixCls}-notifier-message-time`}>{message.time}</p>
<p className={`${prefixCls}-notifier-message-time`}>{message.time}</p>
</div>
);
};
......
import React from 'react';
import { ConfigProvider } from 'antd';
// eslint-disable-next-line import/no-unresolved
import classNames from 'classnames';
import '../styles/common.less';
......@@ -11,24 +12,23 @@ const Unknown = ({ message, confirmRead, handlerUnknowDetail }) => {
const prefixCls = getPrefixCls();
let content = '';
let noticeTitle = '';
const { infoContent } = message;
try {
const type = typeof message.infoContent;
switch (type) {
case 'object':
let { infoContent } = message;
noticeTitle = infoContent.title || '';
content = infoContent.content || JSON.stringify(message.infoContent);
break;
case 'string':
content = message.infoContent;
noticeTitle = message.title || infoContent.title || '';
content = infoContent.content || message.defaultContent || JSON.stringify(message.infoContent);
break;
default:
noticeTitle = message.title || '';
content = message.defaultContent || message.infoContent;
break;
}
} catch (e) {
// i
}
const goPath = (item) => {
const goPath = item => {
handlerUnknowDetail && handlerUnknowDetail(message);
confirmRead(false, [message.id]);
};
......@@ -37,17 +37,18 @@ const Unknown = ({ message, confirmRead, handlerUnknowDetail }) => {
className={classNames(`${prefixCls}-notifier-message_unknown`, `${prefixCls}-notifier-message-container`)}
title="点击查看详情"
onClick={() => goPath(message)}
style={{backgroundImage: `url(${getMessageTypeIcon(message.messType)})`}}
style={{ backgroundImage: `url(${getMessageTypeIcon(message)})` }}
>
<div className={`${prefixCls}-notifier-message-title`}>
<span>{noticeTitle}</span>
<img
className={`${prefixCls}-notifier-message-confirm`}
title="点击标为已读"
onClick={(e) => {
onClick={e => {
e.stopPropagation();
confirmRead(false, [message.id]);
}}
// eslint-disable-next-line global-require
src={require('../../images/oper/ok_line.png')}
alt=""
/>
......
import { MESSAGE_TYPE } from '../constants';
import parseMessageToJSON from './parse';
import alarm_icon from '../images/types/alarm.png';
import approve_icon from '../images/types/approve.png';
import meeting_icon from '../images/types/meeting.png';
import notice_icon from '../images/types/notice.png';
import task_icon from '../images/types/task.png';
import work_icon from '../images/types/work.png';
import write_icon from '../images/types/write.png';
import other_icon from '../images/types/other.png';
import alarmIcon from '../images/types/alarm.png';
import approveIcon from '../images/types/approve.png';
import meetingIcon from '../images/types/meeting.png';
import noticeIcon from '../images/types/notice.png';
import taskIcon from '../images/types/task.png';
import workIcon from '../images/types/work.png';
import writeIcon from '../images/types/write.png';
import otherIcon from '../images/types/other.png';
export const getMessageTypeIcon = messageType => {
let icon = other_icon;
export const getMessageTypeIcon = message => {
const { webIcon } = message;
if (webIcon) return `${window.location.origin}/${webIcon}`;
const { messageType, infoType } = message;
let icon = otherIcon;
if (infoType === '通用报警') {
icon = alarmIcon;
} else if (infoType === '系统通知') {
icon = noticeIcon;
} else if (infoType === '工单提醒') {
icon = workIcon;
}
if (!messageType) return icon;
if (messageType === '工时填报') {
icon = write_icon;
icon = writeIcon;
} else if (messageType.indexOf('审批') > -1) {
icon = approve_icon;
icon = approveIcon;
} else if (messageType.indexOf('会议') > -1) {
icon = meeting_icon;
icon = meetingIcon;
} else if (messageType.indexOf('任务') > -1) {
icon = task_icon;
icon = taskIcon;
}
return icon;
};
export const getMessageClasses = messageType => {
let infoType = '';
switch (messageType) {
// 报警类
case 'SCADA报警':
case '通用报警':
infoType = MESSAGE_TYPE.ALARM_TYPE;
break;
// 工单类
case '工单流程':
case '工单提醒':
infoType = MESSAGE_TYPE.CASE_TYPE;
break;
// 系统消息类
case '系统通知':
case '系统消息':
infoType = MESSAGE_TYPE.SYS_TYPE;
break;
// 其他类
default:
infoType = MESSAGE_TYPE.UNKNOWN;
break;
}
return infoType;
let infoType = '';
switch (messageType) {
// 报警类
case 'SCADA报警':
case '通用报警':
infoType = MESSAGE_TYPE.ALARM_TYPE;
break;
// 工单类
case '工单流程':
case '工单提醒':
infoType = MESSAGE_TYPE.CASE_TYPE;
break;
// 系统消息类
case '系统通知':
case '系统消息':
infoType = MESSAGE_TYPE.SYS_TYPE;
break;
// 其他类
default:
infoType = MESSAGE_TYPE.UNKNOWN;
break;
}
return infoType;
};
/**
* 消息语音单位转换
* 说明:消息通过语音播放时,需要将一些字母单位转换成文字,不然会当做字母播放。
......@@ -76,16 +82,17 @@ export const replaceSpeak = msg => {
return msg;
};
// eslint-disable-next-line arrow-body-style
export const generatedId = () => {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
.replace(/[xy]/g, function(c) {
// eslint-disable-next-line no-bitwise
const r = (Math.random() * 16) | 0;
// eslint-disable-next-line no-bitwise
const v = c === 'x' ? r : (r & 0x3) | 0x8;
return v.toString(16);
})
.toUpperCase();
};
export {
parseMessageToJSON,
}
\ No newline at end of file
export { parseMessageToJSON };
// @eslint-disable
import React, {
Suspense,
useEffect,
useRef,
useState,
} from 'react';
import React, { Suspense, useEffect, useRef, useState } from 'react';
import {
Anchor,
Popover,
Radio,
Spin,
} from 'antd';
import { Anchor, Popover, Radio, Spin } from 'antd';
import classNames from 'classnames';
import Cookies from 'js-cookie';
import _ from 'lodash';
......@@ -19,23 +9,16 @@ import memoized from 'nano-memoize';
import KeepAlive from 'react-activation';
import { connect } from 'react-redux';
import { matchRoutes } from 'react-router-dom';
import Loading from '../components/Loading';
import RightContent from '@/components/GlobalHeader/SimpleRiightContent';
import defaultSetting from '@wisdom-utils/components/lib/AppLayout/layouts/defaultSettings';
// import SettingDrawer from '@wisdom-utils/components/lib/layout/components/SettingDrawer';
import { actionCreators } from '@/containers/App/store';
import Icon, { LoadingOutlined } from '@ant-design/icons';
import BasicLayout from '@wisdom-utils/components/lib/layout/BasicLayout';
import {
useHistory,
useLocation,
} from '@wisdom-utils/runtime';
import {
helpers,
store,
event
} from '@wisdom-utils/utils';
import { useHistory, useLocation } from '@wisdom-utils/runtime';
import { helpers, store, event } from '@wisdom-utils/utils';
import { Storeage as Store } from '@wisdom-utils/utils/lib/helpers';
import Loading from '../components/Loading';
import { waterMark } from '../utils/mark';
import layoutStyles from './BasicLayout.less';
......@@ -49,28 +32,26 @@ const { getParamsV1 } = params;
// const AMap = React.lazy(() => import('../pages/map/amap'));
const CesiumMap = React.lazy(() => import('../pages/map/cesiumMap'));
const waitTime = (time = 100) => {
return new Promise((resolve) => {
const waitTime = (time = 100) =>
new Promise(resolve => {
setTimeout(() => {
resolve(true);
}, time);
});
};
const antIcon = <LoadingOutlined style={{ fontSize: 12 }} spin />;
const arrowSvg = ({ fillColor = '#fff' }) => (
<svg
t='1543324489942'
className='icon'
viewBox='0 0 1024 1024'
version='1.1'
xmlns='http://www.w3.org/2000/svg'
width='16'
height='16'
t="1543324489942"
className="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
>
<path
d='M511.700683 639.423111 191.917496 319.596945 319.830771 319.596945 511.700683 511.715521 703.570595 319.596945 831.48387 319.596945Z'
p-id='8626'
d="M511.700683 639.423111 191.917496 319.596945 319.830771 319.596945 511.700683 511.715521 703.570595 319.596945 831.48387 319.596945Z"
p-id="8626"
// fill={fillColor}
/>
</svg>
......@@ -102,9 +83,15 @@ const StationsItem = (item, action, onChangeVisible, actionRef, setMenuLoading)
const OnlyFocusStations = props => {
const data = props.data.stations;
return (
<Spin spinning={props.loading} tip='加载中' size='small'>
<Spin spinning={props.loading} tip="加载中" size="small">
<div className={layoutStyles.focusStations} style={{ border: 'none' }}>
<ul>{Array.isArray(data) ? data.map(item => StationsItem(item, props.action, props.setVisible, props.actionRef, props.setMenuLoading)) : null}</ul>
<ul>
{Array.isArray(data)
? data.map(item =>
StationsItem(item, props.action, props.setVisible, props.actionRef, props.setMenuLoading),
)
: null}
</ul>
</div>
</Spin>
);
......@@ -128,15 +115,21 @@ const AllStations = props => {
setDefaultTab(event.target.value);
};
return (
<Spin spinning={props.loading} tip='加载中'>
<Spin spinning={props.loading} tip="加载中">
<div className={layoutStyles.focusStations}>
<ul>{Array.isArray(data) ? data.map(item => StationsItem(item, props.action, props.setVisible, props.actionRef, props.setMenuLoading)) : null}</ul>
<ul>
{Array.isArray(data)
? data.map(item =>
StationsItem(item, props.action, props.setVisible, props.actionRef, props.setMenuLoading),
)
: null}
</ul>
</div>
<Radio.Group
options={optionsWith}
optionType='button'
buttonStyle='solid'
size='small'
optionType="button"
buttonStyle="solid"
size="small"
value={defaultTab}
onChange={handleTabChange}
style={{ marginTop: '6px' }}
......@@ -159,7 +152,7 @@ const AllStations = props => {
</Anchor>
</div>
) : (
<div className='city_pane city_container'>{props.data.citySelector}</div>
<div className="city_pane city_container">{props.data.citySelector}</div>
)}
</div>
</Spin>
......@@ -181,26 +174,32 @@ const renderSite = ({ data, config, loading, setLoading, action, actionRef, setM
if (config && config.userInfo && config.userInfo.site === '') {
loaded = false;
}
if (!data.allStation || !_.isArray(data.allStation) || data.allStation.length <= 1)
return <></>;
if (!data.allStation || !_.isArray(data.allStation) || data.allStation.length <= 1) return <></>;
return (
<>
<Spin
indicator={antIcon}
spinning={loaded}
size='small'
size="small"
style={{ marginLeft: '10px' }}
tip=''
tip=""
wrapperClassName={layoutStyles.spinLoadding}
>
<>
<Popover
placement='bottomLeft'
trigger='click'
placement="bottomLeft"
trigger="click"
visible={visible}
content={
<Stations data={data} loading={loading} setLoading={setLoading} setVisible={setVisible} action={action}
actionRef={actionRef} setMenuLoading={setMenuLoading} />
<Stations
data={data}
loading={loading}
setLoading={setLoading}
setVisible={setVisible}
action={action}
actionRef={actionRef}
setMenuLoading={setMenuLoading}
/>
}
arrowPointAtCenter
overlayClassName={classNames(layoutStyles.stationsWrapper, layoutStyles.stationsTop)}
......@@ -228,7 +227,6 @@ const renderSite = ({ data, config, loading, setLoading, action, actionRef, setM
// import defaultProps from '../defaultProps';
const pickRoutes = memoized((routes, pathname, locale) => {
const matches = matchRoutes(routes, { pathname });
const routeConfig = matches ? matches[matches.length - 1].route : null;
......@@ -246,8 +244,12 @@ const transformFloatMenu = (routes, homepage) => {
return routes.concat(route);
};
const Layout = (props) => {
const currentProduct = new Store(`__global__recent_productIndex__micro_${window.location.hostname}`);
const Layout = props => {
const currentProduct = new Store(
`__global__recent_productIndex__micro_${window.location.hostname}_${params.getParams('client') ||
sessionStorage.getItem('client') ||
'city'}`,
);
const menuState = sessionStorage.getItem('menuState') || 'open';
const [cityData, setCityData] = useState({});
const [siteLoading, setSiteLoading] = useState(false);
......@@ -273,11 +275,10 @@ const Layout = (props) => {
});
}, []);
useEffect(() => {
siteAction.setGlobalConfig(props.global);
const tk = Cookies.get('token') || props.global.token;
const isLogin = tk !== null && tk !== 'undefined' && tk !== (void 0);
const isLogin = tk !== null && tk !== 'undefined' && tk !== void 0;
if (!isLogin) {
let client = props?.global?.client || sessionStorage.getItem('client') || null;
client = client !== 'undefined' && !_.isNull(client) && !_.isUndefined(client) ? client : 'city';
......@@ -305,7 +306,6 @@ const Layout = (props) => {
}
}, [cityData, props.global, props.global.userInfo, siteAction]);
useEffect(() => {
window.share.event.on('updateSite', res => {
setCityData(res);
......@@ -333,8 +333,7 @@ const Layout = (props) => {
});
}
};
}, [props.global.userInfo]);
}, [props.global.isHaveMark, props.global.userInfo]);
const onMenuHeaderClick = event => {
// 非云平台不做响应
......@@ -359,8 +358,8 @@ const Layout = (props) => {
const logo =
props.global && _.isFunction(props.global.get) && props.global.get('bannerLogo')
? props.global &&
_.isFunction(props.global.transformDevAssetsBaseURL) &&
props.global.transformDevAssetsBaseURL(props.global.get('bannerLogo'))
_.isFunction(props.global.transformDevAssetsBaseURL) &&
props.global.transformDevAssetsBaseURL(props.global.get('bannerLogo'))
: defaultSetting.logo;
// 添加一个路由跳转事件
......@@ -368,7 +367,7 @@ const Layout = (props) => {
const { share, history } = window;
const findMenuPath = (flatMenu, url) => {
const [path, param = ''] = url.split('|');
let params = param.split('&').reduce((pre, item) => {
const params = param.split('&').reduce((pre, item) => {
if (!item) return pre;
const [key, value] = item.split('=');
pre[key] = value;
......@@ -393,18 +392,13 @@ const Layout = (props) => {
return () => {
share && share.event && share.event.removeListener('route:pushState', skipHandler);
};
}, []);
}, [props.flatMenu]);
if(props.global && props.global.userInfo){
if(!props.global.userInfo.site){
if (props.global && props.global.userInfo) {
if (!props.global.userInfo.site) {
props.global.userInfo.site = '';
}
}
return (
<SecurityLayout {...props}>
<BasicLayout
......@@ -412,7 +406,9 @@ const Layout = (props) => {
route={props.route}
location={location}
navTheme={props.global?.variableTheme?.navTheme ?? 'dark'}
mode='MDI'
homepage={props.global?.homepage ?? ''}
redirect={props.global?.redirect ?? ''}
mode="MDI"
fixedHeader
headerHeight={52}
routeConfig={routeConfig}
......@@ -449,16 +445,15 @@ const Layout = (props) => {
}
menuItemRender={(item, dom) => (
<a
onClick={(event) => {
onClick={event => {
event.preventDefault();
window.history.pushState(null, '', '/civbase' + item.path);
window.history.pushState(null, '', `/civbase${item.path}`);
}}
>
{dom}
</a>
)}
>
<Suspense fallback={<></>}>
{/* {window.location.pathname.startsWith('/civbase/civ_3d') ? ( */}
{/* <KeepAlive> */}
......@@ -475,14 +470,13 @@ const Layout = (props) => {
<KeepAlive>
<CesiumMap />
</KeepAlive>
) : (
window.location.pathname.startsWith('/civbase/civ_webgis') && null
)}
</Suspense>
{subLoading && <Loading loading={subLoading} />}
<div id='micro-container' className='subapp-container'>
<div id="micro-container" className="subapp-container">
{props.children}
</div>
</BasicLayout>
......
......@@ -338,7 +338,7 @@ class Site {
loginSite[token] = site;
localStorage.setItem('loginSite', JSON.stringify(loginSite));
const self = this;
self.props.updateCurrentIndex && self.props.updateCurrentIndex(-1);
// self.props.updateCurrentIndex && self.props.updateCurrentIndex(-1);
const login = new Login(this.props, () => {
self.setLoading(false);
self.getCityStationsForUser().then(res => {
......@@ -373,6 +373,7 @@ class Site {
}
changeGroup(event, item, onChangeVisible, actionRef) {
debugger
event.persist();
const site = item ? item.site : event.target.dataset.site;
const { loginName } = this.globalConfig.userInfo;
......
import React, { memo } from "react";
import SecurityLayout from "../../../layouts/SecurityLayout";
import React from 'react';
import SecurityLayout from '../../../layouts/SecurityLayout';
const HocContainer = Component => {
return (props) => {
return (
<SecurityLayout>
<Component {...props} />
</SecurityLayout>
)
}
}
const HocContainer = Component => props => (
<SecurityLayout>
<Component {...props} />
</SecurityLayout>
);
export default HocContainer;
\ No newline at end of file
export default HocContainer;
import React, { memo } from 'react';
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 = ({ params }) => {
const { linkUrl } = params || {};
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']}>
<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}
......@@ -19,7 +35,7 @@ const TabWidget = ({ params }) => {
styles={{ border: 'none' }}
/>
) : (
<Empty description="配置url链接才能显示哦!"/>
<Empty description="配置url链接才能显示哦!" />
)}
</div>
);
......
......@@ -3,4 +3,34 @@
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;
/* eslint-disable import/no-unresolved */
/* eslint-disable no-underscore-dangle */
/* eslint-disable global-require */
/* eslint-disable eqeqeq */
/*
** 功能名称
** create by tuwei on 2022/2/20
......@@ -8,16 +12,16 @@ import { connect } from 'react-redux';
import { List, message, Avatar, Skeleton, Divider, Select, notification } from 'antd';
import { CheckOutlined } from '@ant-design/icons';
import InfiniteScroll from 'react-infinite-scroll-component';
// eslint-disable-next-line import/no-unresolved
import classnames from 'classnames';
import { noticeService } from '@/api';
import styles from './index.less';
import { formatDate } from './utils'
import { formatDate } from './utils';
const findMenuPath = (flatMenu, url) => {
const [path, param = ''] = url.split('|');
let params = param.split('&').reduce((pre, item) => {
if(!item) return pre;
const params = param.split('&').reduce((pre, item) => {
if (!item) return pre;
const [key, value] = item.split('=');
pre[key] = value;
return pre;
......@@ -31,17 +35,13 @@ const CheckAllMessage = props => {
const { flatMenu } = props;
const [loading, setLoading] = useState(false);
const [data, setData] = useState([]);
const [sortType, setSortType] = useState(1); //排序类型
const [sortType, setSortType] = useState(1); // 排序类型
const [infoTypeList, setInfoTypeList] = useState([]);
const [isRes, setIsRes] = useState(false);
const total = useRef(0);
const pageIndex = useRef(1);
const pageSize = useRef(20);
const infoType = useRef('全部');
useEffect(() => {
loadMoreData();
getTypeList();
}, []);
// 获取类型数据
const getTypeList = () => {
noticeService.getCurrentInfoType({ userID: window.globalConfig.userInfo.OID }).then(res => {
......@@ -49,38 +49,40 @@ const CheckAllMessage = props => {
res.data?.unshift('全部');
res.data && setInfoTypeList(res.data);
}
})
}
});
};
// 加载数据
const loadMoreData = () => {
if (loading) {
return;
}
setLoading(true);
let obj = {}
if (infoType.current == '全部') {
let obj = {};
if (infoType.current === '全部') {
obj = {
userID: window.globalConfig.userInfo.OID,
pageIndex: pageIndex.current,
pageSize: pageSize.current,
sort: sortType
}
sort: sortType,
};
} else {
obj = {
type: infoType.current,
userID: window.globalConfig.userInfo.OID,
pageIndex: pageIndex.current,
pageSize: pageSize.current,
sort: sortType
}
sort: sortType,
};
}
// userID: window.globalConfig.userInfo.OID,
noticeService
.getAllInformationInfo(obj)
.then(res => {
if (res.code === 0) {
// eslint-disable-next-line no-plusplus
pageIndex.current++;
total.current = res.data.totalCount;
// eslint-disable-next-line no-use-before-define
res.data.list && setData([...data, ...deaflData(res.data.list)]);
setIsRes(true);
setLoading(false);
......@@ -89,27 +91,32 @@ const CheckAllMessage = props => {
.catch(() => {
setIsRes(true);
setLoading(false);
})
});
};
useEffect(() => {
loadMoreData();
getTypeList();
}, []);
// eslint-disable-next-line no-shadow, arrow-body-style
const deaflData = (data = []) => {
return data.map(item => {
let content = '';
try {
content = JSON.parse(item.infoContent)
content = JSON.parse(item.infoContent);
content = item.infoContent;
} catch (error) {
content = '{}';
}
return { ...item, infoContent: content}
})
}
return { ...item, infoContent: content };
});
};
// 获取数据
const getData = (obj) => {
const getData = obj => {
noticeService
.getAllInformationInfo(obj)
.then(res => {
if (res.code === 0) {
// eslint-disable-next-line no-plusplus
pageIndex.current++;
total.current = res.data.totalCount;
res.data.list && setData(deaflData(res.data.list));
......@@ -118,66 +125,67 @@ const CheckAllMessage = props => {
})
.catch(() => {
setLoading(false);
})
}
});
};
// 监听选择类型
const onChange = e => {
infoType.current = e;
pageIndex.current = 1
let obj = {}
if (infoType.current == '全部') {
pageIndex.current = 1;
let obj = {};
if (infoType.current === '全部') {
obj = {
userID: window.globalConfig.userInfo.OID,
pageIndex: pageIndex.current,
pageSize: pageSize.current,
sort: sortType
}
sort: sortType,
};
} else {
obj = {
type: infoType.current,
userID: window.globalConfig.userInfo.OID,
pageIndex: pageIndex.current,
pageSize: pageSize.current,
sort: sortType
}
sort: sortType,
};
}
getData(obj);
};
// title 回显
const messageTitle = (themeName, info) => {
var messInfo = "";
switch (themeName) {
case "工单提醒":
const messageTitle = (item, info) => {
const { messType, title } = item;
let messInfo = '';
switch (messType) {
case '工单提醒':
messInfo = `${info.caseType}`;
break;
case "通用报警":
case '通用报警':
messInfo = `${info.title}`;
break;
case "系统通知":
case '系统通知':
messInfo = `${info.noticeType}`;
break;
default:
messInfo = info.title;
messInfo = title || info.title;
break;
}
return messInfo;
};
// content回显
const messageContent = (themeName, info) => {
var messInfo = "";
switch (themeName) {
case "工单提醒":
const messageContent = (item, info) => {
const { messType, defaultContent } = item;
let messInfo = '';
switch (messType) {
case '工单提醒':
messInfo = `${info.flowName},${info.nodeName},承办意见:${info.content}`;
break;
case "通用报警":
case '通用报警':
messInfo = `${info.content},${info.deviceCode}`;
break;
case "系统通知":
case '系统通知':
messInfo = `${info.noticeTitle},${info.noticeContent}`;
break;
default:
messInfo = info.content;
messInfo = info.content || defaultContent;
break;
}
return messInfo;
......@@ -190,26 +198,28 @@ const CheckAllMessage = props => {
const difSeconds = (currentTime.getTime() - createTime.getTime()) / 1000;
let timeMsg = '';
if (difSeconds < 60) {
timeMsg = '刚刚'
timeMsg = '刚刚';
} else if (difSeconds / 60 < 60) {
// eslint-disable-next-line radix
timeMsg = `${parseInt(difSeconds / 60)}分钟前`;
} else if (difSeconds / 3600 < 24) {
// eslint-disable-next-line radix
timeMsg = `${parseInt(difSeconds / 3600)}小时前`;
} else {
timeMsg = formatDate(createTime, 'yyyy-MM-dd');
}
return timeMsg;
}
};
const sortChange = value => {
setSortType(value);
pageIndex.current = 1;
let obj = {};
if (infoType.current == '全部') {
if (infoType.current === '全部') {
obj = {
userID: window.globalConfig.userInfo.OID,
pageIndex: pageIndex.current,
pageSize: pageSize.current,
sort: value
sort: value,
};
} else {
obj = {
......@@ -217,34 +227,35 @@ const CheckAllMessage = props => {
userID: window.globalConfig.userInfo.OID,
pageIndex: pageIndex.current,
pageSize: pageSize.current,
sort: value
sort: value,
};
}
getData(obj);
}
// 渲染头像
const renderImg = val => {
if (val == '通用报警') {
return require('/src/assets/images/system/notifications/icon2.png');
};
// 渲染头像
const renderImg = item => {
const { messType, webIcon } = item;
if (webIcon) return `${window.location.origin}/${webIcon}`;
if (messType === '通用报警') {
return require('../../../assets/images/system/notifications/icon2.png');
}
if (val == '工单提醒') {
return require('/src/assets/images/system/notifications/icon4.png');
if (messType === '工单提醒') {
return require('../../../assets/images/system/notifications/icon4.png');
}
if (val == '系统通知') {
return require('/src/assets/images/system/notifications/icon3.png');
if (messType === '系统通知') {
return require('../../../assets/images/system/notifications/icon3.png');
}
if (val == '工时审批') {
return require('/src/assets/images/system/notifications/icon1.png')
if (messType === '工时审批') {
return require('../../../assets/images/system/notifications/icon1.png');
}
if (val.indexOf('工时填报') != -1) {
return require('/src/assets/images/system/notifications/icon6.png')
if (messType.indexOf('工时填报') != -1) {
return require('../../../assets/images/system/notifications/icon6.png');
}
if (val.indexOf('会议') != -1) {
return require('/src/assets/images/system/notifications/icon7.png')
if (messType.indexOf('会议') != -1) {
return require('../../../assets/images/system/notifications/icon7.png');
}
return require('/src/assets/images/system/notifications/icon3.png');
}
return require('../../../layouts/AppLayout/notifier/images/types/other.png');
};
// 标记为已读
const hasRead = () => {
noticeService.postInformationStatus({ userID: window.globalConfig.userInfo.OID, isAll: 1 }).then(res => {
......@@ -256,7 +267,7 @@ const CheckAllMessage = props => {
userID: window.globalConfig.userInfo.OID,
pageIndex: pageIndex.current,
pageSize: pageSize.current,
sort: sortType
sort: sortType,
};
} else {
obj = {
......@@ -264,26 +275,27 @@ const CheckAllMessage = props => {
userID: window.globalConfig.userInfo.OID,
pageIndex: pageIndex.current,
pageSize: pageSize.current,
sort: sortType
sort: sortType,
};
}
getData(obj);
}
})
}
});
};
// 获取参数
const GetUrlParam = (url) => {
let arrObj = url.split("|");
let params = Object.create(null);
const GetUrlParam = url => {
let arrObj = url.split('|');
const params = Object.create(null);
if (arrObj.length > 1) {
arrObj = arrObj[1].split("&");
arrObj.forEach((item) => {
item = item.split("=");
arrObj = arrObj[1].split('&');
arrObj.forEach(item => {
item = item.split('=');
// eslint-disable-next-line prefer-destructuring
params[item[0]] = item[1];
});
}
return params;
}
};
// 跳转链接
const toLink = val => {
if (!val.web_path) {
......@@ -297,7 +309,7 @@ const CheckAllMessage = props => {
return;
}
let targetMenuPath = findMenuPath(flatMenu, val.web_path);
const targetMenuPath = findMenuPath(flatMenu, val.web_path);
if (targetMenuPath == '') {
notification.error({ message: '提示', duration: 3, description: '你没有跳转菜单权限,请联系管理员添加权限' });
return;
......@@ -312,9 +324,9 @@ const CheckAllMessage = props => {
sessionStorage.setItem('routerParams', JSON.stringify(params));
noticeService.postInformationStatus({ userID: window.globalConfig.userInfo.OID, hisID: val.hisID }).then(res => {
window.history.pushState(params, '', `/civbase/${targetMenuPath}`);
})
});
}
}
};
return (
<div className={styles.contentPage}>
<div className={styles.messageBox}>
......@@ -322,17 +334,15 @@ const CheckAllMessage = props => {
<div className={styles.headerContent}>
{/* 选择类型 */}
<div className={styles.selectForm}>
<div className={styles.lable}>
类型:
</div>
<div className={styles.lable}>类型:</div>
<div className={styles.form}>
<Select
defaultValue="全部"
placeholder="请选择类型"
onChange={onChange}
style={{ width: '154px' }}
>
{infoTypeList.map(item => <Option value={item} key={item}>{item}</Option>)}
<Select defaultValue="全部" placeholder="请选择类型" onChange={onChange} style={{ width: '154px' }}>
{infoTypeList.map(item => (
// eslint-disable-next-line react/jsx-no-undef
<Option value={item} key={item}>
{item}
</Option>
))}
</Select>
</div>
</div>
......@@ -341,11 +351,20 @@ const CheckAllMessage = props => {
<div className={styles.label}>排序:</div>
<div className={styles.form}>
<div className={styles.sortBox}>
<div className={classnames(styles.tab, { [styles.tabActive]: sortType === 1 })} onClick={() => sortChange(1)}>未读通知在前</div>
<div className={classnames(styles.tab, { [styles.tabActive]: sortType === 0 })} onClick={() => sortChange(0)}>默认时间排序</div>
<div
className={classnames(styles.tab, { [styles.tabActive]: sortType === 1 })}
onClick={() => sortChange(1)}
>
未读通知在前
</div>
<div
className={classnames(styles.tab, { [styles.tabActive]: sortType === 0 })}
onClick={() => sortChange(0)}
>
默认时间排序
</div>
</div>
</div>
</div>
<div className={styles.haveRead} onClick={hasRead}>
<CheckOutlined style={{ verticalAlign: 'middle', marginRight: '3px', marginTop: '-2px' }} />
......@@ -353,40 +372,44 @@ const CheckAllMessage = props => {
</div>
</div>
<div
id="scrollableDiv"
className={styles.msgContent}
>
<div id="scrollableDiv" className={styles.msgContent}>
<InfiniteScroll
dataLength={data.length}
next={loadMoreData}
hasMore={data.length < total.current}
loader={<div className={styles.loaderTip}>正在加载更多...</div>}
endMessage={isRes ? (<div className={styles.loaderTip}>没有更多内容了</div>) : ''}
endMessage={isRes ? <div className={styles.loaderTip}>没有更多内容了</div> : ''}
scrollableTarget="scrollableDiv"
>
{data.map((item, index) => (<div className={classnames(styles.msgItem, { [styles.msgHasRead]: item.id == 0 })} key={index} onClick={() => toLink(item)}>
<div className={styles.left}>
<img src={renderImg(item.messType)} alt="" />
</div>
<div className={styles.msgCenter}>
<div className={styles.msgBox}>
<div className={styles.title}>{messageTitle(item.messType, JSON.parse(item.infoContent))}</div>
<div className={styles.msgDesc} title={messageContent(item.messType, JSON.parse(item.infoContent))}>{messageContent(item.messType, JSON.parse(item.infoContent))}</div>
{data.map((item, index) => (
<div
className={classnames(styles.msgItem, { [styles.msgHasRead]: item.id == 0 })}
// eslint-disable-next-line react/no-array-index-key
key={index}
onClick={() => toLink(item)}
>
<div className={styles.left}>
<img src={renderImg(item)} alt="" />
</div>
<div className={styles.msgCenter}>
<div className={styles.msgBox}>
<div className={styles.title}>{messageTitle(item, JSON.parse(item.infoContent))}</div>
<div className={styles.msgDesc} title={messageContent(item, JSON.parse(item.infoContent))}>
{messageContent(item, JSON.parse(item.infoContent))}
</div>
</div>
</div>
<div className={styles.right}>{renderTime(item.hisCreateTime || item.createTime)}</div>
</div>
<div className={styles.right}>{renderTime(item.createTime || item.hisCreateTime)}</div>
</div>))}
))}
</InfiniteScroll>
</div>
</div >
</div >
</div>
</div>
);
};
const mapStateToProps = state => ({
flatMenu: state.getIn(['global', 'flatMenu'])
flatMenu: state.getIn(['global', 'flatMenu']),
});
export default connect(
mapStateToProps,
......
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: [
......
/*
* @Author: 634665781 634665781@qq.com
* @Date: 2022-07-08 14:28:01
* @LastEditors: 634665781 634665781@qq.com
* @LastEditTime: 2022-09-05 17:38:26
* @LastEditors: Please set LastEditors
* @LastEditTime: 2023-01-13 10:01:40
* @FilePath: \CivWeb\src\pages\user\login\index.js
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import React, { useEffect } from 'react';
import BaseLogin from './template/baseLogin';
import NewYear from './template/newYear';
import baseLoginNewYear from './template/baseLoginNewYear';
import InfoLogin from './template/infoLogin';
import Yulin from './template/yulin';
// import { useParams } from '@wisdom-utils/runtime';
......@@ -23,8 +24,12 @@ import HuhehaoteLogin from './template/project/huhehaote';
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 DazuLogin from './template/project/dazu';
import PanoramaLogin from './template/panorama';
import { AppInitState } from '../../../render';
const LoginTemplate = {
'新春.html': baseLoginNewYear,
'新春 - 智联.html': NewYear,
'Dark - IOTMultiLogin.html': BaseLogin,
'Dark.html': BaseLogin,
......@@ -42,6 +47,9 @@ const LoginTemplate = {
'项目 - 新干.html': XinganLogin,
'项目 - 二连浩特.html': ErlianhaoteLogin,
'项目 - 易县.html': YixianLogin,
'项目 - 蠡县.html': LixianLogin,
'项目 - 大足.html': DazuLogin,
'全景图.html': PanoramaLogin,
default: BaseLogin,
};
/* eslint-disable */
......
......@@ -98,25 +98,30 @@ class Login {
site: this.getLocalSiteBytoken(token),
'request.preventCache': Date.now(),
ignoreSite: true,
}).then(response => {
if (response && response.code === 0) {
self.globalConfig.userInfo = window?.globalConfig?.transformUserInfo?.(response.data) ?? {};
self.updateConfig && self.updateConfig(self.globalConfig);
self.getUserInfoAndConfig();
} else {
self.logout && self.logout();
if (params.getParams('token')) {
// token免登录失败,回到登录页,防止reload造成死循环
window.location.href = `${window.location.origin}`;
return false;
}
if (self.globalConfig.style === 'ios' && self.globalConfig.loginTemplate === 'IOSCloud.html') {
window.location.href = `${window.location.origin}`;
return false;
})
.then(response => {
if (response && response.code === 0) {
self.globalConfig.userInfo = window?.globalConfig?.transformUserInfo?.(response.data) ?? {};
self.updateConfig && self.updateConfig(self.globalConfig);
self.getUserInfoAndConfig();
} else {
self.logout && self.logout();
if (params.getParams('token')) {
// token免登录失败,回到登录页,防止reload造成死循环
window.location.href = `${window.location.origin}`;
return false;
}
if (self.globalConfig.style === 'ios' && self.globalConfig.loginTemplate === 'IOSCloud.html') {
window.location.href = `${window.location.origin}`;
return false;
}
window.location.reload();
}
window.location.reload();
}
});
})
.catch(error => {
this.handleLoginError();
Logger.log('获取用户配置失败');
});
}
writeLogs() {
......@@ -182,9 +187,8 @@ class Login {
getWebConfig(token, getIndustry) {
const self = this;
// eslint-disable-next-line no-undef
// 获取网站配置的同时,预先获取到mqtt配置,注册进子应用
Promise.all([
Promise.allSettled([
noticeService.getMqttSiteCode({ 'request.preventCache': Date.now() }),
getWebSiteConfig({
client: self.globalConfig.client,
......@@ -193,17 +197,26 @@ class Login {
}),
])
.then(results => {
const res = results[0] || {};
const promise = results[0];
const mqttConfig = {
mqtt_mess: {},
mqtt_path: DEFAULT_MQTT_PATH,
nginxStart: false,
mqtt_IsSSL: true,
ipConfig: {},
};
if (promise.status === 'rejected') {
self.globalConfig = Object.assign(self.globalConfig, {
...mqttConfig,
});
return results;
}
const res = promise.value || {};
if (res && res.code === 0) {
const mqttConfig = {
mqtt_mess: {},
mqtt_path: DEFAULT_MQTT_PATH,
nginxStart: false,
mqtt_IsSSL: true,
};
if (Array.isArray(res.data) && res.data.length > 0) {
if (res.data[0]) {
const data = res.data[0];
mqttConfig.ipConfig = data;
mqttConfig.mqtt_IsSSL = data.IsSSL ? data.IsSSL : false;
mqttConfig.mqtt_mess.site_code = data.SiteCode || self.globalConfig.userInfo.site;
mqttConfig.mqtt_mess.TcpIP = data.TcpIP;
......@@ -237,7 +250,7 @@ class Login {
return results;
})
.then(results => {
const response = results[1] ?? {};
const response = results[1]?.value ?? {};
const result =
response && response.code === SERVICE_INTERFACE_SUCCESS_CODE
? Array.isArray(response.data)
......@@ -489,7 +502,7 @@ class Login {
id: 'wxlogin_container',
appid: 'wxec56ca668e7f9155',
agentid: '1000083',
redirect_uri: encodeURIComponent(window.location.href.replace('#/', '')),
redirect_uri: encodeURIComponent(window.location.href),
href: 'https://mis.panda-water.cn/web4/styles/wx.css',
});
}
......@@ -511,7 +524,7 @@ class Login {
if (url.indexOf('&code') !== -1) {
// 判断是否存在参数
// eslint-disable-next-line no-useless-escape
url = url.replace(/(\&code|#)[^'"]*/, ''); // 去除参数
url = url.replace(/(\&code|#)[^'"]*/, '&code=success'); // 去除参数
window.history.pushState({}, 0, url);
}
self.isSignIn = true;
......@@ -701,11 +714,16 @@ class Login {
self.updateConfig && self.updateConfig(self.globalConfig);
} catch (error) {
console.log(error);
message.error('登录失败');
if (self.goLogin()) {
return false;
}
// self.handleLoginError(failCallback);
}
})
.catch(error => {
this.handleLoginError();
Logger.log('获取用户配置失败');
});
} else {
self.handleLoginError();
......@@ -852,9 +870,12 @@ class Login {
rules = '';
reg = new RegExp(rules);
}
const check = rules && rules !== '' && !reg.test(pwd)
localStorage.setItem('access_token', response.access_token);
localStorage.setItem('password_token', check);
let check = false;
if(rules !== '') check = !reg.test(pwd)
localStorage.setItem('access_token', response.access_token ? response.access_token : '');
if(check) {
localStorage.setItem('password_token', response.access_token ? response.access_token : '');
}
Cookies.set('client', self.globalConfig.client, {
expires: exp / (24 * 60 * 60 * 1000),
path: '/',
......
/* eslint-disable no-empty */
/* eslint-disable react-hooks/exhaustive-deps */
/* eslint-disable no-undef */
import '@wisdom-utils/utils/lib/helpers/format';
import { params } from '@wisdom-utils/utils/lib/helpers';
import React, { forwardRef, useEffect, useRef, useState } from 'react';
......@@ -8,10 +11,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,31 +21,39 @@ 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 &&
action.events.on('loginSuccess', event => {
// http://127.0.0.1:8080/civbase/civweb4/
// props.updateConfig(Object.assign({}, props.global, {
// homepage: params.getParams('redirect')
// }));
// props.history.push('/' + params.getParams('redirect'))
props.history.push(
`/?client=${props.global.client}`,
props.updateConfig(
Object.assign({}, window.globalConfig, {
redirect,
}),
);
let url = '';
try {
url =
_.isString(redirect) && redirect.replace(new RegExp(/ /g), '').length > 0
? redirect.replace('&skipHome=true', '')
: '';
} catch (error) {}
// props.history.push('/' + params.getParams('redirect'))
props.history.push(`/?client=${props.global.client}`);
// window.share.event.emit('triggerMicro', props.global);
// initMicroApps();
defaultApp(redirect);
defaultApp(url);
});
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 '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';
import useRenderQcode from '../js/useRenderQcode';
import Account from '../js/useAccount';
import IotComponent from '../js/useIOTComponent';
import { defaultApp } from '../../../../micro';
const Login = forwardRef((props, _ref) => {
const videoRef = useRef();
const loginRef = useRef();
const timeRef = useRef();
const loginWrapper = useRef();
const titleRef = useRef();
const sliVerify = useRef();
const loginFormRef = useRef();
const formRef = useRef(null);
const footerRef = useRef();
const [status, setStatus] = useState('normal');
const [autoLogin, setAutoLogin] = useState(false);
const [submitting, setSubmitting] = useState(false);
const [currentDate, setCurrentDate] = useState({});
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 [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]);
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]);
let loginTimeInterval = null;
let videoTimeout = null;
useEffect(() => {
if (loginTimeInterval)
clearInterval(loginTimeInterval), (loginTimeInterval = null);
loginTimeInterval = setInterval(() => {
const date = new Date();
const weekday = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
const time = `${
date.getHours() < 10 ? `0${date.getHours()}` : date.getHours()
}:${
date.getMinutes() < 10 ? `0${date.getMinutes()}` : date.getMinutes()
}:${
date.getSeconds() < 10 ? `0${date.getSeconds()}` : date.getSeconds()
}`;
setCurrentDate({
time,
dayofweek: weekday[date.getDay()],
date: date.pattern('yyyy/MM/dd'),
});
}, 1000);
return () => {
loginTimeInterval && clearInterval(loginTimeInterval);
};
}, []);
useEffect(() => {
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');
dom.removeClass(loginWrapper.current, styles.caseHide);
dom.addClass(loginWrapper.current, 'animate__fadeInUp');
}, 500);
});
}
});
}
return () => {
videoTimeout && clearTimeout(videoTimeout);
videoRef && videoRef.current && videoRef.current.removeEventListener('ended', () => {});
};
}, [videoRef]);
useEffect(() => {
setSubmitting(false);
}, [visible]);
const renderAddons = useRenderQcode(props.global);
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,
};
switch (template) {
case 'DarkCloud.html':
case 'Dark.html':
return <Account {...params} />;
case 'Dark - IOTMultiLogin.html':
return <IotComponent {...params} />;
default:
return <Account {...params} />;
}
};
/* eslint-disable */
return (
<HelmetProvider>
<Helmet>
<title>{props.global.title || defaultSetting.title}</title>
<meta name="description" content={props.global.title || defaultSetting.title} />
</Helmet>
<div className={styles.main}>
{showVideo && <video
src={require("../../../../assets/videos/001.mp4") }
className={styles.videLayer}
autoPlay="autoPlay"
muted
playsInline="playsinline"
ref={videoRef}
/>}
<div className={classNames(styles.inner, styles.newYearInner)}>
<div
className={classNames(styles.loginTime, styles.newYearLoginTime, styles.caseHide, 'animated')}
ref={loginRef}
>
<img
role="logo"
src={props.global && props.global.transformDevAssetsBaseURL && props.global.transformDevAssetsBaseURL(props.global.logo)}
/>
<div
className={classNames(
styles.titleCase,
styles.caseHide,
'animated',
)}
ref={titleRef}
>
<span className={styles.title}>{props.global.title}</span>
<span className={styles.subtitle}>
{window.globalConfig && window.globalConfig.subtitle}
</span>
</div>
</div>
<span
className={classNames(
styles.divider,
styles.caseHide,
'animate__animated',
)}
/>
<div
className={classNames(
styles.timeCase,
styles.caseHide,
'animate__animated',
)}
ref={timeRef}
>
<span className={styles.time}>{currentDate.time}</span>
<span className={styles.dayofweek}>{currentDate.dayofweek}</span>
<span className={styles.date}>{currentDate.date}</span>
</div>
<div className={classNames(
styles.loginBlockWrapper,
'animate__animated',
styles.caseHide,
)} ref={loginWrapper}>
<div
className={classNames(
styles['login-block'],
styles['login-newYear-block'],
styles.caseHide,
'animate__animated',
)}
ref={loginFormRef}
>
<div>
<img src="https://panda-water.cn/web4/assets/images/login/workflow/%E6%99%BA%E8%81%94%E6%96%B0%E6%98%A5%E5%9B%BE%E7%89%87.png" />
</div>
<div className={styles['login-form']} style={{marginTop: '20px'}}>{renderPlatform()}</div>
</div>
</div>
</div>
{/* <div
className={classNames(
styles.footerCase,
styles.caseHide,
'animate__animated',
)}
ref={footerRef}
>
<div className={classNames(styles.quickMark)}>{renderAddons}</div>
<span className={classNames(styles.copyright)}>
Copyright ©
<a target="_blank" href="https://panda-water.cn">
熊猫智慧水务
</a>
{new Date().getFullYear()} All Rights Reserved{' '}
<a target="_blank" id="IndexCaseNumber" href="https://beian.miit.gov.cn">
沪ICP备18045097号-1
</a>
<span className="addons">
<span className="split" />
<a id="qrcode">
<span
className="glyphicon glyphicon-qrcode"
role="button"
title="手持APP下载"
/>
</a>
</span>
</span>
</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,
)((Login));
......@@ -10,7 +10,7 @@ const useWeCom = props => {
id: props.container || 'wxlogin_container',
appid: props.appid || WECOM_APPID,
agentid: props.agentid || AGENTID_CLOUD,
redirect_uri: props.redirect_uri.replace('#/', '') || encodeURIComponent(window.location.href.replace('#/', '')),
redirect_uri: props.redirect_uri || encodeURIComponent(window.location.href),
href: props.href || 'https://panda-water.cn/web4/styles/wx.css',
self_redirect: false,
state: props.state || 'STATE',
......@@ -42,7 +42,7 @@ const useIOTQRCode = () => {
container: 'wxlogin_container',
appid: WECOM_APPID,
agentid: AGENTID_CLOUD,
redirect_uri: encodeURIComponent(window.location.href.replace('#/', '')), // window.location.href
redirect_uri: encodeURIComponent(window.location.href), // window.location.href
href: 'https://panda-water.cn/web4/styles/wecom.css',
state: rstate,
},
......
......@@ -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}>
......
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 defaultSetting from '../../../../../../config/defaultSetting';
import LoginAction from '../../login';
import styles from './style.less';
import useRenderQcode from '../../js/useRenderQcode';
import Account from '../../js/useAccount';
import IotComponent from '../../js/useIOTComponent';
import { defaultApp } from '../../../../../micro';
import Krpano from '../../components/Krpano';
const PanoBaseLogin = forwardRef((props, _ref) => {
const videoRef = useRef();
const loginRef = useRef();
const timeRef = useRef();
const titleRef = useRef();
const sliVerify = useRef();
const loginFormRef = useRef();
const formRef = useRef(null);
const footerRef = useRef();
const [status, setStatus] = useState('normal');
const [autoLogin, setAutoLogin] = useState(false);
const [submitting, setSubmitting] = useState(false);
const [currentDate, setCurrentDate] = useState({});
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));
let { ddCode } = props.global;
const loginMode =props.loginMode;
const { projectName } = props.loginParams
if (loginMode && loginMode === 'iotWechat') ddCode = null;
// useEffect(() => {
// action.globalConfig = props.global;
// }, [props.global]);
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]);
let loginTimeInterval = null;
useEffect(() => {
if (loginTimeInterval)
clearInterval(loginTimeInterval), (loginTimeInterval = null);
loginTimeInterval = setInterval(() => {
const date = new Date();
const weekday = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
const time = `${date.getHours() < 10 ? `0${date.getHours()}` : date.getHours()
}:${date.getMinutes() < 10 ? `0${date.getMinutes()}` : date.getMinutes()
}:${date.getSeconds() < 10 ? `0${date.getSeconds()}` : date.getSeconds()
}`;
setCurrentDate({
time,
dayofweek: weekday[date.getDay()],
date: date.pattern('yyyy/MM/dd'),
});
}, 1000);
return () => {
loginTimeInterval && clearInterval(loginTimeInterval);
};
}, []);
useEffect(() => {
setSubmitting(false);
}, [visible]);
const renderAddons = useRenderQcode(props.global);
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,
};
switch (template) {
case 'DarkCloud.html':
case 'Dark.html':
return <Account {...params} />;
case 'Dark - IOTMultiLogin.html':
return <IotComponent {...params} />;
default:
return <Account {...params} />;
}
};
/* eslint-disable */
return (
<HelmetProvider>
<Helmet>
<title>{props.global.title || defaultSetting.title}</title>
<meta name="description" content={props.global.title || defaultSetting.title} />
</Helmet>
<div className={styles.main}>
<div className={styles.inner}>
<div
className={classNames(styles.loginTime)}
ref={loginRef}
>
<img
role="logo"
src={props.global && props.global.transformDevAssetsBaseURL && props.global.transformDevAssetsBaseURL(props.global.logo)}
/>
<div
className={classNames(
styles.titleCase
)}
ref={titleRef}
>
<span className={styles.title}>{props.global.title}</span>
<span className={styles.subtitle}>
{window.globalConfig && window.globalConfig.subtitle}
</span>
</div>
</div>
<div
className={classNames(
styles.timeCase
)}
ref={timeRef}
>
<span className={styles.time}>{currentDate.time}</span>
<span className={styles.dayofweek}>{currentDate.dayofweek}</span>
<span className={styles.date}>{currentDate.date}</span>
</div>
<div
className={classNames(
styles['login-block']
)}
ref={loginFormRef}
>
<div>
<img src="https://panda-water.cn/web4/assets/images/login/dark/login.png" />
</div>
<div className={styles['login-form']}>{renderPlatform()}</div>
</div>
</div>
{projectName ? <div className={styles.krpano}>
<Krpano projectName={projectName} />
</div> : null}
<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,
)((PanoBaseLogin));
import PanoBaseLogin from "./PanoBaseLogin"
import TieShanLogin from "../project/tieshan"
import { useState , useEffect } from "react"
const LoginTemplate = {
"铁山" : TieShanLogin,
default : PanoBaseLogin
}
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
@import '~antd/es/style/themes/variable.less';
@userPageLogin-prefix-cls: ~'@{ant-prefix}-pro-pages-user-login';
@keyframes loginTimeShow {
0% {
opacity: 1;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
zoom: 2;
}
50% {
opacity: 1;
top: 28px;
left: 45px;
transform: translate(0, 0);
zoom: 1;
}
60% {
opacity: 1;
left: 45px;
top: 28px;
transform: translate(0, 0);
}
70% {
opacity: 1;
left: 45px;
top: 28px;
transform: translate(0, 0);
}
75% {
opacity: 1;
left: 45px;
top: 28px;
transform: translate(0, 0);
}
100% {
opacity: 1;
left: 45px;
top: 28px;
transform: translate(0, 0);
}
}
.main {
// width: 368px;
margin: 0 auto;
height: 100%;
width: 100%;
@media screen and (max-width: @screen-sm) {
width: 95%;
}
.icon {
margin-left: 16px;
color: rgba(0, 0, 0, 0.2);
font-size: 24px;
vertical-align: middle;
cursor: pointer;
transition: color 0.3s;
&:hover {
color: @primary-color;
}
}
.other {
margin-top: 24px;
line-height: 22px;
text-align: left;
.register {
float: right;
}
}
.videLayer {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
object-fit: fill;
}
.inner {
position: absolute;
width: 100%;
height: 100%;
&.newYearInner {
height: 100%!important;
}
.loginTime {
position: absolute;
top: 25px;
left: 50px;
display: flex;
align-items: center;
justify-content: center;
opacity: 1;
z-index: 100;
&.newYearLoginTime {
position: absolute!important;
top: 28px!important;
left: 45px!important;
display: flex;
align-items: center;
justify-content: center;
z-index: 100;
transform: inherit!important;
}
img[role='logo'] {
height: 40px;
vertical-align: middle;
}
&.loginTimeShow {
animation-name: loginTimeShow;
animation-duration: 1s;
animation-iteration-count: 1;
animation-fill-mode: forwards;
}
.titleCase {
display: flex;
flex-direction: column;
margin: -5px 0 0 20px;
max-width: 570px;
.title,
.subtitle {
font-family: 'Microsoft YaHei';
text-align: left;
overflow-wrap: break-word;
color: #ffffff;
}
.title {
font-size: 28px;
}
.subtitle {
font-size: 12px;
line-height: 1;
}
}
}
.timeCase{
position: absolute;
width: 100%;
z-index: 200;
}
.timeCase {
.time,
.dayofweek,
.date {
position: absolute;
font-family: 'MicrosoftYaHeiUI';
color: rgba(255, 255, 255, 1);
}
.time {
top: 26px;
right: 170px;
font-size: 40px;
margin-right: 10px;
}
.dayofweek {
top: 32px;
right: 125px;
font-size: 16px;
}
.date {
top: 57px;
right: 95px;
font-size: 14px;
}
}
.loginBlockWrapper {
width: 100%;
height: 100%;
background-image: url(https://panda-water.com/web4/assets/images/login/workflow/智联新春背景.png);
background-size: 100% 100%;
background-repeat: no-repeat;
}
.login-block {
width: 800px;
position: absolute;
left: 50%;
top: 50%;
display: flex;
background:rgba(255,255,255,0.5);
transform: translate(-50%,-50%);
z-index: 100;
&.login-newYear-block {
width: 994px!important;
height: 424px!important;
margin-left: -497px!important;
margin-top: -212px!important;
background: url(https://panda-water.com/web4/assets/images/login/workflow/%E6%99%BA%E8%81%94%E6%96%B0%E6%98%A5%E8%83%8C%E6%99%AF%E6%A1%86.png)!important;
//width: 994px;
//height: 424px;
//position: absolute;
//left: 50%;
//top: 50%;
//margin-left: -497px;
//margin-top: -212px;
//display: flex;
background-size: 100% 100%;
background-repeat: no-repeat;
img {
margin-top: 90px;
margin-left: 168px;
}
.login-form {
display: flex;
align-items: center;
margin-left: 32px;
padding: 0;
background: transparent;
margin-top: -36px;
// :global {
// .ant-btn-primary {
// background: #ff9600 !important;
// border-color: #ff9600 !important;
// }
// }
}
}
img {
margin-top: 50px;
margin-bottom: 50px;
margin-left: 30px;
}
.login-form {
padding: 50px 50px 50px;
// background-color: #ffffff;
}
}
}
.footerCase {
width: 100%;
height: 16%;
background: #fff;
position: absolute;
bottom: 0;
left: 0;
.quickMark {
position: absolute;
bottom: 48px;
text-align: center;
width: 100%;
font-size: 12px;
min-height: 71px;
&-single {
text-align: center;
width: 120px;
display: inline-block;
span {
&.Android {
display: block;
background-image: url(https://panda-water.cn/web4/assets/images/login/dark/Android1.png);
width: 26px;
height: 32px;
margin: auto;
margin-bottom: 6px;
}
&.Wechat {
display: block;
background-image: url(https://panda-water.cn/web4/assets/images/login/dark/Wechat1.png);
width: 34px;
height: 32px;
margin: auto;
margin-bottom: 6px;
}
&.iphone {
display: block;
background-image: url(https://panda-water.cn/web4/assets/images/login/dark/iphone1.png);
width: 28px;
height: 32px;
margin: auto;
margin-bottom: 6px;
}
}
}
.Android-single .Android-code,
.iphone-single .iphone-code {
margin: 0px 0px 10px 0px;
width: 150px;
height: 150px;
background: #fff;
padding: 5px;
display: none;
transform: translateX(-15px);
}
.icon-Container {
height: 50px;
cursor: pointer;
}
}
.copyright {
position: absolute;
z-index: 2;
text-align: center;
width: 100%;
bottom: 10px;
font-size: 13pz;
color: #000000;
.frontIcon {
margin-top: -5px;
}
a {
color: #000000;
}
.addons {
display: none;
}
.split {
border-left: 1px solid #000000;
margin: 0 8px;
}
.glyphicon-qrcode {
vertical-align: text-top;
}
}
}
:global {
.antd-pro-login-submit {
width: 100%;
margin-top: 24px;
}
}
.wechatQRcode {
width: 250px;
height: 220px;
margin: 0 15px;
}
.loginDisplay {
width: 100%;
display: flex;
justify-content: space-between;
font-size: 12px;
a {
&:hover {
color: @primary-color;
transition: all 0.3s ease-in-out;
}
}
}
.captcha {
color: @primary-6;
font-weight: 400;
cursor: pointer;
font-size: 12px;
}
}
.krpano {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
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.
import React, { forwardRef, useEffect, useRef, useState } from 'react';
import { Modal } from 'antd';
import { Helmet, HelmetProvider } from 'react-helmet-async';
/* eslint-disable */
/*
* @Author: xule;
* @Date: 2021-11-22
* @Description:榆林登录页;
*/
import React from 'react';
import styles from './index.less'
import classNames from 'classnames';
import { connect } from 'react-redux';
import { useHistory, withRouter } from '@wisdom-utils/runtime';
import { actionCreators } from '@/containers/App/store';
import defaultSetting from '../../../../../../../config/defaultSetting';
import { CheckOutlined } from '@ant-design/icons';
import { withRouter } from '@wisdom-utils/runtime';
import LogoQ from './images/切换.png'
import LogoF from './images/电脑切换.png'
import qrcodeimg from './images/下载二维码.png'
import qrcodeS from './images/扫.png'
import Logo from './images/登录图标.png'
import Logoimg from './images/登录logo.png'
import Code from '@/assets/images/login/榆林/小程序@2x.png'
import MyHead from '@/assets/images/login/榆林/d-我的.png'
import PassWord from '@/assets/images/login/榆林/密码.png'
import Close from '@/assets/oa/login/close.png'
import Open from '@/assets/oa/login/open.png'
import LoginAction from '../../../login';
import styles from './index.less';
import Account from '../../../js/useAccount';
import { defaultApp } from '../../../../../../micro';
import { actionCreators } from '@/containers/App/store';
import Cookies from 'js-cookie';
import QRCode from 'qrcode.react';
import classnames from 'classnames';
const renderQRCode = props => {
const qrcodes = props.qrcode.split('|') || [];
if (qrcodes.length > 0 && qrcodes[0]) {
let value = qrcodes[0].replace(/{ip}/gi, props.ip || window.location.host).split('=')[1];
return <QRCode value={value} />;
import { defaultApp } from '../../../../../../micro';
const Logger = logger('login');
// 、登录页
class InfoLogin extends React.Component {
state = {
loginStyle: false, //true 账号密码登录 false 扫码登录
isOpen: false, //查看密码
isRember: false, //记住密码
ddOrWeixin: '',
qrcode: '',//二维码
codeLenth: 1,
time: '',
week: '',
date: '',
isQrcode: false
}
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 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);
};
componentDidMount() {
let action = new LoginAction(this.props, false, true)
this.loginEvent(action);
this.renderQRcode();
this.renderTime();
}
renderQRcode() {
var me = this;
var list = globalConfig.qrcode ? globalConfig.qrcode.split("|") : [];
let str = [];
if (list.length) {
list.forEach(function (val, index) {
if (val && val.replace(/ /g, "").length > 0) {
str.push(me.creatCodeHtml(val, index));
}
})
} else {
str.push(<span>手持APP下载未配置</span>);
}
this.setState({
qrcode: str,
codeLenth: list.length
})
}
renderTime() {
let me = this;
setInterval(() => {
const date = new Date();
const weekday = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
const time = `${date.getHours() < 10 ? `0${date.getHours()}` : date.getHours()
}:${date.getMinutes() < 10 ? `0${date.getMinutes()}` : date.getMinutes()}`;
me.setState({
time,
week: weekday[date.getDay()],
date: date.pattern('yyyy/MM/dd'),
})
}, 1000);
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);
}
creatCodeHtml(val, index) {
return (
<div className={('codeCase codeCase' + index)}>
<QRCode value={val.replace(/{ip}/ig, globalConfig.ip).split('=')[0]} />
<div className={styles.codeText}>{val.replace(/{ip}/ig, globalConfig.ip).split('=')[0]}</div>
</div>);
}
// 切换登录方式
changeloginStyle = () => {
const { ddOrWeixin } = this.state
this.setState({
loginStyle: !this.state.loginStyle,
ddOrWeixin: ddOrWeixin ? '' : 'dingding'
}, () => {
Cookies.set('loginMode', `${this.state.ddOrWeixin ? 'dingding' : 'pdw'}`, {
path: '/',
});
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]);
if (this.state.ddOrWeixin === 'dingding') {
let action = new LoginAction(this.props, false, true)
action.loginByDD()
}
})
}
// 查看密码
seePassWord = (e) => {
this.setState({
isOpen: !this.state.isOpen
})
}
// 记住密码
remberWord = () => {
this.setState({
isRember: !this.state.isRember
})
}
// 输入框变化
handleForm = (e) => {
const target = e.target
// 判断事件类型,如果是checkbox返回checked值,不是返回文本框的value值
const value = target.type == 'checkbox' ? target.checked : target.value;
// 获取文本框的name值
const name = target.name
this.setState({
[name]: value
})
}
onKeyDownchange(e){
if(e.keyCode == 13){
this.loginToWeb5();
}
}
//
checkLogType = () => {
this.setState({
isQrcode: !this.state.isQrcode
})
}
// 登录
loginToWeb5 = () => {
const { loginName, passWord, isRember } = this.state
let action = new LoginAction(this.props, false, true)
action.loginHandler(loginName, passWord, null, isRember, false)
this.loginEvent(action)
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 */
}
// 登录成功事件
loginEvent(action) {
action.globalConfig = this.props.global;
this.props.updateCurrentIndex && this.props.updateCurrentIndex(-1);
action && action.events.on('loginSuccess', event => {
this.props.updateCurrentIndex && this.props.updateCurrentIndex(0);
this.props.history.push(`/?client=${this.props.global.client}`);
// window.share.event.emit('triggerMicro', this.props.global);
defaultApp();
});
action && action.events.on('loginError', event => {
});
action && action.events.on('loginVisible', status => {
return (
<HelmetProvider>
<Helmet>
<title>{props.global.title || defaultSetting.title}</title>
<meta name="description" content={props.global.title || defaultSetting.title} />
</Helmet>
<div className={styles.login}>
<div className={styles['inner-wrapper']}>
<div className={styles['inner-center']}>
<div className={styles['img-wrapper']} />
<div className={classnames(styles['inner-bg'], styles['login-part'])} ref={loginFormRef}>
{renderPlatform()}
</div>
<div className={styles['APPcodeBox']}>
<p className={styles['APPCtext']}>查看二维码,扫码下载APP</p>
<div className={styles['APPCimg']}>{renderQRCode(props.global)}</div>
});
}
render() {
const { loginStyle, isOpen, isRember, loginName, passWord, qrcode, codeLenth, time, week, date, isQrcode } = this.state
return (
<div className={styles.InfoBg}>
<div className={styles.IBtimeBox}>
<div className={styles.TitleCont}>
<img src={Logoimg} alt=""></img>
</div>
<span className={styles.IBTtime}>{time}</span>
<span className={styles.IBTweek}>{week}</span>
<span className={styles.IBTdate}>{date}</span>
</div>
<div className={styles.loginBg}>
{/* 标题 */}
{/* <div className={styles.IBtitle}>
<img src={Logo} alt="" />
</div> */}
<div className={styles.IBcenter}>
<div className={styles.IBCleft}></div>
<div className={styles.IBCright}>
<div className={styles.IBlogoc}>
<img src={isQrcode ? LogoF : LogoQ} alt='' onClick={() => this.checkLogType()}></img>
</div>
<div className={styles.IBLogoForm} style={{ display: isQrcode ? 'none' : '' }}>
<div className={styles.IBlogo}>
<img src={Logo} alt=''></img>
</div>
{/* 登录主题 */}
<form className={styles.loginForm} >
<div className={styles.formgroup}>
<img className={styles.IBCRimg} src={MyHead} alt="" />
<input type="text" className={styles.inputLg} id='loginName' name='loginName' value={loginName} onChange={this.handleForm} placeholder="请输入你的用户名" />
</div>
<div className={styles.formgroup}>
<img className={styles.IBCRimg} src={PassWord} alt="" />
<input type={isOpen ? 'text' : "password"} className={styles.inputLg} onKeyDown={e=> this.onKeyDownchange(e)} id='passWord' name='passWord' value={passWord} onChange={this.handleForm} placeholder="请输入你的密码" />
<img className={styles.eyes} src={isOpen ? Open : Close} alt="" onMouseDown={(e) => this.seePassWord(e)} onMouseUp={(e) => this.seePassWord(e)} />
</div>
<div className={styles.formgroup} style={{ position: 'relative', marginTop: '20px' }}>
<label className={classNames(isRember ? (styles.rmpwdInput, styles.active) : styles.rmpwdInput)} onClick={() => this.remberWord()}>
<CheckOutlined style={{ display: isRember ? '' : 'none' }} />
</label>
<span style={{ color: '#9FA8B3', marginLeft: '10px', fontSize: '14px' }}>记住密码</span>
</div>
<div className={styles.logoBtn}>
<div className={styles.submitBtn} onClick={this.loginToWeb5}>登录</div>
</div>
</form>
</div>
<div className={styles.IBLogoForm} style={{ display: isQrcode ? '' : 'none' }}>
<div className={styles.QrcodeCont}>
<img src={qrcodeimg} alt=''></img>
</div>
<div className={styles.qrcodedis}>
<img src={qrcodeS} alt=''></img>
<div className={styles.textCont}>
<p>打开手机扫一扫</p>
<p>
<span>下载</span>
<span className={styles.lastText}>熊猫掌天下</span>
</p>
</div>
</div>
</div>
</div>
{/* <div className={styles.codeBox}>
<img className={styles.codeImg} src={Code} alt="" />
<div className={styles.codeBig} style={{ width: codeLenth * 148 + 'px' }}>
{qrcode}
</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']),
......@@ -149,4 +262,5 @@ const mapDispatchToProps = dispatch => ({
export default connect(
mapStateToProps,
mapDispatchToProps,
)(withRouter(Login));
)(withRouter(InfoLogin));
.login {
width: 100%;
height: 100%;
background: url('./images/2.png') no-repeat center;
background-size: 100% 100%;
background-clip: border-box;
position: relative;
min-height: 7.0rem;
overflow: hidden;
}
.login .inner-bg {
.InfoBg{
width: 100%;
height: 100%;
&>div {
width: 70%;
margin: 0 auto;
background-image: url('./images/背景.png');
background-size: cover;
background-repeat: no-repeat;
position: relative;
.loginBg{
position: absolute;
top: 40%;
left: 40%;
margin-left: -385px;
margin-top: -226px;
width: 1101px;
height: 646px;
background-image: url('./images/标题.png');
background-size: 100% 100%;
background-repeat: no-repeat;
.IBcenter{
width: 100%;
height: 596px;
margin-top: 50px;
.IBCleft{
width: 682px;
height: 100%;
background-image: url('./images/左图.png');
background-size: 100% 100%;
background-repeat: no-repeat;
float: left;
}
.IBCright{
width: 419px;
height: 100%;
float: left;
background: rgba(255,255,255,0.8);
.IBlogoc{
height: 74px;
width: 100%;
text-align: end;
img{
height: 74px;
width: 74px;
cursor: pointer;
}
}
.IBLogoForm{
.IBlogo{
height: 100px;
width: 100%;
text-align: center;
img{
height: 100px;
width: 100px;
}
}
.QrcodeCont{
text-align: center;
height: 360px;
width: 100%;
padding-top: 80px;
img{
width: 211px;
height: 211px;
}
}
.qrcodedis{
display: flex;
padding: 0px 40px 0px 105px;
img{
width: 48px;
height: 40px;
margin-top: 10px;
}
.textCont{
margin-left: 25px;
font-size: 16px;
p{
margin-bottom: 5px;
color: #333333;
.lastText{
margin-left: 5px;
color: #1568BA;
}
}
}
}
}
}
}
.IBtitle{
width: 100%;
height: 10.5%;
text-align: center;
img{
width: 70%;
height: 100%;
}
}
.title{
font-family: SourceHanSansCN-Medium;
font-weight: bold;
color: #43484D;
position: absolute;
top: 21px;
right: 50%;
margin-right: -285px;
line-height: 1;
width: 570px;
text-align: center;
overflow-wrap: break-word;
font-size: 24px;
img{
margin-right: 14px;
}
}
.ddCode{
position: absolute;
top: 50px;
right: -9px;
cursor: pointer;
}
.titleImg {
position: absolute;
top: 132px;
right: 133px;
}
.loginForm{
width: 280px;
margin: 9% auto 25%;
.formgroup{
position: relative;
line-height: 1;
display: flex;
align-items: center;
.IBCRimg{
top: 33px;
}
img{
position: absolute;
left: 10px;
top: 50%;
}
.eyes{
left: 89%;
margin-top: 10px;
cursor: pointer;
}
input[type="checkbox"] {
width: 12px;
height: 12px;
}
input {
font-size: 16px;
outline: 0;
}
span {
position: relative;
top: 0px;
}
.formControl{
display: block;
width: 100%;
}
.inputLg{
padding-left: 42px;
color: #2D3033;
border: none;
box-shadow: none;
border-radius: 0;
padding: 10px 50px;
line-height: 1.3333333;
margin-top: 21px;
}
}
.logoBtn{
margin-top: 50px;
height: 45px;
width: 100%;
padding-left: 30px;
.submitBtn {
width: 220px;
background-color: #1568BA !important;
border: none !important;
color: #fff !important;
outline: none !important;
border-color: transparent !important;
height: 45px;
line-height: 45px;
font-size: 18px;
text-align: center;
cursor: pointer;
border-radius: 23px;
}
}
}
.login_container {
position: absolute;
top: 59%;
left: 52%;
margin-left: 150px;
margin-top: -219px;
width: 400px;
height: 500px;
}
.wxlogin_container{
position: absolute;
top: 60%;
left: 55%;
margin-left: 150px;
margin-top: -219px;
width: 300px;
height: 300px;
background: #fff;
}
.changeCode {
position: absolute;
top: 80%;
left: 75%;
align-items: center;
font-size: 14px;
display: flex;
}
.inner-wrapper {
width: 29.6%;
position: absolute;
top: 46%;
right: 0;
transform: translateY(-50%);
}
.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;
.IBCRnamec{
margin-top: 15%;
height: 22px;
font-size: 22px;
letter-spacing: 1px;
font-family: PingFang SC;
font-weight: bold;
color: #0599F4;
line-height: 37px;
text-align: center;
margin-bottom: 0;
}
}
@keyframes waving2 {
from {
left: 0;
.IBCRnameE{
height: 9px;
font-size: 1px;
color: #0599F4;
line-height: 32px;
text-align: center;
}
to {
left: -9999px;
.rmpwdInput{
display: inline-block;
width: 20px;
height: 20px;
border-radius: 10px;
border: 1px solid #0599F4;
position: relative;
cursor: pointer;
margin-left: 8px;
span{
font-size: 12px;
color: #fff;
visibility: hidden;
position: absolute;
top: 3px;
left: -7px;
}
}
}
.form-control:focus {
border-color: #66afe9;
outline: 0;
-webkit-box-shadow: none;
box-shadow: none;
}
.inner-center {
display: flex;
flex-flow: column;
align-items: 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;
}
.APPCimg {
width: 138px;
height: 150px;
background: url('./images/3.png');
background-size: 100% 100%;
background-repeat: no-repeat;
display: none;
position: absolute;
top: 20px;
left: 50%;
transform: translateX(-50%);
padding: 23px 11px 12px;
span {
font-size: 12px;
opacity: 0.75;
.active{
display: inline-block;
width: 20px;
height: 20px;
border-radius: 10px;
border: 1px solid #0599F4;
position: relative;
cursor: pointer;
background-color: #0599F4;
margin-left: 10px;
span{
visibility: visible;
color: #fff;
font-size: 15px;
color: #fff;
position: absolute;
top: 3px;
left: 1px;
font-weight: bold;
}
}
.codeBox{
width: 34px;
height: 34px;
position: absolute;
right: -34px;
bottom: 0px;
background: rgba(255, 255, 255, 0.7);
padding: 6px;
border-radius: 0 3px 3px 0;
cursor: pointer;
}
.codeImg{
width: 23px;
}
.codeBig{
width: 128px;
height: 150px;
position: absolute;
bottom: 0;
left: 0px;
background: rgba(255, 255, 255, 0.7);
padding: 6px;
display: none;
justify-content: space-around;
span{
font-size: 12px;
font-weight: 100;
}
}
.codeBox:hover .codeBig{
display: block;
}
.codeBox:hover .codeImg{
display: none;
}
.codeText{
font-size: 14px;
font-family: PingFang SC;
font-weight: bold;
color: #121F2B;
text-align: center;
line-height: 24px;
}
.codeBox:hover .codeBig {
display: flex;
}
.IBtimeBox{
.TitleCont{
padding: 24px 0px 0px 32px;
img{
width: 496px;
height: 56px;
}
}
}
.IBTtime{
position: absolute;
width: 88px;
height: 26px;
font-size: 32px;
font-family: Microsoft YaHei UI;
font-weight: 400;
color: #FFFFFF;
line-height: 34px;
top: 34px;
right: 130px;
}
.IBTweek{
position: absolute;
top: 25px;
right: 69px;
height: 15px;
font-size: 16px;
font-family: Source Han Sans CN;
font-weight: 200;
color: #FFFFFF;
line-height: 30px;
}
.IBTdate{
position: absolute;
top: 46px;
right: 36px;
width: 80px;
height: 13px;
font-size: 14px;
font-family: Microsoft YaHei UI;
font-weight: 300;
color: #FFFFFF;
line-height: 30px;
}
}
.APPcodeBox:hover .APPCtext {
color: #1685FF;
}
.APPcodeBox:hover .APPCimg {
display: flex;
}
.APPCimg .codeCase {
text-align: center;
padding-top: 32px;
}
\ No newline at end of file
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, 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 classnames from 'classnames';
import moment from 'moment';
import QueueAnim from 'rc-queue-anim';
import defaultSetting from '../../../../../../../config/defaultSetting';
import LoginAction from '../../../login';
import styles from './index.less';
import Account from '../../../js/useAccount';
import { defaultApp } from '../../../../../../micro';
import logo from './images/logo.png';
import loginTitlePng from './images/text.png';
const Login = forwardRef((props, _ref) => {
const sliVerify = useRef();
const videoRef = useRef();
const loginFormRef = useRef();
const formRef = useRef(null);
const [status, setStatus] = useState('normal');
const [show, setShow] = useState(false);
const [autoLogin, setAutoLogin] = useState(false);
const [submitting, setSubmitting] = useState(false);
const [type, setType] = useState('Account');
const [visible, setVisible] = useState(false);
const [videoShow, setVideoShow] = useState(true);
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 7:
weekDayName = '周日';
break;
default:
weekDayName = '';
}
return weekDayName;
};
const onShow = () => {
if (!show) {
setShow(true);
}
};
const onended = () => {
if (videoShow) {
setVideoShow(false);
}
if (!show) {
setShow(true);
}
};
useEffect(() => {
setTimeout(() => {
if (videoRef && videoRef.current) {
videoRef.current.addEventListener('ended', () => {
onended();
});
}
});
return () => {
videoRef.current && videoRef.current.removeEventListener('ended', () => {});
};
}, [videoRef]);
useEffect(() => {
return () => {};
}, [show]);
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.dazulogin)} onClick={onShow}>
{show ? (
<>
<QueueAnim type="top">
<div key="outwrapper" className={styles.dazu_out_wrapper}>
<div className={styles.dazu_out_logo}>
<img src={logo} alt="logo" />
</div>
<div className={styles.dazu_out_title}>泽足水务</div>
</div>
</QueueAnim>
<QueueAnim type="scale" duration={1000}>
<div key={'innerwrapper'} className={classnames(styles['inner-wrapper'])}>
<div className={styles['inner-center']}>
<div className={styles['welcome-title']}>
<img src={loginTitlePng} alt="login-title" />
</div>
<div className={classnames(styles['inner-bg'], styles['login-part'])} ref={loginFormRef}>
{renderPlatform()}
</div>
</div>
</div>
</QueueAnim>
<div key="loginheader" className={classnames(styles['login-header'])}>
<QueueAnim type="left">
<div key="logintitle" className={styles['left-title']}>
<div>
<img src={logo} alt="logo" />
</div>
<div className={styles['cn-title']}>重庆泽足水务投资建设有限公司综合管理平台</div>
</div>
</QueueAnim>
<QueueAnim type="right">
<div key="logintime" 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>
</QueueAnim>
</div>
</>
) : null}
{videoShow ? (
<video
src={require('@/assets/videos/dazu.mp4')}
className={styles.videLayer}
autoPlay="autoPlay"
muted
playsInline="playsinline"
ref={videoRef}
/>
) : null}
<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));
@font-face {
font-family: PingFang SC;
src: url('@/assets/fonts/PingFang.ttf');
}
.dazulogin {
width: 100%;
height: 100%;
background: radial-gradient(#fff 5%, rgba(162, 215, 245, 1) 100%);
position: relative;
min-height: 7.0rem;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
.caseHide {
display: none !important;
}
.videLayer {
width: 100vw;
height: 100vh;
position: absolute;
top: 0;
left: 0;
object-fit: fill;
}
.dazu_out_wrapper {
box-sizing: border-box;
width: 500px;
position: absolute;
top: 120px;
left: calc(50% - 250px);
display: flex;
justify-content: center;
align-items: center;
padding: 10px 0;
z-index: 50;
.dazu_out_title {
font-size: 72px;
font-family: PingFang SC;
font-weight: 800;
color: #265499;
line-height: 1;
margin-left: 20px;
}
}
.inner-bg {
width: 100%;
height: 100%;
&>div {
width: 80%;
margin: 10%;
}
}
.inner-wrapper {
position: absolute;
display: flex;
justify-content: center;
align-items: center;
top: 250px;
left: calc(50% - 240px);
z-index: 50;
}
.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: 480px;
height: 380px;
background: rgba(255, 255, 255, 0.9);
border: 1px solid #FFFFFF;
box-shadow: 1px 1px 12px -3px #22222277;
border-radius: 8px 10px 10px 10px;
}
.welcome-title {
background: linear-gradient(0deg, rgba(9, 128, 238, 1) 0%, rgba(0, 182, 251, 1) 100%);
height: 100px;
border-radius: 8px 8px 0px 0px;
text-align: center;
line-height: 70px;
padding: 16px;
img {
width: 434px;
}
}
.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 {
box-sizing: border-box;
width: 100%;
position: absolute;
top: 0;
left: 0;
height: 82px;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 22px;
z-index: 50;
// border-bottom: 1px solid rgba(255, 255, 255, 0.12);
.left-title {
display: flex;
justify-content: flex-start;
align-items: center;
img {
width: 40px;
}
.cn-title {
font-size: 30px;
font-family: PingFang SC;
line-height: 1;
font-weight: 800;
color: #265499;
margin-left: 10px;
}
}
.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: #265499;
}
.curr-week-date {
margin-left: 10px;
.curr-week {
font-size: 16px;
font-family: Microsoft YaHei;
font-weight: 400;
color: #265499;
}
.curr-date {
font-size: 14px;
font-family: Microsoft YaHei;
font-weight: 400;
color: #265499;
}
}
}
}
.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;
}
}
& :global {}
\ 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.
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.
import React, { forwardRef, useEffect, useRef, useState } from 'react';
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 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 logoPng from './images/9.png';
import img3 from './images/3.png';
import img4 from './images/4.png';
import img8 from './images/8.png';
import img10 from './images/10.png';
import qrcodePng from './images/qrcode.png';
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 [isLoginPage, setIsLoginPage] = useState(true);
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
}
const switchPanel =() => {
setIsLoginPage(!isLoginPage)
}
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.lixianlogin, "lixian")}>
<div className={styles['inner-wrapper']}>
{/* <div className={styles['left-imgbox']}></div> */}
<div className={styles['inner-center']}>
<div className={styles['welcome-title']}>
<img src={img3} alt=''/>
<img src={img8} alt=''/>
<img src={img4} alt=''/>
</div>
{
isLoginPage ?
<div className={classnames(styles['inner-bg'], styles['login-part'])} ref={loginFormRef}>
{renderPlatform()}
<div className={styles['scan-code']} onClick={switchPanel}>
扫码下载APP
</div>
</div>
:
<div className={classnames(styles['inner-bg-download'], styles['login-part'])}>
<div className={styles['download-header']}>
<img src={img10} />
<span>扫码下载APP</span>
</div>
<img src={qrcodePng} alt="" className={styles['qrcode']}/>
<div className={styles['scan-code']} onClick={switchPanel}>
切换至登录界面
</div>
</div>
}
</div>
</div>
<div className={styles['login-header']}>
<div className={styles['left-title']}>
<img src={logoPng} alt='logo' className={styles['logo-png']}/>
<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));
@font-face {
font-family: PingFang SC;
src: url('@/assets/fonts/PingFang.ttf');
}
.lixianlogin {
width: 100%;
height: 100%;
background: url('./images/7.png') no-repeat;
background-size: 100% 100%;
background-clip: border-box;
position: relative;
min-height: 7.0rem;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
.inner-bg {
width: 100%;
height: 290px;
background-color: #FFFFFF;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
&>div {
width: 70%;
margin: 0 auto;
}
}
.inner-bg-download{
width: 100%;
height: 290px;
background-color: #FFFFFF;
display: flex;
flex-direction: column;
justify-content: space-evenly;
align-items: center;
&>div {
width: 70%;
margin: 0 auto;
}
}
.inner-wrapper {
// width: 800px;
// height: 400px;
display: flex;
justify-content: center;
align-items: center;
border-radius: 10px;
// position: absolute;
// bottom: 20%;
// top: 46%;
// right: 0;
// transform: translateY(-50%);
}
.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;
}
.scan-code{
font-size: 14px;
font-family: Microsoft YaHei;
font-weight: 400;
text-decoration: underline;
color: #1685FF;
text-align: center;
width: 100%;
cursor: pointer;
}
.qrcode{
height: 150px;
}
.download-header{
display: flex;
justify-content: center;
align-items: center;
}
.inner-center {
position: relative;
width: 418px;
// height: 316px;
// background: rgba(255,255,255,1);
// border: 1px solid #FFFFFF;
// box-shadow: 0px 15px 15px 3px rgba(140,142,145,0.52);
border-radius: 12px;
}
.welcome-title{
width: 100%;
height: 83px;
line-height: 83px;
font-size: 24px;
font-family: PingFang SC;
font-weight: bold;
color: #000000;
opacity: 0.85;
text-align: center;
display: flex;
justify-content: space-between;
align-items: center;
background: linear-gradient(0deg, #0061E4 0%, #00CEFA 100%);
border-radius: 12px 12px 0px 0px;
padding: 0 38px;
}
.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: 15px;
left: 0px;
padding: 0 30px;
display: flex;
justify-content: space-between;
align-items: center;
.left-title{
display: flex;
justify-content: center;
align-items: center;
.cn-title{
font-size: 24px;
font-family: Microsoft YaHei;
font-weight: 400;
color: #FFFFFF;
text-shadow: 0px 2px 1px rgba(0,112,188,0.5);
margin-left: 13px;
}
.logo-png{
width: 32px;
height: 32px;
}
}
.right-timebox{
display: flex;
justify-content: center;
align-items: center;
height: 60px;
.curr-time{
width: 160px;
font-size: 36px;
font-family: Microsoft YaHei;
font-weight: 500;
color: #FFFFFF;
text-align: right;
}
.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;
}
}
: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;
}
}
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
......@@ -58,9 +58,17 @@ export const AppInitState = () => {
const client = value && value !== 'undefined' ? value : 'city';
return client;
};
const getUrlToken = () => {
const value = params.getParams('token');
const token = value && value !== 'undefined' ? value : null;
return token;
};
const client = getClient();
const token = getUrlToken();
if (sessionStorage.getItem('client') !== client) {
sessionStorage.setItem('client', client);
}
let config = window.globalConfig || {};
// eslint-disable-next-line no-undef, no-restricted-globals
createStoreage.remove(`__PANDA_STORE__${location.hostname}`);
......@@ -123,9 +131,13 @@ export const AppInitState = () => {
}
if (data.pwdRegex) {
localStorage.setItem('password_pwdRegex', data.pwdRegex);
} else {
localStorage.removeItem('password_pwdRegex');
}
if (data.pwdRegexTip) {
localStorage.setItem('password_pwdRegexTip', data.pwdRegexTip);
} else {
localStorage.removeItem('password_pwdRegexTip');
}
store.dispatch(
actionCreators.getConfig(
......@@ -158,7 +170,8 @@ export const AppInitState = () => {
initMicroApps();
}
// eslint-disable-next-line no-new
if (getToken()) {
// 增加免登判定
if (!token && getToken()) {
// eslint-disable-next-line no-new
const action = new Login(
{
......
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