Commit 43e1eb2f authored by 周宏民's avatar 周宏民

feat: 集成登录功能,引导页配置

parent 167230fe
Pipeline #89733 waiting for manual action with stages
const fs = require('fs'); const fs = require('fs');
const path = require('path'); const path = require('path');
const prettierOptions = JSON.parse( const prettierOptions = JSON.parse(fs.readFileSync(path.resolve(__dirname, '.prettierrc'), 'utf8'));
fs.readFileSync(path.resolve(__dirname, '.prettierrc'), 'utf8'),
);
module.exports = { module.exports = {
parser: 'babel-eslint', parser: 'babel-eslint',
...@@ -69,14 +67,14 @@ module.exports = { ...@@ -69,14 +67,14 @@ module.exports = {
'no-unused-vars': 0, 'no-unused-vars': 0,
'no-void': 0, 'no-void': 0,
'func-names': 0, 'func-names': 0,
'array-callback-return':0, 'array-callback-return': 0,
'no-return-assign': 1, 'no-return-assign': 1,
'no-nested-ternary': 0, 'no-nested-ternary': 0,
'consistent-return': 0, 'consistent-return': 0,
'no-param-reassign': 0, 'no-param-reassign': 0,
'no-unused-expressions': 0, 'no-unused-expressions': 0,
'no-restricted-syntax': 0, 'no-restricted-syntax': 0,
"no-shadow": ["error", { "builtinGlobals": false, "hoist": "functions", "allow": [] }], 'no-shadow': ['error', { builtinGlobals: false, hoist: 'functions', allow: [] }],
'no-cond-assign': 1, 'no-cond-assign': 1,
'prefer-template': 2, 'prefer-template': 2,
'react/jsx-wrap-multilines': 0, 'react/jsx-wrap-multilines': 0,
...@@ -87,8 +85,7 @@ module.exports = { ...@@ -87,8 +85,7 @@ module.exports = {
'react/static-property-placement': 0, 'react/static-property-placement': 0,
'react/destructuring-assignment': 0, 'react/destructuring-assignment': 0,
'react/no-array-index-key': 'warn', 'react/no-array-index-key': 'warn',
"react-hooks/rules-of-hooks": "error", 'react-hooks/rules-of-hooks': 'error',
"react-hooks/exhaustive-deps": "warn",
'react/jsx-closing-tag-location': 0, 'react/jsx-closing-tag-location': 0,
'react/forbid-prop-types': 0, 'react/forbid-prop-types': 0,
'react/jsx-first-prop-new-line': [2, 'multiline'], 'react/jsx-first-prop-new-line': [2, 'multiline'],
......
...@@ -50,6 +50,16 @@ export const API = { ...@@ -50,6 +50,16 @@ export const API = {
GET_ACCOUNT_PAGE_LIST: '/PandaWorkFlow/WorkFlow/AccountManage/GetAccountPageList', GET_ACCOUNT_PAGE_LIST: '/PandaWorkFlow/WorkFlow/AccountManage/GetAccountPageList',
GET_VIDEO_PLAY_LIST_BY_DEVICE_CODE: '/PandaMonitor/Monitor/Video/GetVideoPlayListByDeviceCode', GET_VIDEO_PLAY_LIST_BY_DEVICE_CODE: '/PandaMonitor/Monitor/Video/GetVideoPlayListByDeviceCode',
HealthCheckUrl: '/PandaCore/GCK/HealthCheck/ApiCheck', // 检查环境是否能访问 HealthCheckUrl: '/PandaCore/GCK/HealthCheck/ApiCheck', // 检查环境是否能访问
SET_ENABLE_INTEGRATION: '/PandaCore/GCK/IntegrationAuth/SetEnableIntegration', // 设置站点是否启用
SAVE_INTEGRATION_CONFIG: '/PandaCore/GCK/IntegrationAuth/SaveIntegrationConfig', // 保存统一接入
DEL_INTEGRATION: '/PandaCore/GCK/IntegrationAuth/DelIntegration', // 删除站点
SAVE_INTEGRATION_INDEX: '/PandaCore/GCK/IntegrationAuth/SaveIntegrationIndex',
GET_INTEGRATION_CONFIG_ICON: '/PandaOMS/OMS/GetIntegratedloginIcon',
GET_INTEGRATED_LOGIN_SETTING: '/PandaOMS/OMS/GetIntegratedloginSetting',
ADD_INTEGRATED_LOGIN_SETTING: '/PandaOMS/OMS/AddIntegratedloginSetting',
REFRESH_SECRET: '/PandaCore/GCK/IntegrationAuth/RefreshSecret', // 根据APPKey生成APPSecret
CM_EVENT_LOAD_DEPARTMENT_ROLES: '/PandaOMS/OMS/WorkOrderCenter/CM_Event_LoadDepartmentAndRoles',
}; };
const services = { const services = {
...@@ -257,6 +267,46 @@ const services = { ...@@ -257,6 +267,46 @@ const services = {
method: constants.REQUEST_METHOD_GET, method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_HTTP, type: constants.REQUEST_HTTP,
}, },
SetEnableIntegration: {
url: API.SET_ENABLE_INTEGRATION,
method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_HTTP,
},
SaveIntegrationConfig: {
url: API.SAVE_INTEGRATION_CONFIG,
method: constants.REQUEST_METHOD_POST,
type: constants.REQUEST_HTTP,
},
DelIntegration: {
url: API.DEL_INTEGRATION,
method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_HTTP,
},
GetIntegrationConfigIcon: {
url: API.GET_INTEGRATION_CONFIG_ICON,
method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_HTTP,
},
GetIntegratedloginSetting: {
url: API.GET_INTEGRATED_LOGIN_SETTING,
method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_HTTP,
},
AddIntegratedloginSetting: {
url: API.ADD_INTEGRATED_LOGIN_SETTING,
method: constants.REQUEST_METHOD_POST,
type: constants.REQUEST_HTTP,
},
RefreshSecret: {
url: API.REFRESH_SECRET,
method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_HTTP,
},
LoadDepartmentAndRole: {
url: API.CM_EVENT_LOAD_DEPARTMENT_ROLES,
method: constants.REQUEST_METHOD_GET,
type: constants.REQUEST_HTTP,
},
}; };
export const searchAutoCity = keywords => { export const searchAutoCity = keywords => {
...@@ -308,5 +358,10 @@ export const savePagePartInfo = param => ...@@ -308,5 +358,10 @@ export const savePagePartInfo = param =>
data: param.data, data: param.data,
params: param.query, params: param.query,
}); });
export const SaveIntegrationIndex = data =>
request({
url: API.SAVE_INTEGRATION_INDEX,
method: 'post',
data,
});
export default services; export default services;
This diff was suppressed by a .gitattributes entry.
...@@ -13,17 +13,9 @@ import { useHistory, useAliveController } from '@wisdom-utils/runtime'; ...@@ -13,17 +13,9 @@ import { useHistory, useAliveController } from '@wisdom-utils/runtime';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { actionCreators } from '@/containers/App/store'; import { actionCreators } from '@/containers/App/store';
import { SERVICE_INTERFACE_SUCCESS_CODE } from '@/constants'; import { SERVICE_INTERFACE_SUCCESS_CODE } from '@/constants'; // 系统配置项名称
import PandaBootPage from './panda'; import { BootPageTemplate } from './template/constants';
import IntegrationPage from './integration';
import Demonstration from '../demonstration';
const systemItemName = '引导页模板'; // 系统配置项名称
const BootPageTemplate = {
default: PandaBootPage,
integration: IntegrationPage,
demonstration: Demonstration,
};
const BootPage = props => { const BootPage = props => {
const [info, setInfo] = useState({ const [info, setInfo] = useState({
first: true, first: true,
...@@ -33,18 +25,12 @@ const BootPage = props => { ...@@ -33,18 +25,12 @@ const BootPage = props => {
const { clear } = useAliveController(); const { clear } = useAliveController();
const history = useHistory(); const history = useHistory();
const [template, setTemplate] = useState('default'); const [template, setTemplate] = useState('default');
const [pattern, setPattern] = useState(true); // 是否进入演示模式
const RenderComponent = useMemo(() => { const RenderComponent = useMemo(() => {
if (window?.globalConfig?.isIntegration >= 1) { if (BootPageTemplate[template]) {
// 集成登录 return BootPageTemplate[template];
return BootPageTemplate.integration;
} }
if (pattern && template !== 'integration') { return BootPageTemplate.default;
return BootPageTemplate.demonstration; }, [template]);
}
// 云平台
return BootPageTemplate[template] || BootPageTemplate.default;
}, [template, pattern]);
useEffect(() => { useEffect(() => {
const tk = Cookies.get('token') || props.global.token; const tk = Cookies.get('token') || props.global.token;
...@@ -57,15 +43,14 @@ const BootPage = props => { ...@@ -57,15 +43,14 @@ const BootPage = props => {
clear(); clear();
props.logout(); props.logout();
} }
}, [clear, history, props]); }, [props]);
useEffect(() => { useEffect(() => {
if (window?.globalConfig?.isIntegration >= 1) { if (window?.globalConfig?.isIntegration >= 1) {
setInfo({ first: false, loading: false, error: false }); setInfo({ first: false, loading: false, error: false });
return false; return false;
} }
appService appService
.sysConfiguration({ .GetIntegratedloginSetting({
moduleName: systemItemName,
ignoreSite: true, ignoreSite: true,
}) })
.then(res => { .then(res => {
...@@ -75,20 +60,20 @@ const BootPage = props => { ...@@ -75,20 +60,20 @@ const BootPage = props => {
setInfo({ first: false, loading: false, error: true }); setInfo({ first: false, loading: false, error: true });
return; return;
} }
// if (data === null) notification.info({ message: '提示', duration: 3, description: '未配置系统引导页' }); let displayMode = data?.displayMode || 'default';
setTemplate(data); if (displayMode === '卡片' || displayMode === '地图') {
displayMode = 'default';
}
setTemplate(displayMode);
setInfo({ first: false, loading: false, error: false }); setInfo({ first: false, loading: false, error: false });
}) })
.catch(err => { .catch(err => {
notification.error({ message: '提示', duration: 3, description: '系统引导页配置错误' });
setInfo({ first: false, loading: false, error: true }); setInfo({ first: false, loading: false, error: true });
}); });
}, []); }, []);
return ( return (
<SecurityLayout> <SecurityLayout>{info.loading ? <Spin /> : info.error ? <Empty /> : <RenderComponent {...props} />}</SecurityLayout>
{info.loading ? <Spin /> : info.error ? <Empty /> : <RenderComponent setPattern={setPattern} {...props} />}
</SecurityLayout>
); );
}; };
const mapStateToProps = state => ({ const mapStateToProps = state => ({
......
/* eslint-disable prettier/prettier */
/*
* @Title: 引导页模板
* @Author: hongmye
* @Date: 2024-06-11 15:07:45
*/
import Demonstration from './demonstration';
import PandaBootPage from './panda';
import IntegrationPage from './integration';
export const guidePage = [
{
label: '集成登录(默认)',
value: 'default',
},
{
label: '演示环境(旧版)',
value: 'panda',
},
// {
// label: '卡片',
// value: '卡片',
// },
// {
// label: '地图',
// value: '地图',
// },
{
label: '演示环境',
type: true,
value: 'demonstration',
},
];
export const BootPageTemplate = {
default: IntegrationPage,
panda: PandaBootPage,
demonstration: Demonstration,
};
...@@ -22,23 +22,22 @@ const IframeContainer = props => { ...@@ -22,23 +22,22 @@ const IframeContainer = props => {
}; };
useEffect(() => { useEffect(() => {
if (linkUrl) { if (linkUrl) {
// console.log(decodeURIComponent(decode('aHR0cHMlM0ElMkYlMkZzbHlzLnBhbmRhLXdhdGVyLmNuJTJG')), 'decode'); // const url = linkUrl;
const url = linkUrl; // const baseUrl = url.split('civbase')[0];
const baseUrl = url.split('civbase')[0]; // appService
appService // .HealthCheckUrl({
.HealthCheckUrl({ // address: encode(baseUrl),
address: encode(baseUrl), // })
}) // .then(res => {
.then(res => { // if (res?.data !== 1) {
if (res?.data !== 1) { // onMessageBack && onMessageBack({ type: '无法连接' });
onMessageBack && onMessageBack({ type: '无法连接' }); // }
} // })
}) // .catch(err => {
.catch(err => { // onMessageBack && onMessageBack({ type: '无法连接' });
onMessageBack && onMessageBack({ type: '无法连接' }); // });
});
} }
}, [linkUrl, onMessageBack]); }, [linkUrl]);
useEffect(() => { useEffect(() => {
// iframe通信 // iframe通信
window.addEventListener('message', onMessage); window.addEventListener('message', onMessage);
......
This diff is collapsed.
This diff is collapsed.
/* eslint-disable no-lonely-if */
/* eslint-disable no-unused-expressions */
/* eslint-disable prefer-template */
/* eslint-disable react/jsx-boolean-value */
import React, { useState, useEffect } from 'react';
import { Modal, Collapse, notification } from 'antd';
import { appService } from '@/api';
import classnames from 'classnames';
import styles from '../index.less';
const { Panel } = Collapse;
const PreviewModal = props => {
const { callBackSubmit = () => {}, visible, onCancel, imageUrl, keepImgeUrl, type } = props;
const [imgData, setImgData] = useState([]);
const [pickItem, setPickItem] = useState('');
const [keepItem, setKeepItem] = useState('');
const [keepGroupName, setKeepGroupName] = useState([]);
const update = () => {
console.log(keepImgeUrl);
console.log(imageUrl);
appService
.GetIntegrationConfigIcon()
.then(res => {
if (res.code === 0) {
const bb = [];
const aa = [];
res.data.map((i, a) => {
if (i.files.length > 0 && type !== '' && i.groupName !== '网站图标') {
bb.push(i);
aa.push(i.groupName);
}
if (i.files.length > 0 && type === '' && i.groupName === '网站图标') {
bb.push(i);
aa.push(i.groupName);
}
});
setKeepGroupName(aa);
setImgData(bb);
res.data.map(i => {
i.files.map((j, index) => {
if (keepImgeUrl) {
if (j.path == keepImgeUrl) {
setKeepItem(i.groupName);
setPickItem(index);
}
} else {
if (j.path == imageUrl) {
setKeepItem(i.groupName);
setPickItem(index);
}
}
});
});
} else {
notification.error({
message: '获取失败',
description: res.msg,
});
}
})
.catch(err => {
console.error(err);
});
};
useEffect(() => {
setPickItem('');
setKeepItem('');
update();
if (!visible) {
setPickItem('');
setKeepItem('');
}
}, [visible]);
// 提交
const onSubmit = () => {
if (keepItem) {
const aa = imgData.find(i => i.groupName === keepItem);
callBackSubmit(aa.files[pickItem]);
}
onCancel();
};
const handleCollapseChange = key => {
setKeepGroupName(key);
};
return (
<Modal
title="图片库"
style={{ top: '100px' }}
width="1000px"
destroyOnClose
maskClosable={false}
cancelText="取消"
okText="确认"
{...props}
onOk={() => onSubmit()}
forceRender={true}
getContainer={false}
>
<Collapse
style={{ height: '600px', overflow: 'scroll' }}
bordered={false}
activeKey={keepGroupName}
onChange={handleCollapseChange}
>
{imgData.map((i, j) => (
<Panel
header={i.groupName}
key={i.groupName}
style={{
marginBottom: '24px',
overflow: 'hidden',
border: '0px',
background: '#f7f7f7',
borderRadius: '2px',
}}
>
{i.files.map((k, index) => (
// <Image
// src={`${isDev ? process.env.PROXY : window.location.origin}${k}`}
// height="100px"
// />
<div className={styles.divItem} key={index}>
{/* <CheckCircleTwoTone
className={classnames({
[styles.iconHidden]: index !== pickItem || i.groupName !== keepItem,
[styles.iconItem]: index === pickItem && i.groupName === keepItem,
})}
/> */}
<img
src={window.location.origin + `/${k.path}`}
className={classnames({
[styles.imgHidden]: index !== pickItem || i.groupName !== keepItem,
[styles.imgItem]: index === pickItem && i.groupName === keepItem,
})}
height="80px"
width="80px"
alt="集成登录默认"
onClick={e => {
setPickItem(index);
setKeepItem(i.groupName);
}}
/>
<div style={{ textAlign: 'center' }}>
<p>{k.name}</p>
</div>
</div>
))}
</Panel>
))}
</Collapse>
</Modal>
);
};
export default PreviewModal;
This diff is collapsed.
.modalContainer {
.ant-modal-body {
padding: 0;
}
.ant-modal-header {
padding: 28px 16px;
}
.pageContent {
display: flex;
height: 100%;
.optionalList {
position: relative;
width: 68%;
border-right: 1px solid #e7e7e7;
.title {
position: absolute;
left: 17px;
top: 10px;
font-weight: 700;
font-size: 14px;
z-index: 1;
color: #00070d;
}
.tabContent {
height: 590px;
.ant-tabs-content-holder {
height: 523px;
}
}
.searchInput {
position: absolute;
width: 200px;
z-index: 1;
top: 3px;
right: 40px;
.anticon svg {
margin-top: 0px;
}
.ant-input,
.ant-input-affix-wrapper {
border-top-left-radius: 20px;
border-bottom-left-radius: 20px;
}
.ant-input-group-addon {
border-top-right-radius: 20px;
border-bottom-right-radius: 20px;
}
.ant-input-search-button {
width: 40px;
border-top-right-radius: 20px;
border-bottom-right-radius: 20px;
}
}
.checkContent {
display: flex;
flex-wrap: wrap;
margin-left: 32px;
height: 525px;
overflow-y: scroll;
.check {
.ant-checkbox-wrapper {
width: 180px;
margin-bottom: 10px;
margin-left: 6px;
}
.ant-checkbox-wrapper span {
max-width: 160px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.ant-radio-wrapper {
width: 180px;
margin-bottom: 10px;
margin-left: 6px;
}
.ant-radio-wrapper span {
max-width: 160px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
.footer {
padding-left: 25px;
.ant-pagination {
border: none;
}
}
.ant-tabs-nav {
background-color: #f2f1f1;
}
.ant-tabs-tab {
background-color: #f2f1f1;
color: #666666;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}
.ant-tabs-tab-active {
background-color: #fff;
color: #1685ff;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}
}
.selectedList {
position: relative;
width: 40%;
.header {
height: 40px;
width: 100%;
background-color: #f2f1f1;
.title {
position: absolute;
left: 17px;
top: 10px;
font-weight: 700;
font-size: 14px;
z-index: 1;
color: #00070d;
}
.tagHead {
display: flex;
position: absolute;
top: 10px;
left: 88px;
.tagContent {
display: flex;
align-items: center;
margin-right: 11px;
}
.tagRol,
.tagOrg,
.tagSite {
width: 10px;
height: 3px;
margin-right: 5px;
}
.tagRol {
background-color: #87e8de;
}
.tagOrg {
background-color: #ffd591;
}
.tagSite {
background-color: #a785dd;
}
}
}
.selectBox {
height: 528px;
padding: 10px;
overflow-y: scroll;
.selectContent {
display: flex;
flex-wrap: wrap;
flex-direction: row;
.selectValue {
margin-bottom: 15px;
}
}
}
}
}
.ant-empty-normal {
margin: auto;
}
.ant-divider-horizontal {
margin-top: 0px;
margin-bottom: 10px;
}
}
\ No newline at end of file
This diff is collapsed.
.Integrate {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
gap: 8px;
padding: 8px;
.ant-table-pagination.ant-pagination {
margin: 2px 0;
}
.head {
padding: 10px;
background: white;
margin-bottom: 2px;
width: 100%;
display: flex;
justify-content: space-between;
.head1 {
display: flex;
align-items: center;
}
}
.cardContent {
height: 30rem;
overflow-y: scroll;
overflow-x: scroll;
width: 100%;
}
.doctorTable {
margin-bottom: 16px;
}
.divItem {
display: inline-block;
margin-left: 30px;
margin-bottom: 30px;
// width: 80px;
}
.imgItem {
border: 3px solid #00ff37;
box-sizing: border-box;
border-radius: 5px;
display: inline-block;
background-color: #2881a1;
}
.imgHidden {
border: none;
display: inline-block;
background-color: #2881a1;
}
.imgHidden:hover {
border: 3px solid #00ff37;
box-sizing: border-box;
border-radius: 5px;
display: inline-block;
}
.iconItem {
// position: relative;
// left: 70px;
// top: 10px;
// font-size: 17px;
margin-top: -3px;
font-size: 17px;
float: right;
margin-left: -10px;
}
.iconHidden {
display: none;
}
.iconHidden:hover {
// position: relative;
// left: 70px;
// top: 10px;
// font-size: 17px;
margin-top: -3px;
font-size: 17px;
float: right;
margin-left: -10px;
}
.table {
flex: 1;
background-color: white;
//height: calc(100vh - 130px);
//margin-top: 10px;
overflow-y: scroll;
padding: 8px;
}
.ant-card-body {
padding: 0px 24px 24px 17px;
}
.sel {
width: 200px;
}
.icon {
margin-top: -5px !important;
vertical-align: text-bottom;
}
.redText {
color: red;
}
.disabledInput {
:global {
.@{ant-prefix}-input[disabled] {
cursor: default;
background: none;
color: rgba(0, 0, 0, .85)
}
.@{ant-prefix}-input-affix-wrapper-disabled {
background: none;
cursor: default;
}
.@{ant-prefix}-input .@{ant-prefix}-input-disabled {
cursor: default;
background: none;
}
}
}
}
.ant-popover-message>.anticon {
margin-top: 6px;
}
\ No newline at end of file
...@@ -16,8 +16,9 @@ import Notifications from '../pages/system/notifications'; ...@@ -16,8 +16,9 @@ import Notifications from '../pages/system/notifications';
import TabIframe from '../pages/system/iframe/TabWidget'; import TabIframe from '../pages/system/iframe/TabWidget';
import JumpThirdLink from '../pages/system/iframe/JumpThirdLink'; import JumpThirdLink from '../pages/system/iframe/JumpThirdLink';
import IntegratedLogin from '../pages/system/iframe/IntegratedLogin'; import IntegratedLogin from '../pages/system/iframe/IntegratedLogin';
import PrevieView from '../pages/system/previews/preview'; import IntegratedLoginPage from '../pages/integratedLogin'; // 集成登录管理
import PrevieView from '../pages/system/previews/preview';
export const dyRoutes = (routes, layout, theme) => { export const dyRoutes = (routes, layout, theme) => {
// eslint-disable-next-line no-shadow // eslint-disable-next-line no-shadow
const dyRoutes = routes || []; const dyRoutes = routes || [];
...@@ -116,6 +117,9 @@ export const dyRoutes = (routes, layout, theme) => { ...@@ -116,6 +117,9 @@ export const dyRoutes = (routes, layout, theme) => {
if (/system\/notifications/.test(path)) { if (/system\/notifications/.test(path)) {
return <Notifications {...routeConfig} />; return <Notifications {...routeConfig} />;
} }
if (/page\/integratedLoginPage/.test(path)) {
return <IntegratedLoginPage {...routeConfig} />;
}
}, },
}, },
], ],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment