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

1584 lines
56 KiB

import React, { useState, useEffect } from 'react';
import Taro, { useRouter } from '@tarojs/taro';
import { View, RadioGroup, Radio, Image, Input, Picker, Video, Text, CheckboxGroup, Checkbox, Textarea } from '@tarojs/components';
import { AtButton, AtTextarea, AtImagePicker, AtMessage, AtIcon } from 'taro-ui';
import InputPicker from '../components/inputPicker';
import InputPickers from '../components/inputPickers';
import VideoUpload from '../../components/uploads'
import request from '@/services/request';
import environment from '../../config';
import { getState } from '../../store/globalState';
import { postReport, getReportList, getReportDetail, delReport, getRoadSection, postImage, getProject, postHandle, getAllDepUsers, getUsers } from '@/services/api';
import './index.scss';
import arrowIcon from '../../static/img/patrol/arrow-down.svg';
import dayjs from 'dayjs';
const { baseUrl, imgUrl } = environment;
const Index = () => {
const userInfo = Taro.getStorageSync('userInfo') || {};
const isSuperAdmin = userInfo && userInfo.username === 'SuperAdmin' ? true : false
const router = useRouter()
const { params: { type, kind, wait, handle, videoShow } } = router
const isView = type === 'view' ? true : false
const isPatrol = kind === 'patrol' || kind == 'conserve' ? true : false
const isRoad = kind === 'road' ? true : false
const isAnomaly = kind === 'anomaly' ? true : false
const noDel = wait === 'wait' || handle === 'handle'
const [reportType, setReportType] = useState(kind || 'patrol') // 上报类型
const [projectType, setProjectType] = useState('') // 工程类型
const [projectName, setProjectName] = useState('') // 项目名称
const [road, setRoad] = useState('') // 所在道路
const [roadSectionStart, setRoadSectionStart] = useState('') // 路段 Start
const [roadSectionEnd, setRoadSectionEnd] = useState('') // 路段 End
const [address, setAddress] = useState('') // 具体位置
const [content, setContent] = useState('') // 巡查内容
const [scenePic, setScenePic] = useState([]) // 现场图片
const [conserveBeforePic, setConserveBeforePic] = useState([]) // 养护前图片
const [conserveUnderwayPic, setConserveUnderwayPic] = useState([]) // 养护中图片
const [conserveAfterPic, setConserveAfterPic] = useState([]) // 养护后图片
const [longitude, setLongitude] = useState(0) // 经度
const [latitude, setLatitude] = useState(0) // 纬度
const [sceneImg, setSceneImg] = useState([]) // 现场图片七牛云url
const [conserveBeforeImg, setConserveBeforeImg] = useState([]) // 养护前图片
const [conserveUnderwayImg, setConserveUnderwayImg] = useState([]) // 养护中图片
const [conserveAfterImg, setConserveAfterImg] = useState([]) // 养护后图片
const [sourceRoadStartSel, setSourceRoadStartSel] = useState([])
const [sourceRoadEndSel, setSourceRoadEndSel] = useState([])
const [codeRoadSel, setCodeRoadSel] = useState([])
const [roadList, setRoadList] = useState([])
const [codeRoad, setCodeRoad] = useState('')
const [projectList, setProjdetList] = useState([])
const [handleCenter, setHandleCenter] = useState('')
const [handlePic, setHandlePic] = useState([])
const [handlePicPn, setHandlePicPn] = useState([])
const [handleId, setHandleId] = useState([])
const [video, setVideo] = useState('')
const [videoqn, setVideoqn] = useState([])
const [handleState, setHandleState] = useState('')
const [roadCodeHead, setRoadCodeHead] = useState('X')
const [roadCodeEnd, setRoadCodeEnd] = useState('')
const [patrolContentEdit, setPatrolContentEdit] = useState(true) // 养护基本信息是否可编辑
const [patrolContent, setPatrolContent] = useState({
inspectionNoException: {
label: '巡查结果无异常',
selected: false,
value: '',
},
roadDamage: {
label: '路面损坏',
selected: false,
value: '',
},
securityDamage: {
label: '安防损坏',
selected: false,
value: '',
},
bridgeDamage: {
label: '桥梁损坏',
selected: false,
value: '',
},
culvertDamage: {
label: '涵洞损坏',
selected: false,
value: '',
},
securityDeficiency: {
label: '安防缺失',
selected: false,
value: '',
},
encounteredEnvironment: {
label: '路域环境',
selected: false,
value: '',
},
otherDescription: {
label: '其他',
selected: false,
value: '',
},
})
const [conserveInfo, setConserveInfo] = useState({
roadType: {
label: '路面类型',
value: '',
unit: '',
},
roadWidth: {
label: '路面宽度',
value: '',
unit: '米',
},
wrongLane: {
label: '错车道',
value: '',
unit: '个',
},
roadsideTrees: {
label: '行道树',
value: '',
unit: '棵',
},
roadsideDitch: {
label: '边沟',
value: '',
unit: '米',
},
guardrail: {
label: '护栏',
value: '',
unit: '米',
},
roadMarking: {
label: '标线',
value: '',
unit: '米',
},
})
const [conserveContent, setConserveContent] = useState({
maintenanceStaffCount: {
label: '本次养护共安排养护人员',
value: '',
unit: '人',
},
shoulderRepair: {
label: '整修路肩、边坡',
value: '',
unit: '平米',
},
ditchCleaning: {
label: '开挖、清理边沟',
value: '',
unit: '米',
},
asphaltRepair: {
label: '修补沥青路面',
value: '',
unit: '平米',
},
concreteRepair: {
label: '修补水泥路面',
value: '',
unit: '平米',
},
grassMowing: {
label: '除草',
value: '',
unit: '米',
},
treeWhitening: {
label: '行道树刷白',
value: '',
unit: '株/公里',
},
pileWhitening: {
label: '公里桩/百米桩刷漆',
value: '',
unit: '个',
},
guardrailMaintenance: {
label: '维修护栏',
value: '',
unit: '米',
},
endHeadRepair: {
label: '修复端头',
value: '',
unit: '块',
},
})
const [otherDescription, setOtherDescription] = useState('') // 其他养护内容
const [isBeforeReport, setIsBeforeReport] = useState(false) // V1.1.0上报内容修改,查看时根据时间判断展示逻辑)
const [isAppoint, setIsAppoint] = useState(true) // 指派 / 不处理
const [allDepUsers, setAllDepUsers] = useState([]) // 所有部门用户列表
const [userList, setUserList] = useState([]) // 所有用户列表
const [appointUser, setAppointUser] = useState(null) // 责任人在userList的index
const [handleAdvice, setHandleAdvice] = useState('') // 处理意见
const [routeNameList, setRouteNameList] = useState([]);
const [routeCodeList, setRouteCodeList] = useState([]);
const [sectionNoList, setSectionNoList] = useState([]);
const [roadChecked, setRoadChecked] = useState({
routeName: '',
routeCode: '',
sectionNo: '',
startingPlaceName: '',
stopPlaceName: '',
})
const [routeCodeDisabled, setRouteCodeDisabled] = useState(true);
const [sectionNoDisabled, setSectionNoDisabled] = useState(true);
const prjType =
isAnomaly ?
[
{ text: '养护', value: 'conserve' },
{ text: '巡查', value: 'patrol' },
{ text: '在建', value: 'construction' },
]
:
[
{ text: '无', value: '' },
{ text: '道路', value: 'road', onlyView: true },
{ text: '县道', value: 'countyRoad', onlyView: true },
{ text: '乡道', value: 'villageRoad', onlyView: true },
{ text: '村道', value: 'rusticRoad', onlyView: true },
{ text: '桥梁', value: 'bridge' },
{ text: '涵洞', value: 'culvert' },
{ text: '其他', value: 'other' },
]
const prjTypeSelector = prjType.map(item => {
return item.onlyView ? '' : item.text
}).filter(item => item)
// [
// // '道路',
// '县道', '乡道', '村道',
// '桥梁', '涵洞', '其他'
// ]
const [roadStartSel, setRoadStartSel] = useState([])
const [roadEndSel, setRoadEndSel] = useState([])
const [canReport, setCanReport] = useState(true)
useEffect(() => {
if (isRoad) {
Taro.setNavigationBarTitle({ title: '在建项目' })
} else if (wait == 'wait') {
Taro.setNavigationBarTitle({ title: '待办事项' })
} else if (handle == 'handle') {
Taro.setNavigationBarTitle({ title: '已办事项' })
} else if (isAnomaly) {
Taro.setNavigationBarTitle({ title: '异常反馈' })
} else if (kind == 'conserve') {
Taro.setNavigationBarTitle({ title: '养护上报' })
} else {
Taro.setNavigationBarTitle({ title: '巡查上报' })
}
if (isView) { // 查看
Taro.showLoading({ title: '加载中' })
request.get(getReportDetail(router.params.id)).then(res => {
Taro.hideLoading()
if (res.statusCode == 200 || res.statusCode == 204) {
const { data } = res
let showPrjType = ''
for (const item of prjType) {
if (item.value === data.projectType) {
showPrjType = item.text
break
}
}
setReportType(data.reportType)
setProjectType(showPrjType || data.projectType)
setProjectName(data.projectName)
setRoad(data.road)
setCodeRoad(data.codeRoad)
setRoadSectionStart(data.roadSectionStart)
setRoadSectionEnd(data.roadSectionEnd)
setAddress(data.address)
setContent(data.content)
setHandleState(data.handleState)
setScenePic(data.scenePic ? data.scenePic.map(item => ({ url: imgUrl + item })) : [])
setHandlePic(data.handlePic ? data.handlePic.map(item => ({ url: imgUrl + item })) : [])
setConserveBeforePic(data.conserveBeforePic ? data.conserveBeforePic.map(item => ({ url: imgUrl + item })) : [])
setConserveUnderwayPic(data.conserveUnderwayPic ? data.conserveUnderwayPic.map(item => ({ url: imgUrl + item })) : [])
setConserveAfterPic(data.conserveAfterPic ? data.conserveAfterPic.map(item => ({ url: imgUrl + item })) : [])
setHandleId(data.id)
setVideo((data.videoUrl && data.videoUrl[0]) ? imgUrl + data.videoUrl[0] : '')
setRoadCodeHead(data.codeRoad ? data.codeRoad.slice(0, 1) : '')
setRoadCodeEnd(data.codeRoad ? data.codeRoad.slice(1) : '')
if (data.reportType === 'patrol') {
let next = { ...patrolContent }
next.inspectionNoException.selected = data.inspectionNoException
Object.keys(patrolContent).forEach(key => {
if (data[key]) {
next[key].selected = true
next[key].value = data[key]
}
})
setPatrolContent(next)
} else if (data.reportType === 'conserve') {
let nextInfo = { ...conserveInfo }
Object.keys(conserveInfo).forEach(key => {
if (data[key]) nextInfo[key].value = data[key]
})
setConserveInfo(nextInfo)
let nextContent = { ...conserveContent }
Object.keys(conserveContent).forEach(key => {
if (data[key]) nextContent[key].value = data[key]
})
setConserveContent(nextContent)
setOtherDescription(data.otherDescription)
} else if (data.reportType === 'anomaly') {
setAppointUser(data.performerId)
setHandleAdvice(data.handleAdvice)
}
if (data.handleContent) {
setHandleCenter(data.handleContent)
}
setIsBeforeReport(dayjs(data.time).diff('2023-08-03 00:00:00', 'h') < 0)
setRoadChecked({
routeName: data.road,
routeCode: data.codeRoad,
sectionNo: data.road_?.sectionNo || '-',
startingPlaceName: data.roadSectionStart,
stopPlaceName: data.roadSectionEnd,
})
} else {
Taro.showToast({ title: res.data.message || '请求出错', icon: 'none' })
}
}, err => {
Taro.showToast({ title: err.message || '请求出错', icon: 'none' })
})
} else { // 填报
Taro.showLoading({ title: '加载中' })
let key = 'ODQBZ-3FZAU-6VIVL-2XXNM-F7CP7-WVFCY' // 写自己申请的key
Taro.getLocation({
// type: 'wgs84',
type: 'gcj02',
// isHighAccuracy: true,
isHighAccuracy: false,
highAccuracyExpireTime: 1000 * 6,
success: function (res) {
setLongitude(res.longitude)
setLatitude(res.latitude)
Taro.request({
url: `https://apis.map.qq.com/ws/geocoder/v1/?location=${res.latitude},${res.longitude}&key=${key}`,
success: function (res) {
// 根据自己项目需求获取res内容
let addresscity = ''
// addresscity =
// res.data.result.address_component.province
// + res.data.result.address_component.city
// + res.data.result.address_component.district
// + res.data.result.address_component.street_number
// + res.data.result.address_component.street
// addresscity = res.data.result.formatted_addresses.standard_address
addresscity = res.data.result.address
let street = res.data.result.address_component.street
// setRoad(street)
setAddress(addresscity)
}
})
}
})
request.get(getRoadSection()).then(res => {
Taro.hideLoading()
if (res.statusCode == 200 || res.statusCode == 204) {
const { data } = res
let nextSourceRoadStartSel = []
let nextSourceRoadEndSel = []
let nextCodeRoadSel = []
let routeName = []
let routeCode = []
let sectionNo = []
data.forEach(item => {
nextSourceRoadStartSel.push(item.startingPlaceName)
nextSourceRoadEndSel.push(item.stopPlaceName)
nextCodeRoadSel.push(item.routeCode)
if (item.routeName && !routeName.includes(item.routeName)) {
routeName.push(item.routeName)
}
if (item.routeCode && !routeCode.includes(item.routeCode)) {
routeCode.push(item.routeCode)
}
if (item.sectionNo && !sectionNo.includes(item.sectionNo)) {
sectionNo.push(item.sectionNo)
}
})
setSourceRoadStartSel(nextSourceRoadStartSel)
setSourceRoadEndSel(nextSourceRoadEndSel)
setCodeRoadSel(nextCodeRoadSel)
setRoadList(data)
setRouteNameList(routeName)
setRouteCodeList(routeCode)
setSectionNoList(sectionNo)
} else {
Taro.showToast({ title: res.data.message || '请求出错', icon: 'none' })
}
}, err => {
Taro.showToast({ title: err.message || '请求出错', icon: 'none' })
})
request.get(getProject()).then(res => {
if (res.statusCode == 200 || res.statusCode == 204) {
const { data } = res
let projectList = []
if (data.length) {
data.forEach(e => {
if (e.done == false) {
projectList.push(e.entryName)
}
})
}
setProjdetList(projectList)
}
})
}
if (isSuperAdmin && kind === 'anomaly') {
request.get(getAllDepUsers()).then(res => {
if (res.statusCode === 200) {
setAllDepUsers(res.data)
}
})
request.get(getUsers()).then(res => {
if (res.statusCode === 200) {
const users = res.data.filter(u => u.phone !== 'SuperAdmin')
setUserList(users)
}
})
}
}, [])
function report() {
if (!canReport) { return }
if (
((isPatrol || isAnomaly) && (!roadChecked.routeCode || !roadChecked.sectionNo || !roadChecked.routeName))
|| (kind === 'patrol'
&& (Object.values(patrolContent).every(c => c.value === '') && !patrolContent.inspectionNoException.selected
|| Object.values(patrolContent).some(c => c.label !== '巡查结果无异常' && c.selected && c.value === '')))
|| (kind === 'conserve'
&& (Object.values(conserveInfo).every(c => c.value === '')
|| (Object.values(conserveContent).every(c => c.value === '') && !otherDescription)
|| !conserveBeforeImg.length || !conserveUnderwayImg.length || !conserveAfterImg.length))
|| ((kind === 'patrol' || kind === 'road' || kind === 'anomaly') && !sceneImg.length)
) {
Taro.showToast({ title: '请完善必填信息', icon: 'none' })
return
}
if (isAnomaly && prjTypeSelector.indexOf(projectType) === -1) {
Taro.showToast({ title: isAnomaly ? '反馈类型错误' : '工程类型错误', icon: 'none' })
return
}
if (content.length > 50) {
Taro.showToast({ title: '内容字数不能超过50', icon: 'none' })
return
}
if (isRoad && !projectName) {
Taro.showToast({ title: '请完善项目名称', icon: 'none' })
return
}
const reportProjectType = prjType.find(p => p.text == projectType)?.value || ''
let data = {
reportType: isPatrol ? reportType : kind,
projectType: reportProjectType,
road: roadChecked.routeName,
roadSectionStart: roadChecked.startingPlaceName,
roadSectionEnd: roadChecked.stopPlaceName,
address,
content,
longitude,
latitude,
codeRoad: roadChecked.routeCode,
projectName,
handleState: isAnomaly ? '待处理' : undefined,
videoUrl: videoqn,
roadId: roadList.find(r => roadChecked?.routeName == r?.routeName
&& roadChecked?.routeCode == r?.routeCode
&& roadChecked?.sectionNo == r?.sectionNo
)?.id,
}
if (reportType === 'patrol' || isAnomaly || isRoad) {
data['scenePic'] = sceneImg
} else {
data['conserveBeforePic'] = conserveBeforeImg
data['conserveUnderwayPic'] = conserveUnderwayImg
data['conserveAfterPic'] = conserveAfterImg
}
if (isPatrol) {
if (kind === 'patrol') {
Object.keys(patrolContent).forEach(key => {
data[key] = patrolContent[key].value
})
data.inspectionNoException = patrolContent.inspectionNoException.selected
} else if (kind === 'conserve') {
Object.keys(conserveInfo).forEach(key => {
data[key] = key === 'roadType' ? conserveInfo[key].value : Number(conserveInfo[key].value)
})
Object.keys(conserveContent).forEach(key => {
data[key] = Number(conserveContent[key].value)
})
data.otherDescription = otherDescription
}
}
Taro.showModal({
title: '提示',
content: '您要进行信息上报么?',
success: function (res) {
if (res.confirm) {
setCanReport(false)
setTimeout(() => {
setCanReport(true)
}, 3000) // 3秒内不可以重复点击
Taro.showLoading({
title: '上报中'
})
request.post(postReport(), data).then(res => {
Taro.hideLoading()
if (res.statusCode == 200 || res.statusCode == 204) {
Taro.showToast({ title: '上报成功', icon: 'none', duration: 1500 })
setTimeout(() => {
Taro.navigateBack()
}, 1500)
} else {
Taro.showToast({ title: res.data.message || '请求出错', icon: 'none' })
}
}, err => {
Taro.showToast({ title: err.message || '请求出错', icon: 'none' })
})
}
}
})
}
function deleteReport() {
Taro.showModal({
title: '提示',
content: '确定删除吗?',
success: function (res) {
if (res.confirm) {
Taro.showLoading({
title: '删除中'
})
request.del(delReport(router.params.id)).then(res => {
Taro.hideLoading()
if (res.statusCode == 200 || res.statusCode == 204) {
Taro.showToast({ title: '删除成功', icon: 'none', duration: 1500 })
setTimeout(() => {
Taro.navigateBack()
}, 1000)
} else {
Taro.showToast({ title: res.data.message || '请求出错', icon: 'none' })
}
}, err => {
Taro.showToast({ title: err.message || '请求出错', icon: 'none' })
})
}
}
})
}
function queryConserveInfo(roadCodeHead, value) {
let routeCode = ''
let roadStart = []
let roadEnd = []
let routeName = ''
for (const r of roadList) {
if (r.routeCode === roadCodeHead + value) {
roadStart.push(r.startingPlaceName)
roadEnd.push(r.stopPlaceName)
routeCode = r.routeCode
routeName = r.routeName
}
}
setRoadStartSel(roadStart)
setRoadEndSel(roadEnd)
setRoadSectionStart('')
setRoadSectionEnd('')
if (routeName) {
setRoad(routeName)
} else {
setRoad('')
}
if (kind === 'conserve' && routeCode) {
request.get(getReportList(), { limit: 1, page: 0, codeRoad: routeCode }).then(res => {
if (res.statusCode === 200 && res.data.length) {
request.get(getReportDetail(res.data[0].id)).then(detailRes => {
if (res.statusCode === 200) {
let nextInfo = { ...conserveInfo }
Object.keys(conserveInfo).forEach(key => {
if (detailRes.data[key]) nextInfo[key].value = detailRes.data[key]
})
setConserveInfo(nextInfo)
setPatrolContentEdit(false)
} else {
if (!patrolContentEdit) {
setPatrolContentEdit(true)
let nextInfo = { ...conserveInfo }
Object.keys(conserveInfo).forEach(key => {
nextInfo[key].value = ''
})
setConserveInfo(nextInfo)
}
}
})
} else {
if (!patrolContentEdit) {
setPatrolContentEdit(true)
let nextInfo = { ...conserveInfo }
Object.keys(conserveInfo).forEach(key => {
nextInfo[key].value = ''
})
setConserveInfo(nextInfo)
}
}
})
}
}
function handleInput({ detail: { value } }, type, key) {
switch (type) {
case 'roadSectionStart':
setRoadSectionStart(value)
if (value) {
setRoadStartSel(sourceRoadStartSel.filter(item => item && item.includes(value)))
} else {
setRoadStartSel(sourceRoadStartSel)
}
break;
case 'roadSectionEnd':
setRoadSectionEnd(value)
if (value) {
setRoadEndSel(sourceRoadEndSel.filter(item => item && item.includes(value)))
} else {
setRoadEndSel(sourceRoadEndSel)
}
break;
case 'address':
setAddress(value)
break;
case 'content':
setContent(value)
break;
case "projectName":
setProjectName(value)
break;
case "wait":
setHandleCenter(value)
break;
case "roadCodeEnd":
setRoadCodeEnd(value)
if (value.length >= 9) {
queryConserveInfo(roadCodeHead, value)
} else {
setRoadStartSel([])
setRoadEndSel([])
setRoadSectionStart('')
setRoadSectionEnd('')
setRoad('')
if (!patrolContentEdit) {
setPatrolContentEdit(true)
let nextInfo = { ...conserveInfo }
Object.keys(conserveInfo).forEach(key => {
nextInfo[key].value = ''
})
setConserveInfo(nextInfo)
}
}
break;
case "conserveInfo":
let nextInfo = { ...conserveInfo }
nextInfo[key].value = value
setConserveInfo(nextInfo)
break;
case "conserveContent":
let nextContent = { ...conserveContent }
if (value.split('.')[1] && value.split('.')[1].length > 3 || value.includes('-')) {
setConserveContent(nextContent)
Taro.showToast({ title: '请输入最多三位小数的正数', icon: 'none', duration: 1500 })
return;
}
nextContent[key].value = value
setConserveContent(nextContent)
break;
case "otherDescription":
setOtherDescription(value)
break;
case "contentCheck":
let nextCheck = { ...patrolContent }
Object.keys(patrolContent).forEach(key => {
if (value.indexOf(key) !== -1) {
nextCheck[key].selected = true
} else {
nextCheck[key].selected = false
}
})
setPatrolContent(nextCheck)
break;
case "patrolContent":
let nextPatrolContent = { ...patrolContent }
nextPatrolContent[key].value = value
if (value) nextPatrolContent[key].selected = true
setPatrolContent(nextPatrolContent)
break;
default:
break;
}
}
const handleRoadCheckChange = (value, key) => {
let nextValue = {
...roadChecked,
[key]: value
}
let routeCode = []
let sectionNo = []
let data = [...roadList]
if (key == 'routeName') {
// routeName关键字筛选
let routeName = []
roadList.forEach(item => {
if (item.routeName && !routeName.includes(item.routeName)) {
routeName.push(item.routeName)
}
})
if (value) {
routeName = routeName.filter(item => item.indexOf(value) > -1)
}
setRouteNameList(routeName)
nextValue.routeCode = ''
nextValue.sectionNo = ''
data?.forEach(v => {
if (nextValue?.routeName && nextValue?.routeName == v.routeName && v.routeCode && !routeCode.includes(v.routeCode)) {
routeCode.push(v.routeCode)
}
});
setRouteCodeList(routeCode)
}
if (key == 'routeCode') {
nextValue.sectionNo = ''
data = roadList?.filter(s => nextValue?.routeName == s?.routeName)
data?.forEach(v => {
if (nextValue?.routeCode && nextValue?.routeCode == v?.routeCode && v.sectionNo && !sectionNo.includes(v.sectionNo)) {
sectionNo.push(v.sectionNo)
}
if (!nextValue?.routeCode && v.routeCode && !routeCode.includes(v.routeCode)) {
routeCode.push(v.routeCode)
}
});
if (!nextValue?.routeCode) {
setRouteCodeList(routeCode)
}
setSectionNoList(sectionNo)
}
if (nextValue?.routeName) {
setRouteCodeDisabled(false)
} else {
setRouteCodeDisabled(true)
}
if (nextValue?.routeName && nextValue?.routeCode) {
setSectionNoDisabled(false)
} else {
setSectionNoDisabled(true)
}
if (nextValue.routeName && nextValue.routeCode && nextValue.sectionNo) {
let find = roadList?.find(
s => nextValue.routeName == s.routeName
&& nextValue.routeCode == s.routeCode
&& nextValue.sectionNo == s.sectionNo
)
nextValue.startingPlaceName = find?.startingPlaceName
nextValue.stopPlaceName = find?.stopPlaceName
setRoadCodeHead(find?.routeCode?.charAt(0))
} else {
nextValue.startingPlaceName = ''
nextValue.stopPlaceName = ''
}
setRoadChecked(nextValue)
}
function handleImgChange(files, operationType, index, type) {
if (operationType === 'remove') {
setImg(false)
}
function setImg(isAdd, url) {
switch (type) {
case 'scenePic':
let nextImg = sceneImg
if (isAdd) {
nextImg.push(url)
} else {
nextImg.splice(index, 1)
}
setSceneImg(nextImg)
setScenePic(files)
break;
case 'wait':
let handlPicImg = handlePicPn
if (isAdd) {
handlPicImg.push(url)
} else {
handlPicImg.splice(index, 1)
}
setHandlePicPn(handlPicImg)
setHandlePic(files)
break;
case 'conserveBeforePic':
let nextConserveBeforeImg = conserveBeforeImg
if (isAdd) {
nextConserveBeforeImg.push(url)
} else {
nextConserveBeforeImg.splice(index, 1)
}
setConserveBeforeImg(nextConserveBeforeImg)
setConserveBeforePic(files)
break;
case 'conserveUnderwayPic':
let nextConserveUnderwayImg = conserveUnderwayImg
if (isAdd) {
nextConserveUnderwayImg.push(url)
} else {
nextConserveUnderwayImg.splice(index, 1)
}
setConserveUnderwayImg(nextConserveUnderwayImg)
setConserveUnderwayPic(files)
break;
case 'conserveAfterPic':
let nextConserveAfterImg = conserveAfterImg
if (isAdd) {
nextConserveAfterImg.push(url)
} else {
nextConserveAfterImg.splice(index, 1)
}
setConserveAfterImg(nextConserveAfterImg)
setConserveAfterPic(files)
break;
default:
break;
}
}
if (operationType === 'add' && files.length > 0) {
Taro.showLoading({ title: '上传中' })
let i = 0
switch (type) {
case 'scenePic':
i = scenePic.length
break;
case 'wait':
i = handlePic.length
break;
case 'conserveBeforePic':
i = conserveBeforePic.length
break;
case 'conserveUnderwayPic':
i = conserveUnderwayPic.length
break;
case 'conserveAfterPic':
i = conserveAfterPic.length
break;
default:
break;
}
for (i; i < files.length; i++) {
const tempFilePaths = files[i].url
let token = getState('token') || Taro.getStorageSync('token')
Taro.uploadFile({
url: `${baseUrl}${postImage()}?token=${token}`,
filePath: tempFilePaths,
name: 'file',
success: (res) => {
if (i === files.length) {
Taro.hideLoading();
}
if (res.statusCode == 200) {
setImg(true, JSON.parse(res.data).key)
} else {
Taro.showToast({ title: '上传失败,请重试', icon: 'error' })
}
}
});
}
}
}
function handleImgClick(index, file) {
Taro.previewImage({
urls: [file.url] // 需要预览的图片http链接列表
})
}
function handleImgClicks(index, file) {
Taro.previewImage({
urls: [file.url] // 需要预览的图片http链接列表
})
}
useEffect(() => {
if (!isView) {
let newRoadList = roadList.filter(e => e?.routeName?.match(road))
let codeRoadSel = []
if (newRoadList.length && road != '') {
newRoadList.forEach((e, index) => {
codeRoadSel.push(e.routeCode)
})
}
setCodeRoadSel(codeRoadSel)
if (codeRoadSel.length) {
setCodeRoad(codeRoadSel[0])
} else {
setCodeRoad('')
}
}
}, [road])
function handleOk() {
if (!canReport) { return }
let str = handleCenter.trim()
if (!isSuperAdmin) {
if (!str) {
Taro.showToast({ title: '请完善处理内容', icon: 'none' })
return
}
if (str.length > 50) {
Taro.showToast({ title: '内容字数不能超过50', icon: 'none' })
return
}
if (!handlePicPn.length) {
Taro.showToast({ title: '请上传处理图片', icon: 'none' })
return
}
} else {
if (isAppoint && appointUser === null) {
Taro.showToast({ title: '请选择责任人', icon: 'none' })
return
}
}
let data = {}
if (isSuperAdmin) {
data = {
handleState: isAppoint ? '已指派' : '不处理',
performerId: userList[appointUser]?.id,
handleAdvice,
}
} else {
data = {
handleContent: str,
handlePic: handlePicPn,
handleState: '已处理'
}
}
Taro.showModal({
title: '提示',
content: '您要进行处理提交吗?',
success: function (res) {
if (res.confirm) {
setCanReport(false)
setTimeout(() => {
setCanReport(true)
}, 3000) // 3秒内不可以重复点击
Taro.showLoading({
title: '提交中'
})
request.post(postHandle(handleId), data).then(res => {
Taro.hideLoading()
if (res.statusCode == 200 || res.statusCode == 204) {
Taro.showToast({ title: '提交成功', icon: 'none', duration: 1500 })
setTimeout(() => {
Taro.navigateBack()
}, 1500)
} else {
Taro.showToast({ title: res.data.message || '请求出错', icon: 'none' })
}
}, err => {
Taro.showToast({ title: err.message || '请求出错', icon: 'none' })
})
}
}
})
}
function addVideo() {
wx.chooseMedia({
count: 1,
mediaType: ['video'],
sourceType: ['album', 'camera'],
maxDuration: 15,
camera: 'back',
success(res) {
const tempFilePaths = res.tempFiles[0].tempFilePath
let token = getState('token') || Taro.getStorageSync('token')
if (res.tempFiles[0].duration < 15) {
Taro.showLoading({
title: '视频上传中'
})
Taro.uploadFile({
url: `${baseUrl}${postImage()}?token=${token}`,
filePath: tempFilePaths,
name: 'file',
success: (ress) => {
Taro.hideLoading();
if (ress.statusCode == 200) {
setVideo(res.tempFiles[0].tempFilePath)
let videoqns = []
videoqns.push(JSON.parse(ress.data).key)
setVideoqn(videoqns)
} else {
Taro.showToast({ title: '上传失败,请重试', icon: 'error' })
}
},
fail: (res) => {
Taro.hideLoading();
}
});
} else {
Taro.atMessage({
'message': '请传15秒内的视频!',
'type': 'error',
})
}
}
})
}
return (
<View className='patrol'>
{
isPatrol || isAnomaly ? <>
<View className='code-choice'>
<Text style={{ color: 'red' }}>*&nbsp;</Text>线
<View className='select-box'>
<View className='picker'>
<Input
type='text'
placeholder='输入关键字筛选'
border={false}
value={roadChecked.routeName}
onInput={e => handleRoadCheckChange(e.detail.value, 'routeName')}
disabled={isView}
/>
<Picker
mode='selector'
range={routeNameList}
onChange={e => handleRoadCheckChange(routeNameList[e.detail.value], 'routeName')}
disabled={isView}
>
<AtIcon className='arrow' value='chevron-down' size='20' color='#999' />
</Picker>
</View>
{!isView && <AtIcon
value='close-circle'
size='20'
color='#999'
onClick={() => handleRoadCheckChange('', 'routeName')}
/>}
</View>
</View>
{!(isView && isBeforeReport) && <View className={`code-choice ${routeCodeDisabled && !isView ? ` disabled` : ``}`}>
<Text style={{ color: 'red' }}>*&nbsp;</Text>线
<View className='select-box'>
<Picker
mode='selector'
range={routeCodeList}
onChange={e => handleRoadCheckChange(routeCodeList[e.detail.value], 'routeCode')}
disabled={routeCodeDisabled}
>
<View className='picker'>
<View>{roadChecked.routeCode || '请选择线路编码'}</View>
<AtIcon className='arrow' value='chevron-down' size='20' color='#999' />
</View>
</Picker>
{roadChecked.routeCode && !isView && <AtIcon
value='close-circle'
size='20'
color='#999'
onClick={() => handleRoadCheckChange('', 'routeCode')}
/>}
</View>
</View>}
<View className={`code-choice ${sectionNoDisabled && !isView ? ` disabled` : ``}`}>
<Text style={{ color: 'red' }}>*&nbsp;</Text>
<View className='select-box'>
<Picker
mode='selector'
range={sectionNoList}
onChange={e => handleRoadCheckChange(sectionNoList[e.detail.value], 'sectionNo')}
disabled={sectionNoDisabled}
>
<View className='picker'>
<View>{roadChecked.sectionNo || '请选择路段序号'}</View>
<AtIcon className='arrow' value='chevron-down' size='20' color='#999' />
</View>
</Picker>
{roadChecked.sectionNo && !isView && <AtIcon
value='close-circle'
size='20'
color='#999'
onClick={() => handleRoadCheckChange('', 'sectionNo')}
/>}
</View>
</View>
<View className='code-choice'>
<Text style={{ color: 'red' }}>*&nbsp;</Text>
<Input
style={{ width: '30%' }}
type='text'
value={isView && isBeforeReport
? projectType
: roadCodeHead === 'X' ? '县道' : roadCodeHead === 'Y' ? '乡道' : '村道'}
onInput={() => { }}
disabled={true}
/>
</View>
</> : ''
}
{
isAnomaly ?
<InputPicker
title='反馈类型:'
placeholder='请选择反馈类型'
value={projectType}
onInput={setProjectType}
selector={prjTypeSelector}
isView={isView}
onlySelect={true}
/> : ''
}
{/* {
isRoad ?
<View className='address'>
<View className='title'>项目名称:</View>
<Input
className='input'
type='text'
placeholder={isView ? '' : '请输入项目名称'}
value={projectName}
onInput={e => handleInput(e, 'projectName')}
disabled={isView}
/>
</View> : ''
} */}
{
isRoad ?
<InputPicker
title='项目名称:'
value={projectName}
placeholder='请选择项目'
onInput={setProjectName}
selector={projectList}
isView={isView}
onlySelect={true}
/> : ''
}
{
isPatrol || isAnomaly ?
<View className='road-section'>
<View className='title'>所属路段</View>
<Input
className='input text---'
type='text'
border={false}
value={roadChecked.startingPlaceName}
disabled={true}
/>
<View>&nbsp;</View>
<Input
className='input text---'
type='text'
border={false}
value={roadChecked.stopPlaceName}
disabled={true}
/>
</View> : ''
}
<View className='address'>
<View className='title'>具体位置</View>
<Input
className='input'
type='text'
placeholder={isView ? '' : '根据定位自动获取,可手动修改'}
value={address}
onInput={e => handleInput(e, 'address')}
disabled={isView}
/>
</View>
{
kind === 'patrol' && !(isView && isBeforeReport) && <View className='patrol-content'>
<View className='title'>
<View><Text style={{ color: 'red' }}>*&nbsp;</Text></View>
</View>
<View className='cell-box'>
<CheckboxGroup onChange={e => handleInput(e, 'contentCheck')}>
{
Object.keys(patrolContent).map(key => <View className='item'>
<Checkbox color='#0080EE' value={key} checked={patrolContent[key].selected} disabled={isView} />
<Text style={{ width: patrolContent[key].label === '巡查结果无异常' ? '100%' : '75px' }}>{patrolContent[key].label + (patrolContent[key].label !== '巡查结果无异常' ? ':' : '')}</Text>
{patrolContent[key].label !== '巡查结果无异常' && <Textarea
autoHeight
className='input'
placeholder={!isView ? '具体内容' : ''}
value={patrolContent[key].value}
onInput={e => handleInput(e, 'patrolContent', key)}
disabled={isView}
/>}
</View>)
}
</CheckboxGroup>
</View>
</View >
}
{
kind === 'conserve' && !(isView && isBeforeReport) && <View>
<View className='conserve-info'>
<View className='title'>
<View><Text style={{ color: 'red' }}>*&nbsp;</Text></View>
{
(!patrolContentEdit && !isView) && <View style={{ color: '#0080EE' }} onClick={() => {
Taro.showModal({
title: '提示',
content: '是否要进行信息修改?',
success: function (res) {
if (res.confirm) {
setPatrolContentEdit(true)
} else if (res.cancel) {
}
}
})
}}>修改</View>
}
</View>
<View>
<View className='grid-box'>
{
Object.keys(conserveInfo).map(key => <View className='item'>
<Text className='label'>{conserveInfo[key].label}</Text>
<Input
className='input'
type={key === 'roadType' ? 'text' : 'digit'}
placeholder={patrolContentEdit && !isView ? '请输入' : ''}
value={conserveInfo[key].value}
onInput={e => handleInput(e, 'conserveInfo', key)}
disabled={isView || !patrolContentEdit}
/>
<Text>{conserveInfo[key].unit}</Text>
</View>)
}
</View>
</View>
</View>
<View className='conserve-content'>
<View className='title'>
<View><Text style={{ color: 'red' }}>*&nbsp;</Text></View>
</View>
<View className='cell-box'>
{
Object.keys(conserveContent).map(key => <View className='item'>
<Text className='label'>{conserveContent[key].label}</Text>
<Input
className='input'
type='digit'
placeholder={!isView ? '请输入' : ''}
value={conserveContent[key].value}
onInput={e => handleInput(e, 'conserveContent', key)}
disabled={isView}
/>
<Text>{conserveContent[key].unit}</Text>
</View>)
}
<View className='item'>
<Text>其他</Text>
<Input
style={{ width: '80%' }}
type='text'
placeholder={'其他养护内容'}
value={otherDescription}
onInput={e => handleInput(e, 'otherDescription')}
disabled={isView}
/>
</View>
</View>
</View>
</View>
}
{
!isPatrol || (isView && isBeforeReport) ? <AtTextarea
title='巡查内容:'
placeholder={isView ? '' : '请输入具体内容'}
value={content}
onChange={(v, e) => handleInput(e, 'content')}
disabled={isView}
maxLength={50}
/> : null
}
{
reportType === 'patrol' || isRoad || isAnomaly ?
<View className='patrol-img'>
<View><Text style={{ color: 'red' }}>*&nbsp;</Text></View>
{
isView ?
<View className='img-box'>
{scenePic.map(item => (
<Image className='img' src={item.url} onClick={() => handleImgClick(undefined, item)} />
))}
</View> :
<AtImagePicker
className='img-picker'
count={3 - scenePic.length}
showAddBtn={scenePic.length >= 3 ? false : true}
files={scenePic}
onChange={(files, operationType, index) => handleImgChange(files, operationType, index, 'scenePic')}
onImageClick={handleImgClick}
/>
}
{/* <Video
id='video'
src='https://wxsnsdy.tc.qq.com/105/20210/snsdyvideodownload?filekey=30280201010421301f0201690402534804102ca905ce620b1241b726bc41dcff44e00204012882540400&bizid=1023&hy=SH&fileparam=302c020101042530230204136ffd93020457e3c4ff02024ef202031e8d7f02030f42400204045a320a0201000400'
poster='../../static/img/date.png'
initialTime={0}
controls={true}
autoplay={false}
loop={false}
muted={false}
/> */}
{/* <AtButton onClick={() => {
Taro.chooseMedia({
sourceType: ['album', 'camera'], mediaType: ['image', 'video'],
camera: 'back',
success: function (res) {
Taro.showLoading({ title: '上传中' })
const tempFilePaths = res.tempFilePath
let token = getState('token') || Taro.getStorageSync('token')
Taro.uploadFile({
url: `${baseUrl}${postImage()}?token=${token}`,
filePath: tempFilePaths,
name: 'file',
success: (res) => {
Taro.hideLoading();
if (res.statusCode == 200) {
// setImg(true, JSON.parse(res.data).key)
} else {
Taro.showToast({ title: '上传失败,请重试', icon: 'error' })
}
}
});
}
})
}}>
添加视频
</AtButton> */}
</View> :
<View className='conserve-img'>
<View><Text style={{ color: 'red' }}>*&nbsp;</Text>:</View>
<View className='horizontal-line hl-one'>
<View className='circle c-one'></View>
<View className='text t-one'><Text style={{ color: 'red' }}>*&nbsp;</Text></View>
</View>
{
isView ?
<View className='img-box'>
{conserveBeforePic.map(item => (
<Image className='img' src={item.url} onClick={() => handleImgClick(undefined, item)} />
))}
</View> :
<AtImagePicker
className='img-picker'
count={3 - conserveBeforePic.length}
showAddBtn={conserveBeforePic.length >= 3 ? false : true}
files={conserveBeforePic}
onChange={(files, operationType, index) => handleImgChange(files, operationType, index, 'conserveBeforePic')}
onImageClick={handleImgClick}
/>
}
<View className='horizontal-line hl-two'>
<View className='circle c-two'></View>
<View className='text t-two'><Text style={{ color: 'red' }}>*&nbsp;</Text></View>
</View>
{
isView ?
<View className='img-box'>
{conserveUnderwayPic.map(item => (
<Image className='img' src={item.url} onClick={() => handleImgClick(undefined, item)} />
))}
</View> :
<AtImagePicker
className='img-picker'
count={3 - conserveUnderwayPic.length}
showAddBtn={conserveUnderwayPic.length >= 3 ? false : true}
files={conserveUnderwayPic}
onChange={(files, operationType, index) => handleImgChange(files, operationType, index, 'conserveUnderwayPic')}
onImageClick={handleImgClick}
/>
}
<View className='horizontal-line hl-three'>
<View className='circle c-three'></View>
<View className='text t-three'><Text style={{ color: 'red' }}>*&nbsp;</Text></View>
</View>
{
isView ?
<View className='img-box'>
{conserveAfterPic.map(item => (
<Image className='img' src={item.url} onClick={() => handleImgClick(undefined, item)} />
))}
</View> :
<AtImagePicker
className='img-picker'
count={3 - conserveAfterPic.length}
showAddBtn={conserveAfterPic.length >= 3 ? false : true}
files={conserveAfterPic}
onChange={(files, operationType, index) => handleImgChange(files, operationType, index, 'conserveAfterPic')}
onImageClick={handleImgClick}
/>
}
</View>
}
{
videoShow ? '' :
<view>
{
video != '' ? <view style={{ position: 'relative' }}>
<view onClick={() => { setVideo('') }} style={{ position: 'absolute', zIndex: '999', right: '70rpx', top: '30rpx' }}>
{!isView ? <AtIcon value='close-circle' size='30' color='#fff'></AtIcon> : ''}
</view>
<Video
style={{ width: '90%', marginLeft: '-45%', left: '50%', marginBottom: 20 }}
src={video}
poster='../../static/img/date.png'
initialTime={0}
controls={true}
autoplay={false}
loop={false}
muted={false}
/></view> : ''
}
{
!isView && video == '' ? <AtButton type='secondary' size='small' onClick={addVideo}>添加视频</AtButton> : ''
}
</view>
}
{
!isPatrol && (handleState == '已处理' || wait == 'wait' || handle == 'handle') ? <>
{
isSuperAdmin && (wait === 'wait' || kind === 'handle') && <View className='appoint'>
{
handleState === '待处理' && <>
<View className='appoint-radio'>
<RadioGroup onChange={(e) => {
setIsAppoint(e.detail.value === '指派' ? true : false)
}}>
<Radio value='指派' checked={isAppoint} color='#0080EE'>指派</Radio>
<Radio value='不处理' checked={!isAppoint} color='#0080EE' style={{ marginLeft: 10 }}>不处理</Radio>
</RadioGroup>
</View>
{
isAppoint && <>
<View className='picker'>
<Text>责任人{appointUser !== null ? userList[appointUser]?.name : ''}</Text>
<Picker
mode='selector'
range={userList}
rangeKey='name'
onChange={e => setAppointUser(Number(e.detail.value))}
>
<Image src={arrowIcon} className='arrow' />
</Picker>
</View>
<View className='handle-advice'>
<Textarea
placeholder='请输入处理意见'
value={handleAdvice}
onInput={e => setHandleAdvice(e.target.value)}
disabled={isView && handleState !== '待处理'}
maxlength={1024}
/>
</View>
</>
}
</>
}
</View>
}
{
handleState !== '待处理' && <View >
{
isSuperAdmin && handleState === '不处理' && <View className='general-cell'>
处理结果暂不进行处理
</View>
}
{
(!isSuperAdmin || (isSuperAdmin && (handleState === '已指派' || handleState === '已处理'))) && <View className='general-cell' style={{ padding: '5px 10px' }}>
<View>处理意见</View>
<View>{handleAdvice}</View>
</View>
}
{
(isSuperAdmin && (handleState === '已指派' || handleState === '已处理')) && <View className='general-cell' >
<View>责任人</View>
<View>
{appointUser !== null ? allDepUsers.find(d => d.depId === userList.find(u => u.id === appointUser)?.departmentId)?.depName : ''}
-
{appointUser !== null ? userList.find(u => u.id === appointUser)?.name : ''}
</View>
</View>
}
</View>
}
{
((isSuperAdmin && handleState == '已处理') || !isSuperAdmin) && <View style={{ marginTop: 2 }}>
<View className='patrol-img'><Text style={{ color: 'red' }}>*</Text></View>
<AtTextarea
placeholder='请输入处理内容'
value={handleCenter}
onChange={(v, e) => handleInput(e, 'wait')}
disabled={handle == 'handle' ? true : false}
maxLength={50}
/>
<View className='patrol-img'>
<View><Text style={{ color: 'red' }}>*&nbsp;</Text></View>
{
handle == 'handle' || handleState == '已处理' ?
<View className='img-box'>
{handlePic.map(item => (
<Image className='img' src={item.url} onClick={() => handleImgClicks(undefined, item)} />
))}
</View> : handleState != '' ?
<AtImagePicker
className='img-picker'
count={3 - handlePic.length}
showAddBtn={handlePic.length >= 3 ? false : true}
files={handlePic}
onChange={(files, operationType, index) => handleImgChange(files, operationType, index, 'wait')}
onImageClick={handleImgClick}
/> : ''
}
</View>
</View>
}
{handle != 'handle' && handleState != '已处理' ? <AtButton type='primary' className='sub-btn' onClick={handleOk}>提交</AtButton> : ''}
</> : ''
}
{
isView
? isSuperAdmin && !noDel && <AtButton type='primary' className='del-btn' onClick={deleteReport}>删除</AtButton>
: <AtButton type='primary' className='sub-btn' onClick={report}>上报</AtButton>
}
<AtMessage />
</View >
)
}
export default Index