巴林闲侠 1 year ago
parent
commit
82a676b0e8
  1. 3
      api/.vscode/launch.json
  2. 21
      api/app/lib/controllers/report/index.js
  3. 12
      api/app/lib/models/report.js
  4. 6
      scripts/1.3.1/schema/4.update_report.sql
  5. 138
      weapp/src/packages/patrol/index.jsx
  6. 18
      weapp/src/packages/patrol/index.scss
  7. 9
      weapp/src/packages/patrolView/index.jsx
  8. 10
      weapp/src/services/api.js
  9. 16
      web/client/src/sections/fillion/components/luzhengmodel.js
  10. 327
      web/client/src/sections/fillion/components/uploads.js
  11. 35
      web/client/src/sections/fillion/containers/luzheng.js
  12. 102
      web/client/src/sections/quanju/containers/footer/guanli/index.js

3
api/.vscode/launch.json

@ -15,7 +15,8 @@
"args": [
"-p 13400",
"-f http://localhost:13400",
"-g postgres://FashionAdmin:123456@10.8.16.184:5432/sihaogonglu",
// "-g postgres://FashionAdmin:123456@10.8.16.184:5432/sihaogonglu",
"-g postgres://postgres:123@10.8.30.32:5432/highways4good",
// "-g postgres://FashionAdmin:123456@10.8.30.156:5432/highway4goodn0728",
"--qnak XuDgkao6cL0HidoMAPnA5OB10Mc_Ew08mpIfRJK5",
"--qnsk yewcieZLzKZuDfig0wLZ9if9jKp2P_1jd3CMJPSa",

21
api/app/lib/controllers/report/index.js

@ -2,7 +2,7 @@
const { QueryTypes } = require('sequelize');
const moment = require('moment');
async function reportList (ctx) {
async function reportList(ctx) {
try {
const models = ctx.fs.dc.models;
const { limit, page, startTime, endTime, keyword, userId, reportType, isTop, asc, projectType, handleState = '', performerId = '', codeRoad } = ctx.query
@ -95,7 +95,8 @@ async function reportList (ctx) {
findOption.where.performerId = { $in: performerIds }
}
if (handleState) {
findOption.where.handleState = handleState
let handleStates = handleState.split(',')
findOption.where.handleState = { $in: handleStates }
}
if (codeRoad) {
findOption.where.codeRoad = codeRoad
@ -146,7 +147,7 @@ async function reportList (ctx) {
}
}
async function reportPosition (ctx) {
async function reportPosition(ctx) {
try {
const models = ctx.fs.dc.models;
const { startTime, endTime, userId, reportType } = ctx.query
@ -196,7 +197,7 @@ async function reportPosition (ctx) {
}
}
async function reportDetail (ctx) {
async function reportDetail(ctx) {
try {
const models = ctx.fs.dc.models;
const { reportId } = ctx.params
@ -218,7 +219,7 @@ async function reportDetail (ctx) {
}
}
async function reportHandle (ctx) {
async function reportHandle(ctx) {
try {
const { models } = ctx.fs.dc;
@ -248,7 +249,7 @@ async function reportHandle (ctx) {
}
}
async function createReport (ctx) {
async function createReport(ctx) {
try {
const { userId } = ctx.fs.api
const models = ctx.fs.dc.models;
@ -270,7 +271,7 @@ async function createReport (ctx) {
}
}
async function deleteReport (ctx) {
async function deleteReport(ctx) {
try {
const models = ctx.fs.dc.models;
const { reportId } = ctx.params;
@ -293,7 +294,7 @@ async function deleteReport (ctx) {
// TODO 小程序填写道路名称的时候的道路筛选 是一起都返回 还是不断传关键字搜索返回
async function spotPrepare (ctx) {
async function spotPrepare(ctx) {
try {
const { models } = ctx.fs.dc;
const sequelize = ctx.fs.dc.orm;
@ -365,7 +366,7 @@ async function spotPrepare (ctx) {
}
}
async function spotCheck (ctx) {
async function spotCheck(ctx) {
const transaction = await ctx.fs.dc.orm.transaction();
try {
const { models } = ctx.fs.dc;
@ -447,7 +448,7 @@ async function spotCheck (ctx) {
}
}
}
async function spotCheckDetail (ctx) {
async function spotCheckDetail(ctx) {
const { models } = ctx.fs.dc
console.log('txc1', ctx.query)
const { startTime, endTime } = ctx.query

12
api/app/lib/models/report.js

@ -447,7 +447,17 @@ module.exports = dc => {
primaryKey: false,
field: "handle_opinions",
autoIncrement: false
}
},
handleAdvice: {
index: 6,
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: '管理员处理意见',
primaryKey: false,
field: "handle_advice",
autoIncrement: false
},
}, {
tableName: "report",
comment: "",

6
scripts/1.3.1/schema/4.update_report.sql

@ -0,0 +1,6 @@
ALTER TABLE "public"."report"
ADD COLUMN "handle_advice" varchar(1024);
COMMENT ON COLUMN "public"."report"."handle_state" IS '待处理 / 已指派 / 已处理 / 不处理';
COMMENT ON COLUMN "public"."report"."handle_advice" IS '管理员处理意见';

138
weapp/src/packages/patrol/index.jsx

@ -8,7 +8,7 @@ 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 } from '@/services/api';
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';
@ -25,6 +25,7 @@ const Index = () => {
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('') //
@ -60,7 +61,7 @@ const Index = () => {
const [handleId, setHandleId] = useState([])
const [video, setVideo] = useState('')
const [videoqn, setVideoqn] = useState([])
const [handleType, setHandleType] = useState('')
const [handleState, setHandleState] = useState('')
const [roadCodeHead, setRoadCodeHead] = useState('X')
const [roadCodeEnd, setRoadCodeEnd] = useState('')
@ -201,6 +202,12 @@ const Index = () => {
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) // userListindex
const [handleAdvice, setHandleAdvice] = useState('') //
const prjType =
isAnomaly ?
[
@ -282,7 +289,7 @@ const Index = () => {
setRoadSectionEnd(data.roadSectionEnd)
setAddress(data.address)
setContent(data.content)
setHandleType(data.handleState)
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 })) : [])
@ -314,6 +321,9 @@ const Index = () => {
})
setConserveContent(nextContent)
setOtherDescription(data.otherDescription)
} else if (data.reportType === 'anomaly') {
setAppointUser(data.performerId)
setHandleAdvice(data.handleAdvice)
}
if (data.handleContent) {
setHandleCenter(data.handleContent)
@ -401,6 +411,19 @@ const Index = () => {
}
})
}
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' && u.isAdmin)
setUserList(users)
}
})
}
}, [])
useEffect(() => {
@ -829,6 +852,7 @@ const Index = () => {
function handleOk() {
if (!canReport) { return }
let str = handleCenter.trim()
if (!isSuperAdmin) {
if (!str) {
Taro.showToast({ title: '请完善处理内容', icon: 'none' })
return
@ -837,11 +861,27 @@ const Index = () => {
Taro.showToast({ title: '内容字数不能超过50', icon: 'none' })
return
}
let data = {
} 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: '您要进行处理提交吗?',
@ -1399,17 +1439,75 @@ const Index = () => {
</view>
}
{
isView ?
isSuperAdmin &&
<AtButton type='primary' className='del-btn' onClick={deleteReport}>删除</AtButton>
:
<AtButton type='primary' className='sub-btn' onClick={report}>上报</AtButton>
!isPatrol && (handleState == '已处理' || wait == 'wait' || handle == 'handle') ? <>
{
isSuperAdmin && (wait === 'wait' || kind === 'handle') && <View className='appoint'>
{
handleState === '待处理' && <>
<RadioGroup onChange={(e) => {
setIsAppoint(e.detail.value === '指派' ? true : false)
}}>
<Radio value='指派' checked={isAppoint} color='#0080EE' className='radio'>指派</Radio>
<Radio value='不处理' checked={!isAppoint} color='#0080EE' className='radio' style={{ marginLeft: 10 }}>不处理</Radio>
</RadioGroup>
{
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>
<Textarea
placeholder='请输入处理意见'
value={handleAdvice}
onInput={e => setHandleAdvice(e.target.value)}
disabled={isView && handleState !== '待处理'}
maxlength={1024}
/>
</>
}
</>
}
</View>
}
{
handleState !== '待处理' && <View style={{ backgroundColor: '#fff', padding: 10 }}>
{
isSuperAdmin && handleState === '不处理' && <Text>
处理结果暂不进行处理
</Text>
}
{
(!isSuperAdmin || (isSuperAdmin && (handleState === '已指派' || handleState === '已处理'))) && <>
<View>处理意见</View>
<View>{handleAdvice}</View>
</>
}
{
!isPatrol && (handleType == '已处理' || wait == 'wait' || handle == 'handle') ? <view>
<view className='patrol-img'><text style={{ color: 'red' }}>*</text>处理内容</view>
(isSuperAdmin && (handleState === '已指派' || handleState === '已处理')) && <>
<View style={{ marginTop: 10 }}>责任人</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>
}
{
((isSuperAdmin && handleState == '已处理') || !isSuperAdmin) && <>
<View className='patrol-img'><Text style={{ color: 'red' }}>*</Text>处理内容</View>
<AtTextarea
title='处理内容:'
placeholder='请输入处理内容'
value={handleCenter}
onChange={(v, e) => handleInput(e, 'wait')}
disabled={handle == 'handle' ? true : false}
@ -1418,12 +1516,12 @@ const Index = () => {
<View className='patrol-img'>
处理图片
{
handle == 'handle' || handleType == '已处理' ?
handle == 'handle' || handleState == '已处理' ?
<View className='img-box'>
{handlePic.map(item => (
<Image className='img' src={item.url} onClick={() => handleImgClicks(undefined, item)} />
))}
</View> : handleType != '已处理' ?
</View> : handleState != '已处理' ?
<AtImagePicker
className='img-picker'
count={3 - handlePic.length}
@ -1433,9 +1531,17 @@ const Index = () => {
onImageClick={handleImgClick}
/> : ''
}
{handle != 'handle' && handleType != '已处理' ? <AtButton type='primary' className='sub-btn' onClick={handleOk}>提交</AtButton> : ''}
</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 >

18
weapp/src/packages/patrol/index.scss

@ -281,4 +281,22 @@ page {
}
}
}
.appoint {
margin-top: 10px;
padding: 10px 20px;
background-color: #fff;
.picker {
margin: 10px 0;
display: flex;
justify-content: flex-start;
.arrow {
width: 24px;
height: 14px;
margin: 0 10px;
}
}
}
}

9
weapp/src/packages/patrolView/index.jsx

@ -16,6 +16,7 @@ import conserveActiveIcon from '../../static/img/patrolView/conserve-active.svg'
function Index() {
const userInfo = Taro.getStorageSync('userInfo') || {};
const isAdmin = userInfo && userInfo.username === 'SuperAdmin' ? true : false
const router = useRouter()
const { params: { filter, kind, } } = router
@ -76,7 +77,11 @@ function Index() {
if (typeSearch != '全部') {
handleState = typeSearch
} else {
handleState = isWait ? '待处理' : ishandle ? '已处理' : ''
handleState = isWait
? isAdmin ? '待处理' : '待处理,已指派'
: ishandle
? isAdmin ? '已处理,已指派,不处理' : '已处理'
: ''
}
const data = {
limit,
@ -87,7 +92,7 @@ function Index() {
reportType: isWait || ishandle ? 'anomaly' : reportType,
userId: filter === 'my' && !ishandle ? userInfo.id : '',
handleState: handleState,
performerId: isWait || ishandle ? userInfo.id : ''
performerId: (isWait || ishandle) && !isAdmin ? userInfo.id : '', //
}
request.get(getReportList(), data).then(res => {
Taro.hideLoading()

10
weapp/src/services/api.js

@ -7,6 +7,16 @@ export const getLogoutUrl = () => {
return `/logout`;
};
// 获取所有部门用户列表
export const getAllDepUsers = () => {
return `/allDepUsers`;
};
// 获取所有用户列表
export const getUsers = () => {
return `/user`;
};
// 巡查上报
export const postReport = () => {
return `/report`;

16
web/client/src/sections/fillion/components/luzhengmodel.js

@ -6,13 +6,13 @@ import { getAssess, delAssess, editAssess } from '../actions/assess';
import moment from 'moment';
import { getRoadadministration,addRoadadministration,delRoadadministration,modifyRoadadministration } from '../actions/luzheng';
// import Uploads from "../../../../components/Upload/index"
import Uploads from '../../../components/Upload/index'
// import Uploads from '../../../components/Upload/index'
import Uploads from './uploads'
const { Option } = Select;
const LuzhengModel = ({ editData, check, visible, onCancel, dispatch }) => {
const [form] = Form.useForm();
console.log(editData,'editData')
return (
<Modal
title="路政信息"
@ -75,19 +75,21 @@ const LuzhengModel = ({ editData, check, visible, onCancel, dispatch }) => {
<DatePicker/>
</Form.Item>
<Form.Item name="roadname" label="执法道路" rules={[{ required: true, message: '请填写' }]}>
<Form.Item name="roadname" label="执法道路" rules={[{ required: true, message: '请填写' },{ max: 100, message: '不可超过一百个字符' }]}>
<Input/>
</Form.Item>
<Form.Item name="enforcementreslt" label="执法成果" rules={[{ required: true, message: '请填写' }]}>
<Form.Item name="enforcementreslt" label="执法成果" rules={[{ required: true, message: '请填写' },{ max: 100, message: '不可超过一百个字符' }]}>
<Input/>
</Form.Item>
<Form.Item name="picfile" label="执法图片">
<Uploads
maxFilesNum={1}
maxFilesNum={3}
fileTypes={['png','jpg','jpeg']}
maxFileSize={200}
fileList={editData?.picfile}
listType ={'picture-card'}
isedit={editData?true:false}
/>
</Form.Item>
</Form>

327
web/client/src/sections/fillion/components/uploads.js

@ -0,0 +1,327 @@
'use strict';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Spin, Upload, message, Modal, Card, Button } from 'antd';
import moment from 'moment';
import { PlusOutlined, UploadOutlined, CloseOutlined } from '@ant-design/icons';
class Uploads extends Component {
constructor(props) {
super(props);
this.ApiRoot = localStorage.getItem('tyApiRoot')
this.state = {
fileUploading: false,
fileList: [],
curPreviewPic: '',
delPicIng: false,
removeFilesList: []
};
}
dealName = (uploaded) => {
let realName = uploaded.split('/')[2]
let x1 = realName.split('.')
let x2 = x1[0].split('_')
let showName = `${x2[0]}.${x1[1]}`
return showName
}
setFileList = (value) => {
let defaultFileList = [];
defaultFileList = value.map((u, index) => {
// let fileUrl = `${this.ApiRoot}/${u.url}`;
let fileUrl = `${u.url}`;
return {
uid: -index - 1,
name: this.dealName(u.url),
status: 'done',
storageUrl: u.url,
url: fileUrl
};
});
// onChange(defaultFileList)
this.setState({
fileList: defaultFileList
});
};
componentDidMount () {
const { value } = this.props;
if (value) {
this.setFileList(value);
}
}
componentWillReceiveProps (np) {
const { dispatch, value: thisEditData, onChange } = this.props;
const { value: nextEditData, clearFileList } = np;
const setFileList = () => {
let defaultFileList = [];
defaultFileList = nextEditData.map((u, index) => {
// let fileUrl = `${this.ApiRoot}/${u.storageUrl}`;
let fileUrl = `${u.storageUrl}`;
return {
uid: -index - 1,
name: this.dealName(u.storageUrl),
status: 'done',
storageUrl: u.storageUrl,
url: fileUrl,
size: u.size || -1
};
});
this.setState({
fileList: defaultFileList
});
};
if (nextEditData && nextEditData.length) {
if (!thisEditData || !this.state.fileList.length) {
setFileList();
} else if (nextEditData.length != thisEditData.length) {
setFileList();
} else {
let repeat = true;
for (let i = 0; i < thisEditData.length; i++) {
if (thisEditData[i] != nextEditData[i]) {
repeat = false;
break;
}
}
if (!repeat) {
setFileList();
}
}
}
if (clearFileList) {
this.setState({
fileList: []
});
}
// else{
// this.setState({
// fileList:[],
// })
// }
}
render () {
const UploadPath = {
project: ['txt', 'dwg', 'doc', 'docx', 'xls', 'xlsx', 'pdf', 'png', 'jpg', 'rar', 'zip'],
report: ['doc', 'docx', 'xls', 'xlsx', 'pdf'],
data: ['txt', 'xls', 'xlsx'],
image: ['png', 'jpg', 'svg', 'jpeg'],
three: ['js'],
video: ['mp4']
};
/**
* uploadType string 主要区别文件上传路径 以及类型 web/routes/attachment/index.js UploadPath key 值为准默认 project
* disabled boolean 上传是否可用
* maxFilesNum number 最大上传数量
* fileTypes array[string] 可允许上传的文件类型
* maxFileSize number 单个文件最大大小 M
* listType antd upload 组件的属性
* onChange function 文件数量变化时候回调 返回文件
* value array[obj] 编辑数据 [{url:'xxx', [size:999]}]
* onStateChange function 文件状态改变回调函数 上传中 return { uploading:true/false }
*/
const {
uploadType,
disabled,
maxFilesNum,
fileTypes,
maxFileSize,
listType,
onChange,
value,
showUploadList,
onStateChange
} = this.props;
const { fileList, curPreviewPic, delPicIng, removeFilesList } = this.state;
const that = this;
let uploadType_ = uploadType || 'project';
let maxFilesNum_ = maxFilesNum || 1;
let defaultFileTypes = fileTypes || UploadPath[uploadType_];
const uploadProps = {
name: 'checkFile_',
multiple: false,
showUploadList: showUploadList || true,
action: `${this.ApiRoot}/attachments/${uploadType_}`,
listType: listType || 'text',
disabled: disabled,
beforeUpload: (file) => {
if (fileList.length >= maxFilesNum_) {
message.warning(`最多选择${maxFilesNum_}个文件上传`);
return false;
}
if (file.name.length > 60) {
message.warning(`文件名过长(大于60字符),请修改后上传`);
return false;
}
const extNames = file.name.split('.');
var reg = /^[\.\s\u4e00-\u9fa5a-zA-Z0-9_-]{0,}$/;
if (!reg.exec(file.name)) {
message.warning(`文件名包含除字母、汉字、数字、中划线、下划线之外的字符,请修改后上传`);
return false;
}
let isDAE = false;
if (extNames.length > 0) {
let fileType = extNames[extNames.length - 1].toLowerCase();
isDAE = defaultFileTypes.some((f) => f == fileType);
}
if (!isDAE) {
message.error(`只能上传 ${defaultFileTypes.join()} 格式的文件!`);
return false;
}
const isLt = file.size / 1024 / 1024 < (maxFileSize || 3);
if (!isLt) {
message.error(`文件必须小于${maxFileSize || 3}MB!`);
return false;
}
this.setState({
fileUploading: true
});
if (onStateChange) {
onStateChange({ uploading: true });
}
},
onChange (info) {
const status = info.file.status;
if (status === 'uploading') {
that.setState({
fileList: info.fileList
});
}
if (status === 'done') {
let { uploaded, url } = info.file.response;
let size = info.file.size;
let nextFileList = fileList;
nextFileList[nextFileList.length - 1] = {
uid: -moment().unix(),
name: that.dealName(uploaded),
status: 'done',
storageUrl: uploaded,
url: url,
size: size
};
onChange(nextFileList);
that.setState({
fileUploading: false,
fileList: nextFileList
});
if (onStateChange) {
onStateChange({ uploading: false });
}
} else if (status === 'error') {
that.setState({
fileUploading: false
});
message.error(`${info.file.name} 上传失败,请重试`);
if (onStateChange) {
onStateChange({ uploading: false });
}
}
},
onRemove (file) {
let nextFileList = [];
fileList.map((f, i) => {
if (f.uid != file.uid) {
nextFileList.push(f);
}
});
let nextRemoveFiles = removeFilesList.concat([file.storageUrl]);
if (curPreviewPic == file.url) {
that.setState({
curPreviewPic: ''
});
}
onChange(nextFileList);
that.setState({
fileList: nextFileList,
removeFilesList: nextRemoveFiles
});
},
onPreview (file) {
let filePostfix = file.url.split('.').pop();
filePostfix = filePostfix.toLowerCase();
if (UploadPath.image.some((img) => img == filePostfix)) {
that.setState({
curPreviewPic: file.url
});
} else {
message.warn('仅支持图片预览');
}
}
};
let fileList_ = fileList
// .map(f => {
// if (f.storageUrl) {
// let realName = f.storageUrl.split('/').pop()
// if (f.name != realName) {
// f.name = realName
// }
// }
// return f
// })
return (
<div>
<Spin spinning={delPicIng}>
<Upload {...uploadProps} fileList={fileList_}>
{
disabled ? (
''
) :
listType == 'picture-card' ?
(
fileList.length >= maxFilesNum_ ? null : (
<div style={{}}>
<PlusOutlined />
<div>上传图片</div>
</div>
)
) : (
<Button disabled={fileList.length >= maxFilesNum_} icon={<UploadOutlined />}> 文件上传 </Button>
)
}
</Upload>
{
curPreviewPic ? (
<Card
bodyStyle={{
padding: 8
}}
>
<div style={{ marginBottom: 8 }} >
<span>文件预览</span>
<span
style={{ float: 'right' }}
onClick={() => { this.setState({ curPreviewPic: '' }); }}
>
<CloseOutlined style={{ fontSize: 20 }} />
</span>
</div>
<img style={{ width: '100%' }} src={curPreviewPic}></img>
</Card>
) : ''
}
</Spin>
</div>
);
}
}
function mapStateToProps (state) {
const { auth } = state
return {
user: auth.user
};
}
export default connect(mapStateToProps)(Uploads);

35
web/client/src/sections/fillion/containers/luzheng.js

@ -38,6 +38,7 @@ function Assess(props) {
const [datasource,setdatasource] = useState([])
const [dateRange, setDateRange] = useState(['1970-1-1', '2099-12-31']);
const { RangePicker } = DatePicker
const [total,settotal]= useState(0)
const [editAble, setEditAble] = useState(user?.username !== 'SuperAdmin' && user?.userResources?.find(i => i.resourceId === 'ASSESSMANAGE')?.isshow === "true" ? true : '')
useEffect(() => {
@ -50,9 +51,11 @@ function Assess(props) {
const getData = () => {
setLoading(true)
dispatch(getRoadadministration(query)).then(res => {
console.log(query,'query')
dispatch(getRoadadministration({...query})).then(res => {
if(res?.success){
setdatasource(res?.payload?.data?.rows)
settotal(res?.payload?.data?.count)
setLoading(false)
}
})
@ -63,8 +66,8 @@ function Assess(props) {
<div style={{ marginBottom: '20px', display: 'flex', justifyContent: 'space-between' }}>
<Form layout="inline" onFinish={(v) => {
setQuery({ ...query, unit: v.unit,startTime : moment(v?.time[0]).startOf('day').format('YYYY-MM-DD HH:mm:ss'),
endTime :moment(v?.time[1]).add(1, 'days').endOf('day').format('YYYY-MM-DD HH:mm:ss') })
setQuery({ ...query, page:1,unit: v.unit,startTime : v?.time && moment(v?.time[0]).startOf('day').format('YYYY-MM-DD HH:mm:ss'),
endTime : v?.time && moment(v?.time[1]).add(1, 'days').endOf('day').format('YYYY-MM-DD HH:mm:ss') })
}}>
@ -106,12 +109,20 @@ function Assess(props) {
dataIndex: 'picfile',
key: 'picfile',
render:(t,r)=>{
if(r?.picfile && r?.picfile?.length!==0){
return r?.picfile?.map(i=>{
return <Image
width={200}
src={i?.storageUrl}
/>
return <span style={{marginRight:10}}>
<Image src={i?.url} width={80}/>
</span>
})
}else{
return '--'
}
}
},
@ -128,8 +139,8 @@ function Assess(props) {
<Button type="link" onClick={() => {
setAssessModalVisible(true)
setEditData(record)
disabled = { editAble }
}}>编辑</Button>
}} disabled = { editAble }>编辑</Button>
<Popconfirm
title="确定删除此条数据吗?"
onConfirm={() => {
@ -137,7 +148,8 @@ function Assess(props) {
dispatch(delRoadadministration(record.id)).then(res => {
setLoading(false)
if (res.success) {
getData()
setQuery({...query, page: 1, pageSize: 10, limit: 10})
// getData(page)
}
})
}}
@ -150,11 +162,12 @@ function Assess(props) {
dataSource={datasource || []}
loading={loading}
pagination={{
total: assess?.count || 0,
total: total || 0,
pageSize: 10,
defaultPageSize: 10,
showSizeChanger: false,
onChange: (page, pageSize) => {
console.log(page,'page')
setQuery({
...query,
page, limit: pageSize

102
web/client/src/sections/quanju/containers/footer/guanli/index.js

@ -1,18 +1,20 @@
import React, { useEffect, useState } from 'react';
import { connect } from 'react-redux';
import { Carousel, Tooltip } from 'antd'
import { Carousel, Tooltip, Image } from 'antd'
import AutoRollComponent from '../build/AutoRollComponent'
import VideoMonitor from '../build/videoMonitor'
import Module from '../../public/module'
import moment from 'moment'
import LeftItem from './LeftItem'
import { getjiandmanage, getjiandetail } from '../../../actions/example'
import { getRoadadministration } from '../../../../fillion/actions/luzheng'
import './style.less'
import NoData from '../../public/noData';
const Guanli = (props) => {
const { dispatch } = props
const [leftDatas, setleftDatas] = useState([])
const [rightDatas, setrightDatas] = useState([])
const [rightitemlist, setrightitemlist] = useState()
const [rightitemlist, setrightitemlist] = useState([])
const requestleftDatas = async () => {
const res = await dispatch(getjiandmanage())
res.payload.data?.sort((a, b) => {
@ -50,48 +52,80 @@ const Guanli = (props) => {
// console.log(d2,'完美')
// console.log(res.payload.data,'嘿嘿嘿')
}
const roadManagement = async () => {
await dispatch(getRoadadministration({})).then(res => {
if (res.success) {
setrightitemlist(res.payload.data?.rows || [])
}
})
}
useEffect(() => {
requestleftDatas();
requestRightDatas()
// requestRightDatas()
roadManagement()
}, [])
// let datalist = newArry(30)
// datalist.fill({licensePlate:"赣A44454",overrunRate:"30%",fine:"200元",processingTime:"2020年4月1日"})
// const content = (
// );
const renderContent = () => {
// console.log(rightitemlist);
return <div style={{ height: "100%" }}>
{rightitemlist && rightitemlist.length !== 0 ? rightitemlist?.map(({ id, licensePlate, overrunRate, fine, processingTime, deductPoints, nameOfInspectionPoint }, index) => {
{rightitemlist && rightitemlist.length !== 0 ? rightitemlist?.map(({ enforcementdate, enforcementreslt, roadname, picfile }, index) => {
if (index < 120) {
return <div key={index} className='guanli-right-item'>
<Tooltip title={<div className='popover-content'>
<div style={{ width: "100%", height: "100%", marginTop: "0" }}>
<div style={{ width: '100%', height: "100%", marginTop: "0", display: "flex" }}>
{/* <img src='/assets/images/leadership/beijinglan.png' style={{ width: "100%", height: "100%" }} /> */}
<div style={{ position: "absolute", top: "0", width: "50%", padding: "20px" }}>
<img src='/assets/images/leadership/yuanxing.png' style={{ width: "100%", height: "100%" }} />
<p style={{ color: "#09BAFF", position: "absolute", top: "42%", left: "27%", fontSize: "29px", fontFamily: "YouSheBiaoTiHei" }}>{overrunRate ? overrunRate.toFixed(2) : 0}%{/* {item.overrunRate ? item.overrunRate + "%" : "--"} */}</p>
<p style={{ color: "rgba(216,240,255,0.8)", position: "absolute", top: "60%", left: "43%", fontSize: "14px" }}>超限</p>
</div>
<div style={{ position: "absolute", top: "0", width: "50%", left: "50%", top: '5px' }}>
<p style={{ color: "rgba(216,240,255,0.8)", marginTop: "30px", fontSize: "14px", fontFamily: "PingFangSC-Regular, PingFang SC" }}>车牌号<span style={{ color: "#EEF4FF", marginLeft: "33px", fontFamily: " PingFangSC-Medium, PingFang SC" }}>{licensePlate}{/* {item.licensePlate} */}</span></p>
<p style={{ color: "rgba(216,240,255,0.8)", fontSize: "14px", fontFamily: "PingFangSC-Regular, PingFang SC" }}>检测点<span style={{ color: "#EEF4FF", marginLeft: "33px", fontFamily: " PingFangSC-Medium, PingFang SC" }}>{nameOfInspectionPoint}</span></p>
<p style={{ color: "rgba(216,240,255,0.8)", fontSize: "14px", fontFamily: "PingFangSC-Regular, PingFang SC" }}>处罚<span style={{ color: "#FF0001", marginLeft: "50px", fontFamily: " PingFangSC-Medium, PingFang SC" }}>{deductPoints ? `-${deductPoints}` : ""}-{fine}{fine ? "元" : ""}{/* {item.deductPoints ? "-" + item.deductPoints + "分" : ""}{item.deductPoints && item.fine ? "和" : ""}{item.fine ? "-" + item.fine + "元" : ""}{item.deductPoints || item.fine ? "" : "--"} */}</span></p>
<p style={{ color: "rgba(216,240,255,0.8)", fontSize: "14px", fontFamily: "PingFangSC-Regular, PingFang SC" }}>日期<span style={{ color: "#EEF4FF", marginLeft: "50px", fontFamily: " PingFangSC-Medium, PingFang SC" }}>{processingTime}{/* {item.processingTime ? item.processingTime : "--"} */}</span></p>
{picfile?.length > 0 ? <Carousel autoplay style={{ width: 200, height: 200, margin: "20px 0px 0px 20px" }}>
{picfile?.map(v => <Image
width={200}
src={`/_file-server/${v.storageUrl}`}
/>)}
</Carousel>
: <img src="/" style={{
width: 200, height: 200, margin: "20px 0px 0px 20px", display: 'inline-block', borderRight: "1px solid #FFF",
}} />
}
<div style={{ width: 240, marginLeft: 20, marginTop: 20, display: "flex", flexDirection: "column", justifyContent: "space-around" }}>
<p style={{ color: "rgba(216,240,255,0.8)", fontSize: "14px", fontFamily: "PingFangSC-Regular, PingFang SC", display: "flex" }}>
执法日期:<span style={{
color: "#EEF4FF", marginLeft: "10px", fontFamily: " PingFangSC-Medium, PingFang SC",
overflow: 'hidden', whiteSpace: "nowrap", textOverflow: "ellipsis"
}}>
{enforcementdate && moment(enforcementdate).format("YYYY-MM-DD") || "--"}
</span></p>
<p style={{ color: "rgba(216,240,255,0.8)", fontSize: "14px", fontFamily: "PingFangSC-Regular, PingFang SC", display: "flex" }}>
执法道路:<span style={{
color: "#EEF4FF", marginLeft: "10px", fontFamily: " PingFangSC-Medium, PingFang SC",
overflow: 'hidden', whiteSpace: "nowrap", textOverflow: "ellipsis", display: 'inline-block', width: 160
}}>
{roadname}
</span></p>
<p style={{ color: "rgba(216,240,255,0.8)", fontSize: "14px", fontFamily: "PingFangSC-Regular, PingFang SC", display: "flex" }}>
执法成果:<span style={{
color: "#EEF4FF", marginLeft: "10px", fontFamily: " PingFangSC-Medium, PingFang SC",
overflow: 'hidden', whiteSpace: "nowrap", textOverflow: "ellipsis", display: 'inline-block', width: 160
}}>
{enforcementreslt}</span></p>
</div>
</div>
</div>}
placement="leftTop"
overlayStyle={{ minWidth: 400, minHeight: 212, padding: 0, margin: 0, backgroundImage: `url(../../../../../assets/images/leadership/beijinglan.png)` }}
overlayStyle={{ minWidth: 500, minHeight: 200, paddingTop: 10, margin: 0, backgroundImage: `url(../../../../../assets/images/leadership/beijinglan.png)` }}
overlayClassName='popover'
>
<div style={{ width: '100%', height: '100%', display: 'flex' }}>
<span>{licensePlate}</span>
<span>{overrunRate}%</span>
<span>{deductPoints ? `-${deductPoints}` : ""}-{fine}{fine ? "元" : ""}</span>
<span>{processingTime}</span>
<div style={{ width: '100%', height: '100%', display: 'flex', color: "#FFF" }}>
<div style={{ width: '50%', textAlign: "center", }}>{enforcementdate && moment(enforcementdate).format("YYYY-MM-DD") || "--"}</div>
<div title={enforcementreslt} style={{ width: '50%', textAlign: "center", overflow: 'hidden', whiteSpace: "nowrap", textOverflow: "ellipsis" }}>{enforcementreslt}</div>
</div>
</Tooltip>
</div>
@ -121,22 +155,26 @@ const Guanli = (props) => {
</Module>
</div>
<div className='guanli-right'>
<Module style={{ height: "100%" }} title="治超详情" customize={true}>
<div className="guanli-right-top">
<Module style={{ height: "100%" }} title="道路隐患排查治理" customize={true}>
{/* <div className="guanli-right-top">
<img src="/assets/images/quanju/zhicaolog.png"></img>
<span>已处理</span>
<span>{rightDatas?.processed || 0}</span>
<span></span>
</div>
<div className='guanli-right-title'>
</div> */}
{/* <div className='guanli-right-title'>
<span>车牌号</span>
<span>超限</span>
<span>处罚</span>
<span>处理日期</span>
</div> */}
o<div style={{ width: "100%", display: "flex", color: "#FFF" }}>
<div style={{ width: '50%', textAlign: "center" }}>执法日期</div>
<div style={{ width: '50%', textAlign: "center", }}>执法成果</div>
</div>
{rightitemlist && rightitemlist.length !== 0 ? <AutoRollComponent content={renderContent()}
containerStyle={{ position: "relative", height: "90%", }}
divHeight={"100%"} divId={"chart-overview-deviceList"} /> : <NoData style={{ height: "70%" }} />}
divHeight={"100%"} divId={"chart-overview-deviceList"} /> : <NoData style={{ height: "20%" }} />}
</Module>
</div>
</>

Loading…
Cancel
Save