diff --git a/web/client/src/app.js b/web/client/src/app.js
index 98d351d..1597273 100644
--- a/web/client/src/app.js
+++ b/web/client/src/app.js
@@ -7,6 +7,7 @@ import Safetymanage from './sections/safetymanage';
import ProjectRegime from './sections/projectRegime';
import Organization from './sections/organization';
import PatrolManage from './sections/patrolManage';
+import IssueHandle from './sections/issueHandle'
const App = props => {
const { projectName } = props
@@ -18,7 +19,7 @@ const App = props => {
return (
)
diff --git a/web/client/src/sections/issueHandle/actions/checkItems.js b/web/client/src/sections/issueHandle/actions/checkItems.js
new file mode 100644
index 0000000..f7a2666
--- /dev/null
+++ b/web/client/src/sections/issueHandle/actions/checkItems.js
@@ -0,0 +1,78 @@
+'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_GRROUP',
+ url: ApiTable.checkItemsGroup,
+ msg: { error: '获取检查项分组失败' },
+ reducer:{name:'checkItemsGroup'}
+ });
+}
+
+export function createCheckItemsGroup(data) {
+ return dispatch => basicAction({
+ type: 'post',
+ data,
+ dispatch: dispatch,
+ actionType: 'CREATE_CHECK_ITEMS_GRROUP',
+ url: ApiTable.checkItemsGroup,
+ 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,
+}
\ No newline at end of file
diff --git a/web/client/src/sections/issueHandle/actions/index.js b/web/client/src/sections/issueHandle/actions/index.js
new file mode 100644
index 0000000..d6e7974
--- /dev/null
+++ b/web/client/src/sections/issueHandle/actions/index.js
@@ -0,0 +1,13 @@
+'use strict';
+
+import * as plan from './plan'
+import * as record from './record'
+import * as template from './template'
+import * as checkItems from './checkItems'
+
+export default {
+ ...plan,
+ ...record,
+ ...template,
+ ...checkItems,
+}
\ No newline at end of file
diff --git a/web/client/src/sections/issueHandle/actions/plan.js b/web/client/src/sections/issueHandle/actions/plan.js
new file mode 100644
index 0000000..6b94bca
--- /dev/null
+++ b/web/client/src/sections/issueHandle/actions/plan.js
@@ -0,0 +1,80 @@
+'use strict';
+
+import { basicAction } from '@peace/utils'
+import { ApiTable } from '$utils'
+
+export function getPatrolPlan() {
+ return dispatch => basicAction({
+ type: 'get',
+ 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: '获取点位列表失败', },
+ });
+}
\ No newline at end of file
diff --git a/web/client/src/sections/issueHandle/actions/record.js b/web/client/src/sections/issueHandle/actions/record.js
new file mode 100644
index 0000000..a6ae77e
--- /dev/null
+++ b/web/client/src/sections/issueHandle/actions/record.js
@@ -0,0 +1,17 @@
+'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' }
+ });
+}
\ No newline at end of file
diff --git a/web/client/src/sections/issueHandle/actions/template.js b/web/client/src/sections/issueHandle/actions/template.js
new file mode 100644
index 0000000..0442191
--- /dev/null
+++ b/web/client/src/sections/issueHandle/actions/template.js
@@ -0,0 +1,47 @@
+'use strict';
+
+import { basicAction } from '@peace/utils'
+import { ApiTable } from '$utils'
+
+export function getPatrolTemplate () {
+ return dispatch => basicAction({
+ type: 'get',
+ 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: '修改巡检模板' },
+ });
+}
\ No newline at end of file
diff --git a/web/client/src/sections/issueHandle/components/isuue-handle-mdal.js b/web/client/src/sections/issueHandle/components/isuue-handle-mdal.js
new file mode 100644
index 0000000..4c14b5b
--- /dev/null
+++ b/web/client/src/sections/issueHandle/components/isuue-handle-mdal.js
@@ -0,0 +1,207 @@
+import React, { useState, useRef } from 'react';
+import { Button, Form, Row, Col, Table, Popconfirm, Input, message } from 'antd';
+import {
+ ModalForm,
+ ProFormText,
+ ProFormSelect,
+ ProFormTextArea,
+ ProFormDatePicker
+} 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, companyList, user } = props;
+ const formItemLayout = { labelCol: { span: 6 }, wrapperCol: { span: 16 } };
+ const initialValues = editData ? {
+ ...editData
+ } : {};
+ const [reason, setReason] = useState('')
+
+
+ const columns = [
+ {
+ title: '序号',
+ dataIndex: 'index',
+ key: 'index',
+ render: (text, record, index) => index + 1
+ },
+ {
+ title: '提交时间',
+ dataIndex: 'time',
+ key: 'time',
+ },
+ {
+ title: '整改附件',
+ dataIndex: 'file',
+ key: 'file',
+ render: (text, record) => {
+ return
+ }
+ },
+ {
+ title: '结论',
+ dataIndex: 'status',
+ key: 'status',
+ // 0 未审批 1 通过 2驳回
+ render: (text, record) => {
+ return user?.departmentId != -1 && record?.status === 0 ? <>
+ 驳回原因: {
+ setReason(e.target.value)
+ }} />>}
+ onConfirm={() => {
+ if (!reason) {
+ message.warning('未填写驳回原因');
+ return;
+ }
+ handleResult(false)
+ }} >
+
+
+ >
+ : record?.status === 1 ? "整改完成" : record?.reason
+ }
+ },
+ ];
+
+ const handleResult = (approve) => {
+ const results = JSON.parse(JSON.stringify(editData?.result || []))
+ results[results.length - 1] = {
+ ...results[results.length - 1], status: approve ? 1 : 2,
+ reason
+ }
+ onFinish && onFinish({
+ msg: approve ? '任务审批' : '任务驳回',
+ state: approve ? 3 : 1,
+ result: results
+ }, editData)
+ }
+
+ return (
+
+ {title || ''}
+
+ }
+ width={1200}
+ layout="horizontal"
+ // grid={true}
+ {...formItemLayout}
+ modalProps={{
+ destroyOnClose: true,
+ onCancel: () => { },
+ bodyStyle: { height: 720, overflowY: 'auto' }
+ }}
+ onFinish={async (values) => {
+
+ onFinish && await onFinish(values, editData)
+ //message.success('提交成功');
+ return true;
+ }}
+ submitter={!readOnly}
+ >
+
+
+
+
+
+ );
+};
\ No newline at end of file
diff --git a/web/client/src/sections/issueHandle/containers/index.js b/web/client/src/sections/issueHandle/containers/index.js
new file mode 100644
index 0000000..2a7741e
--- /dev/null
+++ b/web/client/src/sections/issueHandle/containers/index.js
@@ -0,0 +1,5 @@
+'use strict';
+
+import PatrolReocrd from './patrolRecord';
+
+export { PatrolReocrd };
\ No newline at end of file
diff --git a/web/client/src/sections/issueHandle/containers/patrolRecord.js b/web/client/src/sections/issueHandle/containers/patrolRecord.js
new file mode 100644
index 0000000..938dae2
--- /dev/null
+++ b/web/client/src/sections/issueHandle/containers/patrolRecord.js
@@ -0,0 +1,211 @@
+
+'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'
+
+const { Panel } = Collapse;
+
+const PatrolRecord = (props) => {
+ const { dispatch, actions, user } = 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 times = [moment().subtract(70, 'years').format(format), moment().format(format)]
+ const [search, setSearch] = useState({ name: null, time: [times[0], times[1]], state: 'null' })
+
+ useEffect(() => {
+ record(search)
+ }, [])
+
+ const record = (params) => {
+ dispatch(patrolManage.records(`patrolRecord/all/${times[0]}/${times[1]}/null/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 onFinish = () => {
+
+ }
+
+ const renderOptionText = (currentState) => {
+ let text = '查看'
+ if (user?.departmentId == -1) {
+ if (currentState == 1) text = '整改'
+ } else {
+ if (currentState == 2) text = '审批'
+ }
+
+ return text
+ }
+
+ const columns = [{
+ title: '结构物名称',
+ dataIndex: 'name',
+ key: 'name',
+ width: '10%',
+ showInDetail: true,
+ render: (text, record, index) => {
+ return !record.points?.project ? '' :
{record.points.project.name}
+ }
+ }, {
+ title: '巡检计划',
+ dataIndex: 'name',
+ key: 'name',
+ width: '10%',
+ showInDetail: true,
+ render: (text, record, index) => {
+ return !record.patrolPlan ? '' : {record.patrolPlan.name}
+ }
+ }, {
+ title: '巡检点位',
+ dataIndex: 'type',
+ key: 'type',
+ showInDetail: true,
+ width: '10%',
+ render: (text, record, index) => {
+ return !record.points?.user ? '' : {record.points.itemData.name}
+ }
+ }, {
+ title: '巡检人',
+ dataIndex: 'type',
+ key: 'type',
+ showInDetail: true,
+ width: '10%',
+ render: (text, record, index) => {
+ return !record.points?.user ? '' : {record.points.user.name}
+ }
+ }, {
+ title: '巡检单位',
+ dataIndex: 'type',
+ showInDetail: true,
+ key: 'type',
+ width: '10%',
+ render: (text, record, index) => {
+ return !record.points?.user ? '' : {record.points.user.department.name}
+ }
+ }, {
+ title: '巡检频次',
+ dataIndex: 'describe',
+ key: 'describe',
+ showInDetail: true,
+ width: '10%',
+ render: (text, record, index) => {
+ return !record.points ? '' : {record.points.frequency}
+ }
+ }, {
+ 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 (
+ {renderOptionText(1)}}
+ user={{}}
+ onFinish={onFinish} />
+ )
+ }
+ }
+ ]
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+function mapStateToProps(state) {
+ const { auth, global } = state;
+ return {
+ user: auth.user,
+ actions: global.actions,
+ };
+}
+
+export default connect(mapStateToProps)(PatrolRecord);
diff --git a/web/client/src/sections/issueHandle/index.js b/web/client/src/sections/issueHandle/index.js
new file mode 100644
index 0000000..7cd6175
--- /dev/null
+++ b/web/client/src/sections/issueHandle/index.js
@@ -0,0 +1,15 @@
+'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
+};
\ No newline at end of file
diff --git a/web/client/src/sections/issueHandle/nav-item.js b/web/client/src/sections/issueHandle/nav-item.js
new file mode 100644
index 0000000..f9ab880
--- /dev/null
+++ b/web/client/src/sections/issueHandle/nav-item.js
@@ -0,0 +1,18 @@
+import React from 'react';
+import { Link } from 'react-router-dom';
+import { Menu } from 'antd';
+import { SettingOutlined } from '@ant-design/icons';
+
+const SubMenu = Menu.SubMenu;
+
+export function getNavItem(user, dispatch) {
+ // if (!Func.isAuthorized("ORG_MANAGE")) {
+ // return null
+ // }
+ return (
+ } key="issueHandle">
+ 维修处理
+
+
+ );
+}
\ No newline at end of file
diff --git a/web/client/src/sections/issueHandle/reducers/index.js b/web/client/src/sections/issueHandle/reducers/index.js
new file mode 100644
index 0000000..0203d01
--- /dev/null
+++ b/web/client/src/sections/issueHandle/reducers/index.js
@@ -0,0 +1,5 @@
+'use strict';
+
+export default {
+
+};
\ No newline at end of file
diff --git a/web/client/src/sections/issueHandle/reducers/record.js b/web/client/src/sections/issueHandle/reducers/record.js
new file mode 100644
index 0000000..91fa14a
--- /dev/null
+++ b/web/client/src/sections/issueHandle/reducers/record.js
@@ -0,0 +1,32 @@
+'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;
\ No newline at end of file
diff --git a/web/client/src/sections/issueHandle/routes.js b/web/client/src/sections/issueHandle/routes.js
new file mode 100644
index 0000000..f4ac052
--- /dev/null
+++ b/web/client/src/sections/issueHandle/routes.js
@@ -0,0 +1,13 @@
+'use strict';
+import { PatrolReocrd } from './containers';
+
+export default [{
+ type: 'inner',
+ route: {
+ path: '/issueHandle',
+ key: 'issueHandle',
+ breadcrumb: '维修处理',
+ component: PatrolReocrd,
+
+ }
+}];
\ No newline at end of file
diff --git a/web/client/src/sections/issueHandle/style.less b/web/client/src/sections/issueHandle/style.less
new file mode 100644
index 0000000..143a23b
--- /dev/null
+++ b/web/client/src/sections/issueHandle/style.less
@@ -0,0 +1,13 @@
+.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;
+}
\ No newline at end of file