zhaobing
10 months ago
150 changed files with 5 additions and 13136 deletions
@ -1,60 +0,0 @@ |
|||
'use strict'; |
|||
import { basicAction } from '@peace/utils' |
|||
import { ApiTable } from '$utils' |
|||
|
|||
export function getAdvisoryNotices(query) { |
|||
return dispatch => basicAction({ |
|||
type: 'get', |
|||
dispatch: dispatch, |
|||
query, |
|||
actionType: 'GET_ADVISORY_NOTICES', |
|||
url: `${ApiTable.getAdvisoryNotices}`, |
|||
msg: { error: '获取资讯公告失败' }, |
|||
reducer: { name: 'advisoryNotice'} |
|||
}) |
|||
} |
|||
|
|||
export function addOrUpdateAdvisoryNotice(data) { |
|||
return dispatch => basicAction({ |
|||
type: 'post', |
|||
dispatch: dispatch, |
|||
data, |
|||
actionType: 'ADD_OR_UPDATE_ADVISORY_NOTICE', |
|||
url: `${ApiTable.addOrUpdateAdvisoryNotice}`, |
|||
msg: { option: data?.id?'编辑资讯公告':'新增资讯公告' }, |
|||
}) |
|||
} |
|||
export function delAdvisoryNotice(id) { |
|||
return dispatch => basicAction({ |
|||
type: 'delete', |
|||
dispatch: dispatch, |
|||
actionType: 'DEL_ADVISORY_NOTICE', |
|||
url: ApiTable.delAdvisoryNotice.replace('{id}', id), |
|||
msg: { option: '删除资讯公告' }, |
|||
}) |
|||
} |
|||
|
|||
|
|||
export function updateAdvisoryNoticeState(id,data) { |
|||
return dispatch => basicAction({ |
|||
type: 'post', |
|||
dispatch: dispatch, |
|||
data, |
|||
actionType: 'UPDATE_ADVISORY_NOTICE_STATE', |
|||
url: ApiTable.updateAdvisoryNoticeState.replace('{id}', id), |
|||
msg: { option: data?.msg?.includes('发布')?'发布资讯公告':'下架资讯公告' }, |
|||
}) |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
export default{ |
|||
getAdvisoryNotices, |
|||
addOrUpdateAdvisoryNotice, |
|||
delAdvisoryNotice, |
|||
updateAdvisoryNoticeState |
|||
} |
@ -1,6 +0,0 @@ |
|||
|
|||
'use strict'; |
|||
import advisoryNotice from './advisoryNotice' |
|||
export default { |
|||
...advisoryNotice |
|||
} |
@ -1,108 +0,0 @@ |
|||
import React, { useRef, useState, useEffect } from 'react' |
|||
import { Button, Form } from 'antd' |
|||
import { connect } from 'react-redux' |
|||
import { InfoCircleOutlined } from '@ant-design/icons' |
|||
import { ModalForm, ProFormSelect, ProFormText, ProFormDatePicker, ProFormTextArea,ProForm } from '@ant-design/pro-form' |
|||
import moment from 'moment' |
|||
import Uploads from '$components/Uploads' |
|||
|
|||
function AddAdvisoryNoticeModal(props) { |
|||
const { |
|||
title, |
|||
triggerRender, |
|||
editData = null, |
|||
onFinish, |
|||
devices, |
|||
actions, |
|||
dispatch, |
|||
disabled, |
|||
} = props |
|||
const formItemLayout = { labelCol: { span: 6 }, wrapperCol: { span: 16 } } |
|||
const initialValues = editData ? { ...editData } : {} |
|||
const [form] = Form.useForm() |
|||
const formRef = useRef() |
|||
|
|||
return ( |
|||
<ModalForm |
|||
width={500} |
|||
formRef={formRef} |
|||
title={title || ''} |
|||
initialValues={initialValues} |
|||
trigger={triggerRender ? triggerRender : <Button type='primary'>{title || ''}</Button>} |
|||
layout='horizontal' |
|||
grid={true} |
|||
{...formItemLayout} |
|||
modalProps={{ |
|||
destroyOnClose: true, |
|||
onCancel: () => {}, |
|||
}} |
|||
onFinish={async values => { |
|||
let value = { |
|||
title: values?.title, |
|||
content: values?.content, |
|||
id: initialValues ? initialValues.id : null, |
|||
attachments:values?.attachments?.length? |
|||
values?.attachments[0]?.name ? values?.attachments.map(u => u.storageUrl) : editData?.attachments:[], |
|||
} |
|||
if(disabled){ |
|||
return true |
|||
} |
|||
return onFinish && (await onFinish(value)) |
|||
// return true;
|
|||
}}> |
|||
<ProFormText |
|||
rules={[{ required: true, message: '资讯标题' }]} |
|||
placeholder='请输入资讯标题' |
|||
name='title' |
|||
label='资讯标题' |
|||
disabled={disabled ? true : false} |
|||
/> |
|||
<ProFormTextArea |
|||
rules={[{ required: true, message: '咨讯内容' }]} |
|||
placeholder='请输入咨讯内容' |
|||
name='content' |
|||
label='咨讯内容' |
|||
disabled={disabled ? true : false} |
|||
/> |
|||
<div className='ant-col ant-col-xs-24'> |
|||
<Form.Item |
|||
label='文件:' |
|||
name='attachments' |
|||
// rules={[{ required: true, message: '请添加附件!' }]}
|
|||
disabled={disabled ? true : false}> |
|||
<Uploads |
|||
disabled={disabled ? true : false} |
|||
listType='picture-card' |
|||
uploadType='project' |
|||
maxFilesNum={10} |
|||
maxFileSize={10} |
|||
isQiniu={true} |
|||
// disabled={true}
|
|||
fileTypes={['png', 'jpg']} |
|||
defaultValue={(() => { |
|||
let nextV = [] |
|||
for (let s of editData?.attachments || []) { |
|||
if (s) { |
|||
nextV.push({ |
|||
storageUrl: s, |
|||
}) |
|||
} |
|||
} |
|||
return nextV |
|||
})()} |
|||
/> |
|||
</Form.Item> |
|||
</div> |
|||
</ModalForm> |
|||
) |
|||
} |
|||
function mapStateToProps(state) { |
|||
const { auth, global, device } = state |
|||
return { |
|||
loading: device.isRequesting, |
|||
clientHeight: global.clientHeight, |
|||
actions: global.actions, |
|||
} |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(AddAdvisoryNoticeModal) |
@ -1,216 +0,0 @@ |
|||
import React, { useEffect, useState, useRef, useMemo } from 'react' |
|||
import { Spin, Popconfirm, message, Button, Input, Select } from 'antd' |
|||
import { connect } from 'react-redux' |
|||
import ProTable from '@ant-design/pro-table' |
|||
import moment from 'moment' |
|||
import AddAdvisoryNoticeModal from '../components/addAdvisoryNoticeModal' |
|||
function AdvisorNotice(props) { |
|||
const { loading, clientHeight, actions, dispatch } = props |
|||
const { advisorNotice } = actions |
|||
const tableRef = useRef() |
|||
const proTableFormRef = useRef() |
|||
const [tableParams, setTableParams] = useState({}) |
|||
const [dataSource, setDataSource] = useState([]) |
|||
|
|||
const queryData = () => { |
|||
dispatch(advisorNotice.getAdvisoryNotices()).then(res => { |
|||
if (res.success) { |
|||
const list = res?.payload?.data?.rows |
|||
setDataSource(list) |
|||
} |
|||
}) |
|||
} |
|||
//初始化
|
|||
useEffect(() => { |
|||
queryData() |
|||
}, []) |
|||
|
|||
//新增或编辑
|
|||
const onFinish = async values => { |
|||
const dataToSave = { title: values?.title, content: values?.content,attachments:values?.attachments,id: values?.id } |
|||
return dispatch(advisorNotice.addOrUpdateAdvisoryNotice(dataToSave)).then(res => { |
|||
if (res.success) { |
|||
queryData() |
|||
// tableRef.current.reload()
|
|||
return true |
|||
} else { |
|||
return false |
|||
} |
|||
}) |
|||
} |
|||
//删除
|
|||
const handleDelete = id => { |
|||
dispatch(advisorNotice.delAdvisoryNotice(id)).then(res => { |
|||
if (res.success) { |
|||
queryData() |
|||
} |
|||
}) |
|||
} |
|||
|
|||
//查询公告(搜索按钮)
|
|||
const tableDatas = useMemo(() => { |
|||
const { title } = tableParams |
|||
let rslt = dataSource |
|||
rslt = rslt.filter(s => (title ? (s.title ? s.title.includes(title) : false) : true)) |
|||
return rslt |
|||
}) |
|||
//上架下架处理
|
|||
const publishHandler=(record)=>{ |
|||
const msg=record.state===2?'下架':'发布' |
|||
const publishTime=record.state===2?moment(record.publishTime).format('YYYY-MM-DD HH:mm:ss'):null |
|||
dispatch(advisorNotice.updateAdvisoryNoticeState(record.id,{msg,publishTime})).then(res => { |
|||
if (res.success) { |
|||
queryData() |
|||
} |
|||
}) |
|||
} |
|||
|
|||
const columns = [ |
|||
{ |
|||
title: '序号', |
|||
dataIndex: 'id', |
|||
width: '12%', |
|||
render: (text, record, index) => { |
|||
return index + 1 |
|||
}, |
|||
search: false, |
|||
|
|||
}, |
|||
{ |
|||
title: '公告标题', |
|||
dataIndex: 'title', |
|||
ellipsis: true, |
|||
}, |
|||
{ |
|||
title: '发布时间', |
|||
dataIndex: 'publishTime', |
|||
ellipsis: true, |
|||
search: false, |
|||
render: (text, record, index) => { |
|||
return record?.publishTime?moment(record?.publishTime).format('YYYY-MM-DD HH:mm:ss'):'--' |
|||
}, |
|||
}, |
|||
{ |
|||
title: '当前状态', |
|||
dataIndex: 'state', |
|||
ellipsis: true, |
|||
search: false, |
|||
render: (text, record, index) => { |
|||
return record?.state===1?'草稿':record?.state===2?'已发布':'已下架' |
|||
}, |
|||
}, |
|||
{ |
|||
title: '操作', |
|||
width: 300, |
|||
key: 'option', |
|||
valueType: 'option', |
|||
render: (text, record) => { |
|||
const options = [] |
|||
options.push( |
|||
<AddAdvisoryNoticeModal |
|||
triggerRender={<a>查看详情</a>} |
|||
editData={record} |
|||
disabled={true} |
|||
title='查看详情' |
|||
onFinish={onFinish} |
|||
key='lookModel' |
|||
/> |
|||
) |
|||
options.push( |
|||
<Popconfirm |
|||
key='del' |
|||
placement='top' |
|||
title={record?.state===2?'确定下架吗?':'确定发布吗?'} |
|||
onConfirm={() => publishHandler(record)} |
|||
okText='是' |
|||
cancelText='否'> |
|||
<a>{record?.state===2?'下架':'发布'}</a> |
|||
</Popconfirm> |
|||
) |
|||
record.state ===1||record.state ===3? options.push( |
|||
<AddAdvisoryNoticeModal |
|||
triggerRender={<a>编辑</a>} |
|||
editData={record} |
|||
title='编辑资讯' |
|||
onFinish={onFinish} |
|||
key='editModel' |
|||
/> |
|||
):'' |
|||
|
|||
record.state ===1||record.state ===3?options.push( |
|||
<Popconfirm |
|||
key='del' |
|||
placement='top' |
|||
title='是否确认删除资讯?' |
|||
onConfirm={() => handleDelete(record.id)} |
|||
okText='是' |
|||
cancelText='否'> |
|||
<a style={{color:'red'}}>删除</a> |
|||
</Popconfirm> |
|||
):'' |
|||
|
|||
return options |
|||
}, |
|||
}, |
|||
] |
|||
|
|||
return ( |
|||
<Spin spinning={loading}> |
|||
<div id='patrol-record' className='global-main'> |
|||
{/* <Spin spinning={loading}> */} |
|||
<div style={{ marginBottom: 19 }}> |
|||
<div className='top' style={{ marginBottom: 19 }}> |
|||
<div className='title'> |
|||
<span className='line'></span> |
|||
<span className='cn'>咨讯公告</span> |
|||
<span className='en'> ADVISORYNOTICE</span> |
|||
</div> |
|||
<div></div> |
|||
</div> |
|||
</div> |
|||
<AddAdvisoryNoticeModal |
|||
triggerRender={<Button type='primary'>新增</Button>} |
|||
title='新增资讯' |
|||
onFinish={onFinish} |
|||
key='addModel' |
|||
/> |
|||
<ProTable |
|||
formRef={proTableFormRef} |
|||
rowKey='id' |
|||
options={false} |
|||
request={async params => { |
|||
setTableParams(params) |
|||
return { |
|||
data: [], |
|||
success: true, |
|||
} |
|||
}} |
|||
actionRef={tableRef} |
|||
columns={columns} |
|||
pagination={{ pageSize: 10, size: 'default', className: 'global-pagination' }} |
|||
dataSource={tableDatas || []} |
|||
// search={{
|
|||
// labelWidth: 100,
|
|||
// }}
|
|||
// search={{
|
|||
// optionRender: ({searchText, resetText}, {form}, dom) => [
|
|||
// <Button type="primary" onClick={searchHandler}>查询</Button>,
|
|||
// ]
|
|||
// }}
|
|||
></ProTable> |
|||
{/* </Spin> */} |
|||
</div> |
|||
</Spin> |
|||
) |
|||
} |
|||
|
|||
function mapStateToProps(state) { |
|||
const { auth, global, advisoryNotice } = state |
|||
return { |
|||
loading: advisoryNotice.isRequesting, |
|||
clientHeight: global.clientHeight, |
|||
actions: global.actions, |
|||
} |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(AdvisorNotice) |
@ -1,5 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
import AdvisoryNotice from './advisoryNotice' |
|||
|
|||
export { AdvisoryNotice } |
@ -1,15 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
import reducers from './reducers'; |
|||
import routes from './routes'; |
|||
import actions from './actions'; |
|||
import { getNavItem } from './nav-item'; |
|||
|
|||
export default { |
|||
key: 'advisorNotice', |
|||
name: '资讯广告', |
|||
reducers: reducers, |
|||
routes: routes, |
|||
actions: actions, |
|||
getNavItem: getNavItem |
|||
}; |
@ -1,14 +0,0 @@ |
|||
import React from 'react'; |
|||
import { Link } from 'react-router-dom'; |
|||
import { Menu } from 'antd'; |
|||
import { HomeOutlined } from '@ant-design/icons'; |
|||
import { Func } from '$utils'; |
|||
const SubMenu = Menu.SubMenu; |
|||
|
|||
export function getNavItem (user, dispatch) { |
|||
|
|||
return <Menu.Item key="advisoryNotice" icon={<img src='/assets/images/menu/home.svg' style={{ width: 24, height: 24 }} />}> |
|||
<Link to="/advisoryNotice">咨讯公告</Link> |
|||
</Menu.Item> |
|||
|
|||
} |
@ -1,5 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
export default { |
|||
|
|||
} |
@ -1,12 +0,0 @@ |
|||
'use strict'; |
|||
import { AdvisoryNotice } from './containers'; |
|||
|
|||
export default [{ |
|||
type: 'inner', |
|||
route: { |
|||
path: '/advisoryNotice', |
|||
key: 'advisoryNotice', |
|||
breadcrumb: '咨询公告', |
|||
component: AdvisoryNotice, |
|||
} |
|||
}]; |
@ -1,8 +1,7 @@ |
|||
'use strict'; |
|||
|
|||
import * as device from './device' |
|||
import * as network from './network' |
|||
|
|||
export default { |
|||
...device,...network |
|||
...device, |
|||
} |
@ -1,50 +0,0 @@ |
|||
'use strict'; |
|||
import { basicAction } from '@peace/utils' |
|||
import { ApiTable } from '$utils' |
|||
|
|||
export function getNetworks(query) { |
|||
return dispatch => basicAction({ |
|||
type: 'get', |
|||
dispatch: dispatch, |
|||
query, |
|||
actionType: 'GET_NETWORKS', |
|||
url: `${ApiTable.getNetworks}`, |
|||
msg: { error: '获取宽带专网失败' }, |
|||
reducer: { name: 'networks'} |
|||
}) |
|||
} |
|||
|
|||
export function addOrUpdateNetwork(data) { |
|||
return dispatch => basicAction({ |
|||
type: 'post', |
|||
dispatch: dispatch, |
|||
data, |
|||
actionType: 'ADD_OR_UPDATE_NETWORK', |
|||
url: `${ApiTable.addOrUpdateNetwork}`, |
|||
msg: { option: data?.id?'编辑宽带专网':'新增宽带专网' }, |
|||
}) |
|||
} |
|||
export function delNetwork(id) { |
|||
return dispatch => basicAction({ |
|||
type: 'delete', |
|||
dispatch: dispatch, |
|||
actionType: 'DEL_NETWORK', |
|||
url: ApiTable.delNetwork.replace('{id}', id), |
|||
msg: { option: '删除宽带专网' }, |
|||
}) |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
export default{ |
|||
getNetworks, |
|||
addOrUpdateNetwork, |
|||
delNetwork, |
|||
} |
@ -1,103 +0,0 @@ |
|||
import React, { useRef, useState, useEffect } from 'react' |
|||
import { Button, Form } from 'antd' |
|||
import { connect } from 'react-redux' |
|||
import { InfoCircleOutlined } from '@ant-design/icons' |
|||
import { ModalForm, ProFormSelect, ProFormText, ProFormDatePicker, ProFormTextArea,ProForm, ProFormTimePicker } from '@ant-design/pro-form' |
|||
import moment from 'moment' |
|||
|
|||
function addNetworkModal(props) { |
|||
const { |
|||
title, |
|||
structureListOpt, |
|||
triggerRender, |
|||
editData = null, |
|||
onFinish, |
|||
devices, |
|||
actions, |
|||
dispatch, |
|||
type |
|||
} = props |
|||
const formItemLayout = { labelCol: { span: 6 }, wrapperCol: { span: 16 } } |
|||
const initialValues = editData ? { ...editData } : {} |
|||
const [form] = Form.useForm() |
|||
const formRef = useRef() |
|||
|
|||
return ( |
|||
<ModalForm |
|||
width={500} |
|||
formRef={formRef} |
|||
title={title || ''} |
|||
initialValues={initialValues} |
|||
trigger={triggerRender ? triggerRender : <Button type='primary'>{title || ''}</Button>} |
|||
layout='horizontal' |
|||
grid={true} |
|||
{...formItemLayout} |
|||
modalProps={{ |
|||
destroyOnClose: true, |
|||
onCancel: () => {}, |
|||
}} |
|||
|
|||
onFinish={async values => { |
|||
console.log('x111',values) |
|||
let value = { |
|||
name: values?.name, |
|||
type:values?.type, |
|||
account:values?.account, |
|||
indate: values?.indate, |
|||
id: initialValues ? initialValues.id : null, |
|||
projectId:values?.projectId |
|||
} |
|||
|
|||
return onFinish && (await onFinish(value)) |
|||
// return true;
|
|||
}}> |
|||
<ProFormText |
|||
rules={[{ required: true, message: '请输入专网名称' }]} |
|||
placeholder='请输入专网名称' |
|||
name='name' |
|||
label='专网名称' |
|||
/> |
|||
<ProFormSelect |
|||
rules={[{ required: true, message: '请选择专网类型' }]} |
|||
placeholder='请选择专网类型' |
|||
options={type?.map(s => { |
|||
return { label: s.label, value: s.id } |
|||
})} |
|||
name='type' |
|||
label='专网类型' |
|||
/> |
|||
<ProFormText |
|||
rules={[{ required: true, message: '请输入账号' }]} |
|||
placeholder='请输入账号' |
|||
name='account' |
|||
label='账号' |
|||
/> |
|||
<ProFormDatePicker |
|||
rules={[{ required: true, message: '请输入有效期' }]} |
|||
placeholder='请输入有效期' |
|||
name='indate' |
|||
label='有效期' |
|||
/> |
|||
<ProFormSelect |
|||
showSearch |
|||
allowClear |
|||
rules={[{ required: true, message: '请选择结构物' }]} |
|||
placeholder='请选择结构物' |
|||
options={structureListOpt?.map(s => { |
|||
return { label: s.label, value: s.id } |
|||
})} |
|||
name='projectId' |
|||
label='关联结构物' |
|||
/> |
|||
</ModalForm> |
|||
) |
|||
} |
|||
function mapStateToProps(state) { |
|||
const { auth, global } = state |
|||
return { |
|||
clientHeight: global.clientHeight, |
|||
actions: global.actions, |
|||
} |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(addNetworkModal) |
@ -1,5 +1,4 @@ |
|||
'use strict'; |
|||
|
|||
import DeviceManage from './deviceManage' |
|||
import Network from './network' |
|||
export { DeviceManage,Network}; |
|||
export { DeviceManage}; |
|||
|
@ -1,213 +0,0 @@ |
|||
import React, { useEffect, useState, useRef, useMemo } from 'react' |
|||
import { Spin, Popconfirm, message, Button, Input, Select } from 'antd' |
|||
import { connect } from 'react-redux' |
|||
import ProTable from '@ant-design/pro-table' |
|||
import moment from 'moment' |
|||
import AddNetworkModal from '../components/addNetworkModal'; |
|||
|
|||
|
|||
|
|||
const type=[{id:1,label:'外网'},{id:2,label:'内网'}] |
|||
function Network(props) { |
|||
const { loading, clientHeight, actions, dispatch, } = props |
|||
const { deviceManage,projectRegime} = actions |
|||
const tableRef = useRef() |
|||
const proTableFormRef = useRef() |
|||
const [tableParams, setTableParams] = useState({}) |
|||
const [dataSource, setDataSource] = useState([]) |
|||
const [structureListOpt, setStructureListOpt] = useState([])//巡检结构物
|
|||
const queryData = () => { |
|||
dispatch(deviceManage.getNetworks()).then(res => { |
|||
if (res.success) { |
|||
const list = res?.payload?.data?.rows |
|||
setDataSource(list) |
|||
} |
|||
}) |
|||
} |
|||
//初始化
|
|||
useEffect(() => { |
|||
dispatch(projectRegime.getProjectList()).then(res => { |
|||
if (res.success) { |
|||
const dp = res.payload.data?.rows?.filter(i=>i.type==='管廊')?.map(item => { |
|||
return { |
|||
label: item?.name, |
|||
id: item?.id, |
|||
} |
|||
}) |
|||
setStructureListOpt(dp) |
|||
} |
|||
}) |
|||
queryData() |
|||
}, []) |
|||
|
|||
//新增或编辑
|
|||
const onFinish = async values => { |
|||
const dataToSave = { |
|||
name: values?.name, |
|||
type:values?.type, |
|||
account:values?.account, |
|||
indate: values?.indate, |
|||
id: values.id , |
|||
projectId:values?.projectId |
|||
} |
|||
return dispatch(deviceManage.addOrUpdateNetwork(dataToSave)).then(res => { |
|||
if (res.success) { |
|||
queryData() |
|||
// tableRef.current.reload()
|
|||
return true |
|||
} else { |
|||
return false |
|||
} |
|||
}) |
|||
} |
|||
//删除
|
|||
const handleDelete = id => { |
|||
dispatch(deviceManage.delNetwork(id)).then(res => { |
|||
if (res.success) { |
|||
queryData() |
|||
} |
|||
}) |
|||
} |
|||
|
|||
//查询宽带名字(搜索按钮)
|
|||
const tableDatas = useMemo(() => { |
|||
const { name } = tableParams |
|||
let rslt = dataSource |
|||
rslt = rslt.filter(s => (name ? (s.name ? s.name.includes(name) : false) : true)) |
|||
return rslt |
|||
}) |
|||
|
|||
|
|||
const columns = [ |
|||
{ |
|||
title: '专网名称', |
|||
dataIndex: 'name', |
|||
ellipsis: true, |
|||
}, |
|||
{ |
|||
title: '专网类型', |
|||
dataIndex: 'type', |
|||
ellipsis: true, |
|||
search: false, |
|||
valueEnum: type.reduce((enumObj, { id, label }) => { |
|||
enumObj[id] = { text: label }; |
|||
return enumObj; |
|||
}, {}), |
|||
|
|||
}, |
|||
{ |
|||
title: '账号', |
|||
dataIndex: 'account', |
|||
ellipsis: true, |
|||
search: false, |
|||
}, |
|||
{ |
|||
title: '有效期', |
|||
dataIndex: 'indate', |
|||
ellipsis: true, |
|||
search: false, |
|||
render: (text, record, index) => { |
|||
return record?.indate?moment(record?.indate).format('YYYY-MM-DD'):'--' |
|||
}, |
|||
}, |
|||
{ |
|||
title: '关联结构物', |
|||
dataIndex: 'projectId', |
|||
ellipsis: true, |
|||
search: false, |
|||
valueEnum: structureListOpt.reduce((enumObj, { id, label }) => { |
|||
enumObj[id] = { text: label }; |
|||
return enumObj; |
|||
}, {}), |
|||
}, |
|||
{ |
|||
title: '操作', |
|||
width: 300, |
|||
key: 'option', |
|||
valueType: 'option', |
|||
render: (text, record) => { |
|||
const options = [] |
|||
options |
|||
.push( <AddNetworkModal |
|||
type={type} |
|||
structureListOpt={structureListOpt} |
|||
triggerRender={<a>编辑</a>} |
|||
editData={record} |
|||
title='编辑宽带专网' |
|||
onFinish={onFinish} |
|||
key='editModel' |
|||
/> |
|||
) |
|||
|
|||
|
|||
options.push( |
|||
<Popconfirm |
|||
key='del' |
|||
placement='top' |
|||
title='是否确认删除宽带专网?' |
|||
onConfirm={() => handleDelete(record.id)} |
|||
okText='是' |
|||
cancelText='否'> |
|||
<a style={{ color: 'red' }}>删除</a> |
|||
</Popconfirm> |
|||
) |
|||
|
|||
return options |
|||
}, |
|||
}, |
|||
] |
|||
|
|||
return ( |
|||
<Spin spinning={loading}> |
|||
<div id='patrol-record' className='global-main'> |
|||
{/* <Spin spinning={loading}> */} |
|||
<div style={{ marginBottom: 19 }}> |
|||
<div className='top' style={{ marginBottom: 19 }}> |
|||
<div className='title'> |
|||
<span className='line'></span> |
|||
<span className='cn'>宽带专网</span> |
|||
<span className='en'> NETWORK</span> |
|||
</div> |
|||
<div></div> |
|||
</div> |
|||
</div> |
|||
<AddNetworkModal |
|||
type={type} |
|||
structureListOpt={structureListOpt} |
|||
triggerRender={<Button type='primary'>新增</Button>} |
|||
title='新增宽带宽带' |
|||
onFinish={onFinish} |
|||
key='addModel' |
|||
/> |
|||
<ProTable |
|||
formRef={proTableFormRef} |
|||
rowKey='id' |
|||
options={false} |
|||
request={async params => { |
|||
setTableParams(params) |
|||
return { |
|||
data: [], |
|||
success: true, |
|||
} |
|||
}} |
|||
actionRef={tableRef} |
|||
columns={columns} |
|||
pagination={{ pageSize: 10, size: 'default', className: 'global-pagination' }} |
|||
dataSource={tableDatas || []} |
|||
></ProTable> |
|||
{/* </Spin> */} |
|||
</div> |
|||
</Spin> |
|||
) |
|||
} |
|||
|
|||
function mapStateToProps(state) { |
|||
const { auth, global, networks } = state |
|||
return { |
|||
loading: networks.isRequesting, |
|||
clientHeight: global.clientHeight, |
|||
actions: global.actions, |
|||
} |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(Network) |
@ -1,11 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
|
|||
import * as record from './record' |
|||
|
|||
|
|||
export default { |
|||
|
|||
...record, |
|||
|
|||
} |
@ -1,32 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
import { basicAction } from '@peace/utils' |
|||
import { ApiTable } from '$utils' |
|||
|
|||
|
|||
export function addPatrolRecordIssueHandle(params) { |
|||
return (dispatch) => basicAction({ |
|||
type: 'post', |
|||
data: params, |
|||
dispatch, |
|||
actionType: 'ADD_PatrolRecordIssueHandle_REPORT', |
|||
url: ApiTable.addPatrolRecordIssueHandle, |
|||
msg: { |
|||
option: '维修计划新增', |
|||
}, |
|||
}); |
|||
} |
|||
|
|||
export function modifyPatrolRecordIssueHandle(id, params, msg) { |
|||
return (dispatch) => basicAction({ |
|||
type: 'put', |
|||
data: params, |
|||
dispatch, |
|||
actionType: 'MODIFY_PatrolRecordIssueHandle_REPORT', |
|||
url: ApiTable.modifyPatrolRecordIssueHandle.replace('{id}', id), |
|||
msg: { |
|||
option: msg || '维修计划审批', |
|||
}, |
|||
}); |
|||
} |
|||
|
@ -1,429 +0,0 @@ |
|||
import React, { useState, useRef } from 'react'; |
|||
import { Button, Form, Row, Col, Table, Popconfirm, Input, message } from 'antd'; |
|||
import { |
|||
ModalForm, |
|||
ProFormText, |
|||
ProFormSelect, |
|||
ProFormTextArea, |
|||
ProFormDatePicker, |
|||
ProFormDateRangePicker, |
|||
ProFormDependency |
|||
} from '@ant-design/pro-form'; |
|||
import Uploads from '$components/Uploads'; |
|||
import moment from 'moment'; |
|||
const FormItem = Form.Item; |
|||
//state: 1下发未上报 2已上报待审批 3整改完成 上报结果result: status 0 已上报未审批 1 审批通过 2 审批驳回
|
|||
export default (props) => { |
|||
const { title, triggerRender, editData = null, onFinish, readOnly, structsUsers, user } = props; |
|||
const users = structsUsers?.find(s => s.id == editData?.points?.project?.id)?.users?.map(v => { return { value: v.id, label: v.name, ...v } }) |
|||
const formItemLayout = { labelCol: { span: 7 }, wrapperCol: { span: 16 } }; |
|||
const formRef = useRef(); |
|||
|
|||
const initialValues = editData ? { |
|||
...editData, |
|||
...editData?.patrolRecordIssueHandles[0], |
|||
approvePerson: editData?.patrolRecordIssueHandles[0]?.approvePerson?.name || '', |
|||
approveDate: editData?.patrolRecordIssueHandles[0]?.approveDate ? moment(editData?.patrolRecordIssueHandles[0]?.approveDate).format('YYYY-MM-DD HH:mm:ss') : "", |
|||
repairPerson: users?.find(s => s.value == editData?.patrolRecordIssueHandles[0]?.repairPerson?.id) ? editData?.patrolRecordIssueHandles[0]?.repairPerson?.id : null, |
|||
checkPerson: users?.find(s => s.value == editData?.patrolRecordIssueHandles[0]?.checkPerson?.id) ? editData?.patrolRecordIssueHandles[0]?.checkPerson?.id : null, |
|||
} : {}; |
|||
if (editData?.patrolRecordIssueHandles?.length > 0) { |
|||
initialValues.dateRange = [editData?.patrolRecordIssueHandles[0]?.startTime, editData?.patrolRecordIssueHandles[0]?.endTime] |
|||
} |
|||
const [approve, setApprove] = useState('') |
|||
|
|||
const approveHandle = async (values) => { |
|||
onFinish && await onFinish({ |
|||
msg: approve ? '计划同意' : '计划驳回', |
|||
state: approve ? 4 : 3, |
|||
approveOpinion: values?.approveOpinion, |
|||
approvePerson: user, |
|||
approveDate: moment() |
|||
}, editData) |
|||
} |
|||
|
|||
const renderPlanInfo = () => { |
|||
return <> |
|||
{/* <Card title={'巡检信息'}> */} |
|||
<div className="item-title">{"巡检信息"}</div> |
|||
<Form> |
|||
<Row> |
|||
<Col span={12}> |
|||
<Form.Item label="结构物名称:" {...formItemLayout}> |
|||
<Input value={editData?.points?.project?.name} readOnly /> |
|||
</Form.Item> |
|||
<Form.Item label="巡检人:" {...formItemLayout}> |
|||
<Input value={editData?.points?.user?.name} readOnly /> |
|||
</Form.Item> |
|||
</Col> |
|||
<Col span={12}> |
|||
<Form.Item label="巡检单位:" {...formItemLayout}> |
|||
<Input value={editData?.points?.user?.department?.name} readOnly title={222} /> |
|||
</Form.Item> |
|||
|
|||
<Form.Item label="巡检时间:" {...formItemLayout}> |
|||
<Input value={editData?.inspectionTime && moment(editData?.inspectionTime).format('YYYY-MM-DD HH:mm:ss')} readOnly /> |
|||
</Form.Item> |
|||
</Col> |
|||
</Row> |
|||
</Form> |
|||
|
|||
<div className="item-title">{"问题详情"}</div> |
|||
<Row> |
|||
<Col span={12}> |
|||
<Form.Item label="点位名称:" {...formItemLayout}> |
|||
<Input value={editData?.points?.itemData?.name} readOnly /> |
|||
</Form.Item> |
|||
</Col> |
|||
</Row> |
|||
<Row> |
|||
<Col span={24}> |
|||
{ |
|||
editData?.points?.inspectContent && Array.isArray(editData?.points?.inspectContent) && |
|||
editData?.points?.inspectContent?.map(s => { |
|||
if (s?.alarm == true) { |
|||
return <> |
|||
{s?.deviceName && <Col span={12}> |
|||
<Form.Item label="设备名称:" {...formItemLayout}> |
|||
<Input value={s?.deviceName} readOnly /> |
|||
</Form.Item> |
|||
</Col>} |
|||
{ |
|||
s?.checkItems?.map(k => { |
|||
return <Row style={{ marginBottom: 15 }}> |
|||
<Col span={12}> |
|||
<Form.Item label="检查项:" {...formItemLayout}> |
|||
<Input value={k.name} readOnly /> |
|||
</Form.Item> |
|||
<Form.Item label="异常等级:" {...formItemLayout}> |
|||
<Input value={k?.level} readOnly /> |
|||
</Form.Item> |
|||
</Col> |
|||
<Col span={12}> |
|||
<Form.Item label="问题描述:" {...formItemLayout}> |
|||
<Input value={k?.msgInp} readOnly title={222} /> |
|||
</Form.Item> |
|||
|
|||
<Form.Item label="现场图片:" {...formItemLayout}> |
|||
<Uploads |
|||
listType='picture-card' |
|||
uploadType='project' |
|||
maxFilesNum={1} |
|||
maxFileSize={10} |
|||
isQiniu={true} |
|||
disabled={true} |
|||
fileTypes={["png", "jpg"]} |
|||
defaultValue={ |
|||
(() => { |
|||
let nextV = [] |
|||
for (let s of (k.imgs || [])) { |
|||
if (s) { |
|||
nextV.push({ |
|||
storageUrl: s |
|||
}) |
|||
} |
|||
} |
|||
return nextV |
|||
})() |
|||
} |
|||
/> |
|||
|
|||
</Form.Item> |
|||
</Col> |
|||
</Row> |
|||
}) |
|||
} |
|||
</> |
|||
|
|||
|
|||
} |
|||
}) |
|||
} |
|||
</Col> |
|||
</Row></> |
|||
} |
|||
|
|||
const renderRepairInfo = () => { |
|||
return <> |
|||
<div className="item-title">{"维修处理"}</div> |
|||
|
|||
<ProFormTextArea |
|||
name="repairDesc" |
|||
label="维修情况描述:" |
|||
disabled={true} |
|||
/> |
|||
|
|||
<Form.Item label="完工图片:"> |
|||
<Uploads |
|||
listType='picture-card' |
|||
uploadType='project' |
|||
maxFilesNum={1} |
|||
maxFileSize={10} |
|||
isQiniu={true} |
|||
disabled={true} |
|||
fileTypes={["png", "jpg"]} |
|||
defaultValue={ |
|||
(() => { |
|||
let nextV = [] |
|||
for (let s of (editData?.patrolRecordIssueHandles[0]?.repairImage || [])) { |
|||
if (s) { |
|||
nextV.push({ |
|||
storageUrl: s |
|||
}) |
|||
} |
|||
} |
|||
return nextV |
|||
})() |
|||
} |
|||
/> |
|||
|
|||
</Form.Item> |
|||
|
|||
</> |
|||
} |
|||
|
|||
const renderCheckInfo = () => { |
|||
return <> |
|||
<div className="item-title">{"质检验收"}</div> |
|||
|
|||
<ProFormTextArea |
|||
name="checkPerson1" |
|||
label="验收人:" |
|||
disabled={true} |
|||
value={editData?.patrolRecordIssueHandles[0]?.checkPerson?.name} |
|||
/> |
|||
|
|||
<ProFormText |
|||
name="checkPerson1" |
|||
label="成本(元):" |
|||
disabled={true} |
|||
value={editData?.patrolRecordIssueHandles[0]?.cost} |
|||
/> |
|||
|
|||
<Form.Item label="完工图片:"> |
|||
<Uploads |
|||
listType='picture-card' |
|||
uploadType='project' |
|||
maxFilesNum={1} |
|||
maxFileSize={10} |
|||
isQiniu={true} |
|||
disabled={true} |
|||
fileTypes={["png", "jpg"]} |
|||
defaultValue={ |
|||
(() => { |
|||
let nextV = [] |
|||
for (let s of (editData?.patrolRecordIssueHandles[0]?.checkImage || [])) { |
|||
if (s) { |
|||
nextV.push({ |
|||
storageUrl: s |
|||
}) |
|||
} |
|||
} |
|||
return nextV |
|||
})() |
|||
} |
|||
/> |
|||
</Form.Item> |
|||
|
|||
<ProFormTextArea |
|||
name="checkOpinion" |
|||
label="验收意见:" |
|||
disabled={true} |
|||
/> |
|||
|
|||
<ProFormTextArea |
|||
name="checkState" |
|||
label="验收结果:" |
|||
disabled={true} |
|||
value={editData?.patrolRecordIssueHandles[0]?.state == 6 ? '验收通过' : '验收不通过'} |
|||
/> |
|||
</> |
|||
} |
|||
return ( |
|||
<ModalForm |
|||
formRef={formRef} |
|||
title={title || ''} |
|||
initialValues={initialValues} |
|||
trigger={ |
|||
triggerRender ? triggerRender : <Button type="primary" > |
|||
{title || ''} |
|||
</Button> |
|||
} |
|||
width={1300} |
|||
layout="horizontal" |
|||
// grid={true}
|
|||
{...formItemLayout} |
|||
modalProps={{ |
|||
destroyOnClose: true, |
|||
// onCancel: () => { },
|
|||
bodyStyle: { height: 620, overflowY: 'auto' } |
|||
}} |
|||
onFinish={async (values) => { |
|||
if (editData?.patrolRecordIssueHandles[0]?.state === 2 && title == '审核') { |
|||
approveHandle(values) |
|||
return true; |
|||
} else { |
|||
values.repairUnit = values?.repairUnits; |
|||
values.startTime = values?.dateRange[0]; |
|||
values.endTime = values?.dateRange[1]; |
|||
values.repairPerson = { id: users?.find(s => s.value == values.repairPerson)?.value, name: users?.find(s => s.id == values.repairPerson)?.label } |
|||
values.checkPerson = { id: users?.find(s => s.value == values.checkPerson)?.value, name: users?.find(s => s.id == values.checkPerson)?.label } |
|||
onFinish && await onFinish(values, editData) |
|||
//message.success('提交成功');
|
|||
return true; |
|||
} |
|||
}} |
|||
|
|||
submitter={editData?.patrolRecordIssueHandles[0]?.state === 2 && title != '修改计划' && title != '查看详情' ? { |
|||
render: (props, defaultDoms) => { |
|||
return [ |
|||
<Button onClick={() => { |
|||
setApprove(1) |
|||
props.submit(); |
|||
}} type='primary'>确定</Button>, |
|||
<Button onClick={() => { |
|||
setApprove(0) |
|||
props.submit(); |
|||
}}>驳回</Button> |
|||
]; |
|||
} |
|||
} : (!readOnly)} |
|||
> |
|||
<div> |
|||
{/*问题记录信息*/} |
|||
{renderPlanInfo()} |
|||
|
|||
{/*问题处理计划表单*/} |
|||
{ |
|||
((editData?.patrolRecordIssueHandles[0]?.state == 1 && title != '查看详情') || editData?.patrolRecordIssueHandles[0]?.state > 1) && |
|||
<> |
|||
<div className="item-title">{"维修计划信息"}</div> |
|||
<Row> |
|||
<Col span={12}> |
|||
{!readOnly ? <ProFormSelect |
|||
rules={[{ required: true, message: '请选择维修人' }]} |
|||
options={users || []} |
|||
disabled={readOnly} |
|||
name="repairPerson" |
|||
label="维修人" |
|||
fieldProps={{ |
|||
showSearch: true |
|||
}} |
|||
/> : |
|||
<ProFormText |
|||
name="repairPerson1" |
|||
label="维修人:" |
|||
disabled={true} |
|||
value={editData?.patrolRecordIssueHandles[0]?.repairPerson?.name} |
|||
/> |
|||
} |
|||
</Col> |
|||
<Col span={12}> |
|||
<ProFormDependency name={['repairPerson']}> |
|||
{({ repairPerson }) => { |
|||
const department = users?.find(s => s.id == repairPerson)?.department?.name |
|||
|
|||
return ( |
|||
<ProFormText |
|||
disabled={true} |
|||
name="repairUnits" |
|||
label="维修单位" |
|||
placeholder="" |
|||
fieldProps={{ |
|||
showSearch: true |
|||
}} |
|||
colProps={{ |
|||
span: 12, |
|||
}} |
|||
value={department} |
|||
/> |
|||
); |
|||
}} |
|||
</ProFormDependency> |
|||
|
|||
</Col> |
|||
|
|||
<Col span={12}> |
|||
<ProFormDateRangePicker |
|||
disabled={readOnly} |
|||
name="dateRange" |
|||
label="计划开始时间~结束时间:" |
|||
rules={[{ required: true, message: '请选择计划时间范围' }]} |
|||
/> |
|||
</Col> |
|||
<Col span={12}> |
|||
{!readOnly ? <ProFormSelect |
|||
rules={[{ required: true, message: '请选择质检人' }]} |
|||
options={users || []} |
|||
disabled={readOnly} |
|||
name="checkPerson" |
|||
label="质检人" |
|||
fieldProps={{ |
|||
showSearch: true |
|||
}} |
|||
/> : <ProFormText |
|||
name="checkPerson1" |
|||
label="质检人:" |
|||
disabled={true} |
|||
value={editData?.patrolRecordIssueHandles[0]?.checkPerson?.name} |
|||
/>} |
|||
</Col> |
|||
<Col span={12}> |
|||
<ProFormTextArea |
|||
name="repairAsk" |
|||
label="维修要求:" |
|||
disabled={readOnly} |
|||
rules={[ |
|||
{ |
|||
max: 200, message: '维修要求长度不能大于200个字符' |
|||
}, |
|||
{ |
|||
whitespace: true, message: '请勿输入空格' |
|||
}]} |
|||
placeholder="" |
|||
/></Col> |
|||
{editData?.patrolRecordIssueHandles[0]?.state && editData?.patrolRecordIssueHandles[0]?.state > 3 && <Col span={12}> |
|||
<ProFormText |
|||
name="approvePerson" |
|||
label="制定人:" |
|||
disabled={true} |
|||
/> |
|||
<ProFormText |
|||
name="approveDate" |
|||
label="制定时间:" |
|||
disabled={true} |
|||
/> |
|||
</Col>} |
|||
</Row> |
|||
</> |
|||
} |
|||
|
|||
{ |
|||
((editData?.patrolRecordIssueHandles[0]?.state > 2) || title == '审核') && |
|||
<> |
|||
<div className="item-title">{"维修计划审批"}</div> |
|||
<div> |
|||
<ProFormTextArea |
|||
name="approveOpinion" |
|||
label="审批意见:" |
|||
disabled={title != '审核'} |
|||
rules={[ |
|||
{ required: true, message: '请输入审批意见' }, |
|||
{ |
|||
max: 200, message: '审批意见长度不能大于200个字符' |
|||
}, |
|||
{ |
|||
whitespace: true, message: '请勿输入空格' |
|||
}]} |
|||
placeholder="请输入审批意见" |
|||
/> |
|||
</div> |
|||
</> |
|||
} |
|||
|
|||
{(editData?.patrolRecordIssueHandles[0]?.state && editData?.patrolRecordIssueHandles[0]?.state > 4) && renderRepairInfo()} |
|||
{(editData?.patrolRecordIssueHandles[0]?.state && editData?.patrolRecordIssueHandles[0]?.state > 5) && renderCheckInfo()} |
|||
</div> |
|||
</ ModalForm> |
|||
); |
|||
}; |
@ -1,5 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
import PatrolReocrd from './patrolRecord'; |
|||
|
|||
export { PatrolReocrd }; |
@ -1,268 +0,0 @@ |
|||
|
|||
'use strict' |
|||
|
|||
import React, { useEffect, useState } from 'react'; |
|||
import { connect } from 'react-redux'; |
|||
import { Form, Input, Select, Button, Table, Modal, DatePicker, Checkbox, Row, Col, Collapse } from 'antd'; |
|||
import moment from "moment"; |
|||
import Uploads from '$components/Uploads'; |
|||
import IssueHandleModal from '../components/isuue-handle-mdal' |
|||
import '../style.less' |
|||
import { useFsRequest, ApiTable, Func } from '$utils'; |
|||
|
|||
const { Panel } = Collapse; |
|||
const ISSUEHANDLE_STATE = [1, 2, 3, 4, 5, 6, 7] |
|||
const STATE_TEXT = { 1: '待制定计划', 2: '待审核', 3: '计划驳回', 4: '待维修', 5: '待验收', 6: '验收通过', 7: '验收不通过', } |
|||
|
|||
const PatrolRecord = (props) => { |
|||
const { dispatch, actions, user } = props |
|||
const { patrolManage, issueHandle } = actions |
|||
const [tableList, settableList] = useState([]) |
|||
const [name, setName] = useState(''); |
|||
const [curState, setCurState] = useState('全部'); |
|||
const format = 'YYYY-MM-DD HH:mm:ss' |
|||
const times = [moment().subtract(70, 'years').format(format), moment().format(format)] |
|||
const [search, setSearch] = useState({ name: null, time: [times[0], times[1]], state: 'null' }) |
|||
|
|||
const { data: structsUsers = [] } = useFsRequest({ url: 'structures/users' }); |
|||
useEffect(() => { |
|||
queryData() |
|||
}, []) |
|||
|
|||
const queryData = () => { |
|||
dispatch(patrolManage.records(`patrolRecord/all/${times[0]}/${times[1]}/true/null`)).then(res => { |
|||
if (res.success) { |
|||
settableList(name != null ? res.payload.data |
|||
?.filter(v => (v.points.itemData.name.indexOf(name) != -1 || v.points.project.name.indexOf(name) != -1)) |
|||
.filter(x => curState == '全部' || curState == renderOptionText(x?.patrolRecordIssueHandles[0]?.state)) |
|||
.map(v => ({ ...v, key: v.id })) : res.payload.data?.map(v => ({ ...v, key: v.id }))) |
|||
} |
|||
}) |
|||
} |
|||
const onFinish = async (values, editData) => { |
|||
const dataToSave = { ...values }; |
|||
if (editData?.patrolRecordIssueHandles?.length > 0) { |
|||
let msg = ''; |
|||
if (editData?.patrolRecordIssueHandles[0]?.state == 3) { |
|||
dataToSave.state = 2; |
|||
msg = '维修计划修改'; |
|||
} |
|||
|
|||
if (editData?.patrolRecordIssueHandles[0]?.state == 1) { |
|||
dataToSave.state = 2; |
|||
dataToSave.creator = user; |
|||
dataToSave.createTime = moment(); |
|||
msg = '计划制定'; |
|||
} |
|||
return dispatch( |
|||
issueHandle.modifyPatrolRecordIssueHandle(editData?.patrolRecordIssueHandles[0]?.id, dataToSave, |
|||
values?.msg || msg), |
|||
).then(() => { |
|||
queryData(); |
|||
}); |
|||
} |
|||
let state = ISSUEHANDLE_STATE[1]; |
|||
|
|||
return dispatch(issueHandle.addPatrolRecordIssueHandle({ |
|||
...dataToSave, |
|||
state, |
|||
patrolRecordId: editData?.id, |
|||
creator: user, |
|||
createTime: moment() |
|||
})).then(() => { |
|||
queryData(); |
|||
}); |
|||
}; |
|||
|
|||
const renderOptionText = (currentState) => { |
|||
let text = '待制定计划' |
|||
|
|||
return STATE_TEXT[currentState] || text |
|||
} |
|||
|
|||
const columns = [ |
|||
{ |
|||
title: '结构物名称', |
|||
dataIndex: 'name', |
|||
key: 'name', |
|||
width: '10%', |
|||
showInDetail: true, |
|||
render: (text, record, index) => { |
|||
return !record.points?.project ? '' : <div>{record.points.project.name}</div> |
|||
} |
|||
}, |
|||
{ |
|||
title: '上报人', |
|||
dataIndex: 'type', |
|||
key: 'type', |
|||
showInDetail: true, |
|||
width: '10%', |
|||
render: (text, record, index) => { |
|||
return !record.points?.user ? '' : <div>{record.points.user.name}</div> |
|||
} |
|||
}, |
|||
{ |
|||
title: '上报时间', |
|||
dataIndex: 'time', |
|||
key: 'time', |
|||
showInDetail: true, |
|||
render: (text, record, index) => moment(record.inspectionTime).format('YYYY-MM-DD HH:mm:ss') || '--' |
|||
}, { |
|||
title: '点位名称', |
|||
dataIndex: 'station', |
|||
key: 'station', |
|||
showInDetail: true, |
|||
render: (text, record, index) => record?.points?.itemData?.name |
|||
}, |
|||
{ |
|||
title: '问题来源', |
|||
dataIndex: 'source', |
|||
key: 'source', |
|||
showInDetail: true, |
|||
render: (text, record, index) => record?.patrolPlanId == -1 ? '主动上报' : '巡检上报' //暂定巡检上报 后续会增加平台录入
|
|||
}, |
|||
{ |
|||
title: '严重等级', |
|||
dataIndex: 'level', |
|||
key: 'level', |
|||
showInDetail: true, |
|||
render: (text, record, index) => { |
|||
const LEVELS_ = ['严重', '中度', '轻微']; |
|||
const recordLevels = [] |
|||
record?.points?.inspectContent ? Object.keys(record?.points?.inspectContent).map(key => { |
|||
recordLevels.push(record?.points?.inspectContent[key]?.level) |
|||
}) : '' |
|||
|
|||
|
|||
if (Array.isArray(record?.points?.inspectContent)) { |
|||
record?.points?.inspectContent?.map(x => { |
|||
x.checkItems?.map(v => { |
|||
recordLevels.push(v?.level) |
|||
}) |
|||
}) |
|||
} |
|||
|
|||
const level = LEVELS_.find(s => recordLevels.find(x => x == s)) |
|||
return level || '-'; |
|||
} |
|||
}, |
|||
{ |
|||
title: '当前状态', |
|||
dataIndex: 'state', |
|||
key: 'name', |
|||
width: '10%', |
|||
showInDetail: true, |
|||
render: (text, record, index) => { |
|||
return !record?.patrolRecordIssueHandles || record?.patrolRecordIssueHandles?.length == 0 ? '待制定计划' : |
|||
renderOptionText(record?.patrolRecordIssueHandles[0]?.state) |
|||
} |
|||
}, |
|||
{ |
|||
title: '操作', |
|||
dataIndex: 'operation', |
|||
key: 'operation', |
|||
render: (text, record, index) => { |
|||
const options = []; |
|||
if (Func.isAuthorized('ZHIDINGJIHUA') && (!record?.patrolRecordIssueHandles || record?.patrolRecordIssueHandles?.length == 0 || record?.patrolRecordIssueHandles[0]?.state == 1)) { |
|||
options.push(<IssueHandleModal |
|||
structsUsers={structsUsers} |
|||
editData={record} |
|||
readOnly={false} |
|||
key="edit" |
|||
title="制定计划" |
|||
triggerRender={<a style={{ marginRight: 8 }}>制定计划</a>} |
|||
user={user} |
|||
onFinish={onFinish} />) |
|||
} |
|||
|
|||
if (Func.isAuthorized('ZHIDINGJIHUA') && (record?.patrolRecordIssueHandles[0]?.state == 3 || record?.patrolRecordIssueHandles[0]?.state == 2)) { |
|||
options.push(<IssueHandleModal |
|||
structsUsers={structsUsers} |
|||
editData={record} |
|||
readOnly={false} |
|||
key="edit" |
|||
title="修改计划" |
|||
triggerRender={<a style={{ marginRight: 8 }}>修改计划</a>} |
|||
user={user} |
|||
onFinish={onFinish} />) |
|||
} |
|||
|
|||
if (Func.isAuthorized('SHENHE') && record?.patrolRecordIssueHandles[0]?.state == 2) { |
|||
options.push(<IssueHandleModal |
|||
structsUsers={structsUsers} |
|||
editData={record} |
|||
readOnly={true} |
|||
key="edit" |
|||
title="审核" |
|||
triggerRender={<a style={{ marginRight: 8 }}>审核</a>} |
|||
user={user} |
|||
onFinish={onFinish} />) |
|||
} |
|||
|
|||
|
|||
Func.isAuthorized('CHAKANXIANGQING') && options.push(<IssueHandleModal |
|||
structsUsers={structsUsers} |
|||
editData={record} |
|||
readOnly={true} |
|||
key="edit" |
|||
title="查看详情" |
|||
triggerRender={<a>查看详情</a>} |
|||
user={user} |
|||
onFinish={onFinish} />) |
|||
|
|||
return options; |
|||
} |
|||
} |
|||
] |
|||
|
|||
return ( |
|||
<div id='patrol-record' className='global-main'> |
|||
<div style={{ marginBottom: 20, display: 'flex', justifyContent: 'space-between' }}> |
|||
<div className='title'> |
|||
<span className='line'></span> |
|||
<span className='cn'>问题处理</span> |
|||
<span className='en'> PROBLEM HANDLING</span> |
|||
</div> |
|||
<div> |
|||
<Input style={{ width: 240, marginRight: 20 }} |
|||
value={name} onChange={e => { setName(e.target.value) }} |
|||
placeholder="请输入结构物名称或点位名称" allowClear /> |
|||
<Select |
|||
value={curState} |
|||
onChange={e => { setCurState(e) }} |
|||
style={{ width: 140, marginRight: 20 }} |
|||
options={[ |
|||
{ value: '全部', label: '全部' }, |
|||
].concat(ISSUEHANDLE_STATE.map(s => { |
|||
return { value: renderOptionText(s), label: renderOptionText(s) } |
|||
}))} /> |
|||
<Button type='primary' onClick={() => { queryData() }}>搜索</Button> |
|||
</div> |
|||
</div> |
|||
<Table |
|||
columns={columns} |
|||
dataSource={tableList} |
|||
pagination={{ |
|||
showSizeChanger: true, |
|||
pageSizeOptions: [10, 20, 50], |
|||
className: 'global-pagination', |
|||
}} |
|||
rowClassName={(record, index) => { |
|||
let className = 'global-light-row'; |
|||
if (index % 2 === 1) className = 'global-dark-row'; |
|||
return className; |
|||
}} |
|||
/> |
|||
</div> |
|||
) |
|||
} |
|||
|
|||
function mapStateToProps(state) { |
|||
const { auth, global } = state; |
|||
return { |
|||
user: auth.user, |
|||
actions: global.actions, |
|||
}; |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(PatrolRecord); |
@ -1,15 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
import reducers from './reducers'; |
|||
import routes from './routes'; |
|||
import actions from './actions'; |
|||
import { getNavItem } from './nav-item'; |
|||
|
|||
export default { |
|||
key: 'issueHandle', |
|||
name: '', |
|||
reducers: reducers, |
|||
routes: routes, |
|||
actions: actions, |
|||
getNavItem: getNavItem |
|||
}; |
@ -1,21 +0,0 @@ |
|||
import React from 'react'; |
|||
import { Link } from 'react-router-dom'; |
|||
import { Menu } from 'antd'; |
|||
import { CompressOutlined } from '@ant-design/icons'; |
|||
import { Func } from '$utils'; |
|||
const SubMenu = Menu.SubMenu; |
|||
|
|||
export function getNavItem(user, dispatch) { |
|||
// if (!Func.isAuthorized("ORG_MANAGE")) {
|
|||
// return null
|
|||
// }
|
|||
return ( |
|||
(Func.isAuthorized("SHENHE") |
|||
|| Func.isAuthorized("ZHIDINGJIHUA") |
|||
|| Func.isAuthorized("CHAKANXIANGQING")) && |
|||
<Menu.Item icon={<img src='/assets/images/menu/issue.svg' style={{ width: 24, height: 24 }} />} key="issueHandle"> |
|||
<Link to="/issueHandle">问题处理</Link> |
|||
</Menu.Item> |
|||
|
|||
); |
|||
} |
@ -1,5 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
export default { |
|||
|
|||
}; |
@ -1,32 +0,0 @@ |
|||
'use strict'; |
|||
import * as actionTypes from '../actions/record'; |
|||
import Immutable from 'immutable'; |
|||
|
|||
const initState = { |
|||
data: {}, |
|||
isRequesting: false, |
|||
error: null |
|||
}; |
|||
|
|||
function record(state = initState, action) { |
|||
const payload = action.payload; |
|||
switch (action.type){ |
|||
case actionTypes.GET_PATROL_RECORD_LIST: |
|||
return Immutable.fromJS(state).set('data', |
|||
payload.data).toJS(); |
|||
case actionTypes.GET_PATROL_RECORD_LIST_SUCCESS: |
|||
return Immutable.fromJS(state).merge({ |
|||
isRequesting: false, |
|||
data: payload.data |
|||
}).toJS(); |
|||
case actionTypes.GET_PATROL_RECORD_LIST_ERROR: |
|||
return Immutable.fromJS(state).merge({ |
|||
isRequesting: false, |
|||
error: payload.error |
|||
}).toJS(); |
|||
default: |
|||
return state; |
|||
} |
|||
} |
|||
|
|||
export default record; |
@ -1,13 +0,0 @@ |
|||
'use strict'; |
|||
import { PatrolReocrd } from './containers'; |
|||
|
|||
export default [{ |
|||
type: 'inner', |
|||
route: { |
|||
path: '/issueHandle', |
|||
key: 'issueHandle', |
|||
breadcrumb: '问题处理', |
|||
component: PatrolReocrd, |
|||
|
|||
} |
|||
}]; |
@ -1,13 +0,0 @@ |
|||
.patrol-record-detail-modal { |
|||
.ant-collapse>.ant-collapse-item>.ant-collapse-header { |
|||
padding: 0 |
|||
} |
|||
} |
|||
|
|||
.item-title { |
|||
background-color: #4A93DF; |
|||
padding: 10px; |
|||
color: #fff; |
|||
margin-bottom: 20px; |
|||
padding-left: 20px; |
|||
} |
@ -1,51 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
import { basicAction } from '@peace/utils' |
|||
import { ApiTable } from '$utils' |
|||
|
|||
export function getAuthority(orgId) { |
|||
return dispatch => basicAction({ |
|||
type: 'get', |
|||
dispatch: dispatch, |
|||
actionType: 'GET_MEMBERS', |
|||
url: `${ApiTable.getEnterprisesMembers.replace('{enterpriseId}', orgId)}`, |
|||
msg: { error: '获取用户列表失败' }, |
|||
reducer: { name: 'members' } |
|||
}); |
|||
} |
|||
export function getResource(userId) { |
|||
return dispatch => basicAction({ |
|||
type: 'get', |
|||
dispatch: dispatch, |
|||
actionType: 'GET_RESOURCE', |
|||
url: `${ApiTable.getResource}`, |
|||
msg: { error: '获取权限失败' }, |
|||
reducer: { name: 'resource' } |
|||
}); |
|||
} |
|||
export function getUserResource(userId) { |
|||
return dispatch => basicAction({ |
|||
type: 'get', |
|||
dispatch: dispatch, |
|||
actionType: 'GET_USER_RESOURCE', |
|||
url: `${ApiTable.getUserResource}?userId=${userId}`, |
|||
msg: { error: '获取用户权限失败' }, |
|||
reducer: { name: 'userResource' } |
|||
}); |
|||
} |
|||
export function postUserRes(body) { |
|||
return dispatch => basicAction({ |
|||
type: 'post', |
|||
dispatch: dispatch, |
|||
actionType: 'UPDATE_USER_RESOURCE', |
|||
url: `${ApiTable.postUserRes}`, |
|||
data: body, |
|||
msg: { success: '更新用户权限' } |
|||
}); |
|||
} |
|||
export default { |
|||
getAuthority, |
|||
getResource, |
|||
getUserResource, |
|||
postUserRes |
|||
} |
@ -1,11 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
import * as authority from './authority' |
|||
import { getDepMessage, getDepUser, createUser } from './user' |
|||
|
|||
export default { |
|||
...authority, |
|||
getDepMessage, |
|||
getDepUser, |
|||
createUser, |
|||
} |
@ -1,113 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
import { basicAction } from '@peace/utils' |
|||
import { ApiTable } from '$utils' |
|||
|
|||
export function getDepMessage() { |
|||
return dispatch => basicAction({ |
|||
type: 'get', |
|||
dispatch: dispatch, |
|||
actionType: 'GET_DEPARTMENT_MESSAGE', |
|||
url: ApiTable.getDepMessage, |
|||
msg: { error: '获取部门信息失败' }, |
|||
reducer: { name: 'depMessage' } |
|||
}); |
|||
} |
|||
|
|||
//新建部门
|
|||
export function createDept(data) { |
|||
return dispatch => basicAction({ |
|||
type: 'post', |
|||
data, |
|||
dispatch: dispatch, |
|||
actionType: 'CREATE_DEPT', |
|||
url: ApiTable.createDept, |
|||
msg: { option: '新建部门' }, |
|||
}); |
|||
} |
|||
|
|||
//修改部门
|
|||
export function updateDept(id, data) { |
|||
return dispatch => basicAction({ |
|||
type: 'put', |
|||
data, |
|||
dispatch: dispatch, |
|||
actionType: 'UPDATE_DEPT', |
|||
url: ApiTable.updateDept.replace('{id}', id), |
|||
msg: { option: '修改部门' }, |
|||
}); |
|||
} |
|||
|
|||
//删除部门
|
|||
export function delDept(id) { |
|||
return dispatch => basicAction({ |
|||
type: 'del', |
|||
dispatch: dispatch, |
|||
actionType: 'DEL_DEPT', |
|||
url: ApiTable.delDept.replace('{id}', id), |
|||
msg: { option: '删除部门' }, |
|||
}); |
|||
} |
|||
|
|||
export function getDepUser(depId) { |
|||
return dispatch => basicAction({ |
|||
type: 'get', |
|||
dispatch: dispatch, |
|||
actionType: 'GET_DEPARTMENT_USER', |
|||
url: ApiTable.getDepUser.replace('{depId}', depId), |
|||
msg: { error: '获取部门下用户信息失败' }, |
|||
reducer: { name: 'depUser' } |
|||
}); |
|||
} |
|||
|
|||
export function createUser(data) { |
|||
return dispatch => basicAction({ |
|||
type: 'post', |
|||
data, |
|||
dispatch: dispatch, |
|||
actionType: 'CREATE_DEPARTMENT_USER', |
|||
url: ApiTable.createUser, |
|||
msg: { option: '新建用户' }, |
|||
}); |
|||
} |
|||
|
|||
export function updateUser(id, data) { |
|||
return dispatch => basicAction({ |
|||
type: 'put', |
|||
data, |
|||
dispatch: dispatch, |
|||
actionType: 'UPDATE_DEPARTMENT_USER', |
|||
url: ApiTable.updateUser.replace('{id}', id), |
|||
msg: { option: '修改用户' }, |
|||
}); |
|||
} |
|||
|
|||
export function delUser(ids) { |
|||
return dispatch => basicAction({ |
|||
type: 'del', |
|||
dispatch: dispatch, |
|||
actionType: 'DEL_DEPARTMENT_USER', |
|||
url: ApiTable.delUser.replace('{ids}', ids), |
|||
msg: { option: '删除用户' }, |
|||
}); |
|||
} |
|||
|
|||
export function resetPwd(id, data) { |
|||
return dispatch => basicAction({ |
|||
type: 'put', |
|||
data, |
|||
dispatch: dispatch, |
|||
actionType: 'CREATE_DEPARTMENT_USER', |
|||
url: ApiTable.resetPwd.replace('{id}', id), |
|||
msg: { option: '重置用户密码' }, |
|||
}); |
|||
} |
|||
|
|||
export default { |
|||
getDepMessage, |
|||
getDepUser, |
|||
createUser, |
|||
updateUser, |
|||
delUser, |
|||
resetPwd |
|||
} |
@ -1,88 +0,0 @@ |
|||
import React from 'react'; |
|||
import { connect } from 'react-redux'; |
|||
import { ProFormText, ModalForm, ProFormSelect } from '@ant-design/pro-form'; |
|||
|
|||
const DeptModal = (props) => { |
|||
const { visible, modalType, onVisibleChange, onConfirm, editData, depts } = props |
|||
let deptOptions = [], sonArr = []; |
|||
depts.map(d => { |
|||
deptOptions.push({ |
|||
value: d.id, |
|||
label: d.name |
|||
}); |
|||
|
|||
d.subordinate.map(ds => { |
|||
sonArr.push({ |
|||
value: ds.id, |
|||
label: ds.name |
|||
}) |
|||
}) |
|||
}) |
|||
const onFinish = (values) => { |
|||
if (onConfirm) { |
|||
if (modalType === 'edit') { |
|||
values.contract.parentDeptId = values.contract.parentDeptId || null |
|||
onConfirm(values) |
|||
} else { |
|||
onConfirm(values); |
|||
} |
|||
} |
|||
} |
|||
|
|||
const checkName = (rule, value, callback) => { |
|||
const list = modalType == 'edit' ? deptOptions.concat(sonArr).filter(g => g.value != editData.id) : deptOptions.concat(sonArr) |
|||
if (list.filter(s => s.label == value).length) { |
|||
callback('该名称已存在'); |
|||
} else { |
|||
callback(); |
|||
} |
|||
} |
|||
|
|||
return ( |
|||
<ModalForm |
|||
width={400} |
|||
title={modalType == 'edit' ? '编辑部门' : '新建部门'} |
|||
visible={visible} |
|||
onVisibleChange={onVisibleChange} |
|||
onFinish={onFinish} |
|||
destroyOnClose |
|||
initialValues={ |
|||
modalType == 'edit' ? |
|||
{ |
|||
contract: editData |
|||
} : |
|||
{ |
|||
contract: { |
|||
enable: true |
|||
} |
|||
} |
|||
} |
|||
> |
|||
<ProFormText |
|||
name={['contract', 'name']} |
|||
maxLength={24} |
|||
width="md" |
|||
label="部门名称" |
|||
required |
|||
placeholder="请输入部门名称" |
|||
rules={[{ required: true, message: '请输入部门名称' }, { validator: checkName }]} |
|||
/> |
|||
<ProFormSelect |
|||
name={['contract', 'dependence']} |
|||
label="上级部门" |
|||
request={async () => { |
|||
let t = modalType === 'edit' ? deptOptions.filter(i => i.value !== editData.id) : deptOptions |
|||
return t |
|||
}} |
|||
disabled={modalType === 'edit' ? editData.subordinate?.length === 0 ? false : true : false} |
|||
/> |
|||
</ModalForm> |
|||
) |
|||
} |
|||
|
|||
function mapStateToProps(state) { |
|||
return { |
|||
}; |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(DeptModal); |
@ -1,74 +0,0 @@ |
|||
import React, { useRef, useState } from 'react'; |
|||
import { connect } from 'react-redux'; |
|||
import { Spin, Card, Modal, TreeSelect } from 'antd'; |
|||
import ProForm, { ProFormText, ModalForm, ProFormSwitch, ProFormTreeSelect } from '@ant-design/pro-form'; |
|||
|
|||
const ResetPwd = (props) => { |
|||
const { visible, onVisibleChange, onConfirm } = props; |
|||
const formRef = useRef(); |
|||
|
|||
const onFinish = (values) => { |
|||
if (onConfirm) { |
|||
onConfirm(values); |
|||
} |
|||
} |
|||
|
|||
return ( |
|||
<Spin spinning={false}> |
|||
<ModalForm |
|||
title={'重置密码'} |
|||
visible={visible} |
|||
onVisibleChange={onVisibleChange} |
|||
onFinish={onFinish} |
|||
formRef={formRef} |
|||
destroyOnClose |
|||
> |
|||
<ProFormText.Password |
|||
name={['password']} |
|||
width="md" |
|||
label="新密码" |
|||
required |
|||
placeholder="请输入密码" |
|||
fieldProps={{ |
|||
autocomplete: 'new-password' |
|||
}} |
|||
rules={[ |
|||
{ required: true, message: '请填写密码' }, |
|||
{ min: 6, message: '请填写至少6位密码' }, |
|||
]} |
|||
/> |
|||
<ProFormText.Password |
|||
name={['checkPassword']} |
|||
width="md" |
|||
label="确认密码" |
|||
required |
|||
autocomplete='off' |
|||
placeholder="请输入密码" |
|||
rules={[ |
|||
{ required: true, message: '请再次填写密码' }, |
|||
{ min: 6, message: '请填写至少6位密码' }, |
|||
{ |
|||
validator: (rule, value, callback) => { |
|||
const pwd = formRef.current.getFieldValue('password'); |
|||
if (!value) { |
|||
callback(); |
|||
} |
|||
if (pwd == value) { |
|||
callback(); |
|||
} else { |
|||
callback('两次输入的密码不一致'); |
|||
} |
|||
} |
|||
} |
|||
]} |
|||
/> |
|||
</ModalForm> |
|||
</Spin> |
|||
) |
|||
} |
|||
|
|||
function mapStateToProps(state) { |
|||
return {}; |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(ResetPwd); |
@ -1,126 +0,0 @@ |
|||
import React, { useEffect } from 'react'; |
|||
import { Checkbox, Table } from 'antd'; |
|||
import { useState } from 'react'; |
|||
|
|||
const CheckboxGroup = Checkbox.Group; |
|||
|
|||
const Resource = props => { |
|||
const { roleData, userRole, userSelected, setResCode, userType } = props; |
|||
const [indeterminate, setIndeterminate] = useState({}); |
|||
const [roleCheck, setRoleCheck] = useState({});//一级权限码
|
|||
const [parentRoleCheck, setParentRoleCheck] = useState({}); //二级权限码
|
|||
|
|||
const roleDatas = roleData.slice(0) |
|||
useEffect(() => { |
|||
const check = {} |
|||
const parentCheck = {} |
|||
const initInd = {} |
|||
roleData && roleData.map && roleData.map(r => { |
|||
let currentInd = false; |
|||
let sum = 0; |
|||
if (r.resources) { |
|||
check[r.code] = [] |
|||
r.resources.map(child => { |
|||
if (userRole.find(code => code.resourceId == child.code)) { |
|||
currentInd = true; |
|||
sum++; |
|||
check[r.code].push(child.code); |
|||
} |
|||
}) |
|||
} |
|||
parentCheck[r.code] = r.resources.length === sum |
|||
initInd[r.code] = parentCheck[r.code] ? false : currentInd |
|||
}); |
|||
setParentRoleCheck(parentCheck) |
|||
setRoleCheck(check); |
|||
setIndeterminate(initInd); |
|||
}, [userRole]); |
|||
|
|||
const setResData = (role) => { |
|||
let codes = []; |
|||
// Object.keys(partRole).map(r => {
|
|||
// if (partRole[r]) codes.push(r)
|
|||
// })
|
|||
Object.keys(role).map(r => { |
|||
if (role[r].length) { |
|||
codes.push(r); |
|||
} |
|||
codes = codes.concat(role[r]) |
|||
}) |
|||
setResCode(codes) |
|||
} |
|||
return ( |
|||
<Table |
|||
bordered |
|||
pagination={false} |
|||
dataSource={roleDatas} |
|||
rowClassName={(record, index) => { |
|||
let className = 'global-light-row'; |
|||
if (index % 2 === 1) className = 'global-dark-row'; |
|||
return className; |
|||
}} |
|||
columns={[{ |
|||
title: '功能', |
|||
key: 'name', |
|||
dataIndex: 'name', |
|||
render: (text, record) => { |
|||
const parentCode = record.code |
|||
return <Checkbox |
|||
|
|||
indeterminate={indeterminate[parentCode]} |
|||
onChange={(e) => { |
|||
const currentParCheck = JSON.parse(JSON.stringify(parentRoleCheck)); |
|||
currentParCheck[parentCode] = e.target.checked; |
|||
const currentCode = JSON.parse(JSON.stringify(roleCheck)); |
|||
currentCode[parentCode] = e.target.checked ? roleData.find(r => r.code == parentCode).resources.map(r => r.code) : [] |
|||
const currentInd = JSON.parse(JSON.stringify(indeterminate)); |
|||
currentInd[parentCode] = false; |
|||
|
|||
setParentRoleCheck(currentParCheck); |
|||
setRoleCheck(currentCode); |
|||
setIndeterminate(currentInd); |
|||
setResData(currentCode) |
|||
}} |
|||
checked={parentRoleCheck[parentCode] || false} |
|||
disabled={userSelected === "SuperAdmin" || userType === 4} |
|||
options={''} |
|||
> |
|||
{text} |
|||
</Checkbox> |
|||
} |
|||
}, { |
|||
title: '列表', |
|||
key: 'resources', |
|||
dataIndex: 'resources', |
|||
render: (text, record) => { |
|||
let data = []; |
|||
console.log() |
|||
text.map(s => { s.name !== "整治汇总编辑" ? data.push({ label: s.name, value: s.code }) : '' }) |
|||
let parentCode = record.code; |
|||
|
|||
return <CheckboxGroup |
|||
disabled={userSelected === "SuperAdmin" || userType === 4} |
|||
options={data} |
|||
value={roleCheck[parentCode] || []} |
|||
onChange={value => { |
|||
const checkArr = JSON.parse(JSON.stringify(roleCheck)); |
|||
const parentCheck = JSON.parse(JSON.stringify(parentRoleCheck)); |
|||
const ind = JSON.parse(JSON.stringify(indeterminate)); |
|||
const currentCode = roleData.find(r => r.code == parentCode) || {} |
|||
|
|||
checkArr[parentCode] = value; |
|||
ind[parentCode] = !!value.length && value.length < currentCode.resources.length |
|||
parentCheck[parentCode] = value.length === currentCode.resources.length |
|||
|
|||
setRoleCheck(checkArr); |
|||
setIndeterminate(ind); |
|||
setParentRoleCheck(parentCheck); |
|||
setResData(checkArr) |
|||
}} |
|||
/> |
|||
} |
|||
}]} |
|||
></Table > |
|||
) |
|||
} |
|||
export default Resource |
@ -1,237 +0,0 @@ |
|||
import React from 'react'; |
|||
import { connect } from 'react-redux'; |
|||
import { Spin, Card, Modal, TreeSelect, message } from 'antd'; |
|||
import ProForm, { ProFormText, ModalForm, ProFormSwitch, ProFormTreeSelect, ProFormSelect } from '@ant-design/pro-form'; |
|||
|
|||
const UserModal = (props) => { |
|||
const { visible, modalType, depData, onVisibleChange, onConfirm, editData, tableList } = props |
|||
const reg_tel = /^1([358][0-9]|4[579]|66|7[0135678]|9[89])[0-9]{8}$/; |
|||
const onFinish = (values) => { |
|||
if (onConfirm) { |
|||
onConfirm(values); |
|||
} |
|||
} |
|||
const mobile = (value) => { |
|||
if (reg_tel.test(value)) { |
|||
return |
|||
} |
|||
return message('请输入姓名') |
|||
} |
|||
return ( |
|||
<Spin spinning={false}> |
|||
<ModalForm |
|||
modalProps={{ |
|||
className: "global-modal-form", |
|||
}} |
|||
layout="horizontal" |
|||
grid={true} |
|||
width={800} |
|||
title={modalType == 'edit' ? '编辑用户' : '新建用户'} |
|||
visible={visible} |
|||
onVisibleChange={onVisibleChange} |
|||
onFinish={onFinish} |
|||
destroyOnClose |
|||
initialValues={ |
|||
modalType == 'edit' ? |
|||
{ |
|||
contract: editData |
|||
} : |
|||
{ |
|||
contract: { |
|||
enable: true, |
|||
role: '巡检人员' |
|||
}, |
|||
} |
|||
} |
|||
> |
|||
<ProForm.Group> |
|||
<ProFormText |
|||
name={['contract', 'name']} |
|||
colProps={{ md: 12, xl: 12 }} |
|||
maxLength={24} |
|||
label="姓名" |
|||
required |
|||
placeholder="请输入姓名" |
|||
rules={[{ required: true, message: '请输入姓名' }]} |
|||
bordered={false} |
|||
/> |
|||
<ProFormText |
|||
name={['contract', 'phone']} |
|||
colProps={{ md: 12, xl: 12 }} |
|||
label="用户名(手机号)" |
|||
required |
|||
fieldProps={{ |
|||
maxLength: 11, |
|||
}} |
|||
getValueFromEvent={(event) => { |
|||
return event.target.value.replace(/\D/g, '') |
|||
}} |
|||
placeholder="请输入用户名(手机号)" |
|||
rules={[ |
|||
{ required: true, valueType: Number, max: 11 }, { pattern: /^1(3|4|5|6|7|8|9)\d{9}$/, message: "请输入正确的手机号" } |
|||
]} |
|||
/> |
|||
</ProForm.Group> |
|||
<ProForm.Group> |
|||
<ProFormTreeSelect |
|||
name={['contract', 'departmentId']} |
|||
placeholder="请选择所属部门" |
|||
colProps={{ md: 12, xl: 12 }} |
|||
label="所属部门" |
|||
required |
|||
fieldNames={{ |
|||
title: 'name', |
|||
key: 'id', |
|||
children: 'subordinate' |
|||
}} |
|||
onSelect={(selectedKeys, { selected, selectedNodes }) => { |
|||
if (selected) { |
|||
setDepSelectedKeys(selectedKeys) |
|||
setDepSelected(selectedNodes[0].name || "") |
|||
dispatch(getDepUser(selectedKeys[0])) |
|||
} |
|||
}} |
|||
fieldProps={{ |
|||
fieldNames: { |
|||
label: 'title', |
|||
}, |
|||
treeDefaultExpandAll: false, |
|||
}} |
|||
rules={[{ required: true, message: '请选择所属部门' }]} |
|||
request={async () => { |
|||
console.log(depData); |
|||
return depData |
|||
}} |
|||
expandedKeys={["title"]} |
|||
/> |
|||
< ProFormText |
|||
name={['contract', 'post']} |
|||
colProps={{ md: 12, xl: 12 }} |
|||
label="职位" |
|||
// required
|
|||
placeholder="请输入职位" |
|||
/> |
|||
</ProForm.Group> |
|||
<ProForm.Group> |
|||
{/* <ProFormTreeSelect |
|||
name={['contract', 'structure']} |
|||
placeholder="请选择结构物" |
|||
width="md" |
|||
mode="multiple" |
|||
label="关注结构物" |
|||
required |
|||
// fieldNames={{
|
|||
// title: 'name',
|
|||
// key: 'id',
|
|||
// children: 'subordinate'
|
|||
// }}
|
|||
onSelect={(selectedKeys, { selected, selectedNodes }) => { |
|||
|
|||
}} |
|||
fieldProps={{ |
|||
mode: 'multiple', |
|||
fieldNames: { |
|||
label: 'title', |
|||
}, |
|||
treeDefaultExpandAll: false, |
|||
}} |
|||
rules={[{ required: true, message: '请选择结构物' }]} |
|||
request={async () => { |
|||
console.log(tableList); |
|||
const opts = tableList?.map(i=>({title:i.name,value:i.id})) |
|||
return opts |
|||
}} |
|||
expandedKeys={["title"]} |
|||
/> */} |
|||
<ProFormSelect |
|||
colProps={{ md: 12, xl: 12 }} |
|||
label="关注结构物" |
|||
name={['contract', 'structure']} |
|||
mode="multiple" |
|||
// fieldProps={{//这里使用了select的onChange方法,必须使用这样的写法来进行调用onChange方法
|
|||
// onChange:(val) => handleChange(val),
|
|||
// }}
|
|||
request={async () => { |
|||
console.log(tableList); |
|||
const opts = tableList?.map(i => ({ label: i.name, value: i.id })) |
|||
return opts |
|||
}} |
|||
placeholder="请选择结构物" |
|||
rules={[{ required: true, message: '结构物不能为空' }]} |
|||
/> |
|||
|
|||
<ProFormText |
|||
name={['contract', 'email']} |
|||
colProps={{ md: 12, xl: 12 }} |
|||
label="邮箱" |
|||
// required
|
|||
placeholder="请输入邮箱" |
|||
rules={[ |
|||
// { required: true, message: '请输入邮箱' },
|
|||
{ type: 'email', message: '请输入正确格式的邮箱' }, |
|||
]} |
|||
/> |
|||
</ProForm.Group> |
|||
<ProForm.Group> |
|||
{modalType == 'edit' ? null : <ProFormText.Password |
|||
name={['contract', 'password']} |
|||
colProps={{ md: 12, xl: 12 }} |
|||
label="密码" |
|||
required |
|||
placeholder="请输入密码" |
|||
fieldProps={{ |
|||
autocomplete: 'new-password' |
|||
}} |
|||
rules={[ |
|||
{ required: true, message: '请填写密码' }, |
|||
{ min: 6, message: '请填写至少6位密码' }, |
|||
]} |
|||
/>} |
|||
<ProFormSwitch |
|||
name={['contract', 'enable']} |
|||
colProps={{ md: 12, xl: 12 }} |
|||
label="是否启用" |
|||
placeholder="请选择" |
|||
// defaultChecked
|
|||
valuePropName="checked" |
|||
/> |
|||
</ProForm.Group> |
|||
|
|||
<ProFormSelect |
|||
name={['contract', 'role']} |
|||
colProps={{ md: 12, xl: 12 }} |
|||
label="角色" |
|||
placeholder="请选择角色" |
|||
options={[{ label: '巡检人员', value: '巡检人员' }, { label: '管理人员', value: '管理人员' }]} |
|||
rules={[ |
|||
{ required: true, message: '请选择角色' }, |
|||
]} |
|||
/> |
|||
</ModalForm> |
|||
</Spin> |
|||
) |
|||
} |
|||
|
|||
function mapStateToProps(state) { |
|||
const { depMessage } = state; |
|||
|
|||
const pakData = (dep) => { |
|||
// console.log(dep);
|
|||
return dep.map((d) => { |
|||
return { |
|||
title: d.name, |
|||
value: d.id, |
|||
// key: d.id,
|
|||
children: pakData(d.subordinate) |
|||
} |
|||
}) |
|||
} |
|||
let depData = pakData(depMessage.data || []) |
|||
|
|||
return { |
|||
loading: depMessage.isRequesting, |
|||
depData, |
|||
}; |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(UserModal); |
@ -1,158 +0,0 @@ |
|||
import React, { useEffect, useState } from 'react'; |
|||
import { connect } from 'react-redux'; |
|||
import { Spin, Row, Col, Card, Button, Tree, Empty, Divider } from 'antd'; |
|||
import { getDepMessage, getDepUser } from '../actions/user'; |
|||
import { getResource, getUserResource, postUserRes } from '../actions/authority'; |
|||
import Resource from '../components/resource'; |
|||
import './authority.less'; |
|||
|
|||
const Authority = (props) => { |
|||
const { dispatch, loading, depMessage, depUser, resource, userResource, clientHeight } = props |
|||
const [depSelectedKeys, setDepSelectedKeys] = useState([]) |
|||
const [userSelectedKeys, setUserSelectedKeys] = useState([]) |
|||
const [depSelected, setDepSelected] = useState() |
|||
const [userSelected, setUserSelected] = useState() |
|||
const [resCode, setResCode] = useState({}) |
|||
const [useName, setUseName] = useState()// 选中名字
|
|||
const [userType, setUserType] = useState() |
|||
useEffect(() => { |
|||
dispatch(getResource()) |
|||
if (!(depMessage && depMessage.length)) { |
|||
dispatch(getDepMessage()) |
|||
} |
|||
|
|||
}, []) |
|||
useEffect(() => { |
|||
if (depMessage.length) { |
|||
setDepSelectedKeys([depMessage[0].id]) |
|||
setDepSelected([depMessage[0].name]) |
|||
dispatch(getDepUser(depMessage[0].id)) |
|||
} |
|||
|
|||
}, [depMessage]) |
|||
useEffect(() => { |
|||
if (depUser.length) { |
|||
setUserSelectedKeys([depUser[0].id]) |
|||
setUserSelected(depUser[0].username) |
|||
dispatch(getUserResource(depUser[0].id)) |
|||
setUseName(depUser[0].name) |
|||
} else { |
|||
setUseName('') |
|||
} |
|||
}, [depUser]) |
|||
|
|||
const handleSave = () => { |
|||
dispatch(postUserRes({ userId: userSelectedKeys[0], resCode: resCode })).then(res => { |
|||
if (res.success) { |
|||
dispatch(getUserResource(userSelectedKeys[0])) |
|||
} |
|||
}) |
|||
} |
|||
return ( |
|||
<div className='main'> |
|||
<Spin spinning={loading}> |
|||
<div> |
|||
<div className='title'> |
|||
<span className='line'></span> |
|||
<span className='cn'>权限功能</span> |
|||
<span className='en'> PERMISSION FUNCTION</span> |
|||
</div> |
|||
<div className='tree-box'> |
|||
{ |
|||
depMessage.length ? |
|||
<Tree |
|||
style={{ width: 272 }} |
|||
height={195} |
|||
defaultExpandedKeys={[depMessage[0].id]} |
|||
selectedKeys={depSelectedKeys} |
|||
onSelect={(selectedKeys, { selected, selectedNodes, node }) => { |
|||
setUserType(selectedNodes[0].type) |
|||
if (selected) { |
|||
setDepSelectedKeys(selectedKeys) |
|||
setDepSelected(selectedNodes[0].name || "") |
|||
dispatch(getDepUser(selectedKeys[0])) |
|||
} |
|||
|
|||
}} |
|||
treeData={depMessage} |
|||
fieldNames={{ |
|||
title: 'name', |
|||
key: 'id', |
|||
children: 'subordinate' |
|||
}} |
|||
/> : '' |
|||
} |
|||
<div className='user-list'> |
|||
<div className='list-title'> |
|||
{(depSelected ? `【${depSelected}】` : "") + '用户列表'} |
|||
</div> |
|||
{ |
|||
depUser.length ? |
|||
<Tree |
|||
// style={{ width: 272 }}
|
|||
height={168} |
|||
defaultSelectedKeys={[depUser[0].id]} |
|||
selectedKeys={userSelectedKeys} |
|||
onSelect={(selectedKeys, { selected, selectedNodes, node, event }) => { |
|||
const name = node.name |
|||
setUseName(name) |
|||
|
|||
if (selected) { |
|||
setUserSelectedKeys(selectedKeys) |
|||
setUserSelected(selectedNodes[0].username || '') |
|||
dispatch(getUserResource(selectedKeys[0])) |
|||
} |
|||
|
|||
}} |
|||
treeData={depUser} |
|||
fieldNames={{ |
|||
title: 'name', |
|||
key: 'id' |
|||
}} |
|||
/> : <Empty /> |
|||
} |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<Divider /> |
|||
<div className='list-title'> |
|||
{`【${useName || ''}】 功能范围`} |
|||
</div> |
|||
{depUser.length ? |
|||
<Card bordered={false} bodyStyle={{ padding: 8, paddingTop: 24 }}> |
|||
<Resource |
|||
userSelected={userSelected} |
|||
roleData={resource} |
|||
userRole={userResource} |
|||
setResCode={setResCode} |
|||
userType={userType} |
|||
/> |
|||
<Row type="flex" justify="center" style={{ marginBottom: 16, marginTop: 16, textAlign: 'center' }}> |
|||
<Col span="24"> |
|||
<Button |
|||
disabled={userSelected === "SuperAdmin" || userType === 4} |
|||
onClick={handleSave} |
|||
style={{ width: '60%' }} |
|||
type='primary'>保存修改</Button> |
|||
</Col></Row> |
|||
</Card> |
|||
: <Empty /> |
|||
} |
|||
</Spin> |
|||
</div> |
|||
) |
|||
} |
|||
|
|||
function mapStateToProps(state) { |
|||
const { userResource, resource, depMessage, depUser, global } = state; |
|||
return { |
|||
clientHeight: global.clientHeight, |
|||
loading: depMessage.isRequesting || depUser.isRequesting || resource.isRequesting, |
|||
userResource: userResource.data || [], |
|||
resource: resource.data || [], |
|||
depMessage: depMessage.data || [], |
|||
depUser: depUser.data || [] |
|||
}; |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(Authority); |
@ -1,49 +0,0 @@ |
|||
.main { |
|||
width: 100%; |
|||
background: #fff; |
|||
padding: 10px 16px; |
|||
|
|||
.title { |
|||
display: inline-block; |
|||
|
|||
.line { |
|||
display: inline-block; |
|||
width: 3px; |
|||
height: 20px; |
|||
background: #006BE3; |
|||
} |
|||
|
|||
.cn { |
|||
font-family: YouSheBiaoTiHei; |
|||
font-size: 24px; |
|||
color: #101531; |
|||
margin-left: 11px; |
|||
} |
|||
|
|||
.en { |
|||
font-family: D-DINExp-Italic; |
|||
font-weight: Italic; |
|||
font-size: 12px; |
|||
color: #969799; |
|||
} |
|||
} |
|||
|
|||
.tree-box { |
|||
display: flex; |
|||
width: 100%; |
|||
|
|||
.user-list { |
|||
display: flex; |
|||
flex-direction: column; |
|||
margin-left: 100px; |
|||
} |
|||
} |
|||
|
|||
.list-title { |
|||
font-family: PingFangSC-Medium; |
|||
font-weight: 600; |
|||
font-size: 16px; |
|||
color: #000000d9; |
|||
margin-left: 15px; |
|||
} |
|||
} |
@ -1,6 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
import Authority from './authority'; |
|||
import UserManage from './user'; |
|||
|
|||
export { Authority, UserManage }; |
@ -1,355 +0,0 @@ |
|||
import React, { useEffect, useState } from 'react'; |
|||
import { connect } from 'react-redux'; |
|||
import { FormOutlined, DeleteOutlined } from '@ant-design/icons'; |
|||
import { Spin, Tooltip, Button, Popconfirm, Row, Col, Tree, Card, Switch } from 'antd'; |
|||
import ProTable from '@ant-design/pro-table'; |
|||
import { getDepMessage, getDepUser, createUser, updateUser, delUser, resetPwd, createDept, updateDept, delDept } from '../actions/user'; |
|||
import UserModal from '../components/userModal'; |
|||
import ResetPwd from '../components/resetPwd'; |
|||
import DeptModal from '../components/deptModal'; |
|||
import './user.less'; |
|||
|
|||
const TreeNode = Tree.TreeNode; |
|||
|
|||
const UserManage = (props) => { |
|||
const user = JSON.parse(sessionStorage.getItem('user')); |
|||
const [tableList, settableList] = useState([]) |
|||
const { dispatch, loading, depMessage, depUser, clientHeight, actions } = props; |
|||
// 部门
|
|||
const [deptModalVisible, setDeptModalVisible] = useState(false); |
|||
const [deptModalType, setDeptModalType] = useState(); |
|||
const [deptModalRecord, setDeptModalRecord] = useState(); |
|||
const { projectRegime } = actions |
|||
// 成员
|
|||
const [modalVisible, setModalVisible] = useState(false); |
|||
const [modalType, setModalType] = useState(); |
|||
const [modalRecord, setModalRecord] = useState(); |
|||
const [pwdModalVisible, setPwdModalVisible] = useState(false); |
|||
const [depSelectedKeys, setDepSelectedKeys] = useState([]) |
|||
const [rowSelected, setRowSelected] = useState([]) |
|||
|
|||
useEffect(() => { |
|||
dispatch(getDepMessage()) |
|||
projectList() |
|||
}, []) |
|||
|
|||
const projectList = (obj) => { |
|||
|
|||
dispatch(projectRegime.getProjectList()).then(res => { |
|||
// console.log(res)
|
|||
if (res.success) { |
|||
settableList(res.payload.data?.rows) |
|||
// setLimits(res.payload.data?.count)
|
|||
} |
|||
}) |
|||
} |
|||
|
|||
useEffect(() => { |
|||
if (depMessage.length) { |
|||
setDepSelectedKeys([depMessage[0].id]) |
|||
dispatch(getDepUser(depMessage[0].id)) |
|||
} |
|||
}, [depMessage]) |
|||
|
|||
const columns = [ |
|||
{ |
|||
title: '姓名', |
|||
dataIndex: 'name', |
|||
}, { |
|||
title: '用户名(手机号)', |
|||
dataIndex: 'username', |
|||
}, |
|||
{ |
|||
title: '职位', |
|||
dataIndex: 'post', |
|||
}, { |
|||
title: '邮箱', |
|||
dataIndex: 'email', |
|||
}, { |
|||
title: '启用状态', |
|||
dataIndex: 'enable', |
|||
render: (_, r) => { |
|||
return <Switch checkedChildren="启用" unCheckedChildren="禁用" disabled defaultChecked={r.enable} /> |
|||
} |
|||
}, { |
|||
title: '操作', |
|||
dataIndex: 'action', |
|||
render: (dom, record) => { |
|||
|
|||
return record.username == 'SuperAdmin' ? '' : [ |
|||
<Button type="link" onClick={() => { openModal('edit', record) }}>编辑</Button>, |
|||
<Popconfirm |
|||
title="确认删除?" |
|||
onConfirm={() => { |
|||
delUsers([record.id]) |
|||
}} |
|||
> |
|||
<Button type="link">删除</Button> |
|||
</Popconfirm>, |
|||
<Button |
|||
type="link" |
|||
onClick={() => { |
|||
setModalRecord(record); |
|||
setPwdModalVisible(true); |
|||
}} |
|||
>重置密码</Button> |
|||
] |
|||
}, |
|||
}, |
|||
]; |
|||
|
|||
//弹窗确认
|
|||
const onConfirm = (values) => { |
|||
if (modalType == 'edit') { |
|||
dispatch(updateUser(modalRecord.id, values.contract)).then(res => { |
|||
if (res.success) { |
|||
setModalVisible(false); |
|||
dispatch(getDepUser(depSelectedKeys[0])); |
|||
} |
|||
}); |
|||
} else { |
|||
dispatch(createUser(values.contract)).then(res => { |
|||
if (res.success) { |
|||
setModalVisible(false); |
|||
dispatch(getDepUser(depSelectedKeys[0])); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
} |
|||
|
|||
//打开弹窗
|
|||
const openModal = (type, record) => { |
|||
setModalVisible(true); |
|||
setModalType(type); |
|||
if (type == 'edit') { |
|||
setModalRecord(record); |
|||
} else { |
|||
setModalRecord(null); |
|||
} |
|||
} |
|||
|
|||
//删除用户
|
|||
const delUsers = (ids, type) => { |
|||
dispatch(delUser(ids)).then(res => { |
|||
dispatch(getDepUser(depSelectedKeys[0])); |
|||
if (type == 'batch') { |
|||
setRowSelected([]); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
//重置密码
|
|||
const onPwdConfirm = (values) => { |
|||
dispatch(resetPwd(modalRecord.id, { password: values.password })).then(res => { |
|||
if (res.success) { |
|||
setPwdModalVisible(false); |
|||
dispatch(getDepUser(depSelectedKeys[0])); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
const openDeptModal = (type, record) => { |
|||
console.log(type, record, 'type, record') |
|||
|
|||
setDeptModalVisible(true); |
|||
setDeptModalType(type); |
|||
if (type === 'edit') { |
|||
setDeptModalRecord(record); |
|||
} else { |
|||
setDeptModalRecord(null); |
|||
} |
|||
} |
|||
const onDeptConfirm = (values) => { |
|||
if (deptModalType === 'edit') { |
|||
dispatch(updateDept(deptModalRecord.id, values.contract)).then(res => { |
|||
if (res.success) { |
|||
setDeptModalVisible(false); |
|||
dispatch(getDepMessage()) |
|||
} |
|||
}); |
|||
} else { |
|||
dispatch(createDept(values.contract)).then(res => { |
|||
if (res.success) { |
|||
setDeptModalVisible(false); |
|||
dispatch(getDepMessage()) |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
const delDepartment = (id) => { |
|||
dispatch(delDept(id)).then(res => { |
|||
if (res.success) { |
|||
dispatch(getDepMessage()) |
|||
} |
|||
}); |
|||
} |
|||
|
|||
const renderTree = (item, id) => { |
|||
// let cannotDel = item.users.length || item.subordinate?.filter(is => is.users.length).length;//自己下面有成员 或者下级部门下有成员 不能删除
|
|||
return <div style={{ display: 'flex', width: '10vw', justifyContent: 'space-between' }}> |
|||
<Tooltip title={item.name}> |
|||
<div style={{ width: '80%', textOverflow: 'ellipsis', whiteSpace: 'nowrap', overflow: 'hidden' }}>{item.name}</div> |
|||
</Tooltip> |
|||
<div style={{ width: '20%' }} > |
|||
{ |
|||
depSelectedKeys == id && user.username === "SuperAdmin" ? |
|||
<> |
|||
<FormOutlined onClick={() => { |
|||
setDeptModalRecord(item) |
|||
setDeptModalVisible(true) |
|||
setDeptModalType('edit') |
|||
}} /> |
|||
{ |
|||
<Popconfirm title='是否确认删除?' onConfirm={() => { delDepartment(id) }}> |
|||
<DeleteOutlined style={{ marginLeft: 5 }} /> |
|||
</Popconfirm> |
|||
} |
|||
</> : null |
|||
} |
|||
</div> |
|||
</div> |
|||
} |
|||
|
|||
return (<> |
|||
<Spin spinning={loading} style={{ height: clientHeight }}> |
|||
<div className='dep-box'> |
|||
<div className='top'> |
|||
<div className='title'> |
|||
<span className='line'></span> |
|||
<span className='cn'>部门</span> |
|||
<span className='en'> DEPARTMENT</span> |
|||
</div> |
|||
{ |
|||
user.username === "SuperAdmin" && <Button |
|||
type="primary" |
|||
key="primary" |
|||
onClick={() => openDeptModal('create')} |
|||
>新建部门</Button> |
|||
} |
|||
</div> |
|||
{ |
|||
depMessage.length ? |
|||
<Tree |
|||
style={{ width: 272 }} |
|||
height={150} |
|||
defaultExpandedKeys={[depMessage[0].id]} |
|||
selectedKeys={depSelectedKeys} |
|||
onSelect={(selectedKeys, e) => { |
|||
if (e.selected) { |
|||
setDepSelectedKeys(selectedKeys) |
|||
dispatch(getDepUser(selectedKeys[0])) |
|||
} |
|||
}} |
|||
// treeData={depMessage}
|
|||
// fieldNames={{
|
|||
// title: 'name',
|
|||
// key: 'id',
|
|||
// children: 'subordinate'
|
|||
// }}
|
|||
> |
|||
{ |
|||
depMessage.map((s, index) => { |
|||
return <TreeNode title={renderTree(s, s.id)} key={s.id} > |
|||
{ |
|||
s.subordinate.map(k => { |
|||
return <TreeNode title={renderTree(k, k.id)} key={k.id} onMouseOver={() => { setIShowIcon(k.id) }} onMouseOut={() => { setIShowIcon(null) }}> |
|||
</TreeNode> |
|||
}) |
|||
} |
|||
</TreeNode> |
|||
}) |
|||
} |
|||
</Tree> : '' |
|||
} |
|||
</div> |
|||
<div className='user-box'> |
|||
<div className='top' style={{ marginBottom: 19 }}> |
|||
<div className='title'> |
|||
<span className='line'></span> |
|||
<span className='cn'>用户</span> |
|||
<span className='en'> USER</span> |
|||
</div> |
|||
<div> |
|||
<Button |
|||
type="primary" |
|||
key="primary" |
|||
style={{ marginRight: 10 }} |
|||
onClick={() => openModal('create')} |
|||
>新建用户</Button> |
|||
<Button style={{ marginRight: 10 }} onClick={() => { dispatch(getDepUser(depSelectedKeys[0])); }}>刷新</Button> |
|||
<Popconfirm title="确认删除?" onConfirm={() => { delUsers(rowSelected, 'batch') }}> |
|||
<Button>批量删除</Button> |
|||
</Popconfirm> |
|||
</div> |
|||
</div> |
|||
<ProTable |
|||
columns={columns} |
|||
dataSource={depUser} |
|||
style={{ width: "100% ", height: clientHeight - 371, overflow: "auto" }} |
|||
rowSelection={{ |
|||
selectedRowKeys: rowSelected, |
|||
onChange: (selectedRowKeys) => { |
|||
setRowSelected(selectedRowKeys); |
|||
|
|||
}, |
|||
getCheckboxProps: (record) => { |
|||
return { |
|||
disabled: record.username === 'SuperAdmin', |
|||
} |
|||
}, |
|||
}} |
|||
options={false} |
|||
search={false} |
|||
rowKey="id" |
|||
rowClassName={(record, index) => { |
|||
let className = 'global-light-row'; |
|||
if (index % 2 === 1) className = 'global-dark-row'; |
|||
return className; |
|||
}} |
|||
pagination={{ size: 'default', className: 'global-pagination' }} |
|||
/> |
|||
</div> |
|||
{ |
|||
deptModalVisible ? |
|||
<DeptModal |
|||
visible={deptModalVisible} |
|||
onVisibleChange={setDeptModalVisible} |
|||
modalType={deptModalType} |
|||
onConfirm={onDeptConfirm} |
|||
editData={deptModalRecord} |
|||
depts={depMessage} |
|||
/> |
|||
: '' |
|||
} |
|||
{ |
|||
depMessage.length && modalVisible ? |
|||
<UserModal |
|||
visible={modalVisible} |
|||
onVisibleChange={setModalVisible} |
|||
modalType={modalType} |
|||
onConfirm={onConfirm} |
|||
editData={{ ...modalRecord, structure: modalRecord?.structure || [] }} |
|||
tableList={tableList} |
|||
/> |
|||
: '' |
|||
} |
|||
{pwdModalVisible ? <ResetPwd visible={pwdModalVisible} |
|||
onVisibleChange={setPwdModalVisible} |
|||
onConfirm={onPwdConfirm} /> : ''} |
|||
</Spin> |
|||
</>) |
|||
} |
|||
|
|||
function mapStateToProps(state) { |
|||
const { depMessage, depUser, global } = state; |
|||
return { |
|||
clientHeight: global.clientHeight, |
|||
loading: depMessage.isRequesting, |
|||
depMessage: depMessage.data || [], |
|||
depUser: depUser.data || [], |
|||
actions: global.actions |
|||
}; |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(UserManage); |
@ -1,42 +0,0 @@ |
|||
.dep-box { |
|||
height: 213px; |
|||
background: #fff; |
|||
padding: 10px 16px; |
|||
margin-bottom: 20px; |
|||
} |
|||
|
|||
.user-box { |
|||
background: #fff; |
|||
padding: 10px 16px; |
|||
} |
|||
|
|||
.top { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
|
|||
.title { |
|||
background-color: #fff; |
|||
display: inline-block; |
|||
|
|||
.line { |
|||
display: inline-block; |
|||
width: 3px; |
|||
height: 20px; |
|||
background: #006BE3; |
|||
} |
|||
|
|||
.cn { |
|||
font-family: YouSheBiaoTiHei; |
|||
font-size: 24px; |
|||
color: #101531; |
|||
margin-left: 11px; |
|||
} |
|||
|
|||
.en { |
|||
font-family: D-DINExp-Italic; |
|||
font-weight: Italic; |
|||
font-size: 12px; |
|||
color: #969799; |
|||
} |
|||
} |
|||
} |
@ -1,15 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
import reducers from './reducers'; |
|||
import routes from './routes'; |
|||
import actions from './actions'; |
|||
import { getNavItem } from './nav-item'; |
|||
|
|||
export default { |
|||
key: 'organization', |
|||
name: '', |
|||
reducers: reducers, |
|||
routes: routes, |
|||
actions: actions, |
|||
getNavItem: getNavItem |
|||
}; |
@ -1,22 +0,0 @@ |
|||
import React from 'react'; |
|||
import { Link } from 'react-router-dom'; |
|||
import { Menu } from 'antd'; |
|||
import { FormatPainterOutlined } from '@ant-design/icons'; |
|||
import { Func } from '$utils'; |
|||
const SubMenu = Menu.SubMenu; |
|||
|
|||
export function getNavItem(user, dispatch) { |
|||
// if (!Func.isAuthorized("ORG_MANAGE")) {
|
|||
// return null
|
|||
// }
|
|||
return ( |
|||
Func.isAuthorized('ORG_MANAGE') && <SubMenu key="organization" icon={<img src='/assets/images/menu/org.svg' style={{ width: 24, height: 24 }} />} title={'组织管理'}> |
|||
{Func.isAuthorized('USER_CONFIG') && <Menu.Item key="userManage"> |
|||
<Link to="/organization/user">部门成员</Link> |
|||
</Menu.Item>} |
|||
{Func.isAuthorized('AUTH_CONFIG') && <Menu.Item key="authority"> |
|||
<Link to="/organization/authority">权限配置</Link> |
|||
</Menu.Item>} |
|||
</SubMenu> |
|||
); |
|||
} |
@ -1,5 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
export default { |
|||
|
|||
}; |
@ -1,26 +0,0 @@ |
|||
'use strict'; |
|||
import { UserManage, Authority } from './containers'; |
|||
|
|||
export default [{ |
|||
type: 'inner', |
|||
route: { |
|||
path: '/organization', |
|||
key: 'organization', |
|||
breadcrumb: '组织管理', |
|||
menuSelectKeys: ['userManage'], |
|||
menuOpenKeys: ['organization'], |
|||
childRoutes: [{ |
|||
path: '/user', |
|||
key: 'userManage', |
|||
menuSelectKeys: ['userManage'], |
|||
component: UserManage, |
|||
breadcrumb: '部门成员', |
|||
}, { |
|||
path: '/authority', |
|||
key: 'authority', |
|||
component: Authority, |
|||
menuSelectKeys: ['authority'], |
|||
breadcrumb: '权限配置', |
|||
}] |
|||
} |
|||
}]; |
@ -1,88 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
import { basicAction } from '@peace/utils' |
|||
import { ApiTable } from '$utils' |
|||
|
|||
export function getCheckItemsGroup() { |
|||
return dispatch => basicAction({ |
|||
type: 'get', |
|||
dispatch: dispatch, |
|||
actionType: 'GET_CHECK_ITEMS_GROUP', |
|||
url: ApiTable.checkItemsGroup, |
|||
msg: { error: '获取检查项分组失败' }, |
|||
reducer:{name:'checkItemsGroup'} |
|||
}); |
|||
} |
|||
|
|||
export function createCheckItemsGroup(data) { |
|||
return dispatch => basicAction({ |
|||
type: 'post', |
|||
data, |
|||
dispatch: dispatch, |
|||
actionType: 'CREATE_CHECK_ITEMS_GROUP', |
|||
url: ApiTable.checkItemsGroup, |
|||
msg: { option: '创建检查项分组' }, |
|||
}); |
|||
} |
|||
|
|||
export function delCheckItemsGroup(id) { |
|||
return dispatch => basicAction({ |
|||
type: 'del', |
|||
dispatch: dispatch, |
|||
actionType: 'DEL_CHECK_ITEMS_GROUP', |
|||
url: ApiTable.delCheckItemsGroup.replace('{id}', id), |
|||
msg: { option: '删除检查项分组' }, |
|||
}); |
|||
} |
|||
|
|||
export function getCheckItems(query) { |
|||
return dispatch => basicAction({ |
|||
type: 'get', |
|||
dispatch: dispatch, |
|||
query: query, |
|||
actionType: 'GET_CHECK_ITEMS', |
|||
url: ApiTable.checkItems, |
|||
msg: { error: '获取检查项失败' } |
|||
}); |
|||
} |
|||
|
|||
export function createCheckItems(data) { |
|||
return dispatch => basicAction({ |
|||
type: 'post', |
|||
data, |
|||
dispatch: dispatch, |
|||
actionType: 'CREATE_CHECK_ITEMS', |
|||
url: ApiTable.checkItems, |
|||
msg: { option: '新建检查项' }, |
|||
}); |
|||
} |
|||
|
|||
export function updateCheckItems(id, data) { |
|||
return dispatch => basicAction({ |
|||
type: 'put', |
|||
data, |
|||
dispatch: dispatch, |
|||
actionType: 'UPDATE_CHECK_ITEMS', |
|||
url: ApiTable.updateCheckItems.replace('{id}', id), |
|||
msg: { option: '修改检查项' }, |
|||
}); |
|||
} |
|||
|
|||
export function delCheckItems(ids) { |
|||
return dispatch => basicAction({ |
|||
type: 'del', |
|||
dispatch: dispatch, |
|||
actionType: 'DEL_CHECK_ITEMS', |
|||
url: ApiTable.delCheckItems.replace('{ids}', ids), |
|||
msg: { option: '删除检查项' }, |
|||
}); |
|||
} |
|||
|
|||
export default { |
|||
getCheckItemsGroup, |
|||
createCheckItemsGroup, |
|||
getCheckItems, |
|||
createCheckItems, |
|||
updateCheckItems, |
|||
delCheckItems, |
|||
} |
@ -1,18 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
import * as plan from './plan' |
|||
import * as record from './record' |
|||
import * as report from './report' |
|||
import * as template from './template' |
|||
import * as checkItems from './checkItems' |
|||
import * as yujingguanli from './yujingguanli' |
|||
import * as reportConf from './reportConf' |
|||
export default { |
|||
...plan, |
|||
...record, |
|||
...report, |
|||
...template, |
|||
...checkItems, |
|||
...yujingguanli, |
|||
...reportConf |
|||
} |
@ -1,81 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
import { basicAction } from '@peace/utils' |
|||
import { ApiTable } from '$utils' |
|||
|
|||
export function getPatrolPlan(query) { |
|||
return dispatch => basicAction({ |
|||
type: 'get', |
|||
query, |
|||
dispatch: dispatch, |
|||
actionType: 'GET_PATROL_PLAN', |
|||
url: ApiTable.patrolPlan, |
|||
msg: { error: '获取巡检计划失败' }, |
|||
}); |
|||
} |
|||
|
|||
export function createPatrolPlan(data) { |
|||
return dispatch => basicAction({ |
|||
type: 'post', |
|||
data, |
|||
dispatch: dispatch, |
|||
actionType: 'CREATE_PATROL_PLAN', |
|||
url: ApiTable.patrolPlan, |
|||
msg: { error: '新增巡检计划失败' }, |
|||
}); |
|||
} |
|||
|
|||
export function delPatrolPlan(id) { |
|||
return dispatch => basicAction({ |
|||
type: 'del', |
|||
dispatch: dispatch, |
|||
actionType: 'DEL_PATROL_PLAN', |
|||
url: ApiTable.delPatrolPlan.replace('{id}', id), |
|||
msg: { error: '删除巡检计划失败' }, |
|||
}); |
|||
} |
|||
|
|||
export function updatePatrolPlan(data) { |
|||
return dispatch => basicAction({ |
|||
type: 'put', |
|||
data, |
|||
dispatch: dispatch, |
|||
actionType: 'UPDATE_PATROL_PLAN', |
|||
url: ApiTable.patrolPlan, |
|||
msg: { error: '修改巡检计划失败' }, |
|||
}); |
|||
} |
|||
|
|||
export function getUserList() { |
|||
return dispatch => basicAction({ |
|||
type: 'get', |
|||
dispatch: dispatch, |
|||
actionType: 'GET_USER_LIST', |
|||
url: ApiTable.getDepUser.replace('{depId}', null), |
|||
msg: { error: '获取人员列表失败' }, |
|||
reducer: { name: 'userList' } |
|||
}); |
|||
} |
|||
|
|||
export function getProjectList(query) { |
|||
return (dispatch) => basicAction({ |
|||
type: 'get', |
|||
query, |
|||
dispatch, |
|||
actionType: 'GET_PROJEECT_LIST', |
|||
url: ApiTable.getProjectList, |
|||
msg: { error: '获取结构物列表失败', }, |
|||
reducer: { name: 'structureList' } |
|||
}); |
|||
} |
|||
|
|||
export function positionList(query) { |
|||
return (dispatch) => basicAction({ |
|||
type: 'get', |
|||
query, |
|||
dispatch, |
|||
actionType: 'POSITION_LIST', |
|||
url: ApiTable.position, |
|||
msg: { error: '获取点位列表失败', }, |
|||
}); |
|||
} |
@ -1,17 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
import { basicAction } from '@peace/utils' |
|||
|
|||
export const GET_PATROL_RECORD_LIST = 'GET_PATROL_RECORD_LIST'; |
|||
export const GET_PATROL_RECORD_LIST_SUCCESS = 'GET_PATROL_RECORD_LIST_SUCCESS'; |
|||
export const GET_PATROL_RECORD_LIST_ERROR = 'GET_PATROL_RECORD_LIST_ERROR'; |
|||
export function records(url) { |
|||
return (dispatch) => basicAction({ |
|||
type: 'get', |
|||
dispatch, |
|||
actionType: GET_PATROL_RECORD_LIST, |
|||
url: url, |
|||
msg: { error: '获取巡检记录失败', }, |
|||
reducer: { name: 'record' } |
|||
}); |
|||
} |
@ -1,26 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
import { basicAction } from '@peace/utils' |
|||
import { ApiTable } from '$utils' |
|||
|
|||
export function getPatrolReport (query) { |
|||
return dispatch => basicAction({ |
|||
type: 'get', |
|||
query, |
|||
dispatch: dispatch, |
|||
actionType: 'GET_PATROL_REPORT', |
|||
url: ApiTable.patrolReport, |
|||
msg: { error: '获取巡检报告失败' }, |
|||
}); |
|||
} |
|||
|
|||
|
|||
export function delpatrolRecord (id) { |
|||
return dispatch => basicAction({ |
|||
type: 'delete', |
|||
dispatch: dispatch, |
|||
actionType: 'DEL_PATROL_RECORD', |
|||
url: ApiTable.delpatrolRecord.replace('{id}', id), |
|||
msg: { error: '删除巡检报告失败' }, |
|||
}) |
|||
} |
@ -1,55 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
import { basicAction } from '@peace/utils' |
|||
import { ApiTable } from '$utils' |
|||
|
|||
export function getReportList (query) { |
|||
return dispatch => basicAction({ |
|||
type: 'get', |
|||
query, |
|||
dispatch: dispatch, |
|||
actionType: 'GET_REPORT_LIST', |
|||
url: ApiTable.getReportList, |
|||
msg: { error: '获取报表配置列表失败' }, |
|||
}); |
|||
} |
|||
|
|||
|
|||
export function postReport (data = {}) { |
|||
return dispatch => basicAction({ |
|||
type: 'post', |
|||
data, |
|||
dispatch: dispatch, |
|||
actionType: 'POST_REPORT', |
|||
url: `${ApiTable.postReport}`, |
|||
msg: { option: data?.id ? '编辑报表生成规则' : "新增报表生成规则" }, |
|||
}); |
|||
} |
|||
|
|||
|
|||
export function delReport (id) {//删除报表文件
|
|||
return dispatch => basicAction({ |
|||
type: 'del', |
|||
dispatch: dispatch, |
|||
actionType: 'DEL_REPORT', |
|||
url: `${ApiTable.delReport.replace('{id}', id)}`, |
|||
msg: { option: '删除报表规则' }, |
|||
|
|||
|
|||
}); |
|||
} |
|||
|
|||
export function postGenerateReport (data = {}) { //生成报表
|
|||
return dispatch => basicAction({ |
|||
type: 'post', |
|||
data, |
|||
dispatch: dispatch, |
|||
actionType: 'POST_GENERATE_REPORT', |
|||
url: `${ApiTable.generateReport}`, |
|||
msg: { option: "生成报表" }, |
|||
reducer: { |
|||
name: "generateReport", |
|||
params: { noClear: true } |
|||
} |
|||
}); |
|||
} |
@ -1,48 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
import { basicAction } from '@peace/utils' |
|||
import { ApiTable } from '$utils' |
|||
|
|||
export function getPatrolTemplate (query) { |
|||
return dispatch => basicAction({ |
|||
type: 'get', |
|||
query, |
|||
dispatch: dispatch, |
|||
actionType: 'GET_PATROL_TEMPLATE', |
|||
url: ApiTable.patrolTemplate, |
|||
msg: { error: '获取巡检模板失败' }, |
|||
reducer: { name: 'patrolTemplate' } |
|||
}); |
|||
} |
|||
|
|||
export function createPatrolTemplate (data) { |
|||
return dispatch => basicAction({ |
|||
type: 'post', |
|||
data, |
|||
dispatch: dispatch, |
|||
actionType: 'CREATE_PATROL_TEMPLATE', |
|||
url: ApiTable.patrolTemplate, |
|||
msg: { option: '新增巡检模板' }, |
|||
}); |
|||
} |
|||
|
|||
export function delPatrolTemplate (id) { |
|||
return dispatch => basicAction({ |
|||
type: 'del', |
|||
dispatch: dispatch, |
|||
actionType: 'DEL_PATROL_TEMPLATE', |
|||
url: ApiTable.delPatrolTemplate.replace('{id}', id), |
|||
msg: { option: '删除巡检模板' }, |
|||
}); |
|||
} |
|||
|
|||
export function updatePatrolTemplate (data) { |
|||
return dispatch => basicAction({ |
|||
type: 'put', |
|||
data, |
|||
dispatch: dispatch, |
|||
actionType: 'UPDATE_PATROL_TEMPLATE', |
|||
url: ApiTable.patrolTemplate, |
|||
msg: { option: '修改巡检模板' }, |
|||
}); |
|||
} |
@ -1,24 +0,0 @@ |
|||
import { basicAction } from '@peace/utils' |
|||
import { ApiTable } from '$utils' |
|||
|
|||
export function putxinxi (data) { |
|||
return dispatch => basicAction({ |
|||
type: 'post', |
|||
data, |
|||
dispatch: dispatch, |
|||
actionType: 'PUT_XINXI', |
|||
url: ApiTable.yujingguanli, |
|||
msg: { option: '发送信息' }, |
|||
}); |
|||
} |
|||
|
|||
export function modifyPatrolRecordIssueHandle(id, params, msg) { |
|||
return (dispatch) => basicAction({ |
|||
type: 'put', |
|||
data: params, |
|||
dispatch, |
|||
actionType: 'MODIFY_PatrolRecordIssueHandle_REPORT', |
|||
url: ApiTable.modifyPatrolRecordIssueHandle.replace('{id}', id), |
|||
msg: '', |
|||
}); |
|||
} |
@ -1,281 +0,0 @@ |
|||
import { Button, Form, Input, Modal, Select, DatePicker,message } from 'antd' |
|||
import React, { useState, useEffect } from 'react' |
|||
import { connect } from 'react-redux' |
|||
import Uploads from '$components/Uploads' |
|||
const { RangePicker } = DatePicker |
|||
import moment from 'moment' |
|||
|
|||
const AddReportRulesModal = props => { |
|||
const [form] = Form.useForm() |
|||
const { user, visible, cancelHandle, actions, dispatch, onOk, modalData,typeList,structAll} = props |
|||
const [systemList, setSystemList] = useState([{ value: 1, label: '动力系统' },{ value: 2, label: '网络系统' }]) |
|||
const { patrolManage } = actions |
|||
const [type, setType] = useState(0) |
|||
const [system,setSystem]=useState(0)//system
|
|||
const [isShow, setIsShow] = useState(false) |
|||
const [structlist, setStructlist] = useState([])//结构物列表(只包括id和name)
|
|||
// const [startTime,setStartTime]=useState('')
|
|||
// const [endTime,setEndTime]=useState('')
|
|||
useEffect(()=>{ |
|||
if(modalData){ |
|||
setType(modalData.type) |
|||
} |
|||
},[modalData]) |
|||
const typeChange = e => { |
|||
setType(e) |
|||
form.setFieldValue('system', '') |
|||
form.setFieldValue('structure', undefined) |
|||
} |
|||
useEffect(()=>{ |
|||
if(type){ |
|||
if(type==1){ |
|||
const list = structAll.filter(v => v.type === '管廊')?.map(k => { |
|||
return { |
|||
value: k.id, |
|||
label: k.name |
|||
} |
|||
}) |
|||
setStructlist(list) |
|||
} |
|||
} |
|||
},[type]) |
|||
useEffect(()=>{ |
|||
//过滤管廊类型的数据
|
|||
const list = structAll.filter(v => v.type === '管廊')?.map(k => { |
|||
return { |
|||
value: k.id, |
|||
label: k.name |
|||
} |
|||
}) |
|||
setStructlist(list) |
|||
},[]) |
|||
|
|||
useEffect(() => { |
|||
// setPic(modalData?.reportpic)
|
|||
form.setFieldsValue({ |
|||
structure: null, |
|||
pic: null, |
|||
name: null, |
|||
type: null, |
|||
timeRange: null, |
|||
}) |
|||
form.setFieldsValue({ |
|||
structure: modalData?.structure, |
|||
name: modalData?.name, |
|||
type: modalData?.type, |
|||
system:modalData?.system, |
|||
pic: modalData?.reportpic?.map(item=>{return {storageUrl:item}}), |
|||
timeRange: modalData?.startTime ? [moment(modalData?.startTime), moment(modalData?.endTime)] : [], |
|||
}) |
|||
}, [visible]) |
|||
const timeChane = e => {} |
|||
const okHandler = () => { |
|||
form |
|||
.validateFields() |
|||
.then(values => { |
|||
if(values.pic?.length<4){ |
|||
message.warning(`最少选择4张图片`) |
|||
return |
|||
} |
|||
const params = { |
|||
id: modalData?.id, |
|||
name: values.name, |
|||
type: values.type, |
|||
system:values.system, |
|||
structure: Array.isArray(values.structure) ? [...values.structure] : [values.structure], |
|||
endTime: moment(values.timeRange[1]).endOf('day').format('YYYY-MM-DD HH:mm:ss'), |
|||
startTime: moment(values.timeRange[0]).startOf('day').format('YYYY-MM-DD HH:mm:ss'), |
|||
reportpic: values?.pic[0]?.name ? values?.pic.map(u => u.storageUrl) : modalData?.reportpic, |
|||
} |
|||
dispatch(patrolManage.postReport(params)).then(res => { |
|||
if (res.success) { |
|||
// form.resetFields()
|
|||
cancelHandle() |
|||
onOk() |
|||
setType(null) |
|||
} |
|||
}) |
|||
}) |
|||
.catch(info => { |
|||
console.log('Validate Failed:', info) |
|||
}) |
|||
} |
|||
//use
|
|||
// const structChange=(e)=>{
|
|||
// setStructObj(structAll.find(item=>item.id==e))
|
|||
// }
|
|||
// useEffect(()=>{
|
|||
// if(strcutObj){
|
|||
// if(strcutObj.subType.includes('供配电系统')||strcutObj.subType.includes('防雷')){
|
|||
// setSystemList([{ value: 1, label: '动力系统' }])
|
|||
// setIsShow(true)
|
|||
// }else if(strcutObj.subType.includes('指挥中心')||strcutObj.subType.includes('安防'))
|
|||
// setSystemList([{ value: 2, label: '网络系统' }])
|
|||
// setIsShow(true)
|
|||
// }
|
|||
|
|||
// },[strcutObj])
|
|||
|
|||
const systemChange=(e)=>{ |
|||
setSystem(e) |
|||
// setType(null)
|
|||
form.setFieldValue('structure', undefined) |
|||
if(e==1){ |
|||
const list=structAll.filter(v => v.type === '管廊')?.filter(item=>item.subType.includes('供配电系统')||item.subType.includes('防雷')) |
|||
if(list&&list.length){ |
|||
setStructlist( list?.map(item=>{ |
|||
return {value: item.id, |
|||
label: item.name} |
|||
})) |
|||
|
|||
}else{ |
|||
setStructlist([]) |
|||
} |
|||
}else if(e==2){ |
|||
const list=structAll.filter(v => v.type === '管廊')?.filter(item=>item.subType.includes('指挥中心')||item.subType.includes('安防')) |
|||
if(list&&list.length){ |
|||
setStructlist( list?.map(item=>{ |
|||
return {value: item.id, |
|||
label: item.name} |
|||
})) |
|||
|
|||
}else{ |
|||
setStructlist([]) |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
} |
|||
console.log('reportpic',modalData?.reportpic) |
|||
return ( |
|||
<> |
|||
<Modal |
|||
destroyOnClose |
|||
title={modalData ? '编辑报表规则' : '新建报表规则'} |
|||
visible={visible} |
|||
onCancel={() => { |
|||
cancelHandle() |
|||
setIsShow(false) |
|||
setType(0) |
|||
form.setFieldsValue({ |
|||
structure: null, |
|||
pic: null, |
|||
name: null, |
|||
type: null, |
|||
timeRange: null, |
|||
}) |
|||
// form.resetFields()
|
|||
}} |
|||
onOk={okHandler}> |
|||
<Form |
|||
form={form} |
|||
labelCol={{ |
|||
span: 5, |
|||
}} |
|||
initialValues={ |
|||
{ |
|||
// structure:modalData?.structure,
|
|||
// pic:modalData?.reportpic,
|
|||
// name:modalData?.name,
|
|||
// type:modalData?.type,
|
|||
// timeRange:[moment(modalData?.startTime),moment(modalData?.endTime)]
|
|||
} |
|||
}> |
|||
<Form.Item label='报表名称' name='name' rules={[{ required: true, message: '请输入报表名称' }]}> |
|||
<Input /> |
|||
</Form.Item> |
|||
<Form.Item label='报表类型' name='type' rules={[{ required: true, message: '请选择报表类型' }]}> |
|||
<Select onChange={typeChange}> |
|||
{typeList?.map(g => { |
|||
return ( |
|||
<Option key={g.value} value={g.value} label={g.label}> |
|||
<div |
|||
style={{ |
|||
display: 'flex', |
|||
justifyContent: 'space-between', |
|||
}}> |
|||
{g.label} |
|||
</div> |
|||
</Option> |
|||
) |
|||
})} |
|||
</Select> |
|||
</Form.Item> |
|||
{type===2? |
|||
<Form.Item label='系统' name='system' rules={[{ required: true, message: '请选择系统' }]}> |
|||
<Select onChange={systemChange} > |
|||
{systemList?.map(g => { |
|||
return ( |
|||
<Option key={g.value} value={g.value} label={g.label}> |
|||
<div |
|||
style={{ |
|||
display: 'flex', |
|||
justifyContent: 'space-between', |
|||
}}> |
|||
{g.label} |
|||
</div> |
|||
</Option> |
|||
) |
|||
})} |
|||
</Select> |
|||
</Form.Item>:''} |
|||
<Form.Item label='关联结构物' name='structure' rules={[{ required: true, message: '请选择结构物' }]}> |
|||
<Select mode={type === 2 ? 'multiple' : undefined}> |
|||
{structlist?.map(g => { |
|||
return ( |
|||
<Option key={g.value} value={g.value} label={g.label}> |
|||
<div |
|||
style={{ |
|||
display: 'flex', |
|||
justifyContent: 'space-between', |
|||
}}> |
|||
{g.label} |
|||
</div> |
|||
</Option> |
|||
) |
|||
})} |
|||
</Select> |
|||
</Form.Item> |
|||
|
|||
<Form.Item label='生成时间' name='timeRange' rules={[{ required: true, message: '请选择时间' }]}> |
|||
<RangePicker onChange={timeChane} /> |
|||
</Form.Item> |
|||
<Form.Item label='发现问题上传:' name='pic' rules={[{ required: true, message: '请选择图片' }]}> |
|||
<Uploads |
|||
listType='picture-card' |
|||
uploadType='project' |
|||
maxFilesNum={15} |
|||
maxFileSize={10} |
|||
isQiniu={true} |
|||
// disabled={true}
|
|||
fileTypes={['png', 'jpg']} |
|||
fileList={modalData?.reportpic} |
|||
defaultValue={(() => { |
|||
let nextV = [] |
|||
for (let s of modalData?.reportpic || []) { |
|||
if (s) { |
|||
nextV.push({ |
|||
url: s, |
|||
storageUrl: s, |
|||
}) |
|||
} |
|||
} |
|||
return nextV |
|||
})()} |
|||
/> |
|||
</Form.Item> |
|||
</Form> |
|||
</Modal> |
|||
</> |
|||
) |
|||
} |
|||
|
|||
function mapStateToProps(state) { |
|||
const { auth, global } = state |
|||
return { |
|||
user: auth.user, |
|||
actions: global.actions, |
|||
} |
|||
} |
|||
export default connect(mapStateToProps)(AddReportRulesModal) |
@ -1,122 +0,0 @@ |
|||
import { Button, Form, Input, Modal, Select } from 'antd'; |
|||
import { DeleteOutlined } from '@ant-design/icons'; |
|||
import React, { useState, useEffect } from 'react'; |
|||
import { connect } from 'react-redux'; |
|||
import { getCheckItemsGroup, delCheckItemsGroup } from '../actions/checkItems'; |
|||
const { Option } = Select; |
|||
|
|||
const CheckItemsModal = ({ visible, onOk, onCancel, curRecord, dispatch }) => { |
|||
const [group, setGroup] = useState([]); |
|||
const [isNewGroup, setIsNewGroup] = useState(false); |
|||
const [form] = Form.useForm(); |
|||
|
|||
useEffect(() => { |
|||
getGroup(); |
|||
}, []) |
|||
|
|||
function getGroup() { |
|||
dispatch(getCheckItemsGroup()).then(res => { |
|||
if (res.success) { |
|||
const opt = res.payload.data?.map(g => ({ value: g.id, label: g.name })); |
|||
setGroup(opt); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
function delGroup(id, lastGroup) { |
|||
dispatch(delCheckItemsGroup(id)).then(res => { |
|||
if (res.success) { |
|||
form.setFieldValue('group', lastGroup === id ? null : lastGroup) |
|||
getGroup(); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
return ( |
|||
<Modal |
|||
visible={visible} |
|||
title={curRecord ? "检查项修改" : "检查项添加"} |
|||
okText="确定" |
|||
cancelText="取消" |
|||
onCancel={() => { |
|||
form.resetFields(); |
|||
onCancel(); |
|||
}} |
|||
onOk={() => { |
|||
form |
|||
.validateFields() |
|||
.then((values) => { |
|||
form.resetFields(); |
|||
const params = { |
|||
...values, |
|||
isNewGroup |
|||
} |
|||
onOk(params); |
|||
}) |
|||
.catch((info) => { |
|||
console.log('Validate Failed:', info); |
|||
}); |
|||
}} |
|||
> |
|||
<Form |
|||
form={form} |
|||
layout="vertical" |
|||
name="form_in_modal" |
|||
initialValues={{ |
|||
...curRecord, |
|||
group: curRecord?.checkItemsGroup?.id |
|||
}} |
|||
> |
|||
<Form.Item |
|||
name="name" |
|||
label="检查项名称" |
|||
rules={[ |
|||
{ required: true, message: '请输入检查项名称' }, |
|||
]} |
|||
> |
|||
<Input /> |
|||
</Form.Item> |
|||
<Form.Item |
|||
name="group" |
|||
label="分组名称" |
|||
rules={[ |
|||
{ required: true, message: '请选择分组' }, |
|||
]} |
|||
> |
|||
{ |
|||
isNewGroup |
|||
? <Input /> |
|||
: <Select loading={!group?.length} optionLabelProp="label"> |
|||
{ |
|||
group?.map((g) => { |
|||
return <Option key={g.value} value={g.value} label={g.label}> |
|||
<div style={{ display: 'flex', justifyContent: 'space-between' }}> |
|||
{g.label} |
|||
<DeleteOutlined onClick={() => { delGroup(g.value, form.getFieldValue('group')) }} /> |
|||
</div> |
|||
</Option> |
|||
}) |
|||
} |
|||
</Select> |
|||
} |
|||
</Form.Item> |
|||
</Form> |
|||
<Button type='link' onClick={() => { |
|||
if (!isNewGroup) { |
|||
form.setFieldsValue({ group: null }) |
|||
} else { |
|||
form.setFieldsValue({ group: curRecord?.checkItemsGroup?.id }) |
|||
} |
|||
setIsNewGroup(!isNewGroup); |
|||
}}>{isNewGroup ? '选择已有' : '创建分组'}</Button> |
|||
</Modal > |
|||
); |
|||
}; |
|||
|
|||
function mapStateToProps(state) { |
|||
const { auth } = state |
|||
return { |
|||
user: auth.user, |
|||
} |
|||
} |
|||
export default connect(mapStateToProps)(CheckItemsModal); |
@ -1,263 +0,0 @@ |
|||
import { Form, Input, Modal, Select, DatePicker } from 'antd'; |
|||
import { DownOutlined } from '@ant-design/icons'; |
|||
import React, { useState, useEffect } from 'react'; |
|||
import { connect } from 'react-redux'; |
|||
import { getUserList, getProjectList, positionList } from '../actions/plan'; |
|||
import moment from 'moment'; |
|||
|
|||
const { RangePicker } = DatePicker; |
|||
|
|||
const PlanModal = ({ visible, onCreate, onCancel, dispatch, userLoading, userList, structureList, struLoading, type, curRecord, templateLoading, patrolTemplate }) => { |
|||
const [userOpt, setUserOpt] = useState(); |
|||
const [struOpt, setStruOpt] = useState(); |
|||
const [pointOpt, setPointOpt] = useState(); |
|||
const [points, setPoints] = useState(); |
|||
const [unit, setUnit] = useState(curRecord?.frequency ? curRecord.frequency.substring(curRecord.frequency.length - 3, curRecord.frequency.length) : "次/天"); |
|||
const [form] = Form.useForm(); |
|||
|
|||
useEffect(() => { |
|||
if (type === 'view') { |
|||
|
|||
} else { |
|||
dispatch(getUserList()) |
|||
dispatch(getProjectList()) |
|||
} |
|||
if (type === 'edit' || type === 'view') { |
|||
dispatch(positionList({ projectId: curRecord?.project?.id })).then(res => { |
|||
if (res.success) { |
|||
setPoints(res.payload.data?.rows) |
|||
setPointOpt(res.payload.data?.rows[0]?.points?.map(p => ({ label: p.name, value: p.id }))) |
|||
} |
|||
}) |
|||
} |
|||
}, []) |
|||
|
|||
useEffect(() => { |
|||
if (userList.length) { |
|||
setUserOpt(userList?.filter(f => f.structure?.includes(curRecord?.project?.id))?.map(u => ({ label: u.name, value: u.id }))) |
|||
// 如果巡检人员用户被删除,筛掉被删除的用户
|
|||
const userListIds = userList?.map(u => u.id); |
|||
const filterUsers = curRecord?.users?.filter(u => userListIds.includes(u.id)); |
|||
const nextUserIds = filterUsers?.map(u => u.id); |
|||
form.setFieldsValue({ |
|||
userIds: nextUserIds, |
|||
userDept: [...new Set(filterUsers?.map(u => u.department?.name))].join() |
|||
}); |
|||
} |
|||
}, [userList]) |
|||
|
|||
useEffect(() => { |
|||
if (structureList?.rows?.length) { |
|||
setStruOpt(structureList?.rows?.map(s => ({ label: s.name, value: s.id }))) |
|||
} |
|||
}, [structureList]) |
|||
|
|||
const selectAfter = ( |
|||
<Select |
|||
defaultValue={curRecord?.frequency ? curRecord.frequency.substring(curRecord.frequency.length - 3, curRecord.frequency.length) : "次/天"} |
|||
onChange={value => setUnit(value)} |
|||
suffixIcon={<DownOutlined style={{ color: '#fff' }} />} |
|||
> |
|||
<Option value="次/天">次/天</Option> |
|||
<Option value="次/周">次/周</Option> |
|||
<Option value="次/月">次/月</Option> |
|||
</Select> |
|||
); |
|||
return ( |
|||
<Modal |
|||
className="global-modal" |
|||
width={717} |
|||
visible={visible} |
|||
title={(type === 'view' ? '查看' : type === 'edit' ? '编辑' : '新增') + "巡检计划"} |
|||
okText="确定" |
|||
cancelText="取消" |
|||
onCancel={() => { |
|||
form.resetFields(); |
|||
onCancel(); |
|||
}} |
|||
onOk={() => { |
|||
if (type === 'view') { |
|||
form.resetFields(); |
|||
onCancel(); |
|||
return; |
|||
} |
|||
form |
|||
.validateFields() |
|||
.then((values) => { |
|||
form.resetFields(); |
|||
const params = { |
|||
...values, |
|||
frequency: values.frequency + unit, |
|||
startTime: values.time[0], |
|||
endTime: values.time[1], |
|||
points: points[0]?.points?.filter(p => values?.points?.includes(p.id)) |
|||
} |
|||
onCreate(params); |
|||
}) |
|||
.catch((info) => { |
|||
console.log('Validate Failed:', info); |
|||
}); |
|||
}} |
|||
> |
|||
<Form |
|||
form={form} |
|||
name="form_in_modal" |
|||
labelAlign='right' |
|||
labelCol={{ span: 4 }} wrapperCol={{ span: 18 }} |
|||
initialValues={{ |
|||
...curRecord, |
|||
time: [moment(curRecord?.startTime), moment(curRecord?.endTime)], |
|||
points: curRecord?.points?.map(p => p.id), |
|||
userIds: curRecord?.users?.map(u => u.id), |
|||
userDept: [...new Set(curRecord?.users?.map(u => u.department?.name))].join(), |
|||
frequency: curRecord?.frequency?.split('次')[0] |
|||
}} |
|||
disabled={type === 'view'} |
|||
> |
|||
<div style={{ position: 'relative', display: 'flex', justifyContent: 'space-between' }}> |
|||
<Form.Item |
|||
name="structureId" |
|||
label="结构物名称" |
|||
labelCol={{ span: 9 }} |
|||
style={{ width: 330 }} |
|||
rules={[ |
|||
{ required: true, message: '请选择结构物' }, |
|||
]} |
|||
> |
|||
<Select disabled={type === 'view'} bordered={false} options={struOpt} loading={struLoading} onChange={(projectId) => { |
|||
dispatch(positionList({ projectId })).then(res => { |
|||
if (res.success) { |
|||
setPoints(res.payload.data?.rows) |
|||
setPointOpt(res.payload.data?.rows[0]?.points?.map(p => ({ label: p.name, value: p.id }))) |
|||
} |
|||
}) |
|||
form.setFieldsValue({ userIds: [], userDept: [] }); |
|||
setUserOpt(userList?.filter(f => f.structure?.includes(projectId))?.map(u => ({ label: u.name, value: u.id }))) |
|||
}} /> |
|||
</Form.Item> |
|||
<Form.Item |
|||
name="name" |
|||
label="巡检任务名称" |
|||
labelCol={{ span: 9 }} |
|||
style={{ width: 330 }} |
|||
rules={[ |
|||
{ required: true, message: '请输入巡检任务名称' }, |
|||
]} |
|||
> |
|||
<Input disabled={type === 'view'} bordered={false} /> |
|||
</Form.Item> |
|||
</div> |
|||
<div style={{ position: 'relative', display: 'flex', justifyContent: 'space-between' }}> |
|||
<Form.Item |
|||
name="way" |
|||
label="巡检方式" |
|||
labelCol={{ span: 8 }} |
|||
style={{ width: 330 }} |
|||
rules={[ |
|||
{ required: true, message: '请选择巡检方式' }, |
|||
]} |
|||
initialValue='周期巡检' |
|||
> |
|||
<Select bordered={false} options={[{ |
|||
label: '周期巡检', |
|||
value: '周期巡检' |
|||
}]} disabled /> |
|||
</Form.Item> |
|||
<Form.Item |
|||
name="frequency" |
|||
label="巡检频次" |
|||
labelCol={{ span: 8 }} |
|||
style={{ width: 330 }} |
|||
rules={[ |
|||
{ required: true, message: '请选择巡检频次' }, |
|||
]} |
|||
> |
|||
<Input addonAfter={selectAfter} disabled={type === 'view'} bordered={false} /> |
|||
</Form.Item> |
|||
</div> |
|||
<div style={{ position: 'relative', display: 'flex', justifyContent: 'space-between' }}> |
|||
<Form.Item |
|||
name="templateId" |
|||
label="巡检模板" |
|||
labelCol={{ span: 8 }} |
|||
style={{ width: 330 }} |
|||
rules={[ |
|||
{ required: true, message: '请选择巡检模板' }, |
|||
]} |
|||
> |
|||
<Select |
|||
bordered={false} |
|||
disabled={type === 'view'} |
|||
options={patrolTemplate.map(t => { |
|||
return { label: t.name, value: t.id } |
|||
})} |
|||
loading={templateLoading} |
|||
/> |
|||
</Form.Item> |
|||
<Form.Item |
|||
name="time" |
|||
label="任务周期" |
|||
labelCol={{ span: 8 }} |
|||
style={{ width: 330 }} |
|||
rules={[ |
|||
{ required: true, message: '请选择任务周期' }, |
|||
]} |
|||
> |
|||
<RangePicker disabled={type === 'view'} bordered={false} /> |
|||
</Form.Item> |
|||
</div> |
|||
<div style={{ position: 'relative', display: 'flex', justifyContent: 'space-between' }}> |
|||
<Form.Item |
|||
name="points" |
|||
label="巡检点" |
|||
labelCol={{ span: 8 }} |
|||
style={{ width: 330 }} |
|||
rules={[ |
|||
{ required: true, message: '请选择巡检点' }, |
|||
]} |
|||
> |
|||
<Select mode="multiple" options={pointOpt} disabled={!pointOpt || type === 'view'} bordered={false} showSearch |
|||
filterOption={(input, option) => (option?.label ?? '').toLowerCase().includes(input.toLowerCase())} |
|||
/> |
|||
</Form.Item> |
|||
<Form.Item |
|||
name="userIds" |
|||
label="巡检人员" |
|||
labelCol={{ span: 8 }} |
|||
style={{ width: 330 }} |
|||
rules={[ |
|||
{ required: true, message: '请选择巡检人员' }, |
|||
]} |
|||
> |
|||
<Select mode="multiple" disabled={type === 'view'} bordered={false} options={userOpt} loading={userLoading} onChange={(values) => { |
|||
const selectUser = userList?.filter(u => values?.includes(u.id)) |
|||
form.setFieldsValue({ |
|||
userDept: [...new Set(selectUser?.map(u => u.department.name))].join() |
|||
}); |
|||
}} /> |
|||
</Form.Item> |
|||
</div> |
|||
<Form.Item |
|||
name="userDept" |
|||
label="巡检单位" |
|||
> |
|||
<Input disabled bordered={false} /> |
|||
</Form.Item> |
|||
</Form> |
|||
</Modal > |
|||
); |
|||
}; |
|||
|
|||
function mapStateToProps(state) { |
|||
const { auth, userList, structureList, patrolTemplate } = state |
|||
return { |
|||
user: auth.user, |
|||
userList: userList.data || [], |
|||
structureList: structureList.data || [], |
|||
patrolTemplate: (patrolTemplate.data || { rows: [] }).rows, |
|||
userLoading: userList.isRequesting, |
|||
struLoading: structureList.isRequesting, |
|||
templateLoading: patrolTemplate.isRequesting, |
|||
} |
|||
} |
|||
export default connect(mapStateToProps)(PlanModal); |
@ -1,122 +0,0 @@ |
|||
import { Button, Form, Input, Modal, Select, DatePicker } from 'antd'; |
|||
import React, { useState, useEffect } from 'react'; |
|||
import { connect } from 'react-redux'; |
|||
import { createPatrolTemplate, delPatrolTemplate, updatePatrolTemplate, getPatrolTemplate } from '../actions/template'; |
|||
import moment from 'moment'; |
|||
|
|||
const { RangePicker } = DatePicker; |
|||
const { TextArea } = Input; |
|||
|
|||
const PlanModal = ({ visible, onCancel, dispatch, type, curRecord, tableRef, checkItemsGroup }) => { |
|||
const [form] = Form.useForm(); |
|||
|
|||
return ( |
|||
<Modal |
|||
visible={visible} |
|||
title="新增巡检模板" |
|||
okText="确定" |
|||
cancelText="取消" |
|||
onCancel={() => { |
|||
form.resetFields(); |
|||
onCancel(); |
|||
}} |
|||
onOk={() => { |
|||
form |
|||
.validateFields() |
|||
.then((values) => { |
|||
|
|||
const params = { |
|||
...values, |
|||
} |
|||
|
|||
if (type === 'create') { |
|||
dispatch(createPatrolTemplate(params)).then(res => { |
|||
if (res.success) { |
|||
tableRef.current.reload(); |
|||
form.resetFields(); |
|||
onCancel(); |
|||
} |
|||
}) |
|||
} else { |
|||
dispatch(updatePatrolTemplate({ |
|||
...params, |
|||
id: curRecord.id |
|||
})).then(res => { |
|||
if (res.success) { |
|||
tableRef.current.reload(); |
|||
form.resetFields(); |
|||
onCancel(); |
|||
} |
|||
}) |
|||
} |
|||
}) |
|||
.catch((info) => { |
|||
console.log('Validate Failed:', info); |
|||
}); |
|||
}} |
|||
> |
|||
<Form |
|||
form={form} |
|||
layout="vertical" |
|||
name="form_in_modal" |
|||
initialValues={{ |
|||
...curRecord, |
|||
checkItems: curRecord?.checkItems?.map(c => c.id) |
|||
}} |
|||
> |
|||
<Form.Item |
|||
name="name" |
|||
label="模板名称" |
|||
rules={[ |
|||
{ required: true, message: '请输入巡检模板名称' }, |
|||
]} |
|||
> |
|||
<Input /> |
|||
</Form.Item> |
|||
<Form.Item |
|||
name="describe" |
|||
label="描述" |
|||
rules={[]} |
|||
> |
|||
<TextArea rows={4} /> |
|||
</Form.Item> |
|||
<Form.Item |
|||
name="checkItems" |
|||
label="检查项" |
|||
rules={[ |
|||
{ required: true, message: '请选择检查项' }, |
|||
]} |
|||
> |
|||
<Select |
|||
style={{ |
|||
// width: 200,
|
|||
}} |
|||
mode="multiple" |
|||
options={ |
|||
checkItemsGroup.map(g => { |
|||
return { |
|||
label: g.name, |
|||
options: g.checkItems.map(c => { |
|||
return { |
|||
label: c.name, |
|||
value: c.id, |
|||
} |
|||
}) |
|||
} |
|||
}) |
|||
} |
|||
/> |
|||
</Form.Item> |
|||
</Form> |
|||
</Modal > |
|||
); |
|||
}; |
|||
|
|||
function mapStateToProps (state) { |
|||
const { auth, checkItemsGroup } = state |
|||
return { |
|||
user: auth.user, |
|||
checkItemsGroup: checkItemsGroup.data || [] |
|||
} |
|||
} |
|||
export default connect(mapStateToProps)(PlanModal); |
@ -1,89 +0,0 @@ |
|||
import { Button, Form, Input, Modal, Select, DatePicker,Checkbox, message } from 'antd'; |
|||
import React, { useState, useEffect } from 'react'; |
|||
import { connect } from 'react-redux'; |
|||
import {modifyPatrolRecordIssueHandle} from '../actions/yujingguanli' |
|||
import {putxinxi} from '../actions/yujingguanli' |
|||
import moment from 'moment'; |
|||
|
|||
const { RangePicker } = DatePicker; |
|||
const { TextArea } = Input; |
|||
|
|||
const PlanModal = ({ visible, onCancel, dispatch, type, curRecord, tableRef, checkItemsGroup,userlist ,actions,onHandle}) => { |
|||
const [form] = Form.useForm(); |
|||
const { issueHandle } = actions |
|||
const shigutypes = [{value:1,label: '短信告警'}, |
|||
{value:2,label:'邮件告警'}] |
|||
console.log(userlist,'userlist') |
|||
return ( |
|||
<Modal |
|||
visible={visible} |
|||
title="下发告警" |
|||
okText="确定" |
|||
cancelText="取消" |
|||
onCancel={() => { |
|||
form.resetFields(); |
|||
onCancel(); |
|||
}} |
|||
onOk={() => { |
|||
form |
|||
.validateFields() |
|||
.then((values) => { |
|||
const params = { |
|||
...values, |
|||
} |
|||
console.log('user,',userlist) |
|||
let usedata = userlist.filter(i=>i?.username===values.name) |
|||
console.log(usedata,'usedata') |
|||
dispatch(putxinxi({phone:[params.name],email:[usedata[0]?.email],type:params.type,struction:curRecord?.points?.project?.name |
|||
,point:curRecord?.points?.itemData?.name,number:curRecord?.patrolRecordIssueHandles[0]?.yanshoucishu})).then(res=>{ |
|||
console.log(res,'res') |
|||
}).then(()=>{ |
|||
dispatch(modifyPatrolRecordIssueHandle(curRecord?.patrolRecordIssueHandles[0]?.id,{ |
|||
isgaojing:true, |
|||
yujingshijian:moment().format('YYYY-MM-DD HH:mm:ss') |
|||
})).then(()=>message.success('下发告警成功')), |
|||
onCancel(); |
|||
onHandle() |
|||
}) |
|||
console.log(curRecord,'curRecord') |
|||
console.log(params,'params') |
|||
}) |
|||
.catch((info) => { |
|||
console.log('Validate Failed:', info); |
|||
}); |
|||
}} |
|||
> |
|||
<Form |
|||
form={form} |
|||
// layout="vertical"
|
|||
name="form_in_modal" |
|||
|
|||
labelCol={{ span: 5 }} wrapperCol={{ span: 19 }} |
|||
> |
|||
<Form.Item |
|||
name="name" |
|||
label="告警接收人" |
|||
rules={[ |
|||
{ required: true, message: '请输入用户账号' }, |
|||
]} |
|||
> |
|||
<Select options={userlist?.map(i=>({value:i?.username,label:i?.name}))}></Select> |
|||
</Form.Item> |
|||
<Form.Item label="告警方式" |
|||
name="type"> |
|||
<Checkbox.Group options={shigutypes}/> |
|||
</Form.Item> |
|||
</Form> |
|||
</Modal > |
|||
); |
|||
}; |
|||
|
|||
function mapStateToProps (state) { |
|||
const { auth, checkItemsGroup,global } = state |
|||
return { |
|||
user: auth.user, |
|||
checkItemsGroup: checkItemsGroup.data || [], |
|||
actions: global.actions, |
|||
} |
|||
} |
|||
export default connect(mapStateToProps)(PlanModal); |
@ -1,176 +0,0 @@ |
|||
import React, { useState, useRef } from 'react'; |
|||
import { connect } from 'react-redux'; |
|||
import { Button, Popconfirm } from 'antd'; |
|||
import ProTable from '@ant-design/pro-table'; |
|||
import CheckItemsModal from '../components/checkItemsModal'; |
|||
import { getCheckItems, createCheckItems, updateCheckItems, delCheckItems, createCheckItemsGroup } from '../actions/checkItems'; |
|||
|
|||
function CheckItems(props) { |
|||
const { dispatch } = props; |
|||
const tableRef = useRef(); |
|||
const [dataSource, setDataSource] = useState([{}]); |
|||
const [visible, setVisible] = useState(false); |
|||
const [curRecord, setCurRecord] = useState(null); // 新增 or 修改
|
|||
const [select, setSelect] = useState([]); |
|||
|
|||
const onOk = async (values) => { |
|||
let groupId = null; |
|||
if (values.isNewGroup) { |
|||
await dispatch(createCheckItemsGroup({ name: values.group })).then(res => { |
|||
if (res.success) { |
|||
groupId = res.payload.data?.groupId |
|||
} |
|||
}) |
|||
} |
|||
if (!curRecord) { |
|||
dispatch(createCheckItems({ |
|||
name: values.name, |
|||
groupId: groupId ? groupId : values.group |
|||
})).then(res => { |
|||
if (res.success) { |
|||
tableRef.current.reload(); |
|||
} |
|||
}) |
|||
} else { |
|||
dispatch(updateCheckItems(curRecord.id, { |
|||
name: values.name, |
|||
groupId: groupId ? groupId : values.group |
|||
})).then(res => { |
|||
if (res.success) { |
|||
tableRef.current.reload(); |
|||
} |
|||
}) |
|||
} |
|||
setVisible(false); |
|||
}; |
|||
|
|||
function delItems(ids) { |
|||
dispatch(delCheckItems(ids)).then(res => { |
|||
if (res.success) { |
|||
tableRef.current.reload(); |
|||
setSelect([]); |
|||
} |
|||
}) |
|||
} |
|||
|
|||
const columns = [{ |
|||
title: '检查项', |
|||
dataIndex: 'name', |
|||
key: 'name', |
|||
ellipsis: true, |
|||
width: 150, |
|||
}, { |
|||
title: '分组名称', |
|||
dataIndex: 'groupName', |
|||
key: 'groupName', |
|||
ellipsis: true, |
|||
search: false, |
|||
width: 150, |
|||
render: (_, record) => { |
|||
return <div>{record?.checkItemsGroup?.name}</div> |
|||
} |
|||
}, { |
|||
title: '操作', |
|||
dataIndex: 'action', |
|||
key: 'action', |
|||
search: false, |
|||
width: 200, |
|||
render: (_, record) => { |
|||
return <> |
|||
<Button type="link" onClick={() => { |
|||
setCurRecord(record) |
|||
setVisible(true) |
|||
}}>修改</Button> |
|||
<Popconfirm |
|||
title="确认删除?" |
|||
onConfirm={() => { delItems(record.id) }} |
|||
disabled={record && record.patrolTemplates && record.patrolTemplates.length} |
|||
> |
|||
<Button type="link" danger disabled={record && record.patrolTemplates && record.patrolTemplates.length}>删除</Button> |
|||
</Popconfirm> |
|||
</> |
|||
}, |
|||
}]; |
|||
|
|||
return ( |
|||
<> |
|||
<ProTable |
|||
columns={columns} |
|||
actionRef={tableRef} |
|||
options={false} |
|||
dataSource={dataSource || []} |
|||
rowKey='id' |
|||
pagination={{ pageSize: 10, size: 'default', className: 'global-pagination' }} |
|||
request={async (params = {}) => { |
|||
const res = await dispatch(getCheckItems({ |
|||
limit: params.pageSize, |
|||
page: params.current - 1, |
|||
name: params?.name |
|||
})); |
|||
setDataSource(res?.payload.data?.rows); |
|||
return { |
|||
...res, |
|||
total: res.payload.data.count ? res.payload.data.count : 0, |
|||
}; |
|||
}} |
|||
onReset={() => { }} |
|||
search={{ |
|||
defaultCollapsed: false, |
|||
optionRender: (searchConfig, formProps, dom) => [ |
|||
...dom.reverse(), |
|||
<Button |
|||
key="add" |
|||
type='primary' |
|||
onClick={() => { |
|||
setCurRecord(null) |
|||
setVisible(true) |
|||
}} |
|||
>新增</Button>, |
|||
<Button |
|||
key="del" |
|||
type='primary' |
|||
disabled={!select?.length} |
|||
onClick={() => { |
|||
const ids = select?.map(s => s.id).join(); |
|||
delItems(ids); |
|||
}} |
|||
>批量删除</Button>, |
|||
], |
|||
}} |
|||
rowSelection={{ |
|||
selectedRowKeys: select?.map(v => v.id) || [], |
|||
onChange: (_, selectedRows) => { |
|||
setSelect(selectedRows) |
|||
}, |
|||
getCheckboxProps: (record) => ({ |
|||
disabled: record && record.patrolTemplates && record.patrolTemplates.length, |
|||
}), |
|||
}} |
|||
rowClassName={(record, index) => { |
|||
let className = 'global-light-row'; |
|||
if (index % 2 === 1) className = 'global-dark-row'; |
|||
return className; |
|||
}} |
|||
/> |
|||
{ |
|||
visible ? |
|||
<CheckItemsModal |
|||
visible={visible} |
|||
onOk={onOk} |
|||
curRecord={curRecord} |
|||
onCancel={() => { |
|||
setVisible(false); |
|||
}} |
|||
/> : null |
|||
} |
|||
</> |
|||
) |
|||
} |
|||
|
|||
function mapStateToProps(state) { |
|||
const { auth } = state |
|||
return { |
|||
user: auth.user |
|||
} |
|||
} |
|||
export default connect(mapStateToProps)(CheckItems); |
@ -1,10 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
import PatrolPlan from './patrolPlan'; |
|||
import PatrolReocrd from './patrolRecord'; |
|||
import PatrolReport from './patrolReport'; |
|||
import CheckItems from './checkItems'; |
|||
import PlanTemplate from './patrolTemplate'; |
|||
import YujingGuanli from './yujingguanli'; |
|||
|
|||
export { PatrolPlan, PatrolReocrd, PatrolReport, CheckItems, PlanTemplate,YujingGuanli }; |
@ -1,192 +0,0 @@ |
|||
import React, { useState, useRef, useEffect } from 'react'; |
|||
import { connect } from 'react-redux'; |
|||
import { Button, Popconfirm } from 'antd'; |
|||
import ProTable from '@ant-design/pro-table'; |
|||
import PlanModal from '../components/planModal'; |
|||
import { createPatrolPlan, delPatrolPlan, updatePatrolPlan, getPatrolPlan } from '../actions/plan'; |
|||
import { getPatrolTemplate } from '../actions/template'; |
|||
import moment from 'moment'; |
|||
import './patrolPlan.less' |
|||
|
|||
function PatrolPlan(props) { |
|||
const { dispatch, user } = props; |
|||
const tableRef = useRef(); |
|||
const [dataSource, setDataSource] = useState([{}]); |
|||
const [visible, setVisible] = useState(false); |
|||
const [type, setType] = useState(); |
|||
const [curRecord, setCurRecord] = useState(); |
|||
|
|||
useEffect(() => { |
|||
dispatch(getPatrolTemplate({})) |
|||
}, []) |
|||
|
|||
const onCreate = (values) => { |
|||
if (type === 'create') { |
|||
dispatch(createPatrolPlan(values)).then(res => { |
|||
if (res.success) { |
|||
tableRef.current.reload(); |
|||
} |
|||
}) |
|||
} else { |
|||
dispatch(updatePatrolPlan({ ...values, id: curRecord.id })).then(res => { |
|||
if (res.success) { |
|||
tableRef.current.reload(); |
|||
} |
|||
}) |
|||
} |
|||
setVisible(false); |
|||
setCurRecord(null); |
|||
}; |
|||
|
|||
const columns = [{ |
|||
title: '结构物名称', |
|||
dataIndex: 'projectName', |
|||
key: 'projectName', |
|||
ellipsis: true, |
|||
render: (_, record) => { |
|||
return <div>{record?.project?.name}</div> |
|||
} |
|||
}, { |
|||
title: '巡检任务名称', |
|||
dataIndex: 'name', |
|||
key: 'name', |
|||
ellipsis: true |
|||
}, { |
|||
title: '开始时间', |
|||
dataIndex: 'startTime', |
|||
key: 'startTime', |
|||
ellipsis: true, |
|||
search: false, |
|||
render: (_, record) => moment(record.startTime).format('YYYY-MM-DD') |
|||
}, { |
|||
title: '结束时间', |
|||
dataIndex: 'endTime', |
|||
key: 'endTime', |
|||
ellipsis: true, |
|||
search: false, |
|||
render: (_, record) => moment(record.endTime).format('YYYY-MM-DD') |
|||
}, { |
|||
title: '巡检频次', |
|||
dataIndex: 'frequency', |
|||
key: 'frequency', |
|||
ellipsis: true, |
|||
search: false, |
|||
}, { |
|||
title: '巡检点位', |
|||
dataIndex: 'patrolPoints', |
|||
key: 'patrolPoints', |
|||
ellipsis: true, |
|||
search: false, |
|||
render: (_, record) => record?.points?.length ? record?.points?.map(p => p.name).join() : '-' |
|||
}, { |
|||
title: '巡检人', |
|||
dataIndex: 'patrolPerson', |
|||
key: 'patrolPerson', |
|||
ellipsis: true, |
|||
search: false, |
|||
render: (_, record) => record?.users?.map(u => u.name).join() || '-' |
|||
}, { |
|||
title: '巡检次数统计', |
|||
dataIndex: 'patrolCount', |
|||
key: 'patrolCount', |
|||
ellipsis: true, |
|||
search: false, |
|||
}, { |
|||
title: '操作', |
|||
dataIndex: 'action', |
|||
key: 'action', |
|||
search: false, |
|||
width: 200, |
|||
render: (_, record) => { |
|||
return <> |
|||
<Button type="link" onClick={() => { |
|||
setType('edit') |
|||
setCurRecord(record) |
|||
setVisible(true) |
|||
}}>修改</Button> |
|||
<Button type="link" onClick={() => { |
|||
setType('view') |
|||
setCurRecord(record) |
|||
setVisible(true) |
|||
}}>查看</Button> |
|||
<Popconfirm |
|||
title="确认删除?" |
|||
onConfirm={() => { |
|||
dispatch(delPatrolPlan(record.id)).then(res => { |
|||
if (res.success) { |
|||
tableRef.current.reload(); |
|||
} |
|||
}) |
|||
}}> |
|||
<Button type="link" danger>删除</Button> |
|||
</Popconfirm> |
|||
</> |
|||
}, |
|||
}]; |
|||
|
|||
return ( |
|||
<div className='plan-main'> |
|||
<div className='title'> |
|||
<span className='line'></span> |
|||
<span className='cn'>巡检计划制定</span> |
|||
<span className='en'> Inspection plan making</span> |
|||
</div> |
|||
<ProTable |
|||
columns={columns} |
|||
actionRef={tableRef} |
|||
options={false} |
|||
dataSource={dataSource || []} |
|||
rowKey='id' |
|||
pagination={{ pageSize: 10, size: 'default', className: 'global-pagination' }} |
|||
search={{ |
|||
className: 'search-form', |
|||
defaultCollapsed: false, |
|||
labelWidth: 'auto', |
|||
optionRender: (searchConfig, formProps, dom) => [ |
|||
...dom.reverse(), |
|||
<Button |
|||
type="primary" |
|||
key="primary" |
|||
onClick={() => { |
|||
setType('create') |
|||
setVisible(true) |
|||
}} |
|||
>新增巡检计划</Button>, |
|||
], |
|||
}} |
|||
request={async (params = {}) => { |
|||
const res = await dispatch(getPatrolPlan(params)); |
|||
setDataSource(res?.payload.data?.rows); |
|||
return { ...res }; |
|||
}} |
|||
onReset={() => { }} |
|||
rowClassName={(record, index) => { |
|||
let className = 'global-light-row'; |
|||
if (index % 2 === 1) className = 'global-dark-row'; |
|||
return className; |
|||
}} |
|||
/> |
|||
{ |
|||
visible ? |
|||
<PlanModal |
|||
visible={visible} |
|||
onCreate={onCreate} |
|||
type={type} |
|||
curRecord={curRecord} |
|||
onCancel={() => { |
|||
setVisible(false); |
|||
setCurRecord(null) |
|||
}} |
|||
/> : null |
|||
} |
|||
</div> |
|||
) |
|||
} |
|||
|
|||
function mapStateToProps(state) { |
|||
const { auth } = state |
|||
return { |
|||
user: auth.user |
|||
} |
|||
} |
|||
export default connect(mapStateToProps)(PatrolPlan); |
@ -1,20 +0,0 @@ |
|||
.plan-main { |
|||
background: #fff; |
|||
|
|||
.search-form { |
|||
.ant-row-start { |
|||
justify-content: flex-end; |
|||
|
|||
.ant-col-offset-6 { |
|||
margin-left: 0; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.title { |
|||
position: absolute; |
|||
top: 50px; |
|||
left: 50px; |
|||
z-index: 1; |
|||
} |
|||
} |
@ -1,387 +0,0 @@ |
|||
|
|||
'use strict' |
|||
|
|||
import React, { useEffect, useState } from 'react'; |
|||
import { connect } from 'react-redux'; |
|||
import { Form, Input, Select, Button, Table, Modal, DatePicker, message, Row, Col, Collapse, Popconfirm } from 'antd'; |
|||
import moment from "moment"; |
|||
import XLSX from 'xlsx'; |
|||
import Uploads from '$components/Uploads'; |
|||
import '../style.less' |
|||
|
|||
const { Panel } = Collapse; |
|||
|
|||
const PatrolRecord = (props) => { |
|||
const { dispatch, actions, } = props |
|||
const { patrolManage } = actions |
|||
const [tableList, settableList] = useState([]) |
|||
const [showDetailModal, setShowDetail] = useState(false) |
|||
const [modelData, setModelData] = useState({}) |
|||
const [query, setQuery] = useState({ limit: 10, page: 0 }) |
|||
const [limits, setLimits] = useState() |
|||
const format = 'YYYY-MM-DD HH:mm:ss' |
|||
const [search, setSearch] = useState({ name: null, time: [moment().add(-7, 'd').format(format), moment().format(format)], state: 'null' }) |
|||
const [exportLoading, setExportLoading] = useState(false) |
|||
const aboutDisaster={handleObj:'排查及处理对象',installLocation:'安装位置',handleGoal:'排查及处理目的',rtuNo:'RTU编号'} |
|||
useEffect(() => { |
|||
record(search) |
|||
}, []) |
|||
|
|||
const record = (params) => { |
|||
dispatch(patrolManage.records(`patrolRecord/all/${params.time[0]}/${params.time[1]}/${params.state}/null`)).then(res => { |
|||
if (res.success) { |
|||
settableList(params.name != null ? res.payload.data?.filter(v => |
|||
(v.points.user.name.indexOf(params.name) != -1 || v.points.project.name.indexOf(params.name) != -1)) |
|||
.map(v => ({ ...v, key: v.id })) : res.payload.data?.map(v => ({ ...v, key: v.id }))) |
|||
setLimits(res.payload.data?.length) |
|||
} |
|||
}) |
|||
} |
|||
|
|||
const exportRecord = () => { |
|||
if (tableList.length === 0) { |
|||
message.warning('没有数据可以导出') |
|||
return |
|||
} |
|||
setExportLoading(true) |
|||
const workbook = XLSX.utils.book_new(); // 新建工作簿
|
|||
let data = [['结构物名称', '巡检计划', '巡检点位', '巡检人', '巡检单位', '巡检频次', '上次巡检日期', '本次巡检日期', '巡检结果']]; |
|||
for (const item of tableList) { |
|||
data.push([ |
|||
item.points?.project?.name || '--', |
|||
item.patrolPlan?.name || '--', |
|||
item.points?.itemData?.name || '--', |
|||
item.points?.user?.name || '--', |
|||
item.points?.user?.department?.name || '--', |
|||
item.points?.frequency || '--', |
|||
item.lastInspectionTime ? moment(item.lastInspectionTime).format('YYYY-MM-DD HH:mm:ss') : '--', |
|||
moment(item.inspectionTime).format('YYYY-MM-DD HH:mm:ss'), |
|||
!item.alarm ? '正常' : '异常', |
|||
]) |
|||
} |
|||
const worksheet = XLSX.utils.aoa_to_sheet(data); // 从二维数组新建工作表
|
|||
XLSX.utils.book_append_sheet(workbook, worksheet, "sheet1"); // 将工作表添加到工作簿
|
|||
XLSX.writeFile(workbook, '巡检记录.xlsx'); // 将工作簿数据建立为./xlsx文件(浏览器环境下会直接下载)
|
|||
message.success('导出成功') |
|||
setExportLoading(false) |
|||
} |
|||
|
|||
const columns = [{ |
|||
title: '结构物名称', |
|||
dataIndex: 'name', |
|||
key: 'name', |
|||
width: '10%', |
|||
showInDetail: true, |
|||
render: (text, record, index) => { |
|||
return !record.points?.project ? '--' : <div>{record.points.project.name}</div> |
|||
} |
|||
}, { |
|||
title: '巡检计划', |
|||
dataIndex: 'name', |
|||
key: 'name', |
|||
width: '10%', |
|||
showInDetail: true, |
|||
render: (text, record, index) => { |
|||
return !record.patrolPlan ? '--' : <div>{record?.patrolPlan?.name || '-'}</div> |
|||
} |
|||
}, { |
|||
title: '巡检点位', |
|||
dataIndex: 'type', |
|||
key: 'type', |
|||
showInDetail: true, |
|||
width: '10%', |
|||
render: (text, record, index) => { |
|||
return !record.points?.user ? '--' : <div>{record.points.itemData.name}</div> |
|||
} |
|||
}, { |
|||
title: '巡检人', |
|||
dataIndex: 'type', |
|||
key: 'type', |
|||
showInDetail: true, |
|||
width: '10%', |
|||
render: (text, record, index) => { |
|||
return !record.points?.user ? '--' : <div>{record.points.user.name}</div> |
|||
} |
|||
}, { |
|||
title: '巡检单位', |
|||
dataIndex: 'type', |
|||
showInDetail: true, |
|||
key: 'type', |
|||
width: '10%', |
|||
render: (text, record, index) => { |
|||
return !record.points?.user ? '--' : <div>{record.points.user.department.name}</div> |
|||
} |
|||
}, { |
|||
title: '巡检频次', |
|||
dataIndex: 'describe', |
|||
key: 'describe', |
|||
showInDetail: true, |
|||
width: '10%', |
|||
render: (text, record, index) => { |
|||
return !record.points ? '--' : <div>{record.points.frequency || '-'}</div> |
|||
} |
|||
}, { |
|||
title: '上次巡检日期', |
|||
dataIndex: 'describe', |
|||
showInDetail: true, |
|||
key: 'describe', |
|||
render: (text, record, index) => record.lastInspectionTime ? moment(record.lastInspectionTime).format('YYYY-MM-DD HH:mm:ss') : '--' |
|||
}, { |
|||
title: '本次巡检日期', |
|||
dataIndex: 'describe', |
|||
key: 'describe', |
|||
showInDetail: true, |
|||
render: (text, record, index) => moment(record.inspectionTime).format('YYYY-MM-DD HH:mm:ss') || '--' |
|||
}, { |
|||
title: '巡检结果', |
|||
dataIndex: 'describe', |
|||
key: 'describe', |
|||
render: (text, record, index) => !record.alarm ? '正常' : '异常' |
|||
}, { |
|||
title: '操作', |
|||
dataIndex: 'operation', |
|||
key: 'operation', |
|||
render: (text, record, index) => { |
|||
return ( |
|||
<div style={{ width: 190 }}> |
|||
<Button type="link" onClick={() => { |
|||
setShowDetail(true) |
|||
setModelData(record) |
|||
}}> |
|||
查看详情</Button> |
|||
</div> |
|||
) |
|||
} |
|||
} |
|||
] |
|||
|
|||
return ( |
|||
<div id='patrol-record' className='global-main'> |
|||
<div style={{ display: 'flex', justifyContent: 'space-between', padding: '0 10px' }}> |
|||
<Form |
|||
style={{ display: 'flex', }} |
|||
onFinish={r => { |
|||
record({ |
|||
name: r.name, |
|||
time: [moment(r.time[0]).format(format), moment(r.time[1]).format(format)], |
|||
state: r.state |
|||
}) |
|||
}} |
|||
> |
|||
<Form.Item |
|||
name="name" |
|||
style={{ marginRight: 16, minWidth: 250 }} |
|||
> |
|||
<Input placeholder="请输入结构物名称或巡检人" allowClear /> |
|||
</Form.Item> |
|||
<Form.Item |
|||
name="time" |
|||
style={{ marginRight: 16, }} |
|||
initialValue={[moment(search.time[0], format), moment(search.time[1], format)]} |
|||
> |
|||
<DatePicker.RangePicker showTime style={{ marginRight: 16, }} /> |
|||
</Form.Item> |
|||
<Form.Item |
|||
name="state" |
|||
style={{ marginRight: 16, }} |
|||
initialValue={'null'} |
|||
> |
|||
<Select allowClear |
|||
options={[ |
|||
{ value: 'null', label: '全部' }, |
|||
{ value: false, label: '正常' }, |
|||
{ value: true, label: '异常' }]} /> |
|||
</Form.Item> |
|||
<Form.Item wrapperCol={{}}> |
|||
<Button type="primary" htmlType="submit" style={{ marginRight: 16 }}>搜索</Button> |
|||
<Button type="primary" onClick={exportRecord} loading={exportLoading}>导出</Button> |
|||
</Form.Item> |
|||
</Form> |
|||
</div> |
|||
<Table |
|||
columns={columns} |
|||
dataSource={tableList} |
|||
pagination={{ |
|||
className: 'global-pagination', |
|||
showTotal: (total, range) => `第 ${range[0]}-${range[1]} 条/总共 ${total} 条` |
|||
}} |
|||
rowClassName={(record, index) => { |
|||
let className = 'global-light-row'; |
|||
if (index % 2 === 1) className = 'global-dark-row'; |
|||
return className; |
|||
}} |
|||
/> |
|||
<Modal |
|||
title='巡检记录详情' |
|||
open={showDetailModal} |
|||
onCancel={() => setShowDetail(false)} |
|||
footer={[<Button onClick={() => setShowDetail(false)}>关闭</Button>]} |
|||
className='patrol-record-detail-modal' |
|||
width={666} |
|||
> |
|||
{(() => { |
|||
let dataArr = [] |
|||
columns.forEach(c => { |
|||
if (c.showInDetail) { |
|||
dataArr.push( |
|||
<> |
|||
<Row> |
|||
<Col span={5} style={{ |
|||
// textAlign: 'justify', textAlignLast: 'justify'
|
|||
}}>{c.title} :</Col> |
|||
<Col span={19}>{c.render('', modelData)}</Col> |
|||
</Row> |
|||
</> |
|||
) |
|||
} |
|||
}) |
|||
|
|||
if (modelData && modelData.points && modelData.points.inspectContent) { |
|||
//地灾相关详情数据渲染
|
|||
if(modelData.points.aboutDisaster){ |
|||
for (let v in modelData.points.aboutDisaster) { |
|||
dataArr.push( <> |
|||
<Row> |
|||
<Col span={5} style={{ |
|||
// textAlign: 'justify', textAlignLast: 'justify'
|
|||
}}>{aboutDisaster[v]} :</Col> |
|||
<Col span={19}>{modelData.points.aboutDisaster[v]}</Col> |
|||
</Row> |
|||
</>) |
|||
} |
|||
|
|||
} |
|||
if (modelData?.points?.itemData?.pointDevices?.length > 0) { |
|||
let inspectContent = modelData.points.inspectContent |
|||
inspectContent?.map(s => { |
|||
dataArr.push( |
|||
<> |
|||
<Row> |
|||
<Col span={5} style={{}}>{s?.deviceName} :</Col> |
|||
<Col span={19}> |
|||
{ |
|||
!s.alarm ? '正常' : |
|||
<Collapse ghost style={{ padding: 0 }}> |
|||
<Panel header="异常" key="1" style={{ padding: 0 }}> |
|||
{s?.checkItems?.map(k => { |
|||
return <> |
|||
<Row style={{ fontWeight: 'bold' }}>{k.name}:</Row> |
|||
<Row style={{ marginBottom: 20 }}> |
|||
<Col span={4} style={{}}>巡查详情 :</Col> |
|||
<Col span={20}>{k.msgInp}</Col> |
|||
<Col span={4} style={{}}>严重等级 :</Col> |
|||
<Col span={20}>{k.level}</Col> |
|||
<Col span={4} style={{}}>现场照片 :</Col> |
|||
<Col span={20}> |
|||
<Uploads |
|||
listType='picture-card' |
|||
uploadType='project' |
|||
maxFilesNum={1} |
|||
maxFileSize={10} |
|||
isQiniu={true} |
|||
disabled={true} |
|||
fileTypes={["png", "jpg"]} |
|||
defaultValue={ |
|||
(() => { |
|||
let nextV = [] |
|||
for (let s of (k.imgs || [])) { |
|||
if (s) { |
|||
nextV.push({ |
|||
storageUrl: s |
|||
}) |
|||
} |
|||
} |
|||
return nextV |
|||
})() |
|||
} |
|||
/> |
|||
</Col> |
|||
</Row> |
|||
</> |
|||
|
|||
})} |
|||
|
|||
</Panel> |
|||
</Collapse> |
|||
} |
|||
</Col> |
|||
</Row> |
|||
</> |
|||
) |
|||
}) |
|||
|
|||
} else { |
|||
let inspectContent = modelData.points.inspectContent |
|||
for (let v in inspectContent) { |
|||
inspectContent[v]?.checkItems?.map(k => { |
|||
dataArr.push( |
|||
<> |
|||
<Row> |
|||
<Col span={5} style={{}}>{k?.name} :</Col> |
|||
<Col span={19}> |
|||
{ |
|||
!k.level ? '正常' : |
|||
<Collapse ghost style={{ padding: 0 }}> |
|||
<Panel header="异常" key="1" style={{ padding: 0 }}> |
|||
<Row> |
|||
<Col span={4} style={{}}>巡查详情 :</Col> |
|||
<Col span={20}>{k.msgInp}</Col> |
|||
<Col span={4} style={{}}>严重等级 :</Col> |
|||
<Col span={20}>{k.level}</Col> |
|||
<Col span={4} style={{}}>现场照片 :</Col> |
|||
<Col span={20}> |
|||
<Uploads |
|||
listType='picture-card' |
|||
uploadType='project' |
|||
maxFilesNum={1} |
|||
maxFileSize={10} |
|||
isQiniu={true} |
|||
disabled={true} |
|||
fileTypes={["png", "jpg"]} |
|||
defaultValue={ |
|||
(() => { |
|||
let nextV = [] |
|||
for (let s of (k.imgs || [])) { |
|||
if (s) { |
|||
nextV.push({ |
|||
storageUrl: s |
|||
}) |
|||
} |
|||
} |
|||
return nextV |
|||
})() |
|||
} |
|||
/> |
|||
</Col> |
|||
</Row> |
|||
</Panel> |
|||
</Collapse> |
|||
} |
|||
</Col> |
|||
</Row> |
|||
</> |
|||
) |
|||
}) |
|||
|
|||
|
|||
} |
|||
|
|||
} |
|||
|
|||
} |
|||
return dataArr |
|||
})()} |
|||
</Modal> |
|||
</div> |
|||
) |
|||
} |
|||
|
|||
function mapStateToProps(state) { |
|||
const { auth, global } = state; |
|||
return { |
|||
user: auth.user, |
|||
actions: global.actions, |
|||
}; |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(PatrolRecord); |
@ -1,378 +0,0 @@ |
|||
import React, { useState, useRef, useEffect } from 'react'; |
|||
import { connect } from 'react-redux'; |
|||
import { Button, Tabs, Popconfirm, Tooltip, Spin } from 'antd'; |
|||
import ProTable from '@ant-design/pro-table'; |
|||
import { getPatrolReport } from '../actions/report'; |
|||
import { getProjectList } from '../actions/plan'; |
|||
import moment from 'moment'; |
|||
import AddReportRulesModal from '../components/addReportRulesModal'; |
|||
function patrolReport(props) { |
|||
const { dispatch, actions } = props; |
|||
const { projectRegime, patrolManage } = actions |
|||
const tableRef = useRef(); |
|||
const tableRef2 = useRef(); |
|||
const [selectOpts, setSelectOpts] = useState([]); |
|||
const [date, setDate] = useState([moment().subtract(1, 'days'), moment()]); |
|||
const [dataSource, setDataSource] = useState([]); |
|||
const [modalVis, setModalVis] = useState(false) |
|||
const [structAll, setStructAll] = useState([])//完整的结构物列表(包括subType)
|
|||
const [reportList, setReportList] = useState([])//报表
|
|||
const qnDomain = localStorage.getItem('qnDomain'); |
|||
const [query, setQuery] = useState({ limit: 10, page: 0 }) |
|||
const [typeList, setTypeList] = useState([{ value: 1, label: '周报表' }, { value: 2, label: '月报表' }]) |
|||
const [modalData, setModalData] = useState(null) |
|||
const [loading, setLoading] = useState(false) |
|||
//报表配置
|
|||
// const getReportConfig = (query) => {
|
|||
// const { limit, page, name } = query
|
|||
// dispatch(patrolManage.getReportList({ limit, page, name })).then(res => {
|
|||
// if (res.success) {
|
|||
// //过滤管廊类型的数据
|
|||
// const list = res.payload.data?.rows
|
|||
// setReportList(list)
|
|||
// }
|
|||
// })
|
|||
// }
|
|||
//结构物
|
|||
const projectList = () => { |
|||
dispatch(projectRegime.getProjectList()).then(res => { |
|||
if (res.success) { |
|||
|
|||
const nextSelectOpts = res.payload?.data?.rows.map(d => { |
|||
return { label: d.name, value: d.id } |
|||
}) |
|||
setStructAll(res.payload?.data?.rows) |
|||
setSelectOpts(nextSelectOpts) |
|||
// setStructlist(list)
|
|||
} |
|||
}) |
|||
} |
|||
useEffect(() => { |
|||
// dispatch(getProjectList()).then(res => {
|
|||
// if (res.success) {
|
|||
|
|||
// }
|
|||
// });
|
|||
projectList() |
|||
// getReportConfig(query)
|
|||
}, []) |
|||
const edithandler = (e) => { |
|||
setModalData(e) |
|||
setModalVis(true) |
|||
} |
|||
const onOk = () => { |
|||
tableRef2.current.reload(); |
|||
} |
|||
const confirmHandler = (id) => { |
|||
dispatch(patrolManage.delReport(id)).then(res => { |
|||
if (res.success) { |
|||
// getReportConfig(query)
|
|||
tableRef2.current.reload(); |
|||
|
|||
} |
|||
}) |
|||
} |
|||
const generateReport = (record) => { |
|||
setLoading(true) |
|||
let data = { |
|||
reportName: record?.name, |
|||
startTime: moment(record?.startTime).format('YYYY-MM-DD HH:mm:ss'), |
|||
endTime: moment(record?.endTime).format('YYYY-MM-DD HH:mm:ss'), |
|||
structIds: record?.structure, |
|||
structNames: structAll?.filter(item => record?.structure.some(q => q == item.id))?.map(o => o.name) || [], |
|||
reportType: record?.type, |
|||
system: record?.system, |
|||
images: record?.reportpic.map(item => qnDomain + '/' + item) || [] |
|||
} |
|||
dispatch(patrolManage.postGenerateReport(data)).then(res => { |
|||
if (res.success) { |
|||
setLoading(false) |
|||
tableRef.current.reload(); |
|||
|
|||
} |
|||
}) |
|||
} |
|||
//删除巡检记录
|
|||
const delReport = (id) => { |
|||
|
|||
} |
|||
|
|||
|
|||
const columns = [{ |
|||
title: '结构物名称', |
|||
dataIndex: 'projectName', |
|||
key: 'projectName', |
|||
valueType: 'select', |
|||
fieldProps: { |
|||
showSearch: true, |
|||
defaultValue: '', |
|||
options: [{ label: '全部', value: '' }, ...selectOpts], |
|||
}, |
|||
ellipsis: true, |
|||
width: 150, |
|||
render: (_, record) => { |
|||
const rslt = structAll?.filter(p => record.structure?.some(q => q == p.id)) |
|||
return <> |
|||
<div>{record?.project ? record?.project?.name : record.structure?.length > 1 ? <Tooltip title={rslt?.map(item => item.name)?.join(',')}> |
|||
<span>{rslt && rslt.length ? rslt[0].name + '...' : ''}</span> |
|||
</Tooltip> : rslt?.map(item => item.name)?.join(',') |
|||
}</div> |
|||
|
|||
</> |
|||
|
|||
|
|||
} |
|||
}, { |
|||
title: '巡检报告名称', |
|||
dataIndex: 'groupName', |
|||
key: 'groupName', |
|||
ellipsis: true, |
|||
search: false, |
|||
width: 250, |
|||
render: (_, record) => { |
|||
const fileName = record?.excelPath?.substring(record?.excelPath?.lastIndexOf('/') + 1); |
|||
return <div>{fileName}</div> |
|||
} |
|||
}, { |
|||
title: '生成日期', |
|||
dataIndex: 'date', |
|||
key: 'date', |
|||
valueType: 'dateRange', |
|||
fieldProps: { |
|||
value: date, |
|||
onChange: e => { setDate(e) } |
|||
}, |
|||
ellipsis: true, |
|||
width: 150, |
|||
render: (_, record) => { |
|||
return <div>{moment(record?.inspectTm).format('YYYY-MM-DD')}</div> |
|||
} |
|||
}, { |
|||
title: '操作', |
|||
dataIndex: 'action', |
|||
key: 'action', |
|||
search: false, |
|||
width: 200, |
|||
render: (_, record) => { |
|||
return <> |
|||
<Button type="link" onClick={() => { |
|||
window.open(`https://view.officeapps.live.com/op/view.aspx?src=${qnDomain}/${record?.excelPath}`) |
|||
}}>预览</Button> |
|||
{/* onClick={() => { window.open() }} */} |
|||
<a href={'/_file-server' + '/' + record?.excelPath}>下载</a> |
|||
<Popconfirm |
|||
placement='left' |
|||
title={`确定删除?`} |
|||
onConfirm={() => { |
|||
dispatch(patrolManage.delpatrolRecord(record?.id)).then(res=>{ |
|||
if(res.success){ |
|||
tableRef.current.reload(); |
|||
} |
|||
}) |
|||
}} |
|||
> |
|||
<Button type="link">删除</Button> |
|||
</Popconfirm> |
|||
</> |
|||
}, |
|||
}]; |
|||
const column2 = [ |
|||
{ |
|||
title: '报表名称', |
|||
dataIndex: 'name', |
|||
key: 'name', |
|||
ellipsis: true, |
|||
width: 250, |
|||
fieldProps: { |
|||
showSearch: true, |
|||
defaultValue: '', |
|||
}, |
|||
}, |
|||
{ |
|||
title: '报表类型', |
|||
dataIndex: 'type', |
|||
key: 'type', |
|||
ellipsis: true, |
|||
search: false, |
|||
width: 250, |
|||
render: (_, record) => { |
|||
return <> |
|||
{typeList.find(item => record.type == item.value)?.label} |
|||
</> |
|||
} |
|||
|
|||
}, |
|||
{ |
|||
title: '关联结构物', |
|||
dataIndex: 'structure', |
|||
key: 'structure', |
|||
ellipsis: true, |
|||
search: false, |
|||
width: 250, |
|||
render: (_, record) => { |
|||
const rslt = structAll?.filter(p => record.structure?.some(q => q == p.id)) |
|||
return <> |
|||
{record.structure.length > 1 ? <Tooltip title={rslt?.map(item => item.name)?.join(',')}> |
|||
<span>{rslt && rslt.length ? rslt[0].name + '...' : ''}</span> |
|||
</Tooltip> : rslt?.map(item => item.name)?.join(',')} |
|||
</> |
|||
} |
|||
}, |
|||
{ |
|||
title: '生成时间范围', |
|||
key: 'timeRange', |
|||
// ellipsis: true,
|
|||
search: false, |
|||
width: 250, |
|||
render: (_, record) => { |
|||
return <> |
|||
{moment(record.startTime).format('YYYY-MM-DD')} ~ {moment(record.endTime).format('YYYY-MM-DD')} |
|||
</> |
|||
} |
|||
}, |
|||
{ |
|||
title: '系统', |
|||
key: 'system', |
|||
// ellipsis: true,
|
|||
search: false, |
|||
width: 250, |
|||
render: (_, record) => { |
|||
return <> |
|||
{record.system ? record.system === 1 ? '动力系统' : record.system === 2 ? '网络系统' : '--' : '--'} |
|||
</> |
|||
} |
|||
}, |
|||
{ |
|||
title: '操作', |
|||
key: 'option', |
|||
// ellipsis: true,
|
|||
search: false, |
|||
width: 250, |
|||
render: (_, record) => { |
|||
return <> |
|||
<Button type="primary" style={{ marginRight: 10 }} onClick={() => { edithandler(record) }}>编辑</Button> |
|||
<Popconfirm title="确定删除报表吗" |
|||
description="确定删除报表吗?" |
|||
onConfirm={() => { confirmHandler(record?.id) }} |
|||
><Button type="primary" style={{ marginRight: 10 }} danger>删除</Button></Popconfirm> |
|||
<Button type="primary" onClick={() => { generateReport(record) }}>立即生成</Button> |
|||
</> |
|||
} |
|||
} |
|||
] |
|||
|
|||
const onChange = (key) => { |
|||
|
|||
}; |
|||
const cancelHandle = () => { |
|||
setModalVis(false) |
|||
setModalData(null) |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
return ( |
|||
|
|||
<> |
|||
<Tabs |
|||
defaultActiveKey="1" |
|||
onChange={onChange} |
|||
items={[ |
|||
{ |
|||
label: `报表列表`, |
|||
key: '1', |
|||
children: <ProTable |
|||
columns={columns} |
|||
actionRef={tableRef} |
|||
options={false} |
|||
dataSource={dataSource || []} |
|||
rowKey='id' |
|||
pagination={{ pageSize: 10, size: 'default', className: 'global-pagination' }} |
|||
request={async (params = {}) => { |
|||
const res = await dispatch(getPatrolReport({ |
|||
limit: params?.pageSize, |
|||
page: params?.current - 1, |
|||
projectId: params?.projectName, |
|||
startTime: date ? date[0].format('YYYY-MM-DD') + ' 00:00:00' : '', |
|||
endTime: date ? date[1].format('YYYY-MM-DD') + ' 23:59:59' : '', |
|||
})); |
|||
setDataSource(res?.payload.data?.rows); |
|||
return { |
|||
...res, |
|||
total: res.payload.data.count ? res.payload.data.count : 0, |
|||
}; |
|||
}} |
|||
onReset={() => { setDate([moment().subtract(1, 'days'), moment()]) }} |
|||
rowClassName={(record, index) => { |
|||
let className = 'global-light-row'; |
|||
if (index % 2 === 1) className = 'global-dark-row'; |
|||
return className; |
|||
}} |
|||
/>, |
|||
}, |
|||
{ |
|||
label: `报表配置`, |
|||
key: '2', |
|||
children: <> |
|||
<Spin spinning={loading}> |
|||
<ProTable |
|||
|
|||
actionRef={tableRef2} |
|||
options={false} |
|||
columns={column2} |
|||
dataSource={reportList || []} |
|||
pagination={{ pageSize: 10, size: 'default', className: 'global-pagination' }} |
|||
request={async (query) => { |
|||
const { limit, page, name } = query |
|||
const res = await dispatch(patrolManage.getReportList({ limit, page, name })) |
|||
const list = res?.payload?.data?.rows |
|||
setReportList(list) |
|||
return { |
|||
...res, |
|||
total: res.payload.data.count ? res.payload.data.count : 0, |
|||
}; |
|||
}} |
|||
// cardProps={{ title: '新建报表规则', bordered: true }}
|
|||
headerTitle={ |
|||
<Button |
|||
key="primary" |
|||
type="primary" |
|||
onClick={() => { |
|||
setModalVis(true) |
|||
}} |
|||
> |
|||
新建报表规则 |
|||
</Button> |
|||
|
|||
} |
|||
rowKey="key" |
|||
search={true} |
|||
/> |
|||
</Spin> |
|||
<AddReportRulesModal structAll={structAll} typeList={typeList} modalData={modalData} onOk={onOk} visible={modalVis} cancelHandle={cancelHandle}> |
|||
|
|||
</AddReportRulesModal> |
|||
</> |
|||
, |
|||
}, |
|||
|
|||
]} |
|||
/> |
|||
|
|||
</> |
|||
) |
|||
} |
|||
|
|||
function mapStateToProps(state) { |
|||
const { auth, structureList, global } = state |
|||
return { |
|||
user: auth.user, |
|||
struList: structureList.data || [], |
|||
struLoading: structureList.isRequesting, |
|||
actions: global.actions, |
|||
} |
|||
} |
|||
export default connect(mapStateToProps)(patrolReport); |
@ -1,136 +0,0 @@ |
|||
import React, { useState, useRef, useEffect } from 'react'; |
|||
import { connect } from 'react-redux'; |
|||
import { Button, Popconfirm, Tag } from 'antd'; |
|||
import ProTable from '@ant-design/pro-table'; |
|||
import PlanTemplateModal from '../components/planTemplateModal'; |
|||
import { createPatrolTemplate, delPatrolTemplate, updatePatrolTemplate, getPatrolTemplate } from '../actions/template'; |
|||
import { getCheckItemsGroup } from '../actions/checkItems'; |
|||
|
|||
function PatrolTemplate(props) { |
|||
const { dispatch, user } = props; |
|||
const tableRef = useRef(); |
|||
const [dataSource, setDataSource] = useState([{}]); |
|||
const [visible, setVisible] = useState(false); |
|||
const [type, setType] = useState(); |
|||
const [curRecord, setCurRecord] = useState(); |
|||
|
|||
useEffect(() => { |
|||
dispatch(getCheckItemsGroup()) |
|||
}, []) |
|||
|
|||
const columns = [{ |
|||
title: '模板名称', |
|||
dataIndex: 'name', |
|||
key: 'name', |
|||
ellipsis: true, |
|||
}, { |
|||
title: '模板描述', |
|||
dataIndex: 'describe', |
|||
key: 'describe', |
|||
ellipsis: true, |
|||
search: false, |
|||
}, { |
|||
title: '操作人', |
|||
dataIndex: 'user.name', |
|||
key: 'user.name', |
|||
ellipsis: true, |
|||
search: false, |
|||
render: (t, r, i) => { |
|||
return r.user ? r.user.name : '-' |
|||
} |
|||
}, { |
|||
title: '检查项', |
|||
dataIndex: 'checkItems', |
|||
key: 'checkItems', |
|||
ellipsis: true, |
|||
search: false, |
|||
render: (_, r) => { |
|||
return r?.checkItems ? r?.checkItems.map(c => <Tag>{c.name}</Tag>) : '-' |
|||
} |
|||
}, { |
|||
title: '操作', |
|||
dataIndex: 'action', |
|||
key: 'action', |
|||
search: false, |
|||
width: 200, |
|||
render: (_, record) => { |
|||
return <> |
|||
<Button type="link" onClick={() => { |
|||
setType('edit') |
|||
setCurRecord(record) |
|||
setVisible(true) |
|||
}}>修改</Button> |
|||
<Popconfirm |
|||
title="确认删除?" |
|||
onConfirm={() => { |
|||
dispatch(delPatrolTemplate(record.id)).then(res => { |
|||
if (res.success) { |
|||
tableRef.current.reload(); |
|||
} |
|||
}) |
|||
}}> |
|||
<Button type="link" danger disabled={record && record.patrolPlans && record.patrolPlans.length}>删除</Button> |
|||
</Popconfirm> |
|||
</> |
|||
}, |
|||
}]; |
|||
|
|||
return ( |
|||
<> |
|||
<ProTable |
|||
columns={columns} |
|||
actionRef={tableRef} |
|||
options={false} |
|||
dataSource={dataSource || []} |
|||
rowKey='id' |
|||
pagination={{ pageSize: 10, size: 'default', className: 'global-pagination' }} |
|||
search={{ |
|||
defaultCollapsed: false, |
|||
optionRender: (searchConfig, formProps, dom) => [ |
|||
...dom.reverse(), |
|||
<Button |
|||
type="primary" |
|||
key="primary" |
|||
onClick={() => { |
|||
setType('create') |
|||
setVisible(true) |
|||
}} |
|||
>新增巡检模板</Button>, |
|||
], |
|||
}} |
|||
request={async (params = {}) => { |
|||
const res = await dispatch(getPatrolTemplate(params)); |
|||
setDataSource(res?.payload.data?.rows); |
|||
return { ...res }; |
|||
}} |
|||
onReset={() => { }} |
|||
rowClassName={(record, index) => { |
|||
let className = 'global-light-row'; |
|||
if (index % 2 === 1) className = 'global-dark-row'; |
|||
return className; |
|||
}} |
|||
/> |
|||
{ |
|||
visible ? |
|||
<PlanTemplateModal |
|||
visible={visible} |
|||
type={type} |
|||
curRecord={curRecord} |
|||
onCancel={() => { |
|||
setVisible(false); |
|||
setCurRecord({}) |
|||
}} |
|||
tableRef={tableRef} |
|||
/> : null |
|||
} |
|||
</> |
|||
) |
|||
} |
|||
|
|||
function mapStateToProps(state) { |
|||
const { auth } = state |
|||
return { |
|||
user: auth.user |
|||
} |
|||
} |
|||
export default connect(mapStateToProps)(PatrolTemplate); |
@ -1,300 +0,0 @@ |
|||
import React, { useState, useRef, useEffect } from 'react'; |
|||
import { connect } from 'react-redux'; |
|||
import { Button, Popconfirm, Tag,Tabs } from 'antd'; |
|||
import ProTable from '@ant-design/pro-table'; |
|||
import Xiafagaojin from '../components/xiafagaojin'; |
|||
import {getDepUser} from '../../organization/actions/user' |
|||
import { createPatrolTemplate, delPatrolTemplate, updatePatrolTemplate, getPatrolTemplate } from '../actions/template'; |
|||
import { getCheckItemsGroup } from '../actions/checkItems'; |
|||
import moment from 'moment'; |
|||
function YujingGuanli (props) { |
|||
const { dispatch, user,actions,depUser} = props; |
|||
const tableRef = useRef(); |
|||
const format = 'YYYY-MM-DD HH:mm:ss' |
|||
const { patrolManage } = actions |
|||
const [dataSource, setDataSource] = useState([{}]); |
|||
const [dataSource2, setDataSource2] = useState([{}]); |
|||
const [visible, setVisible] = useState(false); |
|||
const [type, setType] = useState(); |
|||
const [curRecord, setCurRecord] = useState(); |
|||
const [tabs,settabs] = useState(1) |
|||
const [data,setdata]= useState([]) |
|||
const [tableList, settableList] = useState([]) |
|||
const [name, setName] = useState(''); |
|||
const [curState, setCurState] = useState('全部'); |
|||
const times = [moment().subtract(70, 'years').format(format), moment().format(format)] |
|||
const [search, setSearch] = useState({ name: null, time: [times[0], times[1]], state: 'null' }) |
|||
const STATE_TEXT = { 1: '待制定计划', 2: '待审核', 3: '计划驳回', 4: '待维修', 5: '待验收', 6: '验收通过', 7: '验收不通过', } |
|||
const onChange = (key) => { |
|||
settabs(key) |
|||
}; |
|||
const renderOptionText = (currentState) => { |
|||
let text = '待制定计划' |
|||
|
|||
return STATE_TEXT[currentState] || text |
|||
} |
|||
const queryData = () => { |
|||
dispatch(patrolManage.records(`patrolRecord/all/${times[0]}/${times[1]}/true/null`)).then(res => { |
|||
if (res.success) { |
|||
console.log(res,'水平') |
|||
|
|||
// res?.payload?.data?.map(i=>{
|
|||
// if(obj[i?.points?.project?.id]){
|
|||
// // if(obj[i?.points?.project?.id.toString()][i.pointId.toString()]){
|
|||
// // obj[i?.points?.project?.id.toString()][i.pointId.toString()].ponintname=i.points?.itemData?.name
|
|||
// // obj[i?.points?.project?.id.toString()][i.pointId.toString()].num=obj[i?.points?.project?.id.toString()][i.pointId.toString()].num+i?.patrolRecordIssueHandles[0]?.state==6?1:0
|
|||
|
|||
// // }else{
|
|||
// // obj[i?.points?.project?.id.toString()][i.pointId.toString()].ponintname=i.points?.itemData?.name
|
|||
// // obj[i?.points?.project?.id.toString()][i.pointId.toString()].num=i?.patrolRecordIssueHandles[0]?.state==6?1:0
|
|||
// // }
|
|||
// obj[i?.points?.project?.id]?.push({pointId:i.pointId,pointname:i.points.itemData.name})
|
|||
// // i?patrolRecordIssueHandles[0]?.state==6
|
|||
// obj[i?.points?.project?.id].num= obj[i?.points?.project?.id].num + i?.patrolRecordIssueHandles[0]?.state==6 ?1:0
|
|||
// }else{
|
|||
// obj[i?.points?.project?.id]={name:i?.points?.project?.name,num:i?.patrolRecordIssueHandles[0]?.state==6 ?1:0 }
|
|||
|
|||
// }
|
|||
// console.log(obj,'obj')
|
|||
// })
|
|||
|
|||
} |
|||
}) |
|||
} |
|||
console.log(depUser,'depUser') |
|||
useEffect(() => { |
|||
|
|||
dispatch(getDepUser()) |
|||
queryData() |
|||
// dispatch(getCheckItemsGroup())
|
|||
}, []) |
|||
// console.log(tableList,'tablist')
|
|||
const columns = [{ |
|||
title: '结构物名称', |
|||
dataIndex: 'name', |
|||
key: 'name', |
|||
// search: false,
|
|||
ellipsis: true, |
|||
render: (t, r, i) => { |
|||
// console.log(r,'测试')
|
|||
return r?.points?.project?.name |
|||
} |
|||
}, { |
|||
title: '点位名称', |
|||
dataIndex: 'pointname', |
|||
key: 'pointname', |
|||
search: false, |
|||
ellipsis: true, |
|||
render: (t, r, i) => { |
|||
// console.log(r,'测试')
|
|||
return r?.points?.itemData?.name |
|||
} |
|||
}, { |
|||
title: '异常次数', |
|||
dataIndex: 'yanshoucishu', |
|||
key: 'yanshoucishu', |
|||
ellipsis: true, |
|||
search: false, |
|||
render: (t, r, i) => { |
|||
|
|||
return r?.patrolRecordIssueHandles && r?.patrolRecordIssueHandles[0]?.yanshoucishu |
|||
} |
|||
}, { |
|||
title: '产生时间', |
|||
dataIndex: 'yujingshijian', |
|||
key: 'yujingshijia', |
|||
ellipsis: true, |
|||
search: false, |
|||
render: (_, r) => { |
|||
return r?.patrolRecordIssueHandles && moment(r?.patrolRecordIssueHandles[0]?.yujingshijian).format('YYYY-MM-DD HH:mm:ss') |
|||
} |
|||
}, { |
|||
title: '更新时间', |
|||
dataIndex: 'updatatime', |
|||
key: 'updatatime', |
|||
search: false, |
|||
ellipsis: true, |
|||
render: (_, r) => { |
|||
return r?.patrolRecordIssueHandles && moment(r?.patrolRecordIssueHandles[0]?.yanshoushijian).format('YYYY-MM-DD HH:mm:ss') |
|||
} |
|||
}, { |
|||
title: '操作', |
|||
dataIndex: 'action', |
|||
key: 'action', |
|||
search: false, |
|||
width: 200, |
|||
render: (_, record) => { |
|||
return <> |
|||
<Button type="link" onClick={() => { |
|||
setType('edit') |
|||
setCurRecord(record) |
|||
setVisible(true) |
|||
}}>下发告警</Button> |
|||
|
|||
</> |
|||
}, |
|||
}]; |
|||
const columns1 = [{ |
|||
title: '结构物名称', |
|||
dataIndex: 'name', |
|||
key: 'name', |
|||
// search: false,
|
|||
ellipsis: true, |
|||
render: (t, r, i) => { |
|||
// console.log(r,'测试')
|
|||
return r?.points?.project?.name |
|||
} |
|||
}, { |
|||
title: '点位名称', |
|||
dataIndex: 'pointname', |
|||
key: 'pointname', |
|||
search: false, |
|||
ellipsis: true, |
|||
render: (t, r, i) => { |
|||
// console.log(r,'测试')
|
|||
return r?.points?.itemData?.name |
|||
} |
|||
}, { |
|||
title: '异常次数', |
|||
dataIndex: 'yanshoucishu', |
|||
key: 'yanshoucishu', |
|||
ellipsis: true, |
|||
search: false, |
|||
render: (t, r, i) => { |
|||
// console.log(r,'r')
|
|||
return r?.patrolRecordIssueHandles && r?.patrolRecordIssueHandles[0]?.yanshoucishu |
|||
} |
|||
}, { |
|||
title: '下发时间', |
|||
dataIndex: 'yujingshijian', |
|||
key: 'yujingshijia', |
|||
ellipsis: true, |
|||
search: false, |
|||
render: (_, r) => { |
|||
return r?.patrolRecordIssueHandles && moment(r?.patrolRecordIssueHandles[0]?.yujingshijian).format('YYYY-MM-DD HH:mm:ss') |
|||
} |
|||
}]; |
|||
return ( |
|||
<> |
|||
<Tabs |
|||
activeKey={tabs} |
|||
onChange={onChange} |
|||
style={{marginLeft:'20px',marginRight:'20px'}} |
|||
items={[ |
|||
{ |
|||
label: `未告警`, |
|||
key: 1, |
|||
children: <ProTable |
|||
columns={columns} |
|||
actionRef={tableRef} |
|||
options={false} |
|||
dataSource={dataSource || []} |
|||
rowKey='id' |
|||
pagination={{ pageSize: 10 }} |
|||
// search={false}
|
|||
request={async (params = {}) => { |
|||
// dispatch(patrolManage.records(`patrolRecord/all/${times[0]}/${times[1]}/true/null`)).then(res => {
|
|||
// if (res.success) {
|
|||
// console.log(res,'水平')
|
|||
// const t1 = res?.payload?.data?.filter(i=>i.patrolRecordIssueHandles[0]?.isgaojing!==true&& i.patrolRecordIssueHandles[0]?.yanshoucishu>=3)
|
|||
// }
|
|||
// })
|
|||
const res = await dispatch(patrolManage.records(`patrolRecord/all/${times[0]}/${times[1]}/true/null`)); |
|||
const data = res?.payload?.data?.filter(i=>{ |
|||
|
|||
return i?.patrolRecordIssueHandles[0]?.yanshoucishu>2&&i?.patrolRecordIssueHandles[0]?.isgaojing!==true |
|||
&&res?.payload?.data?.filter(j=>j?.pointId===i?.pointId&&j?.points?.project?.id===i?.points?.project?.id |
|||
&&j?.patrolRecordIssueHandles[0]?.yujingshijian |
|||
&&i?.patrolRecordIssueHandles[0]?.yujingshijian |
|||
&&moment(i?.patrolRecordIssueHandles[0].yanshoushijian).valueOf()<moment(j?.patrolRecordIssueHandles[0]?.yanshoushijian).valueOf() |
|||
).length===0 |
|||
}) |
|||
// console.log(res,'res')
|
|||
// console.log(data,'data')
|
|||
// setDataSource(res?.payload?.data.filter(i=>i?.points?.project?.name.match(params.name)));
|
|||
setDataSource(data.filter(i=>i?.points?.project?.name.match(params.name))); |
|||
}} |
|||
/>, |
|||
}, |
|||
{ |
|||
label: `已告警`, |
|||
key: 2, |
|||
children: <ProTable |
|||
columns={columns1} |
|||
actionRef={tableRef} |
|||
options={false} |
|||
dataSource={dataSource2 || []} |
|||
rowKey='id' |
|||
pagination={{ pageSize: 10 }} |
|||
// search={false}
|
|||
request={async (params = {}) => { |
|||
const res = await dispatch(patrolManage.records(`patrolRecord/all/${times[0]}/${times[1]}/true/null`)); |
|||
const data = res?.payload?.data?.filter(i=>{ |
|||
return i?.patrolRecordIssueHandles[0]?.isgaojing===true&&i?.patrolRecordIssueHandles[0]?.yujingafchishu===null |
|||
// &&res?.payload?.data?.filter(j=>
|
|||
// {
|
|||
// return j?.pointId===i?.pointId
|
|||
// &&j?.points?.project?.id===i?.points?.project?.id&&i?.patrolRecordIssueHandles[0]?.yujingshijian&&
|
|||
// parseInt(moment(i?.patrolRecordIssueHandles[0].yujingshijian).format('YYYYMMDDHHMMSS'))<parseInt(moment(j?.patrolRecordIssueHandles[0]?.yujingshijian).format('YYYYMMDDHHMMSS'))
|
|||
// }).length===0
|
|||
}) |
|||
console.log(data,'data') |
|||
setDataSource2(data.filter(i=>i?.points?.project?.name.match(params.name)).sort((a, b) => moment(b.patrolRecordIssueHandles[0].yanshoushijian).valueOf() - moment(a.patrolRecordIssueHandles[0].yanshoushijian).valueOf())); |
|||
|
|||
}} |
|||
/>, |
|||
} |
|||
]} |
|||
/> |
|||
{ |
|||
visible &&depUser.filter(i=>i.username&&i.email).length!==0 ? |
|||
<Xiafagaojin |
|||
visible={visible} |
|||
type={type} |
|||
curRecord={curRecord} |
|||
userlist={depUser.filter(i=>i.username&&i.email)} |
|||
onCancel={() => { |
|||
setVisible(false); |
|||
setCurRecord({}) |
|||
}} |
|||
onHandle={async ()=>{ |
|||
const res = await dispatch(patrolManage.records(`patrolRecord/all/${times[0]}/${times[1]}/true/null`)); |
|||
const data2 = res?.payload?.data?.filter(i=>{ |
|||
return i?.patrolRecordIssueHandles[0]?.isgaojing===true&&i?.patrolRecordIssueHandles[0]?.yujingafchishu===null |
|||
// &&res?.payload?.data?.filter(j=>
|
|||
// {
|
|||
// return j?.pointId===i?.pointId
|
|||
// &&j?.points?.project?.id===i?.points?.project?.id&&i?.patrolRecordIssueHandles[0]?.yujingshijian&&
|
|||
// parseInt(moment(i?.patrolRecordIssueHandles[0].yujingshijian).format('YYYYMMDDHHMMSS'))<parseInt(moment(j?.patrolRecordIssueHandles[0]?.yujingshijian).format('YYYYMMDDHHMMSS'))
|
|||
// }).length===0
|
|||
}) |
|||
// console.log(data,'data')
|
|||
const data = res?.payload?.data?.filter(i=>{ |
|||
return i?.patrolRecordIssueHandles[0]?.yanshoucishu>2&&i?.patrolRecordIssueHandles[0]?.isgaojing!==true |
|||
&&res?.payload?.data?.filter(j=>j?.pointId===i?.pointId |
|||
&&j?.points?.project?.id===i?.points?.project?.id |
|||
&&moment(i?.patrolRecordIssueHandles[0].yanshoushijian).valueOf()<moment(j?.patrolRecordIssueHandles[0]?.yanshoushijian).valueOf() |
|||
).length===0 |
|||
}) |
|||
console.log(res,'res') |
|||
// setDataSource(res?.payload?.data.filter(i=>i?.points?.project?.name.match(params.name)));
|
|||
setDataSource(data); |
|||
setDataSource2(data2.sort((a, b) => moment(b.patrolRecordIssueHandles[0].yanshoushijian).valueOf() - moment(a.patrolRecordIssueHandles[0].yanshoushijian).valueOf())); |
|||
settabs(2) |
|||
}} |
|||
tableRef={tableRef} |
|||
/> : null |
|||
} |
|||
</> |
|||
) |
|||
} |
|||
|
|||
function mapStateToProps (state) { |
|||
const { auth, global ,depUser} = state |
|||
return { |
|||
user: auth.user, |
|||
actions: global.actions, |
|||
depUser: depUser.data || [], |
|||
} |
|||
} |
|||
export default connect(mapStateToProps)(YujingGuanli); |
@ -1,15 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
import reducers from './reducers'; |
|||
import routes from './routes'; |
|||
import actions from './actions'; |
|||
import { getNavItem } from './nav-item'; |
|||
|
|||
export default { |
|||
key: 'patrolManage', |
|||
name: '', |
|||
reducers: reducers, |
|||
routes: routes, |
|||
actions: actions, |
|||
getNavItem: getNavItem |
|||
}; |
@ -1,34 +0,0 @@ |
|||
import React from 'react'; |
|||
import { Link } from 'react-router-dom'; |
|||
import { Menu } from 'antd'; |
|||
import { GatewayOutlined } from '@ant-design/icons'; |
|||
import { Func } from '$utils'; |
|||
const SubMenu = Menu.SubMenu; |
|||
|
|||
export function getNavItem (user, dispatch) { |
|||
// if (!Func.isAuthorized("ORG_MANAGE")) {
|
|||
// return null
|
|||
// }
|
|||
return ( |
|||
Func.isAuthorized('PATROL_MANAGE') && <SubMenu key="patrolManage" icon={<img src='/assets/images/menu/xun.svg' style={{ width: 24, height: 24 }} />} title={'巡检管理'}> |
|||
{Func.isAuthorized('PATROL_PLAN_CONFIG') && <Menu.Item key="patrolPlan"> |
|||
<Link to="/patrolManage/patrolPlan">巡检计划制定</Link> |
|||
</Menu.Item>} |
|||
{Func.isAuthorized('PATROL_RECORD_VIEW') && <Menu.Item key="patrolRecord"> |
|||
<Link to="/patrolManage/patrolRecord">巡检记录</Link> |
|||
</Menu.Item>} |
|||
{Func.isAuthorized('CHECKREPORT') && <Menu.Item key="patrolReport"> |
|||
<Link to="/patrolManage/patrolReport">巡检报告</Link> |
|||
</Menu.Item>} |
|||
{Func.isAuthorized('CHECKITEMSET') && <Menu.Item key="checkItems"> |
|||
<Link to="/patrolManage/checkItems">检查项设定</Link> |
|||
</Menu.Item>} |
|||
{Func.isAuthorized('CHECKMOULD') && <Menu.Item key="patrolTemplate"> |
|||
<Link to="/patrolManage/patrolTemplate">巡检模板</Link> |
|||
</Menu.Item>} |
|||
{ <Menu.Item key="yujingguanli"> |
|||
<Link to="/patrolManage/yujingguanli">预警管理</Link> |
|||
</Menu.Item>} |
|||
</SubMenu> |
|||
); |
|||
} |
@ -1,5 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
export default { |
|||
|
|||
}; |
@ -1,32 +0,0 @@ |
|||
'use strict'; |
|||
import * as actionTypes from '../actions/record'; |
|||
import Immutable from 'immutable'; |
|||
|
|||
const initState = { |
|||
data: {}, |
|||
isRequesting: false, |
|||
error: null |
|||
}; |
|||
|
|||
function record(state = initState, action) { |
|||
const payload = action.payload; |
|||
switch (action.type){ |
|||
case actionTypes.GET_PATROL_RECORD_LIST: |
|||
return Immutable.fromJS(state).set('data', |
|||
payload.data).toJS(); |
|||
case actionTypes.GET_PATROL_RECORD_LIST_SUCCESS: |
|||
return Immutable.fromJS(state).merge({ |
|||
isRequesting: false, |
|||
data: payload.data |
|||
}).toJS(); |
|||
case actionTypes.GET_PATROL_RECORD_LIST_ERROR: |
|||
return Immutable.fromJS(state).merge({ |
|||
isRequesting: false, |
|||
error: payload.error |
|||
}).toJS(); |
|||
default: |
|||
return state; |
|||
} |
|||
} |
|||
|
|||
export default record; |
@ -1,44 +0,0 @@ |
|||
'use strict'; |
|||
import { PatrolPlan, PatrolReocrd, PatrolReport, CheckItems, PlanTemplate ,YujingGuanli} from './containers'; |
|||
|
|||
export default [{ |
|||
type: 'inner', |
|||
route: { |
|||
path: '/patrolManage', |
|||
key: 'patrolManage', |
|||
breadcrumb: '巡检管理', |
|||
childRoutes: [{ |
|||
path: '/patrolPlan', |
|||
key: 'patrolPlan', |
|||
component: PatrolPlan, |
|||
breadcrumb: '巡检计划制定', |
|||
}, { |
|||
path: '/patrolRecord', |
|||
key: 'patrolRecord', |
|||
component: PatrolReocrd, |
|||
breadcrumb: '巡检记录', |
|||
}, { |
|||
path: '/patrolReport', |
|||
key: 'patrolReport', |
|||
component: PatrolReport, |
|||
breadcrumb: '巡检报告', |
|||
}, { |
|||
path: '/checkItems', |
|||
key: 'checkItems', |
|||
component: CheckItems, |
|||
breadcrumb: '检查项设定', |
|||
}, { |
|||
path: '/patrolTemplate', |
|||
key: 'patrolTemplate', |
|||
component: PlanTemplate, |
|||
breadcrumb: '巡检模板', |
|||
}, |
|||
{ |
|||
path: '/yujingguanli', |
|||
key: 'yujingguanli', |
|||
component: YujingGuanli, |
|||
breadcrumb: '预警管理', |
|||
} |
|||
] |
|||
} |
|||
}]; |
@ -1,5 +0,0 @@ |
|||
.patrol-record-detail-modal { |
|||
.ant-collapse>.ant-collapse-item>.ant-collapse-header { |
|||
padding: 0 |
|||
} |
|||
} |
@ -1,6 +0,0 @@ |
|||
|
|||
'use strict'; |
|||
import projectBinding from './projectBinding' |
|||
export default { |
|||
...projectBinding |
|||
} |
@ -1,59 +0,0 @@ |
|||
'use strict'; |
|||
import { basicAction } from '@peace/utils' |
|||
import { ApiTable } from '$utils' |
|||
|
|||
export function getanxinyunProject(data) { |
|||
return dispatch => basicAction({ |
|||
type: 'post', |
|||
dispatch: dispatch, |
|||
data, |
|||
actionType: 'GET_ANXINYUN_PROJECT', |
|||
url: `${ApiTable.getanxinyunProject}`, |
|||
msg: { error: '获取安心云结构物失败' }, |
|||
reducer: { name: 'anxinyunProject'} |
|||
}); |
|||
} |
|||
|
|||
|
|||
export function addorEditRelation(data) { |
|||
return dispatch => basicAction({ |
|||
type: 'post', |
|||
dispatch: dispatch, |
|||
data, |
|||
actionType: 'ADD_OR_EDIT_RELATION', |
|||
url: `${ApiTable.addorEditRelation}`, |
|||
msg: { option:data?.id? '编辑绑定关系':'新增绑定关系' }, |
|||
// reducer: { name: 'anxinyunProject'}
|
|||
}); |
|||
} |
|||
|
|||
export function getRelation(query) { |
|||
return dispatch => basicAction({ |
|||
type: 'get', |
|||
query, |
|||
dispatch: dispatch, |
|||
actionType: 'GET_RELATION', |
|||
url: `${ApiTable.getRelation}`, |
|||
msg: { error:'查询项目映射关系失败' }, |
|||
reducer: { name: 'relation'} |
|||
}); |
|||
} |
|||
|
|||
export function delRelation(id) { |
|||
return dispatch => basicAction({ |
|||
type: 'delete', |
|||
dispatch: dispatch, |
|||
actionType: 'DEL_RELATION', |
|||
url: ApiTable.delRelation.replace('{id}', id), |
|||
msg: { option:'删除项目映射关系' }, |
|||
// reducer: { name: 'anxinyunProject'}
|
|||
}); |
|||
} |
|||
|
|||
|
|||
export default{ |
|||
getanxinyunProject, |
|||
getRelation, |
|||
addorEditRelation, |
|||
delRelation |
|||
} |
@ -1,88 +0,0 @@ |
|||
import React, { useRef,useState,useEffect } from 'react' |
|||
import { Button, Form } from 'antd' |
|||
import { connect } from 'react-redux'; |
|||
import { InfoCircleOutlined } from '@ant-design/icons' |
|||
import { ModalForm, ProFormSelect, ProFormText, ProFormDatePicker } from '@ant-design/pro-form' |
|||
import moment from 'moment' |
|||
function RelationModal(props) { |
|||
const { title, triggerRender, editData = null, onFinish, devices,actions,dispatch,proejctListOpt,structureListOpt } = props |
|||
const{projectBinding}=actions |
|||
const formItemLayout = { labelCol: { span: 6 }, wrapperCol: { span: 16 } } |
|||
const initialValues = editData? { ...editData,} : {} |
|||
const [form] = Form.useForm() |
|||
const formRef = useRef() |
|||
|
|||
|
|||
return ( |
|||
<ModalForm |
|||
formRef={formRef} |
|||
title={title || ''} |
|||
initialValues={initialValues} |
|||
trigger={triggerRender ? triggerRender : <Button type='primary'>{title || ''}</Button>} |
|||
layout='horizontal' |
|||
grid={true} |
|||
{...formItemLayout} |
|||
modalProps={{ |
|||
destroyOnClose: true, |
|||
onCancel: () => {}, |
|||
}} |
|||
onFinish={async values => { |
|||
// console.log('values1',editData)
|
|||
let value={ |
|||
anxinyunProject:values?.anxinyunProject, |
|||
structName:values?.structName, |
|||
id:initialValues?initialValues.key:null |
|||
} |
|||
return onFinish && (await onFinish(value)) |
|||
// return true;
|
|||
}} |
|||
width={500}> |
|||
<ProFormSelect |
|||
rules={[{ required: true, message: '安心云结构物' }]} |
|||
showSearch |
|||
options={proejctListOpt?.map(s => { |
|||
return { label: s.label, value: s.value } |
|||
})} |
|||
name='anxinyunProject' |
|||
label='安心云结构物' |
|||
/> |
|||
<ProFormSelect |
|||
rules={[{ required: true, message: '关联结构物' }]} |
|||
showSearch |
|||
options={structureListOpt?.map(s => { |
|||
return { label: s.label, value: s.value } |
|||
})} |
|||
name='structName' |
|||
label='关联结构物' |
|||
/> |
|||
</ModalForm> |
|||
) |
|||
} |
|||
function mapStateToProps(state) { |
|||
const {auth, global, device } = state; |
|||
return { |
|||
loading: device.isRequesting, |
|||
clientHeight: global.clientHeight, |
|||
actions: global.actions, |
|||
}; |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
export const DEVICE_TYPES = [ |
|||
'安防系统', |
|||
'厨房系统', |
|||
'电梯', |
|||
'供电系统', |
|||
'空调', |
|||
'排水系统', |
|||
'水系统', |
|||
'通道门禁', |
|||
'通风系统', |
|||
'通信系统', |
|||
'显示视频', |
|||
'消防系统', |
|||
'照明系统', |
|||
] |
|||
export default connect(mapStateToProps)(RelationModal) |
@ -1,5 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
import ProjectBinding from './projectBinding' |
|||
|
|||
export { ProjectBinding }; |
@ -1,304 +0,0 @@ |
|||
import React, { useEffect, useState, useRef, useMemo } from 'react' |
|||
import { Spin, Popconfirm, message, Button, Input, Select } from 'antd' |
|||
import { connect } from 'react-redux' |
|||
import ProTable from '@ant-design/pro-table' |
|||
import moment from 'moment' |
|||
import RelationModal from '../components/relationModal' |
|||
function ProjectBinding(props) { |
|||
const {loading, clientHeight, actions, dispatch, devices,anxinyunProjectLoading,relationLoading } = props |
|||
const { projectBinding, projectRegime } = actions |
|||
const tableRef = useRef() |
|||
const proTableFormRef = useRef() |
|||
const [proejctListOpt, setProjectListOpt] = useState([])//安心云结构物
|
|||
const [structureListOpt, setStructureListOpt] = useState([])//巡检结构物
|
|||
const [dataSource, setDataSource] = useState([]) |
|||
// const [dataCopy,setDataCopy]=useState([])
|
|||
const [tableParams, setTableParams] = useState({}) |
|||
// const fetchData = async () => {
|
|||
// let data={
|
|||
// url:"users/{orgId}/projects",
|
|||
// type:"get"
|
|||
// }
|
|||
// dispatch(projectBinding.getanxinyunProject(data)).then(async res=>{
|
|||
// if(res.success){
|
|||
// const d=res.payload.data?.map(item=>{
|
|||
// return {
|
|||
// label:item?.projects[0]?.name,
|
|||
// value:item?.projects[0]?.id
|
|||
// }
|
|||
// })
|
|||
// setProjectListOpt(d)
|
|||
// const r2= await dispatch(projectRegime.getProjectList())
|
|||
// const dp=r2.pauseStatemap(item=>{
|
|||
// return {
|
|||
// label:item?.name,
|
|||
// value:item?.id
|
|||
// }
|
|||
// })
|
|||
// setStructureListOpt(dp)
|
|||
// const r= await dispatch(projectBinding.getRelation())
|
|||
// const list = r?.payload?.data?.rows?.map(item=>{
|
|||
// return {
|
|||
// key: item.id,
|
|||
// anxinyunProject:d?.find(q=>q.value===item.axyProjectId)?.label,
|
|||
// structName:dp?.find(q=>q.value===item.structureId)?.label
|
|||
// }
|
|||
// })
|
|||
// setDataSource(list)
|
|||
// }
|
|||
// })
|
|||
|
|||
// }
|
|||
//初始化
|
|||
useEffect(() => { |
|||
let data = { |
|||
url:'organizations/{orgId}/structures', |
|||
// url: 'users/{orgId}/projects',
|
|||
type: 'get', |
|||
} |
|||
dispatch(projectBinding.getanxinyunProject(data)).then(res => { |
|||
if (res.success) { |
|||
const d = res.payload.data?.map(item => { |
|||
return { |
|||
label: item?.name, |
|||
value: item?.iotaThingId, |
|||
} |
|||
}) |
|||
setProjectListOpt(d) |
|||
} |
|||
}) |
|||
dispatch(projectRegime.getProjectList()).then(res => { |
|||
if (res.success) { |
|||
const dp = res.payload.data?.rows?.map(item => { |
|||
return { |
|||
label: item?.name, |
|||
value: item?.id, |
|||
} |
|||
}) |
|||
setStructureListOpt(dp) |
|||
} |
|||
}) |
|||
}, []) |
|||
const queryData = () => { |
|||
dispatch(projectBinding.getRelation()).then(res => { |
|||
if (res.success) { |
|||
const list = res?.payload?.data?.rows?.map(item => { |
|||
return { |
|||
key: item.id, |
|||
anxinyunProject: proejctListOpt?.find(q => q.value === item.axyProjectId)?.value, |
|||
structName: structureListOpt?.find(q => q.value === item.structureId)?.value, |
|||
} |
|||
}) |
|||
setDataSource(list) |
|||
// setDataCopy(list)
|
|||
} |
|||
}) |
|||
} |
|||
useEffect(() => { |
|||
if (proejctListOpt && structureListOpt && proejctListOpt.length && structureListOpt.length) { |
|||
queryData() |
|||
} |
|||
}, [proejctListOpt, structureListOpt]) |
|||
|
|||
const onFinish = async values => { |
|||
const dataToSave = { axyProjectId: values?.anxinyunProject, structrueId: values?.structName, id: values?.id } |
|||
return dispatch(projectBinding.addorEditRelation(dataToSave)).then(res => { |
|||
if (res.success) { |
|||
queryData() |
|||
// tableRef.current.reload()
|
|||
return true |
|||
} else { |
|||
return false |
|||
} |
|||
}) |
|||
} |
|||
//删除按钮
|
|||
const handleDelete = id => { |
|||
dispatch(projectBinding.delRelation(id)).then(res => { |
|||
if (res.success) { |
|||
queryData() |
|||
} |
|||
}) |
|||
} |
|||
|
|||
const filterOption = (input, option) => (option?.label ?? '').toLowerCase().includes(input.toLowerCase()) |
|||
|
|||
const columns = [ |
|||
{ |
|||
title: '安心云结构物', |
|||
dataIndex: 'anxinyunProject', |
|||
ellipsis: true, |
|||
valueType: 'select', |
|||
fieldProps: { |
|||
options: proejctListOpt, |
|||
}, |
|||
renderFormItem: () => ( |
|||
<Select |
|||
showSearch |
|||
// style={{paddingLeft:10}}
|
|||
allowClear |
|||
placeholder='请选择' |
|||
options={proejctListOpt?.map(item => ({ label: item.label, value: item.value }))} |
|||
filterOption={filterOption} |
|||
optionFilterProp='children'></Select> |
|||
), |
|||
// fieldProps: {
|
|||
// showSearch: true,
|
|||
// defaultValue: '',
|
|||
// },
|
|||
// onFilter: (value, record) => record.name.includes(value),
|
|||
// search:false
|
|||
}, |
|||
{ |
|||
title: '结构物名称', |
|||
dataIndex: 'structName', |
|||
ellipsis: true, |
|||
valueType: 'select', |
|||
fieldProps: { |
|||
options: structureListOpt, |
|||
}, |
|||
renderFormItem: () => ( |
|||
<Select |
|||
showSearch |
|||
// style={{paddingLeft:10}}
|
|||
allowClear |
|||
placeholder='请选择' |
|||
options={structureListOpt?.map(item => ({ label: item.label, value: item.value }))} |
|||
filterOption={filterOption} |
|||
optionFilterProp='children'></Select> |
|||
), |
|||
// fieldProps: {
|
|||
// showSearch: true,
|
|||
// defaultValue: '',
|
|||
// },
|
|||
// search:false
|
|||
valueType: 'select', |
|||
fieldProps: { |
|||
options: structureListOpt, |
|||
}, |
|||
}, |
|||
{ |
|||
title: '操作', |
|||
width: 160, |
|||
key: 'option', |
|||
valueType: 'option', |
|||
render: (text, record) => { |
|||
const options = [] |
|||
options.push( |
|||
<RelationModal |
|||
proejctListOpt={proejctListOpt} |
|||
triggerRender={<a>修改映射关系</a>} |
|||
editData={record} |
|||
structureListOpt={structureListOpt} |
|||
title='修改映射关系' |
|||
onFinish={onFinish} |
|||
key='editModel' |
|||
/> |
|||
) |
|||
|
|||
options.push( |
|||
<Popconfirm |
|||
key='del' |
|||
placement='top' |
|||
title='是否确认删除映射关系?' |
|||
onConfirm={() => handleDelete(record.key)} |
|||
okText='是' |
|||
cancelText='否'> |
|||
<a>删除</a> |
|||
</Popconfirm> |
|||
) |
|||
|
|||
return options |
|||
}, |
|||
}, |
|||
] |
|||
// useMemo(()=>{
|
|||
|
|||
// })
|
|||
|
|||
const tableDatas = useMemo(() => { |
|||
const { anxinyunProject, structName } = tableParams |
|||
let rslt = dataSource |
|||
rslt = rslt |
|||
.filter(s => (anxinyunProject ? (s.anxinyunProject ? s.anxinyunProject === anxinyunProject : false) : true)) |
|||
?.filter(s => (structName ? (s.structName ? s.structName === structName : false) : true)) |
|||
return rslt |
|||
}) |
|||
|
|||
// const searchHandler=()=>{
|
|||
// const anxinyunProject=proTableFormRef.current.getFieldsValue()?.anxinyunProject
|
|||
// const structName=proTableFormRef.current.getFieldsValue()?.structName
|
|||
// setDataSource(
|
|||
// dataCopy.filter(f =>
|
|||
// (!anxinyunProject || f.anxinyunProject?.includes(anxinyunProject)) &&
|
|||
// (!structName || f?.structName === structName)
|
|||
// )
|
|||
// )
|
|||
|
|||
// }
|
|||
|
|||
return ( |
|||
<Spin spinning={anxinyunProjectLoading||relationLoading}> |
|||
<div id='patrol-record' className='global-main'> |
|||
{/* <Spin spinning={loading}> */} |
|||
<div style={{ marginBottom: 19 }}> |
|||
<div className='top' style={{ marginBottom: 19 }}> |
|||
<div className='title'> |
|||
<span className='line'></span> |
|||
<span className='cn'>项目绑定</span> |
|||
<span className='en'> PROJECT</span> |
|||
</div> |
|||
<div></div> |
|||
</div> |
|||
</div> |
|||
<RelationModal |
|||
structureListOpt={structureListOpt} |
|||
proejctListOpt={proejctListOpt} |
|||
triggerRender={<Button type='primary'>新增</Button>} |
|||
title='新增映射关系' |
|||
onFinish={onFinish} |
|||
key='addModel' |
|||
/> |
|||
<ProTable |
|||
formRef={proTableFormRef} |
|||
rowKey='id' |
|||
options={false} |
|||
request={async params => { |
|||
setTableParams(params) |
|||
return { |
|||
data: [], |
|||
success: true, |
|||
} |
|||
}} |
|||
actionRef={tableRef} |
|||
columns={columns} |
|||
pagination={{ pageSize: 10, size: 'default', className: 'global-pagination' }} |
|||
dataSource={tableDatas || []} |
|||
search={{ |
|||
labelWidth: 100, |
|||
|
|||
}} |
|||
// search={{
|
|||
// optionRender: ({searchText, resetText}, {form}, dom) => [
|
|||
// <Button type="primary" onClick={searchHandler}>查询</Button>,
|
|||
// ]
|
|||
// }}
|
|||
></ProTable> |
|||
{/* </Spin> */} |
|||
</div> |
|||
</Spin> |
|||
) |
|||
} |
|||
|
|||
function mapStateToProps(state) { |
|||
const { auth, global, device,anxinyunProject, relation} = state |
|||
return { |
|||
loading: device.isRequesting, |
|||
clientHeight: global.clientHeight, |
|||
actions: global.actions, |
|||
relationLoading:relation.isRequesting, |
|||
anxinyunProjectLoading:anxinyunProject.isRequesting, |
|||
} |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(ProjectBinding) |
@ -1,15 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
import reducers from './reducers'; |
|||
import routes from './routes'; |
|||
import actions from './actions'; |
|||
import { getNavItem } from './nav-item'; |
|||
|
|||
export default { |
|||
key: 'projectBinding', |
|||
name: '项目绑定', |
|||
reducers: reducers, |
|||
routes: routes, |
|||
actions: actions, |
|||
getNavItem: getNavItem |
|||
}; |
@ -1,13 +0,0 @@ |
|||
import React from 'react'; |
|||
import { Link } from 'react-router-dom'; |
|||
import { Menu } from 'antd'; |
|||
import { Func } from '$utils'; |
|||
export function getNavItem(user, dispatch) { |
|||
return ( |
|||
<Menu.Item icon={<img src='/assets/images/menu/device.png' style={{ width: 24, height: 24 }} />} |
|||
key="projectBinding"> |
|||
<Link to="/projectBinding">项目绑定</Link> |
|||
</Menu.Item> |
|||
|
|||
); |
|||
} |
@ -1,5 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
export default { |
|||
|
|||
} |
@ -1,13 +0,0 @@ |
|||
'use strict'; |
|||
import { ProjectBinding } from './containers'; |
|||
|
|||
export default [{ |
|||
type: 'inner', |
|||
route: { |
|||
path: '/projectBinding', |
|||
key: 'projectBinding', |
|||
breadcrumb: '项目绑定', |
|||
component: ProjectBinding, |
|||
|
|||
} |
|||
}]; |
@ -1,83 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
import { basicAction } from '@peace/utils' |
|||
import { ApiTable } from '$utils' |
|||
|
|||
export function getProjectGraph(projectId) { |
|||
return (dispatch) => basicAction({ |
|||
type: 'get', |
|||
dispatch, |
|||
actionType: 'GET_PROJECT_PLANAR_GRAPH', |
|||
url: ApiTable.getProjectGraph.replace('{projectId}', projectId), |
|||
msg: { option: '获取结构物平面图' }, |
|||
reducer: { name: 'projectGraph' } |
|||
}); |
|||
} |
|||
|
|||
|
|||
export function createGraph(data) { |
|||
return (dispatch) => basicAction({ |
|||
type: 'post', |
|||
data, |
|||
dispatch, |
|||
actionType: 'ADD_PROJECT_PLANAR_GRAPH', |
|||
url: ApiTable.createGraph, |
|||
msg: { option: '新增结构物平面图' }, |
|||
}); |
|||
} |
|||
|
|||
export function updateGraph(id, data) { |
|||
return (dispatch) => basicAction({ |
|||
type: 'post', |
|||
data, |
|||
dispatch, |
|||
actionType: 'UPDATE_PROJECT_PLANAR_GRAPH', |
|||
url: ApiTable.updateGraph.replace('{id}', id), |
|||
msg: { option: '修改结构物平面图' }, |
|||
}); |
|||
} |
|||
|
|||
export function deleteGraph(id) { |
|||
return (dispatch) => basicAction({ |
|||
type: 'del', |
|||
dispatch, |
|||
actionType: 'DELETE_PROJECT_GRAPH', |
|||
url: ApiTable.deleteGraph.replace('{id}', id), |
|||
msg: { |
|||
option: '删除结构物布设图', |
|||
}, |
|||
}); |
|||
} |
|||
|
|||
export function getProjectPoints(projectId) { |
|||
return (dispatch) => basicAction({ |
|||
type: 'get', |
|||
dispatch, |
|||
actionType: 'GET_PROJECT_ALL_POINTS', |
|||
url: ApiTable.getProjectPoints.replace('{projectId}', projectId), |
|||
msg: { option: '获取结构物所有点位' }, |
|||
reducer: { name: 'projectAllPoints' } |
|||
}); |
|||
} |
|||
|
|||
export function getDeployPoints(pictureId) { |
|||
return (dispatch) => basicAction({ |
|||
type: 'get', |
|||
dispatch, |
|||
actionType: 'GET_PROJECT_DEPLOY_POINTS', |
|||
url: ApiTable.getDeployPoints.replace('{pictureId}', pictureId), |
|||
msg: { option: '获取结构物平面图测点分布' }, |
|||
reducer: { name: 'projectDeployPoints' } |
|||
}); |
|||
} |
|||
|
|||
export function setDeployPoints(pictureId, data) { |
|||
return (dispatch) => basicAction({ |
|||
type: 'post', |
|||
data, |
|||
dispatch, |
|||
actionType: 'SET_PROJECT_DEPLOY_POINTS', |
|||
url: ApiTable.setDeployPoints.replace('{pictureId}', pictureId), |
|||
msg: { option: '结构物平面图点位布设' }, |
|||
}); |
|||
} |
@ -1,10 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
|
|||
import * as projectSituation from './projectSituation' |
|||
import * as projectGraph from './graph' |
|||
|
|||
export default { |
|||
...projectSituation, |
|||
...projectGraph |
|||
} |
@ -1,101 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
import { basicAction } from '@peace/utils' |
|||
import { ApiTable } from '$utils' |
|||
|
|||
|
|||
export function getProjectList (query) { |
|||
return (dispatch) => basicAction({ |
|||
type: 'get', |
|||
query, |
|||
dispatch, |
|||
actionType: 'GET_PROJEECT_LIST', |
|||
url: ApiTable.getProjectList, |
|||
msg: { error: '获取结构物列表失败', }, |
|||
}); |
|||
} |
|||
|
|||
|
|||
export function postAddProject (data) { |
|||
return (dispatch) => basicAction({ |
|||
type: 'post', |
|||
data, |
|||
dispatch, |
|||
actionType: 'POST_ADD_PROJECT', |
|||
url: ApiTable.postAddProject, |
|||
msg: { option: data?.id ? '编辑结构物' : '新增结构物', }, |
|||
}); |
|||
} |
|||
|
|||
|
|||
export function delProject (id) { |
|||
return (dispatch) => basicAction({ |
|||
type: 'del', |
|||
dispatch, |
|||
actionType: 'DEL_PROJECT', |
|||
url: ApiTable.delProject.replace('{id}', id), |
|||
msg: { |
|||
option: '删除结构物', |
|||
}, |
|||
}); |
|||
} |
|||
|
|||
|
|||
export function addPosition (data, point) { |
|||
return (dispatch) => basicAction({ |
|||
type: 'post', |
|||
data, |
|||
dispatch, |
|||
actionType: 'ADD_POSITION', |
|||
url: ApiTable.position, |
|||
msg: { option: point ? '二维码生成' : data?.id ? '编辑点位' : '新增点位', }, |
|||
}); |
|||
} |
|||
|
|||
export function positionList (query) { |
|||
return (dispatch) => basicAction({ |
|||
type: 'get', |
|||
query, |
|||
dispatch, |
|||
actionType: 'POSITION_LIST', |
|||
url: ApiTable.position, |
|||
msg: { error: '获取点位列表失败', }, |
|||
reducer: { name: 'projectPoints' } |
|||
}); |
|||
} |
|||
|
|||
|
|||
export function delPosition (id) { |
|||
return (dispatch) => basicAction({ |
|||
type: 'del', |
|||
dispatch, |
|||
actionType: 'DEL_POSITION', |
|||
url: ApiTable.delPosition.replace('{id}', id), |
|||
msg: { |
|||
option: '删除点位', |
|||
}, |
|||
}); |
|||
} |
|||
|
|||
|
|||
export function qrCodeShow (query) { |
|||
return (dispatch) => basicAction({ |
|||
type: 'get', |
|||
query, |
|||
dispatch, |
|||
actionType: 'GET_QR_CODE', |
|||
url: ApiTable.qrCodeShow, |
|||
msg: { error: '获取二维码列表失败', }, |
|||
}); |
|||
} |
|||
|
|||
export function q () { |
|||
return (dispatch) => basicAction({ |
|||
type: 'get', |
|||
dispatch, |
|||
actionType: 'GET_CODE', |
|||
url: ApiTable.q, |
|||
msg: { error: '获取二维码列表失败', }, |
|||
}); |
|||
} |
|||
|
@ -1,57 +0,0 @@ |
|||
'use strict' |
|||
|
|||
import React, { Component, PropTypes } from 'react'; |
|||
import { DropTarget } from 'react-dnd'; |
|||
import StationSpot from './station-spot'; |
|||
|
|||
const heatmapTarget = { |
|||
drop(props, monitor) { |
|||
//get item from station-spot.js
|
|||
//item:{deployed, rect, spotInlist, info}
|
|||
const item = monitor.getItem(); |
|||
const move = monitor.getDifferenceFromInitialOffset(); |
|||
props.onDeploySpot({ ...item, move }); |
|||
} |
|||
}; |
|||
|
|||
function collect(connect, monitor) { |
|||
return { |
|||
connectDropTarget: connect.dropTarget(), |
|||
isOver: monitor.isOver() |
|||
}; |
|||
} |
|||
|
|||
class Heatmap extends React.Component { |
|||
componentDidMount() { |
|||
|
|||
} |
|||
|
|||
renderSpots() { |
|||
const { width, height, spots, onRemoveSpot } = this.props; |
|||
return spots.map(s => <StationSpot key={s.sensorId} info={s} |
|||
size={{ "width": width, "height": height }} |
|||
onRemoveSpot={onRemoveSpot} />); |
|||
} |
|||
|
|||
render() { |
|||
const { connectDropTarget, height, width, image } = this.props; |
|||
|
|||
let targetStyle = { |
|||
position: 'relative', |
|||
width: width, |
|||
// overflow:'hidden',
|
|||
height: height, |
|||
background: `url("/_file-server/${image}") no-repeat`, |
|||
backgroundSize: '100% 100%', |
|||
}; |
|||
|
|||
return connectDropTarget( |
|||
<div id="dragTarget" style={targetStyle}> |
|||
{this.renderSpots()} |
|||
</div> |
|||
) |
|||
} |
|||
} |
|||
|
|||
export default DropTarget('stationSpot', heatmapTarget, collect)(Heatmap); |
|||
|
@ -1,114 +0,0 @@ |
|||
/** |
|||
* Created by yuanfenghua on 2018/6/18. |
|||
*/ |
|||
'use strict' |
|||
|
|||
import React, { Component } from 'react'; |
|||
import { findDOMNode } from 'react-dom'; |
|||
import { connect } from 'react-redux'; |
|||
import { DragSource } from 'react-dnd'; |
|||
import { Tooltip } from 'antd'; |
|||
import { MinusOutlined } from '@ant-design/icons'; |
|||
import Style from './style.css'; |
|||
|
|||
const stationSource = { |
|||
beginDrag(props, monitor, component) { |
|||
const dom = findDOMNode(component); |
|||
const rect = { |
|||
x: dom.offsetLeft - dom.offsetParent.scrollLeft, |
|||
y: dom.offsetTop - dom.offsetParent.scrollTop |
|||
}; |
|||
const spotInlist = { |
|||
x: dom.getBoundingClientRect().left, |
|||
y: dom.getBoundingClientRect().top |
|||
}; |
|||
|
|||
return { |
|||
info: props.info, |
|||
rect: rect, |
|||
spotInlist: spotInlist, |
|||
deployed: props.info.deployed |
|||
}; |
|||
}, |
|||
endDrag(props, monitor) { |
|||
if (!monitor.didDrop() && props.onRemoveSpot) { |
|||
props.onRemoveSpot(monitor.getItem().info); |
|||
} |
|||
}, |
|||
canDrag(props) { |
|||
if (props.size) { |
|||
//热点图上的热点可拖拽
|
|||
return true; |
|||
} else { |
|||
//测点树未布设的叶结点可拖拽
|
|||
return !props.children && props.info.deployed == false |
|||
} |
|||
}, |
|||
}; |
|||
|
|||
function collect(connect, monitor) { |
|||
return { |
|||
connectDragSource: connect.dragSource(), |
|||
isDragging: monitor.isDragging() |
|||
} |
|||
} |
|||
|
|||
class StationSpot extends React.Component { |
|||
constructor(props) { |
|||
super(props); |
|||
} |
|||
|
|||
|
|||
renderTreeTitle = () => { |
|||
const { isDragging, info } = this.props; |
|||
const { spotId, location, deployed } = info; |
|||
const opacity = isDragging ? 0.4 : 1; |
|||
return ( |
|||
<span style={{ lineHeight: '15px', opacity }} className={Style['icon']}> |
|||
<span key={spotId}> |
|||
<Tooltip title={location}> |
|||
<span className={deployed == false ? Style['station-tree-node-normal'] : null}>{location.length >= 12 ? location.substring(0, 12) + "..." : location}</span> |
|||
</Tooltip> |
|||
{deployed ? <MinusOutlined type="minus-circle-o" className={Style['tip']} onClick={this.onRemoveSpot} /> : null} |
|||
</span> |
|||
</span> |
|||
); |
|||
}; |
|||
|
|||
onRemoveSpot = () => { |
|||
|
|||
const { onRemoveSpot, info } = this.props; |
|||
if (onRemoveSpot) { |
|||
onRemoveSpot(info); |
|||
} |
|||
}; |
|||
|
|||
renderHotspot = () => { |
|||
const { info, size } = this.props; |
|||
const { key, location, x, y, screenWidth, screenHeight } = info; |
|||
const { width, height } = size; |
|||
let style = { |
|||
position: 'absolute', |
|||
left: width * x / screenWidth, |
|||
top: height * y / screenHeight, |
|||
cursor: 'move' |
|||
}; |
|||
|
|||
return <span style={style}> |
|||
<Tooltip title={location}> |
|||
<div style={{ height: 24, width: 24, borderRadius: '100%', backgroundColor: 'rgba(16,142,233,0.2)', padding: '5px' }}> |
|||
<div style={{ height: 14, width: 14, borderRadius: '100%', backgroundColor: '#108ee9', boxShadow: '0 0 10px #108ee9' }}></div> |
|||
</div> |
|||
</Tooltip> |
|||
</span> |
|||
}; |
|||
|
|||
render() { |
|||
const { connectDragSource, size } = this.props; |
|||
return connectDragSource( |
|||
size ? this.renderHotspot() : this.renderTreeTitle() |
|||
); |
|||
} |
|||
} |
|||
|
|||
export default connect()(DragSource('stationSpot', stationSource, collect)(StationSpot)); |
@ -1,91 +0,0 @@ |
|||
.station-tree-node-normal{ |
|||
margin-right: 6px; |
|||
padding: 0 4px; |
|||
height: 15px; |
|||
line-height: 15px; |
|||
background: #108ee9; |
|||
color: #fff; |
|||
font-size: 12px; |
|||
text-align: center; |
|||
} |
|||
|
|||
.icon .tip{ |
|||
margin-left:10px; |
|||
-webkit-transition:opacity 0.1s 0.2s; |
|||
opacity:0; |
|||
pointer-events:none; |
|||
} |
|||
.icon:hover .tip{ |
|||
-webkit-transition:opacity 0.2s; |
|||
opacity:1; |
|||
pointer-events:auto; |
|||
} |
|||
.icon .tip:hover{ |
|||
-webkit-transition:none; |
|||
} |
|||
|
|||
|
|||
:global(.no-card-border>.ant-card-head){ |
|||
border: none; |
|||
} |
|||
|
|||
.cardCoverBox{ |
|||
position: absolute; |
|||
top: 50px; |
|||
left: 0; |
|||
right: 0; |
|||
bottom: 0; |
|||
} |
|||
.cardCover{ |
|||
display: flex; |
|||
flex-direction: column; |
|||
justify-content: center; |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
right: 0; |
|||
bottom: 0; |
|||
width: 100%; |
|||
height: 100%; |
|||
background-color: rgba(240 , 240, 240, 0.9); |
|||
z-index: 2; |
|||
} |
|||
.cardCover .btnCell{ |
|||
text-align: center; |
|||
margin: 25px; |
|||
} |
|||
|
|||
.cardFootCover{ |
|||
display: flex; |
|||
justify-content: space-around; |
|||
align-items: center; |
|||
position: absolute; |
|||
top: 0; |
|||
width: 100%; |
|||
height: 100%; |
|||
background-color: rgba(255, 255, 255, 0.9); |
|||
z-index: 1; |
|||
opacity: 0; |
|||
} |
|||
.cardFootCover:hover{ |
|||
opacity: 1; |
|||
} |
|||
.deleteBox{ |
|||
margin: 0 40px; |
|||
} |
|||
.deleteBox h3{ |
|||
text-align: center; |
|||
margin-bottom: 5px; |
|||
} |
|||
.deleteBox .btnRow{ |
|||
display: flex; |
|||
justify-content: space-around; |
|||
margin-top: 10px; |
|||
width: 100%; |
|||
} |
|||
.loadingBox{ |
|||
width: 100%; |
|||
margin-bottom: 50px; |
|||
text-align: center; |
|||
padding: 50px 0; |
|||
} |
@ -1,219 +0,0 @@ |
|||
import React, { useState } from 'react'; |
|||
import { Button, Form, Input, Modal, Select, DatePicker } from 'antd'; |
|||
import { EnvironmentTwoTone } from '@ant-design/icons'; |
|||
const { TextArea } = Input; |
|||
import { connect } from 'react-redux'; |
|||
import Uploads from '$components/Uploads'; |
|||
import { useEffect } from 'react'; |
|||
import moment from 'moment'; |
|||
|
|||
const ProjectAddModel = ({ dispatch, actions, user, modelData, close, success, qrCodeId, devices }) => { |
|||
|
|||
const { projectRegime } = actions |
|||
const [showBaiduMap, setShowBaiduMap] = useState(false) |
|||
const [form] = Form.useForm(); |
|||
|
|||
useEffect(() => { |
|||
if (modelData?.longitude && modelData?.latitude) { |
|||
form.setFieldValue('longitude', modelData?.longitude) |
|||
form.setFieldValue('latitude', modelData?.latitude) |
|||
} |
|||
var map = new AMap.Map('container', { |
|||
resizeEnable: true, //是否监控地图容器尺寸变化
|
|||
zoom: 11, //初始化地图层级
|
|||
center: [116.397428, 39.90923] //初始化地图中心点
|
|||
}); |
|||
|
|||
var autoOptions = { |
|||
input: "tipinput" |
|||
}; |
|||
|
|||
AMap.plugin(['AMap.PlaceSearch', 'AMap.AutoComplete', 'AMap.Geocoder'], () => { |
|||
var auto = new AMap.AutoComplete(autoOptions); |
|||
var placeSearch = new AMap.PlaceSearch({ |
|||
map: map |
|||
}); //构造地点查询类
|
|||
|
|||
function select(e) { |
|||
if (e) { |
|||
placeSearch.setCity(e.poi.adcode); |
|||
placeSearch.search(e.poi.name, function (status, result) { |
|||
form.setFieldValue('longitude', result.poiList.pois[0].location.lat) |
|||
form.setFieldValue('latitude', result.poiList.pois[0].location.lng) |
|||
}) //关键字查询查询
|
|||
} |
|||
} |
|||
auto.on("select", select);//注册监听,当选中某条记录时会触发
|
|||
map.on('click', function (e) { //点击地图获取经纬度
|
|||
form.setFieldValue('longitude', e.lnglat.lat) |
|||
form.setFieldValue('latitude', e.lnglat.lng) |
|||
}); |
|||
}); |
|||
|
|||
|
|||
}, []) |
|||
|
|||
|
|||
return ( |
|||
<Modal |
|||
title={modelData.id ? '编辑点位' : '新增点位'} |
|||
width={570} |
|||
open={true} |
|||
onOk={() => { |
|||
form.validateFields().then(r => { |
|||
dispatch(projectRegime.addPosition({ |
|||
...r, |
|||
id: modelData?.id, |
|||
projectId: qrCodeId, |
|||
latitude: r?.latitude ? r?.latitude : null, |
|||
longitude: r?.longitude ? r?.longitude : null, |
|||
img: r.img ? r.img.map(u => u.storageUrl) : [], |
|||
})).then(res => { |
|||
if (res.success) { |
|||
success() |
|||
} |
|||
}) |
|||
}) |
|||
}} |
|||
onCancel={() => { |
|||
close() |
|||
}} |
|||
> |
|||
<Form |
|||
style={{}} |
|||
form={form} |
|||
labelAlign='right' |
|||
labelCol={{ span: 6 }} wrapperCol={{ span: 18 }} |
|||
onFinish={r => { |
|||
|
|||
}} |
|||
initialValues={{ |
|||
img: (modelData.img || []).map(s => { |
|||
return { |
|||
storageUrl: s |
|||
} |
|||
}), |
|||
}} |
|||
> |
|||
<Form.Item label='点位名称' name="name" style={{}} |
|||
initialValue={modelData?.name} |
|||
rules={[{ required: true, message: '必填,名称不能包含 \\ / : * ? " < > | #', pattern: new RegExp('^[^\\\\/|:*?\"<>#]+$') },]} |
|||
> |
|||
<Input placeholder="请输入点位名称" allowClear /> |
|||
</Form.Item> |
|||
<div style={{ position: 'relative' }}> |
|||
{/* /^\d+$|^\d*\.\d+$/g */} |
|||
<Form.Item label="所在地区:" labelCol={{ span: 11 }} labelAlign='right' name="longitude" style={{ display: 'inline-block', width: 'calc(60% - 30px)', }} |
|||
rules={[{ required: false, message: '', }, { |
|||
validator: (rule, value, callback) => { |
|||
const sjh = /^\d+$|^\d*\.\d+$/g; |
|||
if (value) { |
|||
let valid = sjh.test(value); |
|||
if (!valid) { |
|||
return callback([new Error("横坐标填写错误")]); |
|||
} |
|||
callback(); |
|||
} |
|||
// return callback([new Error("请输入横坐标")]);
|
|||
return Promise.resolve(); |
|||
} |
|||
}]} |
|||
> |
|||
<Input placeholder="经度支持数字" /> |
|||
</Form.Item> |
|||
~ |
|||
<Form.Item name="latitude" style={{ display: 'inline-block', width: 'calc(40% + 15px)', }} |
|||
rules={[{ required: false, message: '', }, { |
|||
validator: (rule, value, callback) => { |
|||
const sjh = /^\d+$|^\d*\.\d+$/g; |
|||
if (value) { |
|||
let valid = sjh.test(value); |
|||
if (!valid) { |
|||
return callback([new Error("纵坐标填写错误")]); |
|||
} |
|||
callback(); |
|||
} |
|||
// return callback([new Error("请输入纵坐标")]);
|
|||
return Promise.resolve(); |
|||
} |
|||
}]} |
|||
> |
|||
<Input placeholder="维度支持数字" /> |
|||
</Form.Item> |
|||
<EnvironmentTwoTone style={{ position: 'absolute', top: 5, right: 27, fontSize: 22 }} onClick={() => { |
|||
setShowBaiduMap(!showBaiduMap) |
|||
}} /> |
|||
</div> |
|||
<Form.Item |
|||
label={"地址"} |
|||
name='location' |
|||
style={showBaiduMap ? { display: 'block' } : { display: 'none' }} |
|||
> |
|||
<Input id="tipinput" /> |
|||
</Form.Item> |
|||
<Form.Item |
|||
|
|||
label="地图" |
|||
name='map' |
|||
style={showBaiduMap ? { display: 'block' } : { display: 'none' }} |
|||
> |
|||
<div id="container" style={{ width: '100%', height: '425px', marginBottom: '15px' }}></div> |
|||
</Form.Item> |
|||
<Form.Item name='describe' label="描述" |
|||
initialValue={modelData?.describe} |
|||
rules={[{ required: true, message: '请输入描述内容', },]}> |
|||
<TextArea /> |
|||
</Form.Item> |
|||
<Form.Item label='设备编号' name="equipmentNo" style={{}} |
|||
initialValue={modelData?.equipmentNo}> |
|||
<Input placeholder="请输入设备编号" allowClear /> |
|||
</Form.Item> |
|||
<Form.Item label='设备型号' name="equipmentModel" style={{}} |
|||
initialValue={modelData?.equipmentModel}> |
|||
<Input placeholder="请输入设备型号" allowClear /> |
|||
</Form.Item> |
|||
<Form.Item label='设备绑定' name="devices" style={{}} |
|||
initialValue={modelData?.pointDevices?.map(s => s?.deviceId) || []}> |
|||
<Select mode="multiple" showSearch filterOption={(input, option) => (option?.children ?? '').toLowerCase().includes(input.toLowerCase())}> |
|||
{ |
|||
devices?.map(s => <Select.Option |
|||
disabled={s?.pointDevices?.length > 0 && !s?.pointDevices?.find(x => x.pointId == modelData?.id)} |
|||
value={s.id} >{s?.name}</Select.Option>) |
|||
} |
|||
</Select> |
|||
</Form.Item> |
|||
<Form.Item |
|||
label="点位图片" |
|||
name='img' |
|||
help={<div style={{ fontSize: 12 }}>说明:请上传png,jpg格式图片,图片大小不超过10M</div>} |
|||
> |
|||
<Uploads |
|||
listType='picture-card' |
|||
uploadType='project' |
|||
maxFilesNum={1} |
|||
maxFileSize={10} |
|||
isQiniu={true} |
|||
fileTypes={["png", "jpg"]} |
|||
defaultValue={(modelData.img || []).map(s => { |
|||
return { |
|||
storageUrl: s |
|||
} |
|||
})} |
|||
/> |
|||
</Form.Item> |
|||
</Form> |
|||
</Modal> |
|||
|
|||
); |
|||
}; |
|||
|
|||
|
|||
function mapStateToProps(state) { |
|||
const { auth, global } = state; |
|||
return { |
|||
user: auth.user, |
|||
actions: global.actions, |
|||
}; |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(ProjectAddModel); |
@ -1,234 +0,0 @@ |
|||
import React, { useState } from 'react'; |
|||
import { Form, Input, Modal, Select, Row, Col } from 'antd'; |
|||
// import { EnvironmentTwoTone } from '@ant-design/icons';
|
|||
const { TextArea } = Input; |
|||
import { connect } from 'react-redux'; |
|||
import Uploads from '$components/Uploads'; |
|||
import { useEffect } from 'react'; |
|||
// import moment from 'moment';
|
|||
const type_options = [ |
|||
{ value: '桥梁', label: '桥梁' }, |
|||
{ value: '隧道', label: '隧道' }, |
|||
{ value: '管廊', label: '管廊' }, |
|||
{ value: '地灾', label: '地灾' }, |
|||
] |
|||
const ProjectAddModel = ({ dispatch, actions, user, modelData, close, success, firmList }) => { |
|||
|
|||
const { projectRegime } = actions |
|||
const [showBaiduMap, setShowBaiduMap] = useState(false) |
|||
const [type, setType] = useState(modelData?.type || type_options[0]) |
|||
const [form] = Form.useForm(); |
|||
|
|||
useEffect(() => { |
|||
if (modelData?.longitude && modelData?.latitude) { |
|||
form.setFieldValue('longitude', modelData?.longitude) |
|||
form.setFieldValue('latitude', modelData?.latitude) |
|||
} |
|||
var map = new AMap.Map('container', { |
|||
resizeEnable: true, //是否监控地图容器尺寸变化
|
|||
zoom: 11, //初始化地图层级
|
|||
center: [116.397428, 39.90923] //初始化地图中心点
|
|||
}); |
|||
|
|||
var autoOptions = { |
|||
input: "tipinput" |
|||
}; |
|||
|
|||
AMap.plugin(['AMap.PlaceSearch', 'AMap.AutoComplete', 'AMap.Geocoder'], () => { |
|||
var auto = new AMap.AutoComplete(autoOptions); |
|||
var placeSearch = new AMap.PlaceSearch({ |
|||
map: map |
|||
}); //构造地点查询类
|
|||
|
|||
function select(e) { |
|||
if (e) { |
|||
placeSearch.setCity(e.poi.adcode); |
|||
placeSearch.search(e.poi.name, function (status, result) { |
|||
form.setFieldValue('longitude', result.poiList.pois[0].location.lng) |
|||
form.setFieldValue('latitude', result.poiList.pois[0].location.lat) |
|||
}) //关键字查询查询
|
|||
} |
|||
} |
|||
auto.on("select", select);//注册监听,当选中某条记录时会触发
|
|||
map.on('click', function (e) { //点击地图获取经纬度
|
|||
form.setFieldValue('longitude', e.lnglat.lng) |
|||
form.setFieldValue('latitude', e.lnglat.lat) |
|||
}); |
|||
}); |
|||
|
|||
}, []) |
|||
|
|||
|
|||
|
|||
return ( |
|||
<Modal |
|||
className="global-modal" |
|||
title={modelData?.id ? '编辑项目' : '新建项目'} |
|||
width={717} |
|||
open={true} |
|||
onOk={() => { |
|||
form.validateFields().then(v => { |
|||
dispatch(projectRegime.postAddProject({ |
|||
...v, |
|||
img: v.img ? v.img.map(u => u.storageUrl) : [], |
|||
id: modelData?.id |
|||
})).then(res => { |
|||
if (res.success) { |
|||
success() |
|||
} |
|||
}) |
|||
}) |
|||
}} |
|||
onCancel={() => close()} |
|||
> |
|||
<Form |
|||
style={{}} |
|||
form={form} |
|||
labelAlign='right' |
|||
labelCol={{ span: 4 }} wrapperCol={{ span: 18 }} |
|||
onFinish={r => { |
|||
}} |
|||
initialValues={{ |
|||
img: (modelData.img || []).map(s => { |
|||
return { |
|||
storageUrl: s |
|||
} |
|||
}), |
|||
describe: modelData?.describe, |
|||
}} |
|||
> |
|||
<div style={{ position: 'relative', display: 'flex' }}> |
|||
<Form.Item label='结构物名称' labelCol={{ span: 9 }} name="name" style={{ width: 369 }} |
|||
initialValue={modelData?.name} |
|||
rules={[{ required: true, message: '请输入结构物名称' },]} |
|||
> |
|||
<Input placeholder="请输入结构物名称" allowClear bordered={false} /> |
|||
</Form.Item> |
|||
<Form.Item label='结构物类型' labelCol={{ span: 9 }} name="type" style={{ width: 254 }} |
|||
initialValue={modelData?.type || '桥梁'} |
|||
// rules={[{ required: true, message: '请选择结构物类型' },]}
|
|||
> |
|||
<Select |
|||
onChange={value => { setType(value) }} |
|||
bordered={false} |
|||
allowClear |
|||
options={type_options} |
|||
/> |
|||
</Form.Item> |
|||
</div> |
|||
{type == '管廊' && <Form.Item label='子系统' name="subType" |
|||
initialValue={modelData?.subType || '指挥中心'} |
|||
rules={[{ required: true, message: '请选择子系统' }]} |
|||
> |
|||
<Select |
|||
bordered={false} |
|||
options={[ |
|||
{ value: '指挥中心', label: '指挥中心' }, |
|||
{ value: '管廊本体', label: '管廊本体' }, |
|||
{ value: '电梯系统', label: '电梯系统' }, |
|||
{ value: '供配电系统', label: '供配电系统' }, |
|||
{ value: '防雷与接地系统', label: '防雷与接地系统' }, |
|||
{ value: '燃气仓', label: '燃气仓' }, |
|||
{ value: '给水仓', label: '给水仓' }, |
|||
{ value: '电气仓', label: '电气仓' }, |
|||
{ value: '安防系统', label: '安防系统' }, |
|||
{ value: '高压电力仓', label: '高压电力仓' }, |
|||
]} |
|||
/> |
|||
</Form.Item>} |
|||
<div style={{ position: 'relative' }}> |
|||
<Form.Item label="所在地区:" labelCol={{ span: 9 }} labelAlign='right' name="longitude" style={{ display: 'inline-block', width: 'calc(60% - 50px)', }} |
|||
rules={[{ required: true, message: '', }, { |
|||
validator: (rule, value, callback) => { |
|||
const sjh = /^\d+$|^\d*\.\d+$/g; |
|||
if (value) { |
|||
let valid = sjh.test(value); |
|||
if (!valid) { |
|||
return callback([new Error("横坐标填写错误")]); |
|||
} |
|||
callback(); |
|||
} |
|||
return callback([new Error("请输入横坐标")]); |
|||
} |
|||
}]} |
|||
> |
|||
<Input placeholder="经度支持数字" bordered={false} /> |
|||
</Form.Item> |
|||
— |
|||
<Form.Item name="latitude" style={{ display: 'inline-block', width: 'calc(40% + 15px)', }} |
|||
rules={[{ required: true, message: '', }, { |
|||
validator: (rule, value, callback) => { |
|||
const sjh = /^\d+$|^\d*\.\d+$/g; |
|||
if (value) { |
|||
let valid = sjh.test(value); |
|||
if (!valid) { |
|||
return callback([new Error("纵坐标填写错误")]); |
|||
} |
|||
callback(); |
|||
} |
|||
return callback([new Error("请输入纵坐标")]); |
|||
} |
|||
}]} |
|||
> |
|||
<Input placeholder="维度支持数字" bordered={false} /> |
|||
</Form.Item> |
|||
<img src='/assets/images/show_map.svg' style={{ position: 'absolute', width: 28, top: 2, right: 47, cursor: 'pointer' }} onClick={() => { |
|||
setShowBaiduMap(!showBaiduMap) |
|||
}} /> |
|||
</div> |
|||
<Form.Item |
|||
label={"地址"} |
|||
name='location' |
|||
style={showBaiduMap ? { display: 'block' } : { display: 'none' }} |
|||
> |
|||
<Input id="tipinput" bordered={false} /> |
|||
</Form.Item> |
|||
<Form.Item |
|||
label="地图" |
|||
name='map' |
|||
style={showBaiduMap ? { display: 'block' } : { display: 'none' }} |
|||
> |
|||
<div id="container" style={{ width: '100%', height: '425px', marginBottom: '15px' }}></div> |
|||
</Form.Item> |
|||
<Form.Item name='describe' label="描述"> |
|||
<TextArea bordered={false} /> |
|||
</Form.Item> |
|||
<Form.Item |
|||
label="结构物图片" |
|||
name='img' |
|||
help={<div style={{ fontSize: 12 }}>说明:请上传png,jpg格式图片,图片大小不超过5M,建议图片宽高比16:9</div>} |
|||
// rules={[{ required: true, message: '请上传图片', },]}
|
|||
> |
|||
<Uploads |
|||
// className='upload'
|
|||
listType='picture-card' |
|||
uploadType='project' |
|||
maxFilesNum={1} |
|||
maxFileSize={5} |
|||
isQiniu={true} |
|||
// onChange={vsjunct}
|
|||
fileTypes={["png", "jpg"]} |
|||
// value={editUrl}
|
|||
defaultValue={(modelData.img || []).map(s => { |
|||
return { |
|||
storageUrl: s |
|||
} |
|||
})} |
|||
/> |
|||
</Form.Item> |
|||
</Form> |
|||
</Modal> |
|||
|
|||
); |
|||
}; |
|||
|
|||
|
|||
function mapStateToProps(state) { |
|||
const { auth, global } = state; |
|||
return { |
|||
user: auth.user, |
|||
actions: global.actions, |
|||
}; |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(ProjectAddModel); |
@ -1,9 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
|
|||
import QrCode from './qrCode' |
|||
import Information from './information' |
|||
import Point from './point' |
|||
import PointDeploy from './pointDeploy/default' |
|||
|
|||
export { QrCode, Information, Point, PointDeploy }; |
@ -1,251 +0,0 @@ |
|||
import React, { useEffect, useState } from 'react'; |
|||
import { connect } from 'react-redux'; |
|||
import { Form, Input, Button, Table, Modal, Popconfirm, Tooltip } from 'antd'; |
|||
import '../style.less'; |
|||
import { push } from 'react-router-redux'; |
|||
import ProjectAddModel from '../components/projectAddModel' |
|||
import './information.less'; |
|||
|
|||
|
|||
const Information = (props) => { |
|||
const { dispatch, actions, user, loading } = props |
|||
const { projectRegime } = actions |
|||
const [firmList, setFirmList] = useState([]) |
|||
const [tableList, settableList] = useState([]) |
|||
const [addModel, setAddModel] = useState(false) |
|||
const [modelData, setModelData] = useState({}) |
|||
const [query, setQuery] = useState({ limit: 10, page: 0 }) |
|||
const [limits, setLimits] = useState() |
|||
const [search, setSearch] = useState({}) |
|||
const [isPicture, setIsPicture] = useState(false) |
|||
const [pictureUrl, setPictureUrl] = useState() |
|||
const [companyID, setCompanyId] = useState('') |
|||
const [select, setSelect] = useState([]) |
|||
// var QRCode = require('qrcode')
|
|||
|
|||
useEffect(() => { |
|||
projectList(query) |
|||
}, []) |
|||
|
|||
const projectList = (obj) => { |
|||
const { limit, page, name } = obj |
|||
dispatch(projectRegime.getProjectList({ limit, page, name, })).then(res => { |
|||
// console.log(res)
|
|||
if (res.success) { |
|||
settableList(res.payload.data?.rows?.map(v => ({ ...v, key: v.id }))) |
|||
setLimits(res.payload.data?.count) |
|||
} |
|||
}) |
|||
} |
|||
|
|||
// const createQrCode = (name) => {
|
|||
// let url = ''
|
|||
// QRCode.toDataURL(name, {
|
|||
// errorCorrectionLevel: 'low',
|
|||
// type: 'image/png',
|
|||
// quality: 0.3,
|
|||
// margin: 2,
|
|||
// maskPattern: 9,
|
|||
// width: 400,
|
|||
// color: {
|
|||
// dark: "#000000ff",
|
|||
// light: "#ffffffff"
|
|||
// }
|
|||
// }, function (err, v) {
|
|||
// url = v
|
|||
// })
|
|||
// return url
|
|||
// }
|
|||
|
|||
const columns = [ |
|||
{ |
|||
title: '序号', |
|||
dataIndex: 'index', |
|||
key: 'index', |
|||
render: (text, record, index) => index + 1 |
|||
}, { |
|||
title: '结构物名称', |
|||
dataIndex: 'name', |
|||
key: 'name', |
|||
}, { |
|||
title: '所在地区', |
|||
dataIndex: 'type', |
|||
key: 'type', |
|||
render: (text, record, index) => { |
|||
return record.longitude && record.latitude ? <div style={{ width: 100 }}>{record.longitude},{record.latitude}</div> : "--" |
|||
} |
|||
}, { |
|||
title: '结构物类型', |
|||
dataIndex: 'type', |
|||
key: 'type', |
|||
render: (text, record, index) => record.type || '--' |
|||
}, { |
|||
title: '描述', |
|||
dataIndex: 'describe', |
|||
key: 'describe', |
|||
render: (text, record, index) => record.describe?.length>10?<Tooltip title={record.describe}><span> |
|||
{record?.describe.substring(0,10)}... |
|||
</span> |
|||
</Tooltip>: record.describe || '--' |
|||
}, { |
|||
title: '操作', |
|||
dataIndex: 'operation', |
|||
key: 'operation', |
|||
render: (text, record, index) => { |
|||
return ( |
|||
<div> |
|||
<Button type="link" onClick={() => { |
|||
setAddModel(true) |
|||
setModelData(record) |
|||
}} |
|||
>编辑</Button> |
|||
<Popconfirm |
|||
title={<div style={{ width: 180 }}>删除此结构物后,与结构物对应的点位、巡检计划、巡检记录也会删除,是否确认删除?</div>} |
|||
position='topLeft' |
|||
onConfirm={() => { |
|||
dispatch(projectRegime.delProject(record.id)).then(res => { |
|||
if (res.success) { |
|||
if ((limits > 11 && tableList.length > 1) || limits < 11) { |
|||
projectList({ ...query, ...search }) |
|||
} else { |
|||
projectList({ limit: query?.limit, page: query?.page - 1, ...search }) |
|||
setQuery({ limit: query?.limit, page: query?.page - 1 }); |
|||
} |
|||
|
|||
} |
|||
}) |
|||
}} |
|||
> |
|||
<Button type="link" danger >删除</Button> |
|||
</Popconfirm> |
|||
{/* <Button type="link" danger >二维码生成</Button> */} |
|||
<Button type="link" onClick={() => { |
|||
dispatch(push(`/projectRegime/information/${record.id}/point`)); |
|||
}} >点位</Button> |
|||
<Button type="link" onClick={() => { |
|||
dispatch(push(`/projectRegime/information/${record.id}/deploy`)); |
|||
}} >布设</Button> |
|||
</div> |
|||
) |
|||
} |
|||
} |
|||
] |
|||
|
|||
return ( |
|||
<div className='global-main'> |
|||
<div style={{ display: 'flex', justifyContent: 'space-between' }}> |
|||
<div className='title'> |
|||
<span className='line'></span> |
|||
<span className='cn'>结构物</span> |
|||
<span className='en'> Structure</span> |
|||
</div> |
|||
<div className='flex-end'> |
|||
<Form |
|||
style={{ display: 'flex' }} |
|||
onFinish={r => { |
|||
projectList({ limit: 10, page: 0, ...r, companyId: companyID || r?.companyId }) |
|||
setQuery({ limit: 10, page: 0 }); |
|||
setSearch(r) |
|||
}} |
|||
> |
|||
<Form.Item |
|||
label='结构物名称' |
|||
name="name" |
|||
style={{ marginRight: 16, minWidth: 180 }} |
|||
> |
|||
<Input placeholder="请输入结构物名称" allowClear suffix={<img src='/assets/images/search.svg' style={{ width: 16 }} />} /> |
|||
</Form.Item> |
|||
<Form.Item wrapperCol={{}}> |
|||
<Button htmlType="submit"> |
|||
搜索 |
|||
</Button> |
|||
</Form.Item> |
|||
</Form> |
|||
<div style={{ display: 'flex', marginLeft: 20 }}> |
|||
<Button type="primary" onClick={() => { |
|||
setAddModel(true) |
|||
}}>新建结构物</Button> |
|||
{/* <Button type="primary" style={{ marginLeft: 20 }} onClick={() => { |
|||
console.log(45513); |
|||
setAddModel(true) |
|||
}}>一键生成二维码</Button> */} |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<Table |
|||
columns={columns} |
|||
dataSource={tableList} |
|||
pagination={{ |
|||
className: 'global-pagination', |
|||
current: query.page + 1, |
|||
total: limits, |
|||
showSizeChanger: true, |
|||
showQuickJumper: true, |
|||
pageSizeOptions: [10, 20, 50], |
|||
showTotal: (total) => { |
|||
return <span style={{ fontSize: 15 }}>{`共${Math.ceil(total / query?.limit)}页,${total}项`}</span> |
|||
}, |
|||
onChange: (page, pageSize) => { |
|||
setQuery({ limit: pageSize, page: page - 1 }); |
|||
projectList({ limit: pageSize, page: page - 1, ...search, companyId: companyID || search?.companyId }) |
|||
} |
|||
}} |
|||
rowSelection={{ |
|||
selectedRowKeys: select || [], |
|||
onChange: (selectedRowKeys, selectedRows) => { |
|||
setSelect(selectedRowKeys) |
|||
console.log(selectedRowKeys, selectedRows); |
|||
} |
|||
}} |
|||
rowClassName={(record, index) => { |
|||
let className = 'global-light-row'; |
|||
if (index % 2 === 1) className = 'global-dark-row'; |
|||
return className; |
|||
}} |
|||
// scroll={{ y: 590 }}
|
|||
/> |
|||
{ |
|||
<Modal |
|||
// title={ }
|
|||
width={570} |
|||
open={isPicture} |
|||
onOk={() => { }} |
|||
footer={null} |
|||
onCancel={() => { |
|||
setIsPicture(false) |
|||
setPictureUrl('') |
|||
}} |
|||
> |
|||
{pictureUrl && pictureUrl[0] ? <img src={`/_file-server/${pictureUrl}`} width={500} /> : "暂无图片"} |
|||
</Modal> |
|||
} |
|||
{ |
|||
addModel ? |
|||
<ProjectAddModel |
|||
firmList={firmList} |
|||
modelData={modelData} |
|||
close={() => { |
|||
setAddModel(false) |
|||
setModelData({}) |
|||
}} |
|||
success={() => { |
|||
setAddModel(false) |
|||
setModelData({}) |
|||
setQuery({ limit: 10, page: 0 }); |
|||
projectList({ limit: 10, page: 0, ...search, companyId: companyID || search?.companyId }) |
|||
}} |
|||
/> : "" |
|||
} |
|||
</div> |
|||
) |
|||
} |
|||
|
|||
function mapStateToProps(state) { |
|||
const { auth, global } = state; |
|||
return { |
|||
user: auth.user, |
|||
actions: global.actions, |
|||
}; |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(Information); |
@ -1,30 +0,0 @@ |
|||
.title { |
|||
background-color: #fff; |
|||
display: inline-block; |
|||
|
|||
.line { |
|||
display: inline-block; |
|||
width: 3px; |
|||
height: 20px; |
|||
background: #006BE3; |
|||
} |
|||
|
|||
.cn { |
|||
font-family: YouSheBiaoTiHei; |
|||
font-size: 24px; |
|||
color: #101531; |
|||
margin-left: 11px; |
|||
} |
|||
|
|||
.en { |
|||
font-family: D-DINExp-Italic; |
|||
font-weight: Italic; |
|||
font-size: 12px; |
|||
color: #969799; |
|||
} |
|||
} |
|||
|
|||
.flex-end { |
|||
display: flex; |
|||
justify-content: flex-end; |
|||
} |
@ -1,196 +0,0 @@ |
|||
import React, { useEffect, useState } from 'react'; |
|||
import { connect } from 'react-redux'; |
|||
import { Button, Table, Popconfirm, Input } from 'antd'; |
|||
import '../style.less'; |
|||
import PointModel from '../components/pointModel' |
|||
|
|||
const Information = (props) => { |
|||
const { dispatch, actions, devices } = props |
|||
const { projectRegime } = actions |
|||
const [tableList, settableList] = useState([]) |
|||
const [addModel, setAddModel] = useState(false) |
|||
const [modelData, setModelData] = useState({}) |
|||
const [query, setQuery] = useState({ limit: 10, page: 0 }) |
|||
const [limits, setLimits] = useState() |
|||
const [search, setSearch] = useState({}) |
|||
const [companyID, setCompanyId] = useState('') |
|||
const [select, setSelect] = useState([]) |
|||
const [selec, setSelec] = useState() |
|||
const [qrCodeingIds, setQrCodeingIds] = useState(null) |
|||
const [searchTableList, setSearchTableList] = useState([]) |
|||
const [name, setName] = useState('') |
|||
|
|||
const qrCodeId = props?.match?.params?.id |
|||
|
|||
useEffect(() => { |
|||
projectList(query) |
|||
}, []) |
|||
|
|||
const projectList = (obj) => { |
|||
const { limit, page } = obj |
|||
dispatch(actions.deviceManage.getDeviceList()); |
|||
dispatch(projectRegime.positionList({ limit, page: 0, projectId: qrCodeId })).then(res => { |
|||
if (res.success) { |
|||
let data = [] |
|||
res.payload.data?.rows?.map(v => { |
|||
v.points?.map(r => { |
|||
data?.push(r) |
|||
}) |
|||
}) |
|||
settableList(data?.map(v => ({ ...v, key: v.id }))) |
|||
setSearchTableList(data?.map(v => ({ ...v, key: v.id }))) |
|||
setLimits(res.payload.data?.count) |
|||
} |
|||
}) |
|||
} |
|||
|
|||
const columns = [ |
|||
{ |
|||
title: '序号', |
|||
dataIndex: 'index', |
|||
key: 'index', |
|||
render: (text, record, index) => index + 1 |
|||
}, { |
|||
title: '点位名称', |
|||
dataIndex: 'name', |
|||
key: 'name', |
|||
}, { |
|||
title: '所在地区', |
|||
dataIndex: 'position', |
|||
key: 'position', |
|||
render: (text, record, index) => { |
|||
return record.longitude && record.latitude ? <div style={{ width: 100 }}>{record.longitude},{record.latitude}</div> : "--" |
|||
} |
|||
}, { |
|||
title: '描述', |
|||
dataIndex: 'describe', |
|||
key: 'describe', |
|||
render: (text, record, index) => record.describe || '--' |
|||
}, { |
|||
title: '操作', |
|||
dataIndex: 'operation', |
|||
key: 'operation', |
|||
render: (text, record, index) => { |
|||
return ( |
|||
<> |
|||
<Button type="link" onClick={() => { |
|||
setAddModel(true) |
|||
setModelData(record) |
|||
}}>编辑</Button> |
|||
<Popconfirm |
|||
title={<div style={{ width: 184 }}>删除该点位后,与巡检计划关联的点位删除,对应的巡检记录删除,是否确认删除?</div>} |
|||
position='topLeft' |
|||
onConfirm={() => { |
|||
dispatch(projectRegime.delPosition(record.id)).then(res => { |
|||
if (res.success) { |
|||
if ((limits > 11 && tableList.length > 1) || limits < 11) { |
|||
projectList({ ...query, ...search }) |
|||
} else { |
|||
projectList({ limit: query?.limit, page: query?.page - 1, ...search }) |
|||
setQuery({ limit: query?.limit, page: query?.page - 1 }); |
|||
} |
|||
} |
|||
}) |
|||
}} |
|||
> |
|||
<Button type="link" danger >删除</Button> |
|||
</Popconfirm> |
|||
<Button type="link" onClick={() => { |
|||
setQrCodeingIds([record.id]) |
|||
dispatch(projectRegime.addPosition({ |
|||
qrCode: true, |
|||
id: record.id, |
|||
}, true)).then(() => { |
|||
setQrCodeingIds(null) |
|||
}) |
|||
}} loading={qrCodeingIds?.includes(record.id)}>二维码生成</Button> |
|||
</> |
|||
) |
|||
} |
|||
} |
|||
] |
|||
|
|||
return ( |
|||
<> |
|||
<img src={selec} /> |
|||
<div style={{ display: 'flex', marginBottom: 10 }}> |
|||
<Button type="primary" onClick={() => { |
|||
setAddModel(true) |
|||
}}>新建点位</Button> |
|||
<Button type="primary" style={{ marginLeft: 20 }} onClick={() => { |
|||
if (select.length) { |
|||
setQrCodeingIds(select.map(s => s.id)); |
|||
select?.map((v, i) => { |
|||
dispatch(projectRegime.addPosition({ |
|||
qrCode: true, |
|||
id: v.id, |
|||
}, true)).then(() => { |
|||
if (i === select.length - 1) { |
|||
setQrCodeingIds(null); |
|||
} |
|||
}) |
|||
}) |
|||
} |
|||
}} disabled={qrCodeingIds?.length}>一键生成二维码</Button> |
|||
<Input style={{ width: 300, margin: '0px 20px' }} placeholder="请输入点位名称" onChange={(e) => { setName(e.target.value) }} /> |
|||
<Button type="primary" onClick={() => { |
|||
setSearchTableList(tableList?.filter(l => l.name?.includes(name))) |
|||
}}>搜索</Button> |
|||
</div> |
|||
|
|||
<Table |
|||
columns={columns} |
|||
dataSource={searchTableList} |
|||
pagination={{ |
|||
// current: query.page + 1,
|
|||
// total: limits,
|
|||
showSizeChanger: true, |
|||
showQuickJumper: true, |
|||
pageSizeOptions: [10, 20, 50], |
|||
showTotal: (total) => { |
|||
return <span style={{ fontSize: 15 }}>{`共${Math.ceil(total / query?.limit)}页,${total}项`}</span> |
|||
}, |
|||
onChange: (page, pageSize) => { |
|||
setQuery({ limit: pageSize, page: page - 1 }); |
|||
projectList({ limit: pageSize, page: page - 1, ...search, companyId: companyID || search?.companyId }) |
|||
} |
|||
}} |
|||
rowSelection={{ |
|||
selectedRowKeys: select?.map(v => v.id) || [], |
|||
onChange: (selectedRowKeys, selectedRows) => { |
|||
setSelect(selectedRows) |
|||
} |
|||
}} |
|||
/> |
|||
{ |
|||
addModel ? |
|||
<PointModel |
|||
modelData={modelData} |
|||
qrCodeId={qrCodeId} |
|||
devices={devices} |
|||
close={() => { |
|||
setAddModel(false) |
|||
setModelData({}) |
|||
}} |
|||
success={() => { |
|||
setAddModel(false) |
|||
setModelData({}) |
|||
setQuery({ limit: 10, page: 0 }); |
|||
projectList({ limit: 10, page: 0 }) |
|||
}} |
|||
/> : "" |
|||
} |
|||
</> |
|||
) |
|||
} |
|||
|
|||
function mapStateToProps(state) { |
|||
const { auth, global, device } = state; |
|||
return { |
|||
user: auth.user, |
|||
actions: global.actions, |
|||
devices: device?.data?.rows || [] |
|||
}; |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(Information); |
@ -1,404 +0,0 @@ |
|||
'use strict' |
|||
|
|||
import React, { Component } from 'react'; |
|||
import { connect } from 'react-redux'; |
|||
import { findDOMNode } from 'react-dom'; |
|||
import Heatmap from '../../components/pointDeploy/heatmap'; |
|||
import { DragDropContext } from 'react-dnd'; |
|||
import HTML5Backend from 'react-dnd-html5-backend'; |
|||
import { Layout, Tree, Button, Input, Popconfirm, message, Spin } from 'antd' |
|||
const { Content, Sider } = Layout; |
|||
const Search = Input.Search; |
|||
const TreeNode = Tree.TreeNode; |
|||
import StationSpot from '../../components/pointDeploy/station-spot'; |
|||
import './deploy-style.less'; |
|||
import { getProjectGraph, deleteGraph, getProjectPoints, getDeployPoints, setDeployPoints } from '../../actions/graph'; |
|||
import UploadImgModal from './upload-img-modal'; |
|||
import PerfectScrollbar from 'perfect-scrollbar'; |
|||
|
|||
class ConfigPlanarGraph extends Component { |
|||
constructor(props) { |
|||
super(props); |
|||
this.ps = null; |
|||
this.state = { |
|||
uploadImgModal: '', |
|||
searchValue: '', |
|||
deployState: -1, //0未布,1已布,-1全部
|
|||
filteredSpots: [], |
|||
spots: [], |
|||
dataHasChanged: false, |
|||
} |
|||
this.projectId = props?.match?.params?.id |
|||
} |
|||
|
|||
componentDidUpdate() { |
|||
let ele = document.getElementById('security-spots-scroller'); |
|||
if (ele) { |
|||
this.ps = new PerfectScrollbar(ele); |
|||
} |
|||
} |
|||
|
|||
componentDidMount() { |
|||
this.props.dispatch(getProjectPoints(this.projectId));//获取所有点位列表
|
|||
this.getData(); |
|||
} |
|||
|
|||
getData = () => { |
|||
this.props.dispatch(getProjectGraph(this.projectId)).then(_ => { |
|||
if (_.success) { |
|||
let graph = _.payload.data; |
|||
if (graph) {//有图片
|
|||
this.props.dispatch(getDeployPoints(graph.id));//获取平面图点位分布
|
|||
} |
|||
} |
|||
}); |
|||
} |
|||
|
|||
componentWillReceiveProps(nextProps) { |
|||
const { allPoints, projectDeployPoints } = nextProps; |
|||
if (projectDeployPoints && projectDeployPoints != this.props.projectDeployPoints) { |
|||
this.setSpotsState(allPoints, projectDeployPoints); |
|||
} |
|||
} |
|||
|
|||
setSpotsState = (allPoints, projectDeployPoints) => { |
|||
const { searchValue } = this.state; |
|||
let deployedSpotsMap = new Map(); |
|||
projectDeployPoints?.forEach(s => { |
|||
deployedSpotsMap.set(s.pointId, s); |
|||
}); |
|||
let tempData = []; |
|||
allPoints?.map(m => { |
|||
let x = null, y = null, screenH = null, screenW = null; |
|||
let deployed = false; |
|||
let station = deployedSpotsMap.get(m.id); |
|||
if (station) { |
|||
let p = JSON.parse(station.position); |
|||
x = p.x; |
|||
y = p.y; |
|||
screenH = p.screenHeight; |
|||
screenW = p.screenWidth; |
|||
deployed = true; |
|||
} |
|||
tempData.push({ |
|||
groupId: 1, |
|||
groupName: '全部', |
|||
pointId: m.id, |
|||
location: m.name, |
|||
x: x, |
|||
y: y, |
|||
screenHeight: screenH, |
|||
screenWidth: screenW, |
|||
deployed: deployed, |
|||
}) |
|||
}); |
|||
|
|||
let searchSpots = tempData; |
|||
if (searchValue.trim().length > 0) { |
|||
searchSpots = tempData.filter(s => s.location.indexOf(searchValue) >= 0); |
|||
} |
|||
|
|||
this.setState({ |
|||
spots: tempData, |
|||
filteredSpots: searchSpots, |
|||
}); |
|||
} |
|||
|
|||
onAddImgClick = () => { |
|||
this.openPcrModal(null) |
|||
}; |
|||
|
|||
editHandler = (heatmap) => { |
|||
this.openPcrModal(heatmap) |
|||
}; |
|||
|
|||
openPcrModal = (heatmap) => { |
|||
const { dispatch } = this.props; |
|||
this.setState({ |
|||
uploadImgModal: <UploadImgModal |
|||
dispatch={dispatch} |
|||
projectId={this.projectId} |
|||
pictureInfo={heatmap} |
|||
onCancel={this.closeUploadPointsImgModal} |
|||
getData={this.getData} |
|||
/>, |
|||
}) |
|||
} |
|||
|
|||
closeUploadPointsImgModal = () => { |
|||
this.setState({ uploadImgModal: '' }) |
|||
}; |
|||
|
|||
onDeploySpot = (spot) => { |
|||
const { pictureInfo, clientHeight, clientWidth } = this.props; |
|||
const { spots, deployState, searchValue, partsSpots } = this.state; |
|||
const that = this; |
|||
let h = clientHeight / 1.3; |
|||
let w = clientWidth / 1.4; |
|||
function dealPosition(spot, item) { |
|||
if (spot.deployed) { |
|||
item.x = spot.rect.x + spot.move.x; |
|||
item.y = spot.rect.y + spot.move.y; |
|||
item.screenHeight = h; |
|||
item.screenWidth = w; |
|||
} else { |
|||
const boundingClientRect = findDOMNode(that.refs.heatmapComponent).getBoundingClientRect(); |
|||
item.x = spot.spotInlist.x + spot.move.x - boundingClientRect.left; |
|||
item.y = spot.spotInlist.y + spot.move.y - boundingClientRect.top; |
|||
item.screenHeight = h; |
|||
item.screenWidth = w; |
|||
item.deployed = true; |
|||
} |
|||
} |
|||
if (pictureInfo) { |
|||
let tempSpots = Object.assign([], spots); |
|||
if (spot.info.pointId) { |
|||
tempSpots.forEach(item => { |
|||
if (item.pointId == spot.info.pointId) { |
|||
dealPosition(spot, item) |
|||
} |
|||
}); |
|||
} |
|||
|
|||
this.setState({ spots: tempSpots }); |
|||
this.filterSpots(deployState, searchValue); |
|||
this.setState({ changedTreeNodeKey: spot.info.key, dataHasChanged: true }); |
|||
} |
|||
}; |
|||
|
|||
filterSpots = (deployState, searchValue) => { |
|||
let deploySpots = this.state.spots; |
|||
if (deployState != -1) { |
|||
deploySpots = this.state.spots.filter(s => s.deployed == (deployState == 1 ? true : false)); |
|||
} |
|||
|
|||
let searchSpots = deploySpots; |
|||
if (searchValue.trim().length > 0) { |
|||
searchSpots = deploySpots.filter(s => s.location.indexOf(searchValue) >= 0); |
|||
} |
|||
|
|||
this.setState({ |
|||
searchValue, |
|||
deployState, |
|||
filteredSpots: searchSpots |
|||
}); |
|||
}; |
|||
|
|||
onSearch = (searchValue) => { |
|||
this.filterSpots(this.state.deployState, searchValue); |
|||
}; |
|||
handleStateChange = (deployState) => { |
|||
this.filterSpots(deployState, this.state.searchValue); |
|||
}; |
|||
|
|||
onRemoveSpot = (spot) => { |
|||
const { pictureInfo } = this.props; |
|||
const { spots, deployState, searchValue, partsSpots } = this.state; |
|||
if (pictureInfo) { |
|||
let tempSpots; |
|||
if (spot.pointId) { |
|||
tempSpots = Object.assign([], spots); |
|||
tempSpots.forEach(item => { |
|||
if (item.pointId == spot.pointId) { |
|||
item.x = null; |
|||
item.y = null; |
|||
item.screenWidth = null; |
|||
item.screenHeight = null; |
|||
item.deployed = false; |
|||
} |
|||
}); |
|||
tempSpots = tempSpots.concat(partsSpots) |
|||
} else { |
|||
tempSpots = Object.assign([], partsSpots); |
|||
tempSpots.forEach(item => { |
|||
if (item.partId == spot.partId) { |
|||
item.x = null; |
|||
item.y = null; |
|||
item.screenWidth = null; |
|||
item.screenHeight = null; |
|||
item.deployed = false; |
|||
} |
|||
}); |
|||
tempSpots = tempSpots.concat(spots) |
|||
} |
|||
this.filterSpots(deployState, searchValue); |
|||
this.setState({ changedTreeNodeKey: spot.key, dataHasChanged: true }); |
|||
} |
|||
}; |
|||
|
|||
loop = (data) => { |
|||
if (!data || data.length == 0) return; |
|||
|
|||
const treeNodes = []; |
|||
data.forEach((item) => { |
|||
let title = <StationSpot info={item} children={item.children} />; |
|||
if (item.children) { |
|||
treeNodes.push( |
|||
<TreeNode key={item.key} title={title}> |
|||
{this.loop(item.children)} |
|||
</TreeNode> |
|||
); |
|||
} else { |
|||
let titleProps = { |
|||
info: item, |
|||
children: item.children, |
|||
onRemoveSpot: this.onRemoveSpot, |
|||
}; |
|||
//性能优化,减少组件渲染
|
|||
if (this.state.changedTreeNodeKey == item.key) titleProps.key = Math.random(); |
|||
let nodeTitle = <StationSpot {...titleProps} />; |
|||
treeNodes.push(<TreeNode key={item.key} title={nodeTitle} />); |
|||
} |
|||
}); |
|||
return treeNodes; |
|||
}; |
|||
|
|||
formatTreeSource = (data) => { |
|||
if (!data || data.length == 0) return; |
|||
let tempGroups = new Map(); |
|||
data.map(item => { |
|||
if (tempGroups.has(item.groupId)) { |
|||
let groupChildren = tempGroups.get(item.groupId).children; |
|||
item.key = `0-${item.groupId}-${item.pointId}`; |
|||
groupChildren.set(item.pointId, item); |
|||
} else { |
|||
tempGroups.set(item.groupId, { |
|||
'key': `0-${item.groupId}`, |
|||
'location': item.groupName, |
|||
'groupId': item.groupId, |
|||
'children': new Map(), |
|||
}); |
|||
let groupChildren = tempGroups.get(item.groupId).children; |
|||
item.key = `0-${item.groupId}-${item.pointId}`; |
|||
groupChildren.set(item.pointId, item); |
|||
} |
|||
}); |
|||
return tempGroups; |
|||
}; |
|||
|
|||
onSaveClick = () => { |
|||
this.saveHotspots(this.state.spots); |
|||
}; |
|||
|
|||
saveHotspots = (data) => { |
|||
const { pictureInfo } = this.props; |
|||
let postData = data.filter(s => s.x != null && s.y != null).map(item => { |
|||
const { x, y, screenWidth, screenHeight } = item; |
|||
let relativeX = parseFloat((x / screenWidth).toFixed(4)); |
|||
let relativeY = parseFloat((y / screenHeight).toFixed(4)); |
|||
if (item.pointId) { |
|||
return ({ |
|||
pointId: item.pointId, |
|||
position: { x, y, screenWidth, screenHeight, relativeX, relativeY } |
|||
}) |
|||
} |
|||
}); |
|||
this.props.dispatch(setDeployPoints(pictureInfo.id, { "spots": postData })).then(res => { |
|||
this.setState({ dataHasChanged: false, deployState: -1 }, () => { |
|||
this.props.dispatch(getDeployPoints(pictureInfo.id));//获取平面图点位分布
|
|||
}); |
|||
}); |
|||
}; |
|||
|
|||
render() { |
|||
const { pictureInfo, clientHeight, clientWidth, allPoints } = this.props; |
|||
const { deployState, spots, filteredSpots, dataHasChanged } = this.state; |
|||
const treeDataSource = this.formatTreeSource(filteredSpots); |
|||
let h = clientHeight / 1.3; |
|||
let w = clientWidth / 1.4; |
|||
return (<div className='patrolLayout'> |
|||
<header className='title' style={{ marginBottom: 10 }}> |
|||
<span className='line'></span> |
|||
<span className='cn'>布设信息</span> |
|||
<span className='en'> DEPLOYMENT INFORMATION</span> |
|||
</header> |
|||
<Layout> |
|||
<Sider width={'23%'} style={{ background: 'transparent' }}> |
|||
<div style={{ display: 'flex' }}> |
|||
<div style={{ display: 'flex', flexDirection: 'column' }}> |
|||
<Button className={deployState == -1 ? 'btn-spots-filter' : 'btn-default'} style={{ borderRadius: 0, margin: '0 20px 7px 0' }} onClick={() => this.handleStateChange(-1)}>全部</Button> |
|||
<Button className={deployState == 1 ? 'btn-spots-filter' : 'btn-default'} style={{ borderRadius: 0, margin: '0 20px 7px 0' }} onClick={() => this.handleStateChange(1)}>已布</Button> |
|||
<Button className={deployState == 0 ? 'btn-spots-filter' : 'btn-default'} style={{ borderRadius: 0, margin: '0 20px 7px 0' }} onClick={() => this.handleStateChange(0)}>未布</Button> |
|||
</div> |
|||
<div className='PingFangSC-Regular'>点位:</div> |
|||
<div> |
|||
<div className='search-panel'> |
|||
<div style={{ marginTop: -1 }}> |
|||
<Search |
|||
placeholder={"请输入名称关键字搜索"} |
|||
style={{ borderRadius: 0 }} |
|||
onChange={e => this.onSearch(e.target.value)} |
|||
/> |
|||
</div> |
|||
</div> |
|||
{ |
|||
treeDataSource ? |
|||
<div id='security-spots-scroller' style={{ position: 'relative', height: h - 63 }}> |
|||
<Tree className='equip-tree' showLine defaultExpandAll={true}> |
|||
{this.loop(treeDataSource)} |
|||
</Tree> </div> : <div style={{ textAlign: 'center' }}>暂无点位</div> |
|||
} |
|||
</div> |
|||
</div> |
|||
</Sider> |
|||
<Layout> |
|||
<Content className='spots-opr-content' style={{ width: w }}> |
|||
{spots && pictureInfo?.graph ? |
|||
<Heatmap key={Math.random()} |
|||
ref="heatmapComponent" |
|||
height={h} |
|||
width={w} |
|||
image={pictureInfo?.graph} |
|||
spots={spots.filter(s => s.deployed == true)} |
|||
onRemoveSpot={this.onRemoveSpot} |
|||
onDeploySpot={this.onDeploySpot} |
|||
/> |
|||
: <div style={{ border: '1px dashed #999', width: w, height: h, paddingTop: h * 0.3, textAlign: 'center' }}> |
|||
<img className='no-deploy-img' src='/assets/images/no_deploy.svg'></img> |
|||
<div className='PingFangSC-Regular'>暂无热点图~</div> |
|||
</div> |
|||
} |
|||
<div className='opr-tip-row'> |
|||
<div className='PingFangSC-Regular'>说明:拖拽点位进行布设,拖出画布移除点位。</div> |
|||
{ |
|||
pictureInfo ? |
|||
<div className='opr-button'> |
|||
<Popconfirm |
|||
title='确认删除该结构物布设图?(已布点位将同步删除)' |
|||
position='top' |
|||
onConfirm={() => { |
|||
this.props.dispatch(deleteGraph(pictureInfo.id)).then(_ => { |
|||
this.getData(); |
|||
this.setSpotsState(allPoints, []) |
|||
}) |
|||
}}> |
|||
<Button className='graph-cfg-btn'>删除图片</Button> |
|||
</Popconfirm> |
|||
<Button className='graph-cfg-btn' onClick={() => this.editHandler(pictureInfo)} style={{ marginLeft: 15 }}>修改图片</Button> |
|||
<Button className='graph-cfg-btn' type='primary' onClick={this.onSaveClick} disabled={!dataHasChanged} style={{ marginLeft: 15 }}>完成</Button> |
|||
</div> |
|||
: |
|||
<div className='opr-button'> |
|||
<Button className='graph-cfg-btn' type='primary' onClick={this.onAddImgClick}>添加布设图</Button> |
|||
</div> |
|||
} |
|||
</div> |
|||
</Content> |
|||
</Layout> |
|||
</Layout> |
|||
{this.state.uploadImgModal} |
|||
</div>) |
|||
} |
|||
} |
|||
function mapStateToProps(state) { |
|||
const { global, projectGraph, projectDeployPoints, projectAllPoints } = state; |
|||
return { |
|||
pictureInfo: projectGraph.data, |
|||
projectDeployPoints: projectDeployPoints?.data || [], |
|||
clientHeight: global.clientHeight, |
|||
clientWidth: global.clientWidth, |
|||
allPoints: projectAllPoints?.data || [] |
|||
}; |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(DragDropContext(HTML5Backend)(ConfigPlanarGraph)); |
@ -1,137 +0,0 @@ |
|||
.spots-opr-content { |
|||
padding: 0; |
|||
margin: 0; |
|||
position: relative; |
|||
} |
|||
|
|||
.opr-tip-row { |
|||
display: flex; |
|||
margin-top: 10px; |
|||
justify-content: space-between; |
|||
} |
|||
|
|||
.opr-button { |
|||
|
|||
.ant-btn-disabled, |
|||
.ant-btn.disabled, |
|||
.ant-btn[disabled] { |
|||
//按钮 禁用 |
|||
background-color: #3198F7; |
|||
} |
|||
} |
|||
|
|||
.graph-cfg-btn { |
|||
color: #fff; |
|||
background-color: #3198F7; |
|||
border-color: #3198F7; |
|||
} |
|||
|
|||
//蓝色按钮 鼠标悬浮 |
|||
.graph-cfg-btn:hover, |
|||
.graph-cfg-btn:focus { |
|||
//color: #fff; |
|||
background-color: #3198F7; |
|||
border-color: #3198F7; |
|||
} |
|||
|
|||
.patrolLayout { |
|||
margin-top: 20px; |
|||
background-color: #fff; |
|||
padding: 10px 16px; |
|||
|
|||
.ant-layout { |
|||
background-color: transparent; |
|||
} |
|||
|
|||
.ant-input:hover, |
|||
.ant-input:focus { |
|||
border-color: #fff; |
|||
} |
|||
|
|||
.search-panel { |
|||
text-align: center; |
|||
margin-bottom: 7px; |
|||
|
|||
.btn-spots-filter { |
|||
//选中的 |
|||
background-color: #3198F7; |
|||
border-color: #3198F7; |
|||
color: #fff; |
|||
} |
|||
} |
|||
|
|||
.search-panel input { |
|||
-webkit-border-radius: 0; |
|||
-moz-border-radius: 0; |
|||
border-radius: 0; |
|||
} |
|||
} |
|||
|
|||
.equip-tree { |
|||
|
|||
//测点 树结构 |
|||
.ant-tree.ant-tree-show-line li span.ant-tree-switcher { |
|||
//展开, 关闭按钮 |
|||
color: #fff; |
|||
} |
|||
|
|||
.ant-tree li .ant-tree-node-content-wrapper { |
|||
//文字白色 |
|||
color: #fff; |
|||
} |
|||
|
|||
.ant-tree.ant-tree-show-line li:not(:last-child)::before { |
|||
//不显示竖线 |
|||
width: 0px; |
|||
border: 0px; |
|||
} |
|||
|
|||
.ant-tree li .ant-tree-node-content-wrapper.ant-tree-node-selected { |
|||
background-color: #98e5f381; |
|||
} |
|||
|
|||
.ant-tree-node-content-wrapper:hover, |
|||
.ant-tree-node-content-wrapper:focus { |
|||
//文字鼠标悬浮 背景色 蓝色 |
|||
background-color: #3198F7 !important; |
|||
} |
|||
} |
|||
|
|||
//查询按钮 |
|||
.ant-input-group-addon { |
|||
background-color: transparent; |
|||
|
|||
.ant-btn { |
|||
background-color: transparent !important; |
|||
} |
|||
|
|||
.ant-btn-primary { |
|||
float: right; |
|||
width: 90px; |
|||
height: 45px; |
|||
margin: 5px 0px 0px 10px; |
|||
background-color: #3198f7; |
|||
border-color: #3198f7; |
|||
} |
|||
|
|||
.ant-btn-primary:hover { |
|||
border-color: #3198f7; |
|||
} |
|||
|
|||
.ant-btn-primary:focus { |
|||
border-color: #3198f7; |
|||
} |
|||
} |
|||
|
|||
.PingFangSC-Regular { |
|||
font-family: PingFangSC-Regular; |
|||
font-weight: 400; |
|||
font-size: 14px; |
|||
color: #4A4A4A; |
|||
line-height: 30px; |
|||
} |
|||
|
|||
.no-deploy-img { |
|||
width: 289px; |
|||
height: 216px; |
|||
} |
@ -1,94 +0,0 @@ |
|||
import React, { useEffect, useState } from 'react'; |
|||
import { connect } from 'react-redux'; |
|||
import Uploads from '$components/Uploads'; |
|||
import { Input, Modal, Form, Button, message, Select } from 'antd'; |
|||
import { getProjectGraph, createGraph, updateGraph } from '../../actions/graph'; |
|||
|
|||
const DisclosureModal = (props) => { |
|||
const { dispatch, onCancel, projectId, pictureInfo, getData } = props; |
|||
let files = pictureInfo ? [{ storageUrl: pictureInfo.graph }] : [] |
|||
const [form] = Form.useForm(); |
|||
const [editUrl, setEditUrl] = useState(files); |
|||
//初始化表单数据
|
|||
const getinitialValues = () => { |
|||
if (pictureInfo) { |
|||
return { files: 1 }; |
|||
} |
|||
return {} |
|||
}; |
|||
|
|||
useEffect(() => { |
|||
}, []); |
|||
|
|||
const handleOk = () => { |
|||
form.validateFields().then(values => { |
|||
let data = { |
|||
projectId: projectId, |
|||
graph: editUrl[0]?.storageUrl, |
|||
} |
|||
if (pictureInfo) {//更新
|
|||
dispatch(updateGraph(pictureInfo.id, data)).then(_ => { |
|||
getData() |
|||
}); |
|||
} else {//新增
|
|||
dispatch(createGraph(data)).then(_ => { |
|||
getData(); |
|||
}); |
|||
} |
|||
onCancel() |
|||
}) |
|||
} |
|||
|
|||
const vsjunct = (params) => { |
|||
if (params.length) { |
|||
let appendix = [] |
|||
for (let p of params) { |
|||
appendix.push({ |
|||
fName: p.name, |
|||
size: p.size, |
|||
fileSize: p.size, |
|||
storageUrl: p.storageUrl,//必须有storageUrl
|
|||
}) |
|||
} |
|||
setEditUrl(appendix) |
|||
} else { |
|||
setEditUrl([]) |
|||
} |
|||
} |
|||
|
|||
return ( |
|||
<Modal title='添加布设图' visible={true} destroyOnClose |
|||
onCancel={onCancel} onOk={handleOk}> |
|||
<Form form={form} labelCol={{ span: 6 }} wrapperCol={{ span: 17 }} initialValues={getinitialValues()}> |
|||
<Form.Item label="布设图" name='files' |
|||
rules={[{ required: true, message: '请上传布设图' }]}> |
|||
<Uploads |
|||
className='upload' |
|||
listType='card' |
|||
uploadType='project' |
|||
maxFilesNum={1} |
|||
maxFileSize={10} |
|||
isQiniu={true} |
|||
onChange={vsjunct} |
|||
fileTypes={["png", "jpeg", "jpg"]} |
|||
value={editUrl} |
|||
defaultValue={editUrl} |
|||
/> |
|||
</Form.Item> |
|||
<Form.Item style={{ paddingLeft: '17%' }}> |
|||
<div style={{ color: '#999', width: 460 }}>说明:附件格式为png、jpeg、jpg,大小不超过10MB</div> |
|||
</Form.Item> |
|||
</Form> |
|||
</Modal> |
|||
) |
|||
} |
|||
|
|||
function mapStateToProps(state) { |
|||
const { auth, global } = state; |
|||
return { |
|||
user: auth.user, |
|||
actions: global.actions, |
|||
} |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(DisclosureModal); |
@ -1,173 +0,0 @@ |
|||
import React, { useEffect, useState } from 'react'; |
|||
import { connect } from 'react-redux'; |
|||
import { Form, Input, Select, Button, message } from 'antd'; |
|||
import JSZip from 'jszip'; |
|||
import './qrCode.less'; |
|||
|
|||
const QrCode = (props) => { |
|||
const { dispatch, actions } = props |
|||
const { projectRegime } = actions |
|||
const [firmList, setFirmList] = useState([]) |
|||
const [tableList, settableList] = useState([]) |
|||
const [downloading, setDownloading] = useState(false) |
|||
|
|||
useEffect(() => { |
|||
dispatch(projectRegime.getProjectList({ justStructure: true })).then(res => { |
|||
if (res.success) { |
|||
setFirmList(res.payload.data?.rows?.map(v => ({ value: v.id, label: v.name }))) |
|||
} |
|||
}) |
|||
projectList({}) |
|||
}, []) |
|||
|
|||
const projectList = (obj) => { |
|||
const { projectId, name } = obj |
|||
dispatch(projectRegime.qrCodeShow({ projectId, name })).then(res => { |
|||
if (res.success) { |
|||
settableList(res.payload.data?.rows) |
|||
} |
|||
}) |
|||
} |
|||
|
|||
const imgError = (e) => { |
|||
const img = e.currentTarget; |
|||
img.src = '/assets/images/no_qcoder.png'; |
|||
img.onerror = null; |
|||
} |
|||
|
|||
const batchDownload = () => { |
|||
if (tableList.length === 0) { |
|||
message.warning('没有数据可以导出') |
|||
return |
|||
} |
|||
setDownloading(true) |
|||
let promiseArr = [], nameArr = [] |
|||
tableList.forEach(l => { |
|||
promiseArr.push( |
|||
window.fetch(`/_file-server/${l.qrCode}`, { |
|||
method: 'get', |
|||
headers: { |
|||
"Accept": "application/json", |
|||
"Content-Type": "application/json", |
|||
"X-Requested-With": "XMLHttpRequest", |
|||
}, |
|||
}) |
|||
) |
|||
nameArr.push(l.name + '.jpeg') |
|||
}) |
|||
try { |
|||
Promise.all(promiseArr).then(async resArr => { |
|||
const zip = new JSZip() |
|||
for (let i = 0; i < resArr.length; i++) { |
|||
const response = resArr[i] |
|||
const blob = await response.blob() |
|||
zip.file(nameArr[i], blob) |
|||
} |
|||
zip.generateAsync({ type: "blob" }).then(blob => { |
|||
const url = window.URL.createObjectURL(blob) |
|||
downloadFile(url, "点位二维码.zip") |
|||
setDownloading(false) |
|||
message.success('下载成功') |
|||
}); |
|||
}) |
|||
} catch (error) { |
|||
console.log(error) |
|||
setDownloading(false) |
|||
message.error('下载失败') |
|||
} |
|||
} |
|||
|
|||
return ( |
|||
<div className='global-main'> |
|||
<div className='top'> |
|||
<div className='title'> |
|||
<span className='line'></span> |
|||
<span className='cn'>二维码</span> |
|||
<span className='en'> QRCode</span> |
|||
</div> |
|||
<Form |
|||
style={{ display: 'flex', }} |
|||
onFinish={r => { |
|||
projectList(r) |
|||
}} |
|||
> |
|||
<Form.Item |
|||
label='结构物名称' |
|||
name="projectId" |
|||
style={{ marginRight: 16, width: 240 }} |
|||
// initialValue={firmList[0]?.name}
|
|||
> |
|||
<Select allowClear placeholder="请选择结构物名称" options={firmList} /> |
|||
</Form.Item> |
|||
<Form.Item |
|||
label='点位名称' |
|||
name="name" |
|||
style={{ marginRight: 16, width: 260 }} |
|||
> |
|||
<Input placeholder="请输入点位名称" allowClear /> |
|||
</Form.Item> |
|||
<Form.Item wrapperCol={{}}> |
|||
<Button htmlType="submit" style={{ marginRight: 16 }}>搜索</Button> |
|||
<Button type="primary" onClick={batchDownload} loading={downloading}>导出</Button> |
|||
</Form.Item> |
|||
</Form> |
|||
</div> |
|||
|
|||
<div> |
|||
{ |
|||
tableList?.map(v => { |
|||
return <div key={v.name + v.id} |
|||
style={{ |
|||
display: 'inline-block', |
|||
margin: '0 20px 20px 0', |
|||
border: '1px solid #3c383824', |
|||
borderRadius: '3px' |
|||
}} |
|||
> |
|||
<img src={`/_file-server/${v.qrCode}`} style={{ display: 'inline-block', width: 234 }} onError={imgError} /> |
|||
<div style={{ |
|||
display: 'flex', flexDirection: 'column', padding: '6px 0', |
|||
width: 220, alignItems: 'center' |
|||
}}> |
|||
<span className='stru-name'>{firmList?.filter(u => u.value == v.projectId)[0]?.label}</span> |
|||
<span className='point-name'>点位名称:{v.name}</span> |
|||
</div> |
|||
<div style={{ |
|||
width: 234, height: 60, display: 'flex', |
|||
justifyContent: 'center', alignItems: 'center', |
|||
}}> |
|||
<Button type="primary" onClick={() => { |
|||
const tempArr = v.qrCode.split('/') |
|||
const filename = tempArr[tempArr.length - 1] |
|||
downloadFile(`/_file-server/${v.qrCode}`, filename) |
|||
}}>下载二维码</Button> |
|||
</div> |
|||
</div> |
|||
} |
|||
) |
|||
} |
|||
</div> |
|||
|
|||
</div> |
|||
) |
|||
} |
|||
|
|||
function mapStateToProps(state) { |
|||
const { auth, global } = state; |
|||
return { |
|||
user: auth.user, |
|||
actions: global.actions, |
|||
}; |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(QrCode); |
|||
|
|||
function downloadFile(url, fileName) { |
|||
const a = document.createElement('a'); |
|||
a.style.display = 'none'; |
|||
a.href = url; |
|||
a.download = fileName; |
|||
document.body.appendChild(a); |
|||
a.click(); |
|||
document.body.removeChild(a); |
|||
} |
@ -1,44 +0,0 @@ |
|||
.top { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
|
|||
.title { |
|||
background-color: #fff; |
|||
display: inline-block; |
|||
|
|||
.line { |
|||
display: inline-block; |
|||
width: 3px; |
|||
height: 20px; |
|||
background: #006BE3; |
|||
} |
|||
|
|||
.cn { |
|||
font-family: YouSheBiaoTiHei; |
|||
font-size: 24px; |
|||
color: #101531; |
|||
margin-left: 11px; |
|||
} |
|||
|
|||
.en { |
|||
font-family: D-DINExp-Italic; |
|||
font-weight: Italic; |
|||
font-size: 12px; |
|||
color: #969799; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.stru-name { |
|||
font-family: PingFangSC-Medium; |
|||
font-weight: 500; |
|||
font-size: 16px; |
|||
color: #323233; |
|||
} |
|||
.point-name { |
|||
font-family: PingFangSC-Regular; |
|||
font-weight: 400; |
|||
font-size: 14px; |
|||
color: #646566; |
|||
line-height: 18px; |
|||
} |
@ -1,15 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
import reducers from './reducers'; |
|||
import routes from './routes'; |
|||
import actions from './actions'; |
|||
import { getNavItem } from './nav-item'; |
|||
|
|||
export default { |
|||
key: 'projectRegime', |
|||
name: '结构物管理', |
|||
reducers: reducers, |
|||
routes: routes, |
|||
actions: actions, |
|||
getNavItem: getNavItem |
|||
}; |
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue