peng.peng 10 months ago
parent
commit
18078164da
  1. 2
      api/.vscode/launch.json
  2. 90
      api/app/lib/controllers/images/index.js
  3. 99
      api/app/lib/controllers/report/index.js
  4. 44
      api/app/lib/models/car_images.js
  5. 9
      api/app/lib/models/road_spot_check_preview.js
  6. 10
      api/app/lib/routes/images/index.js
  7. 1
      api/package.json
  8. 2
      api/sequelize-automate.config.js
  9. BIN
      scripts/1.4.0/data/2_update_road_data_无需执行/no_exist_village.txt
  10. 16
      scripts/1.4.2/1.create_car_images.sql
  11. 5
      scripts/1.4.2/5.alter_road_spot_check_preview.sql
  12. 3
      weapp/project.config.json
  13. 1
      weapp/src/app.config.js
  14. 8
      weapp/src/packages/maintenanceSpotCheck/index.jsx
  15. 20
      weapp/src/packages/maintenanceSpotCheck/spotChange/index.jsx
  16. 3
      weapp/src/packages/maintenanceSpotCheck/spotCheckRoad/index.config.js
  17. 99
      weapp/src/packages/maintenanceSpotCheck/spotCheckRoad/index.jsx
  18. 29
      weapp/src/packages/maintenanceSpotCheck/spotCheckRoad/index.scss
  19. 2
      weapp/src/packages/maintenanceSpotCheck/spotCheckRoadDetail/index.config.js
  20. 136
      weapp/src/packages/maintenanceSpotCheck/spotCheckRoadDetail/index.jsx
  21. 28
      weapp/src/packages/maintenanceSpotCheck/spotCheckRoadDetail/index.scss
  22. 25
      weapp/src/packages/maintenanceSpotCheck/startSpotCheck/index.jsx
  23. BIN
      web/client/src/components/README.txt
  24. 15
      web/client/src/sections/fillion/actions/carimages.js
  25. 124
      web/client/src/sections/fillion/containers/carimages.js
  26. 20
      web/client/src/sections/fillion/containers/maintenanceSpotCheck-new.js
  27. 17
      web/client/src/sections/fillion/nav-item.js
  28. 35
      web/client/src/sections/fillion/routes.js
  29. 14
      web/client/src/utils/webapi.js
  30. 1
      web/package.json

2
api/.vscode/launch.json

@ -17,7 +17,7 @@
"-f http://localhost:13400",
// "-g postgres://FashionAdmin:123456@10.8.16.184:5432/sihaogonglu",
// "-g postgres://postgres:123@10.8.30.32:5432/highways4good",
"-g postgres://postgres:123@10.8.30.32:5432/highway4test",
"-g postgres://postgres:123@10.8.30.32:5432/highwaytest1226",
// "-g postgres://FashionAdmin:123456@10.8.30.156:5432/highway4goodn0728",
"--qnak XuDgkao6cL0HidoMAPnA5OB10Mc_Ew08mpIfRJK5",
"--qnsk yewcieZLzKZuDfig0wLZ9if9jKp2P_1jd3CMJPSa",

90
api/app/lib/controllers/images/index.js

@ -0,0 +1,90 @@
'use strict'
const request = require('superagent')
const moment = require('moment')
// function getFileCarImages (opts) {
// return async function (ctx, next) {
// let error = { message: '文件夹名称更新失败' }
// const models = ctx.fs.dc.models
// const { page, limit, } = ctx.query
// try {
// let searchWhere = {}
// let option = {
// where: searchWhere,
// order: [["id", "desc"]],
// }
// option.where = searchWhere
// let limit_ = limit || 10
// let page_ = page || 1
// let offset = (page_ - 1) * limit_
// if (limit && page) {
// option.limit = limit_
// option.offset = offset
// }
// const res = await models.CarImages.findAndCount(option)
// error = null
// } catch (err) {
// ctx.status = 500
// ctx.body = { detail: err, ...error }
// }
// if (error) {
// ctx.status = 400
// ctx.body = { ...error }
// } else {
// ctx.status = 200
// ctx.body = { message: '文件夹名称更新成功' }
// }
// }
// }
function getFileCarImages (opts) {
return async function (ctx, next) {
const models = ctx.fs.dc.models
const { page, limit, } = ctx.query
const Op = ctx.fs.dc.ORM.Op
let errMsg = { message: '获取图片失败' }
try {
let searchWhere = {}
let option = {
where: searchWhere,
order: [["id", "ASC"]],
}
option.where = searchWhere
let limit_ = limit || 10
let page_ = page || 1
let offset = (page_ - 1) * limit_
if (limit && page) {
option.limit = limit_
option.offset = offset
}
const res = await models.CarImages.findAndCount(option)
ctx.status = 200
ctx.body = res
} catch (error) {
ctx.status = 400
ctx.body = errMsg
}
}
}
module.exports = {
getFileCarImages
}

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

