|
|
|
'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 = [] // 上次查得的村道id
|
|
|
|
let lastVillageIds = []
|
|
|
|
let gather = [] //汇总
|
|
|
|
|
|
|
|
if (lastSpotRes) {
|
|
|
|
lastCountyPercentage = lastSpotRes.countyPercentage
|
|
|
|
lastCountyRoadIds = lastSpotRes.countyRoadId || []
|
|
|
|
|
|
|
|
let lastCounty = await models.RoadSpotCheckPreview.findAll({
|
|
|
|
where: {
|
|
|
|
checked: true,
|
|
|
|
id: { $lte: lastSpotRes.id }
|
|
|
|
},
|
|
|
|
limit: 3,
|
|
|
|
order: [['date', 'DESC']],
|
|
|
|
})
|
|
|
|
|
|
|
|
if (lastCounty) {
|
|
|
|
lastCounty.forEach(d => {
|
|
|
|
lastTownRoadIds = lastTownRoadIds.concat(d.townshipRoadId) || []
|
|
|
|
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
let lastVillage = await models.RoadSpotCheckPreview.findAll({
|
|
|
|
where: {
|
|
|
|
checked: true,
|
|
|
|
id: { $lte: lastSpotRes.id }
|
|
|
|
},
|
|
|
|
limit: 9,
|
|
|
|
order: [['date', 'DESC']],
|
|
|
|
})
|
|
|
|
|
|
|
|
if (lastVillage) {
|
|
|
|
lastVillage.forEach(d => {
|
|
|
|
lastVillageRoadRoadIds = lastVillageRoadRoadIds.concat(d.villageRoadId) || []
|
|
|
|
lastVillageIds = lastVillageIds.concat(d.villageId) || []
|
|
|
|
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 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
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
|
|
if (accumulationMileage >= targetMileage) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (accumulationMileage < targetMileage) {
|
|
|
|
// 还小于 说明没取够
|
|
|
|
await filterRoad(otherWhere, true)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
await filterRoad(otherWhere, true)
|
|
|
|
}
|
|
|
|
|
|
|
|
return [spotRoadIds, accumulationMileage]
|
|
|
|
}
|
|
|
|
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 = []
|
|
|
|
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 = 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 (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]
|
|
|
|
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,
|
|
|
|
township: township,
|
|
|
|
village: village
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 {
|
|
|
|
id: item.id,
|
|
|
|
date: item.date,
|
|
|
|
countyPercentage: item.countyPercentage,
|
|
|
|
spotCountyRoadCount: item.countyRoadId ? item.countyRoadId.length : 0,
|
|
|
|
spotTownRoadCount: item.townshipRoadId ? item.townshipRoadId.length : 0,
|
|
|
|
spotVillageRoadCount: item.villageRoadId ? item.villageRoadId.length : 0,
|
|
|
|
countyRoadId: item.countyRoadId,
|
|
|
|
townshipRoadId: item.townshipRoadId,
|
|
|
|
villageRoadId: item.villageRoadId,
|
|
|
|
villageMil: item.villageMil,
|
|
|
|
townMil: item.townMil,
|
|
|
|
countryMil: item.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 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,
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
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 == '县') {
|
|
|
|
previewRes.gather && previewRes.gather.forEach(d => {
|
|
|
|
if (!d.code) {
|
|
|
|
d.countyPresent = d.countyPresent + differenceValue
|
|
|
|
d.countyDifferenceValue = d.countyDifferenceValue + differenceValue
|
|
|
|
}
|
|
|
|
})
|
|
|
|
milData = { countryMil: previewRes.countryMil + differenceValue, gather: previewRes.gather }
|
|
|
|
} else if (level == '乡') {
|
|
|
|
previewRes.gather && previewRes.gather.forEach(d => {
|
|
|
|
if (d.code == curOriginRoad.townshipCode) {
|
|
|
|
d.townshipPresent = d.townshipPresent - parseFloat(curOriginRoad.chainageMileage)
|
|
|
|
d.townshipDifferenceValue = d.townshipDifferenceValue - parseFloat(curOriginRoad.chainageMileage)
|
|
|
|
}
|
|
|
|
if (d.code == curOriginRoad.curChangeRoad) {
|
|
|
|
d.villagePresent = d.villagePresent + parseFloat(curChangeRoad.chainageMileage)
|
|
|
|
d.townshipDifferenceValue = d.townshipDifferenceValue + parseFloat(curChangeRoad.chainageMileage)
|
|
|
|
}
|
|
|
|
}) || []
|
|
|
|
milData = { townMil: previewRes.townMil + differenceValue, gather: previewRes.gather }
|
|
|
|
} else if (level == '村') {
|
|
|
|
previewRes.gather && previewRes.gather.forEach(d => {
|
|
|
|
if (d.code == curOriginRoad.townshipCode) {
|
|
|
|
d.villageParticipate = d.villageParticipate - parseFloat(curOriginRoad.chainageMileage)
|
|
|
|
d.villageDifferenceValue = d.villageDifferenceValue - parseFloat(curOriginRoad.chainageMileage)
|
|
|
|
}
|
|
|
|
if (d.code == curOriginRoad.curChangeRoad) {
|
|
|
|
d.villageParticipate = d.villageParticipate + parseFloat(curChangeRoad.chainageMileage)
|
|
|
|
d.villageDifferenceValue = d.villageDifferenceValue + parseFloat(curChangeRoad.chainageMileage)
|
|
|
|
}
|
|
|
|
}) || []
|
|
|
|
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 exportSpotRode (ctx) {
|
|
|
|
try {
|
|
|
|
const { models } = ctx.fs.dc;
|
|
|
|
const { previewId } = ctx.query
|
|
|
|
|
|
|
|
const previewRes = await models.RoadSpotCheckPreview.findOne({
|
|
|
|
where: {
|
|
|
|
id: previewId
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
const listRes = await models.RoadSpotCheck.findAll({
|
|
|
|
where: {
|
|
|
|
prepareId: previewId
|
|
|
|
},
|
|
|
|
include: [{
|
|
|
|
model: models.Road,
|
|
|
|
// required: false,
|
|
|
|
where: {
|
|
|
|
del: false,
|
|
|
|
}
|
|
|
|
}]
|
|
|
|
})
|
|
|
|
|
|
|
|
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: '养护次数(次)',
|
|
|
|
},]
|
|
|
|
|
|
|
|
// function judgeLevel (routeCode) {
|
|
|
|
// if (routeCode) {
|
|
|
|
// if (routeCode.startsWith('X')) {
|
|
|
|
// return '县道'
|
|
|
|
// } else if (routeCode.startsWith('Y')) {
|
|
|
|
// return '乡道'
|
|
|
|
// } else if (routeCode.startsWith('C')) {
|
|
|
|
// return '村道'
|
|
|
|
// }
|
|
|
|
// return ''
|
|
|
|
// } else {
|
|
|
|
// return ''
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
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,
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
const fileName = `${moment(previewRes.date).format('YYYY年MM月DD日HH时mm分')}道路抽查记录` + '.csv'
|
|
|
|
const filePath = await xlsxDownload.simpleExcelDown({
|
|
|
|
// data: exportData, header, fileName: fileName
|
|
|
|
data: exportData, header, fileName: fileName, gather: { data: previewRes.gather || [] }
|
|
|
|
})
|
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = {
|
|
|
|
reportList,
|
|
|
|
reportPosition,
|
|
|
|
reportDetail, createReport, deleteReport, reportHandle,
|
|
|
|
spotPrepare, spotCheck, spotCheckDetail,
|
|
|
|
roadSpotPrepare, confirmRoadSpot, roadSpotList, roadSpotDetail, roadSpotChange, roadSpotChangList, exportSpotRode
|
|
|
|
};
|