52 changed files with 1122 additions and 266 deletions
			
			
		@ -0,0 +1,64 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					async function varfiyCode(ctx) { | 
				
			||||
 | 
					    try { | 
				
			||||
 | 
					        const { models } = ctx.fs.dc; | 
				
			||||
 | 
					        const { pushBySms, pushByEmail } = ctx.app.fs.utils | 
				
			||||
 | 
					        const { phone, type ,email} = ctx.request.body | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        // 伪造的请求可能由相同的sig参数组成
 | 
				
			||||
 | 
					        // const checkSigUsed = await models.PhoneValidateCode.findOne({
 | 
				
			||||
 | 
					        //     where: { sig: sig }
 | 
				
			||||
 | 
					        // });
 | 
				
			||||
 | 
					        // if (checkSigUsed) {
 | 
				
			||||
 | 
					        //     throw '参数错误!'
 | 
				
			||||
 | 
					        // }
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        // // 验证sig正确性            
 | 
				
			||||
 | 
					        // const checkSig = Hex.stringify(SHA1(phone + r));
 | 
				
			||||
 | 
					        // if (!r || !sig || sig != checkSig) {
 | 
				
			||||
 | 
					        //     throw '参数错误!'
 | 
				
			||||
 | 
					        // }
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        let varifyCode = '' | 
				
			||||
 | 
					        for (let i = 0; i < 6; i++) { | 
				
			||||
 | 
					            varifyCode += Math.floor(Math.random() * 10) | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					       if(type.includes(1)){ | 
				
			||||
 | 
					        await pushBySms({ | 
				
			||||
 | 
					            phone: phone, | 
				
			||||
 | 
					            templateCode: 'SMS_261950020', | 
				
			||||
 | 
					            templateParam: { | 
				
			||||
 | 
					                code: varifyCode | 
				
			||||
 | 
					            }, | 
				
			||||
 | 
					        }) | 
				
			||||
 | 
					       } | 
				
			||||
 | 
					       if(type.includes(2)){ | 
				
			||||
 | 
					        await pushByEmail({ | 
				
			||||
 | 
					            email: email, | 
				
			||||
 | 
					            title: '测试', | 
				
			||||
 | 
					            text:'你知道吗' | 
				
			||||
 | 
					        }) | 
				
			||||
 | 
					       } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        // await models.PhoneValidateCode.create({
 | 
				
			||||
 | 
					        //     phone: phone,
 | 
				
			||||
 | 
					        //     code: varifyCode,
 | 
				
			||||
 | 
					        //     sig: sig,
 | 
				
			||||
 | 
					        //     expired: moment().add(10, 'minutes').format('YYYY-MM-DD HH:mm:ss')
 | 
				
			||||
 | 
					        // })
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        ctx.status = 204; | 
				
			||||
 | 
					    } catch (error) { | 
				
			||||
 | 
					        ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); | 
				
			||||
 | 
					        ctx.status = 400; | 
				
			||||
 | 
					        ctx.body = { | 
				
			||||
 | 
					            message: typeof error == 'string' ? error : '获取验证码失败' | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					 module.exports = { | 
				
			||||
 | 
					    varfiyCode, | 
				
			||||
 | 
					    // pushByEmail
 | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,11 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					const yujingguanli = require('../../controllers/patrolManage/yujingguanli'); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					module.exports = function (app, router, opts) { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    app.fs.api.logAttr['POST/yujingguanli'] = { content: '下发预警邮件', visible: true }; | 
				
			||||
 | 
					    router.post('/yujingguanli', yujingguanli.varfiyCode); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					}; | 
				
			||||
@ -0,0 +1,2 @@ | 
				
			|||||
 | 
					DELETE FROM public.resource WHERE code = 'REPAIR_MANAGE'; | 
				
			||||
 | 
					DELETE FROM public.resource WHERE parent_resource = 'REPAIR_MANAGE'; | 
				
			||||
@ -0,0 +1,5 @@ | 
				
			|||||
 | 
					ALTER TABLE patrol_record_issue_handle ADD yanshoushijian timestamp(6); | 
				
			||||
 | 
					ALTER TABLE patrol_record_issue_handle ADD yanshoucishu integer; | 
				
			||||
 | 
					ALTER TABLE patrol_record_issue_handle ADD yujingshijian timestamp(6); | 
				
			||||
 | 
					ALTER TABLE patrol_record_issue_handle ADD yujingafchishu integer; | 
				
			||||
 | 
					ALTER TABLE patrol_record_issue_handle ADD isgaojing bool; | 
				
			||||
@ -0,0 +1,4 @@ | 
				
			|||||
 | 
					ALTER TABLE "public"."patrol_record"  | 
				
			||||
 | 
					  ADD COLUMN "project_id" int4; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					COMMENT ON COLUMN "public"."patrol_record"."project_id" IS '结构物id'; | 
				
			||||
@ -0,0 +1,4 @@ | 
				
			|||||
 | 
					ALTER TABLE "public"."patrol_record_issue_handle"  | 
				
			||||
 | 
					  ADD COLUMN "cost" decimal(11,2); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					COMMENT ON COLUMN "public"."patrol_record_issue_handle"."cost" IS '成本'; | 
				
			||||
| 
		 After Width: | Height: | Size: 293 B  | 
| 
		 After Width: | Height: | Size: 1.4 KiB  | 
@ -0,0 +1,66 @@ | 
				
			|||||
 | 
					// package/pointsStatus/pointsStatus.js
 | 
				
			||||
 | 
					Page({ | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  /** | 
				
			||||
 | 
					   * 页面的初始数据 | 
				
			||||
 | 
					   */ | 
				
			||||
 | 
					  data: { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  }, | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  /** | 
				
			||||
 | 
					   * 生命周期函数--监听页面加载 | 
				
			||||
 | 
					   */ | 
				
			||||
 | 
					  onLoad(options) { | 
				
			||||
 | 
					    console.log(options, 'options') | 
				
			||||
 | 
					  }, | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  /** | 
				
			||||
 | 
					   * 生命周期函数--监听页面初次渲染完成 | 
				
			||||
 | 
					   */ | 
				
			||||
 | 
					  onReady() { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  }, | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  /** | 
				
			||||
 | 
					   * 生命周期函数--监听页面显示 | 
				
			||||
 | 
					   */ | 
				
			||||
 | 
					  onShow() { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  }, | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  /** | 
				
			||||
 | 
					   * 生命周期函数--监听页面隐藏 | 
				
			||||
 | 
					   */ | 
				
			||||
 | 
					  onHide() { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  }, | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  /** | 
				
			||||
 | 
					   * 生命周期函数--监听页面卸载 | 
				
			||||
 | 
					   */ | 
				
			||||
 | 
					  onUnload() { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  }, | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  /** | 
				
			||||
 | 
					   * 页面相关事件处理函数--监听用户下拉动作 | 
				
			||||
 | 
					   */ | 
				
			||||
 | 
					  onPullDownRefresh() { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  }, | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  /** | 
				
			||||
 | 
					   * 页面上拉触底事件的处理函数 | 
				
			||||
 | 
					   */ | 
				
			||||
 | 
					  onReachBottom() { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  }, | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  /** | 
				
			||||
 | 
					   * 用户点击右上角分享 | 
				
			||||
 | 
					   */ | 
				
			||||
 | 
					  onShareAppMessage() { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  } | 
				
			||||
 | 
					}) | 
				
			||||
@ -0,0 +1,3 @@ | 
				
			|||||
 | 
					{ | 
				
			||||
 | 
					  "usingComponents": {} | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,2 @@ | 
				
			|||||
 | 
					<!--package/pointsStatus/pointsStatus.wxml--> | 
				
			||||
 | 
					<text>package/pointsStatus/pointsStatus.wxml</text> | 
				
			||||
@ -0,0 +1 @@ | 
				
			|||||
 | 
					/* package/pointsStatus/pointsStatus.wxss */ | 
				
			||||
@ -1,32 +1,14 @@ | 
				
			|||||
<!--pages/index/index.wxml--> | 
					<!--pages/index/index.wxml--> | 
				
			||||
<view> | 
					<map  | 
				
			||||
  <view class="searchFixed"> | 
					  id="mapDom" | 
				
			||||
    <view class="searchBoxs"> | 
					  class="map" | 
				
			||||
      <input class="searchInps" bindinput="formInp" bindconfirm="bindconfirm" value='{{keyName}}' type="text" placeholder="请输入结构物名称" /> | 
					  markers="{{markers}}" | 
				
			||||
      <button class="btnSearch" bindtap="goSearch">搜索</button> | 
					  bindmarkertap="onMarkerTap" | 
				
			||||
    </view> | 
					> | 
				
			||||
  </view> | 
					  <view class="action-box"> | 
				
			||||
 | 
					    <view class="text flex-center" bind:tap="showCallout">数据</view> | 
				
			||||
  <view style="margin-top: 140rpx;"> | 
					    <view class="img flex-center" bind:tap="onRefresh"> | 
				
			||||
    <block wx:for="{{dataList}}" wx:key='*this'> | 
					      <image src="/images/refresh.svg"></image> | 
				
			||||
      <view style="padding-bottom: 60rpx;"> | 
					    </view> | 
				
			||||
        <image wx:if="{{item.img != null && item.img.length > 0}}" style="width: 100%;height: 372rpx;display: block;" src="{{imgUrl + item.img[0]}}"></image> | 
					  </view> | 
				
			||||
        <view wx:if="{{item.img == null || item.img.length == 0}}" style="width: 100%;height: 372rpx;line-height: 372rpx;text-align: center;background: #fff;border-bottom: 2rpx solid #ccc;">暂无图片</view> | 
					</map> | 
				
			||||
        <view class="box"> | 
					 | 
				
			||||
          <view style="font-weight:bold;font-size:32rpx;">{{item.name}}</view> | 
					 | 
				
			||||
          <view style="font-size:28rpx;color: rgb(166,166,166);"> | 
					 | 
				
			||||
            <view style=" margin-top:6rpx;">今日问题:<text>12</text></view> | 
					 | 
				
			||||
            <view style="float:left;width:360rpx;">未处理问题:<text>12</text></view> | 
					 | 
				
			||||
            <view style="float:left;width:350rpx;">已处理问题:<text>12</text></view> | 
					 | 
				
			||||
          </view> | 
					 | 
				
			||||
        </view> | 
					 | 
				
			||||
      </view> | 
					 | 
				
			||||
    </block> | 
					 | 
				
			||||
  </view> | 
					 | 
				
			||||
 | 
					 | 
				
			||||
  <!-- 暂无数据 --> | 
					 | 
				
			||||
  <view hidden="{{hidden}}"> | 
					 | 
				
			||||
    <image class="noData" src="../../images/noData.png"></image> | 
					 | 
				
			||||
    <view class="noTxt">暂无数据~</view> | 
					 | 
				
			||||
  </view> | 
					 | 
				
			||||
</view> | 
					 | 
				
			||||
 | 
				
			|||||
@ -1,70 +1,36 @@ | 
				
			|||||
/* pages/index/index.wxss */ | 
					/* pages/index/index.wxss */ | 
				
			||||
page { | 
					.flex-center { | 
				
			||||
  background: #F7F7FA; | 
					    display: flex; | 
				
			||||
 | 
					    justify-content: center; | 
				
			||||
 | 
					    align-items: center; | 
				
			||||
} | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
.searchBoxs { | 
					.map { | 
				
			||||
  position: relative; | 
					    width: 100vw; | 
				
			||||
  margin: 20rpx 0rpx; | 
					    height: 100vh; | 
				
			||||
  height: 76rpx; | 
					 | 
				
			||||
} | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
.searchInps { | 
					.action-box { | 
				
			||||
  background-color: #fff; | 
					 | 
				
			||||
  width: 542rpx; | 
					 | 
				
			||||
  height: 76rpx; | 
					 | 
				
			||||
  border-radius: 8rpx; | 
					 | 
				
			||||
  padding-left: 32rpx; | 
					 | 
				
			||||
  padding-right: 144rpx; | 
					 | 
				
			||||
  border: 1px solid rgba(225, 225, 225, 0.44); | 
					 | 
				
			||||
    position: absolute; | 
					    position: absolute; | 
				
			||||
  top: -2rpx; | 
					    bottom: 30px; | 
				
			||||
  left: 16rpx; | 
					    right: 10px; | 
				
			||||
  font-size: 28rpx; | 
					    width: 46px; | 
				
			||||
 | 
					    height: 80px; | 
				
			||||
 | 
					    display: flex; | 
				
			||||
 | 
					    flex-direction: column; | 
				
			||||
 | 
					    justify-content: space-evenly; | 
				
			||||
} | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
.btnSearch { | 
					.action-box .text { | 
				
			||||
  width: 128rpx; | 
					    background-color: white; | 
				
			||||
  height: 68rpx; | 
					    height: 30px; | 
				
			||||
  line-height: 68rpx; | 
					 | 
				
			||||
  border-radius: 8rpx; | 
					 | 
				
			||||
  color: #fff; | 
					 | 
				
			||||
  font-size: 28rpx; | 
					 | 
				
			||||
  background: linear-gradient(180deg, #1979ff 0%, #1979ff 100%); | 
					 | 
				
			||||
  position: absolute; | 
					 | 
				
			||||
  top: 6rpx; | 
					 | 
				
			||||
  right: 28rpx; | 
					 | 
				
			||||
  z-index: 10; | 
					 | 
				
			||||
} | 
					 | 
				
			||||
 | 
					 | 
				
			||||
.searchFixed { | 
					 | 
				
			||||
  position: fixed; | 
					 | 
				
			||||
  top: 0; | 
					 | 
				
			||||
  width: 100%; | 
					 | 
				
			||||
  background-color: #fff; | 
					 | 
				
			||||
  box-shadow: 0rpx -4rpx 20rpx #c2c2c2; | 
					 | 
				
			||||
  z-index: 10; | 
					 | 
				
			||||
} | 
					 | 
				
			||||
 | 
					 | 
				
			||||
.box { | 
					 | 
				
			||||
  padding: 20rpx; | 
					 | 
				
			||||
  box-shadow: 0rpx 10rpx 10rpx #ccc; | 
					 | 
				
			||||
  overflow: hidden; | 
					 | 
				
			||||
  line-height: 50rpx; | 
					 | 
				
			||||
  background: #fff; | 
					 | 
				
			||||
} | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
/* 暂无数据 */ | 
					.action-box .img { | 
				
			||||
.noData { | 
					    background-color: white; | 
				
			||||
  width: 254rpx; | 
					 | 
				
			||||
  height: 298rpx; | 
					 | 
				
			||||
  display: block; | 
					 | 
				
			||||
  margin: 450rpx auto 16rpx; | 
					 | 
				
			||||
} | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
.noTxt { | 
					.action-box .img image { | 
				
			||||
  font-size: 30rpx; | 
					    width: 30px; | 
				
			||||
  color: #999; | 
					    height: 30px; | 
				
			||||
  font-weight: bold; | 
					 | 
				
			||||
  text-align: center; | 
					 | 
				
			||||
} | 
					} | 
				
			||||
@ -0,0 +1,13 @@ | 
				
			|||||
 | 
					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: '发送信息' }, | 
				
			||||
 | 
					    }); | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,78 @@ | 
				
			|||||
 | 
					import { Button, Form, Input, Modal, Select, DatePicker,Checkbox } from 'antd'; | 
				
			||||
 | 
					import React, { useState, useEffect } from 'react'; | 
				
			||||
 | 
					import { connect } from 'react-redux'; | 
				
			||||
 | 
					import { createPatrolTemplate, delPatrolTemplate, updatePatrolTemplate, getPatrolTemplate } from '../actions/template'; | 
				
			||||
 | 
					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 }) => { | 
				
			||||
 | 
					    const [form] = Form.useForm(); | 
				
			||||
 | 
					    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})).then(res=>{ | 
				
			||||
 | 
					                            console.log(res,'res') | 
				
			||||
 | 
					                        }) | 
				
			||||
 | 
					                     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 } = state | 
				
			||||
 | 
					    return { | 
				
			||||
 | 
					        user: auth.user, | 
				
			||||
 | 
					        checkItemsGroup: checkItemsGroup.data || [] | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					export default connect(mapStateToProps)(PlanModal); | 
				
			||||
@ -0,0 +1,217 @@ | 
				
			|||||
 | 
					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 [visible, setVisible] = useState(false); | 
				
			||||
 | 
					    const [type, setType] = useState(); | 
				
			||||
 | 
					    const [curRecord, setCurRecord] = useState(); | 
				
			||||
 | 
					    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) => { | 
				
			||||
 | 
					        console.log(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,'水平') | 
				
			||||
 | 
					                            let obj = {} | 
				
			||||
 | 
					            // 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(patrolManage.records(`patrolRecord/all/null/null/true/null`)).then(res=>{
 | 
				
			||||
 | 
					        //     let obj = {}
 | 
				
			||||
 | 
					        //     res?.payload?.data?.map(i=>{
 | 
				
			||||
 | 
					        //         if(obj[i?.points?.project?.id]){
 | 
				
			||||
 | 
					        //             obj[i?.points?.project?.id].name=i?.points?.project?.name;
 | 
				
			||||
 | 
					        //             obj[i?.points?.project?.id].num=obj[i?.points?.project?.id].num +1
 | 
				
			||||
 | 
					        //         }else{
 | 
				
			||||
 | 
					        //             obj[i?.points?.project?.id]={name:i?.points?.project?.name,num:1}
 | 
				
			||||
 | 
					                    | 
				
			||||
 | 
					        //         }
 | 
				
			||||
 | 
					        //     })
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        //     settableList(name != null ? res.payload.data?.filter(v =>
 | 
				
			||||
 | 
					        //         (v.points.user.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 t1 = Object.keys(obj).map(i=>{
 | 
				
			||||
 | 
					        //         return {id:i,name:obj[i].name,num:obj[i].num}
 | 
				
			||||
 | 
					        //     })
 | 
				
			||||
 | 
					        //     console.log(obj,'obj')
 | 
				
			||||
 | 
					        //     console.log(res,'res')
 | 
				
			||||
 | 
					        // })
 | 
				
			||||
 | 
					        dispatch(getDepUser()) | 
				
			||||
 | 
					        queryData() | 
				
			||||
 | 
					        dispatch(getCheckItemsGroup()) | 
				
			||||
 | 
					    }, []) | 
				
			||||
 | 
					console.log(tableList,'tablist') | 
				
			||||
 | 
					    const columns = [{ | 
				
			||||
 | 
					        title: '结构物名称', | 
				
			||||
 | 
					        dataIndex: 'name', | 
				
			||||
 | 
					        key: 'name', | 
				
			||||
 | 
					        // search: false,
 | 
				
			||||
 | 
					        ellipsis: true, | 
				
			||||
 | 
					    }, { | 
				
			||||
 | 
					        title: '点位名称', | 
				
			||||
 | 
					        dataIndex: 'describe', | 
				
			||||
 | 
					        key: 'describe', | 
				
			||||
 | 
					        search: false, | 
				
			||||
 | 
					        ellipsis: true | 
				
			||||
 | 
					    }, { | 
				
			||||
 | 
					        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: 'checkItems', | 
				
			||||
 | 
					        key: 'checkItems', | 
				
			||||
 | 
					        search: false, | 
				
			||||
 | 
					        ellipsis: true, | 
				
			||||
 | 
					        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> | 
				
			||||
 | 
					                 | 
				
			||||
 | 
					            </> | 
				
			||||
 | 
					        }, | 
				
			||||
 | 
					    }]; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    return ( | 
				
			||||
 | 
					        <> | 
				
			||||
 | 
					          <Tabs | 
				
			||||
 | 
					        defaultActiveKey="1" | 
				
			||||
 | 
					        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 = {}) => { | 
				
			||||
 | 
					            const res = await dispatch(getPatrolTemplate(params)); | 
				
			||||
 | 
					            setDataSource(res?.payload.data?.rows); | 
				
			||||
 | 
					            return { ...res }; | 
				
			||||
 | 
					        }} | 
				
			||||
 | 
					         | 
				
			||||
 | 
					        // toolBarRender={() => [
 | 
				
			||||
 | 
					        //     <Button
 | 
				
			||||
 | 
					        //         type="primary"
 | 
				
			||||
 | 
					        //         key="primary"
 | 
				
			||||
 | 
					        //         onClick={() => {
 | 
				
			||||
 | 
					        //             setType('create')
 | 
				
			||||
 | 
					        //             setVisible(true)
 | 
				
			||||
 | 
					        //         }}
 | 
				
			||||
 | 
					        //     >查询</Button>
 | 
				
			||||
 | 
					        // ]}
 | 
				
			||||
 | 
					    />, | 
				
			||||
 | 
					         }, | 
				
			||||
 | 
					        { | 
				
			||||
 | 
					        label: `已告警`, | 
				
			||||
 | 
					        key: '2', | 
				
			||||
 | 
					        children: `Content of Tab Pane 2`, | 
				
			||||
 | 
					         } | 
				
			||||
 | 
					    ]} | 
				
			||||
 | 
					  /> | 
				
			||||
 | 
					  { | 
				
			||||
 | 
					                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({}) | 
				
			||||
 | 
					                        }} | 
				
			||||
 | 
					                        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); | 
				
			||||
