diff --git a/api/app/lib/controllers/report/index.js b/api/app/lib/controllers/report/index.js index a81030f1..2ddc449a 100644 --- a/api/app/lib/controllers/report/index.js +++ b/api/app/lib/controllers/report/index.js @@ -3,22 +3,22 @@ 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 = ` +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 @@ -34,294 +34,294 @@ async function reportList(ctx) { WHERE u.delete = false; ` - const res = await sequelize.query(sqlStr, { type: QueryTypes.SELECT }) - findUsers = res.map(item => { - return item.id - }) - findUsers.push(-1) - } + const res = await sequelize.query(sqlStr, { type: QueryTypes.SELECT }) + findUsers = res.map(item => { + return item.id + }) + findUsers.push(-1) + } - let findOption = { - where: { + 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] - } + }, + 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 (keyword) { + if (reportType == 'road') { + findOption.where.projectName = { + '$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 = ` + } 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 - } - } + 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 - } - } + } + } 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: { +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 } + }, + group: ['report.user_id'], + } + + if (startTime && endTime) { + findMxTimeOption.where = { + time: { + '$between': [startTime, endTime] } - }) - 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 - } - } + } + } + + 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 +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 - } - } + 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 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 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; +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 - } - } + 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 = ` +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 @@ -337,60 +337,60 @@ async function spotPrepare(ctx) { WHERE u.delete = false; ` - const userRes = await sequelize.query(sqlStr, { type: QueryTypes.SELECT }) - let findUsers = [] - findUsers = userRes.map(item => { - return item.id - }) + 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 - } - } + 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 - } - }) +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 sqlStr = ` + const prepareRes = await models.ReportSpotCheckPreview.findOne({ + where: { + id: previewId + } + }) + + const sqlStr = ` WITH RECURSIVE sub_departments AS ( SELECT id, dependence FROM department @@ -406,296 +406,309 @@ async function spotCheck(ctx) { 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 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 + 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 } - }) - 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 - }, + })) + } + 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.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 - } - } + 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']], +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.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 - } - } + 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; +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({ + 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 + checked: true, + id: { $lt: lastSpotRes.id } }, - // attributes: ['id', 'countyPercentage', 'date',], + limit: 3, 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) || [] + }) - }) - } + 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) || [] + 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 || [] - } + // 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(` + // 先查上次没查的范围内的 然后比较百分比 如果重叠 再查上次查过的 + 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 = true + AND spot = ${spot} AND ${keyMap[key]} ${otherWhere.length ? `AND ${otherWhere.join(' AND ')}` : ''} `) - return res[0][0].total_mileage - } + return res[0][0].total_mileage || 0 + } - async function getRoadSpot(key, lastRoadIds = [], inOrNot, otherWhere = []) { - if (!lastRoadIds.length && !inOrNot) { - return [] - } - return await sequelize.query(` + 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'} ( + `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; - } - } - } - } + } + + async function spotRoadId (key, lastRoadIds, targetMileage, otherWhere = [], villageIdList = []) { + let spotRoadIds = [] + let accumulationMileage = 0 + + async function filterRoad (otherWhere, getRepeat = true) { + + if (key == '村' && getRepeat == true) { - 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) + 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; + 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 + }) - // 抽县 - const countryRoadTotalMileage = await getRoadTotalMileage('县') - const countryRoadNeedMileage = countryRoadTotalMileage * countyPercentage / 100 - let spotCountyRoadIdsArr = await spotRoadId('县', lastCountyRoadIds, countryRoadNeedMileage, []) - let spotCountyRoadIds = spotCountyRoadIdsArr[0] - let countryMil_ = spotCountyRoadIdsArr[1] - if (countryMil_) countryMil += countryMil_; + let town = await models.Town.findAll() || [] - // 抽乡 - const allTownCodeRes = await sequelize.query(` + + // 抽乡 + const allTownCodeRes = await sequelize.query(` SELECT DISTINCT township_code FROM road @@ -704,28 +717,33 @@ async function roadSpotPrepare(ctx) { 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 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) - const villageRoadNeedMileage = villageRoadTotalMileage * 10 / 100 - - let spotFirstVillageId = -1 - // 随机选取一个不在上次查过的村 - let villageRes = await sequelize.query(` + 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 * 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 * 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 ( @@ -734,90 +752,131 @@ async function roadSpotPrepare(ctx) { ORDER BY RANDOM() LIMIT 1 `, { type: QueryTypes.SELECT }); - if (!villageRes.length) { - // 没有村了,随机选一个 - villageRes = await sequelize.query(` + 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; - } + } + 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(` + 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_ - } - - const previewRes = await models.RoadSpotCheckPreview.create({ - countyPercentage: countyPercentage, - date: moment().format(), - countyRoadId: spotCountyRoadIds, - townshipRoadId: spotTownRoadIds, - villageRoadId: spotVillageRoadIds, - villageId: spotVillageIds, - checked: false, - villageMil, - townMil, - countryMil - }) - - 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 - } - } + 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 + }) + + } + + town.forEach(async d => { + if (allTownCodeResTown.find(c => c.code == d.code)) { + gather.push({ ...(allTownCodeResTown.find(c => c.code == d.code) || {}), name: d.name }) + } else { + gather.push({ + name: d.name, + township: await getRoadTotalMileage('乡', [`township_code='${d.code}'`], false), + village: await getRoadTotalMileage('村', [`township_code='${d.code}'`], false), + }) + } + }) + + + + 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 +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 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(` + const conserveCountRes = await sequelize.query(` SELECT road_id, COUNT(road_id) as count FROM report WHERE road_id IN ( @@ -826,289 +885,289 @@ async function confirmRoadSpot(ctx) { 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 - }) - } + 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 - } - } + 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 +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 - } - } + 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 (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 - } + if (page && limit) { + findOpt.offset = (page - 1) * limit + findOpt.limit = limit + } - const listRes = await models.RoadSpotCheckPreview.findAll(findOpt) + 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 - } - } + 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 +async function roadSpotDetail (ctx) { + try { + const { models } = ctx.fs.dc; + const { previewId, keyword } = ctx.query - const listRes = await models.RoadSpotCheck.findAll({ + const listRes = await models.RoadSpotCheck.findAll({ + where: { + prepareId: previewId, + }, + include: [{ + model: models.Road, where: { - prepareId: previewId, + ...(keyword ? { routeName: { $ilike: `%${keyword}%` } } : {}), + del: false, }, + }, { + model: models.RoadSpotCheckPreview, + attributes: ['id'], include: [{ - model: models.Road, - where: { - ...(keyword ? { routeName: { $ilike: `%${keyword}%` } } : {}), - del: false, - }, - }, { - model: models.RoadSpotCheckPreview, - attributes: ['id'], - include: [{ - model: models.RoadSpotCheckChangeLog, - attributes: ['id', 'changeRoadId'], - }] + 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 - } - } + }] + }) + + + 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 +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 '原路段与目标路段不能相同' - } + 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') + const previewRes = await models.RoadSpotCheckPreview.findOne({ + where: { + id: previewId + } + }) - if (!previewUpdated) { - throw '更改路段不在抽查范围内' - } + if (!previewRes) { + throw '预览数据不存在' + } - const roadRes = await models.Road.findAll({ - where: { - id: { $in: [originRoadId, changeRoadId] }, - del: false, - } - }) + 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) - if (roadRes.length != 2) { - throw '路段不存在' - } + originRoadIds.splice(originRoadIdIndex, 1, changeRoadId) - let content = '' - let curOriginRoad = roadRes.find(item => item.id == originRoadId) - let curChangeRoad = roadRes.find(item => item.id == changeRoadId) + await models.RoadSpotCheckPreview.update({ + [key]: originRoadIds + }, { + where: { + id: previewId + }, + transaction + }) + previewUpdated = true + } + } + await updatePreview('countyRoadId') + await updatePreview('townshipRoadId') + await updatePreview('villageRoadId') - content = `将${curOriginRoad.routeName}从${curOriginRoad.startingPlaceName}到${curOriginRoad.stopPlaceName}改为${curChangeRoad.routeName}从${curChangeRoad.startingPlaceName}到${curChangeRoad.stopPlaceName}` + if (!previewUpdated) { + throw '更改路段不在抽查范围内' + } - const maintenanceCount = await sequelize.query(` + 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, + await models.RoadSpotCheck.update({ + roadId: changeRoadId, + maintenanceCount: maintenanceCount[0].count + }, { + where: { + roadId: originRoadId, 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 - } - } + }, + 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 +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 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: { + 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 - } - } + }, + 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) { @@ -1194,7 +1253,8 @@ async function exportSpotRode (ctx) { const fileName = `${moment(previewRes.date).format('YYYY年MM月DD日HH时mm分')}道路抽查记录` + '.csv' const filePath = await xlsxDownload.simpleExcelDown({ - data: exportData, header, fileName: fileName, gather:{data: exportData, header} + // data: exportData, header, fileName: fileName, gather: { data: previewRes.gather || [] } + data: exportData, header, fileName: fileName, }) const fileData = fs.readFileSync(filePath); @@ -1213,9 +1273,9 @@ async function exportSpotRode (ctx) { } module.exports = { - reportList, - reportPosition, - reportDetail, createReport, deleteReport, reportHandle, - spotPrepare, spotCheck, spotCheckDetail, - roadSpotPrepare, confirmRoadSpot, roadSpotList, roadSpotDetail, roadSpotChange, roadSpotChangList, exportSpotRode + reportList, + reportPosition, + reportDetail, createReport, deleteReport, reportHandle, + spotPrepare, spotCheck, spotCheckDetail, + roadSpotPrepare, confirmRoadSpot, roadSpotList, roadSpotDetail, roadSpotChange, roadSpotChangList, exportSpotRode }; \ No newline at end of file diff --git a/api/app/lib/models/road_spot_check_preview.js b/api/app/lib/models/road_spot_check_preview.js index 0dfb16ba..43438889 100644 --- a/api/app/lib/models/road_spot_check_preview.js +++ b/api/app/lib/models/road_spot_check_preview.js @@ -104,7 +104,16 @@ module.exports = dc => { primaryKey: false, field: "country_mil", autoIncrement: false - } + }, + gather: { + type: DataTypes.JSONB, + allowNull: true, + defaultValue: null, + comment: null, + primaryKey: false, + field: "gather", + autoIncrement: false + }, }, { tableName: "road_spot_check_preview", comment: "", diff --git a/api/app/lib/models/town.js b/api/app/lib/models/town.js new file mode 100644 index 00000000..e46472a2 --- /dev/null +++ b/api/app/lib/models/town.js @@ -0,0 +1,42 @@ +/* eslint-disable*/ +'use strict'; + +module.exports = dc => { + const DataTypes = dc.ORM; + const sequelize = dc.orm; + const Town = sequelize.define("town", { + id: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: null, + comment: null, + primaryKey: true, + field: "id", + autoIncrement: true + }, + name: { + type: DataTypes.STRING, + allowNull: true, + defaultValue: null, + comment: null, + primaryKey: false, + field: "name", + autoIncrement: false + }, + code: { + type: DataTypes.STRING, + allowNull: true, + defaultValue: null, + comment: null, + primaryKey: false, + field: "code", + autoIncrement: false + }, + }, { + tableName: "town", + comment: "", + indexes: [] + }); + dc.models.Town = Town; + return Town; +}; \ No newline at end of file diff --git a/api/utils/xlsxDownload.js b/api/utils/xlsxDownload.js index 4db50d5c..9e13f87f 100644 --- a/api/utils/xlsxDownload.js +++ b/api/utils/xlsxDownload.js @@ -52,7 +52,7 @@ async function gatherSheet ({ sheet_2, data = [] }) { } const header = [{ - key: '', + key: 'name', title: '', },{ key: 'county', @@ -64,7 +64,7 @@ async function gatherSheet ({ sheet_2, data = [] }) { key: 'countyPresent', title: '本次考核里程', }, { - key: 'county', + key: 'countyDifferenceValue', title: '实际抽取比原计划多', }, { key: 'township', @@ -76,7 +76,7 @@ async function gatherSheet ({ sheet_2, data = [] }) { key: 'townshipPresent', title: '本次考核里程', }, { - key: 'township', + key: 'townshipDifferenceValue', title: '实际抽取比原计划多', }, { key: 'village', @@ -88,7 +88,7 @@ async function gatherSheet ({ sheet_2, data = [] }) { key: 'villagePresent', title: '本次考核里程', }, { - key: 'village', + key: 'villageDifferenceValue', title: '实际抽取比原计划多', },] @@ -100,24 +100,22 @@ async function gatherSheet ({ sheet_2, data = [] }) { } // data - // const style = new xlsx.Style(); - // style.align.h = 'left'; - // style.align.v = 'center'; - // style.border.right = 'thin'; - // style.border.rightColor = '#000000'; - // style.border.bottom = 'thin'; - // style.border.bottomColor = '#000000'; - // for (let i = 0; i < data.length; i++) { - // const row = sheet_2.addRow(); - // const indexCell = row.addCell(); - // indexCell.value = i + 1 - // indexCell.style = headerStyle - // for (let h of header) { - // const cell = row.addCell(); - // cell.value = data[i][h.key]; - // cell.style = style - // } - // } + const style = new xlsx.Style(); + style.align.h = 'left'; + style.align.v = 'center'; + style.border.right = 'thin'; + style.border.rightColor = '#000000'; + style.border.bottom = 'thin'; + style.border.bottomColor = '#000000'; + + for (let i = 0; i < data.length; i++) { + const row = sheet_2.addRow(); + for (let h of header) { + const cell = row.addCell(); + cell.value = data[i][h.key]; + cell.style = style + } + } } async function simpleExcelDown ({ data = [], header = [], fileName = moment().format('YYYY-MM-DD HH:mm:ss'), exp, gather } = {}) { diff --git a/scripts/1.4.1/schema/3.alter_road_spot_check_preview.sql b/scripts/1.4.1/schema/3.alter_road_spot_check_preview.sql new file mode 100644 index 00000000..ae939228 --- /dev/null +++ b/scripts/1.4.1/schema/3.alter_road_spot_check_preview.sql @@ -0,0 +1,5 @@ +alter table road_spot_check_preview + add gather jsonb; + +comment on column road_spot_check_preview.gather is '抽查汇总'; +