@ -540,13 +540,17 @@ async function roadSpotPrepare (ctx) {
let lastCountyPercentage = 0 // 最后一次的县道百分比
let lastCountyRoadIds = [] // 上次查得的县道id
let lastTownRoadIds = [] // 上次查得的乡镇道id
let lastVillageRoadRoadIds = [] // 上次查得的村道id
let lastVillageRoadRoadIds = [-1] // 上次查得的村道id
let lastVillageIds = []
let lastAbstractVillage = {}
let gather = [] //汇总
if (lastSpotRes) {
lastCountyPercentage = lastSpotRes.countyPercentage
lastCountyRoadIds = lastSpotRes.countyRoadId || []
lastAbstractVillage = lastSpotRes.lastAbstractVillage || {}
let lastCounty = await models.RoadSpotCheckPreview.findAll({
where: {
@ -558,9 +562,12 @@ async function roadSpotPrepare (ctx) {
})
if (lastCounty) {
let countyNnmter = 0
lastCounty.forEach(d => {
lastTownRoadIds = lastTownRoadIds.concat(d.townshipRoadId) || []
if (countyNnmter < (100 - (countyPercentage == 75 ? 50 : 25))) {
lastTownRoadIds = lastTownRoadIds.concat(d.townshipRoadId) || []
countyNnmter += (d.countyPercentage == 75 ? 50 : 25)
}
})
}
@ -574,10 +581,14 @@ async function roadSpotPrepare (ctx) {
})
if (lastVillage) {
let villageNnmter = 0
lastVillage.forEach(d => {
lastVillageRoadRoadIds = lastVillageRoadRoadIds.concat(d.villageRoadId) || []
lastVillageIds = lastVillageIds.concat(d.villageId) || []
if (villageNnmter < (100 - (countyPercentage == 75 ? 20 : 10))) {
lastVillageRoadRoadIds = lastVillageRoadRoadIds.concat(d.villageRoadId) || []
lastVillageIds = lastVillageIds.concat(d.villageId) || []
villageNnmter += (d.countyPercentage == 75 ? 20 : 10)
}
})
}
@ -627,6 +638,7 @@ async function roadSpotPrepare (ctx) {
async function spotRoadId (key, lastRoadIds, targetMileage, otherWhere = [], villageIdList = []) {
let spotRoadIds = []
let accumulationMileage = 0
let last = null
async function filterRoad (otherWhere, getRepeat = true) {
@ -671,6 +683,7 @@ async function roadSpotPrepare (ctx) {
], false)
spotVillageIds.push(villageId)
last = villageId
if (accumulationMileage >= targetMileage) {
break;
@ -678,13 +691,27 @@ async function roadSpotPrepare (ctx) {
}
if (accumulationMileage < targetMileage) {
// 还小于 说明没取够
await filterRoad(otherWhere, true)
// await filterRoad(otherWhere, true)
for await (let villageId of villageIdList.reverse()) {
await filterRoad([
...otherWhere,
`village_id=${villageId}`
], true)
spotVillageIds.push(villageId)
last = villageId
if (accumulationMileage >= targetMileage) {
break;
}
}
}
} else {
await filterRoad(otherWhere, true)
}
return [spotRoadIds, accumulationMileage]
return [spotRoadIds, accumulationMileage, last]
}
let villageMil = 0, townMil = 0, countryMil = 0;
@ -723,6 +750,8 @@ async function roadSpotPrepare (ctx) {
let spotVillageIds = []
let allTownCodeResTown = []
let lastEndVillage = {} //获取每个乡镇最后一个被抽取的村
for await (let t of allTownCodeRes) {
// 遍历每个乡镇并抽取
let otherWhere = [`township_code='${t.township_code}'`]
@ -743,26 +772,36 @@ async function roadSpotPrepare (ctx) {
const villageRoadNeedMileage = villageRoadTotalMileage * (countyPercentage == 75 ? 20 : 10) / 100
let spotFirstVillageId = -1
// 随机选取一个不在上次查过的村
let villageRes = await sequelize.query(`
SELECT id FROM village
WHERE township_code = '${t.township_code}'
${lastVillageIds.length ? `AND id NOT IN (
${lastVillageIds.map(item => `'${item}'`).join(',')},-1
)`: ''}
ORDER BY RANDOM()
LIMIT 1
`, { type: QueryTypes.SELECT });
if (!villageRes.length) {
// 没有村了,随机选一个
let villageRes = []
if (lastAbstractVillage[t.township_code]) {
} else {
// 随机选取一个不在上次查过的村
villageRes = await sequelize.query(`
SELECT id FROM village
WHERE township_code = '${t.township_code}'
ORDER BY RANDOM()
LIMIT 1
`, { type: QueryTypes.SELECT });
SELECT id FROM village
WHERE township_code = '${t.township_code}'
${lastVillageIds.length ? `AND id NOT IN (
${lastVillageIds.map(item => `'${item}'`).join(',')},-1
)`: ''}
ORDER BY RANDOM()
LIMIT 1
`, { type: QueryTypes.SELECT });
if (!villageRes.length) {
// 没有村了,随机选一个
villageRes = await sequelize.query(`
SELECT id FROM village
WHERE township_code = '${t.township_code}'
ORDER BY RANDOM()
LIMIT 1
`, { type: QueryTypes.SELECT });
}
}
if (villageRes.length) {
if (lastAbstractVillage[t.township_code]) {
spotVillageIds.push(lastAbstractVillage[t.township_code])
spotFirstVillageId = lastAbstractVillage[t.township_code]
} else if (villageRes.length) {
spotVillageIds.push(villageRes[0].id)
spotFirstVillageId = villageRes[0].id
} else {
@ -793,6 +832,8 @@ async function roadSpotPrepare (ctx) {
let spotVillageRoadIdsArr = await spotRoadId('村', lastVillageRoadRoadIds, villageRoadNeedMileage, otherWhere, villageCheckIdList)
let spotVillageRoadIds_ = spotVillageRoadIdsArr[0]
let villageMil_ = spotVillageRoadIdsArr[1]
lastEndVillage[t.township_code] = spotVillageRoadIdsArr[2]
spotVillageRoadIds = spotVillageRoadIds.concat(spotVillageRoadIds_)
if (villageMil_) villageMil += villageMil_
@ -808,6 +849,8 @@ async function roadSpotPrepare (ctx) {
villageDifferenceValue: villageMil_ - villageRoadNeedMileage
})
}
for (let index = 0; index < town.length; index++) {
@ -846,7 +889,8 @@ async function roadSpotPrepare (ctx) {
villageMil,
townMil,
countryMil,
gather
gather,
lastAbstractVillage: lastEndVillage
})
@ -1000,6 +1044,9 @@ async function roadSpotDetail (ctx) {
...(keyword ? { routeName: { $ilike: `%${keyword}%` } } : {}),
del: false,
},
include: [{
model: models.Village,
}]
}, {
model: models.RoadSpotCheckPreview,
attributes: ['id'],

44
api/app/lib/models/car_images.js

@ -0,0 +1,44 @@
/* eslint-disable*/
'use strict';
module.exports = dc => {
const DataTypes = dc.ORM;
const sequelize = dc.orm;
const CarImages = sequelize.define("carImages", {
id: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: true,
field: "id",
autoIncrement: true,
unique: "car_images_id_uindex"
},
url: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: "图片路径",
primaryKey: false,
field: "url",
autoIncrement: false
},
time: {
type: DataTypes.DATE,
allowNull: true,
defaultValue: null,
comment: "时间",
primaryKey: false,
field: "time",
autoIncrement: false
}
}, {
tableName: "car_images",
comment: "",
indexes: []
});
dc.models.CarImages = CarImages;
return CarImages;
};

9
api/app/lib/models/road_spot_check_preview.js

@ -114,6 +114,15 @@ module.exports = dc => {
field: "gather",
autoIncrement: false
},
lastAbstractVillage:{
type: DataTypes.JSONB,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "last_abstract_village",
autoIncrement: false
}
}, {
tableName: "road_spot_check_preview",
comment: "",

10
api/app/lib/routes/images/index.js

@ -0,0 +1,10 @@
'use strict'
const images = require('../../controllers/images')
module.exports = function (app, router, opts, panCode) {
router.get('/car/images', images.getFileCarImages(opts))
}

1
api/package.json

@ -36,6 +36,7 @@
"redis": "^3.1.2",
"request": "^2.88.2",
"rimraf": "^3.0.2",
"sequelize-automate-freesun": "^1.2.2",
"superagent": "^3.5.2",
"swagger-jsdoc": "^6.1.0",
"uuid": "^3.3.2",

2
api/sequelize-automate.config.js

@ -35,7 +35,7 @@ module.exports = {
dir: './app/lib/models', // 指定输出 models 文件的目录
typesDir: 'models', // 指定输出 TypeScript 类型定义的文件目录,只有 TypeScript / Midway 等会有类型定义
emptyDir: false, // !!! 谨慎操作 生成 models 之前是否清空 `dir` 以及 `typesDir`
tables: ['road_spot_check_preview'], // 指定生成哪些表的 models,如 ['user', 'user_post'];如果为 null,则忽略改属性
tables: ['car_images'], // 指定生成哪些表的 models,如 ['user', 'user_post'];如果为 null,则忽略改属性
skipTables: [], // 指定跳过哪些表的 models,如 ['user'];如果为 null,则忽略改属性
tsNoCheck: false, // 是否添加 `@ts-nocheck` 注释到 models 文件中
ignorePrefix: [], // 生成的模型名称忽略的前缀,因为 项目中有以下表名是以 t_ 开头的,在实际模型中不需要, 可以添加多个 [ 't_data_', 't_',] ,长度较长的 前缀放前面

BIN
scripts/1.4.0/data/2_update_road_data_无需执行/no_exist_village.txt

Binary file not shown.

16
scripts/1.4.2/1.create_car_images.sql

@ -0,0 +1,16 @@
create table car_images
(
id serial
constraint car_images_pk
primary key,
url varchar,
time timestamptz
);
comment on column car_images.url is '图片路径';
comment on column car_images.time is '时间';
create unique index car_images_id_uindex
on car_images (id);

5
scripts/1.4.2/5.alter_road_spot_check_preview.sql

@ -0,0 +1,5 @@
alter table road_spot_check_preview
add last_abstract_village jsonb;
comment on column road_spot_check_preview.last_abstract_village is '每个乡上次抽查的最后一个村';

3
weapp/project.config.json

@ -30,7 +30,8 @@
"disableUseStrict": false,
"useCompilerPlugins": false,
"minifyWXML": true,
"condition": false
"condition": false,
"ignoreDevUnusedFiles": false
},
"compileType": "miniprogram",
"libVersion": "2.25.1",

1
weapp/src/app.config.js

@ -14,6 +14,7 @@ export default {
'video/index',
'maintenanceSpotCheck/index',
'maintenanceSpotCheck/startSpotCheck/index',
'maintenanceSpotCheck/spotCheckRoad/index',
'maintenanceSpotCheck/spotCheckRoadDetail/index',
'maintenanceSpotCheck/spotChange/index',
]

8
weapp/src/packages/maintenanceSpotCheck/index.jsx

@ -90,13 +90,13 @@ function Index() {
{roadSpotList.length ? roadSpotList.map((item, index) => <View
key={item.id}
className='card'
onClick={() => navigateTo(`/packages/maintenanceSpotCheck/spotCheckRoadDetail/index?item=${encodeURIComponent(JSON.stringify(item))}&isOld=${index !== 0}`
onClick={() => navigateTo(`/packages/maintenanceSpotCheck/spotCheckRoad/index?item=${encodeURIComponent(JSON.stringify(item))}&isOld=${index !== 0}`
)}
>
<View className='item'>抽查县道比例%{item.countyPercentage}</View>
<View className='item'>抽查县道{item.spotCountyRoadCount}</View>
<View className='item'>抽查乡道{item.spotTownRoadCount}</View>
<View className='item'>抽查村道{item.spotVillageRoadCount}</View>
<View className='item'>抽查县道公里{item.countryMil?.toFixed(3)}</View>
<View className='item'>抽查乡道公里{item.townMil?.toFixed(3)}</View>
<View className='item'>抽查村道公里{item.villageMil?.toFixed(3)}</View>
<View className='item'>抽查日期{moment(item.date).format('YYYY-MM-DD')}</View>
</View>) : <View style={{ paddingTop: 100 }}><NoData /></View>}
</ScrollView>

20
weapp/src/packages/maintenanceSpotCheck/spotChange/index.jsx

@ -21,8 +21,8 @@ function Index() {
routeName: '',
routeCode: '',
sectionNo: '',
startingPlaceName: '',
stopPlaceName: '',
startStation: '',
stopStation: '',
})
const [routeCodeDisabled, setRouteCodeDisabled] = useState(true);
const [sectionNoDisabled, setSectionNoDisabled] = useState(true);
@ -138,11 +138,11 @@ function Index() {
&& nextValue.routeCode == s.routeCode
&& nextValue.sectionNo == s.sectionNo
)
nextValue.startingPlaceName = find?.startingPlaceName
nextValue.stopPlaceName = find?.stopPlaceName
nextValue.startStation = find?.startStation
nextValue.stopStation = find?.stopStation
} else {
nextValue.startingPlaceName = ''
nextValue.stopPlaceName = ''
nextValue.startStation = ''
nextValue.stopStation = ''
}
setChecked(nextValue)
@ -254,12 +254,12 @@ function Index() {
</View>
</View>
<View className='cell'>
<View className='title'>起点地名</View>
<View className='content'>{checked.startingPlaceName}</View>
<View className='title'>起点桩号</View>
<View className='content'>{checked.startStation}</View>
</View>
<View className='cell'>
<View className='title'>止点地名</View>
<View className='content'>{checked.stopPlaceName}</View>
<View className='title'>止点桩号</View>
<View className='content'>{checked.stopStation}</View>
</View>
<AtButton

3
weapp/src/packages/maintenanceSpotCheck/spotCheckRoad/index.config.js

@ -0,0 +1,3 @@
export default {
navigationBarTitleText: '抽查详情'
}

99
weapp/src/packages/maintenanceSpotCheck/spotCheckRoad/index.jsx

@ -0,0 +1,99 @@
import React, { useEffect, useState } from 'react'
import Taro, { useRouter, useDidShow } from '@tarojs/taro'
import { View } from '@tarojs/components'
import { AtButton, AtSearchBar } from 'taro-ui'
import { NoData } from '@/components/index'
import Skeleton from '../components/skeleton'
import moment from 'moment'
import request from '@/services/request'
import { getRoadSpotDetail } from '@/services/api'
import './index.scss'
function Index() {
const { item, isOld } = useRouter().params
const spotItem = item ? JSON.parse(decodeURIComponent(item)) : null
const [keyword, setKeyword] = useState('')
const [roadDetailList, setRoadDetailList] = useState([])
const [isNoData, setIsNoData] = useState(false)
useDidShow(() => {
getDetail()
})
const getDetail = () => {
if (spotItem) {
Taro.showLoading({ title: '加载中' })
request.get(`${getRoadSpotDetail()}?previewId=${spotItem.id}&keyword=${keyword}`).then(res => {
Taro.hideLoading()
if (res.statusCode === 200) {
setRoadDetailList(res.data)
} else {
Taro.showToast({ title: '获取详情失败', icon: 'error' })
}
if (res.data?.length) {
setIsNoData(false)
} else {
setIsNoData(true)
}
})
}
}
const renderList = () => {
return roadDetailList.length ? roadDetailList.map(item => <View key={item.id} className='card'>
<View className='item'>道路类型{item.road?.level ? (item.road?.level + '道') : '--'}</View>
<View className='item'>路线名称{item.road?.routeName || '--'}</View>
<View className='item at-row'>
<View className='at-col-6'>路线代码{item.road?.routeCode || '--'}</View>
<View className='at-col-6'>路段序号{item.road?.sectionNo || '--'}</View>
</View>
<View className='item at-row'>
<View className='at-col-6'>起点地名{item.road?.startingPlaceName || '--'}</View>
<View className='at-col-6'>止点地名{item.road?.stopPlaceName || '--'}</View>
</View>
<View className='item'>里程{item.road?.chainageMileage || '--'}</View>
<View className='item at-row'>
<View className='at-col-6'>养护次数{item.maintenanceCount}</View>
<View className='at-col-3'>
<AtButton
className='edit-btn'
type='primary'
size='small'
onClick={() => Taro.navigateTo({ url: `/packages/maintenanceSpotCheck/spotCheckRoadDetail/index?detail=${encodeURIComponent(JSON.stringify(item))}` })}
>详情</AtButton>
</View>
<View className='at-col-3'>
<AtButton
className='edit-btn'
type='primary'
size='small'
onClick={() => Taro.navigateTo({ url: `/packages/maintenanceSpotCheck/spotChange/index?detail=${encodeURIComponent(JSON.stringify(item))}&spot=${encodeURIComponent(JSON.stringify(spotItem))}` })}
disabled={
isOld === 'true' ||
item.roadSpotCheckPreview?.roadSpotCheckChangeLogs?.some(l => l.changeRoadId == item.roadId)
}
>调整</AtButton>
</View>
</View>
</View>) : <Skeleton length={3} />
}
const renderNoData = () => {
return <View style={{ marginTop: 100 }}><NoData /></View>
}
return (<View className='page'>
<AtSearchBar
placeholder='道路名称关键字'
showActionButton
value={keyword}
onChange={v => setKeyword(v)}
onActionClick={getDetail}
/>
<View className='top flex'>抽查日期{moment(spotItem.date).format('YYYY-MM-DD')}</View>
{isNoData ? renderNoData() : renderList()}
</View>)
}
export default Index

29
weapp/src/packages/maintenanceSpotCheck/spotCheckRoad/index.scss

@ -0,0 +1,29 @@
.page {
background-color: #fff;
height: 100vh;
font-size: 28px;
padding-bottom: 40px;
.top {
height: 90px;
}
.card {
padding: 20px;
border: gainsboro 1px solid;
border-radius: 10px;
background-color: #fff;
box-shadow: 10px 10px 5px rgb(219, 218, 218);
margin: 0 0 20px 20px;
width: calc(100% - 40px);
box-sizing: border-box;
.item {
padding: 10px 0;
.edit-btn {
width: 100px;
}
}
}
}

2
weapp/src/packages/maintenanceSpotCheck/spotCheckRoadDetail/index.config.js

@ -1,3 +1,3 @@
export default {
navigationBarTitleText: '抽查详情'
navigationBarTitleText: '抽查道路详情'
}

136
weapp/src/packages/maintenanceSpotCheck/spotCheckRoadDetail/index.jsx

@ -1,91 +1,61 @@
import React, { useEffect, useState } from 'react'
import Taro, { useRouter, useDidShow } from '@tarojs/taro'
import { View } from '@tarojs/components'
import { AtButton, AtSearchBar } from 'taro-ui'
import { NoData } from '@/components/index'
import Skeleton from '../components/skeleton'
import moment from 'moment'
import request from '@/services/request'
import { getRoadSpotDetail } from '@/services/api'
import React from 'react'
import Taro, { useRouter } from '@tarojs/taro'
import { View, Text } from '@tarojs/components'
import { AtList, AtListItem } from "taro-ui"
import './index.scss'
function Index() {
const { item, isOld } = useRouter().params
const spotItem = item ? JSON.parse(decodeURIComponent(item)) : null
const [keyword, setKeyword] = useState('')
const [roadDetailList, setRoadDetailList] = useState([])
const [isNoData, setIsNoData] = useState(false)
useDidShow(() => {
getDetail()
})
const getDetail = () => {
if (spotItem) {
Taro.showLoading({ title: '加载中' })
request.get(`${getRoadSpotDetail()}?previewId=${spotItem.id}&keyword=${keyword}`).then(res => {
Taro.hideLoading()
if (res.statusCode === 200) {
setRoadDetailList(res.data)
} else {
Taro.showToast({ title: '获取详情失败', icon: 'error' })
}
if (res.data?.length) {
setIsNoData(false)
} else {
setIsNoData(true)
}
})
}
}
const renderList = () => {
return roadDetailList.length ? roadDetailList.map(item => <View key={item.id} className='card'>
<View className='item'>道路类型{item.road?.level ? (item.road?.level + '道') : '--'}</View>
<View className='item'>路线名称{item.road?.routeName || '--'}</View>
<View className='item at-row'>
<View className='at-col-6'>路线代码{item.road?.routeCode || '--'}</View>
<View className='at-col-6'>路段序号{item.road?.sectionNo || '--'}</View>
</View>
<View className='item at-row'>
<View className='at-col-6'>起点地名{item.road?.startingPlaceName || '--'}</View>
<View className='at-col-6'>止点地名{item.road?.stopPlaceName || '--'}</View>
</View>
<View className='item'>里程{item.road?.chainageMileage || '--'}</View>
<View className='item at-row'>
<View className='at-col-6'>养护次数{item.maintenanceCount}</View>
<View className='at-col-6'>
<AtButton
className='edit-btn'
type='primary'
size='small'
onClick={() => Taro.navigateTo({ url: `/packages/maintenanceSpotCheck/spotChange/index?detail=${encodeURIComponent(JSON.stringify(item))}&spot=${encodeURIComponent(JSON.stringify(spotItem))}` })}
disabled={
isOld === 'true' ||
item.roadSpotCheckPreview?.roadSpotCheckChangeLogs?.some(l => l.changeRoadId == item.roadId)
}
>调整</AtButton>
</View>
</View>
</View>) : <Skeleton length={3} />
}
const roadCode = [
{ title: "八一乡", value: "360121206000" },
{ title: "东新乡", value: "360121205000" },
{ title: "富山乡", value: "360121204000" },
{ title: "冈上镇", value: "360121107000" },
{ title: "广福镇", value: "360121108000" },
{ title: "黄马乡", value: "360121203000" },
{ title: "蒋巷镇", value: "360121105000" },
{ title: "金湖管理处", value: "330052" },
{ title: "泾口乡", value: "360121200000" },
{ title: "莲塘镇", value: "360121100000" },
{ title: "南新乡", value: "360121201000" },
{ title: "三江镇", value: "360121102000" },
{ title: "塔城乡", value: "360121202000" },
{ title: "塘南镇", value: "360121103000" },
{ title: "武阳镇", value: "360121106000" },
{ title: "向塘镇", value: "360121101000" },
{ title: "银三角管委会", value: "360121471000" },
{ title: "幽兰镇", value: "360121104000" },
]
const renderNoData = () => {
return <View style={{ marginTop: 100 }}><NoData /></View>
function Index() {
const { detail } = useRouter().params
const detailItem = detail ? JSON.parse(decodeURIComponent(detail)) : null
let townshipCode = ''
const targetValue = detailItem?.road?.townshipCode ?? ''
const foundItem = roadCode.find(item => item.value === targetValue)
if (foundItem) {
townshipCode = foundItem.title
} else {
townshipCode = "--"
}
return (<View className='page'>
<AtSearchBar
placeholder='道路名称关键字'
showActionButton
value={keyword}
onChange={v => setKeyword(v)}
onActionClick={getDetail}
/>
<View className='top flex'>抽查日期{moment(spotItem.date).format('YYYY-MM-DD')}</View>
{isNoData ? renderNoData() : renderList()}
</View>)
return (
<View className='page'>
<AtList>
<AtListItem title='所属乡镇' extraText={townshipCode} />
<AtListItem title='所属行政村' extraText={detailItem.road?.village?.name || '--'} />
<AtListItem title='道路名称' extraText={detailItem.road?.routeName || '--'} />
<AtListItem title='道路代码' extraText={detailItem.road?.routeCode || '--'} />
<AtListItem title='起点桩号' extraText={detailItem.road?.startStation || '--'} />
<AtListItem title='止点桩号' extraText={detailItem.road?.stopStation || '--'} />
<AtListItem title='技术等级' extraText={detailItem.road?.technicalLevel || '--'} />
<AtListItem title='路面类型' extraText={detailItem.road?.pavementType || '--'} />
<AtListItem title='路面宽度' extraText={detailItem.road?.pavementWidth || '--'} />
<AtListItem title='路基宽度' extraText={detailItem.road?.subgradeWidth || '--'} />
<AtListItem title='桩号里程' extraText={detailItem.road?.chainageMileage || '--'} />
<AtListItem title='养护次数(次)' extraText={detailItem.maintenanceCount} />
</AtList>
</View>
)
}
export default Index

28
weapp/src/packages/maintenanceSpotCheck/spotCheckRoadDetail/index.scss

@ -1,29 +1,9 @@
.page {
background-color: #fff;
height: 100vh;
font-size: 28px;
padding-bottom: 40px;
.top {
height: 90px;
}
.card {
padding: 20px;
border: gainsboro 1px solid;
border-radius: 10px;
background-color: #fff;
box-shadow: 10px 10px 5px rgb(219, 218, 218);
margin: 0 0 20px 20px;
width: calc(100% - 40px);
box-sizing: border-box;
.item {
padding: 10px 0;
background-color: #fff;
// font-size: 28px;
.edit-btn {
width: 100px;
}
}
.at-list__item-extra {
max-width: 470px;
}
}

25
weapp/src/packages/maintenanceSpotCheck/startSpotCheck/index.jsx

@ -17,7 +17,9 @@ function Index() {
})
const startSpotCheck = () => {
Taro.showLoading({ title: '抽取中' })
request.post(roadSpotPrepare(), { countyPercentage: rate === '50%' ? 50 : 75 }).then(res => {
Taro.hideLoading()
if (res.statusCode === 200 || res.statusCode === 204) {
Taro.showToast({ title: '抽取成功', icon: 'success' })
setPrepare(res.data)
@ -33,7 +35,9 @@ function Index() {
Taro.showToast({ title: '请先抽取道路' })
return
}
Taro.showLoading({ title: '提交中' })
request.post(roadSpotConfirm(), { previewId: prepare.previewId }).then(res => {
Taro.hideLoading()
if (res.statusCode === 204) {
Taro.showToast({ title: '提交成功', icon: 'success' })
setTimeout(() => {
@ -49,7 +53,6 @@ function Index() {
return (
<View className='page'>
<View className='content'>
<View className='fs24'>默认抽查乡道比例为25%村道比例为10%</View>
<View className='item'>
<View className='title'>抽查县道比例%:</View>
<Picker mode='selector'
@ -62,20 +65,28 @@ function Index() {
</View>
</Picker>
</View>
<View className='item'>
<View className='title'>抽查乡道比例%</View>
<View className='input disabled'>{rate === '50%' ? '25%' : '50%'}</View>
</View>
<View className='item'>
<View className='title'>抽查村道比例%</View>
<View className='input disabled'>{rate === '50%' ? '10%' : '20%'}</View>
</View>
<AtButton type='primary' className='start-btn' size='small'
onClick={startSpotCheck}
>开始抽取</AtButton>
<View className='item'>
<View className='title'>抽查县道</View>
<View className='input disabled'>{prepare.spotCountyRoadCount}</View>
<View className='title'>抽查县道公里</View>
<View className='input disabled'>{prepare.countryMil}</View>
</View>
<View className='item'>
<View className='title'>抽查乡道</View>
<View className='input disabled'>{prepare.spotTownRoadCount}</View>
<View className='title'>抽查乡道公里</View>
<View className='input disabled'>{prepare.townMil}</View>
</View>
<View className='item'>
<View className='title'>抽查村道</View>
<View className='input disabled'>{prepare.spotVillageRoadCount}</View>
<View className='title'>抽查村道公里</View>
<View className='input disabled'>{prepare.villageMil}</View>
</View>
<AtButton type='primary' className='submit-btn' onClick={onSubmit}>提交</AtButton>
</View>

BIN
web/client/src/components/README.txt

Binary file not shown.

15
web/client/src/sections/fillion/actions/carimages.js

@ -0,0 +1,15 @@
import { basicAction } from '@peace/utils'
import { ApiTable } from '$utils'
export function getCarImages (query) {
return dispatch => basicAction({
type: 'get',
dispatch: dispatch,
actionType: 'GET_CAR_IMAGES',
url: ApiTable.getCarImages,
query,
msg: { error: '获取图片失败' },
reducer: { name: 'carimage' }
})
}

124
web/client/src/sections/fillion/containers/carimages.js

@ -0,0 +1,124 @@
// import React, { useState, useEffect } from 'react'
// import { connect } from 'react-redux'
// import { getCarImages } from '../actions/carimages'
// import ProTable from '@ant-design/pro-table'
// import { Form, Space, DatePicker, Button, Select, Popconfirm, Image, Tooltip } from 'antd'
// import moment from 'moment'
// function Carimages (props) {
// const { dispatch, assess, user } = props
// const [query, setQuery] = useState({ page: 1, pageSize: 10, })
// const [loading, setLoading] = useState(false)
// 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(() => {
// return () => { }
// }, [])
// useEffect(() => {
// getData()
// }, [query])
// const getData = () => {
// console.log(query, 'query')
// dispatch(getCarImages({ ...query })).then(res => {
// if (res?.success) {
// setdatasource(res?.payload?.data?.rows)
// settotal(res?.payload?.data?.count)
// }
// })
// }
// return (
// <div>
// <div style={{ marginBottom: '20px', display: 'flex', justifyContent: 'space-between' }}>
// <Form layout="inline" onFinish={(v) => {
// 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')
// })
// }}>
// {/* <Form.Item>
// <Button type="primary" htmlType="submit">搜索</Button>
// </Form.Item> */}
// </Form>
// {/* <Button type="primary" disabled={editAble}
// onClick={() => {
// setAssessModalVisible(true)
// }}>新增</Button> */}
// </div>
// <ProTable
// columns={[
// {
// title: '序号',
// dataIndex: 'id',
// key: 'id',
// defaultSortOrder: 'ascend',
// },
// {
// title: '抓拍图片',
// dataIndex: 'url',
// key: 'url',
// render: (t, r) => {
// if (r?.url && r?.id) {
// return <span style={{ marginRight: 10 }}>
// <Image src={r?.url} width={200} />
// </span>
// } else {
// return '--'
// }
// }
// },
// {
// title: '日期',
// dataIndex: 'time',
// key: 'time',
// render: (t, r) => {
// const localTime = moment.utc(r?.time).format('YYYY-MM-DD HH:mm:ss')
// return r?.time ? localTime : '--'
// }
// },
// ]}
// dataSource={datasource || []}
// loading={loading}
// pagination={{
// total: total || 0,
// pageSize: 10,
// defaultPageSize: 10,
// showSizeChanger: false,
// onChange: (page, pageSize) => {
// setQuery({
// ...query,
// page,
// limit: pageSize
// })
// }
// }}
// rowKey="key"
// toolBarRender={false}
// search={false}
// />
// </div>
// )
// }
// function mapStateToProps (state) {
// const { auth, assess } = state
// return {
// user: auth.user,
// assess: assess.data || [],
// }
// }
// export default connect(mapStateToProps)(Carimages)

20
web/client/src/sections/fillion/containers/maintenanceSpotCheck-new.js

@ -52,25 +52,7 @@ const MaintenanceSpotCheck = (props) => {
{ title: "银三角管委会", value: "360121471000" },
{ title: "幽兰镇", value: "360121104000" },
]
const [village, setVillage] = useState()
useEffect(() => {
const fetchData = async () => {
try {
const res = await dispatch(getVillageList({}))
let data = res.payload.data
// console.log(data)
data.map(s => {
setVillage(s)
})
} catch (error) {
console.error(error)
}
}
fetchData()
}, [dispatch])
// console.log(village)
const columns = [
{
title: '抽查日期',
@ -238,7 +220,7 @@ const MaintenanceSpotCheck = (props) => {
}
}
},
{ title: '所属行政村', key: 'villageId', dataIndex: 'villageId', render: (_, r) => r.road?.villageId === village.id ? village.name : '--' },
{ title: '所属行政村', key: 'villageId', dataIndex: 'villageId', render: (_, r) => r.road?.village?.name || '--' },
{ title: '道路名称', key: 'routeName', dataIndex: 'routeName', render: (_, r) => r.road?.routeName || '--' },
{ title: '道路代码', key: 'routeCode', dataIndex: 'routeCode', render: (_, r) => r.road?.routeCode || '--' },
// { title: '路段序号', key: 'sectionNo', dataIndex: 'sectionNo', render: (_, r) => r.road?.sectionNo || '--' },

17
web/client/src/sections/fillion/nav-item.js

@ -1,8 +1,8 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { Menu } from 'antd';
import { ReadOutlined } from '@ant-design/icons';
const SubMenu = Menu.SubMenu;
import React from 'react'
import { Link } from 'react-router-dom'
import { Menu } from 'antd'
import { ReadOutlined } from '@ant-design/icons'
const SubMenu = Menu.SubMenu
export function getNavItem (user, dispatch) {
const isshow = user?.userResources?.
some(i => i.resourceId === 'OVERLOADMANAGE' ||
@ -72,6 +72,11 @@ export function getNavItem (user, dispatch) {
<Menu.Item key="fillioninfor">
<Link to="/fillion/infor">治超管理</Link>
</Menu.Item> : ''}
{/* {user?.username == 'SuperAdmin' || user?.userResources?.some(i => i.resourceId === 'OVERLOADMANAGE') ?
<Menu.Item key="fillioncarimages">
<Link to="/fillion/carimages">车辆抓拍管理</Link>
</Menu.Item> : ''}*/}
</SubMenu>
: ''
}
@ -148,5 +153,5 @@ export function getNavItem (user, dispatch) {
</SubMenu> : null
);
)
}

35
web/client/src/sections/fillion/routes.js

@ -1,21 +1,22 @@
'use strict';
import { Infor } from './containers';
import { transportation } from './containers';
import { BridgeTable } from './containers';
import { HigHways } from './containers';
import { OperaTional } from './containers';
import { Enforce } from './containers';
import { Public } from './containers';
import { Videois } from './containers';
import { PromoTional } from './containers';
'use strict'
import { Infor } from './containers'
import { transportation } from './containers'
import { BridgeTable } from './containers'
import { HigHways } from './containers'
import { OperaTional } from './containers'
import { Enforce } from './containers'
import { Public } from './containers'
import { Videois } from './containers'
import { PromoTional } from './containers'
import { Maintenance } from './containers'
import { Patrol } from './containers'
import { File } from './containers';
import { File } from './containers'
import { Jiekouguanli } from './containers'
import { Task, Assess, VideoCenter, } from './containers'
import { Building } from './containers'
import { MaintenanceSpotCheckNew, AdjustLog } from './containers'
import Luzheng from './containers/luzheng';
import Carimages from './containers/carimages'
import Luzheng from './containers/luzheng'
export default [{
type: 'inner',
route: {
@ -32,6 +33,14 @@ export default [{
breadcrumb: '治超管理',
authCode: 'OVERLOADMANAGE'
},
// {
// path: '/carimages',
// key: 'fillioncarimages',
// menuSelectKeys: ['fillioncarimages'],
// component: Carimages,
// breadcrumb: '车辆抓拍管理',
// authCode: 'OVERLOADMANAGE'
// },
{
path: '/luzheng',
key: 'luzheng',
@ -203,4 +212,4 @@ export default [{
}
]
}
}];
}]

14
web/client/src/utils/webapi.js

@ -1,7 +1,7 @@
'use strict';
import { ProxyRequest } from "@peace/utils";
'use strict'
import { ProxyRequest } from "@peace/utils"
export const GodTransRequest = new ProxyRequest("_godTrans");
export const GodTransRequest = new ProxyRequest("_godTrans")
export const ApiTable = {
login: 'login',
@ -70,7 +70,7 @@ export const ApiTable = {
getRoadway: 'road',
putRoadway: 'road',
delRoadway: 'road/{roadId}',
getVillageList:'village/list', //获取村庄
getVillageList: 'village/list', //获取村庄
//道路统计
getBgroadstatistics: "build/road_state",
@ -314,11 +314,13 @@ export const ApiTable = {
getRoadadministration: '/getRoadadministration',
// 发送短信
pushAppointSMS: 'pushAppointSMS',
};
// 获取图片
getCarImages: '/car/images'
}
export const RouteTable = {
apiRoot: '/api/root',
fileUpload: '/_upload/new',
cleanUpUploadTrash: '/_upload/cleanup',
};
}

1
web/package.json

@ -89,6 +89,7 @@
"react-color": "^2.19.3",
"react-router-breadcrumbs-hoc": "^4.0.1",
"react-sortable-hoc": "^2.0.0",
"sequelize-automate-freesun": "^1.2.2",
"superagent": "^6.1.0",
"swiper": "^8.3.1",
"uuid": "^8.3.1",

Loading…
Cancel
Save