Commit 3572b06d authored by 邓晓峰's avatar 邓晓峰

fix industry

parent e020776b
This diff was suppressed by a .gitattributes entry.
export default {
navTheme: 'dark',
layout: 'side',
contentWidth: 'Fluid',
fixedHeader: false,
fixSiderbar: false,
menu: {
locale: true,
},
headerHeight: 48,
title: '熊猫智慧城市监控管理解决方案',
iconfontUrl: '',
primaryColor: '#1890ff',
};
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _default = {
navTheme: 'dark',
layout: 'side',
contentWidth: 'Fluid',
fixedHeader: false,
fixSiderbar: false,
menu: {
locale: true
},
headerHeight: 48,
title: '熊猫智慧城市监控管理解决方案',
iconfontUrl: '',
primaryColor: '#1890ff'
};
exports["default"] = _default;
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
function genActiveRule(routerPrefix) {
return function (location) {
return location.pathname.startsWith(routerPrefix);
};
}
var _default = {
dev: [{
name: 'web4_console',
entry: "//".concat(window.location.hostname, ":3020/civweb4"),
container: '#micro-container',
activeRule: genActiveRule('/civbase/civweb4'),
props: {}
}, {
name: 'civweb5',
entry: "//".concat(window.location.hostname, ":3008/civbase/civweb5"),
container: '#micro-container',
activeRule: genActiveRule('/civbase/civweb5')
}],
prod: [{
name: 'web4_console',
entry: "//".concat(window.location.host, "/civweb4"),
container: '#micro-container',
activeRule: genActiveRule('/civbase/civweb4'),
props: {}
}, {
name: 'civweb5',
entry: "//".concat(window.location.host, "/civweb5"),
container: '#micro-container',
activeRule: genActiveRule('/civbase/civweb5')
}]
};
exports["default"] = _default;
\ No newline at end of file
......@@ -3,7 +3,7 @@
module.exports = {
dev: {
'/CityInterface': {
target: 'http://192.168.10.150:8050',
target: 'http://192.168.10.151:8055',
// target: 'https://panda-water.cn',
// target: 'http://192.168.19.103:8112',
// target: 'http://192.168.12.8:8098',
......
function genActiveRule(routerPrefix) {
return location => location.pathname.startsWith(routerPrefix);
}
export default {
dev: [
{
name: 'web4_console',
entry: `//${window.location.hostname}:3020/civweb4`,
container: '#micro-container',
activeRule: genActiveRule('/civbase/civweb4'),
props: {},
},
{
name: 'civweb5',
entry: `//${window.location.hostname}:3008/civbase/civweb5`,
container: '#micro-container',
activeRule: genActiveRule('/civbase/civweb5'),
},
],
prod: [
{
name: 'web4_console',
entry: `//${window.location.host}/civweb4`,
container: '#micro-container',
activeRule: genActiveRule('/civbase/civweb4'),
props: {},
},
{
name: 'civweb5',
entry: `//${window.location.host}/civweb5`,
container: '#micro-container',
activeRule: genActiveRule('/civbase/civweb5'),
},
],
};
module.exports = {
dev: {
'/CityInterface': {
target: 'http://192.168.10.150:8050',
// target: 'https://panda-water.cn',
// target: 'http://192.168.10.151:8055',
target: 'https://panda-water.cn',
// target: 'http://192.168.19.103:8112',
// target: 'http://192.168.12.8:8098',
changeOrigin: true,
......@@ -14,8 +14,8 @@ module.exports = {
},
},
'/cityinterface': {
target: 'http://192.168.10.151:8055',
// target: 'https://panda-water.cn',
// target: 'http://192.168.10.151:8055',
target: 'https://panda-water.cn',
// target: 'http://192.168.12.8:8098',
changeOrigin: true,
headers: {
......
/**
*
* Tests for {{ properCase name }}
*
* @see https://github.com/react-boilerplate/react-boilerplate/tree/master/docs/testing
*
*/
*
* Tests for {{ properCase name }}
*
*
*/
import React from 'react';
import { render } from 'react-testing-library';
......@@ -18,44 +17,47 @@ import {{ properCase name }} from '../index';
import { DEFAULT_LOCALE } from '../../../i18n';
{{/if}}
describe('<{{ properCase name }} />', () => {
it('Expect to not log errors in console', () => {
const spy = jest.spyOn(global.console, 'error');
describe('
<{{ properCase name }} />', () => {
it('Expect to not log errors in console', () => {
const spy = jest.spyOn(global.console, 'error');
{{#if wantMessages}}
render(
<IntlProvider locale={DEFAULT_LOCALE}>
render(
<IntlProvider locale={DEFAULT_LOCALE}>
<{{ properCase name }} />
</IntlProvider>,
);
</IntlProvider>,
);
{{else}}
render(<{{ properCase name }} />);
render(
<{{ properCase name }} />);
{{/if}}
expect(spy).not.toHaveBeenCalled();
});
expect(spy).not.toHaveBeenCalled();
});
it('Expect to have additional unit tests specified', () => {
expect(true).toEqual(false);
});
it('Expect to have additional unit tests specified', () => {
expect(true).toEqual(false);
});
/**
* Unskip this test to use it
*
* @see {@link https://jestjs.io/docs/en/api#testskipname-fn}
*/
it.skip('Should render and match the snapshot', () => {
/**
* Unskip this test to use it
*
* @see {@link https://jestjs.io/docs/en/api#testskipname-fn}
*/
it.skip('Should render and match the snapshot', () => {
{{#if wantMessages}}
const {
container: { firstChild },
} = render(
<IntlProvider locale={DEFAULT_LOCALE}>
const {
container: { firstChild },
} = render(
<IntlProvider locale={DEFAULT_LOCALE}>
<{{ properCase name }} />
</IntlProvider>,
);
</IntlProvider>,
);
{{else}}
const {
container: { firstChild },
} = render(<{{ properCase name }} />);
const {
container: { firstChild },
} = render(
<{{ properCase name }} />);
{{/if}}
expect(firstChild).toMatchSnapshot();
});
expect(firstChild).toMatchSnapshot();
});
});
\ No newline at end of file
/**
*
* Tests for {{ properCase name }}
*
* @see https://github.com/react-boilerplate/react-boilerplate/tree/master/docs/testing
*
*/
*
* Tests for {{ properCase name }}
*
*
*/
import React from 'react';
import { render } from 'react-testing-library';
......@@ -18,45 +17,48 @@ import { {{ properCase name }} } from '../index';
import { DEFAULT_LOCALE } from '../../../i18n';
{{/if}}
describe('<{{ properCase name }} />', () => {
it('Expect to not log errors in console', () => {
const spy = jest.spyOn(global.console, 'error');
const dispatch = jest.fn();
describe('
<{{ properCase name }} />', () => {
it('Expect to not log errors in console', () => {
const spy = jest.spyOn(global.console, 'error');
const dispatch = jest.fn();
{{#if wantMessages}}
render(
<IntlProvider locale={DEFAULT_LOCALE}>
render(
<IntlProvider locale={DEFAULT_LOCALE}>
<{{ properCase name }} dispatch={dispatch} />
</IntlProvider>,
);
</IntlProvider>,
);
{{else}}
render(<{{ properCase name }} dispatch={dispatch} />);
render(
<{{ properCase name }} dispatch={dispatch} />);
{{/if}}
expect(spy).not.toHaveBeenCalled();
});
expect(spy).not.toHaveBeenCalled();
});
it('Expect to have additional unit tests specified', () => {
expect(true).toEqual(false);
});
it('Expect to have additional unit tests specified', () => {
expect(true).toEqual(false);
});
/**
* Unskip this test to use it
*
* @see {@link https://jestjs.io/docs/en/api#testskipname-fn}
*/
it.skip('Should render and match the snapshot', () => {
/**
* Unskip this test to use it
*
* @see {@link https://jestjs.io/docs/en/api#testskipname-fn}
*/
it.skip('Should render and match the snapshot', () => {
{{#if wantMessages}}
const {
container: { firstChild },
} = render(
<IntlProvider locale={DEFAULT_LOCALE}>
const {
container: { firstChild },
} = render(
<IntlProvider locale={DEFAULT_LOCALE}>
<{{ properCase name }} />
</IntlProvider>,
);
</IntlProvider>,
);
{{else}}
const {
container: { firstChild },
} = render(<{{ properCase name }} />);
const {
container: { firstChild },
} = render(
<{{ properCase name }} />);
{{/if}}
expect(firstChild).toMatchSnapshot();
});
expect(firstChild).toMatchSnapshot();
});
});
\ No newline at end of file
......@@ -8,6 +8,10 @@ var slash = require('slash2');
var pkg = require('../../package.json');
var CopyPlugin = require('copy-webpack-plugin');
var ASSET_PATH = process.env.ASSET_PATH || '/';
module.exports = function (options) {
return {
mode: options.mode,
......@@ -136,7 +140,12 @@ module.exports = function (options) {
// drop any unreachable code.
new webpack.EnvironmentPlugin({
NODE_ENV: 'development'
})]),
}), new webpack.DefinePlugin({
'process.env.ASSET_PATH': JSON.stringify(ASSET_PATH)
}), new CopyPlugin([{
from: path.resolve(process.cwd(), 'theme'),
to: path.resolve(process.cwd(), "".concat(pkg.name.toLocaleLowerCase(), "/theme"))
}])]),
resolve: {
modules: ['node_modules', 'src'],
extensions: ['.js', '.jsx', '.react.js'],
......
......@@ -2,7 +2,9 @@ const path = require('path');
const webpack = require('webpack');
const slash = require('slash2');
const pkg = require('../../package.json');
module.exports = (options) => ({
const CopyPlugin = require('copy-webpack-plugin');
const ASSET_PATH = process.env.ASSET_PATH || '/';
module.exports = options => ({
mode: options.mode,
entry: options.entry,
output: Object.assign(
......@@ -60,8 +62,8 @@ module.exports = (options) => ({
const antdProPath = match[1].replace('.less', '');
const arr = slash(antdProPath)
.split('/')
.map((a) => a.replace(/([A-Z])/g, '-$1'))
.map((a) => a.toLowerCase());
.map(a => a.replace(/([A-Z])/g, '-$1'))
.map(a => a.toLowerCase());
return `panda-pro${arr.join('-')}-${localName}`.replace(
/--/g,
'-',
......@@ -159,6 +161,18 @@ module.exports = (options) => ({
new webpack.EnvironmentPlugin({
NODE_ENV: 'development',
}),
new webpack.DefinePlugin({
'process.env.ASSET_PATH': JSON.stringify(ASSET_PATH),
}),
new CopyPlugin([
{
from: path.resolve(process.cwd(), 'theme'),
to: path.resolve(
process.cwd(),
`${pkg.name.toLocaleLowerCase()}/theme`,
),
},
]),
]),
resolve: {
modules: ['node_modules', 'src'],
......
This diff is collapsed.
......@@ -86,7 +86,6 @@
"chalk": "2.4.2",
"compression": "1.7.4",
"connected-react-router": "6.4.0",
"cross-env": "5.2.0",
"express": "4.16.4",
"fontfaceobserver": "2.1.0",
"history": "4.9.0",
......@@ -98,13 +97,14 @@
"ip": "1.1.5",
"js-base64": "^3.5.2",
"js-cookie": "^2.2.1",
"kit_global_config": "^1.0.5",
"kit_global_config": "^1.0.7",
"kit_utils": "^1.3.6",
"lodash": "4.17.11",
"minimist": "1.2.0",
"prop-types": "15.7.2",
"react": "16.8.6",
"react-dom": "16.8.6",
"qrcode.react": "^1.0.0",
"react": "16.12.0",
"react-dom": "16.12.0",
"react-helmet": "6.0.0-beta",
"react-intl": "2.8.0",
"react-redux": "7.0.2",
......@@ -120,6 +120,7 @@
"devDependencies": {
"@ant-design/icons": "^4.0.0",
"@ant-design/pro-layout": "^6.5.10",
"@ant-design/pro-skeleton": "^1.0.0-beta.2",
"@ant-design/pro-table": "^2.5.3",
"@babel/cli": "7.4.3",
"@babel/core": "7.4.3",
......@@ -133,6 +134,7 @@
"@babel/register": "7.4.0",
"@commitlint/cli": "^9.1.2",
"@commitlint/config-conventional": "^9.1.2",
"@umijs/hooks": "^1.9.3",
"add-asset-html-webpack-plugin": "3.1.3",
"antd": "^4.5.3",
"axios": "^0.19.2",
......@@ -152,8 +154,10 @@
"compression-webpack-plugin": "2.0.0",
"connect-api-mocker": "^1.9.0",
"conventional-changelog-cli": "^2.1.0",
"copy-webpack-plugin": "^5.0.4",
"core-js": "^3.6.5",
"coveralls": "3.0.3",
"cross-env": "^5.2.0",
"css-loader": "^4.2.1",
"cz-customizable": "^6.3.0",
"dumi": "^1.0.13",
......@@ -185,6 +189,7 @@
"lodash": "^4.17.11",
"mockjs": "^1.0.1-beta3",
"moment": "^2.25.3",
"nanoid": "^3.1.16",
"ngrok": "3.1.1",
"node-plop": "0.18.0",
"null-loader": "0.1.1",
......@@ -205,6 +210,7 @@
"react-dom": "^16.8.6",
"react-helmet-async": "^1.0.4",
"react-router-config": "^5.1.1",
"react-sticky": "^6.0.3",
"react-test-renderer": "16.8.6",
"react-testing-library": "6.1.2",
"redux-immutable": "^4.0.0",
......
......@@ -22,8 +22,8 @@ class HttpRequest {
// removeAllPending()
// }
// ------------------------------------------------------------------------------------
if (this.getSite()) {
config.headers['Civ-Site'] = this.getSite();
if (!config.ignoreSite && this.getSite()) {
config.headers['civ-site'] = this.getSite();
}
this.removePending(config); //在一个ajax发送前执行一下取消操作
config.cancelToken = new cancelToken(c => {
......
import { params } from 'kit_utils';
const API = {
GET_CONFIG: "/CityInterface/rest/services.svc/GetConfig",
GENERATE_TOKEN: "/cityinterface/rest/services.svc/generatetoken",
GET_CONFIG: '/CityInterface/rest/services.svc/GetConfig',
GENERATE_TOKEN: '/cityinterface/rest/services.svc/generatetoken',
GENERATE_TOKEN_CHANGE: '/cityinterface/rest/services.svc/generatetokenquick',
GET_WEB_SITE_CONFIG: '/CityInterface/rest/services.svc/GetWebSiteConfig',
GET_USER_INFO: '/CityInterface/rest/services.svc/getUserInfo',
GET_OA : '/CityInterface/rest/services/OA.svc/getLoginInfo',
GET_OA: '/CityInterface/rest/services/OA.svc/getLoginInfo',
GET_LOGS: '/CityInterface/rest/services/portal.svc/OMMonitor/SaveLoginInfo',
GET_INFORMATION: '/CityInterface/rest/services/CountyProduct.svc/SCADAOper/GetInformationInfo'
}
export default (vm) => {
vm.getConfig = (data = {client: params.getParams('client'), ts: Date.now() }) => vm.get(API.GET_CONFIG,data).then(res => Promise.resolve(res))
GET_INFORMATION:
'/CityInterface/rest/services/CountyProduct.svc/SCADAOper/GetInformationInfo',
GET_CITY: 'https://pv.sohu.com/cityjson?ie=utf-8',
GET_ALL_GROUPS_INFO_FORUSER: 'CityInterface/rest/Services/Portal.svc/AuthorityManage/GetAllGroupsInfoForUser',
GET_WEATHER: '/CityInterface/rest/services/CountyProduct.svc/GetWeather'
};
export default vm => {
vm.getConfig = (
data = { client: params.getParams('client') || 'city', ts: Date.now() },
) => vm.get(API.GET_CONFIG, data).then(res => Promise.resolve(res));
vm.generateToken = (data={}) => vm.get(API.GENERATE_TOKEN, data).then(res => Promise.resolve(res))
vm.generateToken = (data = {}) =>
vm.get(API.GENERATE_TOKEN, data).then(res => Promise.resolve(res));
vm.getWebSiteConfig = (data={}) => vm.get(API.GET_WEB_SITE_CONFIG, data).then(res => Promise.resolve(res))
vm.getWebSiteConfig = (data = {}) =>
vm.get(API.GET_WEB_SITE_CONFIG, data).then(res => Promise.resolve(res));
vm.getUserInfo = (data={}) => vm.get(API.GET_USER_INFO, data).then(res => Promise.resolve(res))
vm.getUserInfo = (data = {}) =>
vm.get(API.GET_USER_INFO, data).then(res => Promise.resolve(res));
vm.getOA = (data = {}) => vm.get(API.GET_OA, data).then(res => Promise.resolve(res))
vm.getOA = (data = {}) =>
vm.get(API.GET_OA, data).then(res => Promise.resolve(res));
vm.writeLogs = (data = {}, config = {}) => vm.post(API.GET_LOGS, data, config).then(res => Promise.resolve(res))
vm.writeLogs = (data = {}, config = {}) =>
vm.post(API.GET_LOGS, data, config).then(res => Promise.resolve(res));
vm.getInformationInfo = (data={}) => vm.get(API.GET_INFORMATION, data).then(res => Promise.resolve(res))
}
\ No newline at end of file
vm.getInformationInfo = (data = {}) =>
vm.get(API.GET_INFORMATION, data).then(res => Promise.resolve(res));
vm.getCity = () => vm.get(API.GET_CITY).then(res => Promise.resolve(res))
vm.generateTokenQuick = (data={}) => vm.get(API.GENERATE_TOKEN_CHANGE, data).then(res => Promise.resolve(res))
vm.getAllGroupsInfoForUser = (data = {}, config) => vm.get(API.GET_ALL_GROUPS_INFO_FORUSER, data, config).then(res => Promise.resolve(res))
vm.getWeather = (data={}) => vm.get(API.GET_WEATHER, data).then(res => Promise.resolve(res))
};
......@@ -8,19 +8,23 @@ exports["default"] = void 0;
var _kit_utils = require("kit_utils");
var API = {
GET_CONFIG: "/CityInterface/rest/services.svc/GetConfig",
GENERATE_TOKEN: "/cityinterface/rest/services.svc/generatetoken",
GET_CONFIG: '/CityInterface/rest/services.svc/GetConfig',
GENERATE_TOKEN: '/cityinterface/rest/services.svc/generatetoken',
GENERATE_TOKEN_CHANGE: '/cityinterface/rest/services.svc/generatetokenquick',
GET_WEB_SITE_CONFIG: '/CityInterface/rest/services.svc/GetWebSiteConfig',
GET_USER_INFO: '/CityInterface/rest/services.svc/getUserInfo',
GET_OA: '/CityInterface/rest/services/OA.svc/getLoginInfo',
GET_LOGS: '/CityInterface/rest/services/portal.svc/OMMonitor/SaveLoginInfo',
GET_INFORMATION: '/CityInterface/rest/services/CountyProduct.svc/SCADAOper/GetInformationInfo'
GET_INFORMATION: '/CityInterface/rest/services/CountyProduct.svc/SCADAOper/GetInformationInfo',
GET_CITY: 'https://pv.sohu.com/cityjson?ie=utf-8',
GET_ALL_GROUPS_INFO_FORUSER: 'CityInterface/rest/Services/Portal.svc/AuthorityManage/GetAllGroupsInfoForUser',
GET_WEATHER: '/CityInterface/rest/services/CountyProduct.svc/GetWeather'
};
var _default = function _default(vm) {
vm.getConfig = function () {
var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
client: _kit_utils.params.getParams('client'),
client: _kit_utils.params.getParams('client') || 'city',
ts: Date.now()
};
return vm.get(API.GET_CONFIG, data).then(function (res) {
......@@ -70,6 +74,34 @@ var _default = function _default(vm) {
return Promise.resolve(res);
});
};
vm.getCity = function () {
return vm.get(API.GET_CITY).then(function (res) {
return Promise.resolve(res);
});
};
vm.generateTokenQuick = function () {
var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
return vm.get(API.GENERATE_TOKEN_CHANGE, data).then(function (res) {
return Promise.resolve(res);
});
};
vm.getAllGroupsInfoForUser = function () {
var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var config = arguments.length > 1 ? arguments[1] : undefined;
return vm.get(API.GET_ALL_GROUPS_INFO_FORUSER, data, config).then(function (res) {
return Promise.resolve(res);
});
};
vm.getWeather = function () {
var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
return vm.get(API.GET_WEATHER, data).then(function (res) {
return Promise.resolve(res);
});
};
};
exports["default"] = _default;
\ No newline at end of file
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
......@@ -2,35 +2,32 @@ import React from 'react';
import {
Avatar,
Menu,
Popover,
Spin,
} from 'antd';
import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import {
LogoutOutlined,
SettingOutlined,
UserOutlined,
} from '@ant-design/icons';
import HeaderDropdown from '../HeaderDropdown';
import styles from './index.less';
class AvatarDropdown extends React.Component {
/* eslint-disable no-unused-vars */
onMenuClick = event => {
const { key } = event;
if (key === 'logout') {
createStoreage.remove('PANDA_STORE');
this.props.history.push(
`/civbase/user/login/?client=${window.globalConfig.client}`,
`/user/login/?client=${window.globalConfig.client}`,
);
location.reload();
return;
}
};
getRoles = () => {
const roles = this.props.global.userInfo.roles || []
let ret = []
roles.forEach(item => {
ret.push(item.name)
})
return ret.join(",")
}
render() {
const props = this.props;
const {
......@@ -48,33 +45,49 @@ class AvatarDropdown extends React.Component {
},
} = this.props;
const menuHeaderDropdown = (
<Menu
className={styles.menu}
selectedKeys={[]}
onClick={this.onMenuClick}
>
{
<Menu.Item key="center">
<UserOutlined />
个人中心
</Menu.Item>
}
{
<Menu.Item key="settings">
<SettingOutlined />
个人设置
</Menu.Item>
}
{<Menu.Divider />}
<Menu.Item key="logout">
<LogoutOutlined />
退出登录
</Menu.Item>
</Menu>
<div className={styles.userInfo}>
<div className={styles.header}>
<div className={styles.avatar} style={{backgroundImage: `url(${props.global.userInfo.UserImge})`}}></div>
<div className={styles.name}>{props.global.userInfo.fullName}</div>
</div>
<div className={styles.body}>
<div className={styles.item}>
<ul>
<li>
<span></span>
<span className={styles.label}>账号:</span>
<span className={styles.value}>{props.global.userInfo.loginName}</span>
</li>
<li>
<span></span>
<span className={styles.label}>姓名:</span>
<span className={styles.value}>{props.global.userInfo.fullName}</span>
</li>
<li>
<span></span>
<span className={styles.label}>部门:</span>
<span className={styles.value}>{props.global.userInfo.depart.name}</span>
</li>
<li>
<span></span>
<span className={styles.label}>角色:</span>
<span className={styles.value}>{this.getRoles()}</span>
</li>
<li>
<span></span>
<span className={styles.label}>企业编号:</span>
<span className={styles.value}>{props.global.userInfo.site}</span>
</li>
</ul>
</div>
<div className={styles.exit}>
<a href="javascript:;" onClick={this.onMenuClick}>退出登录</a>
</div>
</div>
</div>
);
return currentUser && currentUser.name ? (
<HeaderDropdown overlay={menuHeaderDropdown}>
<Popover overlayClassName={styles.userWrapper} placement="bottom" trigger="click" content={menuHeaderDropdown}>
<span className={`${styles.action} ${styles.account}`}>
<Avatar
size="small"
......@@ -82,9 +95,9 @@ class AvatarDropdown extends React.Component {
src={currentUser.avatar}
alt="avatar"
/>
<span className={`${styles.name} anticon`}>{currentUser.name}</span>
{/* <span className={`${styles.name} anticon`}>{currentUser.name}</span> */}
</span>
</HeaderDropdown>
</Popover>
) : (
<span className={`${styles.action} ${styles.account}`}>
<Spin
......@@ -99,12 +112,5 @@ class AvatarDropdown extends React.Component {
}
}
const mapStateToProps = state => {
return {
global: state.getIn(['global', 'globalConfig']),
};
};
export default connect(
mapStateToProps,
null,
)(withRouter(AvatarDropdown));
export default withRouter(AvatarDropdown)
import React, { useState } from 'react';
import { message } from 'antd';
import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import Icon from '@ant-design/icons';
// import { searchAutoCity } from '../../api/jsonp/autoService';
import HeaderSearch from '../HeaderSearch';
// import NoticeIcon from '../NoticeIcon';
......@@ -7,6 +13,61 @@ import Avatar from './AvatarDropdown';
import styles from './index.less';
import NoticeIconView from './NoticeIconView';
const orderSvg = () => (
<svg version="1.1" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enableBackground="new 0 0 24 24" space="preserve">
<path fill="#5F718C" d="M7.223,13.131c-0.445,0-0.815,0.364-0.815,0.816c0,0.446,0.37,0.816,0.815,0.816
c0.446,0,0.816-0.37,0.816-0.816C8.039,13.495,7.669,13.131,7.223,13.131L7.223,13.131z M7.223,16.574L7.223,16.574
c-0.445,0-0.815,0.371-0.815,0.817c0,0.45,0.37,0.814,0.815,0.814c0.446,0,0.816-0.364,0.816-0.814
C8.039,16.945,7.669,16.574,7.223,16.574L7.223,16.574z M7.223,9.688L7.223,9.688c-0.445,0-0.815,0.366-0.815,0.817
c0,0.445,0.37,0.815,0.815,0.815c0.446,0,0.816-0.37,0.816-0.815C8.039,10.054,7.669,9.688,7.223,9.688L7.223,9.688z M20.469,4.533
L20.469,4.533h-2.246V4.082c0-0.268-0.22-0.48-0.485-0.48h-2.622c-0.138-0.59-0.434-1.1-0.839-1.505
c-0.59-0.591-1.388-0.95-2.28-0.95c-0.884,0-1.677,0.359-2.262,0.95C9.323,2.502,9.022,3.012,8.879,3.602H6.263
c-0.267,0-0.492,0.213-0.492,0.48v0.451H3.548c-0.451,0-0.821,0.363-0.821,0.814v16.688c0,0.452,0.37,0.817,0.821,0.817h16.921
c0.438,0,0.805-0.365,0.805-0.817V5.348C21.273,4.896,20.907,4.533,20.469,4.533L20.469,4.533z M10.671,3.027
c0.405-0.404,0.718-0.653,1.325-0.653c0.614,0,0.933,0.249,1.337,0.653c0.221,0.227,0.158,0.256,0.273,0.574h-3.208
C10.516,3.283,10.44,3.254,10.671,3.027 M7.015,4.822L7.015,4.822h9.982v1.054H7.015 M19.647,21.215L19.647,21.215H4.359V6.158
h1.411v0.451c0,0.267,0.226,0.486,0.492,0.486h11.475c0.266,0,0.485-0.22,0.485-0.486V6.158h1.425V21.215L19.647,21.215z
M16.742,9.765L16.742,9.765H9.659c-0.267,0-0.485,0.468-0.485,0.74c0,0.267,0.219,0.739,0.485,0.739h7.083
c0.277,0,0.491-0.473,0.491-0.739C17.233,10.232,17.02,9.765,16.742,9.765L16.742,9.765z M16.742,16.65L16.742,16.65H9.659
c-0.267,0-0.485,0.468-0.485,0.741c0,0.271,0.219,0.728,0.485,0.728h7.083c0.277,0,0.491-0.457,0.491-0.728
C17.233,17.118,17.02,16.65,16.742,16.65L16.742,16.65z M16.742,13.213L16.742,13.213H9.659c-0.267,0-0.485,0.462-0.485,0.735
c0,0.271,0.219,0.734,0.485,0.734h7.083c0.277,0,0.491-0.464,0.491-0.734C17.233,13.675,17.02,13.213,16.742,13.213L16.742,13.213z"
/>
</svg>);
const homeSvg = () => (
<svg version="1.1" x="0px" y="0px" width="24px" height="24px" viewBox="0 0 24 24" enableBackground="new 0 0 24 24" space="preserve">
<path fill="#5F718C" d="M23.359,13.561v-1.313L12.057,1.064L0.642,12.247v1.37h2.84v9.318h7.381v-4.935h2.271v4.935h7.385v-9.318
L23.359,13.561z M18.815,11.917v9.319H14.84v-4.935H9.161v4.935H5.185v-9.319H3.311l8.746-8.551l8.577,8.551H18.815z"/>
</svg>
)
const OrderIcon = props => <Icon component={orderSvg} {...props} />;
const HomeIcon = props => <Icon component={homeSvg} {...props}/>
const MESSAGE_BOX_URL = 'product/maintenance/CaseManage/CaseDoingBox/StardCaseDoingBoxView|isDelay=1'
const getConfig = (widgets, url) => {
const widgetconfig = {};
if(!widgets) {
return
} else {
for(let i = 0; i< widgets.length; i++) {
const widget = widgets[i];
if(widget && widget.url) widget.url = widget.url.replace(/\\/g,'/');
if (widget.url && url.toLowerCase() == widget.url.toLowerCase()) {
widgetconfig = widget;
break;
} else {
if (widget.widgets) {
widgetconfig = getConfig(url, widget.widgets);
if (widgetconfig) {
break;
}
}
}
}
}
return widgetconfig
}
const GlobalHeaderRight = props => {
const { theme, layout } = props;
const [options, setOptions] = useState([]);
......@@ -45,6 +106,21 @@ const GlobalHeaderRight = props => {
: setOptions([]);
};
const goHome = (event) => {
event.stopPropagation()
props.history.replace(`/civweb4/?client=${props.global.client}`)
}
const handleOrder = (event) => {
event.stopPropagation()
if(getConfig(props.global.widgets.concat(props.global.uiwidgets), MESSAGE_BOX_URL)) {
props.history.push(`/civweb4/${MESSAGE_BOX_URL}`)
} else {
message.warning('对不起,您没有菜单权限!')
}
}
const handleSelect = (value, data) => {
window.share.event.emit('addTips', options, data);
};
......@@ -60,11 +136,23 @@ const GlobalHeaderRight = props => {
onChange={handleSearch}
onSearch={handleSearch}
/>
<div className={styles.nav}>
<HomeIcon onClick={goHome}/>
<OrderIcon onClick={handleOrder}/>
</div>
<NoticeIconView notices={[]} />
<Avatar menu />
<Avatar menu global={props.global}/>
{/* <SelectLang className={styles.action} /> */}
</div>
);
};
export default GlobalHeaderRight;
const mapStateToProps = state => {
return {
global: state.getIn(['global', 'globalConfig']),
};
};
export default connect(
mapStateToProps,
null,
)(withRouter(GlobalHeaderRight));
......@@ -62,6 +62,102 @@
}
}
}
.userWrapper {
.userInfo {
background-color: #fff;
width: 300px;
position: absolute;
right: 0;
top: 10px;
box-shadow: 0 0 10px rgba(0,0,0,0.15);
border-radius: 6px;
.header {
width: 100%;
height: 80px;
position: relative;
background: #40b3f7;
padding: 14px 12px;
display: flex;
border-top-left-radius: 6px;
border-top-right-radius: 6px;
.avatar {
display: inline-block;
width: 52px;
height: 52px;
border: 2px solid #fff;
background-color: #fff;
border-radius: 50%;
background-size: 100%;
background-repeat: no-repeat;
background-position: center center;
background-position: center;
cursor: pointer;
}
.name {
display: inline-block;
width: 214px;
font-size: 18px;
color: #fff;
font-weight: bold;
padding: 14px;
}
}
.body {
.item {
border-bottom: 1px solid #e0e0e0;
ul {
padding: 0 12px;
list-style: none;
margin: 0;
li {
height: 40px;
line-height: 42px;
border-bottom: 1px dashed #eee;
position: relative;
text-indent: 3px;
overflow: hidden;
width: 100%;
font-size: 12px;
font-weight: 100;
span.label {
padding: 0 2px;
max-width: 200px;
}
span.value {
padding: 0 2px;
max-width: 200px;
}
}
}
}
.exit {
height: 30px;
line-height: 30px;
text-align: right;
padding: 0 10px;
a {
color: #777;
text-decoration: none;
margin: 0 5px;
}
}
}
}
}
.nav {
display: flex;
align-items: center;
span {
&:first-child {
margin-right: 20px;
margin-left: 20px;
}
svg {
transform: scale(0.88);
}
}
}
:global(.ant-pro-global-header) {
.dark {
......
......@@ -8,13 +8,30 @@ import classNames from 'classnames';
import { connect } from 'react-redux';
import useMergeValue from 'use-merge-value';
import { BellOutlined } from '@ant-design/icons';
import Icon from '@ant-design/icons';
import HeaderDropdown from '../HeaderDropdown';
import styles from './index.less';
import NoticeList from './NoticeList';
const { TabPane } = Tabs;
const messageSvg = () => (
<svg version="1.1" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" space="preserve">
<path fill="#5F718C" d="M20.486,16.373l-1.721-2.246v-0.984v-0.352V9.924c0-1.919-0.664-3.698-1.871-5.007
c-0.712-0.776-1.57-1.349-2.551-1.705c-0.091-0.514-0.35-0.983-0.737-1.335c-0.879-0.791-2.334-0.791-3.21,0
c-0.394,0.354-0.653,0.823-0.741,1.336C8.676,3.568,7.817,4.14,7.105,4.917C5.899,6.229,5.234,8.008,5.234,9.923l0.005,4.194
l-1.708,2.234c-0.241,0.256-0.372,0.584-0.372,0.932v1.092c0,0.75,0.615,1.357,1.372,1.357H19.47c0.757,0,1.371-0.607,1.371-1.357
v-1.092C20.841,16.936,20.71,16.607,20.486,16.373z M4.899,17.996v1.016l-0.001-2.061l1.628-2.154
c0.227-0.244,0.353-0.561,0.353-0.893v-4.05c0-1.516,0.509-2.914,1.436-3.935c0.459-0.506,1.001-0.895,1.608-1.166
c1.276-0.565,2.883-0.565,4.155,0c0.609,0.273,1.15,0.667,1.608,1.168c0.925,1.021,1.437,2.417,1.437,3.934v2.762v0.338v0.949
c0,0.334,0.123,0.654,0.336,0.875l1.642,2.164l0.013,1.037L4.899,17.996z"/>
<path fill="#5F718C" d="M13.685,20.236c-0.101,0.238-0.248,0.453-0.444,0.631c-0.677,0.617-1.799,0.615-2.473,0.002
c-0.194-0.18-0.344-0.396-0.446-0.633H8.895c0.146,0.627,0.474,1.199,0.955,1.639c0.588,0.543,1.354,0.841,2.158,0.841
c0.801,0,1.566-0.298,2.154-0.837c0.481-0.439,0.808-1.012,0.954-1.641L13.685,20.236z"/>
</svg>
)
const BellOutlined = props => <Icon component={messageSvg} {...props} style={{transform: 'scale(0.88)'}}/>;
const NoticeIcon = props => {
const getNotificationBox = () => {
const {
......
.sliderBlock {
position: absolute;
left: 0;
top: 0;
}
.sliderContainer {
position: relative;
text-align: center;
width: 310px;
height: 40px;
line-height: 40px;
margin-top: 15px;
background: #f7f9fa;
color: #45494c;
border: 1px solid #e4e7eb;
}
.sliderContainer.sliderContainer_active .slider {
height: 38px;
top: -1px;
border: 1px solid #1991fa;
}
.sliderContainer.sliderContainer_active .sliderMask {
height: 38px;
border-width: 1px;
}
.sliderContainer.sliderContainer_success .slider {
height: 38px;
top: -1px;
border: 1px solid #52ccba;
background-color: #52ccba !important;
}
.sliderContainer.sliderContainer_success .sliderMask {
height: 38px;
border: 1px solid #52ccba;
background-color: #d2f4ef;
}
.sliderContainer.sliderContainer_success .sliderIcon {
background-position: 0 0 !important;
}
.sliderContainer.sliderContainer_fail .sliderMask {
height: 38px;
border: 1px solid #f57a7a;
background-color: #fce1e1;
}
.sliderContainer.sliderContainer_fail .sliderIcon {
top: 14px;
background-position: 0 -82px !important;
}
.sliderContainer.sliderContainer_active .sliderText,
.sliderContainer.sliderContainer_success .sliderText,
.sliderContainer.sliderContainer_fail .sliderText {
display: none;
}
.sliderContainer .sliderMask {
position: absolute;
left: 0;
top: 0;
height: 40px;
border: 0 solid #1991fa;
background: #d1e9fe;
}
.sliderContainer .slider {
position: absolute;
top: 0;
left: 0;
width: 40px;
height: 40px;
background: #fff;
box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);
cursor: pointer;
transition: background 0.2s linear;
}
.sliderContainer .slider:hover {
background: #1991fa;
}
.sliderContainer .slider:hover .sliderIcon {
background-position: 0 -13px;
}
.sliderContainer .sliderIcon {
position: absolute;
top: 15px;
left: 13px;
width: 14px;
height: 12px;
background: url(https://panda-water.cn/web4/assets/images/SlideVerify/icon.png) 0 -26px;
background-size: 34px 471px;
}
.sliderContainer .refreshIcon {
position: absolute;
right: 0;
top: 0;
width: 34px;
height: 34px;
cursor: pointer;
background: url(https://panda-water.cn/web4/assets/images/SlideVerify/icon.png) 0 -437px;
background-size: 34px 471px;
}
This diff is collapsed.
import { dom } from 'kit_utils';
import styles from './index.less';
class SlideVerify {
init() {
debugger
this.initDOM()
this.initImg()
this.bindEvents()
}
render({container, onSuccess, onFail, onRefresh}) {
container.style.position = container.style.position || 'relative'
this.slideLong = 42 // 拼图边长
this.slideRadius = 9 // 拼图缺口半径
this.canvasWidth = 310 // canvas宽度
this.canvasHeight = 155 // canvas高度
this.slideTotalWidth = this.slideLong + this.slideRadius * 2 + 3 // 拼图实际边长
this.container = container
this.onSuccess = onSuccess
this.onFail = onFail
this.onRefresh = onRefresh
this.init()
}
initDOM () {
var canvas = this.createCanvas(this.canvasWidth, this.canvasHeight) // 画布
var block = canvas.cloneNode(true) // 拼图
var sliderContainer = this.createElement('div', styles.sliderContainer)
var refreshIcon = this.createElement('div', styles.refreshIcon)
var sliderMask = this.createElement('div', styles.sliderMask)
var slider = this.createElement('div', styles.slider)
var sliderIcon = this.createElement('span', styles.sliderIcon)
var text = this.createElement('span', styles.sliderText)
block.className = styles.sliderBlock
text.innerHTML = '向右滑动填充拼图'
var el = this.container
el.appendChild(canvas)
el.appendChild(refreshIcon)
el.appendChild(block)
slider.appendChild(sliderIcon)
sliderMask.appendChild(slider)
sliderContainer.appendChild(sliderMask)
sliderContainer.appendChild(text)
el.appendChild(sliderContainer)
Object.assign(this, {
canvas,
block,
sliderContainer,
refreshIcon,
slider,
sliderMask,
sliderIcon,
text,
canvasCtx: canvas.getContext('2d'),
blockCtx: block.getContext('2d')
})
}
initImg () {
var img = this.createImg(() => {
this.startDraw()
this.canvasCtx.drawImage(img, 0, 0, this.canvasWidth, this.canvasHeight)
this.blockCtx.drawImage(img, 0, 0, this.canvasWidth, this.canvasHeight)
var y = this.slideY - this.slideRadius * 2 - 2
var ImageData = this.blockCtx.getImageData(this.slideX - 3, y, this.slideTotalWidth, this.slideTotalWidth)
this.block.width = this.slideTotalWidth
this.blockCtx.putImageData(ImageData, 0, y)
})
this.img = img
}
startDraw () {
// 随机创建拼图的位置(矩形拼图左上顶点位置)
this.slideX = this.getRandomNumberByRange(this.slideTotalWidth + 10, this.canvasWidth - (this.slideTotalWidth + 10))
this.slideY = this.getRandomNumberByRange(10 + this.slideRadius * 2, this.canvasHeight - (this.slideTotalWidth + 10))
this.draw(this.canvasCtx, this.slideX, this.slideY, 'fill')
this.draw(this.blockCtx, this.slideX, this.slideY, 'clip')
}
clean () {
this.canvasCtx.clearRect(0, 0, this.canvasWidth, this.canvasHeight)
this.blockCtx.clearRect(0, 0, this.canvasWidth, this.canvasHeight)
this.block.width = this.canvasWidth
}
bindEvents () {
this.container.onselectstart = () => false
this.refreshIcon.onclick = () => {
this.reset()
typeof this.onRefresh === 'function' && this.onRefresh()
}
var originX, originY, trail = [], isMouseDown = false
var handleDragStart = function (e) {
originX = e.clientX || e.touches[0].clientX
originY = e.clientY || e.touches[0].clientY
isMouseDown = true
}
var handleDragMove = (e) => {
if (!isMouseDown) return false
var eventX = e.clientX || e.touches[0].clientX
var eventY = e.clientY || e.touches[0].clientY
var moveX = eventX - originX
var moveY = eventY - originY
if (moveX < 0 || moveX + 38 >= this.canvasWidth) return false
this.slider.style.left = moveX + 'px' //按钮的滑动距离
var blockLeft = (this.canvasWidth - 40 - 20) / (this.canvasWidth - 40) * moveX //按钮与滑块的移动比例相同
this.block.style.left = blockLeft + 'px'
dom.addClass(this.sliderContainer, styles['sliderContainer_active'])
this.sliderMask.style.width = moveX + 'px'
trail.push(moveY)
}
var handleDragEnd = (e) => {
if (!isMouseDown) return false
isMouseDown = false
var eventX = e.clientX || e.changedTouches[0].clientX
if (eventX == originX) return false
dom.removeClass(this.sliderContainer, styles['sliderContainer_active'])
this.trail = trail
var { spliced, verified } = this.verify()
if (spliced) {
if (verified) {
dom.addClass(this.sliderContainer, styles['sliderContainer_success'])
typeof this.onSuccess === 'function' && this.onSuccess()
} else {
dom.addClass(this.sliderContainer, styles['sliderContainer_fail'])
this.text.innerHTML = '再试一次'
this.reset()
}
} else {
dom.addClass(this.sliderContainer, styles['sliderContainer_fail'])
typeof this.onFail === 'function' && this.onFail()
setTimeout(() => {
this.reset()
}, 1000)
}
}
this.slider.addEventListener('mousedown', handleDragStart)
this.slider.addEventListener('touchstart', handleDragStart)
document.addEventListener('mousemove', handleDragMove)
document.addEventListener('touchmove', handleDragMove)
document.addEventListener('mouseup', handleDragEnd)
document.addEventListener('touchend', handleDragEnd)
}
verify () {
const arr = this.trail // 拖动时y轴的移动距离
const average = arr.reduce(this.sum) / arr.length
const deviations = arr.map(x => x - average)
const stddev = Math.sqrt(deviations.map(this.square).reduce(this.sum) / arr.length) //总体标准差
const left = parseInt(this.block.style.left)
return {
spliced: Math.abs(left - this.slideX) < 10,
verified: stddev !== 0, // 简单验证下拖动轨迹,为零时表示Y轴上下没有波动,可能非人为操作
}
}
reset () {
this.sliderContainer.className = styles.sliderContainer
this.slider.style.left = 0
this.block.style.left = 0
this.sliderMask.style.width = 0
this.clean()
this.img.src = this.getRandomImg()
}
createCanvas(width, height) {
const canvas = this.createElement('canvas')
canvas.width = width
canvas.height = height
return canvas;
}
createElement(tagName, className) {
const element = document.createElement(tagName)
element.className = className
return element
}
getRandomNumberByRange (start, end) {
return Math.round(Math.random() * (end - start) + start)
}
getRandomImg () {
return require(`../../assets/SlideVerify/` + [this.getRandomNumberByRange(1, 8) + '.jpg'])
}
createImg (onload) {
const img = new Image()
img.setAttribute('crossOrigin', 'Anonymous')
img.src = this.getRandomImg()
img.onload = onload
img.onerror = () => {
img.src = this.getRandomImg()
}
return img
}
draw (ctx, x, y, operation) {
const l = this.slideLong // 滑块边长
const r = this.slideRadius
const PI = Math.PI
const borderGap = 2
ctx.beginPath()
ctx.moveTo(x, y)
ctx.arc(x + l / 2, y - r + borderGap, r, 0.72 * PI, 2.26 * PI) //上圆
ctx.lineTo(x + l, y)
ctx.arc(x + l + r - borderGap, y + l / 2, r, 1.21 * PI, 2.78 * PI) //右圆
ctx.lineTo(x + l, y + l)
ctx.lineTo(x, y + l)
ctx.arc(x + r - borderGap, y + l / 2, r + 0.4, 2.76 * PI, 1.24 * PI, true) //左圆
ctx.lineTo(x, y)
ctx.lineWidth = borderGap
ctx.fillStyle = 'rgba(255, 255, 255, 0.7)'
ctx.strokeStyle = 'rgba(255, 255, 255, 0.7)'
ctx.stroke()
ctx[operation]()
ctx.globalCompositeOperation = 'overlay'
}
sum (x, y) {
return x + y
}
square (x) {
return x * x
}
}
export default SlideVerify;
\ No newline at end of file
.sliderBlock {
position: absolute;
left: 0;
top: 0;
}
.sliderContainer {
position: relative;
text-align: center;
width: 310px;
height: 40px;
line-height: 40px;
margin-top: 15px;
background: #f7f9fa;
color: #45494c;
border: 1px solid #e4e7eb;
&.sliderContainer_active {
.slider {
height: 38px;
top: -1px;
border: 1px solid #1991fa;
}
.sliderMask {
height: 38px;
border-width: 1px;
}
}
&.sliderContainer_success {
.slider {
height: 38px;
top: -1px;
border: 1px solid #52ccba;
background-color: #52ccba !important;
}
.sliderMask {
height: 38px;
border: 1px solid #52ccba;
background-color: #d2f4ef;
}
.sliderIcon {
background-position: 0 0 !important;
}
}
&.sliderContainer_fail {
.sliderMask {
height: 38px;
border: 1px solid #f57a7a;
background-color: #fce1e1;
}
.sliderIcon {
top: 14px;
background-position: 0 -82px !important;
}
}
&.sliderContainer_active .sliderText,&.sliderContainer_success .sliderText,
&.sliderContainer_fail .sliderText {
display: none;
}
.sliderMask {
position: absolute;
left: 0;
top: 0;
height: 40px;
border: 0 solid #1991fa;
background: #d1e9fe;
}
.slider {
position: absolute;
top: 0;
left: 0;
width: 40px;
height: 40px;
background: #fff;
box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);
cursor: pointer;
transition: background 0.2s linear;
&:hover {
background: #1991fa;
.sliderIcon {
background-position: 0 -13px;
}
}
}
.sliderIcon {
position: absolute;
top: 15px;
left: 13px;
width: 14px;
height: 12px;
background: url(https://panda-water.cn/web4/assets/images/SlideVerify/icon.png)
0 -26px;
background-size: 34px 471px;
}
.refreshIcon {
position: absolute;
right: 0;
top: 0;
width: 34px;
height: 34px;
cursor: pointer;
background: url(https://panda-water.cn/web4/assets/images/SlideVerify/icon.png)
0 -437px;
background-size: 34px 471px;
}
}
\ No newline at end of file
import { Tabs } from 'antd';
import { Sticky } from 'react-sticky';
const { TabPane } = Tabs;
const renderTabBar = (props, DefaultTabBar) => (
<Sticky bottomOffset={80}>
{({ stylle }) => <DefaultTabBar {...props} style={{ ...stylle }} />}
</Sticky>
);
const TabRoute = () => {};
......@@ -27,7 +27,7 @@ function App(props) {
content={`${props.global && props.global.title}`}
/>
</Helmet>
<Router>
<Router basename="civbase">
<Switch>{renderRoutes(dyRoutes(props.menu || []).routes)}</Switch>
</Router>
</>
......
......@@ -4,6 +4,7 @@ import {
GET_CONFIG,
GET_CURRENT_ROUTES,
GET_ERROR_CONFIG,
GET_THEME_CONFIG,
} from './constants';
export function getConfig(data) {
......@@ -39,3 +40,10 @@ export function generateMenu(data) {
data,
};
}
export function updageSetting(data) {
return {
type: GET_THEME_CONFIG,
data,
};
}
......@@ -3,3 +3,4 @@ export const GET_ERROR_CONFIG = 'App/GET_ERROR_CONFIG';
export const GET_CURRENT_ROUTES = 'App/GET_CURRENT_ROUTES';
export const CREATE_CONEXT = 'App/CREATE_CONEXT';
export const GENERATE_MENU = 'App/GENERATE_MENU';
export const GET_THEME_CONFIG = 'App/THEME_CONFIG';
......@@ -8,6 +8,7 @@ exports.getConfigError = getConfigError;
exports.getCurrentRoute = getCurrentRoute;
exports.createContext = createContext;
exports.generateMenu = generateMenu;
exports.updageSetting = updageSetting;
var _constants = require("./constants");
......@@ -45,3 +46,10 @@ function generateMenu(data) {
data: data
};
}
function updageSetting(data) {
return {
type: _constants.GET_THEME_CONFIG,
data: data
};
}
\ No newline at end of file
......@@ -3,7 +3,7 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.GENERATE_MENU = exports.CREATE_CONEXT = exports.GET_CURRENT_ROUTES = exports.GET_ERROR_CONFIG = exports.GET_CONFIG = void 0;
exports.GET_THEME_CONFIG = exports.GENERATE_MENU = exports.CREATE_CONEXT = exports.GET_CURRENT_ROUTES = exports.GET_ERROR_CONFIG = exports.GET_CONFIG = void 0;
var GET_CONFIG = 'App/GET_CONFIG';
exports.GET_CONFIG = GET_CONFIG;
var GET_ERROR_CONFIG = 'App/GET_ERROR_CONFIG';
......@@ -14,3 +14,5 @@ var CREATE_CONEXT = 'App/CREATE_CONEXT';
exports.CREATE_CONEXT = CREATE_CONEXT;
var GENERATE_MENU = 'App/GENERATE_MENU';
exports.GENERATE_MENU = GENERATE_MENU;
var GET_THEME_CONFIG = 'App/THEME_CONFIG';
exports.GET_THEME_CONFIG = GET_THEME_CONFIG;
\ No newline at end of file
......@@ -7,6 +7,8 @@ exports["default"] = exports.initialState = void 0;
var _immutable = require("immutable");
var _defaultSetting = _interopRequireDefault(require("../../../../config/defaultSetting"));
var _routes = _interopRequireDefault(require("../../../utils/routes"));
var _constants = require("./constants");
......@@ -18,7 +20,8 @@ var initialState = (0, _immutable.fromJS)({
globalConfigError: '',
currentRoutes: {},
instance: null,
menu: []
menu: [],
defaultSetting: _defaultSetting["default"]
});
/* eslint-disable default-case, no-param-reassign */
......@@ -30,12 +33,10 @@ var appReducer = function appReducer() {
switch (action.type) {
case _constants.GET_CONFIG:
debugger;
console.log('updateConfig', action.data);
window.__INITIAL_STATE__ = Object.assign({}, action.data, {
allWidgets: action.data.widgets || []
});
debugger;
window.globalConfig = require('kit_global_config')["default"];
createStoreage.set('globalConfig', window.globalConfig);
var config = createStoreage.get('globalConfig');
......@@ -64,6 +65,11 @@ var appReducer = function appReducer() {
menu: action.data
});
case _constants.GET_THEME_CONFIG:
return state.merge({
defaultSetting: action.data
});
default:
return state;
}
......
import { fromJS } from 'immutable';
import defaultSetting from '../../../../config/defaultSetting';
import generRoutes from '../../../utils/routes';
import {
CREATE_CONEXT,
......@@ -7,6 +8,7 @@ import {
GET_CONFIG,
GET_CURRENT_ROUTES,
GET_ERROR_CONFIG,
GET_THEME_CONFIG,
} from './constants';
export const initialState = fromJS({
......@@ -15,18 +17,18 @@ export const initialState = fromJS({
currentRoutes: {},
instance: null,
menu: [],
defaultSetting: defaultSetting,
});
/* eslint-disable default-case, no-param-reassign */
const appReducer = (state = initialState, action) => {
switch (action.type) {
case GET_CONFIG:
debugger;
console.log('updateConfig', action.data);
window.__INITIAL_STATE__ = Object.assign({}, action.data, {
allWidgets: action.data.widgets || [],
});
debugger;
window.globalConfig = require('kit_global_config').default;
createStoreage.set('globalConfig', window.globalConfig);
......@@ -51,6 +53,10 @@ const appReducer = (state = initialState, action) => {
return state.merge({
menu: action.data,
});
case GET_THEME_CONFIG:
return state.merge({
defaultSetting: action.data,
});
default:
return state;
}
......
......@@ -5,10 +5,10 @@ Object.defineProperty(exports, "__esModule", {
});
exports.defaultApp = exports.initMicroApps = void 0;
var _reactDom = _interopRequireDefault(require("react-dom"));
var _qiankun = require("qiankun");
var _micor = _interopRequireDefault(require("../config/micor"));
var _package = _interopRequireDefault(require("../package.json"));
var _constants = require("./utils/constants");
......@@ -16,41 +16,55 @@ var _constants = require("./utils/constants");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
var initMicroApps = function initMicroApps(loader) {
debugger;
(0, _qiankun.registerMicroApps)([{
name: 'web4_console',
entry: "//".concat(window.location.hostname, ":3020/civweb4"),
container: '#subapp-container',
activeRule: function activeRule(location) {
return location.href.indexOf("/".concat(_package["default"].name.toLocaleLowerCase(), "/civweb4")) !== -1;
},
loader: loader,
props: {
var entrys = process.env.NODE_ENV !== 'production' ? _micor["default"].dev : _micor["default"].prod;
(0, _qiankun.registerMicroApps)(entrys.map(function (item) {
item.loader = loader;
item.props = {
emitter: window.share.event,
baseRoot: 'civweb4',
baseRoot: item.name,
globalConfig: JSON.stringify(createStoreage.get('globalConfig') || {}),
XMLHttpRequest: window.XMLHttpRequest
}
}], {
};
return item;
}), {
beforeLoad: [function (app) {
debugger; // hookRequest()
console.log('[LifeCycle] before load %c%s', 'color: green;', JSON.stringify(app));
// hookRequest()
// console.log(
// '[LifeCycle] before load %c%s',
// 'color: green;',
// JSON.stringify(app),
// );
console.log('[LifeCycle] before load %c%s', 'color: green;', app.name);
}],
beforeMount: [function (app) {
debugger; // hookRequest()
_reactDom["default"].unmountComponentAtNode(document.getElementById('subapp-container'));
console.log('[LifeCycle] before mount %c%s', 'color: green;', JSON.stringify(app)); // window.share.event.removeAllListeners();
// hookRequest()
// ReactDOM.unmountComponentAtNode(
// document.getElementById('subapp-container'),
// );
// console.log(
// '[LifeCycle] before mount %c%s',
// 'color: green;',
// JSON.stringify(app),
// );
// window.share.event.removeAllListeners();
console.log('[LifeCycle] before mount %c%s', 'color: green;', app.name);
}],
afterMount: [function (app) {
console.log('[LifeCycle] after mount %c%s', 'color: green;', app.name);
}],
beforeUnmount: [function (app) {
debugger;
console.log('[LifeCycle] before unmount %c%s', 'color: green;', JSON.stringify(app));
window.share.event.removeAllListeners('changeRoute');
console.log('[LifeCycle] after unmount %c%s', 'color: green;', app.name); // console.log(
// '[LifeCycle] before unmount %c%s',
// 'color: green;',
// JSON.stringify(app),
// );
}],
afterUnmount: [function (app) {
debugger;
console.log('[LifeCycle] after unmount %c%s', 'color: green;', JSON.stringify(app));
afterUnmount: [function (app) {// console.log(
// '[LifeCycle] after unmount %c%s',
// 'color: green;',
// JSON.stringify(app),
// );
}]
});
defaultApp();
......@@ -59,7 +73,7 @@ var initMicroApps = function initMicroApps(loader) {
experimentalStyleIsolation: true,
loose: true
},
singular: false,
singular: true,
scopedCSS: true,
getPublicPath: window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__,
excludeAssetFilter: function excludeAssetFilter(url) {
......@@ -80,8 +94,8 @@ var defaultApp = function defaultApp() {
var config = createStoreage.get('globalConfig');
if (config && config.token) {
var startWith = config.homepage ? config.homepage.split('/') : [];
var basePath = _constants.FILTER_FOLER.indexOf(startWith[0]) > -1 ? 'civweb4' : 'civweb';
// const startWith = config.homepage ? config.homepage.split('/') : [];
var basePath = _constants.FILTER_FOLER_REG.test(config.homepage) ? 'civweb4' : 'civweb';
(0, _qiankun.setDefaultMountApp)("/".concat(_package["default"].name.toLocaleLowerCase(), "/").concat(basePath, "/?client=").concat(config.client) // config.homepage
// ? `/${pkg.name.toLocaleLowerCase()}/${basePath}/${config.homepage}`
// : `/${pkg.name.toLocaleLowerCase()}/${basePath}/?client=${
......
......@@ -115,8 +115,8 @@ a {
& /deep/ .ant-menu-dark {
.ant-menu-submenu-selected {
.ant-menu-item-selected {
background: rgb(39, 49, 80);
border-left: 3px solid rgb(23, 160, 242);
// background: rgb(39, 49, 80);
// border-left: 3px solid rgb(23, 160, 242);
}
}
}
......@@ -148,12 +148,25 @@ a {
}
.ant-menu-dark.ant-menu-dark:not(.ant-menu-horizontal) {
.ant-menu-item-selected {
border-left: 2px solid #1890ff;
background-color: #273150;
// border-left: 2px solid #1890ff;
// background-color: #273150;
}
}
}
& /deep/ .ant-pro-global-header-layout-side {
> div {
display: flex;
}
}
}
.panda-pro-components-global-header-index-userWrapper {
& /deep/ .ant-popover-content > .ant-popover-arrow {
border-top-color: #40b3f7!important;
border-left-color: #40b3f7!important;
}
}
//global scrollbar
......
......@@ -4,19 +4,23 @@ import React, {
useState,
} from 'react';
import { Popover } from 'antd';
import { connect } from 'react-redux';
import { matchRoutes } from 'react-router-config';
import {
Link,
useHistory,
} from 'react-router-dom';
matchRoutes,
renderRoutes,
} from 'react-router-config';
import { useHistory } from 'react-router-dom';
import { MenuFoldOutlined } from '@ant-design/icons';
import ProLayout, { SettingDrawer } from '@ant-design/pro-layout';
import RightContent from '../components/GlobalHeader/RightContent';
import { Panel } from '../components/SliderPanel';
import { actionCreators } from '../containers/App/store';
import { getBaseName } from '../utils/utils';
import SecurityLayout from './SecurityLayout';
import Site from './Site';
import styles from './UserLayout.less';
const renderIcon = (icon, size) => {
......@@ -61,13 +65,37 @@ const menuExtraRender = currentRoutes => {
return;
};
const renderTitle = title => {
return <span className={styles['header-title']}>{title}</span>;
const renderTitle = (title, action) => {
const getCityStationsForUser = action && action.getCityStationsForUser();
console.log(getCityStationsForUser)
return (
<>
<span className={styles['header-title']}>
{title}
</span>
<div className={styles.cityContent}>
<Popover placement="bottom">
<span className={styles.siteName}>
<img src="https://panda-water.cn/web4/assets/images/depart.svg"/>
<span>GCK演示</span>
</span>
</Popover>
<span className={styles.weatcher}>
<img src="https://panda-water.cn/web4/assets/images/weather2/0.svg"/>
<span> -1/17</span>
</span>
</div>
</>
);
};
const BasicLayout = props => {
/* eslint-disable no-unused-vars */
const {children, settings, location = {
pathname: '/',
},} = props
const basename = getBaseName();
const history = useHistory();
const [pathname, setPathname] = useState('/welcome');
const [pathname, setPathname] = useState(props.location.pathname);
const [currentRoutes, setCurrentRoutes] = useState(props.route.routes[0]);
const [currentIndex, setCurrentIndex] = useState(0);
const [selectedKeys, setSelectedKeys] = useState([]);
......@@ -79,6 +107,10 @@ const BasicLayout = props => {
setCollapse(collapse);
};
const [siteAction, setSiteAction] = useState(() => {
return new Site(props)
})
matchRoutes(props.route.routes, props.location.pathname);
const extraRender = menuExtraRender(currentRoutes);
let clearTime = null;
......@@ -92,6 +124,7 @@ const BasicLayout = props => {
}, [currentIndex]);
const updateSettings = config => {
console.log(config);
props.updageSetting && props.updageSetting(config);
};
const handleSelectedKey = key => {
......@@ -102,10 +135,11 @@ const BasicLayout = props => {
const handleLogo = event => {
setTimeout(() => {
history.replace('/civbase/industry');
history.replace(`/industry`);
}, 300);
//
};
return (
<SecurityLayout>
<ProLayout
......@@ -113,14 +147,12 @@ const BasicLayout = props => {
siderWidth="145px"
title=""
fixSiderbar={true}
onMenuHeaderClick={event => handleLogo(event)}
onCollapse={collapse => handleMenuCollapse(collapse)}
menuExtraRender={extraRender.render}
rightContentRender={() => <RightContent />}
headerContentRender={() => renderTitle(props.global.title)}
location={{
pathname,
}}
headerContentRender={() => renderTitle(props.global.title, siteAction)}
menu={{
loading,
}}
......@@ -131,13 +163,22 @@ const BasicLayout = props => {
return defaultDom;
}
return (
<Link to={menuItemProps.path}>
<a
to={menuItemProps.path}
onClick={() =>
window.history.replaceState(
null,
`/${basename}${menuItemProps.path}`,
`/${basename}${menuItemProps.path}`,
)
}
>
{renderIcon(
menuItemProps.extData && menuItemProps.extData.icon,
17,
)}
{defaultDom}
</Link>
</a>
);
}}
subMenuItemRender={(menuItemProps, defaultDom) => {
......@@ -168,9 +209,18 @@ const BasicLayout = props => {
menuDataRef.current = menuData || [];
return menuData || [];
}}
menuProps={{
onClick: ({ item, key, keyPath, domEvent }) => {
setSelectedKeys(`${key}`);
setPathname(`/${basename}${key}`);
window.share && window.share.event.emit('changeRoute', key);
},
selectedKeys: [selectedKeys],
}}
{...props}
{...settings}
>
{/* {renderRoutes(props.route.routes)} */}
{renderRoutes(props.route.routes)}
<Panel
visible={extraRender.toggleSystem}
keyboard={true}
......@@ -179,12 +229,13 @@ const BasicLayout = props => {
onChange={index => setCurrentIndex(index)}
onSelect={selectKeys => handleSelectedKey(selectKeys)}
/>
<div
id="subapp-container"
className="subapp-container"
ref={microApp}
<div id="micro-container" className="subapp-container" ref={microApp} />
<SettingDrawer
settings={props.settings}
onSettingChange={config => updateSettings(config)}
publicPath={`/${basename}/theme`}
/>
<SettingDrawer onSettingChange={config => updateSettings(config)} />
</ProLayout>
</SecurityLayout>
);
......@@ -192,9 +243,17 @@ const BasicLayout = props => {
const mapStateToProps = state => {
return {
global: state.getIn(['global', 'globalConfig']),
settings: state.getIn(['global', 'defaultSetting']),
};
};
const mapDispatchToProps = dispatch => {
return {
updageSetting(setting) {
dispatch(actionCreators.updageSetting(setting));
},
};
};
export default connect(
mapStateToProps,
null,
mapDispatchToProps,
)(BasicLayout);
......@@ -3,6 +3,8 @@ import React from 'react';
import { connect } from 'react-redux';
import { Redirect } from 'react-router-dom';
import { getBaseName } from '../utils/utils';
class SecurityLayout extends React.Component {
state = {
isReady: false,
......@@ -15,12 +17,15 @@ class SecurityLayout extends React.Component {
}
render() {
console.log(this.props);
// const { isReady } = this.state;
const { children, global } = this.props;
const isLogin = global.token !== null;
if (!isLogin && window.location.pathname !== '/civbase/user/login') {
return <Redirect to={`/civbase/user/login?client=${global.client}`} />;
if (
!isLogin &&
window.location.pathname !== `/${getBaseName()}/user/login`
) {
return (
<Redirect to={`/${getBaseName()}/user/login?client=${global.client}`} />
);
}
return children;
}
......
import { message } from 'antd';
import Cookies from 'js-cookie';
import cityJson from './city.json';
const ERR_OK = '0000'
class Site {
constructor(props) {
this.weatherCity = null
this.globalConfig = props.global
}
init(config) {
}
initWeatherCity() {
try {
if(navigator.onLine && this.globalConfig && this.globalConfig.userInfo && this.globalConfig.userInfo.site) {
http.getCity().then(res => {
if(res && !isNaN(res.cid)) {
const cityResult = JSON.parse(cityJson);
const city = cityResult[res.cid];
this.weatherCity = city ? city: null;
}
})
}
}catch(e) {
console.error(e)
}
}
getCityStationsForUser() {
debugger
const loginName = this.globalConfig.userInfo.loginName;
const self = this;
Http.getAllGroupsInfoForUser({
loginName: loginName,
'request.preventCache': new Date().getTime()
}, {
ignoreSite: true
}).then(res => {
debugger
if(res && res.say.errMsg === '' && res.say.statusCode === ERR_OK) {
const result = res.getMe;
let city = self.weatherCity;
let arr = [];
self.globalConfig.userInfo.groupType = ""
self.globalConfig.userInfo.Groups = res.getMe;
self.globalConfig.userInfo.Industries = new Array;
if (self.globalConfig.userInfo.Groups && self.globalConfig.userInfo.Groups.length) {
self.globalConfig.userInfo.Groups.forEach(group => {
if (group.industry && self.globalConfig.userInfo.Industries.indexOf(group.industry) < 0) self.globalConfig.userInfo.Industries.push(group.industry);
});
}
if (self.globalConfig.userInfo && self.globalConfig.userInfo.site && self.globalConfig.userInfo.Groups && self.globalConfig.userInfo.Groups.length) {
var _indestryItem = self.globalConfig.userInfo.Groups.find(item => {
return item.site == self.globalConfig.userInfo.site;
});
if (_indestryItem && _indestryItem.industry) {
self.globalConfig.Industry = _indestryItem.industry;
}
}
let allStation = [];
let projectStation = [];
debugger
if (self.globalConfig.Industry) {
allStation = result.filter((item) => {
return item.industry == self.globalConfig.Industry;
})
self.showStations = allStation.filter((item) => {
return item.promoteIndex && item.promoteIndex > 0;
});
projectStation = allStation.filter((item) => {
return !item.promoteIndex;
})
} else {
allStation = result;
}
if (allStation.length) {
let allChoice = false;
allStation.forEach( (val) => {
if (val.promoteIndex == 0) {
allChoice = true;
}
})
if (!allChoice) {
// me.$el.find('#changeCityWays').hide();
// me.$el.find('.LMBcityBox').hide();
// me.$el.find('div.cities').css('min-width', 'initial');
// me.$el.find('.focusStations').addClass('LMBcolumnList');
}
if (allStation.length > 120) {
// $(me.el).find("div.cities div.cityContent").css("height", '335px');
}
let _enterprise = null;
if (self.globalConfig.userInfo.site && self.globalConfig.userInfo.site.length) {
_enterprise = allStation.filter((enterprise) => {
return enterprise.site == self.globalConfig.userInfo.site;
});
}
if (_enterprise && _enterprise.length) {
if (_enterprise[0].groupName.indexOf("演示" >= 0)) {
arr[0] = _enterprise[0].groupName;
} else {
arr = _enterprise[0].city.split('/');
}
let tmp = _enterprise[0].city.split('/')[1];
city = tmp.substr(0, tmp.length - 1);
self.globalConfig.userInfo.groupType = _enterprise[0].groupType;
} else {
arr = allStation[0].city.split('/');
let tmp = arr[1];
city = tmp.substr(0, tmp.length - 1);
self.globalConfig.userInfo.groupType = allStation[0].groupType;
}
}
if (allStation.length > 1) {
let currentStationName = arr[arr.length - 1];
// $(me.el).find('span.city').html(currentStationName);
// $(me.el).find(".item").show();
// $(me.el).find("div.cityAndWeather span.Weather").css('border-left', '1px solid #aaa');
self.AvailableofRegionName(projectStation);
self.buildCitySelectTemple(projectStation);
}
//只有演示环境出现友好提示
if (allStation.length == self.showStations.length) {
self.isOnlyDisplay = true;
// $(me.el).find(".city_pane").hide().siblings('.noStations').css('display', 'flex')
} else {
self.AvailableofRegionName(projectStation);
self.buildCitySelectTemple(projectStation);
}
console.log("showStations", self.showStations)
console.log("city", city)
return city
this.insertYSStation()
// if(city) {
// Http.getWeather({
// city: city
// }).then(res => {
// if(res.say.statusCode === ERR_OK) {
// const firtValue = res.getMe[0];
// if(firtValue.cityName) {
// const text = firtValue.forcastFirst.split(' ')[1];
// const imgPath = firtValue.presentPictureFirst.replace('gif', 'svg')
// return (
// <>
// <img src={`https://panda-water.cn/web4/assets/images/weather2/${imgPath}`}/>
// <span>{text + " " + firtValue.temperatureFirst}</span>
// </>
// )
// }
// }
// })
// }
}
})
}
insertYSStation() {
let list = [];
const hot = ["HOT", "县", "市", "New"];
this.showStations.sort((a, b) => a.promoteIndex - b.promoteIndex);
}
getNumberofRegion() {
}
AvailableofRegionName() {
}
writeCookie(tk, site) {
const date = new Date();
date.setTime(date.getTime() + 24 * 60 * 60 * 1000)
Cookies.set("token", tk, {
expires: date.toGMTString(),
path: "/"
})
const encodeSite = Base64.encode(encodeURIComponent(site));
Cookies.set("site", encodeSite, {
expires: date.toGMTString(),
path: "/"
})
const loginSite = this.getLocalSites()
loginSite[token] = site
localStorage.setItem("loginSite", JSON.stringify(loginSite))
// window.location.reload
}
changeGroup(event) {
c
Http.generateTokenQuick({
loginName: this.globalConfig.userInfo.loginName
}).then(res => {
const token = res.token
if(token) {
this.beforeChangeCheck(token, "")
}
}).catch(error => {
message.warning("切换企业失败")
})
}
beforeChangeCheck(token, site) {
Http.getUserInfo({
token: token,
subOID: 'subOID',
site: site
}).then(res => {
if(res && !res.errMsg) {
this.writeCookie(token, site)
} else {
message.warning('企业切换失败,请联系管理员排查问题!')
}
}).catch(e => {
message.warning('企业切换失败,请联系管理员排查问题!')
})
}
AvailableofRegionName() {}
buildCitySelectTemple() {}
getLocalSites() {
const localSite = localStorage.getItem("loginSite"), value = {};
if(localSite) {
value = JSON.parse(localSite)
}
return value;
}
}
export default Site;
\ No newline at end of file
......@@ -79,8 +79,50 @@
color: #555;
text-shadow: none;
font-weight: 100;
font-size: 20px;
font-size: 22px;
vertical-align: middle;
// padding-left: 80px;
letter-spacing: 2px;
}
.cityContent {
.siteName {
padding-right: 5px;
display: inline;
flex-grow: 1;
cursor: pointer;
text-shadow: none;
color: #777;
font-size: 14px;
vertical-align: middle;
padding-left: 15px;
letter-spacing: 2px;
font-weight: 100;
span {
padding-left: 5px;
text-shadow: none;
color: #777;
font-size: 14px;
vertical-align: middle;
}
img {
margin: 0!important;
}
}
.weatcher {
border-left: 1px solid rgb(170, 170, 170);
text-shadow: none;
color: #777;
font-size: 14px;
font-weight: 100;
vertical-align: middle;
padding-left: 15px;
letter-spacing: 2px;
span {
padding-left: 5px;
vertical-align: middle;
}
img {
width: 24px;
}
}
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
import ReactDOM from 'react-dom';
import {
addGlobalUncaughtErrorHandler,
registerMicroApps,
......@@ -8,76 +6,91 @@ import {
start,
} from 'qiankun';
import micorConfig from '../config/micor';
import pkg from '../package.json';
import { FILTER_FOLER } from './utils/constants';
import { FILTER_FOLER_REG } from './utils/constants';
export const initMicroApps = loader => {
debugger;
const entrys =
process.env.NODE_ENV !== 'production' ? micorConfig.dev : micorConfig.prod;
registerMicroApps(
[
{
name: 'web4_console',
entry: `//${window.location.hostname}:3020/civweb4`,
container: '#subapp-container',
activeRule: location =>
location.href.indexOf(`/${pkg.name.toLocaleLowerCase()}/civweb4`) !==
-1,
loader,
props: {
entrys.map(item => {
item.loader = loader;
item.props = {
emitter: window.share.event,
baseRoot: 'civweb4',
globalConfig: JSON.stringify(
createStoreage.get('globalConfig') || {},
),
baseRoot: item.name,
globalConfig: JSON.stringify(createStoreage.get('globalConfig') || {}),
XMLHttpRequest: window.XMLHttpRequest,
},
},
],
};
return item;
}),
{
beforeLoad: [
app => {
debugger;
// hookRequest()
// console.log(
// '[LifeCycle] before load %c%s',
// 'color: green;',
// JSON.stringify(app),
// );
console.log(
'[LifeCycle] before load %c%s',
'color: green;',
JSON.stringify(app),
app.name,
);
},
],
beforeMount: [
app => {
debugger;
// hookRequest()
ReactDOM.unmountComponentAtNode(
document.getElementById('subapp-container'),
);
// ReactDOM.unmountComponentAtNode(
// document.getElementById('subapp-container'),
// );
// console.log(
// '[LifeCycle] before mount %c%s',
// 'color: green;',
// JSON.stringify(app),
// );
// window.share.event.removeAllListeners();
console.log(
'[LifeCycle] before mount %c%s',
'color: green;',
JSON.stringify(app),
app.name,
);
// window.share.event.removeAllListeners();
},
],
beforeUnmount: [
afterMount: [
app => {
debugger;
console.log(
'[LifeCycle] before unmount %c%s',
'[LifeCycle] after mount %c%s',
'color: green;',
JSON.stringify(app),
app.name,
);
},
],
afterUnmount: [
beforeUnmount: [
app => {
debugger;
window.share.event.removeAllListeners('changeRoute');
console.log(
'[LifeCycle] after unmount %c%s',
'color: green;',
JSON.stringify(app),
app.name,
);
// console.log(
// '[LifeCycle] before unmount %c%s',
// 'color: green;',
// JSON.stringify(app),
// );
},
],
afterUnmount: [
app => {
// console.log(
// '[LifeCycle] after unmount %c%s',
// 'color: green;',
// JSON.stringify(app),
// );
},
],
},
......@@ -89,7 +102,7 @@ export const initMicroApps = loader => {
experimentalStyleIsolation: true,
loose: true,
},
singular: false,
singular: true,
scopedCSS: true,
getPublicPath: window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__,
excludeAssetFilter: url => {
......@@ -113,9 +126,10 @@ export const initMicroApps = loader => {
export const defaultApp = () => {
const config = createStoreage.get('globalConfig');
if (config && config.token) {
const startWith = config.homepage ? config.homepage.split('/') : [];
const basePath =
FILTER_FOLER.indexOf(startWith[0]) > -1 ? 'civweb4' : 'civweb';
// const startWith = config.homepage ? config.homepage.split('/') : [];
const basePath = FILTER_FOLER_REG.test(config.homepage)
? 'civweb4'
: 'civweb';
setDefaultMountApp(
`/${pkg.name.toLocaleLowerCase()}/${basePath}/?client=${config.client}`,
// config.homepage
......
......@@ -3,11 +3,16 @@ import React, {
useState,
} from 'react';
import { Spin } from 'antd';
import {
Space,
Spin,
} from 'antd';
import classNames from 'classnames';
import { connect } from 'react-redux';
import { actionCreators } from '../../containers/App/store';
import SecurityLayout from '../../layouts/SecurityLayout';
import LoginAction from '../user/login/login';
import styles from './index.less';
const industries = ['供水', '排水', '消防', '暖通', '节水', '实验室'];
......@@ -35,12 +40,23 @@ const BootPage = props => {
const [loadding, setLoadding] = useState(false);
const handlePage = useCallback((event, type) => {
event.persist();
setLoadding(true)
const config = props.global;
let loginAction = new LoginAction(props);
console.log(loginAction)
config.uiwidgets = [];
config.widgets = [];
config.allWidgets = [];
props.instance && props.instance.updateConfig(config);
props.instance && props.instance.getUserInfoAndConfig('', true, type);
// props.instance && props.instance.getUserInfoAndConfig('', true, type);
loginAction.getUserInfoAndConfig('', true, type)
loginAction.events.on('toggleIndustry', event => {
setLoadding(false);
props.history.push(`/?client=${props.global.client}`);
window.share.event.emit('triggerMicro', props.global);
location.reload();
});
}, []);
return (
<SecurityLayout>
......@@ -78,7 +94,10 @@ const BootPage = props => {
{renderIndustries(props.global, handlePage)}
</ul>
</section>
<Spin spinning={loadding} />
<Space className={styles.abs}>
<Spin spinning={loadding} size="large"/>
</Space>
</div>
</div>
</SecurityLayout>
......@@ -90,8 +109,17 @@ const mapStateToProps = state => {
instance: state.getIn(['global', 'instance']),
};
};
const mapDispatchToProps = dispatch => {
return {
updateConfig(config) {
dispatch(actionCreators.getConfig(config));
},
createContext(data) {
dispatch(actionCreators.createContext(data));
},
};
};
export default connect(
mapStateToProps,
null,
mapDispatchToProps,
)(BootPage);
......@@ -97,6 +97,13 @@
}
}
.abs {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
}
......
......@@ -11,6 +11,8 @@ var _jsCookie = _interopRequireDefault(require("js-cookie"));
var _sha = _interopRequireDefault(require("sha1"));
var _SlideVerify = _interopRequireDefault(require("../../../components/SlideVerify"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _readOnlyError(name) { throw new Error("\"" + name + "\" is read-only"); }
......@@ -27,13 +29,12 @@ function () {
function Login(props) {
_classCallCheck(this, Login);
console.log(props);
this.events = window.share.event;
this.globalConfig = props.global;
this.updateConfig = props.updateConfig;
this.createContext = props.createContext;
this.history = props.history;
this.init();
this.hasTry = false; // this.init();
}
_createClass(Login, [{
......@@ -91,7 +92,7 @@ function () {
}
}, {
key: "getIndustry",
value: function getIndustry(flag, token) {
value: function getIndustry(flag, token, _getIndustry) {
var _this3 = this;
this.globalConfig.userInfo.Industries = new Array();
......@@ -105,15 +106,15 @@ function () {
if (!flag && this.isSignIn && this.globalConfig.userInfo.Industries.length && this.globalConfig.userInfo.Industries.length > 1) {
this.createContext(this); //console.log('云平台');
this.history.push('/civbase/industry');
this.history.push('/industry');
return false;
}
this.getWebConfig(token);
this.getWebConfig(token, _getIndustry);
}
}, {
key: "getWebConfig",
value: function getWebConfig(token) {
value: function getWebConfig(token, getIndustry) {
var _this4 = this;
Http.getWebSiteConfig({
......@@ -142,7 +143,9 @@ function () {
_this4.globalConfig.style = 'sandbox';
_this4.globalConfig.uiwidgets = [_this4.globalConfig.shareWidget];
_this4.globalConfig.widgets = [];
} // window.share.event.removeAllListeners('loginSuccess');
} // this.events.removeAllListeners('loginSuccess')
// this.events.removeAllListeners('toggleIndustry')
// window.share.event = this.events;
if (_this4.globalConfig.userInfo.site && _this4.globalConfig.userInfo.site.length > 0) {
......@@ -163,21 +166,14 @@ function () {
if (mainConf.shortcutIcon) _this4.globalConfig.shortcutIcon = mainConf.shortcutIcon;
}
_this4.updateConfig && _this4.updateConfig(_this4.globalConfig); //loginSuccess
debugger;
_this4.events.emit('loginSuccess');
_this4.updateConfig && _this4.updateConfig(_this4.globalConfig);
getIndustry ? _this4.events.emit('toggleIndustry') : _this4.events.emit('loginSuccess');
window.share.event = _this4.events;
});
} else {
//loginSuccess
_this4.updateConfig && _this4.updateConfig(_this4.globalConfig);
debugger;
_this4.events.emit('loginSuccess');
getIndustry ? _this4.events.emit('toggleIndustry') : _this4.events.emit('loginSuccess');
window.share.event = _this4.events;
}
});
......@@ -201,7 +197,6 @@ function () {
}, {
key: "getProjectItems",
value: function getProjectItems() {
debugger;
var MAX_BOTTOM = 0;
var isScale = false;
var widgetIndex = -1;
......@@ -433,7 +428,6 @@ function () {
value: function getUserInfoAndConfig(failCallback, flag, industry) {
var _this7 = this;
debugger;
var token = this.globalConfig.token;
var site = _jsCookie["default"].get('site');
......@@ -470,14 +464,12 @@ function () {
'request.preventCache': Date.now()
}).then(function (response) {
try {
debugger;
if (response && !response.errMsg) {
_this7.globalConfig.userInfo = Object.assign({}, response, _this7.globalConfig.userInfo); // Cookies.set('site', this.globalConfig.userInfo.site);
_this7.writeLogs();
_this7.getIndustry(flag, token);
_this7.getIndustry(flag, token, industry);
} else {
if (_this7.goLogin()) {
return false;
......@@ -508,7 +500,6 @@ function () {
} else {
try {
this.writeLogs();
debugger;
this.getIndustry(flag, token);
} catch (error) {
if (this.goLogin()) {
......@@ -525,6 +516,8 @@ function () {
value: function login(usr, pwd, userPhone, isRememberPWD) {
var _this8 = this;
this.events.removeAllListeners('loginError');
var self = this;
Http.generateToken({
f: 'json',
expiration: this.globalConfig.expiration,
......@@ -562,14 +555,48 @@ function () {
_this8.getUserInfoAndConfig();
} else {
self.hasTry = true;
self.events.emit('loginError', response);
console.log('登录失败', response.message);
_this8.hasTry = true;
}
})["catch"](function (error) {
_this8.handleLoginError();
self.hasTry = true;
self.handleLoginError();
self.events.emit('loginError', error.message);
console.log('登录失败', error.message);
_this8.hasTry = true;
});
}
}, {
key: "loginHandler",
value: function loginHandler(user, pwd, userPhone, isRememberPWD, ref) {
var _this9 = this;
debugger;
if (user && pwd) {
if (this.loginFailed && this.captchaObj) {
this.captchaObj.verify();
} else {
if (this.hasTry) {
this.slideVerify(ref, function () {
_this9.login(user, pwd, userPhone, isRememberPWD);
});
} else {
this.login(user, pwd, userPhone, isRememberPWD);
}
}
}
}
}, {
key: "slideVerify",
value: function slideVerify(ref, _onSuccess, onFail, onRefresh) {
this.events.emit('loginVisible', true);
var slideVerify = new _SlideVerify["default"]();
slideVerify.render({
container: ref.current,
onSuccess: function onSuccess() {
_onSuccess && _onSuccess();
}
});
}
}]);
......
......@@ -7,15 +7,19 @@ import React, {
import {
Alert,
Checkbox,
message,
Modal,
Popover,
} from 'antd';
import classNames from 'classnames';
import { dom } from 'kit_utils';
import QRCode from 'qrcode.react';
import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import { actionCreators } from '../../../containers/App/store';
import LoginForm from './components/Login';
import LoginAction from './Login';
import LoginAction from './login';
import styles from './style.less';
const { UserName, Password, Submit } = LoginForm;
......@@ -23,7 +27,7 @@ const { UserName, Password, Submit } = LoginForm;
const LoginMessage = ({ content }) => (
<Alert
style={{
marginBottom: 24,
marginBottom: 2,
}}
message={content}
type="error"
......@@ -31,35 +35,114 @@ const LoginMessage = ({ content }) => (
/>
);
const useRenderQcode = (props) => {
const qrcodes = props.qrcode.split("|");
const qcodeComponent = (url) => {
return (<img src={url} className="QuickMark-cont" style={{width: '150px', height: '150px'}}/>)
}
let element = [];
qrcodes.forEach((item, index) => {
const firstValue = item.split("=");
switch(firstValue[0]) {
case "小程序":
element.push(
<div className={classNames(styles['quickMark-single'], styles['mini-single'])} key={index}>
<Popover placement="top" content={qcodeComponent("https://panda-water.cn/web4/assets/images/小程序二维码.jpg")}>
<div className={styles['icon-Container']}>
<span className={styles.Wechat}></span>
<span className="iconText WechatText">Wechat</span>
</div>
</Popover>
</div>
)
break;
case "智联小程序":
element.push(
<div className={classNames(styles["quickMark-single"], "miniIOT-single")} key={index}>
<Popover placement="top" content={qcodeComponent("https://panda-water.cn/web4/assets/images/智联小程序二维码.jpg")}>
<div className={styles['icon-Container']}>
<span className={styles.Wechat}></span>
<span className={classNames(styles.iconText, styles.WechatText)}>熊猫智联</span>
</div>
</Popover>
</div>
)
break;
case "Android":
element.push(
<div className={classNames(styles["quickMark-single"], "miniIOT-single")} key={index}>
<Popover placement="top" content={<QRCode value={firstValue[1].replace(/{ip}/ig, props.ip || window.location.host)}/>}>
<div className={styles['icon-Container']}>
<span className={styles.Android}></span>
<span className={classNames(styles.iconText, styles.AndroidText)}>Android</span>
</div>
</Popover>
</div>
)
break;
case "iPhone":
element.push(
<div className={classNames(styles["quickMark-single"], "miniIOT-single")} key={index}>
{/* <img src="https://panda-water.cn/web4/assets/images/智联小程序二维码.jpg" class="QuickMark-cont"/> */}
<Popover placement="top" content={<QRCode value={firstValue[1].replace(/{ip}/ig, props.ip || window.location.host)}/>}>
<div className={styles['icon-Container']}>
<span className={styles.Wechat}></span>
<span className={classNames(styles.iconText, styles.iphoneText)}>iPhone</span>
</div>
</Popover>
</div>
)
break;
default:
if(item && item.replace(/ /g, "").length > 0) {
}
break;
}
})
return element;
}
const Login = props => {
const { userLogin = {} } = props;
const videoRef = useRef();
const loginRef = useRef();
const timeRef = useRef();
const titleRef = useRef();
const sliVerify = useRef();
const loginFormRef = useRef();
const footerRef = useRef();
const { status, type: loginType } = userLogin;
const [status, setStatus ] = useState('normal');
const [autoLogin, setAutoLogin] = useState(true);
const [submitting, setSubmitting] = useState(false);
const [currentDate, setCurrentDate] = useState({});
const [type, setType] = useState('account');
const [visible, setVisible] = useState(false)
const [action, setAction] = useState(() => {
return new LoginAction(props)
})
const handleSubmit = values => {
/* eslint-disable no-console */
let loginAction = new LoginAction(props);
loginAction.login(values.userName, values.password);
action && action.loginHandler(values.userName, values.password, null, false, sliVerify);
setSubmitting(true);
loginAction.events.on('loginSuccess', event => {
action && action.events.on('loginSuccess', event => {
setSubmitting(false);
// window.share.event.on('updateGlobalConfig', props.global);
props.history.push(`/civbase/?client=${props.global.client}`);
props.history.push(`/?client=${props.global.client}`);
window.share.event.emit('triggerMicro', props.global);
});
action && action.events.on('loginError', event => {
console.log(event)
message.error('账户或密码错误')
setSubmitting(false)
})
action && action.events.on('loginVisible', status => {
setVisible(status)
})
};
let loginTimeInterval = null;
let videoTimeout = null;
useEffect(() => {
if (loginTimeInterval)
clearInterval(loginTimeInterval), (loginTimeInterval = null);
......@@ -88,7 +171,7 @@ const Login = props => {
videoRef.current.addEventListener('ended', function() {
dom.removeClass(loginRef.current, styles.caseHide);
dom.addClass(loginRef.current, styles.loginTimeShow);
setTimeout(() => {
videoTimeout = setTimeout(() => {
dom.removeClass(timeRef.current, styles.caseHide);
dom.addClass(timeRef.current, 'animate__fadeIn');
......@@ -102,8 +185,15 @@ const Login = props => {
}, 500);
});
}
return () => {
videoTimeout && clearTimeout(videoTimeout)
}
}, [videoRef]);
const renderAddons = useRenderQcode(props.global)
return (
<div className={styles.main}>
<video
......@@ -173,7 +263,7 @@ const Login = props => {
onTabChange={setType}
onSubmit={handleSubmit}
>
{status === 'error' && loginType === 'account' && !submitting && (
{status === 'error' && type === 'account' && !submitting && (
<LoginMessage content="账户或密码错误" />
)}
<UserName
......@@ -217,7 +307,11 @@ const Login = props => {
)}
ref={footerRef}
>
<div className={classNames('QuickMark', 'QM-wrapper')} />
<div className={classNames(styles.quickMark)}>
{
renderAddons
}
</div>
<span className={classNames(styles.copyright)}>
Copyright ©
<a target="_blank" href="https://panda-water.cn">
......@@ -227,8 +321,22 @@ const Login = props => {
<a target="_blank" id="IndexCaseNumber" href="">
ICP11036640-1
</a>
<span className="addons">
<span className="split"></span>
<a id="qrcode" href="javascript:void(0);"><span class="glyphicon glyphicon-qrcode" role="button" title="手持APP下载"></span></a>
</span>
</span>
</div>
<Modal
centered
visible={visible}
width={340}
footer={null}
closable={false}
bodyStyle={{padding: '15px'}}
>
<div ref={sliVerify}></div>
</Modal>
</div>
);
};
......
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