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

1202 lines
38 KiB

3 years ago
'use strict';
3 years ago
const { QueryTypes } = require('sequelize');
const moment = require('moment');
const xlsxDownload = require('../../../../utils/xlsxDownload.js');
const fs = require('fs');
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}%`
}
3 years ago
}
}
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 = `
2 years ago
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}'
`: ''
}
2 years ago
) AS NR
left join "user" on "user".id = NR.user_id
WHERE NEWINDEX = 1 order by id desc;
2 years ago
`
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
}
}
2 years ago
}
} 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
}
}
3 years ago
}
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 }
3 years ago
}
})
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
}
}
3 years ago
}
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
}
}
3 years ago
}
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
}
}
3 years ago
}
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
}
}
3 years ago
}
// 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 = `
1 year ago
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
}
}
1 year ago
}
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 = `
1 year ago
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
1 year ago
}
})
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
}
}
1 year ago
}
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 = []
if (lastSpotRes) {
lastCountyPercentage = lastSpotRes.countyPercentage
lastCountyRoadIds = lastSpotRes.countyRoadId || []
let lastCounty = await models.RoadSpotCheckPreview.findAll({
where: {
checked: true,
id: { $lt: 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: { $lt: 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 = []) {
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 = true
AND ${keyMap[key]} ${otherWhere.length ? `AND ${otherWhere.join(' AND ')}` : ''}
`)
return res[0][0].total_mileage
}
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
}
// 抽县
const countryRoadTotalMileage = await getRoadTotalMileage('县')
const countryRoadNeedMileage = countryRoadTotalMileage * countyPercentage / 100
let spotCountyRoadIds = await spotRoadId('县', lastCountyRoadIds, countryRoadNeedMileage, [])
// 抽乡
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 = []
for await (let t of allTownCodeRes) {
// 遍历每个乡镇并抽取
let otherWhere = [`township_code='${t.township_code}'`]
const townRoadTotalMileage = await getRoadTotalMileage('乡', otherWhere)
const townRoadNeedMileage = townRoadTotalMileage * 25 / 100
let spotTownRoadIds_ = await spotRoadId('乡', lastTownRoadIds, townRoadNeedMileage, otherWhere)
spotTownRoadIds = spotTownRoadIds.concat(spotTownRoadIds_)
// 抽村
const villageRoadTotalMileage = await getRoadTotalMileage('村', otherWhere)
const villageRoadNeedMileage = villageRoadTotalMileage * 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 {
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 spotVillageRoadIds_ = await spotRoadId('村', lastVillageRoadRoadIds, villageRoadNeedMileage, otherWhere, villageCheckIdList)
spotVillageRoadIds = spotVillageRoadIds.concat(spotVillageRoadIds_)
}
const previewRes = await models.RoadSpotCheckPreview.create({
countyPercentage: countyPercentage,
date: moment().format(),
countyRoadId: spotCountyRoadIds,
townshipRoadId: spotTownRoadIds,
villageRoadId: spotVillageRoadIds,
villageId: spotVillageIds,
checked: false
})
ctx.status = 200;
ctx.body = {
previewId: previewRes.id,
spotCountyRoadCount: spotCountyRoadIds.length,
spotTownRoadCount: spotTownRoadIds.length,
spotVillageRoadCount: spotVillageRoadIds.length,
}
} 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,
}
})
} 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)
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,
}
}]
})
const header = [{
key: 'level',
title: '道路类型',
}, {
key: 'routeName',
title: '路线名称',
}, {
key: 'routeCode',
title: '路线代码',
}, {
key: 'sectionNo',
title: '路段序号',
}, {
key: 'startingPlaceName',
title: '起点名称',
}, {
key: 'stopPlaceName',
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.dataValues
return {
level:
judgeLevel(road.routeCode)
,
routeName: road.routeName,
routeCode: road.routeCode,
sectionNo: road.sectionNo,
startingPlaceName: road.startingPlaceName,
stopPlaceName: road.stopPlaceName,
chainageMileage: road.chainageMileage,
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
})
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
}
}
}
1 year ago
3 years ago
module.exports = {
reportList,
reportPosition,
reportDetail, createReport, deleteReport, reportHandle,
spotPrepare, spotCheck, spotCheckDetail,
roadSpotPrepare, confirmRoadSpot, roadSpotList, roadSpotDetail, roadSpotChange, roadSpotChangList, exportSpotRode
3 years ago
};