@ -0,0 +1,9 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default { | 
				
			||||
 | 
					    | 
				
			||||
 | 
					   | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,9 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import Shouye from './shouye' | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export {  Shouye }; | 
				
			||||
@ -0,0 +1,62 @@ | 
				
			|||||
 | 
					import React, { useEffect, useState } from 'react'; | 
				
			||||
 | 
					import { connect } from 'react-redux'; | 
				
			||||
 | 
					import { Spin, Card, Form, Input, Select, Button, Table, Modal, Popconfirm, Tooltip } from 'antd'; | 
				
			||||
 | 
					import moment from "moment"; | 
				
			||||
 | 
					import '../style.less'; | 
				
			||||
 | 
					import { push } from 'react-router-redux'; | 
				
			||||
 | 
					import { Model } from 'echarts'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					const Information = (props) => { | 
				
			||||
 | 
					   const { dispatch, actions, user, loading } = props | 
				
			||||
 | 
					   const topdata =[] | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					   return ( | 
				
			||||
 | 
					      <> | 
				
			||||
 | 
					      <div className='shouyetop'> | 
				
			||||
 | 
					         <div className='shouyetopitem'> | 
				
			||||
 | 
					            <div className='shouyetopitem-left' > | 
				
			||||
 | 
					               <div>今日巡检</div> | 
				
			||||
 | 
					               <div>0</div> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					            <div className='shouyetopitem-right'> | 
				
			||||
 | 
					               <div>完成巡检:2个</div> | 
				
			||||
 | 
					               <div>巡检上报:2个</div> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					         </div> | 
				
			||||
 | 
					         <div className='shouyetopitem'> | 
				
			||||
 | 
					            <div className='shouyetopitem-left' > | 
				
			||||
 | 
					               <div>今日巡检</div> | 
				
			||||
 | 
					               <div>0</div> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					            <div className='shouyetopitem-right'> | 
				
			||||
 | 
					               <div>完成巡检:2个</div> | 
				
			||||
 | 
					               <div>巡检上报:2个</div> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					         </div> | 
				
			||||
 | 
					         <div className='shouyetopitem'> | 
				
			||||
 | 
					            <div className='shouyetopitem-left' > | 
				
			||||
 | 
					               <div>今日巡检</div> | 
				
			||||
 | 
					               <div>0</div> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					            <div className='shouyetopitem-right'> | 
				
			||||
 | 
					               <div>完成巡检:2个</div> | 
				
			||||
 | 
					               <div>巡检上报:2个</div> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					         </div> | 
				
			||||
 | 
					      </div> | 
				
			||||
 | 
					      </> | 
				
			||||
 | 
					   ) | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					function mapStateToProps (state) { | 
				
			||||
 | 
					   const { auth, global } = state; | 
				
			||||
 | 
					   return { | 
				
			||||
 | 
					      user: auth.user, | 
				
			||||
 | 
					      actions: global.actions, | 
				
			||||
 | 
					   }; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default connect(mapStateToProps)(Information); | 
				
			||||
@ -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: 'shouye', | 
				
			||||
 | 
					    name: '首页', | 
				
			||||
 | 
					    reducers: reducers, | 
				
			||||
 | 
					    routes: routes, | 
				
			||||
 | 
					    actions: actions, | 
				
			||||
 | 
					    getNavItem: getNavItem | 
				
			||||
 | 
					}; | 
				
			||||
@ -0,0 +1,21 @@ | 
				
			|||||
 | 
					import React from 'react'; | 
				
			||||
 | 
					import { Link } from 'react-router-dom'; | 
				
			||||
 | 
					import { Menu } from 'antd'; | 
				
			||||
 | 
					import { SettingOutlined } from '@ant-design/icons'; | 
				
			||||
 | 
					import { Func } from '$utils'; | 
				
			||||
 | 
					const SubMenu = Menu.SubMenu; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export function getNavItem (user, dispatch) { | 
				
			||||
 | 
					   // return <SubMenu key="shouye" icon={<SettingOutlined />} title={'首页'}>
 | 
				
			||||
 | 
					   //    {/* {Func.isAuthorized('STRU_INFO_CONFIG') &&<Menu.Item key="information">
 | 
				
			||||
 | 
					   //       <Link to="/projectRegime/information">结构物基础信息管理</Link>
 | 
				
			||||
 | 
					   //    </Menu.Item>}
 | 
				
			||||
 | 
					   //    {Func.isAuthorized('QR_CODE_CONFIG') &&<Menu.Item key="qrCode">
 | 
				
			||||
 | 
					   //       <Link to="/projectRegime/qrCode">二维码管理</Link>
 | 
				
			||||
 | 
					   //    </Menu.Item>} */}
 | 
				
			||||
 | 
					   // </SubMenu>
 | 
				
			||||
 | 
					   return <Menu.Item key="shouye"> | 
				
			||||
 | 
					             <Link to="/shouye">首页</Link> | 
				
			||||
 | 
					         </Menu.Item> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,5 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,32 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					import { Shouye } from './containers'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default [{ | 
				
			||||
 | 
					   type: 'inner', | 
				
			||||
 | 
					   route: { | 
				
			||||
 | 
					      path: '/shouye', | 
				
			||||
 | 
					      key: 'shouye', | 
				
			||||
 | 
					      breadcrumb: '首页', | 
				
			||||
 | 
					      component: Shouye, | 
				
			||||
 | 
					      // 不设置 component 则面包屑禁止跳转
 | 
				
			||||
 | 
					      // childRoutes: [{
 | 
				
			||||
 | 
					      //    path: '/information',
 | 
				
			||||
 | 
					      //    key: 'information',
 | 
				
			||||
 | 
					      //    breadcrumb: '结构物基础信息管理',
 | 
				
			||||
 | 
					      //    component: Information,
 | 
				
			||||
 | 
					      //    childRoutes: [ {
 | 
				
			||||
 | 
					      //          path: '/:id',
 | 
				
			||||
 | 
					      //          key: ':id',
 | 
				
			||||
 | 
					      //          component: Point,
 | 
				
			||||
 | 
					      //          breadcrumb: '点位',
 | 
				
			||||
 | 
					      //       },
 | 
				
			||||
 | 
					      //    ]
 | 
				
			||||
 | 
					      // }, {
 | 
				
			||||
 | 
					      //    path: '/qrCode',
 | 
				
			||||
 | 
					      //    key: 'qrCode',
 | 
				
			||||
 | 
					      //    component: QrCode,
 | 
				
			||||
 | 
					      //    breadcrumb: '二维码管理',
 | 
				
			||||
 | 
					      // },
 | 
				
			||||
 | 
					      // ]
 | 
				
			||||
 | 
					   } | 
				
			||||
 | 
					}]; | 
				
			||||
@ -0,0 +1,20 @@ | 
				
			|||||
 | 
					.shouyetop{ | 
				
			||||
 | 
					    display: flex; | 
				
			||||
 | 
					    justify-content: space-between; | 
				
			||||
 | 
					    .shouyetopitem{ | 
				
			||||
 | 
					        width: 25%; | 
				
			||||
 | 
					        display: flex; | 
				
			||||
 | 
					        justify-content: space-between; | 
				
			||||
 | 
					        box-shadow: 0 0 10px #F0F2F5; | 
				
			||||
 | 
					            border:1px solid #F0F2F5; | 
				
			||||
 | 
					            color: rgba(0, 0, 0, 0.45); | 
				
			||||
 | 
					            font-size: 1.875rem; | 
				
			||||
 | 
					            height: 7.125rem; | 
				
			||||
 | 
					        .shouyetopitem-left{ | 
				
			||||
 | 
					            width: 50%; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        .shouyetopitem-right{ | 
				
			||||
 | 
					            width: 50%; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
					Loading…
					
					
				
		Reference in new issue