Commit 9c8a6218 authored by wuhao's avatar wuhao 🎯

asder

parent 9ea567e7
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
] ]
}, },
"dependencies": { "dependencies": {
"@ant-design/pro-components": "^2.3.30",
"@ant-design/pro-layout": "^6.5.0", "@ant-design/pro-layout": "^6.5.0",
"ahooks": "^3.7.2", "ahooks": "^3.7.2",
"color-thief-react": "^2.1.0", "color-thief-react": "^2.1.0",
...@@ -28,7 +29,9 @@ ...@@ -28,7 +29,9 @@
"express-http-proxy": "^1.6.3", "express-http-proxy": "^1.6.3",
"react": "17.x", "react": "17.x",
"react-amap": "^1.2.8", "react-amap": "^1.2.8",
"react-custom-scrollbars": "^4.2.1",
"react-dom": "17.x", "react-dom": "17.x",
"react-resizable": "^3.0.4",
"umi": "^3.5.35", "umi": "^3.5.35",
"umi-request": "^1.4.0" "umi-request": "^1.4.0"
}, },
......
import React, { Component } from 'react';
import { Resizable } from 'react-resizable';
function Resizecell({ onResize, onResizeStop, width, onClick, ...restProps }) {
return (
<Resizable
width={width ?? 1}
height={0}
onResize={onResize}
onResizeStop={onResizeStop}
>
<th {...restProps} />
</Resizable>
);
}
export default Resizecell;
/* eslint-disable react-hooks/exhaustive-deps */
/* eslint-disable react-hooks/rules-of-hooks */
import React, { useEffect, useRef, useState, memo, useMemo } from 'react';
import { ProTable } from '@ant-design/pro-components';
import Resizecell from './Resizecell';
import { Tooltip } from 'antd';
import { doFetch } from '@/utils/doFetch';
import { useAsyncEffect } from 'ahooks';
let handlEmptyChild = (tree = []) => {
const newtree = tree.map((item) => {
if (!item.children || item.children.length == 0) {
item.value = item.key;
return item;
} else {
item.value = item.key;
return {
...item,
children: handlEmptyChild(item.children),
};
}
});
return newtree;
};
const Mtable = (props) => {
const {
actionRef, //表格动作
formRef, //表单Ref
rowKey, // key
columns = [], //columns
style, //style
path, //接口地址
extraparams, //额外参数
pageSize, //修改默认pageSize
pagination, //分页设置
x, //横向滚动
activeTabKey, //激活的tabKey 拖拽表格唯一标识使用 其他情况用不到
refreshDep, //依赖刷新 (已废弃)
getDefaultSelected, //存在默认选中向上返回选中值
resizeable = true,
} = props;
const actionRefs = actionRef ?? useRef(),
formRefs = formRef ?? useRef(),
ifspagination = pagination == 'false' || pagination === false,
[size, setsize] = useState('large'),
[valueColumns, setvalueColumns] = useState({});
const [columnes, setcolumnes] = useState(columns ?? []);
//调用接口
const request = async (params, sort, filter) => {
if (!path) return;
let newparams = {
...params,
...extraparams, //父组件传参
pageIndex: params.current,
pageSize: params.pageSize || pageSize,
};
delete newparams.current;
if (ifspagination) {
delete newparams.pageIndex;
delete newparams.pageSize;
}
const result = await doFetch({ url: path, params: newparams });
//分页结果
let data = result?.data?.page?.records,
success = true,
total = result?.data?.page?.total;
//不带分页获取结果
if (ifspagination) {
data = result?.data?.dataList;
total = result?.data?.dataList?.length;
}
//存在默认选中向上返回选中值
getDefaultSelected && getDefaultSelected(result?.data);
return {
data,
success,
total,
};
};
//更新 columns
useEffect(() => {
setcolumnes((s) => {
return columns.map((item, index) => {
let it = { ...item };
let itemwidth = valueColumns[it.key]?.width
? valueColumns[it.key].width
: it.width
? it.width
: resizeable
? 160
: 'auto';
let options = {};
if (
it.valueType == 'select' ||
it.valueType == 'checkbox' ||
it.valueType == 'treeSelect'
) {
if (Array.isArray(it.options)) {
options = {
fieldProps: {
options: [...it.options],
},
};
} else if (it.options) {
options = {
request: async (params) => {
let list = await doFetch({
url: it?.options?.path,
params: it?.options?.params,
});
const res = list.data.dataList;
return it.valueType == 'treeSelect'
? handlEmptyChild(res)
: res;
},
};
}
}
if (it.valueType == 'option') {
options = {
key: 'option',
dataIndex: 'option',
fixed: 'right',
};
}
if (!it.render) {
options = {
...options,
render: (text, row) => {
return (
<Tooltip title={row[it.dataIndex]} placement="topLeft">
<span className="table-cell">{row[it.dataIndex] ?? '-'}</span>
</Tooltip>
);
},
};
}
options = {
...options,
width: itemwidth,
};
delete it.formItemProps;
return {
...it,
...options,
onHeaderCell: (column) => ({
width: column.width ?? itemwidth,
onResize: handleResize(index),
onResizeStop: handleResizeStop(index),
}),
};
});
});
}, [valueColumns]);
let columncs = useMemo(() => {
if (resizeable) return;
return columns.map((item, index) => {
let it = { ...item };
let itemwidth = it.width ? it.width : resizeable ? 160 : 'auto';
let options = {};
if (
it.valueType == 'select' ||
it.valueType == 'checkbox' ||
it.valueType == 'treeSelect'
) {
if (Array.isArray(it.options)) {
options = {
fieldProps: {
options: [...it.options],
},
};
} else if (it.options) {
options = {
request: async (params) => {
let list = await doFetch({
url: it?.options?.path,
params: it?.options?.params,
});
const res = list.data.dataList;
return it.valueType == 'treeSelect' ? handlEmptyChild(res) : res;
},
};
}
}
if (it.valueType == 'option') {
options = {
key: 'option',
dataIndex: 'option',
fixed: 'right',
};
}
if (!it.render) {
options = {
...options,
render: (text, row) => {
return (
<Tooltip title={row[it.dataIndex]} placement="topLeft">
<span className="table-cell">{row[it.dataIndex] ?? '-'}</span>
</Tooltip>
);
},
};
}
options = {
...options,
width: itemwidth,
};
delete it.formItemProps;
return {
...it,
...options,
};
});
}, [columns]);
//初始化操作数据
const initDrage = async () => {
if (!path) return;
let res = await doFetch({
url: '/ngic-base-business/paFieldScene/queryContro',
params: {
sceneMark: activeTabKey ? path + activeTabKey : path,
},
});
if (res.code == '0000') {
//datalist:接口返回状态
let datalist = {};
res?.data?.dataList &&
res.data.dataList.map((it) => {
const { fieldKey, fieldWidth, fieldOrder, fieldFixed, fieldShow } =
it ?? {};
datalist[fieldKey] = {
width: fieldWidth,
order: fieldOrder,
fixed:
fieldKey == 'option' || fieldKey == 'option_dataindex'
? 'right'
: fieldFixed,
show: fieldShow,
};
});
//allcol 默认状态设置 valueColumns 为columns全列设置
let allcol = {};
columns.map((it, i) => {
if (it.valueType == 'option') {
allcol.option = {
order: columns.length - 1,
show: true,
fixed: 'right',
...datalist.option,
};
} else {
allcol[it.key] = {
order: i,
show: true,
...datalist[it.key],
};
}
});
setvalueColumns(allcol);
}
actionRefs?.current?.reload();
actionRefs?.current?.reset();
};
//调用重新渲染表格
useAsyncEffect(async () => {
if (resizeable) {
await initDrage();
}
}, [columns, extraparams, path, activeTabKey, refreshDep]);
//缩放表格
const handleResize =
(index) =>
(e, { size }) => {
e.stopImmediatePropagation();
setcolumnes((s) => {
const nextColumns = [...s];
nextColumns[index] = {
...nextColumns[index],
width: size.width,
};
return nextColumns;
});
};
//更新表格缩放
const handleResizeStop =
(index) =>
(e, { size }) => {
e.stopImmediatePropagation();
let submitdata = { ...valueColumns } ?? {},
curkey = Object.keys(submitdata)[index];
submitdata[curkey].width = parseInt(size.width);
setvalueColumns(submitdata);
doFetch({
url: '/ngic-base-business/paFieldScene/save',
params: {
sceneMark: activeTabKey ? path + activeTabKey : path,
controList: Object.keys(submitdata).map((it, i) => {
return {
fieldKey: it,
fieldWidth:
i == index ? parseInt(size.width) : submitdata[it].width,
fieldOrder: submitdata[it].order,
fieldFixed: submitdata[it].fixed,
fieldShow: submitdata[it].show,
};
}),
},
});
};
const components = resizeable
? {
components: {
header: {
cell: Resizecell,
},
},
columnsState: {
value: valueColumns,
onChange: (val, state) => {
setvalueColumns((s) => {
let submitdata = {
...s,
...val,
};
doFetch({
url: '/ngic-base-business/paFieldScene/save',
params: {
sceneMark: activeTabKey ? path + activeTabKey : path,
controList: Object.keys(submitdata).map((it) => {
return {
fieldKey: it,
fieldWidth: submitdata[it].width,
fieldOrder: submitdata[it].order,
fieldFixed: submitdata[it].fixed,
fieldShow: submitdata[it].show,
};
}),
},
});
return submitdata;
});
},
},
}
: {};
return (
<ProTable
{...props}
{...components}
size={size}
onSubmit={(params) => {
console.log(params, 'onSubmit');
}}
onSizeChange={(size) => {
localStorage.setItem('size', size); //设置全局表格规格缓存
setsize(size);
}}
columns={
resizeable
? columnes?.filter?.((it) => it.valueType != 'split') ?? []
: columncs?.filter?.((it) => it.valueType != 'split') ?? []
}
style={style || {}}
actionRef={actionRefs}
formRef={formRefs}
rowKey={rowKey ?? 'id'} //表格每行数据的key
dateFormatter="string"
request={request}
scroll={
x
? {
x: x,
}
: {}
}
pagination={
ifspagination
? false
: {
showTotal: (total, range) => <span>{total}</span>,
showQuickJumper: true,
showSizeChanger: true,
pageSizeOptions: [5, 10, 15, 30, 50, 100, 200],
defaultPageSize: pageSize || 15,
}
}
search={{
filterType: 'light', //轻量模式
}}
/>
);
};
export default memo(Mtable);
...@@ -912,7 +912,60 @@ body, ...@@ -912,7 +912,60 @@ body,
} }
.diyinput { .diyinput {
input { font-size: 2rem;
background-color: rgba(255, 255, 255, 0.5) !important; text-align: center;
color: #ffffff;
position: relative;
&::before {
content: '';
width: 2vw;
height: 2vw;
position: absolute;
top: -1vw;
left: -2vw;
border: 0.5vw solid #ffffff;
border-right: none;
border-bottom: none;
}
&::after {
content: '';
width: 2vw;
height: 2vw;
position: absolute;
bottom: -1vw;
right: -2vw;
border: 0.5vw solid #ffffff;
border-left: none;
border-top: none;
}
}
// protable 默认样式覆盖
.ant-pro-table .ant-pro-table-search,
.ant-pro-card-body {
margin: 0 !important;
padding: 0 !important;
}
.ant-pro-table-list-toolbar-container {
padding-top: 0 !important;
padding-bottom: 24px !important;
}
.ant-pro-table-list-toolbar-right {
flex: 1 !important;
flex-direction: row !important;
align-items: center !important;
justify-content: space-between !important;
}
.ant-pro-card-body {
padding-top: 0.8rem !important;
* {
font-size: 0.8rem !important;
}
.anticon-download {
* {
font-size: 1rem !important;
}
} }
} }
import React, { useState } from 'react'; import React, { useState } from 'react';
import { Col, Row } from 'antd'; import { Col, Row } from 'antd';
import { history } from 'umi';
const ContentList = (props) => { const ContentList = ({ title, listData }) => {
const { title, listData } = props;
return ( return (
<div className="footer-content"> <div className="footer-content">
<h2>{title}</h2> <h2>{title}</h2>
<div> <div>
{listData.map((item, index) => ( {listData.map((item, index) => (
<li> <li
<a href={item.link}>{item.text}</a> onClick={() => {
history.replace({
pathname: item.link,
query: item?.query ?? {},
});
}}
>
<a>{item.text}</a>
</li> </li>
))} ))}
</div> </div>
...@@ -20,65 +27,74 @@ const ContentList = (props) => { ...@@ -20,65 +27,74 @@ const ContentList = (props) => {
export default () => { export default () => {
const list1 = [ const list1 = [
{ {
link: '#', link: '/about/insert',
text: '走进南高', text: '走进南高',
}, },
{ {
link: '#', link: '/about/honer',
text: '南高荣誉', text: '南高荣誉',
}, },
{ {
link: '#', link: '/about/news',
text: '南高资讯', text: '南高资讯',
}, },
{ {
link: '#', link: '/about/join',
text: '加入南高', text: '加入南高',
}, },
]; ];
const list2 = [ const list2 = [
{ {
link: '#', link: '/factory/typea/mes',
text: 'MES智能制造管理系统', text: 'MES智能制造管理系统',
}, },
{ {
link: '#', link: '/factory/typea/wms',
text: 'WMS智能仓储管理系统', text: 'WMS智能仓储管理系统',
}, },
{ {
link: '#', link: '/factory/typea/ems',
text: 'EMS设备运维管理系统', text: 'EMS设备运维管理系统',
}, },
{ {
link: '#', link: '/factory/typea/iot',
text: 'IOT数据采集系统', text: 'IOT数据采集系统',
}, },
{ {
link: '#', link: '/factory/typea/plm',
text: 'PLM产品生命周期管理系统', text: 'PLM产品生命周期管理系统',
}, },
{ {
link: '#', link: '/factory/typea/pdm',
text: 'PDM产品数据管理系统', text: 'PDM产品数据管理系统',
}, },
{ {
link: '#', link: '/factory/typeb/datagate',
text: '智能网关', text: '智能网关',
}, },
]; ];
const list3 = [ const list3 = [
{ {
link: '#', link: '/download',
query: {
key: '1',
},
text: '硬件产品资料', text: '硬件产品资料',
}, },
{ {
link: '#', link: '/download',
query: {
key: '2',
},
text: '软件产品资料', text: '软件产品资料',
}, },
{ {
link: '#', link: '/download',
query: {
key: '3',
},
text: '宣传画册及其他', text: '宣传画册及其他',
}, },
]; ];
...@@ -97,7 +113,13 @@ export default () => { ...@@ -97,7 +113,13 @@ export default () => {
</Col> </Col>
<Col xs={24} sm={24} xl={24} xxl={6}> <Col xs={24} sm={24} xl={24} xxl={6}>
<div className="footer-content"> <div className="footer-content">
<button>联系我们</button> <button
onClick={() => {
history.push('/about/contact');
}}
>
联系我们
</button>
<div className="contact"> <div className="contact">
<li>电话&nbsp;&nbsp;&nbsp;&nbsp;025-86111901</li> <li>电话&nbsp;&nbsp;&nbsp;&nbsp;025-86111901</li>
<li>邮箱&nbsp;&nbsp;&nbsp;&nbsp;center@jsnangao.com</li> <li>邮箱&nbsp;&nbsp;&nbsp;&nbsp;center@jsnangao.com</li>
......
import React, { useState, useEffect, useMemo } from 'react'; import React, { useState, useRef, useMemo, useEffect } from 'react';
import styles from './index.less'; import styles from './index.less';
import { Menu, Grid, Drawer, Tooltip } from 'antd'; import { Menu, Grid, Drawer, Tooltip, Row, Col } from 'antd';
import { history, Helmet } from 'umi'; import { history, Helmet } from 'umi';
import routes from '../../routes'; import routes from '../../routes';
import { MenuOutlined, PlayCircleFilled } from '@ant-design/icons'; import {
MenuOutlined,
PlayCircleFilled,
PhoneFilled,
WechatFilled,
} from '@ant-design/icons';
import { Scrollbars } from 'react-custom-scrollbars';
import Footer from './footer'; import Footer from './footer';
const { useBreakpoint } = Grid; const { useBreakpoint } = Grid;
const colc = { xs: 24, sm: 24, md: 12, lg: 12, xl: 12, xxl: 12 },
col = { xs: 24, sm: 24, md: 10, lg: 10, xl: 10, xxl: 10 },
cold = { xs: 24, sm: 24, md: 8, lg: 8, xl: 8, xxl: 8 },
colds = { xs: 24, sm: 24, md: 12, lg: 8, xl: 8, xxl: 8 },
cols = { xs: 24, sm: 24, md: 14, lg: 14, xl: 14, xxl: 14 };
const mapTree = (org) => { const mapTree = (org) => {
const haveChildren = Array.isArray(org.routes) && org.routes.length > 0; const haveChildren = Array.isArray(org.routes) && org.routes.length > 0;
if (!org.name || org.hideInMenu) return; if (!org.name || org.hideInMenu) return;
...@@ -38,6 +52,7 @@ const MenuRender = ({ arrs, mode, activeKey }) => { ...@@ -38,6 +52,7 @@ const MenuRender = ({ arrs, mode, activeKey }) => {
function Layout({ children, location }) { function Layout({ children, location }) {
const [collspan, setcollspan] = useState(false); const [collspan, setcollspan] = useState(false);
const scrollRef = useRef();
const screens = useBreakpoint(); const screens = useBreakpoint();
const arrs = useMemo(() => { const arrs = useMemo(() => {
let arr = []; let arr = [];
...@@ -49,6 +64,14 @@ function Layout({ children, location }) { ...@@ -49,6 +64,14 @@ function Layout({ children, location }) {
return arr; return arr;
}, []); }, []);
useEffect(() => {
scrollRef.current.view.scroll({
top: 0,
left: 0,
behavior: 'smooth',
});
}, [location.pathname]);
return ( return (
<div className={styles.container}> <div className={styles.container}>
<Helmet encodeSpecialCharacters={false}> <Helmet encodeSpecialCharacters={false}>
...@@ -121,8 +144,31 @@ function Layout({ children, location }) { ...@@ -121,8 +144,31 @@ function Layout({ children, location }) {
)} )}
</div> </div>
</header> </header>
<div className="content">{children}</div> <Scrollbars
<Footer></Footer> thumbMinSize={10}
autoHide
style={{
width: '100%',
height: 'calc(100vh - 80px)',
overflowX: 'hidden',
}}
hideTracksWhenNotNeeded={true}
ref={scrollRef}
>
<div className="content">{children}</div>
<div className={styles.navbar}>
<Row>
<Col {...cold}>
<PhoneFilled />
</Col>
<Col {...cold}>
<WechatFilled />
</Col>
<Col {...cold}></Col>
</Row>
</div>
<Footer></Footer>
</Scrollbars>
</div> </div>
); );
} }
......
.container { .container {
height: 100%; height: 100%;
overflow: hidden;
li { li {
span { span {
text-align: center !important; text-align: center !important;
......
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { Input, Space, Tabs } from 'antd'; import { Input, Space, Tabs } from 'antd';
import AutoTable from '@/components/AutoTable';
import { DownloadOutlined } from '@ant-design/icons';
import { history } from 'umi';
const { Search } = Input; function Tables({ extraparams }) {
function Download() { return (
const onSearch = (value) => { <AutoTable
console.log(value); path="/fileCenter/getFileCenterPage"
}; extraparams={{ ...extraparams }}
resizeable={false}
columns={[
{
title: '文件名称',
dataIndex: 'fileName',
key: 'fileName',
},
{
title: '文件分类',
dataIndex: 'typeName',
key: 'typeName',
search: false,
},
{
title: '语言',
dataIndex: 'languageName',
key: 'languageName',
search: false,
},
{
title: '下载',
dataIndex: 'fileList',
key: 'fileList',
search: false,
render: (dom, row) => {
return (
<a href={row?.fileList[0]?.url} download={row?.fileList[0]?.name}>
<DownloadOutlined style={{ fontSize: '0.8rem' }} />
</a>
);
},
},
]}
/>
);
}
function Download({ location: { query } }) {
const [fileType, setfileType] = useState(query.key);
const items = [ const items = [
{ label: '宣传画册及其他', key: '1', children: 'Content 1' }, // remember to pass the key prop {
{ label: '硬件产品资料', key: '2', children: 'Content 2' }, label: '硬件产品资料',
{ label: '软件产品资料', key: '3', children: 'Content 2' }, key: '1',
children: (
<Tables
extraparams={{
fileType,
}}
/>
),
},
{
label: '软件产品资料',
key: '2',
children: (
<Tables
extraparams={{
fileType,
}}
/>
),
},
{
label: '宣传画册及其他',
key: '3',
children: (
<Tables
extraparams={{
fileType,
}}
/>
),
},
]; ];
useEffect(() => {
setfileType(query.key);
}, [query]);
return ( return (
<div id="mesContainer"> <div id="mesContainer">
<div style={{ position: 'relative' }}> <div style={{ position: 'relative' }}>
...@@ -31,21 +107,27 @@ function Download() { ...@@ -31,21 +107,27 @@ function Download() {
bottom: 0, bottom: 0,
margin: 'auto', margin: 'auto',
width: '20vw', width: '20vw',
height: 42, height: '3rem',
minWidth: 320, minWidth: 320,
}} }}
> >
<Search 下载中心
placeholder="输入关键词搜索"
onSearch={onSearch}
enterButton
size="large"
style={{ borderRadius: 6, overflow: 'hidden' }}
/>
</div> </div>
</div> </div>
<div className="section"> <div className="section">
<Tabs items={items} /> <Tabs
activeKey={fileType}
onChange={(val) => {
history.push({
pathname: '/download',
query: {
key: val,
},
});
setfileType(val);
}}
items={items}
/>
</div> </div>
</div> </div>
); );
......
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