四好公路
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

680 lines
26 KiB

import { connect } from 'react-redux';
import './protable.less'
import { Card, Button, DatePicker, Input, Modal, Spin, Image, message, Popover, Tree, Tooltip } from 'antd';
import { DownOutlined, RightOutlined, CaretDownOutlined, CaretRightOutlined } from '@ant-design/icons';
import ProTable from '@ant-design/pro-table';
import { getReportList, getReportDetail } from '../actions/patrol';
import React, { useEffect, useState, useMemo } from 'react';
import { httpDel } from '@peace/utils'
import { PinyinHelper } from '@peace/utils';
// @ts-ignore
import styles from './protable.less';
import moment from 'moment';
import { getAllDepUsers } from '../actions/allDepUsers'
import { getDepMessage, getDepUser, createUser, updateUser, delUser, resetPwd, createDep, delDep, updateDep } from '../../organization/actions/user'
import { reportTypeText } from './patrolTable'
const DetailForm = (props) => {
const { visible, data, handleClose, loading } = props;
const [qndmn] = useState(localStorage.getItem('qndmn'));
const keyList = [
{ key: '道路类型', name: 'reportType' },
{ key: '其他', name: 'projectType' },
{ key: '路线代码', name: 'codeRoad' },
{ key: '路线名称', name: 'road' },
{ key: '养护路段', name: 'roadSectionStart' },
{ key: '具体位置', name: 'address' },
{ key: '路面类型', name: 'roadType' },
{ key: '路面宽度', name: 'roadWidth' },
{ key: '错车道', name: 'wrongLane' },
{ key: '行道树', name: 'roadsideTrees' },
{ key: '边沟', name: 'roadsideDitch' },
{ key: '护栏', name: 'guardrail' },
{ key: '标线', name: 'roadMarking' },
{ key: '养护人员人数', name: 'maintenanceStaffCount' },
{ key: '修整路肩', name: 'shoulderRepair' },
{ key: '清理边沟', name: 'ditchCleaning' },
{ key: '修补沥青路面', name: 'asphaltRepair' },
{ key: '修补水泥路面', name: 'concreteRepair' },
{ key: '除草', name: 'grassMowing' },
{ key: '树刷白', name: 'treeWhitening' },
{ key: '桩刷白', name: 'pileWhitening' },
{ key: '维护护栏', name: 'guardrailMaintenance' },
{ key: '修复端头', name: 'endHeadRepair' },
{ key: '其他养护内容', name: 'otherDescription' },
{ key: '养护前图片', name: 'conserveBeforePic' },
{ key: '养护后图片', name: 'conserveAfterPic' },
{ key: '上报视频', name: 'videoUrl' },
];
const keyListOld = [
// { key: '编号', name: 'id' },
{ key: '工程类型', name: 'projectType' },
{ key: '所在路段', name: 'road' },
{ key: '具体位置', name: 'address' },
{ key: '巡查内容', name: 'content' },
{ key: '路线代码', name: 'codeRoad' },
// { key: '病害照片', name: 'scenePic' },
{ key: '养护前', name: 'conserveBeforePic' },
{ key: '养护中', name: 'conserveUnderwayPic' },
{ key: '养护后', name: 'conserveAfterPic' },
];
const renderContent = (data) => {
if (data) {
if (new Date(data.time) > new Date('2023-08-01')) {
return keyList.map(obj => {
return <div style={{ display: 'flex', width: '100%', justifyContent: 'space-between', margin: '12px 0' }}>
<span style={{ fontSize: 16, color: 'gray', minWidth: '26%' }}>{obj.key}</span>
{
obj.name != 'conserveBeforePic' && obj.name != 'conserveAfterPic' && obj.name != 'roadSectionStart' && obj.name != 'videoUrl' && obj.name.indexOf('conserve') == -1 ?
<Input
style={{ width: '70%' }}
value={
obj.name == 'id' ?
moment(data.time).format("YYYYMMDD") * 10000 + data.id
:
obj.name === 'projectType' ?
reportTypeText(data[obj.name])
: obj.name === 'reportType' ? data['codeRoad'] && data['codeRoad'].length ? data['codeRoad'][0] === 'X' ? '县道'
: data['codeRoad'][0] === 'Y' ? '乡道' : '村道' : '' :
data[obj.name]
}
disabled
/>
: obj.name != 'roadSectionStart' && obj.name != 'videoUrl' ?
<div style={{ width: '70%', display: 'flex', position: 'relative', flexWrap: 'wrap' }}>
{
data[obj.name] && data[obj.name] instanceof Array ? data[obj.name].map(imgSrc => {
return <div style={{ width: '44%', margin: 6 }}>
<Image src={qndmn + '/' + imgSrc} width={'100%'} style={{ marginBottom: 4 }} />
</div>
}) : '暂无图片'
}
</div> : obj.name != 'videoUrl' ? <div style={{ width: '70%', display: 'flex', position: 'relative', flexWrap: 'wrap' }}>
<Input style={{ width: '100%' }} disabled value={data[obj.name] + '-' + data['roadSectionEnd']} />
</div> : <div style={{ width: '70%', display: 'flex', position: 'relative', flexWrap: 'wrap' }}>
{
data[obj.name] && data[obj.name] instanceof Array ? data[obj.name].map(videoUrl => {
return <div style={{ width: '44%', margin: 6 }}>
<video src={qndmn + '/' + videoUrl} width={'100%'} style={{ marginBottom: 4 }} controls />
</div>
}) : '暂无视频'
}
</div>
}
</div>
})
} else {
return keyListOld.map(obj => {
return <div style={{ display: 'flex', width: '100%', justifyContent: 'space-between', margin: '12px 0' }}>
<span style={{ fontSize: 16, color: 'gray', minWidth: '26%' }}>{obj.key}</span>
{
obj.name != 'scenePic' && obj.name.indexOf('conserve') == -1 ?
<Input
style={{ width: '70%' }}
value={
obj.name == 'id' ?
moment(data.time).format("YYYYMMDD") * 10000 + data.id
:
obj.name == 'projectType' ?
reportTypeText(data[obj.name]) :
data[obj.name]
}
disabled
/>
:
<div style={{ width: '70%', display: 'flex', position: 'relative', flexWrap: 'wrap' }}>
{
data[obj.name] && data[obj.name] instanceof Array ? data[obj.name].map(imgSrc => {
return <div style={{ width: '44%', margin: 6 }}>
<Image src={qndmn + '/' + imgSrc} width={'100%'} style={{ marginBottom: 4 }} />
</div>
}) : '暂无图片'
}
</div>
}
</div>
})
}
} else {
return '暂无数据'
}
}
return (
<Modal
visible={visible}
footer={null}
onCancel={handleClose}
title={'养护管理详情'}
>
<Spin spinning={loading}>
{renderContent(data)}
</Spin>
</Modal>
)
}
const DetailList = (props) => {
const { reportList, loading, dispatch, handleOpen, handelRefresh, user } = props;
const [visible, setVisible] = useState(false)
const [selectRecord, setSelectRecord] = useState()
const [editAble, setEditAble] = useState(user?.username !== 'SuperAdmin' && user?.userResources?.filter(i => i.resourceId === 'CONSERVATIONMANAGE')[0].isshow === "true" ? true : '')
const checkDetail = (record) => {
dispatch(getReportDetail(record.id))
}
const handleRemove = (record) => {
let url = 'report/{reportId}';
const actionType = "DEL_REPORT_RECORD";
const msg = {}
if (record) {
url = url.replace('{reportId}', record.id)
httpDel(dispatch, { url, actionType, msg }).then(res => {
if (res.success) {
message.success("记录删除成功")
handelRefresh();
} else {
message.error("记录删除失败")
}
})
}
}
let basicDate = null;
let counter = 0;
const columns = [
// {
// title: '编号',
// key: 'id',
// dataIndex: 'id',
// align: 'center',
// render: (text, record) => {
// let day = moment(record.time).format("YYYYMMDD")
// if (!basicDate) {
// basicDate = day;
// counter += 1;
// } else if (basicDate == day) {
// counter += 1;
// } else if (basicDate != day) {
// basicDate = day;
// counter = 1;
// }
// return moment(record.time).format("YYYYMMDD") * 10000 + counter;
// }
// },
{
title: '工程类型',
key: 'projectType',
dataIndex: 'projectType',
align: 'center',
render: (text, record) => {
return record.projectType.length > 0 ? reportTypeText(text) : (record.codeRoad && record.codeRoad.length > 0)
? record.codeRoad[0] === 'X'
? '县道'
: record.codeRoad[0] === 'Y'
? '乡道'
: '村道'
: ''
}
}, {
title: '所属道路',
key: 'road',
dataIndex: 'road',
align: 'center'
}, {
title: '所在路段',
key: 'address',
dataIndex: 'address',
align: 'center',
render: (text, record) => {
return `${record.roadSectionStart || ''}-${record.roadSectionEnd || ''}`
}
},
{
title: '具体位置',
key: 'address',
dataIndex: 'address',
align: 'center'
},
{
title: '上报人',
width: 100,
key: 'userName',
dataIndex: 'userName',
align: 'center',
render: (text, record) => {
return record?.user?.name
}
}, {
title: '上报时间',
key: 'time',
dataIndex: 'time',
valueType: 'dateTime',
align: 'center'
}, {
title: '操作',
width: 200,
key: 'option',
valueType: 'option',
align: 'center',
render: (text, record) => {
return [
<Button
onClick={() => { checkDetail(record); handleOpen(); }}
style={{ marginRight: 10 }}>查看</Button>,
<Popover
content={[
<div style={{ width: '100%', height: 30 }}>
<Button onClick={() => setVisible(false)} style={{ float: "right" }} ></Button>
<Button type="primary" onClick={() => handleRemove(record)} style={{ marginRight: 8, float: "right" }} ></Button>
</div>
]}
visible={selectRecord == record.id && visible}
trigger="click"
onClick={() => user?.username !== 'SuperAdmin' && user?.userResources?.filter(i => i.resourceId === 'CONSERVATIONMANAGE')[0].isshow === "true" ? '' : setSelectRecord(record.id)}
title="是否删除该记录?"
onVisibleChange={(newVisible) => setVisible(newVisible)}
>
<Button disabled={editAble}>删除</Button>
</Popover>
]
}
},
];
return (
<ProTable
columns={columns}
dataSource={reportList}
loading={loading}
pagination={{
pageSize: 10,
defaultPageSize: 10,
showSizeChanger: false,
}}
rowKey="key"
toolBarRender={false}
search={false}
/>
);
};
const PatrolNameList = (props) => {
const { Search } = Input;
const [users, setUsers] = useState([]);
const { onChange, record, userList, loading, depMessage, depUser, clientHeight, dispatch, user } = props;
const [selectRoad, setSelectRoad] = useState();
const [selectedTree, setSelectedTree] = useState();
const [depSelectedKeys, setDepSelectedKeys] = useState([])
const [depAllUser, setDepAllUser] = useState([])
//const [depMessagedata, setdepMessagedata] = useState()//侧边栏的展示数据
const [expandedKeys, setExpandedKeys] = useState([]);
const [searchValue, setSearchValue] = useState('');
const [autoExpandParent, setAutoExpandParent] = useState(true);
const [defaultData, setDefaultData] = useState([]);
const [dataList, setDataList] = useState([]);
//console.log('record', record)
useEffect(() => {
let departments = []
const generateData = (data, _preKey, _tns) => {
const preKey = _preKey || '0';
const tns = _tns || [];
const children = [];
data.forEach(department => {
const key = `${preKey}-${department.depId}`;
const node = {
title: department.depName.toString(),
key,
children: [],
};
if (department.users.length > 0) { // 仅当部门有用户时添加子节点
department.users.forEach(user => {
node.children.push({
title: user.name.toString(),
key: `${key}-${user.id}`,
isLeaf: true, // 用户节点为叶子节点
});
});
}
if (department.children && department.children.length > 0) {
const childKeys = generateData(department.children, key, node.children);
children.push(...childKeys);
}
tns.push(node);
if (node.children.length > 0 && department.expanded) { // 仅当部门展开时添加子节点
children.push(key);
}
});
return children;
};
if (user?.username === 'SuperAdmin') {
departments = [...new Set(depAllUser)]
} else {
let depAllUserCopy = []
depAllUser.map((item) => {
if (item.depId === user?.departmentId) {
depAllUserCopy.push(item)
}
})
departments = [...new Set(depAllUserCopy)]
}
const processedData = [];
const expandedKeys = generateData(departments, null, processedData);
setDefaultData(processedData);
setDataList(processedData.map(item => ({ key: item.key, title: item.title.toString(), children: item.children })));
setExpandedKeys(expandedKeys);
}, [depAllUser])
useEffect(() => {
dispatch(getAllDepUsers()).then((res) => {
if (res.success) setDepAllUser(res?.payload?.data)
})
}, [])
const getParentKey = (key, tree) => {
let parentKey;
for (let i = 0; i < tree.length; i++) {
const node = tree[i];
if (node.children) {
if (node.children.some((item) => item.key === key)) {
parentKey = node.key;
} else {
parentKey = getParentKey(key, node.children);
}
}
if (parentKey) {
break;
}
}
return parentKey;
};
const handleSearch = (value) => {
const filteredKeys = [];
const expandedKeys = [];
const loopTreeData = (data) => {
data.forEach((item) => {
if (item.title.indexOf(value) > -1) {
filteredKeys.push(item.key);
let parentKey = getParentKey(item.key, defaultData);
while (parentKey) {
if (!expandedKeys.includes(parentKey)) {
expandedKeys.push(parentKey);
}
parentKey = getParentKey(parentKey, defaultData);
}
}
if (item.children) {
loopTreeData(item.children);
}
});
};
loopTreeData(defaultData);
setSearchValue(value);
setExpandedKeys(expandedKeys);
};
const handleExpand = (expandedKeys) => {
setExpandedKeys(expandedKeys);
};
const renderTreeNodes = (data) => {
return data.map((item) => {
const { key, title, children } = item;
const isLeaf = !children || children.length === 0;
return (
<Tree.TreeNode
key={key}
title={title}
icon={isLeaf ? null : (
expandedKeys.includes(key) ? <CaretDownOutlined /> : <CaretRightOutlined />
)}
isLeaf={isLeaf}
>
{children && children.length > 0 && renderTreeNodes(children)}
</Tree.TreeNode>
);
});
};
const treeData = useMemo(() => {
const loop = (data) =>
data.map((item) => {
const { title, key, children } = item;
const strTitle = title.toString();
const index = strTitle.indexOf(searchValue);
const beforeStr = strTitle.substring(0, index);
const afterStr = strTitle.slice(index + searchValue.length);
const titleNode = index > -1 ? (
<span>
{beforeStr}
<span style={{ color: '#f50' }}>{searchValue}</span>
{afterStr}
</span>
) : (
<span>{strTitle}</span>
);
if (children && children.length > 0) {
return {
title: titleNode,
key,
children: loop(children),
};
}
return {
title: titleNode,
key,
};
});
return loop(defaultData);
}, [searchValue, defaultData]);
useEffect(() => {
if (userList && userList instanceof Array && userList.length) {
setSelectRoad(userList[0].id)
// onChange(userList[0]);
}
}, [userList])
useEffect(() => {
if (userList && userList instanceof Array) {
let users = userList.filter(user => user.remark != 'sp');
setUsers(users);
}
}, [userList])
const handleSelect = (selectedKeys, { selected, selectedNodes, node }) => {
if (selected) {
if (selectedKeys[0].split("-").length - 1 >= 2) {
let id = selectedKeys[0].split('-')[selectedKeys[0].split('-').length - 1]
//console.log('id', id)
onChange(id);
}
}
//('selectedKeys', selectedKeys, selected, selectedNodes, node)
};
if (loading) {
return <div>Loading...</div>
}
return (
<div className='spilce' style={{ height: '600px', width: '100%', overflow: 'auto' }} >
<Search
placeholder="请输入上报人员"
value={searchValue}
onChange={(e) => handleSearch(e.target.value)}
/>
<Tree
expandedKeys={expandedKeys}
onExpand={handleExpand}
autoExpandParent={autoExpandParent}
onSelect={handleSelect}
>
{renderTreeNodes(treeData)}
</Tree>
</div>
);
};
const MaintenanceTable = (props) => {
const { userList, user, reportList, dispatch, allDepUsers, reportListLoading, reportDetail, reportDetailLoading, userLoading, exports, depMessage, depUser, clientHeight } = props;
const [record, setRecord] = useState(1);
const [dateRange, setDateRange] = useState();
const [detailVisible, setDetailVisible] = useState(false)
const { RangePicker } = DatePicker;
// console.log('allDepUsers', allDepUsers)
useEffect(() => {
queryData()
}, [])
useEffect(() => {
// if (userList && userList instanceof Array) {
// let users = userList.filter(user => user.remark != 'sp');
// setRecord(users[0]);
// }
}, [userList])
useEffect(() => {
// if (record) {
queryData()
// }
}, [record, dateRange, allDepUsers, user])
const queryData = () => {
if (allDepUsers && allDepUsers.length && user) {
//console.log('ssssss',)
const userL = allDepUsers.find(item => item.depId === user.departmentId)?.users?.map(child => { return child.id })
let userId = null
if (user?.username === 'SuperAdmin' && record === 1) {
userId = undefined
} else if (user?.username !== 'SuperAdmin' && record === 1) {
userId = userL && userL.length ? userL + '' : undefined
} else {
userId = record
}
//: user?.username === 'SuperAdmin' && record === 1 ? record?.id : record ? record : user?.id
let query = {
userId,
reportType: 'conserve',
asc: true
}
if ((dateRange && dateRange instanceof Array && dateRange[0] != '')) {
query.startTime = moment(dateRange[0]).startOf('day').format('YYYY-MM-DD HH:mm:ss')
query.endTime = moment(dateRange[1]).endOf('day').format('YYYY-MM-DD HH:mm:ss')
}
dispatch(getReportList(query))
}
}
const handleClose = () => {
setDetailVisible(false)
}
const handleOpen = () => {
setDetailVisible(true)
}
const handelRefresh = () => {
let query = {
userId: record.id,
reportType: 'conserve',
asc: true
}
dispatch(getReportList(query));
}
const handleExport = () => {
if (reportList && reportList instanceof Array && reportList.length) {
let ids = reportList.map(item => item.id);
exports(ids);
}
}
return (
<div className='card-protable'>
<Card >
<PatrolNameList
depMessage={depMessage} depUser={depUser} clientHeight={clientHeight} dispatch={dispatch} user={user}
onChange={(record) => setRecord(record)} record={record} userList={userList} loading={userLoading} handelRefresh={handelRefresh} />
</Card>
<Card style={{ flex: 1 }} >
<div style={{ marginBottom: 20 }}>
<RangePicker onChange={(date, dateString) => { setDateRange(dateString) }} />
<Button style={{ marginLeft: 20 }}>查询</Button>
<Button style={{ marginLeft: 20 }} onClick={handleExport}>导出</Button>
</div>
<Card style={{ flex: 1 }}>
<DetailList
user={user}
reportList={reportList} record={record} loading={reportListLoading} dispatch={dispatch} handleOpen={handleOpen}
handelRefresh={handelRefresh}
/>
</Card>
<DetailForm
visible={detailVisible}
handleClose={handleClose}
data={reportDetail}
loading={reportDetailLoading} />
</Card>
</div>
);
};
function mapStateToProps (state) {
const { auth, depMessage, userList, reportList, reportDetail, depUser, global, allDepUsers } = state;
const pakData = (dep) => {
return dep.map((d) => {
return {
title: d.name,
value: d.id,
children: pakData(d.subordinate)
}
})
}
let depData = pakData(depMessage.data || [])
return {
clientHeight: global.clientHeight,
user: auth.user,
depMessage: depMessage.data || [],
depLoading: depMessage.isRequesting,
depData,
userList: userList.data || [],
userLoading: userList.isRequesting,
reportList: reportList.data,
reportListLoading: reportList.isRequesting,
reportDetail: reportDetail.data,
reportDetailLoading: reportDetail.isRequesting,
depUser: depUser.data || [],
allDepUsers: allDepUsers.data || []
};
}
export default connect(mapStateToProps)(MaintenanceTable);