Commit d7064e43 authored by 张烨's avatar 张烨

feat: web网站配置

parent c6f2ade2
import React, { useEffect } from 'react';
import { Form, Button, Select, Input, Radio } from 'antd';
import { Form, Button, Select, Input, Radio, Checkbox } from 'antd';
import Upload from '@/components/Upload';
import { useForm } from 'antd/lib/form/Form';
......@@ -21,9 +21,10 @@ export const renderButtonGroup = props => {
export const ITEM_TYPE = {
INPUT: 'INPUT',
SELECT: 'SELECT',
IMGSHOP: 'IMGSHOP',
SINGLE_RADIO: 'SINGLE_RADIO',
SELECT: 'SELECT', // 下拉选择
IMGSHOP: 'IMGSHOP', // 图片库
SINGLE_RADIO: 'SINGLE_RADIO', // 单选radio
CHECK_BOX: 'CHECK_BOX', // 多选框
};
const BaseFormItem = itemOption => {
......@@ -51,6 +52,14 @@ const BaseFormItem = itemOption => {
))}
</Radio.Group>
);
case ITEM_TYPE.CHECK_BOX:
return (
<Checkbox.Group {...rest}>
{options.map(o => (
<Checkbox {...o} />
))}
</Checkbox.Group>
);
default:
return null;
}
......
import React from 'react';
import { Button, Col, Drawer, Row } from 'antd';
import styles from './siteConfigDrawer.less';
import BaseForm, { ITEM_TYPE } from '@/components/BaseForm';
let form = null;
const typeContent = hasIntegerate => {
if (hasIntegerate) {
return [];
}
return [
{
value: 'a',
children: '集成网站',
},
];
};
const defaultKeyMap = ({ hasIntegerate }) => ({
title: {
label: '标题',
formType: ITEM_TYPE.INPUT,
allowClear: true,
placeholder: '请输入标题',
rules: [
{
required: true,
message: '标题为必填项',
},
],
},
subtitle: {
label: '副标题',
formType: ITEM_TYPE.INPUT,
allowClear: true,
},
type: {
label: '网站类型',
formType: ITEM_TYPE.SINGLE_RADIO,
initialValue: hasIntegerate ? 'b' : 'a',
options: [
{
value: 'b',
children: '一般网站',
},
].concat(typeContent(hasIntegerate)),
},
shortcutIcon: {
label: '图标icon',
formType: ITEM_TYPE.IMGSHOP,
rules: [
{
required: true,
message: '请选择图标icon',
},
],
},
logo: {
label: '登录logo',
formType: ITEM_TYPE.IMGSHOP,
rules: [
{
required: true,
message: '请选择登录logo',
},
],
},
bannerlogo: {
label: '标题logo',
formType: ITEM_TYPE.IMGSHOP,
rules: [
{
required: true,
message: '请选择标题logo',
},
],
},
client: {
label: '虚拟目录',
formType: ITEM_TYPE.INPUT,
allowClear: true,
size: 'small',
rules: [
{
required: true,
message: '虚拟目录不能为空',
},
],
},
homePage: {
label: '主页',
formType: ITEM_TYPE.INPUT,
allowClear: true,
},
loginTemplate: {
label: '登录模板',
formType: ITEM_TYPE.SELECT,
placeholder: '请选择登录模板',
options: [
{
value: 'a',
children: 'default.html',
},
{
value: 'b',
children: 'dark.html',
},
],
showSearch: true,
filterOption: (input, option) =>
option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0,
rules: [
{
required: true,
message: '登录模板必填',
},
],
},
theme: {
label: '系统皮肤',
formType: ITEM_TYPE.SINGLE_RADIO,
initialValue: 'a',
options: [
{
value: 'a',
children: 'a',
},
{
value: 'b',
children: 'b',
},
],
rules: [
{
required: true,
message: '请选择系统皮肤',
},
],
},
// style: '系统风格',
// menu: '菜单类型',
// mode: '功能标签',
// qrcode: '二维码地址',
// mapPlan: '地图方案',
// waterMark: '地图水印',
});
import { Drawer } from 'antd';
import WebConfigForm from './webConfigForm';
export default props => {
const { visible, onClose, config, hasIntegerate = true } = props;
const { visible, onClose, config, hasIntegerate } = props;
const getForm = f => {
form = f;
};
const itemsMap = defaultKeyMap({ hasIntegerate });
const formConfig = {
getForm,
items: Object.keys(itemsMap).map(k => ({
...itemsMap[k],
dataIndex: k,
})),
buttons: [
{
text: '取消',
type: 'cancel',
onClick: () => {
// eslint-disable-next-line no-unused-expressions
onClose && onClose();
},
},
{
text: '确定',
htmlType: 'submit',
type: 'primary',
style: {
marginLeft: '10px',
},
},
],
buttonsWraper: bts => (
<Row>
<Col span={24} style={{ textAlign: 'right' }}>
{bts}
</Col>
</Row>
),
};
return (
<div className={styles.siteConfigContainer}>
<Drawer
title="添加网站"
width={520}
closable
onClose={onClose}
visible={visible}
maskClosable={false}
>
<BaseForm
{...formConfig}
onFinish={values => {
console.log(values);
}}
/>
</Drawer>
</div>
<Drawer
title={config ? '编辑网站' : '添加网站'}
width={520}
closable
onClose={onClose}
visible={visible}
maskClosable={false}
>
<WebConfigForm
hasIntegerate={hasIntegerate}
config={config}
onCancel={onClose}
onOk={values => {
console.log(values);
}}
/>
</Drawer>
);
};
.siteConfigContainer{
width: 100%;
@minHeight: calc(100vh - 240px);
min-height: @minHeight;
padding: 6px 12px;
.previewBox{
width: 100%;
height: max(@minHeight, 720px);
background: #f5eebb;
}
}
\ No newline at end of file
import BaseForm from '@/components/BaseForm';
import React, { useState } from 'react';
import {
getLoginPage,
getMapCofigs,
getWebThemes,
} from '@/services/webConfig/api';
import { Row, Col } from 'antd';
import { getDefaultGetWebconfig, singleStyleData } from '../utils';
const WebConfigForm = props => {
const { hasIntegerate, config, onCancel, onSubmit, onOk } = props;
const [webThemes, setWebThemes] = useState([]);
const [mapConfigs, setMapConfigs] = useState([]);
const [loginPages, setLoginPages] = useState([]);
const [webType, setWebType] = useState();
const [form, setForm] = useState(null);
const getForm = f => {
setForm(f);
};
const onGetThemes = () => {
if (webThemes.length === 0) {
getWebThemes().then(res => setWebThemes(res));
}
};
const onGetLoginPages = () => {
if (loginPages.length === 0) {
getLoginPage().then(res => setLoginPages(res));
}
};
const onGetMapConfig = () => {
if (mapConfigs.length === 0) {
getMapCofigs().then(res => setMapConfigs(res));
}
};
const itemsMap = getDefaultGetWebconfig({
initialValues: config,
hasIntegerate,
webThemes,
webType,
onGetThemes,
loginPages,
mapConfigs,
onGetLoginPages,
onGetMapConfig,
});
const formConfig = {
getForm,
items: Object.keys(itemsMap).map(k => ({
...itemsMap[k],
dataIndex: k,
})),
buttons: [
{
text: '取消',
type: 'cancel',
size: 'middle',
onClick: () => {
// eslint-disable-next-line no-unused-expressions
onCancel && onCancel();
},
},
{
text: '确定',
htmlType: 'submit',
type: 'primary',
size: 'middle',
style: {
marginLeft: '10px',
},
},
],
buttonsWraper: bts => (
<Row>
<Col span={24} style={{ textAlign: 'right' }}>
{bts}
</Col>
</Row>
),
};
return (
<BaseForm
{...formConfig}
labelCol={{ span: 6 }}
wrapperCol={{ span: 14 }}
onValuesChange={v => {
if (v.type) {
setWebType(v.type);
if (form) {
const sty = form.getFieldValue('style');
if (!singleStyleData[sty]) {
form.setFieldsValue([{ name: 'style', value: 'platform' }]);
}
}
}
}}
onFinish={values => {
// eslint-disable-next-line no-unused-expressions
onSubmit && onSubmit(values);
// eslint-disable-next-line no-unused-expressions
onOk && onOk(values);
}}
/>
);
};
export default WebConfigForm;
import React, { useEffect, useState } from 'react';
import PageContainer from '@/components/BasePageContainer';
import { Tabs } from 'antd';
import { getWebModuleTree } from '@/services/webConfig/api';
import { getWebModuleTree, getWebConfigByName } from '@/services/webConfig/api';
import styles from './index.less';
import SiteConfig from './components/siteConfigDrawer';
import { appConnector } from '@/containers/App/store';
const { TabPane } = Tabs;
const getMenuTree = userMode =>
getWebModuleTree(userMode || 'super').then(res => console.log(res));
const WebConfigPage = props => {
const { userMode } = props;
const [configVisible, setConfigVisible] = useState(false);
const [loading, setLoading] = useState(false);
const [menuTree, setMenuTree] = useState({ children: [] });
const [webs, setWebs] = useState([]);
const [curWeb, setCurWeb] = useState(null); // 当前展示的web配置
const [configObj, setConfigObj] = useState({});
const renderPage = () => {};
const hasIntegerate = () => webs.some(w => w.webType === 'integrate');
useEffect(() => {
getMenuTree(props.userMode).then(res => {
setMenuTree(res);
getWebModuleTree(userMode || 'super').then(res => {
const websArr = [
res.data
.filter(d => d.id === 'Web4IntegrateStation')
.map(r => r.children.map(i => ({ ...i, webType: 'integrate' }))),
res.data
.filter(d => d.id === 'Web4SingleStation')
.map(r => r.children.map(i => ({ ...i, webType: 'single' }))),
].flat(2);
setWebs(websArr);
setCurWeb(websArr[0]);
setLoading(false);
});
}, []);
const renderTabPane = tabPaneItem => (
<TabPane key={tabPaneItem.id} tab={tabPaneItem.text} />
<TabPane key={tabPaneItem.text} tab={tabPaneItem.text}>
<></>
</TabPane>
);
const onEdit = (targetKey, action) => {
......@@ -44,17 +55,21 @@ const WebConfigPage = props => {
setConfigVisible(false);
};
const handleTabChange = v => {
setCurWeb(webs.find(w => w.text === v));
};
return (
<PageContainer loading={loading}>
<div className={styles.webConfigContainer}>
<Tabs type="editable-card" onEdit={onEdit}>
{menuTree?.children?.map(renderTabPane)}
<Tabs type="editable-card" onEdit={onEdit} onChange={handleTabChange}>
{webs.map(renderTabPane)}
</Tabs>
<SiteConfig
visible={configVisible}
onClose={onDrawerClose}
config={configObj}
hasIntegerate={false}
hasIntegerate={hasIntegerate()}
/>
</div>
</PageContainer>
......
import { ITEM_TYPE } from '@/components/BaseForm';
const typeContent = hasIntegerate => {
if (hasIntegerate) {
return [];
}
return [
{
value: 'a',
children: '集成网站',
},
];
};
export const integrateStyleData = {
platform: '工作台',
webgis: 'WEBGIS',
ios: 'IOS',
catalog: 'Catalog',
virtualcity: 'VirtualCity',
};
export const singleStyleData = {
platform: '工作台',
webgis: 'WEBGIS',
};
export const menuStyle = {
'banner-left': '标题栏-左',
banner: '标题栏',
'banner-big': '标题栏-大',
table: '左侧',
dock: '底部',
};
export const MDILabel = {
MDI: '多标签模式',
SDI: '单标签模式',
};
export const notificationTypes = {
notify: '轮询通知',
MQTT: 'MQTT消息',
};
const isIntegerate = (webType, hasIntegerate) => {
if (typeof webType !== 'undefined') {
return webType === 'a';
}
return hasIntegerate;
};
export const getDefaultGetWebconfig = ({
initialValues = {},
hasIntegerate,
webThemes,
onGetThemes,
webType,
loginPages,
onGetLoginPages,
mapConfigs,
onGetMapConfig,
}) => {
const config = {
title: {
label: '标题',
formType: ITEM_TYPE.INPUT,
allowClear: true,
placeholder: '请输入标题',
rules: [
{
required: true,
message: '标题为必填项',
},
],
},
subtitle: {
label: '副标题',
formType: ITEM_TYPE.INPUT,
allowClear: true,
},
type: {
label: '网站类型',
formType: ITEM_TYPE.SINGLE_RADIO,
initialValue: 'b',
options: [
{
value: 'b',
children: '一般网站',
},
].concat(typeContent(hasIntegerate)),
},
shortcutIcon: {
label: '系统icon',
formType: ITEM_TYPE.IMGSHOP,
rules: [
{
required: true,
message: '请选择图标icon',
},
],
},
logo: {
label: '登录logo',
formType: ITEM_TYPE.IMGSHOP,
rules: [
{
required: true,
message: '请选择登录logo',
},
],
},
bannerlogo: {
label: '标题logo',
formType: ITEM_TYPE.IMGSHOP,
rules: [
{
required: true,
message: '请选择标题logo',
},
],
},
client: {
label: '虚拟目录',
formType: ITEM_TYPE.INPUT,
allowClear: true,
size: 'small',
rules: [
{
required: true,
message: '虚拟目录不能为空',
},
],
},
homePage: {
label: '主页',
formType: ITEM_TYPE.INPUT,
allowClear: true,
},
loginTemplate: {
label: '登录模板',
formType: ITEM_TYPE.SELECT,
placeholder: '请选择登录模板',
options: loginPages.map(t => ({
value: t.value,
children: t.text,
key: t.value,
})),
onDropdownVisibleChange: onGetLoginPages,
showSearch: true,
filterOption: (input, option) =>
option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0,
rules: [
{
required: true,
message: '登录模板必填',
},
],
},
theme: {
label: '系统皮肤',
formType: ITEM_TYPE.SINGLE_RADIO,
initialValue: '',
options: webThemes.map(t => ({
value: t.value,
children: t.text,
key: t.value,
})),
onDropdownVisibleChange: onGetThemes,
},
style: {
label: '系统风格',
formType: ITEM_TYPE.SELECT,
initialValue: '',
options: Object.keys(
isIntegerate(webType, hasIntegerate)
? integrateStyleData
: singleStyleData,
).map(k => ({
value: k,
key: k,
children: integrateStyleData[k] || singleStyleData[k],
})),
},
menu: {
label: '菜单类型',
formType: ITEM_TYPE.SINGLE_RADIO,
options: Object.keys(menuStyle).map(k => ({
value: k,
key: k,
children: menuStyle[k],
})),
},
mdi: {
label: '功能标签',
formType: ITEM_TYPE.SINGLE_RADIO,
options: Object.keys(MDILabel).map(k => ({
value: k,
key: k,
children: MDILabel[k],
})),
},
qrcode: {
label: '二维码地址',
formType: ITEM_TYPE.INPUT,
allowClear: true,
},
alarmWays: {
label: '通知方式',
formType: ITEM_TYPE.CHECK_BOX,
options: Object.keys(notificationTypes).map(k => ({
value: k,
key: k,
children: notificationTypes[k],
})),
},
mapPlan: {
label: '地图方案',
formType: ITEM_TYPE.SELECT,
options: mapConfigs.map(m => ({
value: m.value,
children: m.text,
key: m.value,
})),
onDropdownVisibleChange: onGetMapConfig,
},
hideMap: {
label: '按需加载地图',
formType: ITEM_TYPE.SINGLE_RADIO,
options: [
{
value: true,
key: '1',
children: '是',
},
{
value: false,
key: '2',
children: '否',
},
],
},
waterMark: {
label: '地图水印',
formType: ITEM_TYPE.SINGLE_RADIO,
options: [
{
value: true,
key: '1',
children: '显示',
},
{
value: false,
key: '2',
children: '不显示',
},
],
},
};
Object.keys(config).forEach(k => {
if (initialValues[k]) {
config[k].initialValue = initialValues[k];
}
});
return config;
};
import qs from 'qs';
import { get, PUBLISH_SERVICE } from '../index';
import { CITY_SERVICE, get, PUBLISH_SERVICE } from '../index';
export const getWebModuleTree = userMode =>
get(
......@@ -7,3 +7,18 @@ export const getWebModuleTree = userMode =>
userMode,
})}`,
);
export const getWebConfigByName = webName =>
get(`${CITY_SERVICE}/OMS.svc/W4_GetWebsite`, { title: webName });
export const getWebThemes = () =>
get(`${CITY_SERVICE}/OMS.svc/W4_GetThemes`, { query: '' });
export const getLoginPage = () =>
get(`${CITY_SERVICE}/OMS.svc/W4_GetLoginPage`, { query: '' });
export const getMapCofigs = () =>
get(
`${CITY_SERVICE}/OMS.svc/GetAllConfigText?terminalType=scheme&isBaseMap=false`,
{ query: '' },
);
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