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

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

parent 167230fe
Pipeline #89733 waiting for manual action with stages
const fs = require('fs');
const path = require('path');
const prettierOptions = JSON.parse(
fs.readFileSync(path.resolve(__dirname, '.prettierrc'), 'utf8'),
);
const prettierOptions = JSON.parse(fs.readFileSync(path.resolve(__dirname, '.prettierrc'), 'utf8'));
module.exports = {
parser: 'babel-eslint',
......@@ -69,14 +67,14 @@ module.exports = {
'no-unused-vars': 0,
'no-void': 0,
'func-names': 0,
'array-callback-return':0,
'array-callback-return': 0,
'no-return-assign': 1,
'no-nested-ternary': 0,
'consistent-return': 0,
'no-param-reassign': 0,
'no-unused-expressions': 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,
'prefer-template': 2,
'react/jsx-wrap-multilines': 0,
......@@ -87,8 +85,7 @@ module.exports = {
'react/static-property-placement': 0,
'react/destructuring-assignment': 0,
'react/no-array-index-key': 'warn',
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn",
'react-hooks/rules-of-hooks': 'error',
'react/jsx-closing-tag-location': 0,
'react/forbid-prop-types': 0,
'react/jsx-first-prop-new-line': [2, 'multiline'],
......
......@@ -50,6 +50,16 @@ export const API = {
GET_ACCOUNT_PAGE_LIST: '/PandaWorkFlow/WorkFlow/AccountManage/GetAccountPageList',
GET_VIDEO_PLAY_LIST_BY_DEVICE_CODE: '/PandaMonitor/Monitor/Video/GetVideoPlayListByDeviceCode',
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 = {
......@@ -257,6 +267,46 @@ const services = {
method: constants.REQUEST_METHOD_GET,
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 => {
......@@ -308,5 +358,10 @@ export const savePagePartInfo = param =>
data: param.data,
params: param.query,
});
export const SaveIntegrationIndex = data =>
request({
url: API.SAVE_INTEGRATION_INDEX,
method: 'post',
data,
});
export default services;
This diff was suppressed by a .gitattributes entry.
......@@ -13,17 +13,9 @@ import { useHistory, useAliveController } from '@wisdom-utils/runtime';
import { connect } from 'react-redux';
import { actionCreators } from '@/containers/App/store';
import { SERVICE_INTERFACE_SUCCESS_CODE } from '@/constants';
import PandaBootPage from './panda';
import IntegrationPage from './integration';
import Demonstration from '../demonstration';
const systemItemName = '引导页模板'; // 系统配置项名称
import { SERVICE_INTERFACE_SUCCESS_CODE } from '@/constants'; // 系统配置项名称
import { BootPageTemplate } from './template/constants';
const BootPageTemplate = {
default: PandaBootPage,
integration: IntegrationPage,
demonstration: Demonstration,
};
const BootPage = props => {
const [info, setInfo] = useState({
first: true,
......@@ -33,18 +25,12 @@ const BootPage = props => {
const { clear } = useAliveController();
const history = useHistory();
const [template, setTemplate] = useState('default');
const [pattern, setPattern] = useState(true); // 是否进入演示模式
const RenderComponent = useMemo(() => {
if (window?.globalConfig?.isIntegration >= 1) {
// 集成登录
return BootPageTemplate.integration;
}
if (pattern && template !== 'integration') {
return BootPageTemplate.demonstration;
if (BootPageTemplate[template]) {
return BootPageTemplate[template];
}
// 云平台
return BootPageTemplate[template] || BootPageTemplate.default;
}, [template, pattern]);
return BootPageTemplate.default;
}, [template]);
useEffect(() => {
const tk = Cookies.get('token') || props.global.token;
......@@ -57,15 +43,14 @@ const BootPage = props => {
clear();
props.logout();
}
}, [clear, history, props]);
}, [props]);
useEffect(() => {
if (window?.globalConfig?.isIntegration >= 1) {
setInfo({ first: false, loading: false, error: false });
return false;
}
appService
.sysConfiguration({
moduleName: systemItemName,
.GetIntegratedloginSetting({
ignoreSite: true,
})
.then(res => {
......@@ -75,20 +60,20 @@ const BootPage = props => {
setInfo({ first: false, loading: false, error: true });
return;
}
// if (data === null) notification.info({ message: '提示', duration: 3, description: '未配置系统引导页' });
setTemplate(data);
let displayMode = data?.displayMode || 'default';
if (displayMode === '卡片' || displayMode === '地图') {
displayMode = 'default';
}
setTemplate(displayMode);
setInfo({ first: false, loading: false, error: false });
})
.catch(err => {
notification.error({ message: '提示', duration: 3, description: '系统引导页配置错误' });
setInfo({ first: false, loading: false, error: true });
});
}, []);
return (
<SecurityLayout>
{info.loading ? <Spin /> : info.error ? <Empty /> : <RenderComponent setPattern={setPattern} {...props} />}
</SecurityLayout>
<SecurityLayout>{info.loading ? <Spin /> : info.error ? <Empty /> : <RenderComponent {...props} />}</SecurityLayout>
);
};
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 => {
};
useEffect(() => {
if (linkUrl) {
// console.log(decodeURIComponent(decode('aHR0cHMlM0ElMkYlMkZzbHlzLnBhbmRhLXdhdGVyLmNuJTJG')), 'decode');
const url = linkUrl;
const baseUrl = url.split('civbase')[0];
appService
.HealthCheckUrl({
address: encode(baseUrl),
})
.then(res => {
if (res?.data !== 1) {
onMessageBack && onMessageBack({ type: '无法连接' });
}
})
.catch(err => {
onMessageBack && onMessageBack({ type: '无法连接' });
});
// const url = linkUrl;
// const baseUrl = url.split('civbase')[0];
// appService
// .HealthCheckUrl({
// address: encode(baseUrl),
// })
// .then(res => {
// if (res?.data !== 1) {
// onMessageBack && onMessageBack({ type: '无法连接' });
// }
// })
// .catch(err => {
// onMessageBack && onMessageBack({ type: '无法连接' });
// });
}
}, [linkUrl, onMessageBack]);
}, [linkUrl]);
useEffect(() => {
// iframe通信
window.addEventListener('message', onMessage);
......
......@@ -13,9 +13,9 @@ import Cookies from 'js-cookie';
import { defaultApp } from '@/micro';
import { appService } from '@/api';
import { SERVICE_INTERFACE_SUCCESS_CODE } from '@/constants';
import styles from './index.less';
import axios from 'axios';
import imgLogo from '@/assets/bootPage/熊猫图标.png';
import styles from './index.less';
const Integration = props => {
const dataRef = useRef();
const [percentBottom, setPercentBottom] = useState(-40);
......@@ -26,9 +26,8 @@ const Integration = props => {
const [dataList, setDataList] = useState([]);
const [client, setClient] = useState('');
//子站跳转
const handlePage = (item, loginAction) => {
// 子站跳转
const handlePage = useCallback((item, loginAction) => {
let count = 1;
setPercentBottom(-40 + Math.ceil(Math.random() * 8 * count));
......@@ -46,11 +45,11 @@ const Integration = props => {
if (item.subType == '外链') {
if (item.paramValue == 'ticket') {
//获取临时token
// 获取临时token
appService.getTicketByToken({ token: window.globalConfig?.token }).then(res => {
if (res.code === 0) {
let url = item.url + (item.url.indexOf('?') > 0 ? '&' : '?') + item.paramName + '=' + res.data;
window.open(url, "_blank");
const url = `${item.url + (item.url.indexOf('?') > 0 ? '&' : '?') + item.paramName}=${res.data}`;
window.open(url, '_blank');
} else {
notification.error({
message: '提示',
......@@ -60,22 +59,25 @@ const Integration = props => {
}
});
} else {
let url = item.url + (item.url.indexOf('?') > 0 ? '&' : '?') + item.paramName + '=' + window.globalConfig?.token;
window.open(url, "_blank");
const url = `${item.url + (item.url.indexOf('?') > 0 ? '&' : '?') + item.paramName}=${
window.globalConfig?.token
}`;
window.open(url, '_blank');
}
} else if (item.subType == '内链') {
if (window.qiankunIsCache) {
store.set('event:dropCache');
}
let cli = item.url?.indexOf('client=') >= 0 ? item.url.split('client=')[1] : '';
const cli = item.url?.indexOf('client=') >= 0 ? item.url.split('client=')[1] : '';
Cookies.set('client', cli, {
expires: 86400000 / (24 * 60 * 60 * 1000),
path: '/',
});
sessionStorage.setItem('client', cli);
const currentProduct = `__global__recent_productIndex__micro_${window.location.hostname}_${window.globalConfig?.client ?? 'city'}`;
const currentProduct = `__global__recent_productIndex__micro_${window.location.hostname}_${window.globalConfig
?.client ?? 'city'}`;
sessionStorage.removeItem(currentProduct);
const currentProductNew = `__global__recent_productIndex__micro_${window.location.hostname}_${cli || 'city'}`;
sessionStorage.setItem(currentProductNew, 0);
......@@ -95,27 +97,27 @@ const Integration = props => {
// props.instance && props.instance.updateConfig(config);
loginAction && loginAction.getUserInfoAndConfig('', true, item.type);
} else {
let url = item.url;
let { url } = item;
if (url?.indexOf('{userId}') >= 0) {
url = url.replace('{userId}', window.globalConfig?.userInfo?.OID);
}
axios({
url: url,
url,
method: 'get',
dataType: 'json'
dataType: 'json',
}).then(res => {
if (res?.data?.code === 0) {
window.location.href = res.data?.data;
}
});
}
};
});
useEffect(() => {
const handleToggleIndustry = event => {
setPercentBottom(38);
clearInterval(process.current);
props.history.push(`/?client=${client ? client : props.global.client}`);
props.history.push(`/?client=${client || props.global.client}`);
props.updateCurrentIndex(0);
......@@ -128,8 +130,7 @@ const Integration = props => {
};
}, [loginAction.events, props, currentType]);
//获取集成站点数据
// 获取集成站点数据
useEffect(() => {
appService
.GetIntegrationConfig({
......@@ -141,7 +142,6 @@ const Integration = props => {
const { code, data } = res;
if (code !== SERVICE_INTERFACE_SUCCESS_CODE) {
notification.error({ message: '提示', duration: 3, description: '集成站点配置错误' });
return;
} else {
setNum(data.length);
setDataList(data);
......@@ -149,7 +149,7 @@ const Integration = props => {
config.isIntegration = data.length;
props.updateConfig && props.updateConfig(config);
if (data.length == 1) {
handlePage(data[0], loginAction)
handlePage(data[0], loginAction);
}
}
})
......@@ -162,45 +162,73 @@ const Integration = props => {
<div className={styles.bootPage}>
<div className={styles.bootPageMain}>
<header className={styles.bootPageHead}>
{
props.global.logo
? <img role="logo" src={props.global && props.global.transformDevAssetsBaseURL && props.global.transformDevAssetsBaseURL(props.global.logo)} />
: <img src={require(window.globalConfig.logo ? window.globalConfig.logo : `@/assets/bootPage/熊猫图标.png`)} />
}
{props.global.logo && props.global.transformDevAssetsBaseURL ? (
<img role="logo" src={props.global.transformDevAssetsBaseURL(props.global.logo)} alt="" />
) : (
<img src={window.globalConfig.logo ? require(window.globalConfig.logo) : imgLogo} alt="" />
)}
<div className={styles.bootPageTitle}>
<span className={styles.bootPageZh}>{window.globalConfig?.title ?? '熊猫智慧水务一体化解决方案'}</span>
<span className={styles.bootPageEn}>{window.globalConfig.title ? window.globalConfig.subtitle : 'Panda Smart Water Integration Platform & Solution'}</span>
<span className={styles.bootPageEn}>
{window.globalConfig.title
? window.globalConfig.subtitle
: 'Panda Smart Water Integration Platform & Solution'}
</span>
</div>
</header>
<section className={classNames(styles.bootPageSection, 'animate__fadeInDown', 'animate__animated', 'duration-500ms')} >
<ul className={classNames(styles.bootPageUl, 'animate__animated')}
style={{ transform: `scale(${scale})`, left: '300px', bottom: '105px', opacity: 1, width: num === 5 ? 960 : num === 9 || num === 10 ? 1600 : 1280, }} >
{dataList.length > 1 ? dataList.map(item => (
<li className={styles.bootPageLi} key={item.name} onClick={event => handlePage(item, loginAction)} >
<section
className={classNames(styles.bootPageSection, 'animate__fadeInDown', 'animate__animated', 'duration-500ms')}
>
<ul
className={classNames(styles.bootPageUl, 'animate__animated')}
style={{
transform: `scale(${scale})`,
left: '300px',
bottom: '105px',
opacity: 1,
width: num === 5 ? 960 : num === 9 || num === 10 ? 1600 : 1280,
}}
>
{dataList.length > 1
? dataList.map(item => (
<li className={styles.bootPageLi} key={item.name} onClick={event => handlePage(item, loginAction)}>
<div className={styles.bootPageList}>
<div className={styles.listMain}>
{/* <img src={require(`@/assets/bootPage/供水.png`)} alt="" /> */}
<img src={window.location.origin + '/' + (item.icon ? item.icon : 'center/images/科技风/二供.png')} alt="" />
<img
src={`${window.location.origin}/${item.icon ? item.icon : 'center/images/科技风/二供.png'}`}
alt=""
/>
<span className={styles.bootPageName}>{item.name}</span>
</div>
</div>
{currentType === item.name && (
<div className={styles.bootProgress}>
<div className={styles.inner} style={{ bottom: percentBottom }}>
<svg className={styles.wave} xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" viewBox="0 24 150 68" preserveAspectRatio="none" >
<svg
className={styles.wave}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
viewBox="0 24 150 68"
preserveAspectRatio="none"
>
<defs>
<path id="gentle-wave" d="M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z" />
<path
id="gentle-wave"
d="M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z"
/>
</defs>
<g className={styles.parallax}>
<use xlinkHref="#gentle-wave" x="50" y="0" fill={'rgb(16,104,239)'} opacity="0.1" />
<use xlinkHref="#gentle-wave" x="50" y="-1" fill={'rgb(16,104,239)'} opacity="0.2" />
<use xlinkHref="#gentle-wave" x="50" y="0" fill="rgb(16,104,239)" opacity="0.1" />
<use xlinkHref="#gentle-wave" x="50" y="-1" fill="rgb(16,104,239)" opacity="0.2" />
</g>
</svg>
</div>
</div>
)}
</li>
)) : ''}
))
: ''}
</ul>
</section>
</div>
......
import React, { useState, useEffect } from 'react';
// import 'react-quill/dist/quill.snow.css';
import { appService } from '@/api';
import {
Form,
Modal,
Input,
notification,
Radio,
Button,
message,
Upload,
Row,
Col,
Select,
AutoComplete,
Switch,
Tooltip,
} from 'antd';
import { PlusOutlined, LoadingOutlined, RedoOutlined } from '@ant-design/icons';
import CryptoJS from 'crypto-js';
import RMSComponents from './RolePmSite';
import PreviewModal from './PreviewModal';
import styles from '../index.less';
const PUBLISH_SERVICE = '/PandaOMS/OMS';
const { Item } = Form;
const { TextArea } = Input;
const AddModal = props => {
const { callBackSubmit = () => {}, type, pickItem, visible, onCancel, keepSystemName, groupList, targetType } = props;
const [loading, setLoading] = useState(false);
const [radio, setRadio] = useState();
const [identity, setIdentity] = useState(0);
const [form] = Form.useForm();
const [imageUrl, setImageUrl] = useState();
const [im, setIm] = useState();
const [previewModal, setPreviewModal] = useState(false);
const [keepImgeUrl, setKeepImgeUrl] = useState('');
const [fileList, setFileList] = useState([]);
const [isVisibleRoles, setIsVisibleRoles] = useState(false);
const [groupName, setGroupName] = useState('角色');
const [chooseGroupName, setChooseGroupName] = useState(['角色']);
const [checkedList1, setCheckedList1] = useState([]); // 最新选择数据
const [keepFiled, setKeepFiled] = useState([]);
const [pick, setPick] = useState(''); // 复选框数据填入项
const [keepIds, setKeepIds] = useState(null);
const [account, setAccount] = useState(0);
const [isFromLocal, setIsFromLocal] = useState('');
const key = CryptoJS.enc.Utf8.parse('1p2a3n4d5a6o7m8s9a10n1e2t3c4o5re'); // 十六位十六进制数作为密钥
const iv = CryptoJS.enc.Utf8.parse('1234567890000000');
const { Option } = Select;
useEffect(() => {
if (visible) {
setIsFromLocal('');
getRole();
if (type === 'edit') {
setRadio(pickItem.target != 0);
setIdentity(pickItem.siteType);
setAccount(pickItem.accountType);
const { paramName, paramValue, url, name, icon, roles, appKey, appSecret, whiteList, subType } = pickItem;
form.setFieldsValue({
paramName,
paramValue,
url,
subType,
name,
icon,
roles: roles ? roles.split(',') : null,
appKey,
appSecret,
whiteList,
});
if (pickItem.images && pickItem.images.length > 0) {
const arr = [];
pickItem.images.map((i, j) => {
const aa = {};
aa.uid = j;
aa.name = 'image.png';
aa.status = 'done';
aa.url = `${window.location.origin}/${i}`;
aa.submitUrl = i;
arr.push(aa);
});
setFileList(arr);
}
if (pickItem.icon) {
if (!pickItem.icon.includes('images')) {
setImageUrl(getImg(pickItem.icon));
setIm(pickItem.icon);
} else {
if (pickItem.icon.startsWith('CityTemp') || pickItem.icon.startsWith('civ_integratedlogin')) {
setImageUrl(`http://192.168.12.116:8017/${pickItem.icon}`);
} else {
setImageUrl(`${window.location.origin}/${pickItem.icon}`);
}
setIm(pickItem.icon);
}
// }
} else {
form.setFieldsValue({
icon: '',
});
setImageUrl('');
setIm('');
}
} else {
setRadio(0);
setIdentity(0);
setAccount(0);
form.setFieldsValue({
paramValue: 'ticket',
target: 0,
mapSetting: '',
coordinate: '',
siteType: 0,
accountType: 0,
});
}
} else {
setRadio('');
setFileList([]);
setImageUrl('');
setIm('');
setKeepImgeUrl('');
form.resetFields();
}
}, [visible]);
const getRole = () => {
appService.LoadDepartmentAndRole().then(res => {
if (res.code === 0) {
setKeepFiled(groupArr(res.data, 'groupType'));
const aa = groupArr(res.data, 'groupType');
if (type === 'edit' && pickItem.roles) {
const data = pickItem.roles.split(',');
const newData = [];
data.forEach(item => {
newData.push(aa.角色.find(i => i.value == item).label);
});
form.setFieldsValue({ roles: newData.toString() });
}
}
});
};
const pickFiled1 = fileds => {
const values = form.getFieldValue(fileds);
console.log('🚀 ~ values:', values);
if (form.getFieldValue(fileds)) {
setCheckedList1(form.getFieldValue(fileds).split(','));
setPick(fileds);
setIsVisibleRoles(true);
} else {
setCheckedList1([]);
setPick(fileds);
setIsVisibleRoles(true);
}
};
const groupArr = (initialArr, name) => {
const list = {};
initialArr.data.map(i => {
const ar = [];
i.root.map(j => {
const ss = {};
ss.label = j.Name;
ss.value = j.ID.toString();
ar.push(ss);
// console.log(ss);
});
list[i.groupType] = ar;
});
return list;
};
// 提交
const onSubmit = () => {
form.validateFields().then(validate => {
if (validate) {
setLoading(true);
const obj = form.getFieldsValue();
if (identity === 0) {
if (!obj.url) {
notification.warning({
message: '提示',
duration: 3,
description: '请填写地址',
});
return;
}
}
const aa = { key: obj.paramName, value: obj.paramValue };
const bb = [];
bb.push(aa);
if (obj.icon.file) {
obj.icon = obj.icon.file.response.data;
}
let data = [];
if (obj.coordinate) {
data = obj.coordinate.split(',');
}
const dataList = [];
if (fileList.length > 0) {
fileList.map(i => {
if (i.submitUrl) {
dataList.push(i.submitUrl);
} else {
dataList.push(i.response.data);
}
});
}
if (!obj.icon) {
message.error('请选择图标!');
return;
}
// 从本地选取
if (!isFromLocal && isFromLocal !== '') {
if (obj.icon.includes('CityTemp') && obj.icon.includes('图库')) {
obj.icon = obj.icon;
} else {
obj.icon = `CityTemp\\图库\\${obj.icon}`;
}
}
if (type === 'add') {
appService
.SaveIntegrationConfig({
name: obj.name,
type: targetType,
url: obj.url,
roles: keepIds?.join(',') || '',
icon: obj.icon,
userId: window.globalConfig.userInfo.OID,
paramValue: obj.paramValue,
paramName: obj.paramName,
appKey: obj.appKey,
appSecret: obj.appSecret,
whiteList: obj.whiteList,
subType: obj.subType,
})
.then(res => {
if (res.code === 0) {
onCancel();
setLoading(false);
callBackSubmit();
notification.success({
message: '提示',
duration: 3,
description: res.msg || '新增成功',
});
} else {
setLoading(false);
notification.error({
message: '提示',
duration: 3,
description: res.msg || '新增失败',
});
}
})
.catch(err => {
setLoading(false);
});
} else {
appService
.SaveIntegrationConfig({
id: pickItem.id,
name: obj.name,
type: pickItem.type,
url: obj.url,
roles: keepIds === null ? pickItem.roles : keepIds.join(','),
icon: obj.icon,
userId: window.globalConfig.userInfo.OID,
paramValue: obj.paramValue,
paramName: obj.paramName,
whiteList: obj.whiteList,
appKey: obj.appKey,
appSecret: obj.appSecret,
subType: obj.subType,
})
.then(res => {
if (res.code === 0) {
onCancel();
setLoading(false);
callBackSubmit();
notification.success({
message: '提示',
duration: 3,
description: res.msg || '编辑成功',
});
} else {
setLoading(false);
notification.error({
message: '提示',
duration: 3,
description: res.msg || '编辑失败',
});
}
})
.catch(err => {
setLoading(false);
});
}
}
});
};
const layout = {
layout: 'horizontal',
labelCol: { span: 4 },
wrapperCol: { span: 18 },
};
const onChange = e => {
setRadio(e);
};
const beforeUpload = file => {
const isJpgOrPng =
file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/jpg' || file.type === 'image/gif';
if (!isJpgOrPng) {
message.error('只能上传格式为jpeg/png/gif的图片!');
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
message.error('图片必须小于2MB!');
}
return isJpgOrPng && isLt2M;
};
const getImg = img => `/PandaOMS/OMS/FileCenter/DownLoadFiles?module=图库&filePath=${img}`;
const handleChange = info => {
setKeepImgeUrl('');
setIm('');
if (info.file.status === 'uploading') {
setLoading(true);
return;
}
if (info.file.status === 'done') {
if (info.file.response.code === 0) {
setIsFromLocal(false);
if (info.file.response.data.includes('CityTemp') && info.file.response.data.includes('图库')) {
setImageUrl(getImg(info.file.response.data));
} else {
setImageUrl(getImg(info.file.response.data));
}
setLoading(false);
} else {
message.error(info.file.response.msg);
setImageUrl('');
setLoading(false);
}
}
};
const uploadButton = (
<div>
{/* {loading ? <LoadingOutlined/> : <PlusOutlined/>} */}
<div
style={{
marginTop: 8,
}}
>
请选择图片
</div>
</div>
);
const pictruePreview = () => {
setPreviewModal(true);
};
const onOk = props => {
if (props) {
if (!props.path.includes('images')) {
setImageUrl(getImg(props.path));
setIm(props.path);
setKeepImgeUrl(props.path);
} else {
setImageUrl(`${window.location.origin}/${props.path}`);
setIm(props.path);
setKeepImgeUrl(props.path);
}
setIsFromLocal(true);
form.setFieldsValue({ icon: `${props.path}` });
}
};
const options = [
{
value: 'http://{IP:端口}/civbase/user/noscret/?client={client}',
},
{
value: 'http://{IP:端口}/web4/?client={client}',
},
];
const onChangeIdentity = e => {
setIdentity(e.target.value);
};
const onChangeAccount = e => {
setAccount(e.target.value);
};
const onOK = prop => {
setIsVisibleRoles(false);
const inputText = {};
inputText[prop.pickItem] = prop.str;
setCheckedList1(prop.stt);
setKeepIds(prop.ids);
form.setFieldsValue(inputText);
};
const refreshAppSecret = () => {
const appKey = form.getFieldValue('appKey');
appService
.RefreshSecret({
appKey,
})
.then(res => {
if (res.code === 0) {
form &&
form.setFieldsValue({
appSecret: res.data,
});
} else {
form &&
form.setFieldsValue({
appSecret: '',
});
}
});
};
return (
<Modal
title={type === 'add' ? `新增-${targetType}` : `编辑-${targetType}`}
bodyStyle={{ width: '100%', maxHeight: '600px', overflow: 'scroll' }}
width="700px"
destroyOnClose
maskClosable={false}
cancelText="取消"
okText="确认"
{...props}
onOk={() => onSubmit()}
forceRender
getContainer={false}
>
<Form form={form} {...layout}>
{type === 'edit' ? (
<Item
label="名称"
name="name"
rules={[
{ required: true, message: '请输入名称' },
{
validator: (rule, value) => {
const aa = form.getFieldValue().name;
const regEn = /[`~!@#$%^&*()_+<>?:"{},.\/;'[\]]/im;
const regCn = /[·!#¥(——):;“”‘、,|《。》?、【】[\]]/im;
if (keepSystemName.indexOf(aa) != -1 && pickItem.name != aa) {
return Promise.reject('名称已存在');
}
if (regEn.test(aa) || regCn.test(aa)) {
return Promise.reject('名称不能包含特殊字符');
}
return Promise.resolve();
},
},
]}
>
<Input allowClear style={{ width: '100%' }} placeholder="请输入名称" />
</Item>
) : (
<Item
label="名称"
name="name"
rules={[
{ required: true, message: '请输入名称' },
{
validator: (rule, value) => {
const aa = form.getFieldValue().name;
const regEn = /[`~!@#$%^&*()_+<>?:"{},.\/;'[\]]/im;
const regCn = /[·!#¥(——):;“”‘、,|《。》?、【】[\]]/im;
if (keepSystemName.indexOf(aa) != -1) {
return Promise.reject('名称已存在');
}
if (regEn.test(aa) || regCn.test(aa)) {
return Promise.reject('名称不能包含特殊字符');
}
return Promise.resolve();
},
},
]}
>
<Input allowClear style={{ width: '100%' }} placeholder="请输入名称" />
</Item>
)}
<Item label="角色选择" name="roles">
<div style={{ display: 'flex' }}>
<Item name="roles" style={{ marginBottom: 0, width: '100%' }}>
<Input placeholder="请选择执行角色" />
</Item>
<Button
type="dashed"
onClick={() => pickFiled1('roles')}
icon={<PlusOutlined style={{ marginTop: '5px' }} />}
style={{ marginLeft: '10px', width: '70px' }}
/>
</div>
</Item>
<Row>
<Col span={10}>
<Item
label="图标"
name="icon"
style={{ height: '112px' }}
labelCol={{ span: 10 }}
rules={[
{
required: true,
message: '请选择图标',
},
]}
>
<Upload
disabled
name="singleFile"
listType="picture-card"
showUploadList={false}
beforeUpload={beforeUpload}
action={`${window.location.origin}${PUBLISH_SERVICE}/UploadSingleFile`}
// onChange={handleChange}
>
{imageUrl ? (
<img
src={imageUrl}
alt="singleFile"
style={{
width: '90%',
backgroundColor: '#2881a1',
}}
/>
) : (
uploadButton
)}
</Upload>
</Item>
</Col>
<Col span={12}>
<Item>
<Button type="primary" onClick={pictruePreview} style={{ marginTop: '33px' }}>
从图片库中选择
</Button>
</Item>
</Col>
</Row>
<Item label="链接类型" name="subType" initialValue="内链">
<Radio.Group>
<Radio value="内链">站内跳转</Radio>
<Radio value="外链">站外跳转</Radio>
<Radio value="自定义">自定义</Radio>
</Radio.Group>
</Item>
<Item label="地址" name="url" rules={[{ required: true, message: '请输入站点路径' }]}>
<AutoComplete placeholder="请输入可以访问的链接,需要与下方的链接类型对应" allowClear />
</Item>
<Row>
<Col span={12}>
<Item
labelCol={{ span: 8 }}
label="参数名"
name="paramName"
rules={[{ required: true, message: '请输入参数' }]}
>
<Input allowClear placeholder="请填写站点参数" />
</Item>
</Col>
<Col span={10}>
<Item label="参数值" labelCol={{ span: 7 }} name="paramValue">
<Select placeholder="请选择参数值">
<Option value="ticket">ticket</Option>
<Option value="token">token</Option>
</Select>
</Item>
</Col>
</Row>
{
<>
<Item
label="AppKey"
name="appKey"
className={styles.disabledInput}
rules={[{ required: true, message: '请输入参数' }]}
>
<Input disabled={type === 'edit'} placeholder="请输入自定义的AppKey,提交后不可变更" />
</Item>
<Item
label="AppSecret"
name="appSecret"
className={styles.disabledInput}
rules={[{ required: true, message: '请输入AppKey,或点击刷新按钮重新获取AppSecret' }]}
>
<Input
disabled
placeholder="请点击按钮生成AppSecret"
suffix={
<Tooltip title="点击按钮重新生成AppSecret">
<RedoOutlined
style={{ fontSize: 'bold', color: 'rgba(25,128,255,0.74)' }}
onClick={refreshAppSecret}
/>
</Tooltip>
}
/>
</Item>
</>
}
<Item label="白名单" name="whiteList">
<TextArea rows={3} />
</Item>
</Form>
<PreviewModal
visible={previewModal}
onCancel={() => {
setPreviewModal(false);
}}
imageUrl={im}
keepImgeUrl={keepImgeUrl}
type={type}
callBackSubmit={onOk}
/>
<RMSComponents
visible={isVisibleRoles}
onCancel={() => setIsVisibleRoles(false)}
callBackSubmit={onOK}
newCheckedList={checkedList1} // 单选框中的值
pickItem={pick}
groupName={groupName} // 打开组件展示的分组名,用来首次获取数据
chooseGroupName={chooseGroupName} // 可选分组名
keepFiled={keepFiled}
dataType="name"
/>
</Modal>
);
};
export default AddModal;
/* eslint-disable prefer-template */
/* eslint-disable react/jsx-boolean-value */
import React, { useState, useEffect, useMemo } from 'react';
import {
Form,
Modal,
Input,
notification,
Button,
message,
Upload,
Select,
Col,
Row,
Cascader,
Radio,
AutoComplete,
InputNumber,
} from 'antd';
import { appService } from '@/api';
import { PlusOutlined, LoadingOutlined } from '@ant-design/icons';
import { guidePage } from '@/pages/bootpage/template/constants';
import PreviewModal from './PreviewModal';
const PUBLISH_SERVICE = '/PandaOMS/OMS';
const { Item } = Form;
const { Option } = Select;
const colorList = [
{
key: '科技蓝',
color: '#2262B2',
// headerColor: 'linear-gradient(0deg, #0066D6 0%, #39A9FF 100%)',
},
{
key: '环保绿',
color: '#00A295',
// headerColor: 'linear-gradient(0deg, #00845D 0%, #02BF87 100%)',
},
// {
// key: '科技蓝',
// color: '#1890FF',
// // headerColor: 'linear-gradient(0deg, #0066D6 0%, #39A9FF 100%)',
// },
// {
// key: '环保绿',
// color: '#00B496',
// // headerColor: 'linear-gradient(0deg, #00845D 0%, #02BF87 100%)',
// },
];
const Master = props => {
const { callBackSubmit = () => {}, visible, onCancel, type, isPanda } = props;
const [loading, setLoading] = useState(false);
const [form] = Form.useForm();
const [imgBed, setImgBed] = useState();
const [imageUrl, setImageUrl] = useState();
const [im, setIm] = useState();
const [previewModal, setPreviewModal] = useState(false);
const [keepImgeUrl, setKeepImgeUrl] = useState('');
const [options, setOptions] = useState([]);
const [radio, setRadio] = useState();
const [flag, setFlag] = useState(0);
const [keepSettings, setKeepSettings] = useState([]);
const [isFromLocal, setIsFromLocal] = useState(false);
const optionsTemp = useMemo(() => {
const oType = guidePage.filter(item => {
if (isPanda) {
return true;
}
return !item.type;
});
return oType;
}, [isPanda]);
console.log(optionsTemp, 'optionsTemp');
useEffect(() => {
if (visible) {
appService.GetIntegratedloginSetting().then(res => {
if (res.code === 0) {
console.log(res.data);
const aa = res.data.title.split('<br/>');
const bb = res.data.qrCodeConfig.split('|');
const displayMode = res.data.displayMode || 'default';
form.setFieldsValue({
logo: res.data.logo,
primaryColor: res.data.primaryColor,
displayMode,
// subtitle: res.data.subtitle,
title: aa[0],
titlebr: aa[1],
loginTemplate: res.data.loginTemplate,
loadingTime: res.data.loadingTime,
mapSettings: res.data.mapSettings,
qrCodename: bb[0],
qrCodeurl: bb[1],
});
setKeepSettings(res.data.mapSettings);
if (res.data.displayMode === '卡片') {
setFlag(0);
} else {
setFlag(1);
}
const data = res.data.displayMode || 'default';
setRadio(data);
setImageUrl(window.location.origin + `/${res.data.logo}`);
setIm(res.data.logo);
} else {
form.setFieldsValue({
primaryColor: '#1890FF',
});
}
});
} else {
setImageUrl('');
setIm('');
setKeepImgeUrl('');
form.resetFields();
setFlag(0);
}
}, [form, visible]);
// 提交
const onSubmit = () => {
const obj = form.getFieldsValue();
if (obj.qrCodename && !obj.qrCodeurl) {
notification.error({
message: '提示',
duration: 3,
description: '输入二维码名称,则二维码Url必填',
});
} else if (!obj.qrCodename && obj.qrCodeurl) {
notification.error({
message: '提示',
duration: 3,
description: '输入二维码Url,则输入二维码名称必填',
});
} else {
form.validateFields().then(validate => {
if (obj.logo.file) {
obj.logo = obj.logo.file.response.data;
}
if (obj.titlebr) {
obj.title = `${obj.title}<br/>${obj.titlebr}`;
}
console.log(obj.qrCodename || obj.qrCodeurl);
if (validate) {
if (!obj.logo) {
message.error('请选择登录Logo!');
return;
}
if (!isFromLocal) {
if (obj.logo.includes('CityTemp') && obj.logo.includes('图库')) {
obj.logo = obj.logo;
} else {
obj.logo = 'CityTemp\\图库\\' + obj.logo;
}
}
appService
.AddIntegratedloginSetting({
logo: obj.logo,
primaryColor: obj.primaryColor,
subtitle: obj.subtitle,
loginTemplate: obj.loginTemplate || 'Default',
title: obj.title,
displayMode: obj.displayMode,
loadingTime: obj.loadingTime,
mapSettings: obj.displayMode === '卡片' ? keepSettings : obj.mapSettings,
qrCodeConfig: obj.qrCodename && obj.qrCodeurl && `${obj.qrCodename}|${obj.qrCodeurl}`,
})
.then(res => {
if (res.code === 0) {
onCancel();
callBackSubmit();
notification.success({
message: '提示',
duration: 3,
description: res.msg || '操作成功',
});
} else {
notification.error({
message: '提示',
duration: 3,
description: res.msg || '操作失败',
});
}
})
.catch(err => {
console.log(err);
});
}
});
}
console.log(obj);
};
const layout = {
layout: 'horizontal',
labelCol: { span: 4 },
wrapperCol: { span: 18 },
};
const beforeUpload = file => {
const isJpgOrPng =
file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/jpg' || file.type === 'image/gif';
if (!isJpgOrPng) {
message.error('只能上传格式为jpeg/png/gif的图片!');
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
message.error('图片必须小于2MB!');
}
return isJpgOrPng && isLt2M;
};
const getImg = img => `/PandaOMS/OMS/FileCenter/DownLoadFiles?module=图库&filePath=${img}`;
const handleChange = info => {
setKeepImgeUrl('');
setIm('');
if (info.file.status === 'uploading') {
setLoading(true);
return;
}
if (info.file.response.code === 0) {
setIsFromLocal(false);
setImageUrl(getImg(info.file.response.data));
setLoading(false);
} else {
message.error(info.file.response.msg);
setImageUrl('');
setLoading(false);
}
// if (info.file.status === 'done') {
// DownLoadFiles({ module: '图库\\第三方图标', filePath: info.file.response.data }).then(res => {
// let reader = new FileReader();
// reader.readAsDataURL(res);
// reader.onload = function() {
// setImageUrl(reader.result);
// };
// });
// getBase64(info.file.originFileObj, url => {
// setLoading(false);
// setImageUrl(url);
// });
};
const getBase64 = (img, callback) => {
const reader = new FileReader();
reader.addEventListener('load', () => callback(reader.result));
reader.readAsDataURL(img);
};
const uploadButton = (
<div>
{loading ? <LoadingOutlined /> : <PlusOutlined />}
<div
style={{
marginTop: 8,
}}
>
上传
</div>
</div>
);
const pictruePreview = () => {
setPreviewModal(true);
};
const onOk = props => {
if (props) {
setImageUrl(window.location.origin + `/${props.path}`);
setIm(props.path);
setKeepImgeUrl(props.path);
form.setFieldsValue({ logo: `${props.path}` });
setIsFromLocal(true);
}
};
const onChange = e => {
console.log(e);
setRadio(e.target.value);
if (e.target.value == '地图') {
setFlag(1);
} else {
setFlag(0);
}
};
const renderTitle = title => <span>{title}</span>;
const renderItem = title => ({
value: title,
label: (
<div
style={{
display: 'flex',
justifyContent: 'space-between',
}}
>
{title}
</div>
),
});
const options1 = [
{
label: renderTitle('产品'),
options: [renderItem('Default')],
},
{
label: renderTitle('项目'),
options: [
renderItem('Water'),
renderItem('蠡县'),
renderItem('榆林全景'),
renderItem('张掖'),
renderItem('确山水利局'),
],
},
];
return (
<Modal
title="配置集成网站"
style={{ top: '150px' }}
width="700px"
destroyOnClose
maskClosable={false}
cancelText="取消"
okText="确认"
{...props}
onOk={() => onSubmit()}
forceRender={true}
getContainer={false}
>
<Form form={form} {...layout}>
<Row>
<Col span={14}>
<Item
labelCol={{ span: 7 }}
label="标题"
name="title"
rules={[
{
required: true,
message: '标题为必填项',
},
]}
>
<Input placeholder="请输入标题" autoComplete="off" style={{ marginleft: '3px' }} />
</Item>
</Col>
<Col span={8}>
<Item name="titlebr">
<Input placeholder="换行文案" autoComplete="off" style={{ marginLeft: '20px', width: '123%' }} />
</Item>
</Col>
</Row>
<Row>
<Col span={10}>
<Item
label="登录Logo"
name="logo"
style={{ height: '112px' }}
labelCol={{ span: 10 }}
rules={[
{
required: true,
message: '请选择图标icon',
},
]}
>
<Upload
name="singleFile"
listType="picture-card"
className="avatar-uploader"
showUploadList={false}
beforeUpload={beforeUpload}
action={`${window.location.origin}${PUBLISH_SERVICE}/UploadSingleFile`}
onChange={handleChange}
>
{imageUrl ? (
<img
src={imageUrl}
alt="singleFile"
style={{
width: '90%',
backgroundColor: '#2881a1',
}}
/>
) : (
uploadButton
)}
</Upload>
</Item>
</Col>
<Col span={12}>
<Item>
<Button type="primary" onClick={pictruePreview} style={{ marginTop: '33px' }}>
从图片库中选择
</Button>
</Item>
</Col>
</Row>
<Item name="primaryColor" label="主题">
<Select placeholder="请选择颜色" style={{ marginLeft: '3px' }}>
{colorList.map(item => (
<Option value={item.color} key={item.color}>
<div style={{ display: 'flex', alignItems: 'center' }}>
{/* <div
style={{
height: '10px',
width: '10px',
background: item.color,
marginRight: '5px',
}}
/> */}
{`${item.key}`}
</div>
</Option>
))}
</Select>
</Item>
<Item label="登录模板" name="loginTemplate">
<AutoComplete placeholder="请选择登录模板" options={options1} allowClear />
</Item>
<Item label="引导页模板" name="displayMode">
<Select placeholder="请选择引导页模板" options={optionsTemp} />
</Item>
<Row>
<Col span={8}>
<Item
label="加载时间"
name="loadingTime"
labelCol={{ span: 12 }}
rules={[
{
required: true,
message: '加载时间必填项',
},
]}
>
<InputNumber min={0} max={5} />
</Item>
</Col>
<Col span={16}>
<Item>
<span>秒</span>
</Item>
</Col>
</Row>
{/* <Item label="展示方式" name="displayMode">
<Radio.Group onChange={onChange} value={radio}>
<Radio value="卡片">卡片</Radio>
<Radio value="地图">地图</Radio>
</Radio.Group>
</Item> */}
{/* {flag == 1 ? (
<Item
label="地区选择"
name="mapSettings"
rules={[
{
required: true,
message: '地区选择为必填项',
},
]}
>
<Cascader
fieldNames={{
label: 'name',
value: 'adcode',
children: 'districtList',
}}
multiple
showSearch
options={options}
placeholder="请选择行政区"
changeOnSelect
allowClear={false}
/>
</Item>
) : (
<></>
)} */}
<Row>
<Col span={8}>
<Item name="qrCodename" label="二维码" labelCol={{ span: 12 }}>
<Input placeholder="请输入名称" />
</Item>
</Col>
<Col span={16}>
<Item
labelCol={{ span: 4 }}
name="qrCodeurl"
label="url"
rules={[
{
validator: (rule, value) => {
const aa = form.getFieldValue().qrCodeurl;
const regEn = /^((ht|f)tps?):\/\/([\w-]+(\.[\w-]+)*\/?)+(\?([\w\-\.,@?^=%&:\/~\+#]*)+)?$/;
if (aa) {
if (regEn.test(aa) === false) {
return Promise.reject('url必须以http(s)://开头');
}
}
return Promise.resolve();
},
},
]}
>
<Input placeholder="请输入二维码url" style={{ width: '95%' }} />
</Item>
</Col>
</Row>
</Form>
<PreviewModal
visible={previewModal}
onCancel={() => {
setPreviewModal(false);
}}
imageUrl={im}
keepImgeUrl={keepImgeUrl}
callBackSubmit={onOk}
type={type}
/>
</Modal>
);
};
export default Master;
/* 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;
import React, { useState, useEffect, useRef, useCallback } from 'react';
import { Modal, Checkbox, Tabs, Input, Button, Pagination, Empty, Tag, Divider, Radio } from 'antd';
import { appService } from '@/api';
import styles from './index.less';
const CheckboxGroup = Checkbox.Group;
const { TabPane } = Tabs;
const RMSComponents = props => {
const {
callBackSubmit = () => {},
pickItem,
visible,
newCheckedList,
groupName,
chooseGroupName,
dataType,
isRadio,
} = props;
const [checkedList, setCheckedList] = useState([]); // 选中复选框内容
const [searchWord, setSearchWord] = useState(''); // 关键字
const { Search } = Input;
const [total, setTotal] = useState();
const [pageSize, setPageSize] = useState(45);
const [currentPage, setCurrentPage] = useState(1);
const [checkDataRole, setCheckDataRole] = useState([]);
const [checkDataPm, setCheckDataPm] = useState([]);
const [checkDataSite, setCheckDataSite] = useState([]);
const [saveCheckValue, setSaveCheckValue] = useState([]); // 保存选中值
const [keepTabKey, setKeepTabKey] = useState(0); // 保存tabs的key
const [keyValue, setKeyValue] = useState('0');
const [emptyValue, setEmptyValue] = useState(0);
const [selected, setSelected] = useState(new Map()); // 已勾选角色列表
const [optionValue, setOptionValue] = useState([]);
const [indeterminate, setIndeterminate] = useState(false);
const [checkAll, setCheckAll] = useState(false);
const [indeterminate1, setIndeterminate1] = useState(false);
const [checkAll1, setCheckAll1] = useState(false);
const [indeterminate2, setIndeterminate2] = useState(false);
const [checkAll2, setCheckAll2] = useState(false);
const keepFiled = useRef({});
const [radioValue, setRadioValue] = useState();
const radioChange = e => {
setRadioValue(e.target.value);
const data = optionValue['站点'].find(i => i.value === e.target.value);
const cs = new Map();
cs.set(data.value, {
value: data.label,
type: 2,
});
setSelected(cs);
};
const onSubmit = () => {
const selectData = [];
const ids = [];
selected.forEach((val, key) => {
selectData.push(val.value);
ids.push(key);
});
callBackSubmit({
str: selectData.join(','),
pickItem,
stt: selectData,
ids,
});
setKeyValue('0');
setSearchWord('');
};
useEffect(() => {
if (visible) {
appService.LoadDepartmentAndRole().then(res => {
if (res.msg === 'Ok') {
// setFiled1(formateArrDataA1(res.data, 'groupType'));
keepFiled.current = groupArr(res.data, 'groupType');
if (groupName == '角色') {
setKeyValue('0');
setKeepTabKey(0);
} else if (groupName == '部门') {
setKeyValue('1');
setKeepTabKey(1);
} else if (groupName == '站点') {
setKeyValue('2');
setKeepTabKey(2);
}
getRoles(groupName, '', pageSize, 1, 0);
const checkArr = [];
// 角色
const listdata = [];
const listId = [];
newCheckedList.map(checkItem => {
keepFiled.current['角色'].map(i => {
const canSave = dataType === 'name' ? i.label == checkItem : i.value == checkItem;
if (canSave) {
listdata.push(i);
listId.push(i.value.toString());
}
});
});
const cs = selected;
listdata.map(i => {
cs.set(i.value, {
value: i.label,
type: 0,
});
});
setSelected(cs);
const dataId = Array.from(new Set(listId));
setCheckDataRole(dataId); // 用于设置首次展示已选列表角色数据
checkArr[0] = dataId;
// 部门
const pmdata = [];
const pmId = [];
newCheckedList.map(checkItem => {
keepFiled.current['部门'].map(i => {
const canSave = dataType === 'name' ? i.label == checkItem : i.value == checkItem;
if (canSave) {
pmdata.push(i);
pmId.push(i.value.toString());
}
});
});
const cs1 = selected;
pmdata.map(i => {
cs1.set(i.value, {
value: i.label,
type: 1,
});
});
setSelected(cs1);
const datapmId = Array.from(new Set(pmId));
setCheckDataPm(datapmId);
checkArr[1] = datapmId;
// 站点
const sitedata = [];
const siteId = [];
newCheckedList.map(checkItem => {
keepFiled.current['站点'].map(i => {
const canSave = dataType === 'name' ? i.label == checkItem : i.value == checkItem;
if (canSave) {
sitedata.push(i);
siteId.push(i.value.toString());
}
});
});
const cs2 = selected;
sitedata.map(i => {
cs2.set(i.value, {
value: i.label,
type: 2,
});
});
setSelected(cs2);
const datasiteId = Array.from(new Set(siteId));
setCheckDataSite(datasiteId);
checkArr[2] = datasiteId;
if (isRadio) {
setRadioValue(siteId[0]);
}
setSaveCheckValue(checkArr);
setCheckedList(checkArr);
}
});
} else {
setSelected(new Map());
setPageSize(45);
setCurrentPage(1);
setIndeterminate(false);
setCheckAll(false);
setCheckedList([]);
setRadioValue();
setOptionValue([]);
}
}, [visible]);
const submitSearchUser = () => {
if (keepTabKey == 0) {
sreachRoles('角色', searchWord, pageSize, 1);
}
if (keepTabKey == 1) {
sreachRoles('部门', searchWord, pageSize, 1);
}
if (keepTabKey == 2) {
sreachRoles('站点', searchWord, pageSize, 1);
}
};
// 获取搜索框的值
const handleSearch = e => {
setSearchWord(e.target.value);
};
// 监听分页
const paginationChange = (page, pageSizes) => {
setCheckAll(false);
setCheckAll1(false);
setCheckAll2(false);
setIndeterminate(false);
setIndeterminate1(false);
setIndeterminate2(false);
if (keepTabKey == 0) {
getRoles('角色', searchWord, pageSizes, page);
}
if (keepTabKey == 1) {
getRoles('部门', searchWord, pageSizes, page);
}
if (keepTabKey == 2) {
getRoles('站点', searchWord, pageSizes, page);
}
setCurrentPage(page);
setPageSize(pageSizes);
};
// 搜索时获取数据
const sreachRoles = (type, keywords, pageSizes, pageIndex) => {
appService
.LoadDepartmentAndRole({
type,
keywords,
pageSize: pageSizes,
pageIndex,
})
.then(res => {
if (res.msg === 'Ok') {
setOptionValue(groupArr(res.data, 'groupType'));
const aa = groupArr(res.data, 'groupType');
const list = [];
let data = '';
if (type == '角色') {
data = 0;
} else if (type === '部门') {
data = 1;
} else if (type === '站点') {
data = 2;
}
aa[type] &&
aa[type].map(i => {
if (checkedList[data].indexOf(i.value) != -1) {
list.push(i.value);
}
});
if (list.length === aa[type].length) {
if (type === '角色') {
setCheckAll(true);
setIndeterminate(false);
} else if (type === '部门') {
setCheckAll1(true);
setIndeterminate1(false);
} else if (type === '站点') {
setCheckAll2(true);
setIndeterminate2(false);
}
} else if (list.length < aa[type].length && list.length !== 0) {
if (type === '角色') {
setCheckAll(false);
setIndeterminate(true);
} else if (type === '部门') {
setCheckAll1(false);
setIndeterminate1(true);
} else if (type === '站点') {
setCheckAll2(false);
setIndeterminate2(true);
}
} else if (list.length === 0) {
if (type === '角色') {
setCheckAll(false);
setIndeterminate(false);
} else if (type === '部门') {
setCheckAll1(false);
setIndeterminate1(false);
} else if (type === '站点') {
setCheckAll2(false);
setIndeterminate2(false);
}
}
setCurrentPage(1);
setTotal(res.data.count);
if (res.data.count == 0) {
setEmptyValue(1);
} else {
setEmptyValue(0);
}
}
});
};
const getRoles = useCallback((type, keywords, pageSizes, pageIndex, flag) => {
appService
.LoadDepartmentAndRole({
type,
keywords,
pageSize: pageSizes,
pageIndex,
})
.then(res => {
if (res.code === 0) {
setTotal(res.data.count);
setOptionValue(groupArr(res.data, 'groupType'));
const aa = groupArr(res.data, 'groupType');
const list = [];
let data = '';
if (type === '角色') {
data = 0;
} else if (type === '部门') {
data = 1;
} else if (type === '站点') {
data = 2;
}
// 首次进入调用
if (flag != undefined) {
const listId = [];
newCheckedList.map(checkItem => {
keepFiled.current[groupName].map(i => {
const canSave = dataType === 'name' ? i.label == checkItem : i.value == checkItem;
if (canSave) {
listId.push(i.value.toString());
}
});
});
aa[type] &&
aa[type].map(i => {
if (listId.indexOf(i.value) != -1) {
list.push(i.value);
}
});
} else {
aa[type] &&
aa[type].map(i => {
if (checkedList[data].indexOf(i.value) != -1) {
list.push(i.value);
}
});
}
if (list.length === aa[type].length) {
if (type == '角色') {
setCheckAll(true);
setIndeterminate(false);
} else if (type == '部门') {
setCheckAll1(true);
setIndeterminate1(false);
} else if (type == '站点') {
setCheckAll2(true);
setIndeterminate2(false);
}
} else if (list.length < aa[type].length && list.length !== 0) {
if (type == '角色') {
setCheckAll(false);
setIndeterminate(true);
} else if (type == '部门') {
setCheckAll1(false);
setIndeterminate1(true);
} else if (type == '站点') {
setCheckAll2(false);
setIndeterminate2(true);
}
} else if (list.length === 0) {
if (type == '角色') {
setCheckAll(false);
setIndeterminate(false);
} else if (type == '部门') {
setCheckAll1(false);
setIndeterminate1(false);
} else if (type == '站点') {
setCheckAll2(false);
setIndeterminate2(false);
}
}
if (res.data.count == 0) {
setEmptyValue(1);
} else {
setEmptyValue(0);
}
}
});
});
const groupArr = (initialArr, name) => {
const list = {};
initialArr.data.map(i => {
const ar = [];
i.root.map(j => {
const ss = {};
ss.label = j.Name;
ss.value = j.ID.toString();
ar.push(ss);
});
list[i.groupType] = ar;
});
return list;
};
const handleParChange = key => {
setKeyValue(key);
// setSearchWord('');
setCurrentPage(1);
setKeepTabKey(key);
if (key == 0) {
getRoles('角色', searchWord, pageSize, 1);
}
if (key == 1) {
getRoles('部门', searchWord, pageSize, 1);
}
if (key == 2) {
getRoles('站点', searchWord, pageSize, 1);
}
};
const onChangeListNew = list => {
const checkedListArr = [...saveCheckValue];
const data = checkDataRole;
const DataValue = [];
if (optionValue['角色']) {
optionValue['角色'].map(i => {
if (checkDataRole.indexOf(i.value) != -1) {
DataValue.push(i.value);
}
});
}
// del
if (DataValue.length > list.length) {
DataValue.forEach(item => {
if (list.indexOf(item) == -1) {
data.splice(data.findIndex(ele => ele === item), 1);
const hhh = selected;
hhh.delete(item);
setSelected(hhh);
}
});
} else {
// add
list.forEach(item => {
if (data.indexOf(item) == -1) {
data.push(item);
}
});
const arrList = [];
keepFiled.current['角色'] &&
keepFiled.current['角色'].map(k => {
if (data.indexOf(k.value) != -1) {
arrList.push(k);
}
});
const cs = selected;
arrList.map(i => {
cs.set(i.value, {
value: i.label,
type: 0,
});
});
setSelected(cs);
}
checkedListArr[0] = data;
const listdata = [];
optionValue['角色'].map(i => {
if (data.indexOf(i.value) != -1) {
listdata.push(i.value);
}
});
if (listdata.length === optionValue['角色'].length) {
setCheckAll(true);
setIndeterminate(false);
} else if (listdata.length < optionValue['角色'].length && listdata.length !== 0) {
setCheckAll(false);
setIndeterminate(true);
} else if (listdata.length === 0) {
setCheckAll(false);
setIndeterminate(false);
}
setCheckDataRole(data);
setSaveCheckValue(checkedListArr);
setCheckedList(checkedListArr);
};
const onChangeListNew1 = list => {
const checkedListArr = [...saveCheckValue];
const data = checkDataPm;
const DataValue = [];
// 拿到当前页数据
if (optionValue['部门']) {
optionValue['部门'].map(i => {
if (checkDataPm.indexOf(i.value) != -1) {
DataValue.push(i.value);
}
});
}
// del
if (DataValue.length > list.length) {
DataValue.forEach(item => {
if (list.indexOf(item) == -1) {
data.splice(data.findIndex(ele => ele === item), 1);
const hhh = selected;
hhh.delete(item);
setSelected(hhh);
}
});
} else {
// add
list.forEach(item => {
if (data.indexOf(item) == -1) {
data.push(item);
}
});
const arrList = [];
keepFiled.current['部门'] &&
keepFiled.current['部门'].map(k => {
if (data.indexOf(k.value) != -1) {
arrList.push(k);
}
});
const cs = selected;
arrList.map(i => {
cs.set(i.value, {
value: i.label,
type: 1,
});
});
setSelected(cs);
}
checkedListArr[1] = data;
const listdata = [];
optionValue['部门'].map(i => {
if (data.indexOf(i.value) != -1) {
listdata.push(i.value);
}
});
if (listdata.length === optionValue['部门'].length) {
setCheckAll1(true);
setIndeterminate1(false);
} else if (listdata.length < optionValue['部门'].length && listdata.length !== 0) {
setCheckAll1(false);
setIndeterminate1(true);
} else if (listdata.length === 0) {
setCheckAll1(false);
setIndeterminate1(false);
}
setCheckDataPm(data);
setSaveCheckValue(checkedListArr);
setCheckedList(checkedListArr);
};
const onChangeListNew2 = list => {
const checkedListArr = [...saveCheckValue];
const data = checkDataSite;
const DataValue = [];
// 拿到当前页数据
if (optionValue['站点']) {
optionValue['站点'].map(i => {
if (checkDataSite.indexOf(i.value) != -1) {
DataValue.push(i.value);
}
});
}
// del
if (DataValue.length > list.length) {
DataValue.forEach(item => {
if (list.indexOf(item) == -1) {
data.splice(data.findIndex(ele => ele === item), 1);
const hhh = selected;
hhh.delete(item);
setSelected(hhh);
}
});
} else {
// add
list.forEach(item => {
if (data.indexOf(item) == -1) {
data.push(item);
}
});
const arrList = [];
keepFiled.current['站点'] &&
keepFiled.current['站点'].map(k => {
if (data.indexOf(k.value) != -1) {
arrList.push(k);
}
});
const cs = selected;
arrList.map(i => {
cs.set(i.value, {
value: i.label,
type: 2,
});
});
setSelected(cs);
}
checkedListArr[2] = data;
const listdata = [];
optionValue['站点'].map(i => {
if (data.indexOf(i.value) != -1) {
listdata.push(i.value);
}
});
if (listdata.length === optionValue['站点'].length) {
setCheckAll2(true);
setIndeterminate2(false);
} else if (listdata.length < optionValue['站点'].length && listdata.length !== 0) {
setCheckAll2(false);
setIndeterminate2(true);
} else if (listdata.length === 0) {
setCheckAll2(false);
setIndeterminate2(false);
}
setCheckDataSite(data);
setSaveCheckValue(checkedListArr);
setCheckedList(checkedListArr);
};
const changeColor = e => {
if (e === 0) {
return 'cyan';
}
if (e === 1) {
return 'orange';
}
return 'purple';
};
// 删除已选中列表
const delSelected = value => {
setRadioValue('');
const aa = selected.get(value).type;
const list = [];
const checkedListArr = saveCheckValue;
checkedListArr[aa].map(i => {
if (i != value) {
list.push(i);
}
});
checkedListArr[aa] = list;
setSaveCheckValue(checkedListArr);
setCheckedList(checkedListArr);
let name = '';
if (aa === 0) {
setCheckDataRole(list);
name = '角色';
} else if (aa === 1) {
setCheckDataPm(list);
name = '部门';
} else if (aa === 2) {
setCheckDataSite(list);
name = '站点';
}
const hhh = selected;
hhh.delete(value);
setSelected(hhh);
const keepValue = [];
optionValue[name].map(i => {
if (list.indexOf(i.value) != -1) {
keepValue.push(i);
}
});
if (keepValue.length === optionValue[name].length) {
if (aa == 0) {
setCheckAll(true);
setIndeterminate(false);
} else if (aa == 1) {
setCheckAll1(true);
setIndeterminate1(false);
} else if (aa == 2) {
setCheckAll2(true);
setIndeterminate2(false);
}
} else if (keepValue.length < optionValue[name].length && keepValue.length != 0) {
if (aa == 0) {
setCheckAll(false);
setIndeterminate(true);
} else if (aa == 1) {
setCheckAll1(false);
setIndeterminate1(true);
} else if (aa == 2) {
setCheckAll2(false);
setIndeterminate2(true);
}
} else if (keepValue.length === 0) {
if (aa == 0) {
setCheckAll(false);
setIndeterminate(false);
} else if (aa == 1) {
setCheckAll1(false);
setIndeterminate1(false);
} else if (aa == 2) {
setCheckAll2(false);
setIndeterminate2(false);
}
}
};
const onCheckAllChange = e => {
setIndeterminate(false);
setCheckAll(e.target.checked);
const checkedListArr = [...saveCheckValue];
const data = [];
optionValue['角色'] &&
optionValue['角色'].map(i => {
data.push(i.value);
});
let list = [];
if (e.target.checked) {
// 复选框
list = Array.from(new Set([...checkedList[0], ...data]));
checkedListArr[0] = list;
// 已选列表
const cs = selected;
optionValue['角色'].map(i => {
cs.set(i.value, {
value: i.label,
type: 0,
});
});
setSelected(cs);
} else {
checkedListArr[0].map(i => {
if (data.indexOf(i) == -1) {
list.push(i);
}
});
checkedListArr[0] = list;
// 已选列表
const hhh = selected;
data.map(i => {
hhh.delete(i);
});
setSelected(hhh);
}
console.log(checkedListArr);
setCheckDataRole(list);
setSaveCheckValue(checkedListArr);
setCheckedList(checkedListArr);
};
const onCheckAllChange1 = e => {
setIndeterminate1(false);
setCheckAll1(e.target.checked);
const checkedListArr = [...saveCheckValue];
const data = [];
optionValue['部门'] &&
optionValue['部门'].map(i => {
data.push(i.value);
});
let list = [];
if (e.target.checked) {
// 复选框
list = Array.from(new Set([...checkedList[1], ...data]));
checkedListArr[1] = list;
// 已选列表
const cs = selected;
optionValue['部门'].map(i => {
cs.set(i.value, {
value: i.label,
type: 1,
});
});
setSelected(cs);
} else {
checkedListArr[1].map(i => {
if (data.indexOf(i) == -1) {
list.push(i);
}
});
checkedListArr[1] = list;
// 已选列表
const hhh = selected;
data.map(i => {
hhh.delete(i);
});
setSelected(hhh);
}
setCheckDataPm(list);
setSaveCheckValue(checkedListArr);
setCheckedList(checkedListArr);
};
const onCheckAllChange2 = e => {
setIndeterminate2(false);
setCheckAll2(e.target.checked);
const checkedListArr = [...saveCheckValue];
const data = [];
optionValue['站点'] &&
optionValue['站点'].map(i => {
data.push(i.value);
});
let list = [];
if (e.target.checked) {
// 复选框
list = Array.from(new Set([...checkedList[2], ...data]));
checkedListArr[2] = list;
// 已选列表
const cs = selected;
optionValue['站点'].map(i => {
cs.set(i.value, {
value: i.label,
type: 2,
});
});
setSelected(cs);
} else {
checkedListArr[2].map(i => {
if (data.indexOf(i) == -1) {
list.push(i);
}
});
checkedListArr[2] = list;
// 已选列表
const hhh = selected;
data.map(i => {
hhh.delete(i);
});
setSelected(hhh);
}
setCheckDataSite(list);
setSaveCheckValue(checkedListArr);
setCheckedList(checkedListArr);
};
return (
<div className={styles.modalContainer}>
<Modal
title="权限选择"
bodyStyle={{ width: '100%', height: '590px', overflowY: 'scorll' }}
width="1000px"
style={{ top: '-20px' }}
destroyOnClose
centered
cancelText="取消"
okText="确认"
{...props}
onOk={() => onSubmit()}
forceRender
getContainer={false}
afterClose={() => {
setKeyValue('0');
setSearchWord('');
}}
>
<div className={styles.pageContent}>
{/* 可选列表 */}
<div className={styles.optionalList}>
<div className={styles.header} />
<Search
className={styles.searchInput}
allowClear
placeholder="搜索"
onSearch={submitSearchUser}
onChange={e => handleSearch(e)}
value={searchWord}
/>
<div className={styles.tabContent}>
{visible && (
<Tabs type="card" activeKey={keyValue} onChange={handleParChange}>
{chooseGroupName.indexOf('角色') !== -1 ? (
<TabPane tab="角色" key="0">
<div className={styles.checkContent}>
{emptyValue == 0 ? (
<div className={styles.check}>
<Checkbox indeterminate={indeterminate} onChange={onCheckAllChange} checked={checkAll}>
全选
</Checkbox>
<Divider />
<CheckboxGroup
options={optionValue['角色']}
value={checkedList[0]}
onChange={onChangeListNew}
/>
</div>
) : (
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="暂无数据" />
)}
</div>
</TabPane>
) : (
<></>
)}
{chooseGroupName.indexOf('部门') !== -1 ? (
<TabPane tab="部门" key="1">
<div className={styles.checkContent}>
{emptyValue == 0 ? (
<div className={styles.check}>
<Checkbox indeterminate={indeterminate1} onChange={onCheckAllChange1} checked={checkAll1}>
全选
</Checkbox>
<Divider />
<CheckboxGroup
options={optionValue['部门']}
value={checkedList[1]}
onChange={onChangeListNew1}
/>
</div>
) : (
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="暂无数据" />
)}
</div>
</TabPane>
) : (
<></>
)}
{chooseGroupName.indexOf('站点') !== -1 ? (
<TabPane tab="站点" key="2">
<div className={styles.checkContent}>
{emptyValue == 0 ? (
<div className={styles.check}>
{isRadio ? (
<Radio.Group onChange={radioChange} value={radioValue}>
{optionValue['站点']?.map(i => <Radio value={i.value}>{i.label}</Radio>)}
</Radio.Group>
) : (
<>
<Checkbox
indeterminate={indeterminate2}
onChange={onCheckAllChange2}
checked={checkAll2}
>
全选
</Checkbox>
<Divider />
<CheckboxGroup
options={optionValue['站点']}
value={checkedList[2]}
onChange={onChangeListNew2}
/>
</>
)}
</div>
) : (
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="暂无数据" />
)}
</div>
</TabPane>
) : (
<></>
)}
</Tabs>
)}
</div>
{/* 分页 */}
<div className={styles.footer}>
<Pagination
size="small"
total={total}
showSizeChanger
defaultPageSize={pageSize}
defaultCurrent={1}
pageSizeOptions={[10, 20, 45, 100]}
current={currentPage}
onChange={paginationChange}
style={{ marginBottom: '10px' }}
/>
</div>
</div>
{/* 已选列表 */}
<div className={styles.selectedList}>
<div className={styles.header}>
<div className={styles.title}>已选列表</div>
<div className={styles.tagHead}>
{chooseGroupName.indexOf('角色') !== -1 ? (
<div className={styles.tagContent}>
<div className={styles.tagRol} />
<div>角色</div>
</div>
) : (
<></>
)}
{chooseGroupName.indexOf('部门') !== -1 ? (
<div className={styles.tagContent}>
<div className={styles.tagOrg} />
<div>部门</div>
</div>
) : (
<></>
)}
{chooseGroupName.indexOf('站点') !== -1 ? (
<div className={styles.tagContent}>
<div className={styles.tagSite} />
<div>站点</div>
</div>
) : (
<></>
)}
</div>
</div>
<div className={styles.selectBox}>
{[...selected].length > 0 ? (
<div className={styles.selectContent}>
{[...selected].map(item => (
<div className={styles.selectValue} key={item[0]}>
<Tag closable color={changeColor(item[1].type)} onClose={() => delSelected(item[0])}>
{item[1].value}
</Tag>
</div>
))}
</div>
) : (
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description={`请选择${chooseGroupName.toString()}`} />
)}
</div>
</div>
</div>
</Modal>
</div>
);
};
export default RMSComponents;
.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
import React, { useState, useEffect } from 'react';
import { Tooltip, Spin, Modal, Input, Space, Button, Popconfirm, Table, Image, Tag, message, Popover } from 'antd';
import { appService } from '@/api';
import { SaveIntegrationIndex } from '@/api/service/base';
import {
EditTwoTone,
DeleteOutlined,
PlusOutlined,
SyncOutlined,
FilePdfOutlined,
OrderedListOutlined,
LockOutlined,
UnlockOutlined,
DownOutlined,
SortAscendingOutlined,
SortDescendingOutlined,
} from '@ant-design/icons';
// import pdf from '@/assets/pdf/熊猫智慧水务第三方系统接入说明文档.pdf';
import styles from './index.less';
import AddModal from './components/AddModal';
import Master from './components/Master';
const path = require('path');
const IntegratedLogin = props => {
let isPanda = props.params?.isPanda || 'true';
isPanda = isPanda === 'true';
const [loading, setLoading] = useState(false);
const [tableData, setTableData] = useState([]);
const [showSearchStyle, setShowSearchStyle] = useState(false); // 是否显示模糊查询样式
const [searchWord, setSearchWord] = useState(''); // 关键字
const [addVisible, setAddVisible] = useState(false);
const [pickItem, setPickItem] = useState('');
const [type, setType] = useState('');
const [masterVisible, setMasterVisible] = useState(false);
const [keepSystemName, setKeepSystemName] = useState([]);
const [sortVisible, setSortVisible] = useState(false);
const [groupList, setGroupList] = useState([]); // 分组列表
const [targetType, setTargetType] = useState('');
const [migrationLoading, setMigrationLoading] = useState(false);
const menuItems = [
{
label: '集成登录',
key: '集成登录',
icon: <PlusOutlined />,
},
{
label: '单点登录',
key: '单点登录',
icon: <PlusOutlined />,
},
];
const { Search } = Input;
const columns = [
{
title: '序号',
key: 'id ',
dataIndex: 'id',
render: (text, record, index) => (
<Space>
<span>{index + 1}</span>
</Space>
),
width: 60,
align: 'center',
},
{
title: '图标',
dataIndex: 'icon',
key: 'icon',
align: 'center',
width: 200,
render: (text, record) => {
if (text) {
return (
<Image
src={`${window.location.origin}/${text}`}
// src={text}
height="50px"
style={{ backgroundColor: '#2881a1' }}
/>
);
}
},
},
{
title: '名称',
dataIndex: 'name',
key: 'name',
align: 'center',
width: 200,
ellipsis: true,
render: (text, record) => (
<span>
<Tooltip placement="top" title={text}>
{searchStyle(text)}
</Tooltip>
</span>
),
},
{
title: '集成方式',
dataIndex: 'type',
width: 120,
key: 'type',
align: 'center',
},
{
title: 'APPKey',
dataIndex: 'appKey',
width: 120,
key: 'appKey',
align: 'center',
},
{
title: 'APPSecret',
dataIndex: 'appSecret',
key: 'appSecret',
align: 'left',
},
{
title: '操作',
key: 'action',
width: 200,
align: 'center',
render: (record, text, index) => {
console.log(record, text, index);
return (
<Space size="middle">
{index ? (
<Tooltip title="上升">
<Button icon={<SortDescendingOutlined />} type="text" onClick={() => onSort('up', index)} />
</Tooltip>
) : null}
{index < tableData.length - 1 ? (
<Tooltip title="下移">
<Button icon={<SortAscendingOutlined />} type="text" onClick={() => onSort('down', index)} />
</Tooltip>
) : null}
<Tooltip title="编辑">
<EditTwoTone onClick={() => edit(record)} style={{ fontSize: '16px' }} />
</Tooltip>
{!record.isEnable ? (
<Tooltip title="停用">
<Popconfirm
placement="left"
title={
<p>
启用站点
<span className={styles.redText}>{record.name}</span>
</p>
}
okText="确认"
cancelText="取消"
onConfirm={() => freezeUser(record)}
>
<LockOutlined style={{ fontSize: '16px', color: '#e86060' }} />
</Popconfirm>
</Tooltip>
) : (
<Tooltip title="启用">
<Popconfirm
placement="left"
title={
<p>
停用站点
<span className={styles.redText}>{record.name}</span>
</p>
}
okText="确认"
cancelText="取消"
onConfirm={() => freezeUser(record)}
>
<UnlockOutlined style={{ fontSize: '16px', color: '#1890ff' }} />
</Popconfirm>
</Tooltip>
)}
<Tooltip title="删除">
<Popconfirm
placement="bottomRight"
title={
<p>
即将删除 <span>{record.loginName}</span>
,是否确认删除?
</p>
}
okText="确认"
cancelText="取消"
onConfirm={() => dele(record)}
>
<DeleteOutlined style={{ fontSize: '16px', color: '#e86060' }} />
</Popconfirm>
</Tooltip>
</Space>
);
},
},
];
// 停用
const freezeUser = e => {
const aa = e;
aa.isHide = true;
appService
.SetEnableIntegration({
id: e.id,
})
.then(res => {
if (res.code == 0) {
getData();
message.success('设置成功');
} else {
res.msg && message.error(res.msg);
}
});
};
// 模糊查询匹配的样式
const searchStyle = val => {
let n;
if (showSearchStyle) {
n = val.replace(new RegExp(searchWord, 'g'), `<span style='color:red'>${searchWord}</span>`);
} else {
n = val;
}
return <div dangerouslySetInnerHTML={{ __html: n }} />;
};
const getData = () => {
setLoading(true);
appService.GetIntegrationConfig().then(res => {
setLoading(false);
if (res.code === 0) {
const _allName = [];
const _groupList = [];
res.data.forEach(item => {
const _name = item.name;
_allName.push(_name);
_groupList.push({ value: _name, label: _name });
});
setGroupList(_groupList);
setKeepSystemName(_allName);
setTableData(res.data.sort((a, b) => a.index - b.index));
} else {
res.msg && message.error(res.msg);
}
});
};
const add = e => {
setType('add');
setTargetType(e);
setAddVisible(true);
};
const edit = e => {
setType('edit');
setPickItem(e);
setAddVisible(true);
};
const dele = e => {
setPickItem(e);
setLoading(true);
appService
.DelIntegration({
id: e.id,
})
.then(res => {
if (res.code === 0) {
getData();
message.success('删除成功');
} else {
res.msg && message.error(res.msg);
}
setLoading(false);
});
};
const submitSearch = () => {
setLoading(true);
appService.GetIntegrationConfig({ searchKey: searchWord, isHide: false }).then(res => {
if (res.code === 0) {
setShowSearchStyle(true);
const _allName = [];
res.data.forEach(item => {
_allName.push(item.name);
});
setKeepSystemName(_allName);
setTableData(res.data.sort((a, b) => a.index - b.index));
} else {
res.msg && message.error(res.msg);
}
setLoading(false);
});
};
const handleSearch = e => {
setSearchWord(e.target.value);
};
const onSubmit = () => {
getData();
};
const masterStation = () => {
setType('');
setMasterVisible(true);
};
const onSort = (tType, index) => {
let list = [];
tableData.forEach(t => {
list.push(t.id);
});
if (tType === 'up' && list[index - 1]) {
const temp = list[index];
list[index] = list[index - 1];
list[index - 1] = temp;
}
if (tType === 'down' && list[index + 1]) {
const temp = list[index];
list[index] = list[index + 1];
list[index + 1] = temp;
}
list = list.map((l, lIndex) => ({
id: l,
index: lIndex,
}));
console.log(list, 'list');
SaveIntegrationIndex(list).then(res => {
if (res.code === 0) {
message.success('调整成功');
getData();
} else {
res.msg && message.error(res.msg);
}
});
console.log('🚀 ~ list:', list);
};
const migration = () => {
// 调用迁移接口
message.success('迁移成功,重载配置中,请稍后~');
setMigrationLoading(true);
setTimeout(async () => {
await getData();
setMigrationLoading(false);
}, 300);
};
const handleMenuClick = e => {
add(e.key);
};
useEffect(() => {
getData();
}, []);
return (
<div className={styles.Integrate}>
<div className={styles.head}>
<div className={styles.head1}>
<span>快速搜索:</span>
<Search
style={{ width: 260 }}
placeholder="请输入名称"
onSearch={submitSearch}
onChange={e => handleSearch(e)}
enterButton
value={searchWord}
/>
<Popover
content={
<Space direction="vertical">
{menuItems.map(item => (
<Button
onClick={() => {
handleMenuClick(item);
}}
>
{item.label}
</Button>
))}
</Space>
}
trigger="hover"
>
<Button style={{ marginLeft: 20 }}>
<Space>
新增配置
<DownOutlined />
</Space>
</Button>
</Popover>
<Button style={{ marginLeft: 20 }} type="primary" loading={migrationLoading} onClick={migration}>
一键迁移
</Button>
</div>
<div>
<a target="_blank" style={{ marginRight: '20px' }} href={path.join(__dirname, '/center')}>
快速访问平台
</a>
{/* <Tooltip title="点击查看对接文档">
<a
style={{ display: 'inline-block', marginTop: '5px', marginRight: '20px' }}
target="_blank"
href={path.join(__dirname, pdf)}
rel="noopener noreferer"
>
<FilePdfOutlined style={{ fontSize: '24px' }} />
</a>
</Tooltip> */}
<Button onClick={masterStation}>配置集成网站</Button>
</div>
</div>
<div className={styles.table}>
<Table
loading={loading}
size="small"
bordered
rowKey={record => record.SystemName}
columns={columns}
dataSource={tableData}
scroll={{ y: 'calc(100vh - 200px)', x: 'max-content' }}
pagination={false}
/>
</div>
{addVisible ? (
<AddModal
visible={addVisible}
pickItem={pickItem}
onCancel={() => setAddVisible(false)}
type={type}
targetType={targetType}
callBackSubmit={onSubmit}
groupList={groupList}
destroyOnClose
keepSystemName={keepSystemName}
/>
) : (
''
)}
{masterVisible ? (
<Master visible={masterVisible} onCancel={() => setMasterVisible(false)} type={type} isPanda={isPanda} />
) : (
''
)}
</div>
);
};
export default IntegratedLogin;
.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';
import TabIframe from '../pages/system/iframe/TabWidget';
import JumpThirdLink from '../pages/system/iframe/JumpThirdLink';
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) => {
// eslint-disable-next-line no-shadow
const dyRoutes = routes || [];
......@@ -116,6 +117,9 @@ export const dyRoutes = (routes, layout, theme) => {
if (/system\/notifications/.test(path)) {
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