'use strict' ;
const { QueryTypes } = require ( 'sequelize' ) ;
const moment = require ( 'moment' ) ;
const xlsxDownload = require ( '../../../../utils/xlsxDownload.js' ) ;
const fs = require ( 'fs' ) ;
const data = require ( '../../routes/data/index.js' ) ;
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
const { userInfo } = ctx . fs . api
const sequelize = ctx . fs . dc . orm ;
let findUsers = [ ]
if (
userInfo . loginSource == 'wx'
&& userInfo . isAdmin
&& userInfo . phone != 'SuperAdmin'
&& ( ! performerId && ! handleState )
) {
// 是管理员但不是超管 查自己部门及下级部门的所有用户的信息
const sqlStr = `
WITH RECURSIVE sub_departments AS (
SELECT id , dependence
FROM department
WHERE id = $ { userInfo . departmentId }
UNION ALL
SELECT d . id , d . dependence
FROM sub_departments sd
JOIN department d ON sd . id = d . dependence
)
SELECT u . id
FROM "user" AS u
JOIN sub_departments sd ON u . department_id = sd . id
WHERE u . delete = false ;
`
const res = await sequelize . query ( sqlStr , { type : QueryTypes . SELECT } )
findUsers = res . map ( item => {
return item . id
} )
findUsers . push ( - 1 )
}
let findOption = {
where : {
} ,
attributes : [ 'id' , 'road' , 'time' , 'projectType' , 'roadSectionStart' , 'performerId' , 'roadSectionEnd' , 'reportType' , 'address' ,
'content' , 'longitude' , 'latitude' , 'projectName' , 'handleState' , 'codeRoad' , 'handleContent' , 'handlePic' , 'videoUrl' ,
'scenePic' ] ,
include : [ {
model : models . User ,
attributes : [ 'name' ]
} ] ,
//order: [['time', asc ? 'ASC' : 'DESC']],
order : [ [ 'time' , 'DESC' ] ] ,
}
if ( limit ) {
findOption . limit = limit
}
if ( page && limit ) {
findOption . offset = page * limit
}
if ( startTime && endTime ) {
findOption . where = {
time : {
'$between' : [ startTime , endTime ]
}
}
}
if ( keyword ) {
if ( reportType == 'road' ) {
findOption . where . projectName = {
'$like' : ` % ${ keyword } % `
}
} else {
findOption . where . road = {
'$like' : ` % ${ keyword } % `
}
}
}
if ( userId ) {
findOption . where . userId = { $in : userId . split ( ',' ) . map ( Number ) }
}
if ( findUsers . length ) {
findOption . where . userId = { $in : findUsers }
}
if ( reportType ) {
findOption . where . reportType = reportType
}
if ( projectType ) {
findOption . where . projectType = projectType
}
if ( performerId ) {
let performerIds = performerId . split ( ',' )
findOption . where . performerId = { $in : performerIds }
}
if ( handleState ) {
let handleStates = handleState . split ( ',' )
findOption . where . handleState = { $in : handleStates }
}
if ( codeRoad ) {
findOption . where . codeRoad = codeRoad
}
let reportRes = null ;
if ( isTop ) {
const sqlStr = `
select NR . * , "user" . name as user_name
from ( SELECT R . * , "row_number" ( ) OVER ( PARTITION BY R . user_id ORDER BY R . "time" DESC ) AS NEWINDEX
FROM report AS R
$ { reportType ? `
where report_type = '${reportType}'
` : ''
}
) AS NR
left join "user" on "user" . id = NR . user_id
WHERE NEWINDEX = 1 order by id desc ;
`
reportRes = await sequelize . query ( sqlStr , { type : QueryTypes . SELECT } ) ;
if ( reportType == 'road' ) {
const projectNameArr = reportRes . map ( item => item . project_name ) . filter ( item => item )
const projectRes = projectNameArr . length ? await models . Project . findAll ( {
where : {
entryName : { $in : projectNameArr }
}
} ) : [ ]
for ( let r of reportRes ) {
let corProject = projectRes . find ( item => item . entryName == r . project_name )
if ( corProject ) {
r . project = corProject . dataValues
}
}
}
} else {
reportRes = await models . Report . findAll ( findOption )
}
ctx . status = 200 ;
ctx . body = reportRes
} catch ( error ) {
ctx . fs . logger . error ( ` path: ${ ctx . path } , error: ${ error } ` ) ;
ctx . status = 400 ;
ctx . body = {
message : typeof error == 'string' ? error : undefined
}
}
}
async function reportPosition ( ctx ) {
try {
const models = ctx . fs . dc . models ;
const { startTime , endTime , userId , reportType } = ctx . query
const sequelize = ctx . fs . dc . ORM ;
let findMxTimeOption = {
attributes : [
'userId' ,
[ sequelize . fn ( 'MAX' , sequelize . col ( 'time' ) ) , 'maxTime' ] ,
] ,
where : {
} ,
group : [ 'report.user_id' ] ,
}
if ( startTime && endTime ) {
findMxTimeOption . where = {
time : {
'$between' : [ startTime , endTime ]
}
}
}
if ( userId ) {
findMxTimeOption . where . userId = userId
}
if ( reportType ) {
findMxTimeOption . where . reportType = reportType
}
const reportMaxTimeRes = await models . Report . findAll ( findMxTimeOption )
const timeArr = reportMaxTimeRes . map ( item => item . dataValues . maxTime )
const reportRes = await models . Report . findAll ( {
where : {
time : { '$in' : timeArr }
}
} )
ctx . status = 200 ;
ctx . body = reportRes
} catch ( error ) {
ctx . fs . logger . error ( ` path: ${ ctx . path } , error: ${ error } ` ) ;
ctx . status = 400 ;
ctx . body = {
message : typeof error == 'string' ? error : undefined
}
}
}
async function reportDetail ( ctx ) {
try {
const models = ctx . fs . dc . models ;
const { reportId } = ctx . params
const reportRes = await models . Report . findOne ( {
where : {
id : reportId
} ,
include : [ {
model : models . Road ,
// where: {
// del: false
// },
as : 'road_' ,
} ] ,
} )
ctx . status = 200 ;
ctx . body = reportRes
} catch ( error ) {
ctx . fs . logger . error ( ` path: ${ ctx . path } , error: ${ error } ` ) ;
ctx . status = 400 ;
ctx . body = {
message : typeof error == 'string' ? error : undefined
}
}
}
async function reportHandle ( ctx ) {
try {
const { models } = ctx . fs . dc ;
const { reportId } = ctx . params
const { handleState } = ctx . request . body
const data = ctx . request . body
/ * *
* data = {
* handleState ,
* handleContent ,
* handlePic
* }
* /
await models . Report . update ( data , {
where : {
id : reportId
}
} )
ctx . status = 200 ;
} catch ( error ) {
ctx . fs . logger . error ( ` path: ${ ctx . path } , error: ${ error } ` ) ;
ctx . status = 400 ;
ctx . body = {
message : typeof error == 'string' ? error : undefined
}
}
}
async function createReport ( ctx ) {
try {
const { userId } = ctx . fs . api
const models = ctx . fs . dc . models ;
const data = ctx . request . body ;
await models . Report . create ( {
... data ,
userId ,
time : new Date ( ) ,
} )
ctx . status = 204
} catch ( error ) {
ctx . fs . logger . error ( ` path: ${ ctx . path } , error: ${ error } ` ) ;
ctx . status = 400 ;
ctx . body = {
message : typeof error == 'string' ? error : undefined
}
}
}
async function deleteReport ( ctx ) {
try {
const models = ctx . fs . dc . models ;
const { reportId } = ctx . params ;
await models . Report . destroy ( {
where : {
id : reportId
}
} )
ctx . status = 204
} catch ( error ) {
ctx . fs . logger . error ( ` path: ${ ctx . path } , error: ${ error } ` ) ;
ctx . status = 400 ;
ctx . body = {
message : typeof error == 'string' ? error : undefined
}
}
}
// TODO 小程序填写道路名称的时候的道路筛选 是一起都返回 还是不断传关键字搜索返回
async function spotPrepare ( ctx ) {
try {
const { models } = ctx . fs . dc ;
const sequelize = ctx . fs . dc . orm ;
const { percentage } = ctx . request . body ;
const departmentIdRes = await models . Department . findAll ( {
attributes : [ 'id' , 'name' ] ,
where : {
dependence : null ,
delete : false ,
}
} )
let lukyDepartment = ''
if ( departmentIdRes . length ) {
lukyDepartment = departmentIdRes [ ( Math . round ( Math . random ( ) * departmentIdRes . length ) || 1 ) - 1 ]
} else {
throw ` 暂无乡镇信息 `
}
const sqlStr = `
WITH RECURSIVE sub_departments AS (
SELECT id , dependence
FROM department
WHERE id = $ { lukyDepartment . id }
UNION ALL
SELECT d . id , d . dependence
FROM sub_departments sd
JOIN department d ON sd . id = d . dependence
)
SELECT u . id
FROM "user" AS u
JOIN sub_departments sd ON u . department_id = sd . id
WHERE u . delete = false ;
`
const userRes = await sequelize . query ( sqlStr , { type : QueryTypes . SELECT } )
let findUsers = [ ]
findUsers = userRes . map ( item => {
return item . id
} )
const reportCount = findUsers . length ? await models . Report . count ( {
where : {
reportType : 'conserve' ,
userId : { $in : findUsers }
}
} ) : 0
const previewRes = await models . ReportSpotCheckPreview . create ( {
percentage : percentage ,
departmentId : lukyDepartment . id ,
date : moment ( ) . format ( ) ,
reportCount : reportCount ,
checked : false ,
} )
ctx . status = 200 ;
ctx . body = {
lukyDepartment ,
reportCount ,
previewId : previewRes . id
}
} catch ( error ) {
ctx . fs . logger . error ( ` path: ${ ctx . path } , error: ${ error } ` ) ;
ctx . status = 400 ;
ctx . body = {
message : typeof error == 'string' ? error : undefined
}
}
}
async function spotCheck ( ctx ) {
const transaction = await ctx . fs . dc . orm . transaction ( ) ;
try {
const { models } = ctx . fs . dc ;
const sequelize = ctx . fs . dc . orm ;
const { previewId } = ctx . query
if ( ! previewId ) {
throw '参数错误'
}
const prepareRes = await models . ReportSpotCheckPreview . findOne ( {
where : {
id : previewId
}
} )
const sqlStr = `
WITH RECURSIVE sub_departments AS (
SELECT id , dependence
FROM department
WHERE id = $ { prepareRes . departmentId }
UNION ALL
SELECT d . id , d . dependence
FROM sub_departments sd
JOIN department d ON sd . id = d . dependence
)
SELECT u . id
FROM "user" AS u
JOIN sub_departments sd ON u . department_id = sd . id
WHERE u . delete = false ;
`
const userRes = await sequelize . query ( sqlStr , { type : QueryTypes . SELECT } )
let findUsers = [ ]
findUsers = userRes . map ( item => {
return item . id
} )
let checkCount = Math . ceil ( prepareRes . reportCount * ( prepareRes . percentage / 100 ) )
const reportRes = await findUsers . length && checkCount ? await models . Report . findAll ( {
where : {
reportType : 'conserve' ,
userId : { $in : findUsers } ,
} ,
include : [ {
model : models . User ,
attributes : [ 'name' ]
} ] ,
order : sequelize . random ( ) , // 随机排序
limit : checkCount , // 限制返回的记录数
} ) : [ ]
await models . ReportSpotCheckPreview . update ( {
checked : true
} , {
where : {
id : previewId
}
} )
if ( reportRes . length ) {
let spotDate = moment ( ) . format ( 'YYYY-MM-DD' )
await models . ReportSpotCheck . bulkCreate ( reportRes . map ( r => {
return {
reportId : r . id ,
spotDate : spotDate ,
prepareId : previewId
}
} ) )
}
const rslt = findUsers . length && checkCount ? await models . ReportSpotCheckPreview . findAll ( {
where : {
checked : 'true' ,
id : previewId
} ,
include : [ {
model : models . Department ,
attributes : [ 'name' ]
} , {
model : models . ReportSpotCheck ,
include : [ {
model : models . Report ,
include : [ {
model : models . User ,
attributes : [ 'name' ]
} ] ,
} ]
}
] ,
} ) : [ ]
await transaction . commit ( ) ;
ctx . status = 200 ;
ctx . body = rslt
} catch ( error ) {
await transaction . rollback ( ) ;
ctx . fs . logger . error ( ` path: ${ ctx . path } , error: ${ error } ` ) ;
ctx . status = 400 ;
ctx . body = {
message : typeof error == 'string' ? error : undefined
}
}
}
async function spotCheckDetail ( ctx ) {
const { models } = ctx . fs . dc
const { startTime , endTime } = ctx . query
try {
const res = await models . ReportSpotCheckPreview . findAll ( {
where : {
checked : 'true'
} ,
order : [ [ 'date' , 'DESC' ] ] ,
include : [ {
model : models . Department ,
attributes : [ 'name' ]
} , {
model : models . ReportSpotCheck ,
where : { spotDate : { $between : [ moment ( startTime ) . format ( 'YYYY-MM-DD' ) , moment ( endTime ) . format ( 'YYYY-MM-DD' ) ] } } ,
order : [ [ 'spot_date' , 'DESC' ] ] ,
include : [ {
model : models . Report ,
order : [ [ 'date' , 'DESC' ] ] ,
include : [ {
model : models . User ,
attributes : [ 'name' ]
} ] ,
} ]
}
] ,
} )
ctx . body = res
ctx . status = 200
} catch ( error ) {
ctx . fs . logger . error ( ` path: ${ ctx . path } , error: ${ error } ` )
ctx . status = 400
ctx . body = {
message : typeof error == 'string' ? error : undefined
}
}
}
// async function roadSpotPrepare (ctx) {
// try {
// const { models } = ctx.fs.dc;
// const sequelize = ctx.fs.dc.orm;
// const { countyPercentage } = ctx.request.body;
// const lastSpotRes = await models.RoadSpotCheckPreview.findOne({
// where: {
// checked: true
// },
// // attributes: ['id', 'countyPercentage', 'date',],
// order: [['date', 'DESC']],
// // include: [{
// // model: models.RoadSpotCheck,
// // include: [{
// // model: models.Road,
// // // attributes: ['id', 'name']
// // }]
// // }]
// })
// let lastCountyPercentage = 0 // 最后一次的县道百分比
// let lastCountyRoadIds = [] // 上次查得的县道id
// let lastTownRoadIds = [] // 上次查得的乡镇道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: {
// checked: true,
// id: { $lte: lastSpotRes.id }
// },
// limit: 3,
// order: [['date', 'DESC']],
// })
// if (lastCounty) {
// let countyNnmter = 0
// lastCounty.forEach(d => {
// if (countyNnmter < (100 - (countyPercentage == 75 ? 50 : 25))) {
// lastTownRoadIds = lastTownRoadIds.concat(d.townshipRoadId) || []
// countyNnmter += (d.countyPercentage == 75 ? 50 : 25)
// }
// })
// }
// let lastVillage = await models.RoadSpotCheckPreview.findAll({
// where: {
// checked: true,
// id: { $lte: lastSpotRes.id }
// },
// limit: 9,
// order: [['date', 'DESC']],
// })
// if (lastVillage) {
// let villageNnmter = 0
// lastVillage.forEach(d => {
// if (villageNnmter < (100 - (countyPercentage == 75 ? 20 : 10))) {
// lastVillageRoadRoadIds = lastVillageRoadRoadIds.concat(d.villageRoadId) || []
// lastVillageIds = lastVillageIds.concat(d.villageId) || []
// villageNnmter += (d.countyPercentage == 75 ? 20 : 10)
// }
// })
// }
// // lastTownRoadIds = lastSpotRes.townshipRoadId || []
// // lastVillageRoadRoadIds = lastSpotRes.villageRoadId || []
// // lastVillageIds = lastSpotRes.villageId || []
// }
// // 先查上次没查的范围内的 然后比较百分比 如果重叠 再查上次查过的
// let keyMap = {
// '县': `route_code LIKE 'X%'`,
// '乡': `route_code LIKE 'Y%'`,
// '村': `route_code LIKE 'C%'`
// }
// async function getRoadTotalMileage (key, otherWhere = [], spot) {
// let res = await sequelize.query(`
// SELECT
// SUM(COALESCE(CAST(chainage_mileage AS DOUBLE PRECISION), 0)) AS total_mileage
// FROM road
// WHERE del = false
// AND spot = ${spot}
// AND ${keyMap[key]} ${otherWhere.length ? `AND ${otherWhere.join(' AND ')}` : ''}
// `)
// return res[0][0].total_mileage || 0
// }
// async function getRoadSpot (key, lastRoadIds = [], inOrNot, otherWhere = []) {
// if (!lastRoadIds.length && !inOrNot) {
// return []
// }
// return await sequelize.query(`
// SELECT id, chainage_mileage FROM road
// WHERE del = false
// AND spot = true
// AND ${keyMap[key]}
// ${lastRoadIds.length ?
// `AND id ${inOrNot ? 'IN' : 'NOT IN'} (
// ${lastRoadIds.map(item => `'${item}'`).join(',')},-1
// )` : ''
// }
// AND chainage_mileage IS NOT NULL ${otherWhere.length ? `AND ${otherWhere.join(' AND ')}` : ''}
// ORDER BY RANDOM()
// `, { type: QueryTypes.SELECT });
// }
// async function spotRoadId (key, lastRoadIds, targetMileage, otherWhere = [], villageIdList = []) {
// let spotRoadIds = []
// let accumulationMileage = 0
// let last = null
// async function filterRoad (otherWhere, getRepeat = true) {
// if (key == '村' && getRepeat == true) {
// } else {
// let roadUnSpotedRes = await getRoadSpot(key, lastRoadIds, false, otherWhere)
// for (let r of roadUnSpotedRes) {
// spotRoadIds.push(r.id)
// accumulationMileage += parseFloat(r.chainage_mileage)
// if (accumulationMileage >= targetMileage) {
// break;
// }
// }
// }
// if (accumulationMileage < targetMileage && getRepeat) {
// // 还小于 说明没取够
// let roadUnSpotedRepeatRes = await getRoadSpot(
// key,
// lastRoadIds,
// true,
// otherWhere
// )
// for (let r of roadUnSpotedRepeatRes) {
// spotRoadIds.push(r.id)
// accumulationMileage += parseFloat(r.chainage_mileage)
// if (accumulationMileage >= targetMileage) {
// break;
// }
// }
// }
// }
// if (key == '村') {
// for await (let villageId of villageIdList) {
// await filterRoad([
// ...otherWhere,
// `village_id=${villageId}`
// ], false)
// spotVillageIds.push(villageId)
// last = villageId
// if (accumulationMileage >= targetMileage) {
// break;
// }
// }
// if (accumulationMileage < targetMileage) {
// // 还小于 说明没取够
// // 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, last]
// }
// let villageMil = 0, townMil = 0, countryMil = 0;
// // 抽县
// const countryRoadTotalMileage = await getRoadTotalMileage('县', '', true)
// const countryRoadHide = await getRoadTotalMileage('县', '', false)
// const countryRoadNeedMileage = countryRoadTotalMileage * countyPercentage / 100
// let spotCountyRoadIdsArr = await spotRoadId('县', lastCountyRoadIds, countryRoadNeedMileage, [])
// let spotCountyRoadIds = spotCountyRoadIdsArr[0]
// let countryMil_ = spotCountyRoadIdsArr[1] || 0
// if (countryMil_) countryMil += countryMil_;
// gather.push({
// name: '南昌县交通运输局',
// county: countryRoadTotalMileage + countryRoadHide,
// countyParticipate: countryRoadTotalMileage,
// countyPresent: countryMil_,
// countyDifferenceValue: countryMil_ - countryRoadNeedMileage
// })
// let town = await models.Town.findAll() || []
// // 抽乡
// const allTownCodeRes = await sequelize.query(`
// SELECT
// DISTINCT township_code
// FROM road
// WHERE del = false
// AND spot = true
// AND township_code IS NOT NULL
// `, { type: QueryTypes.SELECT });
// let spotTownRoadIds = []
// let spotVillageRoadIds = []
// let spotVillageIds = []
// let allTownCodeResTown = []
// let lastEndVillage = {} //获取每个乡镇最后一个被抽取的村
// for await (let t of allTownCodeRes) {
// // 遍历每个乡镇并抽取
// let otherWhere = [`township_code='${t.township_code}'`]
// const townRoadTotalMileage = await getRoadTotalMileage('乡', otherWhere, true)
// const townRoadHide = await getRoadTotalMileage('乡', otherWhere, false)
// const townRoadNeedMileage = townRoadTotalMileage * (countyPercentage == 75 ? 50 : 25) / 100
// let spotTownRoadIdsArr = await spotRoadId('乡', lastTownRoadIds, townRoadNeedMileage, otherWhere)
// let spotTownRoadIds_ = spotTownRoadIdsArr[0]
// let townMil_ = spotTownRoadIdsArr[1]
// spotTownRoadIds = spotTownRoadIds.concat(spotTownRoadIds_)
// if (townMil_) townMil += townMil_
// // 抽村
// const villageRoadTotalMileage = await getRoadTotalMileage('村', otherWhere, true)
// const villageRoadTotalHide = await getRoadTotalMileage('村', otherWhere, false)
// const villageRoadNeedMileage = villageRoadTotalMileage * (countyPercentage == 75 ? 20 : 10) / 100
// let spotFirstVillageId = -1
// let villageRes = []
// if (lastAbstractVillage[t.township_code]) {
// } else {
// // 随机选取一个不在上次查过的村
// 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) {
// // 没有村了,随机选一个
// villageRes = await sequelize.query(`
// SELECT id FROM village
// WHERE township_code = '${t.township_code}'
// ORDER BY RANDOM()
// LIMIT 1
// `, { type: QueryTypes.SELECT });
// }
// }
// 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 {
// allTownCodeResTown.push({
// code: t.township_code,
// township: townRoadTotalMileage + townRoadHide,
// townshipParticipate: townRoadTotalMileage,
// townshipPresent: townMil_,
// townshipDifferenceValue: townMil_ - townRoadNeedMileage,
// village: villageRoadTotalMileage + villageRoadTotalHide,
// villageParticipate: villageRoadTotalMileage,
// villagePresent: 0,
// villageDifferenceValue: 0
// })
// continue;
// }
// const villageNearRes = await sequelize.query(`
// SELECT id,calc_village,distance FROM village_distance
// WHERE origin_village = ${spotFirstVillageId}
// ORDER BY distance ASC
// `, { type: QueryTypes.SELECT })
// let villageCheckIdList = villageNearRes.map(item => item.calc_village)
// villageCheckIdList.unshift(spotFirstVillageId)
// villageCheckIdList = [...(new Set(villageCheckIdList))]
// 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_
// allTownCodeResTown.push({
// code: t.township_code,
// township: townRoadTotalMileage + townRoadHide,
// townshipParticipate: townRoadTotalMileage,
// townshipPresent: townMil_,
// townshipDifferenceValue: townMil_ - townRoadNeedMileage,
// village: villageRoadTotalMileage + villageRoadTotalHide,
// villageParticipate: villageRoadTotalMileage,
// villagePresent: villageMil_,
// villageDifferenceValue: villageMil_ - villageRoadNeedMileage
// })
// }
// for (let index = 0; index < town.length; index++) {
// let d = town[index]
// if (allTownCodeResTown.find(c => c.code == d.code)) {
// gather.push({ ...(allTownCodeResTown.find(c => c.code == d.code) || {}), name: d.name })
// } else {
// let where = [`township_code='${d.code}'`]
// let township = await getRoadTotalMileage('乡', where, false)
// let village = await getRoadTotalMileage('村', where, false)
// gather.push({
// name: d.name,
// code: d.code,
// township: township,
// townshipParticipate: 0,
// townshipPresent: 0,
// townshipDifferenceValue: 0,
// village: village,
// villageParticipate: 0,
// villagePresent: 0,
// villageDifferenceValue: 0
// })
// }
// }
// const previewRes = await models.RoadSpotCheckPreview.create({
// countyPercentage: countyPercentage,
// date: moment().format(),
// countyRoadId: spotCountyRoadIds,
// townshipRoadId: spotTownRoadIds,
// villageRoadId: spotVillageRoadIds,
// villageId: spotVillageIds,
// checked: false,
// villageMil,
// townMil,
// countryMil,
// gather,
// lastAbstractVillage: lastEndVillage
// })
// ctx.status = 200;
// ctx.body = {
// previewId: previewRes.id,
// spotCountyRoadCount: spotCountyRoadIds.length,
// spotTownRoadCount: spotTownRoadIds.length,
// spotVillageRoadCount: spotVillageRoadIds.length,
// villageMil,
// townMil,
// countryMil
// }
// } catch (error) {
// ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
// ctx.status = 400;
// ctx.body = {
// message: typeof error == 'string' ? error : undefined
// }
// }
// }
async function confirmRoadSpot ( ctx ) {
const transaction = await ctx . fs . dc . orm . transaction ( ) ;
try {
const { models } = ctx . fs . dc ;
const sequelize = ctx . fs . dc . orm ;
const { previewId } = ctx . request . body
const prepareRes = await models . RoadSpotCheckPreview . findOne ( {
where : {
id : previewId
}
} )
let spotedRoadIds = [ ]
spotedRoadIds = spotedRoadIds . concat ( prepareRes . dataValues . countyRoadId )
spotedRoadIds = spotedRoadIds . concat ( prepareRes . dataValues . townshipRoadId )
spotedRoadIds = spotedRoadIds . concat ( prepareRes . dataValues . villageRoadId )
const conserveCountRes = await sequelize . query ( `
SELECT road_id , COUNT ( road_id ) as count
FROM report
WHERE road_id IN (
$ { spotedRoadIds . map ( item => item ) . join ( ',' ) }
) AND report_type = 'conserve'
GROUP BY road_id
` , { type: QueryTypes.SELECT })
let spotRslt = [ ]
for await ( let item of spotedRoadIds ) {
let corConserveCount = conserveCountRes . find ( cc => cc . road_id == item )
spotRslt . push ( {
roadId : item ,
maintenanceCount : corConserveCount ? corConserveCount . count : 0 ,
prepareId : previewId
} )
}
await models . RoadSpotCheck . bulkCreate ( spotRslt , {
transaction
} )
await models . RoadSpotCheckPreview . update ( {
checked : true
} , {
where : {
id : previewId
} ,
transaction
} )
await transaction . commit ( ) ;
ctx . status = 204 ;
} catch ( error ) {
await transaction . rollback ( ) ;
ctx . fs . logger . error ( ` path: ${ ctx . path } , error: ${ error } ` ) ;
ctx . status = 400 ;
ctx . body = {
message : typeof error == 'string' ? error : undefined
}
}
}
async function roadSpotList ( ctx ) {
try {
const { models } = ctx . fs . dc ;
const { startTime , endTime , page , limit } = ctx . query
let findOpt = {
order : [ [ 'id' , 'DESC' ] ] ,
where : {
checked : true
}
}
if ( startTime && endTime ) {
findOpt . where . date = {
$between : [ moment ( startTime ) . startOf ( 'day' ) . format ( ) , moment ( endTime ) . endOf ( 'day' ) . format ( ) ]
}
}
if ( page && limit ) {
findOpt . offset = ( page - 1 ) * limit
findOpt . limit = limit
}
const listRes = await models . RoadSpotCheckPreview . findAll ( findOpt )
ctx . status = 200 ;
ctx . body = listRes . map ( item => {
return {
... item . dataValues ,
spotCountyRoadCount : item . countyRoadId ? item . countyRoadId . length : 0 ,
spotTownRoadCount : item . townshipRoadId ? item . townshipRoadId . length : 0 ,
spotVillageRoadCount : item . villageRoadId ? item . villageRoadId . length : 0 ,
}
} )
} catch ( error ) {
ctx . fs . logger . error ( ` path: ${ ctx . path } , error: ${ error } ` ) ;
ctx . status = 400 ;
ctx . body = {
message : typeof error == 'string' ? error : undefined
}
}
}
async function roadSpotDetail ( ctx ) {
try {
const { models } = ctx . fs . dc ;
const { previewId , keyword } = ctx . query
const listRes = await models . RoadSpotCheck . findAll ( {
where : {
prepareId : previewId ,
} ,
include : [ {
model : models . Road ,
where : {
... ( keyword ? { routeName : { $ilike : ` % ${ keyword } % ` } } : { } ) ,
del : false ,
} ,
include : [ {
model : models . Village ,
} ]
} , {
model : models . RoadSpotCheckPreview ,
attributes : [ 'id' ] ,
include : [ {
model : models . RoadSpotCheckChangeLog ,
attributes : [ 'id' , 'changeRoadId' ] ,
} ]
} ]
} )
ctx . status = 200 ;
ctx . body = listRes
} catch ( error ) {
ctx . fs . logger . error ( ` path: ${ ctx . path } , error: ${ error } ` ) ;
ctx . status = 400 ;
ctx . body = {
message : typeof error == 'string' ? error : undefined
}
}
}
async function roadSpotChange ( ctx ) {
const transaction = await ctx . fs . dc . orm . transaction ( ) ;
try {
const { models } = ctx . fs . dc ;
const sequelize = ctx . fs . dc . orm ;
const { originRoadId , changeRoadId , previewId } = ctx . request . body
if ( originRoadId == changeRoadId ) {
throw '原路段与目标路段不能相同'
}
const previewRes = await models . RoadSpotCheckPreview . findOne ( {
where : {
id : previewId
}
} )
if ( ! previewRes ) {
throw '预览数据不存在'
}
let previewUpdated = false
async function updatePreview ( key ) {
if ( previewUpdated ) return
if ( previewRes [ key ] && previewRes [ key ] . includes ( originRoadId ) ) {
let originRoadIds = previewRes . dataValues [ key ]
let originRoadIdIndex = originRoadIds . indexOf ( originRoadId )
originRoadIds . splice ( originRoadIdIndex , 1 , changeRoadId )
await models . RoadSpotCheckPreview . update ( {
[ key ] : originRoadIds
} , {
where : {
id : previewId
} ,
transaction
} )
previewUpdated = true
}
}
await updatePreview ( 'countyRoadId' )
await updatePreview ( 'townshipRoadId' )
await updatePreview ( 'villageRoadId' )
if ( ! previewUpdated ) {
throw '更改路段不在抽查范围内'
}
const roadRes = await models . Road . findAll ( {
where : {
id : { $in : [ originRoadId , changeRoadId ] } ,
del : false ,
}
} )
if ( roadRes . length != 2 ) {
throw '路段不存在'
}
let content = ''
let curOriginRoad = roadRes . find ( item => item . id == originRoadId )
let curChangeRoad = roadRes . find ( item => item . id == changeRoadId )
const level = curChangeRoad . level ;
let milData = { }
let differenceValue = ( parseFloat ( curChangeRoad . chainageMileage ) - parseFloat ( curOriginRoad . chainageMileage ) ) || 0
if ( level == '县' ) {
if ( previewRes . gather ) {
let town = previewRes . gather [ 'countyRoad' ]
if ( town ) {
town . countyPresent = town . countyPresent + differenceValue
town . countyDifferenceValue = town . countyDifferenceValue + differenceValue
town . countyRoadId = [ ... ( town . countyRoadId . filter ( d => d != originRoadId ) || [ ] ) , changeRoadId ]
}
}
milData = { countryMil : previewRes . countryMil + differenceValue , gather : previewRes . gather }
} else if ( level == '乡' ) {
let town = previewRes . gather [ curOriginRoad . townshipCode ]
if ( town ) {
town . townshipPresent = town . townshipPresent + differenceValue
town . townshipDifferenceValue = town . townshipDifferenceValue + differenceValue
town . townRoadId = [ ... ( town . townRoadId . filter ( d => d != originRoadId ) || [ ] ) , changeRoadId ]
}
milData = { townMil : previewRes . townMil + differenceValue , gather : previewRes . gather }
} else if ( level == '村' ) {
let town = previewRes . gather [ curOriginRoad . townshipCode ]
if ( town ) {
town . villagePresent = town . villagePresent + differenceValue
town . villageDifferenceValue = town . villageDifferenceValue + differenceValue
town . villageRoadId = [ ... ( town . villageRoadId . filter ( d => d != originRoadId ) || [ ] ) , changeRoadId ]
}
milData = { villageMil : previewRes . villageMil + differenceValue , gather : previewRes . gather }
}
await models . RoadSpotCheckPreview . update ( {
... milData
} , {
where : {
id : previewId
} ,
transaction
} )
content = ` 将 ${ curOriginRoad . routeName } 从 ${ curOriginRoad . startingPlaceName } 到 ${ curOriginRoad . stopPlaceName } 改为 ${ curChangeRoad . routeName } 从 ${ curChangeRoad . startingPlaceName } 到 ${ curChangeRoad . stopPlaceName } `
const maintenanceCount = await sequelize . query ( `
SELECT COUNT ( id ) as count
FROM report
WHERE report_type = 'conserve' AND road_id = $ { changeRoadId }
` , { type: QueryTypes.SELECT })
await models . RoadSpotCheck . update ( {
roadId : changeRoadId ,
maintenanceCount : maintenanceCount [ 0 ] . count
} , {
where : {
roadId : originRoadId ,
prepareId : previewId
} ,
transaction
} )
await models . RoadSpotCheckChangeLog . create ( {
userId : ctx . fs . api . userId ,
time : moment ( ) . format ( ) ,
originRoadId : originRoadId ,
changeRoadId : changeRoadId ,
content : content ,
prepareId : previewId
} , {
transaction
} )
await transaction . commit ( ) ;
ctx . status = 204 ;
} catch ( error ) {
await transaction . rollback ( ) ;
ctx . fs . logger . error ( ` path: ${ ctx . path } , error: ${ error } ` ) ;
ctx . status = 400 ;
ctx . body = {
message : typeof error == 'string' ? error : undefined
}
}
}
async function roadSpotChangList ( ctx ) {
try {
const { models } = ctx . fs . dc ;
const { startTime , endTime , page , limit } = ctx . query
let findOptPreview = {
where : {
checked : true ,
} ,
attributes : [ 'id' , 'date' ]
}
if ( startTime && endTime ) {
findOptPreview . where = {
date : {
$between : [ moment ( startTime ) . startOf ( 'day' ) . format ( ) , moment ( endTime ) . endOf ( 'day' ) . format ( ) ]
}
}
}
let findOpt = {
order : [ [ 'id' , 'DESC' ] ] ,
where : {
} ,
include : [ {
model : models . RoadSpotCheckPreview ,
... findOptPreview ,
required : true ,
} , {
model : models . User ,
attributes : [ 'name' ]
} ]
}
if ( page && limit ) {
findOpt . offset = ( page - 1 ) * limit
findOpt . limit = limit
}
const listRes = await models . RoadSpotCheckChangeLog . findAll ( findOpt )
ctx . status = 200 ;
ctx . body = listRes
} catch ( error ) {
ctx . fs . logger . error ( ` path: ${ ctx . path } , error: ${ error } ` ) ;
ctx . status = 400 ;
ctx . body = {
message : typeof error == 'string' ? error : undefined
}
}
}
async function town ( ctx ) {
try {
const { models } = ctx . fs . dc ;
const { } = ctx . query
let options = {
where : {
} ,
}
const res = await models . Town . findAll ( options )
ctx . status = 200 ;
ctx . body = res
} catch ( error ) {
ctx . fs . logger . error ( ` path: ${ ctx . path } , error: ${ error } ` ) ;
ctx . status = 400 ;
ctx . body = {
message : typeof error == 'string' ? error : undefined
}
}
}
async function roadSpotPrepare ( ctx ) {
try {
const { models } = ctx . fs . dc ;
const sequelize = ctx . fs . dc . orm ;
const { countyPercentage , drawPeople , level , code } = ctx . request . body ;
//获取最新的一次
const lastSpotRes = await models . RoadSpotCheckPreview . findOne ( {
where : {
checked : true
} ,
order : [ [ 'date' , 'DESC' ] ] ,
} )
// 先查上次没查的范围内的 然后比较百分比 如果重叠 再查上次查过的
let keyMap = {
'县' : ` route_code LIKE 'X%' ` ,
'乡' : ` route_code LIKE 'Y%' ` ,
'村' : ` route_code LIKE 'C%' `
}
async function getRoadTotalMileage ( key , otherWhere = [ ] , spot ) {
let res = await sequelize . query ( `
SELECT
SUM ( COALESCE ( CAST ( chainage_mileage AS DOUBLE PRECISION ) , 0 ) ) AS total_mileage
FROM road
WHERE del = false
AND spot = $ { spot }
AND $ { keyMap [ key ] } $ { otherWhere . length ? ` AND ${ otherWhere . join ( ' AND ' ) } ` : '' }
` )
return res [ 0 ] [ 0 ] . total_mileage || 0
}
async function getRoadSpot ( key , lastRoadIds = [ ] , inOrNot , otherWhere = [ ] ) {
// if (!lastRoadIds.length && !inOrNot) {
// return []
// }
return await sequelize . query ( `
SELECT id , chainage_mileage , route_code FROM road
WHERE del = false
AND spot = true
AND $ { keyMap [ key ] }
$ { lastRoadIds . length ?
` AND id ${ inOrNot ? 'IN' : 'NOT IN' } (
$ { lastRoadIds . map ( item => ` ' ${ item } ' ` ) . join ( ',' ) } , - 1
) ` : ''
}
AND chainage_mileage IS NOT NULL $ { otherWhere . length ? ` AND ${ otherWhere . join ( ' AND ' ) } ` : '' }
ORDER BY RANDOM ( )
` , { type: QueryTypes.SELECT });
}
async function spotRoadId ( key , lastRoadIds , targetMileage , otherWhere = [ ] , villageIdList = [ ] ) {
let spotRoadIds = [ ]
let accumulationMileage = 0
let last = null
let spotVillageIds = [ ]
//县道乡道随机抽取
async function extractRandomElement ( arr ) {
if ( ! arr . length || accumulationMileage >= targetMileage ) {
return
}
const index = Math . floor ( Math . random ( ) * arr . length ) ;
const extracted = arr . splice ( index , 1 ) [ 0 ] ;
spotRoadIds . push ( extracted . id )
accumulationMileage += parseFloat ( extracted . chainage_mileage )
if ( accumulationMileage >= targetMileage ) {
return
} else {
return await extractRandomElement ( arr )
}
}
if ( key == '县' ) {
let roadUnSpotedRes = await getRoadSpot ( key , lastRoadIds , false , otherWhere ) || [ ]
await extractRandomElement ( roadUnSpotedRes )
if ( accumulationMileage < targetMileage ) {
// 还小于 说明没取够
let roadUnSpotedRepeatRes = await getRoadSpot ( key , lastRoadIds , true , otherWhere )
await extractRandomElement ( roadUnSpotedRepeatRes )
}
} else if ( key == '乡' ) {
let roadUnSpotedRes = await getRoadSpot ( key , lastRoadIds , false , otherWhere )
if ( code == '360121201000' ) {
let townY002 = roadUnSpotedRes . filter ( d => d . route_code . indexOf ( 'Y002' ) != - 1 )
if ( townY002 [ 0 ] ) {
spotRoadIds . push ( townY002 [ 0 ] . id )
accumulationMileage += parseFloat ( townY002 [ 0 ] . chainage_mileage )
}
if ( countyPercentage == 75 ) {
if ( townY002 [ 1 ] ) {
spotRoadIds . push ( townY002 [ 1 ] . id )
accumulationMileage += parseFloat ( townY002 [ 1 ] . chainage_mileage )
}
}
roadUnSpotedRes = roadUnSpotedRes . filter ( d => ! ( d . route_code . indexOf ( 'Y002' ) != - 1 ) )
}
if ( code == '360121105000' ) {
let townY031 = roadUnSpotedRes . filter ( d => d . route_code . indexOf ( 'Y031' ) != - 1 )
let townY032 = roadUnSpotedRes . filter ( d => d . route_code . indexOf ( 'Y032' ) != - 1 )
if ( townY031 [ 0 ] ) {
spotRoadIds . push ( townY031 [ 0 ] . id )
accumulationMileage += parseFloat ( townY031 [ 0 ] . chainage_mileage )
}
if ( townY032 [ 0 ] ) {
spotRoadIds . push ( townY032 [ 0 ] . id )
accumulationMileage += parseFloat ( townY032 [ 0 ] . chainage_mileage )
}
if ( countyPercentage == 75 ) {
if ( townY031 [ 1 ] ) {
spotRoadIds . push ( townY031 [ 1 ] . id )
accumulationMileage += parseFloat ( townY031 [ 1 ] . chainage_mileage )
}
if ( townY032 [ 1 ] ) {
spotRoadIds . push ( townY032 [ 1 ] . id )
accumulationMileage += parseFloat ( townY032 [ 1 ] . chainage_mileage )
}
}
roadUnSpotedRes = roadUnSpotedRes . filter ( d => ! ( d . route_code . indexOf ( 'Y031' ) != - 1 ) && ! ( d . route_code . indexOf ( 'Y032' ) != - 1 ) )
}
await extractRandomElement ( roadUnSpotedRes )
if ( accumulationMileage < targetMileage ) {
// 还小于 说明没取够
let roadUnSpotedRepeatRes = await getRoadSpot ( key , lastRoadIds , true , [ ... otherWhere , ` route_code not Like 'Y032%' ` , ` route_code not Like 'Y002%' ` , ` route_code not Like 'Y031%' ` ] )
await extractRandomElement ( roadUnSpotedRepeatRes )
}
} else if ( key == '村' ) {
for await ( let villageId of villageIdList ) {
let roadUnSpotedRes = await getRoadSpot ( key , lastRoadIds , false , [ ... otherWhere , ` village_id= ${ villageId } ` ] )
for ( let r of roadUnSpotedRes ) {
spotRoadIds . push ( r . id )
accumulationMileage += parseFloat ( r . chainage_mileage )
if ( accumulationMileage >= targetMileage ) {
break ;
}
}
spotVillageIds . push ( villageId )
last = villageId
if ( accumulationMileage >= targetMileage ) {
break ;
}
}
if ( accumulationMileage < targetMileage ) {
// 还小于 说明没取够
// await filterRoad(otherWhere, true)
for await ( let villageId of villageIdList . reverse ( ) ) {
let roadUnSpotedRes = await getRoadSpot ( key , lastRoadIds , true , [ ... otherWhere , ` village_id= ${ villageId } ` ] )
for ( let r of roadUnSpotedRes ) {
spotRoadIds . push ( r . id )
accumulationMileage += parseFloat ( r . chainage_mileage )
if ( accumulationMileage >= targetMileage ) {
break ;
}
}
spotVillageIds . push ( villageId )
last = villageId
if ( accumulationMileage >= targetMileage ) {
break ;
}
}
}
}
return [ spotRoadIds , accumulationMileage , last , spotVillageIds ]
}
async function relevance ( previewId , spotedRoadIds ) {
const conserveCountRes = await sequelize . query ( `
SELECT road_id , COUNT ( road_id ) as count
FROM report
WHERE road_id IN (
$ { spotedRoadIds . map ( item => item ) . join ( ',' ) }
) AND report_type = 'conserve'
GROUP BY road_id
` , { type: QueryTypes.SELECT })
let spotRslt = [ ]
for await ( let item of spotedRoadIds ) {
let corConserveCount = conserveCountRes . find ( cc => cc . road_id == item )
spotRslt . push ( {
roadId : item ,
maintenanceCount : corConserveCount ? corConserveCount . count : 0 ,
prepareId : previewId
} )
}
await models . RoadSpotCheck . bulkCreate ( spotRslt )
}
let gather = { } //汇总
if ( level == '县' ) {
let lastCountyRoadIds = [ ] // 上次查得的县道id
if ( lastSpotRes ) {
lastCountyRoadIds = lastSpotRes . countyRoadId || [ ]
}
//抽取县道长度
let countryMil = 0 ;
// 抽县
const countryRoadTotalMileage = await getRoadTotalMileage ( '县' , '' , true )
const countryRoadHide = await getRoadTotalMileage ( '县' , '' , false )
const countryRoadNeedMileage = countryRoadTotalMileage * countyPercentage / 100
let spotCountyRoadIdsArr = await spotRoadId ( '县' , lastCountyRoadIds , countryRoadNeedMileage , [ ] )
let spotCountyRoadIds = spotCountyRoadIdsArr [ 0 ]
let countryMil_ = spotCountyRoadIdsArr [ 1 ] || 0
if ( countryMil_ ) countryMil += countryMil_ ;
gather . countyRoad = {
id : 'countyRoad' ,
name : '南昌县交通运输局' ,
//总里程
county : countryRoadTotalMileage + countryRoadHide ,
//纳入考核里程
countyParticipate : countryRoadTotalMileage ,
//本次考核里程
countyPresent : countryMil_ ,
//实际抽取比原计划多
countyDifferenceValue : countryMil_ - countryRoadNeedMileage ,
//本次抽取的县道id
countyRoadId : spotCountyRoadIds ,
//抽取时间
abstractTime : moment ( ) . format ( ) ,
//抽取人
drawPeople
}
let spotCheckCreate = await models . RoadSpotCheckPreview . create ( {
countyPercentage : countyPercentage ,
date : moment ( ) . format ( ) ,
countyRoadId : spotCountyRoadIds ,
checked : true ,
countryMil ,
gather ,
abstractFinish : false
} )
if ( spotCheckCreate ) {
await relevance ( spotCheckCreate . id , spotCountyRoadIds )
}
} else {
if ( lastSpotRes ) {
let lastTownRoadIds = [ ] // 上次查得的乡镇道id
let lastVillageRoadRoadIds = [ - 1 ] // 上次查得的村道id
let lastVillageIds = [ ] //抽到的村道id
let lastAbstractVillage = { } //每个乡最后抽查的村
let gather = lastSpotRes . gather || { } //汇总
let lastCounty = await models . RoadSpotCheckPreview . findAll ( {
where : {
checked : true ,
id : { $lt : lastSpotRes . id }
} ,
limit : 9 ,
order : [ [ 'date' , 'DESC' ] ] ,
} )
if ( lastCounty ) {
let countyNnmter = 0
let villageNnmter = 0
lastAbstractVillage = lastCounty [ 0 ] && lastCounty [ 0 ] . lastAbstractVillage || { }
lastCounty . forEach ( d => {
if ( countyNnmter < ( 100 - ( countyPercentage == 75 ? 50 : 25 ) ) ) {
lastTownRoadIds = lastTownRoadIds . concat ( d . townshipRoadId || [ ] ) || [ ]
countyNnmter += ( d . countyPercentage == 75 ? 50 : 25 )
}
if ( villageNnmter < ( 100 - ( countyPercentage == 75 ? 20 : 10 ) ) ) {
lastVillageRoadRoadIds = lastVillageRoadRoadIds . concat ( d . villageRoadId || [ ] ) || [ ]
lastVillageIds = lastVillageIds . concat ( d . villageId || [ ] ) || [ ]
villageNnmter += ( d . countyPercentage == 75 ? 20 : 10 )
}
} )
}
let town = await models . Town . findAll ( ) || [ ]
let spotTownRoadIds = lastSpotRes . townshipRoadId || [ ]
let townMil = lastSpotRes . townMil || 0 //已抽取的乡道公里数
// 抽乡
let otherWhere = [ ` township_code=' ${ code } ' ` ]
const townRoadTotalMileage = await getRoadTotalMileage ( '乡' , otherWhere , true )
const townRoadHide = await getRoadTotalMileage ( '乡' , otherWhere , false )
const townRoadNeedMileage = townRoadTotalMileage * ( countyPercentage == 75 ? 50 : 25 ) / 100
let spotTownRoadIdsArr = await spotRoadId ( '乡' , lastTownRoadIds , townRoadNeedMileage , otherWhere )
let spotTownRoadIds_ = spotTownRoadIdsArr [ 0 ]
let townMil_ = spotTownRoadIdsArr [ 1 ]
spotTownRoadIds = spotTownRoadIds . concat ( spotTownRoadIds_ || [ ] )
if ( townMil_ ) townMil += townMil_ || 0
let spotVillageRoadIds = lastSpotRes . villageRoadId || [ ]
let spotVillageIds = lastSpotRes . villageId || [ ]
let lastEndVillage = lastSpotRes . lastAbstractVillage || { } //获取每个乡镇最后一个被抽取的村
let villageMil = lastSpotRes . villageMil || 0 //已抽取的村道公里数
// 抽村
const villageRoadTotalMileage = await getRoadTotalMileage ( '村' , otherWhere , true )
const villageRoadTotalHide = await getRoadTotalMileage ( '村' , otherWhere , false )
const villageRoadNeedMileage = villageRoadTotalMileage * ( countyPercentage == 75 ? 20 : 10 ) / 100
let spotFirstVillageId = - 1
let villageRes = [ ]
//获取该抽取的村的id
if ( lastAbstractVillage [ code ] ) {
} else {
// 随机选取一个不在上次查过的村
villageRes = await sequelize . query ( `
SELECT id FROM village
WHERE township_code = '${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 = '${code}'
ORDER BY RANDOM ( )
LIMIT 1
` , { type: QueryTypes.SELECT });
}
}
if ( lastAbstractVillage [ code ] ) {
// spotVillageIds.push(lastAbstractVillage[code])
spotFirstVillageId = lastAbstractVillage [ code ]
} else if ( villageRes . length ) {
// spotVillageIds.push(villageRes[0].id)
spotFirstVillageId = villageRes [ 0 ] . id
}
//按照与当前村距离排序获取村id
const villageNearRes = await sequelize . query ( `
SELECT id , calc_village , distance FROM village_distance
WHERE origin_village = $ { spotFirstVillageId }
ORDER BY distance ASC
` , { type: QueryTypes.SELECT })
let villageCheckIdList = villageNearRes . map ( item => item . calc_village )
villageCheckIdList . unshift ( spotFirstVillageId )
villageCheckIdList = [ ... ( new Set ( villageCheckIdList ) ) ]
let spotVillageRoadIdsArr = await spotRoadId ( '村' , lastVillageRoadRoadIds , villageRoadNeedMileage , otherWhere , villageCheckIdList )
let spotVillageRoadIds_ = spotVillageRoadIdsArr [ 0 ]
let villageMil_ = spotVillageRoadIdsArr [ 1 ]
lastEndVillage [ code ] = spotVillageRoadIdsArr [ 2 ]
spotVillageIds = spotVillageIds . concat ( spotVillageRoadIdsArr [ 3 ] || [ ] )
spotVillageRoadIds = spotVillageRoadIds . concat ( spotVillageRoadIds_ || [ ] )
if ( villageMil_ ) villageMil += villageMil_
let fidOne = town . find ( d => d . code == code )
gather [ code ] = {
id : code ,
name : fidOne . name ,
//总里程 乡
township : townRoadTotalMileage + townRoadHide ,
//纳入考核里程 乡
townshipParticipate : townRoadNeedMileage ,
//本次考核里程 乡
townshipPresent : townMil_ ,
//实际抽取比原计划多 乡
townshipDifferenceValue : townMil_ - townRoadNeedMileage ,
//本次抽取的乡道id
townRoadId : spotTownRoadIds_ ,
//总里程 村
village : villageRoadTotalMileage + villageRoadTotalHide ,
//纳入考核里程 村
villageParticipate : villageRoadNeedMileage ,
//本次考核里程 村
villagePresent : villageMil_ ,
//实际抽取比原计划多 村
villageDifferenceValue : villageMil_ - villageRoadNeedMileage ,
//本次抽取的村道id
villageRoadId : spotVillageRoadIds_ ,
//抽取时间
abstractTime : moment ( ) . format ( ) ,
//抽取人
drawPeople : drawPeople
}
let abstractFinish = false
for ( let item of town ) {
if ( item . code != '360121205000' ) {
abstractFinish = true
if ( ! gather [ item . code ] ) {
abstractFinish = false
break ;
}
}
}
let spotCheckCreate = await models . RoadSpotCheckPreview . update ( {
townshipRoadId : spotTownRoadIds ,
villageRoadId : spotVillageRoadIds ,
villageId : spotVillageIds ,
townMil ,
villageMil ,
gather ,
abstractFinish : abstractFinish
} , { where : { id : lastSpotRes . id } } )
if ( spotCheckCreate ) {
await relevance ( lastSpotRes . id , [ ... spotTownRoadIds_ , ... spotVillageRoadIds_ ] )
}
}
}
const res = await models . RoadSpotCheckPreview . findOne ( {
where : {
checked : true
} ,
order : [ [ 'date' , 'DESC' ] ] ,
} )
ctx . status = 200 ;
ctx . body = res
} catch ( error ) {
ctx . fs . logger . error ( ` path: ${ ctx . path } , error: ${ error } ` ) ;
ctx . status = 400 ;
ctx . body = {
message : typeof error == 'string' ? error : undefined
}
}
}
async function exportSpotRode ( ctx ) {
try {
const { models } = ctx . fs . dc ;
const { previewId , roadId , isgather , code } = ctx . query
const previewRes = await models . RoadSpotCheckPreview . findOne ( {
where : {
id : previewId
}
} )
let lastCounty = await models . RoadSpotCheckPreview . findOne ( {
where : {
checked : true ,
id : { $lt : previewId }
} ,
limit : 1 ,
order : [ [ 'date' , 'DESC' ] ] ,
} )
let options = {
where : {
prepareId : previewId
} ,
include : [ {
model : models . Road ,
// required: false,
where : {
del : false ,
}
} ]
}
if ( roadId ) {
options . where . roadId = { $in : roadId . split ( ',' ) }
}
const listRes = await models . RoadSpotCheck . findAll ( options )
let town = await models . Town . findAll ( { } ) || [ ]
let village = await models . Village . findAll ( { attributes : [ 'id' , 'name' ] } ) || [ ]
const header = [ {
key : 'townshipCode' ,
title : '所属乡镇' ,
} , {
key : 'villageId' ,
title : '所属行政村' ,
} , {
key : 'routeName' ,
title : '道路名称' ,
} , {
key : 'routeCode' ,
title : '道路代码' ,
} , {
key : 'startStation' ,
title : '起点桩号' ,
} , {
key : 'stopStation' ,
title : '止点桩号' ,
} , {
key : 'technicalLevel' ,
title : '技术等级' ,
} , {
key : 'pavementType' ,
title : '路面类型' ,
} , {
key : 'pavementWidth' ,
title : '路面宽度' ,
} , {
key : 'subgradeWidth' ,
title : '路基宽度' ,
} , {
key : 'chainageMileage' ,
title : '桩号里程' ,
} , {
key : 'maintenanceCount' ,
title : '养护次数(次)' ,
} ,
{
key : 'remark' ,
title : '备注' ,
} ]
let exportData = listRes . map ( ( { dataValues : item } ) => {
let road = item . road && item . road . dataValues || { }
return {
townshipCode : ( town . find ( d => d . code == road . townshipCode ) || { } ) . name || '--' ,
villageId : ( village . find ( d => road . villageId == d . id ) || { } ) . name || '--' ,
routeName : road . routeName ,
routeCode : road . routeCode ,
startStation : road . startStation || 0 ,
stopStation : road . stopStation || 0 ,
technicalLevel : road . technicalLevel ,
pavementType : road . pavementType ,
pavementWidth : road . pavementWidth || 0 ,
subgradeWidth : road . subgradeWidth || 0 ,
chainageMileage : road . chainageMileage || 0 ,
maintenanceCount : item . maintenanceCount ,
}
} )
let option = {
where : {
prepareId : lastCounty . id
} ,
include : [ {
model : models . Road ,
where : {
del : false ,
}
} ]
}
if ( code ) {
if ( code == 'countyRoad' ) {
option . where . roadId = { $in : lastCounty . nextAbstract && lastCounty . nextAbstract [ 'county' ] || [ ] }
} else {
option . where . roadId = { $in : [ ... ( lastCounty . nextAbstract && lastCounty . nextAbstract [ 'town' ] || [ ] ) , ... ( lastCounty . nextAbstract && lastCounty . nextAbstract [ 'village' ] || [ ] ) ] }
option . include [ 0 ] . where . level = { $in : [ '乡' , '村' ] }
}
} else {
option . where . roadId = { $in : [ ... ( lastCounty . nextAbstract && lastCounty . nextAbstract [ 'county' ] || [ ] ) , ... ( lastCounty . nextAbstract && lastCounty . nextAbstract [ 'town' ] || [ ] ) , ... ( lastCounty . nextAbstract && lastCounty . nextAbstract [ 'village' ] || [ ] ) ] }
}
const res = await models . RoadSpotCheck . findAll ( option ) || [ ]
if ( res . length ) {
res . forEach ( ( { dataValues : item } ) => {
let road = item . road && item . road . dataValues || { }
exportData . push ( {
townshipCode : ( town . find ( d => d . code == road . townshipCode ) || { } ) . name || '--' ,
villageId : ( village . find ( d => road . villageId == d . id ) || { } ) . name || '--' ,
routeName : road . routeName ,
routeCode : road . routeCode ,
startStation : road . startStation || 0 ,
stopStation : road . stopStation || 0 ,
technicalLevel : road . technicalLevel ,
pavementType : road . pavementType ,
pavementWidth : road . pavementWidth || 0 ,
subgradeWidth : road . subgradeWidth || 0 ,
chainageMileage : road . chainageMileage || 0 ,
maintenanceCount : item . maintenanceCount ,
remark : true
} )
} )
}
const fileName = ` ${ moment ( previewRes . date ) . format ( 'YYYY年MM月DD日HH时mm分' ) } 道路抽查记录 ` + '.csv'
let data = {
data : exportData , header , fileName : fileName
}
if ( isgather ) {
let gather = [ previewRes . dataValues . gather [ 'countyRoad' ] ]
town . forEach ( d => {
if ( d . code != '360121205000' ) {
gather . push ( previewRes . dataValues . gather [ d . code ] || { } )
}
} )
data . gather = { data : gather }
}
const filePath = await xlsxDownload . simpleExcelDown ( data )
const fileData = fs . readFileSync ( filePath ) ;
ctx . status = 200 ;
ctx . set ( 'Content-Type' , 'application/x-xls' ) ;
ctx . set ( 'Content-disposition' , 'attachment; filename=' + encodeURI ( fileName ) ) ;
ctx . body = fileData
} catch ( error ) {
ctx . fs . logger . error ( ` path: ${ ctx . path } , error: ${ error } ` ) ;
ctx . status = 400 ;
ctx . body = {
message : typeof error == 'string' ? error : undefined
}
}
}
async function postRoadSpotNext ( ctx ) {
try {
const { models } = ctx . fs . dc ;
const { previewId , level , roadId } = ctx . request . body
const previewRes = await models . RoadSpotCheckPreview . findOne ( {
where : {
id : previewId
}
} )
let nextAbstract = previewRes && previewRes . nextAbstract || { }
if ( level == '县' ) {
nextAbstract . county = [ ... ( nextAbstract . county || [ ] ) , roadId ]
}
if ( level == '乡' ) {
nextAbstract . town = [ ... ( nextAbstract . town || [ ] ) , roadId ]
}
if ( level == '村' ) {
nextAbstract . village = [ ... ( nextAbstract . village || [ ] ) , roadId ]
}
await models . RoadSpotCheckPreview . update ( {
nextAbstract
} , {
where : {
id : previewId
} ,
} )
ctx . status = 204 ;
} catch ( error ) {
ctx . fs . logger . error ( ` path: ${ ctx . path } , error: ${ error } ` ) ;
ctx . status = 400 ;
ctx . body = {
message : typeof error == 'string' ? error : undefined
}
}
}
module . exports = {
reportList ,
reportPosition ,
reportDetail , createReport , deleteReport , reportHandle ,
spotPrepare , spotCheck , spotCheckDetail ,
roadSpotPrepare , confirmRoadSpot , roadSpotList , roadSpotDetail , roadSpotChange , roadSpotChangList , exportSpotRode ,
town , postRoadSpotNext
} ;