Commit 6f7cb50e authored by 程恺文's avatar 程恺文
parents 0dac1009 74c00cba
Pipeline #67124 passed with stages
# Don't check auto-generated stuff into git # Don't check auto-generated stuff into git
coverage coverage
build build
node_modules
stats.json stats.json
.umi .umi
.umi-production .umi-production
...@@ -12,5 +12,10 @@ npm-debug.log ...@@ -12,5 +12,10 @@ npm-debug.log
src/umi src/umi
.vscode .vscode
civbase civbase
# dependencies
node_modules
npm-debug.log*
yarn-error.log
package-lock.json package-lock.json
yarn.lock yarn.lock
\ No newline at end of file
...@@ -53,6 +53,23 @@ module.exports = { ...@@ -53,6 +53,23 @@ module.exports = {
cssLoader: { cssLoader: {
modules: { modules: {
getLocalIdent: (context, _, localName) => { 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 ( if (
context.resourcePath.includes('node_modules') || context.resourcePath.includes('node_modules') ||
context.resourcePath.includes('ant.design.pro.less') || context.resourcePath.includes('ant.design.pro.less') ||
......
...@@ -106,16 +106,17 @@ ...@@ -106,16 +106,17 @@
"@babel/polyfill": "7.4.3", "@babel/polyfill": "7.4.3",
"@babel/runtime": "^7.10.5", "@babel/runtime": "^7.10.5",
"@esri/calcite-colors": "6.0.3", "@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/basictable": "^1.5.16",
"@wisdom-components/empty": "^1.4.1", "@wisdom-components/empty": "^1.4.1",
"@wisdom-map/amap": "1.1.0-beta.42", "@wisdom-map/amap": "1.1.0-beta.47",
"@wisdom-map/arcgismap": "1.4.0-84", "@wisdom-map/arcgismap": "1.4.0-120",
"@wisdom-map/basemap": "1.1.0-17", "@wisdom-map/basemap": "1.1.0-21",
"@wisdom-map/util": "^1.0.28-0", "@wisdom-map/util": "^1.0.28-0",
"@wisdom-utils/components": "0.1.279", "@wisdom-utils/components": "0.1.287",
"@wisdom-utils/runtime": "0.0.32", "@wisdom-utils/runtime": "0.0.38",
"@wisdom-utils/utils": "0.1.319", "@wisdom-utils/utils": "0.1.327",
"animate.css": "^4.1.1", "animate.css": "^4.1.1",
"antd": "4.21.2", "antd": "4.21.2",
"compression": "1.7.4", "compression": "1.7.4",
...@@ -142,6 +143,7 @@ ...@@ -142,6 +143,7 @@
"qiankun": "^2.4.6", "qiankun": "^2.4.6",
"qrcode.react": "^1.0.0", "qrcode.react": "^1.0.0",
"rc-cascader": "^2.3.2", "rc-cascader": "^2.3.2",
"rc-queue-anim": "^2.0.0",
"react": "17.0.2", "react": "17.0.2",
"react-activation": "^0.9.9", "react-activation": "^0.9.9",
"react-dom": "17.0.2", "react-dom": "17.0.2",
......
...@@ -14,6 +14,9 @@ ...@@ -14,6 +14,9 @@
}, },
{ {
"title": "节水主题一" "title": "节水主题一"
},
{
"title": "新春"
} }
] ]
} }
\ No newline at end of file
...@@ -14,6 +14,7 @@ instanceRequest.transformRequestURL = function(url) { ...@@ -14,6 +14,7 @@ instanceRequest.transformRequestURL = function(url) {
'/CityInterface/rest/services.svc/GetConfig', '/CityInterface/rest/services.svc/GetConfig',
'/PandaOMS/OMS/HostManager/GetGateWay', '/PandaOMS/OMS/HostManager/GetGateWay',
'/PandaCore/Identity/AuthorizationToken', '/PandaCore/Identity/AuthorizationToken',
'/PandaEnergy/WaterSaving/download',
'/PandaOMS/OMS/WebSite/GetConfig', '/PandaOMS/OMS/WebSite/GetConfig',
]; ];
if (excludeURL.includes(url)) { if (excludeURL.includes(url)) {
......
import { request } from '@wisdom-utils/utils'; import { request } from '@wisdom-utils/utils';
import * as constants from '../../constants'; import * as constants from '../../constants';
const API = { const API = {
GET_INFORMATION: GET_INFORMATION: '/PandaCore/GCK/Message/GetInformationInfo',
'/PandaCore/GCK/Message/GetInformationInfo', GET_INFORMATION_THREE: '/PandaOMS/OMS/MessageConfig/GetInformationInfo',
GET_MQTT_SITE_CODE: GET_MQTT_SITE_CODE: '/PandaOMS/OMS/HostManager/GetHostConfig',
'/PandaOMS/OMS/HostManager/GetEmqtConfig', GET_ALL_INFORMATION_INFO: '/PandaCore/GCK/Message/GetAllInformationInfo',
GET_ALL_INFORMATION_INFO: GET_ALL_INFORMATION_INFO_THREE: '/PandaOMS/OMS/MessageConfig/GetAllInformationInfo',
'/PandaCore/GCK/Message/GetAllInformationInfo', POST_INFORMATION_STATUS: '/PandaCore/GCK/Message/PostInformationStatus',
POST_INFORMATION_STATUS: POST_ADD_OPTIONS: '/CityInterface/rest/services/WisdomUnion.svc/CustomerManage/AddOption',
'/PandaCore/GCK/Message/PostInformationStatus', GET_CURRENT_INFO_TYPE: '/PandaCore/GCK/Message/GetCurrentInfoType',
POST_ADD_OPTIONS:
'/CityInterface/rest/services/WisdomUnion.svc/CustomerManage/AddOption',
GET_CURRENT_INFO_TYPE:
'/PandaCore/GCK/Message/GetCurrentInfoType',
}; };
const notificationService = { const notificationService = {
...@@ -23,7 +19,8 @@ const notificationService = { ...@@ -23,7 +19,8 @@ const notificationService = {
type: constants.REQUEST_HTTP, type: constants.REQUEST_HTTP,
}, },
getInformationInfo: { 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, method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_HTTP, type: constants.REQUEST_HTTP,
}, },
...@@ -33,7 +30,10 @@ const notificationService = { ...@@ -33,7 +30,10 @@ const notificationService = {
type: constants.REQUEST_HTTP, type: constants.REQUEST_HTTP,
}, },
getAllInformationInfo: { 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, method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_HTTP, type: constants.REQUEST_HTTP,
}, },
...@@ -49,5 +49,4 @@ const notificationService = { ...@@ -49,5 +49,4 @@ const notificationService = {
}, },
}; };
export default notificationService; export default notificationService;
This diff was suppressed by a .gitattributes entry.
...@@ -23,6 +23,7 @@ const ValidContainer = props => { ...@@ -23,6 +23,7 @@ const ValidContainer = props => {
let rules = localStorage.getItem('password_pwdRegex') ? localStorage.getItem('password_pwdRegex') : ''; let rules = localStorage.getItem('password_pwdRegex') ? localStorage.getItem('password_pwdRegex') : '';
const check = localStorage.getItem('password_token'); const check = localStorage.getItem('password_token');
const rulesTip = localStorage.getItem('password_pwdRegexTip') ? localStorage.getItem('password_pwdRegexTip') : ''; const rulesTip = localStorage.getItem('password_pwdRegexTip') ? localStorage.getItem('password_pwdRegexTip') : '';
const accessToken = localStorage.getItem('access_token') ? localStorage.getItem('access_token') : '';
let reg; let reg;
try { try {
reg = new RegExp(rules); reg = new RegExp(rules);
...@@ -36,7 +37,7 @@ const ValidContainer = props => { ...@@ -36,7 +37,7 @@ const ValidContainer = props => {
const tk = global.token; const tk = global.token;
// eslint-disable-next-line no-eval // eslint-disable-next-line no-eval
if (tk) { if (tk) {
if (check && check === true) { if (rules !== '' && check && check === accessToken) {
setNeedChangePassword(true); setNeedChangePassword(true);
} }
} }
......
...@@ -314,7 +314,7 @@ class NoticeIconView extends Component { ...@@ -314,7 +314,7 @@ class NoticeIconView extends Component {
this.renderSysPlatform(message); this.renderSysPlatform(message);
}; };
handlerUnknowDetail = message => { handlerUnknowDetail = (message, type) => {
// 需要有跳转路径 // 需要有跳转路径
if (!message.webPath) if (!message.webPath)
return notification.info({ message: '提示', duration: 3, description: '未配置跳转路径' }); return notification.info({ message: '提示', duration: 3, description: '未配置跳转路径' });
...@@ -343,8 +343,11 @@ class NoticeIconView extends Component { ...@@ -343,8 +343,11 @@ class NoticeIconView extends Component {
} }
params._source = '消息通知'; params._source = '消息通知';
params._target = message.webPath; params._target = message.webPath;
if (type) {
if (/civweb4/.test(targetMenuPath)) return true;
}
sessionStorage.setItem('routerParams', JSON.stringify(params)); sessionStorage.setItem('routerParams', JSON.stringify(params));
window.history.pushState(params, '', `/civbase/${targetMenuPath}`); window.history.pushState(params, '', `/civbase/${targetMenuPath}?v=${Date.now()}`);
} }
render() { render() {
......
import React, { import React, { useRef, useState } from 'react';
useRef,
useState,
} from 'react';
import { import { message, Popover } from 'antd';
message,
Popover,
} from 'antd';
import _ from 'lodash'; import _ from 'lodash';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import Icon from '@ant-design/icons'; import Icon from '@ant-design/icons';
import { import { AvatarDropdown as Avatar, useIntl } from '@wisdom-utils/components';
AvatarDropdown as Avatar,
useIntl,
} from '@wisdom-utils/components';
import HeaderSearch from '@wisdom-utils/components/lib/layout/components/HeaderSearch'; import HeaderSearch from '@wisdom-utils/components/lib/layout/components/HeaderSearch';
import { useHistory } from '@wisdom-utils/runtime'; import { useHistory } from '@wisdom-utils/runtime';
...@@ -112,7 +103,7 @@ const GlobalHeaderRight = props => { ...@@ -112,7 +103,7 @@ const GlobalHeaderRight = props => {
const handleFeedback = event => { const handleFeedback = event => {
event.stopPropagation(); 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 => { const handlerFavitor = event => {
......
...@@ -18,7 +18,6 @@ const App = props => { ...@@ -18,7 +18,6 @@ const App = props => {
useEffect(() => { useEffect(() => {
event.emit('loading', props.loading); event.emit('loading', props.loading);
}, [props.loading]); }, [props.loading]);
const metaSecurity = /https/.test(window.location.protocol) ? ( const metaSecurity = /https/.test(window.location.protocol) ? (
<meta httpEquiv="Content-Security-Policy" content="upgrade-insecure-requests" /> <meta httpEquiv="Content-Security-Policy" content="upgrade-insecure-requests" />
) : null; ) : null;
......
import { fromJS } from 'immutable'; import { fromJS } from 'immutable';
import Cookies from 'js-cookie'; import Cookies from 'js-cookie';
import { AppConfig, store, event, Storage, helpers } from '@wisdom-utils/utils'; 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 defaultSetting from '@wisdom-utils/components/lib/AppLayout/layouts/defaultSettings';
import _ from 'lodash'; import _ from 'lodash';
import memoized from 'nano-memoize'; import memoized from 'nano-memoize';
...@@ -42,7 +42,11 @@ const proxy = require('../../../../config/proxy'); ...@@ -42,7 +42,11 @@ const proxy = require('../../../../config/proxy');
const keywordStorage = new Storage(`__global_search_keywords__micro_${window.location.hostname}`); const keywordStorage = new Storage(`__global_search_keywords__micro_${window.location.hostname}`);
const recentVisitedStorage = new Storage(`__global_recent_visited__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 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'); Cookies.set('loginMode', Cookies.get('loginMode') || 'pdw');
export const initialState = fromJS({ export const initialState = fromJS({
globalConfig: {}, globalConfig: {},
......
...@@ -7,7 +7,9 @@ body, ...@@ -7,7 +7,9 @@ body,
height: 100%; height: 100%;
overflow: hidden; overflow: hidden;
} }
#app {
background: transparent!important;
}
* { * {
margin: 0; margin: 0;
padding: 0; padding: 0;
......
...@@ -2,14 +2,16 @@ import { request } from '@wisdom-utils/utils'; ...@@ -2,14 +2,16 @@ import { request } from '@wisdom-utils/utils';
import * as constants from '@wisdom-utils/components/lib/AppLayout/helpers/constants'; import * as constants from '@wisdom-utils/components/lib/AppLayout/helpers/constants';
const API = { const API = {
GET_INFORMATION: '/PandaCore/GCK/Message/GetInformationInfo', 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_INFORMATION_STATUS: '/PandaCore/GCK/Message/PostInformationStatus',
POST_ADD_OPTIONS: '/CityInterface/rest/services/WisdomUnion.svc/CustomerManage/AddOption', POST_ADD_OPTIONS: '/CityInterface/rest/services/WisdomUnion.svc/CustomerManage/AddOption',
}; };
const services = { const services = {
getInformationInfo: { 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, method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_HTTP, type: constants.REQUEST_HTTP,
}, },
...@@ -30,7 +32,7 @@ const services = { ...@@ -30,7 +32,7 @@ const services = {
}, },
}; };
export const postInformationStatus = (param) => export const postInformationStatus = param =>
request({ request({
url: API.POST_INFORMATION_STATUS, url: API.POST_INFORMATION_STATUS,
method: constants.REQUEST_METHOD_GET, method: constants.REQUEST_METHOD_GET,
......
...@@ -4,8 +4,7 @@ export const API = { ...@@ -4,8 +4,7 @@ export const API = {
IOT_CHANGE_PASSWORD: 'CityInterface/rest/services/OMS.svc/U_UpdatePasswordQuickGCK', IOT_CHANGE_PASSWORD: 'CityInterface/rest/services/OMS.svc/U_UpdatePasswordQuickGCK',
FILE_DOWNLOAD: '/cityinterface/rest/services/filedownload.svc/download', FILE_DOWNLOAD: '/cityinterface/rest/services/filedownload.svc/download',
UPDATE_AVATAR: '/CityInterface/rest/services/OMs.svc/U_EditUser', UPDATE_AVATAR: '/CityInterface/rest/services/OMs.svc/U_EditUser',
UPLOAD_FILE_URL: UPLOAD_FILE_URL: '/cityinterface/rest/services/filedownload.svc/uploadfile/个人信息/{path}/{filename}',
'/cityinterface/rest/services/filedownload.svc/uploadfile/个人信息/{path}/{filename}',
AVATAR_FILE_URL: '/cityinterface/rest/services/filedownload.svc/download', AVATAR_FILE_URL: '/cityinterface/rest/services/filedownload.svc/download',
GET_VERSION: '/CityInterface/rest/services/OMs.svc/U_GetVersion', GET_VERSION: '/CityInterface/rest/services/OMs.svc/U_GetVersion',
}; };
......
...@@ -17,7 +17,6 @@ export const MESSAGE_TYPE = { ...@@ -17,7 +17,6 @@ export const MESSAGE_TYPE = {
export const NEW_MESSAGE = 'NEW_MESSAGE'; export const NEW_MESSAGE = 'NEW_MESSAGE';
export const USERNAME = 'mao2080'; export const USERNAME = 'mao2080';
export const PASSWORD = '123'; export const PASSWORD = '123';
export const PLATFORM_LEVEL = '4'; export const PLATFORM_LEVEL = '4';
......
import React from 'react'; import React from 'react';
import { Badge, Button, ConfigProvider } from 'antd'; import { Badge, Button, ConfigProvider } from 'antd';
// eslint-disable-next-line import/no-unresolved
import classNames from 'classnames'; import classNames from 'classnames';
import useMergeValue from 'use-merge-value'; import useMergeValue from 'use-merge-value';
...@@ -40,8 +41,8 @@ const messageSvg = () => ( ...@@ -40,8 +41,8 @@ const messageSvg = () => (
/> />
</svg> </svg>
); );
const BellOutlined = (props) => <Icon component={messageSvg} {...props} />; const BellOutlined = props => <Icon component={messageSvg} {...props} />;
const NoticeIcon = (props) => { const NoticeIcon = props => {
const { getPrefixCls } = React.useContext(ConfigProvider.ConfigContext); const { getPrefixCls } = React.useContext(ConfigProvider.ConfigContext);
const prefixCls = props.prefixCls || getPrefixCls(); const prefixCls = props.prefixCls || getPrefixCls();
const btnPrefixCls = `${prefixCls}-head-notifier-button`; const btnPrefixCls = `${prefixCls}-head-notifier-button`;
...@@ -54,14 +55,12 @@ const NoticeIcon = (props) => { ...@@ -54,14 +55,12 @@ const NoticeIcon = (props) => {
} }
const panes = []; const panes = [];
React.Children.forEach(children, (child) => { React.Children.forEach(children, child => {
if (!child) { if (!child) {
return; return;
} }
const { list, title } = child.props; const { list, title } = child.props;
panes.push( panes.push(<NoticeList {...child.props} data={list} key={child} title={title} config={props.config} />);
<NoticeList {...child.props} data={list} key={child} title={title} config={props.config} />,
);
}); });
const childProps = panes.length === 1 ? panes[0].props : { list: [] }; const childProps = panes.length === 1 ? panes[0].props : { list: [] };
return ( return (
...@@ -72,7 +71,9 @@ const NoticeIcon = (props) => { ...@@ -72,7 +71,9 @@ const NoticeIcon = (props) => {
type="link" type="link"
onClick={() => (childProps.list.length > 0 ? confirmRead(true) : null)} onClick={() => (childProps.list.length > 0 ? confirmRead(true) : null)}
disabled={childProps.list.length === 0} disabled={childProps.list.length === 0}
>全部标记已读</Button> >
全部标记已读
</Button>
</div> </div>
{panes} {panes}
{renderFooter && renderFooter()} {renderFooter && renderFooter()}
......
import React from 'react'; import React from 'react';
import { List, Spin, ConfigProvider } from 'antd'; import { List, Spin, ConfigProvider } from 'antd';
// eslint-disable-next-line import/no-unresolved
import classNames from 'classnames'; import classNames from 'classnames';
import './style/list.less'; import './style/list.less';
import { Alarm, Case, Notice, Unknown } from './templates'; import { Alarm, Case, Notice, Unknown } from './templates';
...@@ -11,10 +12,7 @@ const Empty = ({ emptyText, ...props }) => { ...@@ -11,10 +12,7 @@ const Empty = ({ emptyText, ...props }) => {
const prefixCls = props.prefixCls || getPrefixCls(); const prefixCls = props.prefixCls || getPrefixCls();
return ( return (
<div className={`${prefixCls}-notFound`}> <div className={`${prefixCls}-notFound`}>
<img <img src="https://gw.alipayobjects.com/zos/rmsportal/sAuJeJzSKbUmHfBQRzmZ.svg" alt="not found" />
src="https://gw.alipayobjects.com/zos/rmsportal/sAuJeJzSKbUmHfBQRzmZ.svg"
alt="not found"
/>
<div>{emptyText}</div> <div>{emptyText}</div>
</div> </div>
); );
...@@ -113,11 +111,11 @@ class NoticeList extends React.Component { ...@@ -113,11 +111,11 @@ class NoticeList extends React.Component {
switch (item.infoClasses) { switch (item.infoClasses) {
case MESSAGE_TYPE.ALARM_TYPE: case MESSAGE_TYPE.ALARM_TYPE:
messageTemplate = ( 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; break;
case MESSAGE_TYPE.CASE_TYPE: case MESSAGE_TYPE.CASE_TYPE:
messageTemplate = <Case message={item} confirmRead={this.confirmRead} />; messageTemplate = <Case message={item} confirmRead={this.confirmRead} handlerUnknowDetail={this.handlerUnknowDetail} />;
break; break;
case MESSAGE_TYPE.SYS_TYPE: case MESSAGE_TYPE.SYS_TYPE:
messageTemplate = ( messageTemplate = (
......
...@@ -12,6 +12,9 @@ class Message { ...@@ -12,6 +12,9 @@ class Message {
webConfig, webConfig,
webPath, webPath,
messType, messType,
defaultContent,
webIcon,
title,
infoClasses infoClasses
} = message) { } = message) {
this.id = id; this.id = id;
...@@ -23,6 +26,9 @@ class Message { ...@@ -23,6 +26,9 @@ class Message {
this.webConfig = webConfig; this.webConfig = webConfig;
this.webPath = webPath; this.webPath = webPath;
this.messType = messType; // 方案名称 - 大类型下细类型 this.messType = messType; // 方案名称 - 大类型下细类型
this.webIcon = webIcon; // 消息图标
this.title = title; // 消息标题
this.defaultContent = defaultContent;
this.infoClasses = infoClasses; this.infoClasses = infoClasses;
} }
} }
...@@ -64,6 +70,9 @@ export const createMessageFromHis = (hisMessage, options = {}) => { ...@@ -64,6 +70,9 @@ export const createMessageFromHis = (hisMessage, options = {}) => {
webConfig: hisMessage.web_config, webConfig: hisMessage.web_config,
webPath: hisMessage.web_path, webPath: hisMessage.web_path,
messType: hisMessage.messType, 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, infoClasses,
}; };
return createMessage(template); return createMessage(template);
...@@ -90,9 +99,9 @@ export const createMessageFromReal = (realMesssage, options = {}) => { ...@@ -90,9 +99,9 @@ export const createMessageFromReal = (realMesssage, options = {}) => {
// 2.0 消息 // 2.0 消息
infoContent = JSON.parse(realMesssage.content || '{}'); infoContent = JSON.parse(realMesssage.content || '{}');
} }
const template = { const template = {
id: realMesssage.infoId, id: realMesssage.infoId || realMesssage.ID,
infoContent, infoContent,
time, time,
infoType: realMesssage.infoType, infoType: realMesssage.infoType,
...@@ -100,7 +109,10 @@ export const createMessageFromReal = (realMesssage, options = {}) => { ...@@ -100,7 +109,10 @@ export const createMessageFromReal = (realMesssage, options = {}) => {
dateTime: realMesssage.createTime, dateTime: realMesssage.createTime,
webConfig: realMesssage.web_config, webConfig: realMesssage.web_config,
webPath: realMesssage.web_path, 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, infoClasses,
} }
......
...@@ -351,6 +351,8 @@ class Notifier { ...@@ -351,6 +351,8 @@ class Notifier {
} }
} catch (e) { } catch (e) {
Logger.error(`收到消息处理异常:${e.message}`); Logger.error(`收到消息处理异常:${e.message}`);
} finally {
window?.share?.event?.emit?.('event:messageArrived', buffer);
} }
} }
...@@ -449,8 +451,8 @@ class Notifier { ...@@ -449,8 +451,8 @@ class Notifier {
const alarmType = message?.infoContent?.alarmType; // 报警类型:“状态报警” const alarmType = message?.infoContent?.alarmType; // 报警类型:“状态报警”
const content = message?.infoContent?.alarmContent; // 报警内容:“出水超压报警” const content = message?.infoContent?.alarmContent; // 报警内容:“出水超压报警”
const alarmValue = message?.infoContent?.alarmValue ?? ''; // 报警值 const alarmValue = message?.infoContent?.alarmValue ?? ''; // 报警值
const level = message?.infoLevel !== '1' ? '紧急报警,紧急报警,紧急报警:' : ''
let msg = `紧急报警:${device},${alarmType},${content},报警值:${isString(alarmValue) ? replaceSpeak(alarmValue) :'' },请注意!!!`; let msg = `${level}${device},${alarmType},${content},报警值:${isString(alarmValue) ? replaceSpeak(alarmValue) :'' },请注意!!!`;
this.speak(msg); this.speak(msg);
}; };
speakCase = message => { speakCase = message => {
...@@ -473,12 +475,13 @@ class Notifier { ...@@ -473,12 +475,13 @@ class Notifier {
}; };
speakOther = message => { speakOther = message => {
// 类型区分‘全员公告’ 还是 ‘个人消息’ // 类型区分‘全员公告’ 还是 ‘个人消息’
const type = isEmpty(message.tousers) || parseMessage.tousers === '' ? '公告' : '消息'; const type = message.title ?? (isEmpty(message.tousers) || parseMessage.tousers === '' ? '公告' : '消息');
// 构建语音消息内容 // 构建语音消息内容
const { infoContent, time } = message; const { infoContent, time } = message;
let content = replaceSpeak((infoContent?.content ?? '').replace(/\\n/g, ',')); let content = replaceSpeak((infoContent?.content ?? message.defaultContent ?? '').replace(/\\n/g, ','));
let msg = `您有新的${type}${content.substring(0, content.lastIndexOf(',')).replace(':', ',')} 时间:${time}`; const text = content.substring(0, content.lastIndexOf(',')).replace(':', ',');
let msg = `您有新的${type}${text !== '' ? text : content} 时间:${time}`;
this.speak(msg); this.speak(msg);
}; };
......
import React from 'react'; import React from 'react';
import _ from 'lodash'; import _ from 'lodash';
// eslint-disable-next-line import/no-unresolved
import classNames from 'classnames'; import classNames from 'classnames';
import { findPathByWidget, isJSON } from '@wisdom-utils/components/lib/AppLayout/helpers'; import { findPathByWidget, isJSON } from '@wisdom-utils/components/lib/AppLayout/helpers';
import '../styles/common.less'; import '../styles/common.less';
import './index.less'; import './index.less';
import { ConfigProvider } from 'antd'; import { ConfigProvider } from 'antd';
import { getMessageTypeIcon } from '../../utils';
/* eslint-disable */ /* eslint-disable */
export class AlarmContent { export class AlarmContent {
constructor({ constructor({
...@@ -26,7 +28,7 @@ export class AlarmContent { ...@@ -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 { getPrefixCls } = React.useContext(ConfigProvider.ConfigContext);
const prefixCls = getPrefixCls(); const prefixCls = getPrefixCls();
...@@ -39,20 +41,22 @@ const Alarm = ({ message, confirmRead, config }) => { ...@@ -39,20 +41,22 @@ const Alarm = ({ message, confirmRead, config }) => {
const alarmThreshold = message?.infoContent?.alarmThreshold; const alarmThreshold = message?.infoContent?.alarmThreshold;
const goPath = (item) => { 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]); 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 }) => { ...@@ -62,6 +66,7 @@ const Alarm = ({ message, confirmRead, config }) => {
className={classNames(`${prefixCls}-notifier-message_scada`, `${prefixCls}-notifier-message-container`)} className={classNames(`${prefixCls}-notifier-message_scada`, `${prefixCls}-notifier-message-container`)}
title="点击查看详情" title="点击查看详情"
onClick={() => goPath(message)} onClick={() => goPath(message)}
style={{ backgroundImage: `url(${getMessageTypeIcon(message)})` }}
> >
<div className={`${prefixCls}-notifier-message-title`}> <div className={`${prefixCls}-notifier-message-title`}>
<span>{alarmType}</span> <span>{alarmType}</span>
......
import React from 'react'; import React from 'react';
import { ConfigProvider } from 'antd'; import { ConfigProvider } from 'antd';
// eslint-disable-next-line import/no-unresolved
import classNames from 'classnames'; import classNames from 'classnames';
import '../styles/common.less'; import '../styles/common.less';
import './index.less'; import './index.less';
import { getMessageTypeIcon } from '../../utils';
// "caseType":"待办工单","flowName":"维修处理流程","nodeName":"审核关单","content":"请迅速到现场处理","time":"2020-11-03 09:11:12" // "caseType":"待办工单","flowName":"维修处理流程","nodeName":"审核关单","content":"请迅速到现场处理","time":"2020-11-03 09:11:12"
export class CaseContent { export class CaseContent {
...@@ -17,7 +19,7 @@ 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 { getPrefixCls } = React.useContext(ConfigProvider.ConfigContext);
const prefixCls = getPrefixCls(); const prefixCls = getPrefixCls();
const caseType = message?.infoContent?.caseType; const caseType = message?.infoContent?.caseType;
...@@ -27,34 +29,36 @@ const Case = ({ message, confirmRead }) => { ...@@ -27,34 +29,36 @@ const Case = ({ message, confirmRead }) => {
const content = message?.infoContent?.content; const content = message?.infoContent?.content;
const goPath = item => { const goPath = item => {
confirmRead(false, [message.id]); if (handlerUnknowDetail && handlerUnknowDetail(message, 'case')) {
const messageType = item.messType; const messageType = item.messType;
let label = ''; let label = '';
let widgetID = ''; let widgetID = '';
switch (messageType) { switch (messageType) {
case '任务派发': case '任务派发':
label = '任务派发'; label = '任务派发';
widgetID = 'widget_city_综合运营_二供管理_维修管理_工单办理'; widgetID = 'widget_city_综合运营_二供管理_维修管理_工单办理';
break; break;
case '任务驳回': case '任务驳回':
label = '任务驳回'; label = '任务驳回';
widgetID = 'widget_city_综合运营_二供管理_维修管理_工单办理'; widgetID = 'widget_city_综合运营_二供管理_维修管理_工单办理';
// eslint-disable-next-line no-underscore-dangle,no-case-declarations // eslint-disable-next-line no-underscore-dangle,no-case-declarations
let _tab; let _tab;
// eslint-disable-next-line prefer-const // eslint-disable-next-line prefer-const
_tab = '任务驳回'; _tab = '任务驳回';
break; break;
default: default:
label = '工单办理'; label = '工单办理';
widgetID = 'widget_city_综合运营_二供管理_维修管理_工单办理'; widgetID = 'widget_city_综合运营_二供管理_维修管理_工单办理';
break; 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'; confirmRead(false, [message.id]);
window.share.event.emit('listenerMointer', {
widgetId: widgetID,
label,
url: webPath,
});
}; };
return ( return (
...@@ -62,6 +66,7 @@ const Case = ({ message, confirmRead }) => { ...@@ -62,6 +66,7 @@ const Case = ({ message, confirmRead }) => {
className={classNames(`${prefixCls}-notifier-message_case`, `${prefixCls}-notifier-message-container`)} className={classNames(`${prefixCls}-notifier-message_case`, `${prefixCls}-notifier-message-container`)}
title="点击查看详情" title="点击查看详情"
onClick={() => goPath(message)} onClick={() => goPath(message)}
style={{ backgroundImage: `url(${getMessageTypeIcon(message)})` }}
> >
<div className={`${prefixCls}-notifier-message-title`}> <div className={`${prefixCls}-notifier-message-title`}>
<span>{caseType}</span> <span>{caseType}</span>
...@@ -72,7 +77,9 @@ const Case = ({ message, confirmRead }) => { ...@@ -72,7 +77,9 @@ const Case = ({ message, confirmRead }) => {
e.stopPropagation(); e.stopPropagation();
confirmRead(false, [message.id]); confirmRead(false, [message.id]);
}} }}
// eslint-disable-next-line global-require
src={require('../../images/oper/ok_line.png')} src={require('../../images/oper/ok_line.png')}
alt=""
/> />
</div> </div>
<div className={`${prefixCls}-notifier-message-content`}> <div className={`${prefixCls}-notifier-message-content`}>
......
import React from 'react'; import React from 'react';
import { ConfigProvider } from 'antd'; import { ConfigProvider } from 'antd';
// eslint-disable-next-line import/no-unresolved
import classNames from 'classnames'; import classNames from 'classnames';
import '../styles/common.less'; import '../styles/common.less';
import './index.less'; import './index.less';
import { getMessageTypeIcon } from '../../utils';
export class NoticeContent { export class NoticeContent {
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
...@@ -15,7 +16,6 @@ export class NoticeContent { ...@@ -15,7 +16,6 @@ export class NoticeContent {
} }
} }
const Notice = ({ message, confirmRead, config, handlerSysDetail }) => { const Notice = ({ message, confirmRead, config, handlerSysDetail }) => {
const { getPrefixCls } = React.useContext(ConfigProvider.ConfigContext); const { getPrefixCls } = React.useContext(ConfigProvider.ConfigContext);
const prefixCls = getPrefixCls(); const prefixCls = getPrefixCls();
...@@ -25,26 +25,31 @@ const Notice = ({ message, confirmRead, config, handlerSysDetail }) => { ...@@ -25,26 +25,31 @@ const Notice = ({ message, confirmRead, config, handlerSysDetail }) => {
const noticeContent = message?.infoContent?.noticeContent ?? ''; const noticeContent = message?.infoContent?.noticeContent ?? '';
// const remark = message?.infoContent?.remark; // const remark = message?.infoContent?.remark;
const goPath = (item) => { const goPath = item => {
confirmRead(false, [message.id]); confirmRead(false, [message.id]);
handlerSysDetail && handlerSysDetail(message); handlerSysDetail && handlerSysDetail(message);
}; };
return ( return (
<div <div
className={classNames(`${prefixCls}-notifier-message_notice`, `${prefixCls}-notifier-message-container`)} className={classNames(`${prefixCls}-notifier-message_notice`, `${prefixCls}-notifier-message-container`)}
title="点击查看详情" title="点击查看详情"
onClick={() => goPath(message)} onClick={() => goPath(message)}
style={{ backgroundImage: `url(${getMessageTypeIcon(message)})` }}
> >
<div className={`${prefixCls}-notifier-message-title`}> <div className={`${prefixCls}-notifier-message-title`}>
<span>{noticeType}{noticeTitle ? `:${noticeTitle}` : ''}</span> <span>
{noticeType}
{noticeTitle ? `:${noticeTitle}` : ''}
</span>
<img <img
className={`${prefixCls}-notifier-message-confirm`} className={`${prefixCls}-notifier-message-confirm`}
title="点击标为已读" title="点击标为已读"
onClick={(e) => { onClick={e => {
e.stopPropagation(); e.stopPropagation();
confirmRead(false, [message.id]); confirmRead(false, [message.id]);
}} }}
// eslint-disable-next-line global-require
src={require('../../images/oper/ok_line.png')} src={require('../../images/oper/ok_line.png')}
alt="" alt=""
/> />
...@@ -52,7 +57,7 @@ const Notice = ({ message, confirmRead, config, handlerSysDetail }) => { ...@@ -52,7 +57,7 @@ const Notice = ({ message, confirmRead, config, handlerSysDetail }) => {
<div className={`${prefixCls}-notifier-message-content`}> <div className={`${prefixCls}-notifier-message-content`}>
<p>{noticeContent}</p> <p>{noticeContent}</p>
</div> </div>
<p className={`${prefixCls}-notifier-message-time`}>{message.time}</p> <p className={`${prefixCls}-notifier-message-time`}>{message.time}</p>
</div> </div>
); );
}; };
......
import React from 'react'; import React from 'react';
import { ConfigProvider } from 'antd'; import { ConfigProvider } from 'antd';
// eslint-disable-next-line import/no-unresolved
import classNames from 'classnames'; import classNames from 'classnames';
import '../styles/common.less'; import '../styles/common.less';
...@@ -11,24 +12,23 @@ const Unknown = ({ message, confirmRead, handlerUnknowDetail }) => { ...@@ -11,24 +12,23 @@ const Unknown = ({ message, confirmRead, handlerUnknowDetail }) => {
const prefixCls = getPrefixCls(); const prefixCls = getPrefixCls();
let content = ''; let content = '';
let noticeTitle = ''; let noticeTitle = '';
const { infoContent } = message;
try { try {
const type = typeof message.infoContent; const type = typeof message.infoContent;
switch (type) { switch (type) {
case 'object': case 'object':
let { infoContent } = message; noticeTitle = message.title || infoContent.title || '';
noticeTitle = infoContent.title || ''; content = infoContent.content || message.defaultContent || JSON.stringify(message.infoContent);
content = infoContent.content || JSON.stringify(message.infoContent);
break;
case 'string':
content = message.infoContent;
break; break;
default: default:
noticeTitle = message.title || '';
content = message.defaultContent || message.infoContent;
break; break;
} }
} catch (e) { } catch (e) {
// i // i
} }
const goPath = (item) => { const goPath = item => {
handlerUnknowDetail && handlerUnknowDetail(message); handlerUnknowDetail && handlerUnknowDetail(message);
confirmRead(false, [message.id]); confirmRead(false, [message.id]);
}; };
...@@ -37,17 +37,18 @@ const Unknown = ({ message, confirmRead, handlerUnknowDetail }) => { ...@@ -37,17 +37,18 @@ const Unknown = ({ message, confirmRead, handlerUnknowDetail }) => {
className={classNames(`${prefixCls}-notifier-message_unknown`, `${prefixCls}-notifier-message-container`)} className={classNames(`${prefixCls}-notifier-message_unknown`, `${prefixCls}-notifier-message-container`)}
title="点击查看详情" title="点击查看详情"
onClick={() => goPath(message)} onClick={() => goPath(message)}
style={{backgroundImage: `url(${getMessageTypeIcon(message.messType)})`}} style={{ backgroundImage: `url(${getMessageTypeIcon(message)})` }}
> >
<div className={`${prefixCls}-notifier-message-title`}> <div className={`${prefixCls}-notifier-message-title`}>
<span>{noticeTitle}</span> <span>{noticeTitle}</span>
<img <img
className={`${prefixCls}-notifier-message-confirm`} className={`${prefixCls}-notifier-message-confirm`}
title="点击标为已读" title="点击标为已读"
onClick={(e) => { onClick={e => {
e.stopPropagation(); e.stopPropagation();
confirmRead(false, [message.id]); confirmRead(false, [message.id]);
}} }}
// eslint-disable-next-line global-require
src={require('../../images/oper/ok_line.png')} src={require('../../images/oper/ok_line.png')}
alt="" alt=""
/> />
......
import { MESSAGE_TYPE } from '../constants'; import { MESSAGE_TYPE } from '../constants';
import parseMessageToJSON from './parse'; import parseMessageToJSON from './parse';
import alarm_icon from '../images/types/alarm.png'; import alarmIcon from '../images/types/alarm.png';
import approve_icon from '../images/types/approve.png'; import approveIcon from '../images/types/approve.png';
import meeting_icon from '../images/types/meeting.png'; import meetingIcon from '../images/types/meeting.png';
import notice_icon from '../images/types/notice.png'; import noticeIcon from '../images/types/notice.png';
import task_icon from '../images/types/task.png'; import taskIcon from '../images/types/task.png';
import work_icon from '../images/types/work.png'; import workIcon from '../images/types/work.png';
import write_icon from '../images/types/write.png'; import writeIcon from '../images/types/write.png';
import other_icon from '../images/types/other.png'; import otherIcon from '../images/types/other.png';
export const getMessageTypeIcon = messageType => { export const getMessageTypeIcon = message => {
let icon = other_icon; 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) return icon;
if (messageType === '工时填报') { if (messageType === '工时填报') {
icon = write_icon; icon = writeIcon;
} else if (messageType.indexOf('审批') > -1) { } else if (messageType.indexOf('审批') > -1) {
icon = approve_icon; icon = approveIcon;
} else if (messageType.indexOf('会议') > -1) { } else if (messageType.indexOf('会议') > -1) {
icon = meeting_icon; icon = meetingIcon;
} else if (messageType.indexOf('任务') > -1) { } else if (messageType.indexOf('任务') > -1) {
icon = task_icon; icon = taskIcon;
} }
return icon; return icon;
}; };
export const getMessageClasses = messageType => { export const getMessageClasses = messageType => {
let infoType = ''; let infoType = '';
switch (messageType) { switch (messageType) {
// 报警类 // 报警类
case 'SCADA报警': case 'SCADA报警':
case '通用报警': case '通用报警':
infoType = MESSAGE_TYPE.ALARM_TYPE; infoType = MESSAGE_TYPE.ALARM_TYPE;
break; break;
// 工单类 // 工单类
case '工单流程': case '工单流程':
case '工单提醒': case '工单提醒':
infoType = MESSAGE_TYPE.CASE_TYPE; infoType = MESSAGE_TYPE.CASE_TYPE;
break; break;
// 系统消息类 // 系统消息类
case '系统通知': case '系统通知':
case '系统消息': case '系统消息':
infoType = MESSAGE_TYPE.SYS_TYPE; infoType = MESSAGE_TYPE.SYS_TYPE;
break; break;
// 其他类 // 其他类
default: default:
infoType = MESSAGE_TYPE.UNKNOWN; infoType = MESSAGE_TYPE.UNKNOWN;
break; break;
} }
return infoType; return infoType;
}; };
/** /**
* 消息语音单位转换 * 消息语音单位转换
* 说明:消息通过语音播放时,需要将一些字母单位转换成文字,不然会当做字母播放。 * 说明:消息通过语音播放时,需要将一些字母单位转换成文字,不然会当做字母播放。
...@@ -76,16 +82,17 @@ export const replaceSpeak = msg => { ...@@ -76,16 +82,17 @@ export const replaceSpeak = msg => {
return msg; return msg;
}; };
// eslint-disable-next-line arrow-body-style
export const generatedId = () => { export const generatedId = () => {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx' return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
.replace(/[xy]/g, function(c) { .replace(/[xy]/g, function(c) {
// eslint-disable-next-line no-bitwise
const r = (Math.random() * 16) | 0; const r = (Math.random() * 16) | 0;
// eslint-disable-next-line no-bitwise
const v = c === 'x' ? r : (r & 0x3) | 0x8; const v = c === 'x' ? r : (r & 0x3) | 0x8;
return v.toString(16); return v.toString(16);
}) })
.toUpperCase(); .toUpperCase();
}; };
export { export { parseMessageToJSON };
parseMessageToJSON,
}
\ No newline at end of file
This diff is collapsed.
...@@ -338,7 +338,7 @@ class Site { ...@@ -338,7 +338,7 @@ class Site {
loginSite[token] = site; loginSite[token] = site;
localStorage.setItem('loginSite', JSON.stringify(loginSite)); localStorage.setItem('loginSite', JSON.stringify(loginSite));
const self = this; const self = this;
self.props.updateCurrentIndex && self.props.updateCurrentIndex(-1); // self.props.updateCurrentIndex && self.props.updateCurrentIndex(-1);
const login = new Login(this.props, () => { const login = new Login(this.props, () => {
self.setLoading(false); self.setLoading(false);
self.getCityStationsForUser().then(res => { self.getCityStationsForUser().then(res => {
...@@ -373,6 +373,7 @@ class Site { ...@@ -373,6 +373,7 @@ class Site {
} }
changeGroup(event, item, onChangeVisible, actionRef) { changeGroup(event, item, onChangeVisible, actionRef) {
debugger
event.persist(); event.persist();
const site = item ? item.site : event.target.dataset.site; const site = item ? item.site : event.target.dataset.site;
const { loginName } = this.globalConfig.userInfo; const { loginName } = this.globalConfig.userInfo;
......
import React, { memo } from "react"; import React from 'react';
import SecurityLayout from "../../../layouts/SecurityLayout"; import SecurityLayout from '../../../layouts/SecurityLayout';
const HocContainer = Component => { const HocContainer = Component => props => (
return (props) => { <SecurityLayout>
return ( <Component {...props} />
<SecurityLayout> </SecurityLayout>
<Component {...props} /> );
</SecurityLayout>
)
}
}
export default HocContainer; export default HocContainer;
\ No newline at end of file
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 Iframe from 'react-iframe';
import Empty from '@wisdom-components/empty'; import Empty from '@wisdom-components/empty';
import styles from './index.less'; import styles from './index.less';
import Hoc from './HocContainer'; import Hoc from './HocContainer';
import useFullScreen from './useFullScreen';
const TabWidget = ({ params }) => { const TabWidget = props => {
const { linkUrl } = params || {}; 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 ( 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 ? ( {linkUrl ? (
<Iframe <Iframe
url={linkUrl} url={linkUrl}
...@@ -19,7 +35,7 @@ const TabWidget = ({ params }) => { ...@@ -19,7 +35,7 @@ const TabWidget = ({ params }) => {
styles={{ border: 'none' }} styles={{ border: 'none' }}
/> />
) : ( ) : (
<Empty description="配置url链接才能显示哦!"/> <Empty description="配置url链接才能显示哦!" />
)} )}
</div> </div>
); );
......
...@@ -3,4 +3,34 @@ ...@@ -3,4 +3,34 @@
height: 100%; height: 100%;
position: relative; position: relative;
overflow: hidden; 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;
This diff is collapsed.
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 'kit_logger';
import React, { import React, { useCallback, useEffect, useState } from 'react';
useCallback,
useEffect, import { Button, Form, Input, message } from 'antd';
useState,
} from 'react';
import {
Button,
Form,
Input,
message,
} from 'antd';
import omit from 'omit.js'; import omit from 'omit.js';
import { useIntl } from '@wisdom-utils/components'; import { useIntl } from '@wisdom-utils/components';
...@@ -26,12 +17,7 @@ import ItemMap from './map'; ...@@ -26,12 +17,7 @@ import ItemMap from './map';
const FormItem = Form.Item; const FormItem = Form.Item;
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
const Logger = logger('loginForm'); const Logger = logger('loginForm');
const getFormItemOptions = ({ const getFormItemOptions = ({ onChange, defaultValue, customProps = {}, rules }) => {
onChange,
defaultValue,
customProps = {},
rules,
}) => {
const options = { const options = {
rules: rules || customProps.rules, rules: rules || customProps.rules,
}; };
...@@ -78,7 +64,7 @@ const LoginItem = props => { ...@@ -78,7 +64,7 @@ const LoginItem = props => {
} }
}) })
.catch(error => { .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 => { ...@@ -98,7 +84,7 @@ const LoginItem = props => {
}, 1000); }, 1000);
} }
return () => clearInterval(interval); return () => clearInterval(interval);
}, [timing]); }, [props, timing]);
if (!name) { if (!name) {
return null; return null;
...@@ -114,7 +100,7 @@ const LoginItem = props => { ...@@ -114,7 +100,7 @@ const LoginItem = props => {
return Promise.resolve(); return Promise.resolve();
} }
// eslint-disable-next-line prefer-promise-reject-errors // 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 // eslint-disable-next-line no-shadow
const rules = [ const rules = [
...@@ -126,7 +112,7 @@ const LoginItem = props => { ...@@ -126,7 +112,7 @@ const LoginItem = props => {
delete options.rules; delete options.rules;
return ( return (
<FormItem shouldUpdate style={{marginBottom: '14px'}}> <FormItem shouldUpdate style={{ marginBottom: '14px' }}>
{({ getFieldValue, validateFields }) => ( {({ getFieldValue, validateFields }) => (
<> <>
<FormItem name={name} {...options} rules={rules}> <FormItem name={name} {...options} rules={rules}>
...@@ -147,8 +133,8 @@ const LoginItem = props => { ...@@ -147,8 +133,8 @@ const LoginItem = props => {
}} }}
> >
{timing {timing
? `${intl.formatMessage({id: 'pages.login.phoneLogin.sendCationCode'})}(${count})` ? `${intl.formatMessage({ id: 'pages.login.phoneLogin.sendCationCode' })}(${count})`
: intl.formatMessage({id: 'pages.login.phoneLogin.getVerificationCode'})} : intl.formatMessage({ id: 'pages.login.phoneLogin.getVerificationCode' })}
</Button> </Button>
</> </>
)} )}
...@@ -156,6 +142,13 @@ const LoginItem = props => { ...@@ -156,6 +142,13 @@ const LoginItem = props => {
); );
} }
if (type === 'Password') {
return (
<FormItem name={name} {...options}>
<Input.Password {...customProps} {...otherProps} />
</FormItem>
);
}
return ( return (
<FormItem name={name} {...options}> <FormItem name={name} {...options}>
<Input {...customProps} {...otherProps} /> <Input {...customProps} {...otherProps} />
...@@ -169,15 +162,7 @@ Object.keys(ItemMap).forEach(key => { ...@@ -169,15 +162,7 @@ Object.keys(ItemMap).forEach(key => {
const item = ItemMap[key]; const item = ItemMap[key];
LoginItems[key] = props => ( LoginItems[key] = props => (
<LoginContext.Consumer> <LoginContext.Consumer>
{context => ( {context => <LoginItem customProps={item.props} rules={item.rules} {...props} type={key} {...context} />}
<LoginItem
customProps={item.props}
rules={item.rules}
{...props}
type={key}
{...context}
/>
)}
</LoginContext.Consumer> </LoginContext.Consumer>
); );
}); });
......
...@@ -5,6 +5,8 @@ import { ...@@ -5,6 +5,8 @@ import {
MailOutlined, MailOutlined,
MobileOutlined, MobileOutlined,
UserOutlined, UserOutlined,
EyeInvisibleOutlined,
EyeTwoTone,
} from '@ant-design/icons'; } from '@ant-design/icons';
import styles from './index.less'; import styles from './index.less';
...@@ -27,9 +29,7 @@ export default { ...@@ -27,9 +29,7 @@ export default {
NewYearPassword: { NewYearPassword: {
props: { props: {
size: 'large', size: 'large',
prefix: ( prefix: <LockOutlined className={styles.prefixIcon} twoToneColor="#ff9600" />,
<LockOutlined className={styles.prefixIcon} twoToneColor="#ff9600" />
),
type: 'password', type: 'password',
id: 'password', id: 'password',
placeholder: '888888', placeholder: '888888',
...@@ -45,6 +45,7 @@ export default { ...@@ -45,6 +45,7 @@ export default {
props: { props: {
size: 'large', size: 'large',
prefix: <LockOutlined className={styles.prefixIcon} />, prefix: <LockOutlined className={styles.prefixIcon} />,
iconRender: visible => (visible ? <EyeTwoTone /> : <EyeInvisibleOutlined />),
type: 'password', type: 'password',
id: 'password', id: 'password',
placeholder: '888888', placeholder: '888888',
...@@ -90,9 +91,7 @@ export default { ...@@ -90,9 +91,7 @@ export default {
NewYearMobile: { NewYearMobile: {
props: { props: {
size: 'large', size: 'large',
prefix: ( prefix: <MobileOutlined className={styles.prefixIcon} twoToneColor="#ff9600" />,
<MobileOutlined className={styles.prefixIcon} twoToneColor="#ff9600" />
),
placeholder: 'mobile number', placeholder: 'mobile number',
id: 'mobile', id: 'mobile',
}, },
...@@ -110,9 +109,7 @@ export default { ...@@ -110,9 +109,7 @@ export default {
NewYearCaptcha: { NewYearCaptcha: {
props: { props: {
size: 'large', size: 'large',
prefix: ( prefix: <MailOutlined className={styles.prefixIcon} twoToneColor="#ff9600" />,
<MailOutlined className={styles.prefixIcon} twoToneColor="#ff9600" />
),
placeholder: '请输入短信验证码', placeholder: '请输入短信验证码',
}, },
rules: [ rules: [
......
/* /*
* @Author: 634665781 634665781@qq.com * @Author: 634665781 634665781@qq.com
* @Date: 2022-07-08 14:28:01 * @Date: 2022-07-08 14:28:01
* @LastEditors: 634665781 634665781@qq.com * @LastEditors: Please set LastEditors
* @LastEditTime: 2022-09-05 17:38:26 * @LastEditTime: 2023-01-13 10:01:40
* @FilePath: \CivWeb\src\pages\user\login\index.js * @FilePath: \CivWeb\src\pages\user\login\index.js
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/ */
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
import BaseLogin from './template/baseLogin'; import BaseLogin from './template/baseLogin';
import NewYear from './template/newYear'; import NewYear from './template/newYear';
import baseLoginNewYear from './template/baseLoginNewYear';
import InfoLogin from './template/infoLogin'; import InfoLogin from './template/infoLogin';
import Yulin from './template/yulin'; import Yulin from './template/yulin';
// import { useParams } from '@wisdom-utils/runtime'; // import { useParams } from '@wisdom-utils/runtime';
...@@ -23,8 +24,12 @@ import HuhehaoteLogin from './template/project/huhehaote'; ...@@ -23,8 +24,12 @@ import HuhehaoteLogin from './template/project/huhehaote';
import XinganLogin from './template/project/xingan'; import XinganLogin from './template/project/xingan';
import ErlianhaoteLogin from './template/project/erlianhaote'; import ErlianhaoteLogin from './template/project/erlianhaote';
import YixianLogin from './template/project/yixian'; 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'; import { AppInitState } from '../../../render';
const LoginTemplate = { const LoginTemplate = {
'新春.html': baseLoginNewYear,
'新春 - 智联.html': NewYear, '新春 - 智联.html': NewYear,
'Dark - IOTMultiLogin.html': BaseLogin, 'Dark - IOTMultiLogin.html': BaseLogin,
'Dark.html': BaseLogin, 'Dark.html': BaseLogin,
...@@ -42,6 +47,9 @@ const LoginTemplate = { ...@@ -42,6 +47,9 @@ const LoginTemplate = {
'项目 - 新干.html': XinganLogin, '项目 - 新干.html': XinganLogin,
'项目 - 二连浩特.html': ErlianhaoteLogin, '项目 - 二连浩特.html': ErlianhaoteLogin,
'项目 - 易县.html': YixianLogin, '项目 - 易县.html': YixianLogin,
'项目 - 蠡县.html': LixianLogin,
'项目 - 大足.html': DazuLogin,
'全景图.html': PanoramaLogin,
default: BaseLogin, default: BaseLogin,
}; };
/* eslint-disable */ /* eslint-disable */
......
...@@ -98,25 +98,30 @@ class Login { ...@@ -98,25 +98,30 @@ class Login {
site: this.getLocalSiteBytoken(token), site: this.getLocalSiteBytoken(token),
'request.preventCache': Date.now(), 'request.preventCache': Date.now(),
ignoreSite: true, ignoreSite: true,
}).then(response => { })
if (response && response.code === 0) { .then(response => {
self.globalConfig.userInfo = window?.globalConfig?.transformUserInfo?.(response.data) ?? {}; if (response && response.code === 0) {
self.updateConfig && self.updateConfig(self.globalConfig); self.globalConfig.userInfo = window?.globalConfig?.transformUserInfo?.(response.data) ?? {};
self.getUserInfoAndConfig(); self.updateConfig && self.updateConfig(self.globalConfig);
} else { self.getUserInfoAndConfig();
self.logout && self.logout(); } else {
if (params.getParams('token')) { self.logout && self.logout();
// token免登录失败,回到登录页,防止reload造成死循环 if (params.getParams('token')) {
window.location.href = `${window.location.origin}`; // token免登录失败,回到登录页,防止reload造成死循环
return false; window.location.href = `${window.location.origin}`;
} return false;
if (self.globalConfig.style === 'ios' && self.globalConfig.loginTemplate === 'IOSCloud.html') { }
window.location.href = `${window.location.origin}`; if (self.globalConfig.style === 'ios' && self.globalConfig.loginTemplate === 'IOSCloud.html') {
return false; window.location.href = `${window.location.origin}`;
return false;
}
window.location.reload();
} }
window.location.reload(); })
} .catch(error => {
}); this.handleLoginError();
Logger.log('获取用户配置失败');
});
} }
writeLogs() { writeLogs() {
...@@ -182,9 +187,8 @@ class Login { ...@@ -182,9 +187,8 @@ class Login {
getWebConfig(token, getIndustry) { getWebConfig(token, getIndustry) {
const self = this; const self = this;
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
// 获取网站配置的同时,预先获取到mqtt配置,注册进子应用 // 获取网站配置的同时,预先获取到mqtt配置,注册进子应用
Promise.all([ Promise.allSettled([
noticeService.getMqttSiteCode({ 'request.preventCache': Date.now() }), noticeService.getMqttSiteCode({ 'request.preventCache': Date.now() }),
getWebSiteConfig({ getWebSiteConfig({
client: self.globalConfig.client, client: self.globalConfig.client,
...@@ -193,17 +197,26 @@ class Login { ...@@ -193,17 +197,26 @@ class Login {
}), }),
]) ])
.then(results => { .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) { 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 (Array.isArray(res.data) && res.data.length > 0) {
if (res.data[0]) { if (res.data[0]) {
const data = res.data[0]; const data = res.data[0];
mqttConfig.ipConfig = data;
mqttConfig.mqtt_IsSSL = data.IsSSL ? data.IsSSL : false; mqttConfig.mqtt_IsSSL = data.IsSSL ? data.IsSSL : false;
mqttConfig.mqtt_mess.site_code = data.SiteCode || self.globalConfig.userInfo.site; mqttConfig.mqtt_mess.site_code = data.SiteCode || self.globalConfig.userInfo.site;
mqttConfig.mqtt_mess.TcpIP = data.TcpIP; mqttConfig.mqtt_mess.TcpIP = data.TcpIP;
...@@ -237,7 +250,7 @@ class Login { ...@@ -237,7 +250,7 @@ class Login {
return results; return results;
}) })
.then(results => { .then(results => {
const response = results[1] ?? {}; const response = results[1]?.value ?? {};
const result = const result =
response && response.code === SERVICE_INTERFACE_SUCCESS_CODE response && response.code === SERVICE_INTERFACE_SUCCESS_CODE
? Array.isArray(response.data) ? Array.isArray(response.data)
...@@ -489,7 +502,7 @@ class Login { ...@@ -489,7 +502,7 @@ class Login {
id: 'wxlogin_container', id: 'wxlogin_container',
appid: 'wxec56ca668e7f9155', appid: 'wxec56ca668e7f9155',
agentid: '1000083', 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', href: 'https://mis.panda-water.cn/web4/styles/wx.css',
}); });
} }
...@@ -511,7 +524,7 @@ class Login { ...@@ -511,7 +524,7 @@ class Login {
if (url.indexOf('&code') !== -1) { if (url.indexOf('&code') !== -1) {
// 判断是否存在参数 // 判断是否存在参数
// eslint-disable-next-line no-useless-escape // eslint-disable-next-line no-useless-escape
url = url.replace(/(\&code|#)[^'"]*/, ''); // 去除参数 url = url.replace(/(\&code|#)[^'"]*/, '&code=success'); // 去除参数
window.history.pushState({}, 0, url); window.history.pushState({}, 0, url);
} }
self.isSignIn = true; self.isSignIn = true;
...@@ -701,11 +714,16 @@ class Login { ...@@ -701,11 +714,16 @@ class Login {
self.updateConfig && self.updateConfig(self.globalConfig); self.updateConfig && self.updateConfig(self.globalConfig);
} catch (error) { } catch (error) {
console.log(error); console.log(error);
message.error('登录失败');
if (self.goLogin()) { if (self.goLogin()) {
return false; return false;
} }
// self.handleLoginError(failCallback); // self.handleLoginError(failCallback);
} }
})
.catch(error => {
this.handleLoginError();
Logger.log('获取用户配置失败');
}); });
} else { } else {
self.handleLoginError(); self.handleLoginError();
...@@ -852,9 +870,12 @@ class Login { ...@@ -852,9 +870,12 @@ class Login {
rules = ''; rules = '';
reg = new RegExp(rules); reg = new RegExp(rules);
} }
const check = rules && rules !== '' && !reg.test(pwd) let check = false;
localStorage.setItem('access_token', response.access_token); if(rules !== '') check = !reg.test(pwd)
localStorage.setItem('password_token', check); 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, { Cookies.set('client', self.globalConfig.client, {
expires: exp / (24 * 60 * 60 * 1000), expires: exp / (24 * 60 * 60 * 1000),
path: '/', path: '/',
......
/* eslint-disable no-empty */
/* eslint-disable react-hooks/exhaustive-deps */
/* eslint-disable no-undef */
import '@wisdom-utils/utils/lib/helpers/format'; import '@wisdom-utils/utils/lib/helpers/format';
import { params } from '@wisdom-utils/utils/lib/helpers'; import { params } from '@wisdom-utils/utils/lib/helpers';
import React, { forwardRef, useEffect, useRef, useState } from 'react'; import React, { forwardRef, useEffect, useRef, useState } from 'react';
...@@ -8,10 +11,7 @@ import LoginAction from './login'; ...@@ -8,10 +11,7 @@ import LoginAction from './login';
import { defaultApp } from '../../../micro'; import { defaultApp } from '../../../micro';
const Login = forwardRef((props, _ref) => { const Login = forwardRef((props, _ref) => {
const history = useHistory(); const history = useHistory();
const [action, setAction] = useState( const [action, setAction] = useState(() => new LoginAction(Object.assign({}, props, { history }), () => {}, false));
() =>
new LoginAction(Object.assign({}, props, { history }), () => {}, false),
);
const [redirect] = useState(() => { const [redirect] = useState(() => {
const param = params.getParams('redirect')?.replaceAll(';', '&'); const param = params.getParams('redirect')?.replaceAll(';', '&');
return param ? decodeURIComponent(escape(param)) : null; return param ? decodeURIComponent(escape(param)) : null;
...@@ -21,31 +21,39 @@ const Login = forwardRef((props, _ref) => { ...@@ -21,31 +21,39 @@ const Login = forwardRef((props, _ref) => {
const hasLogin = useRef(); const hasLogin = useRef();
useEffect(() => { useEffect(() => {
action.globalConfig = props.global; action.globalConfig = props.global;
// eslint-disable-next-line no-prototype-builtins
if (props.global && props.global.hasOwnProperty('products') && hasLogin.current !== true) { if (props.global && props.global.hasOwnProperty('products') && hasLogin.current !== true) {
hasLogin.current = true; hasLogin.current = true;
action.init(); action.init();
} }
}, [action.globalConfig, props.global]); }, [action, action.globalConfig, props.global]);
useEffect(() => { useEffect(() => {
action && action &&
action.events.on('loginSuccess', event => { action.events.on('loginSuccess', event => {
// http://127.0.0.1:8080/civbase/civweb4/ // http://127.0.0.1:8080/civbase/civweb4/
// props.updateConfig(Object.assign({}, props.global, { props.updateConfig(
// homepage: params.getParams('redirect') Object.assign({}, window.globalConfig, {
// })); redirect,
// props.history.push('/' + params.getParams('redirect')) }),
props.history.push(
`/?client=${props.global.client}`,
); );
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); // window.share.event.emit('triggerMicro', props.global);
// initMicroApps(); // initMicroApps();
defaultApp(redirect); defaultApp(url);
}); });
return () => { return () => {
action && action.events && action.events.removeAllListeners('loginSuccess'); action && action.events && action.events.removeAllListeners('loginSuccess');
} };
}, [action, props.global.client, props.global.generateType, props.history]); }, [action, props.global.client, props.global.generateType, props.history, redirect]);
return <div>{props.children}</div>; return <div>{props.children}</div>;
}); });
......
...@@ -3,12 +3,14 @@ import 'kit_utils/lib/format'; ...@@ -3,12 +3,14 @@ import 'kit_utils/lib/format';
import React, { forwardRef, useEffect, useRef, useState } from 'react'; import React, { forwardRef, useEffect, useRef, useState } from 'react';
import { Modal } from 'antd'; import { Modal } from 'antd';
// eslint-disable-next-line import/no-unresolved
import classNames from 'classnames'; import classNames from 'classnames';
import { dom } from '@wisdom-utils/utils/lib/helpers'; import { dom } from '@wisdom-utils/utils/lib/helpers';
import { Helmet, HelmetProvider } from 'react-helmet-async'; import { Helmet, HelmetProvider } from 'react-helmet-async';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { useHistory } from '@wisdom-utils/runtime'; import { useHistory } from '@wisdom-utils/runtime';
import { actionCreators } from '@/containers/App/store'; import { actionCreators } from '@/containers/App/store';
import Cookies from 'js-cookie';
import defaultSetting from '../../../../../config/defaultSetting'; import defaultSetting from '../../../../../config/defaultSetting';
import LoginAction from '../login'; import LoginAction from '../login';
import styles from '../style.less'; import styles from '../style.less';
...@@ -32,11 +34,11 @@ const Login = forwardRef((props, _ref) => { ...@@ -32,11 +34,11 @@ const Login = forwardRef((props, _ref) => {
const [type, setType] = useState('Account'); const [type, setType] = useState('Account');
const [visible, setVisible] = useState(false); const [visible, setVisible] = useState(false);
const history = useHistory(); const history = useHistory();
const [action, setAction] = useState( const [action, setAction] = useState(() => new LoginAction(Object.assign({}, props, { history }), setVisible, false));
() => const [showVideo, setShowVideo] = useState(false);
new LoginAction(Object.assign({}, props, { history }), setVisible, false), let { ddCode } = props.global;
); const loginMode = Cookies.get('loginMode') || null;
if (loginMode && loginMode === 'iotWechat') ddCode = null;
// useEffect(() => { // useEffect(() => {
// action.globalConfig = props.global; // action.globalConfig = props.global;
// }, [props.global]); // }, [props.global]);
...@@ -116,22 +118,27 @@ const Login = forwardRef((props, _ref) => { ...@@ -116,22 +118,27 @@ const Login = forwardRef((props, _ref) => {
}, []); }, []);
useEffect(() => { useEffect(() => {
if (videoRef && videoRef.current) { if(ddCode && loginMode === 'qywx') {
videoRef.current.addEventListener('ended', function() { setShowVideo(false);
dom.removeClass(loginRef.current, styles.caseHide); } else {
dom.addClass(loginRef.current, styles.loginTimeShow); setShowVideo(true);
videoTimeout = setTimeout(() => { setTimeout(() => {
dom.removeClass(timeRef.current, styles.caseHide); if (videoRef && videoRef.current) {
dom.addClass(timeRef.current, 'animate__fadeIn'); videoRef.current.addEventListener('ended', function() {
dom.removeClass(loginRef.current, styles.caseHide);
dom.removeClass(loginFormRef.current, styles.caseHide); dom.addClass(loginRef.current, styles.loginTimeShow);
dom.addClass(loginFormRef.current, 'animate__fadeInUp'); videoTimeout = setTimeout(() => {
dom.removeClass(timeRef.current, styles.caseHide);
dom.removeClass(footerRef.current, styles.caseHide); dom.addClass(timeRef.current, 'animate__fadeIn');
dom.addClass(footerRef.current, 'animate__slideInUp'); dom.removeClass(loginFormRef.current, styles.caseHide);
dom.removeClass(titleRef.current, styles.caseHide); dom.addClass(loginFormRef.current, 'animate__fadeInUp');
dom.addClass(titleRef.current, 'animte__fadeInUp'); dom.removeClass(footerRef.current, styles.caseHide);
}, 500); 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) => { ...@@ -178,14 +185,14 @@ const Login = forwardRef((props, _ref) => {
<meta name="description" content={props.global.title || defaultSetting.title} /> <meta name="description" content={props.global.title || defaultSetting.title} />
</Helmet> </Helmet>
<div className={styles.main}> <div className={styles.main}>
<video {showVideo && <video
src={require("../../../../assets/videos/beforPage.mp4") } src={require("../../../../assets/videos/beforPage.mp4") }
className={styles.videLayer} className={styles.videLayer}
autoPlay="autoPlay" autoPlay="autoPlay"
muted muted
playsInline="playsinline" playsInline="playsinline"
ref={videoRef} ref={videoRef}
/> />}
<div className={styles.inner}> <div className={styles.inner}>
<div <div
className={classNames(styles.loginTime, styles.caseHide)} className={classNames(styles.loginTime, styles.caseHide)}
......
This diff is collapsed.
...@@ -10,7 +10,7 @@ const useWeCom = props => { ...@@ -10,7 +10,7 @@ const useWeCom = props => {
id: props.container || 'wxlogin_container', id: props.container || 'wxlogin_container',
appid: props.appid || WECOM_APPID, appid: props.appid || WECOM_APPID,
agentid: props.agentid || AGENTID_CLOUD, 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', href: props.href || 'https://panda-water.cn/web4/styles/wx.css',
self_redirect: false, self_redirect: false,
state: props.state || 'STATE', state: props.state || 'STATE',
...@@ -42,7 +42,7 @@ const useIOTQRCode = () => { ...@@ -42,7 +42,7 @@ const useIOTQRCode = () => {
container: 'wxlogin_container', container: 'wxlogin_container',
appid: WECOM_APPID, appid: WECOM_APPID,
agentid: AGENTID_CLOUD, 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', href: 'https://panda-water.cn/web4/styles/wecom.css',
state: rstate, state: rstate,
}, },
......
...@@ -16,7 +16,7 @@ import useRenderQcode from '../../js/useRenderQcode'; ...@@ -16,7 +16,7 @@ import useRenderQcode from '../../js/useRenderQcode';
import Account from '../../js/useAccount'; import Account from '../../js/useAccount';
import IotComponent from '../../js/useIOTComponent'; import IotComponent from '../../js/useIOTComponent';
import CloudForm from './cloudForm'; import CloudForm from './cloudForm';
import { initMicroApps } from '../../../../../micro'; import { defaultApp } from '../../../../../micro';
import useTime from '../../js/useTime'; import useTime from '../../js/useTime';
const isRQcodeFunc = loginFunc => { const isRQcodeFunc = loginFunc => {
...@@ -25,8 +25,10 @@ const isRQcodeFunc = loginFunc => { ...@@ -25,8 +25,10 @@ const isRQcodeFunc = loginFunc => {
}; };
const loginFuncImg = loginFunc => { const loginFuncImg = loginFunc => {
if (isRQcodeFunc(loginFunc)) { if (isRQcodeFunc(loginFunc)) {
// eslint-disable-next-line global-require
return require('@/assets/images/login/cloud/func_pwd.png'); return require('@/assets/images/login/cloud/func_pwd.png');
} }
// eslint-disable-next-line global-require
return require('@/assets/images/login/cloud/func_rqcode.png'); return require('@/assets/images/login/cloud/func_rqcode.png');
}; };
...@@ -48,7 +50,10 @@ const Login = forwardRef((props, _ref) => { ...@@ -48,7 +50,10 @@ const Login = forwardRef((props, _ref) => {
const [visible, setVisible] = useState(false); const [visible, setVisible] = useState(false);
const history = useHistory(); const history = useHistory();
const [action, setAction] = useState(() => new LoginAction(Object.assign({}, props, { history }), setVisible, true)); 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 => { const handleSubmit = values => {
/* eslint-disable */ /* eslint-disable */
action && action &&
...@@ -70,7 +75,8 @@ const Login = forwardRef((props, _ref) => { ...@@ -70,7 +75,8 @@ const Login = forwardRef((props, _ref) => {
props.updateCurrentIndex && props.updateCurrentIndex(0); props.updateCurrentIndex && props.updateCurrentIndex(0);
props.history.push(`/?client=${props.global.client}`); props.history.push(`/?client=${props.global.client}`);
// window.share.event.emit('triggerMicro', props.global); // window.share.event.emit('triggerMicro', props.global);
initMicroApps(); // initMicroApps();
defaultApp();
}); });
action && action &&
action.events.on('loginError', event => { action.events.on('loginError', event => {
...@@ -92,28 +98,34 @@ const Login = forwardRef((props, _ref) => { ...@@ -92,28 +98,34 @@ const Login = forwardRef((props, _ref) => {
let videoTimeout = null; let videoTimeout = null;
useEffect(() => { useEffect(() => {
if (videoRef && videoRef.current) { if(ddCode && loginMode === 'qywx') {
videoRef.current.addEventListener('ended', function() { setShowVideo(false);
dom.removeClass(loginRef.current, styles.caseHide); } else {
dom.addClass(loginRef.current, styles.loginTimeShow); setShowVideo(true);
videoTimeout = setTimeout(() => { setTimeout(() => {
dom.removeClass(timeRef.current, styles.caseHide); if (videoRef && videoRef.current) {
dom.addClass(timeRef.current, 'animate__fadeIn'); videoRef.current.addEventListener('ended', function() {
dom.removeClass(loginRef.current, styles.caseHide);
dom.removeClass(loginFormRef.current, styles.caseHide); dom.addClass(loginRef.current, styles.loginTimeShow);
dom.addClass(loginFormRef.current, 'animate__fadeInUp'); videoTimeout = setTimeout(() => {
dom.removeClass(timeRef.current, styles.caseHide);
dom.removeClass(footerRef.current, styles.caseHide); dom.addClass(timeRef.current, 'animate__fadeIn');
dom.addClass(footerRef.current, 'animate__slideInUp');
dom.removeClass(titleRef.current, styles.caseHide); dom.removeClass(loginFormRef.current, styles.caseHide);
dom.addClass(titleRef.current, 'animte__fadeInUp'); dom.addClass(loginFormRef.current, 'animate__fadeInUp');
}, 500);
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 () => { return () => {
videoTimeout && clearTimeout(videoTimeout); videoTimeout && clearTimeout(videoTimeout);
videoRef.current.removeEventListener('ended', () => {}); videoRef.current && videoRef.current.removeEventListener('ended', () => {});
}; };
}, [videoRef]); }, [videoRef]);
useEffect(() => { useEffect(() => {
...@@ -164,14 +176,17 @@ const Login = forwardRef((props, _ref) => { ...@@ -164,14 +176,17 @@ const Login = forwardRef((props, _ref) => {
<meta name="description" content={props.global.title || defaultSetting.title} /> <meta name="description" content={props.global.title || defaultSetting.title} />
</Helmet> </Helmet>
<div className={styles.main}> <div className={styles.main}>
<video {
src={require('@/assets/videos/beforPage.mp4')} showVideo && <video
className={styles.videLayer} src={require('@/assets/videos/beforPage.mp4')}
autoPlay="autoPlay" className={styles.videLayer}
muted autoPlay="autoPlay"
playsInline="playsinline" muted
ref={videoRef} playsInline="playsinline"
/> ref={videoRef}
/>
}
{/* main content */} {/* main content */}
<div className={styles.inner}> <div className={styles.inner}>
<div className={classNames(styles.loginTime, styles.caseHide)} ref={loginRef}> <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.
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 is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment