diff --git a/api/app/lib/controllers/data/road.js b/api/app/lib/controllers/data/road.js index b12d1a67..38a41386 100644 --- a/api/app/lib/controllers/data/road.js +++ b/api/app/lib/controllers/data/road.js @@ -1,202 +1,212 @@ 'use strict'; const roadKeyMap = require('./road.json') -async function importIn(ctx) { - // 数据导入 - try { - const models = ctx.fs.dc.models; - const { level, } = ctx.query; - const data = ctx.request.body; - - const roadRes = await models.Road.findAll({ - where: { - level - } - }) - let preCreateArr = [] - for (let d of data) { - if (roadRes.some(r => r.routeCode + r.sectionNo == d['路线代码'] + d['路段序号'])) { - //repeat - } else { - // await models.Road.create(d); - } - } - - 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 importIn (ctx) { + // 数据导入 + try { + const models = ctx.fs.dc.models; + const { level, } = ctx.query; + const data = ctx.request.body; + + const roadRes = await models.Road.findAll({ + where: { + level, + del: false + } + }) + let preCreateArr = [] + for (let d of data) { + if (roadRes.some(r => r.routeCode + r.sectionNo == d['路线代码'] + d['路段序号'])) { + //repeat + } else { + // await models.Road.create(d); + } + } + + 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 get(ctx) { - try { - const models = ctx.fs.dc.models; - const { codePrefix, level, road, sectionStart, sectionEnd, alterId } = ctx.query; - - let findOption = { - where: {}, - order: [['id', 'DESC']], - } - if (level == '村') { - findOption.include = [{ model: models.Village, }] - } - if (alterId) { - findOption.where.id = { $notIn: alterId } - } - - if (codePrefix) { - findOption.where.routeCode = { $like: `${codePrefix}%` } - } - - if (level) { - findOption.where.level = level - } - if (road || sectionStart || sectionEnd) { - findOption.where['$or'] = {} - if (road) { - findOption.where['$or']. - routeName = { $like: `%${road}%` } - } - if (sectionStart) { - findOption.where['$or']. - startingPlaceName = { $like: `%${sectionStart}%` } - - } - if (sectionEnd) { - findOption.where['$or']. - stopPlaceName = { $like: `%${sectionEnd}%` } - - } - } - - const roadRes = await models.Road.findAll(findOption) - - ctx.status = 200; - ctx.body = roadRes - } catch (error) { - ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); - ctx.status = 400; - ctx.body = { - message: typeof error == 'string' ? error : undefined - } - } -} +async function get (ctx) { + try { + const models = ctx.fs.dc.models; + const { codePrefix, level, road, sectionStart, sectionEnd, alterId } = ctx.query; + + let findOption = { + where: { + del: false + }, + order: [['id', 'DESC']], + } + if (level == '村') { + findOption.include = [{ model: models.Village, }] + } + if (alterId) { + findOption.where.id = { $notIn: alterId } + } + + if (codePrefix) { + findOption.where.routeCode = { $like: `${codePrefix}%` } + } + + if (level) { + findOption.where.level = level + } + if (road || sectionStart || sectionEnd) { + findOption.where['$or'] = {} + if (road) { + findOption.where['$or']. + routeName = { $like: `%${road}%` } + } + if (sectionStart) { + findOption.where['$or']. + startingPlaceName = { $like: `%${sectionStart}%` } + + } + if (sectionEnd) { + findOption.where['$or']. + stopPlaceName = { $like: `%${sectionEnd}%` } -async function getRoadSection(ctx) { - try { - const models = ctx.fs.dc.models; - const { level, road, sectionStart, sectionEnd } = ctx.query; - let findOption = { - where: {}, - order: [['id', 'DESC']], - attributes: ['id', 'routeName', 'startingPlaceName', 'stopPlaceName', 'routeCode', 'sectionNo', 'level'] - } - - if (level) { - findOption.where.level = level - } - if (road || sectionStart || sectionEnd) { - findOption.where['$or'] = {} - if (road) { - findOption.where['$or']. - routeName = { $like: `%${road}%` } - } - if (sectionStart) { - findOption.where['$or']. - startingPlaceName = { $like: `%${sectionStart}%` } - - } - if (sectionEnd) { - findOption.where['$or']. - stopPlaceName = { $like: `%${sectionEnd}%` } - } - } - - const roadRes = await models.Road.findAll(findOption) - - ctx.status = 200; - ctx.body = roadRes - } catch (error) { - ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); - ctx.status = 400; - ctx.body = { - message: typeof error == 'string' ? error : undefined - } - } + } + } + + const roadRes = await models.Road.findAll(findOption) + + ctx.status = 200; + ctx.body = roadRes + } catch (error) { + ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); + ctx.status = 400; + ctx.body = { + message: typeof error == 'string' ? error : undefined + } + } } -async function edit(ctx) { - try { - const models = ctx.fs.dc.models; - const data = ctx.request.body; +async function getRoadSection (ctx) { + try { + const models = ctx.fs.dc.models; + const { level, road, sectionStart, sectionEnd } = ctx.query; + let findOption = { + where: {}, + order: [['id', 'DESC']], + attributes: ['id', 'routeName', 'startingPlaceName', 'stopPlaceName', 'routeCode', 'sectionNo', 'level'] + } + + if (level) { + findOption.where.level = level + } + if (road || sectionStart || sectionEnd) { + findOption.where['$or'] = {} + if (road) { + findOption.where['$or']. + routeName = { $like: `%${road}%` } + } + if (sectionStart) { + findOption.where['$or']. + startingPlaceName = { $like: `%${sectionStart}%` } - if (!data.roadId) { - await models.Road.create(data) - } else { - await models.Road.update( - data, { - where: { - id: data.roadId } - }) - } - - 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 - } - } + if (sectionEnd) { + findOption.where['$or']. + stopPlaceName = { $like: `%${sectionEnd}%` } + } + } + + const roadRes = await models.Road.findAll(findOption) + + ctx.status = 200; + ctx.body = roadRes + } catch (error) { + ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); + ctx.status = 400; + ctx.body = { + message: typeof error == 'string' ? error : undefined + } + } } -async function del(ctx) { - try { - const models = ctx.fs.dc.models; - const { roadId } = ctx.params; - - await models.Road.destroy({ - where: { - id: roadId - } - }) - - 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 edit (ctx) { + try { + const models = ctx.fs.dc.models; + const data = ctx.request.body; + + if (!data.roadId) { + await models.Road.create(data) + } else { + await models.Road.update( + data, { + where: { + id: data.roadId + } + }) + } + + 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 del (ctx) { + try { + const models = ctx.fs.dc.models; + const { roadId } = ctx.params; + + // await models.Road.destroy({ + // where: { + // id: roadId + // } + // }) + await models.Road.update({ + del: true + }, { + where: { + id: roadId + } + }) + + 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 getVillageList(ctx) { - try { - const models = ctx.fs.dc.models; - const { } = ctx.query; - - const res = await models.Village.findAll() - - ctx.status = 200; - ctx.body = res - } catch (error) { - ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); - ctx.status = 400; - ctx.body = { - message: typeof error == 'string' ? error : undefined - } - } +async function getVillageList (ctx) { + try { + const models = ctx.fs.dc.models; + const { } = ctx.query; + + const res = await models.Village.findAll() + + ctx.status = 200; + ctx.body = res + } catch (error) { + ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); + ctx.status = 400; + ctx.body = { + message: typeof error == 'string' ? error : undefined + } + } } module.exports = { - importIn, - getRoadSection, - get, edit, del, - getVillageList, + importIn, + getRoadSection, + get, edit, del, + getVillageList, }; \ No newline at end of file diff --git a/api/app/lib/controllers/data/task.js b/api/app/lib/controllers/data/task.js index 70b86d68..6bdfa745 100644 --- a/api/app/lib/controllers/data/task.js +++ b/api/app/lib/controllers/data/task.js @@ -1,6 +1,6 @@ 'use strict'; -async function getTask(ctx) { +async function getTask (ctx) { try { const models = ctx.fs.dc.models const query = ctx.query @@ -8,7 +8,8 @@ async function getTask(ctx) { isdanger: query.isdanger } const whereRoadOpt = { - id: query.id + id: query.id, + del: false } const taskRes = await models.TaskManage.findAndCountAll({ order: [['id', 'DESC']], @@ -40,7 +41,7 @@ async function getTask(ctx) { } //删除任务 -async function delTask(ctx) { +async function delTask (ctx) { try { const models = ctx.fs.dc.models const { id } = ctx.params @@ -56,12 +57,12 @@ async function delTask(ctx) { } //编辑任务 -async function editTask(ctx) { +async function editTask (ctx) { //const transaction = await ctx.fs.dc.orm.transaction(); try { const models = ctx.fs.dc.models const params = ctx.request.body - const road = await models.Road.findOne({ where: { id: params.routeId } }) + const road = await models.Road.findOne({ where: { id: params.routeId, del: false } }) const user = await models.User.findOne({ where: { id: params.userId } }) if (!params.id) { await models.TaskManage.create({ diff --git a/api/app/lib/controllers/overview/building.js b/api/app/lib/controllers/overview/building.js index df819587..54ef4202 100644 --- a/api/app/lib/controllers/overview/building.js +++ b/api/app/lib/controllers/overview/building.js @@ -27,12 +27,14 @@ const areaCode = { "360121572000": "良种繁殖场", } -async function roadState(ctx) { +async function roadState (ctx) { try { const models = ctx.fs.dc.models; const { userId } = ctx.fs.api; - const roadRes = await models.Road.findAll({}) + const roadRes = await models.Road.findAll({ + del: false + }) const projectRoadRes = await models.Project.findAll({ type: 'road', }) diff --git a/api/app/lib/controllers/report/index.js b/api/app/lib/controllers/report/index.js index 08412723..3ad56cf2 100644 --- a/api/app/lib/controllers/report/index.js +++ b/api/app/lib/controllers/report/index.js @@ -4,21 +4,21 @@ 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 = ` + 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,292 +34,295 @@ 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) - } - - 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}%` + 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] + } } - } else { - findOption.where.road = { - '$like': `%${keyword}%` + } + 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 = ` + } + 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: { - - }, - group: ['report.user_id'], - } - - if (startTime && endTime) { - findMxTimeOption.where = { - time: { - '$between': [startTime, endTime] + 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 } } - } - } - - 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 - } - } + }) + 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, - 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 - } - } + 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 - } - } + 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 - } - } + 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 - } - } + 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 = ` + 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 @@ -335,60 +338,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 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 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 = ` + 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 @@ -404,314 +407,320 @@ 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 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 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 rslt = findUsers.length && checkCount ? await models.ReportSpotCheckPreview.findAll({ - where: { - checked: 'true', - id: previewId - }, - include: [{ - model: models.Department, - attributes: ['name'] - }, { - model: models.ReportSpotCheck, + }) + 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.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.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']], + 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.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.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; + 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({ + const lastSpotRes = await models.RoadSpotCheckPreview.findOne({ where: { - checked: true, - id: { $lt: lastSpotRes.id } + checked: true }, - limit: 3, + // 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) || [] + 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']], }) - } - 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) || [] - 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(` + + // 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 ${keyMap[key]} ${otherWhere.length ? `AND ${otherWhere.join(' AND ')}` : ''} + 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(` + 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 ${keyMap[key]} + 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) { + + } 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) + 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) } - } else { - await filterRoad(otherWhere, true) - } - return spotRoadIds - } + return spotRoadIds + } - // 抽县 - const countryRoadTotalMileage = await getRoadTotalMileage('县') - const countryRoadNeedMileage = countryRoadTotalMileage * countyPercentage / 100 - let spotCountyRoadIds = await spotRoadId('县', lastCountyRoadIds, countryRoadNeedMileage, []) + // 抽县 + const countryRoadTotalMileage = await getRoadTotalMileage('县') + const countryRoadNeedMileage = countryRoadTotalMileage * countyPercentage / 100 + let spotCountyRoadIds = await spotRoadId('县', lastCountyRoadIds, countryRoadNeedMileage, []) - // 抽乡 - const allTownCodeRes = await sequelize.query(` + // 抽乡 + const allTownCodeRes = await sequelize.query(` SELECT DISTINCT township_code FROM road - WHERE township_code IS NOT NULL + 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(` + 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 ( @@ -720,80 +729,80 @@ 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; - } - - const villageNearRes = await sequelize.query(` + } + 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 - } - } + 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(` + 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 ( @@ -802,387 +811,392 @@ 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 - }) - } - - 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 - } - } + 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 + 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 - } - } + 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, + try { + const { models } = ctx.fs.dc; + const { previewId, keyword } = ctx.query + + const listRes = await models.RoadSpotCheck.findAll({ where: { - ...(keyword ? { routeName: { $ilike: `%${keyword}%` } } : {}) + prepareId: previewId, }, - }, { - model: models.RoadSpotCheckPreview, - attributes: ['id'], include: [{ - model: models.RoadSpotCheckChangeLog, - attributes: ['id', 'changeRoadId'], + 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 - } - } + }) + + + 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] } - } - }) - - 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(` + 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, + 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 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 - } - } + }, { + 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()] + 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 - } - } + } + + 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, - }] - }) - - 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 '村道' + 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, } - 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 - } - } + }) + + 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 + } + } } 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.js b/api/app/lib/models/road.js index 3d23b92d..9ccc468b 100644 --- a/api/app/lib/models/road.js +++ b/api/app/lib/models/road.js @@ -784,7 +784,25 @@ module.exports = dc => { primaryKey: false, field: "village_id", autoIncrement: false - } + }, + del: { + type: DataTypes.BOOLEAN, + allowNull: true, + defaultValue: false, + comment: null, + primaryKey: false, + field: "del", + autoIncrement: false + }, + spot: { + type: DataTypes.BOOLEAN, + allowNull: true, + defaultValue: true, + comment: null, + primaryKey: false, + field: "spot", + autoIncrement: false + }, }, { tableName: "road", comment: "", diff --git a/scripts/1.4.0/data/2_update_road_data_无需执行/.vscode/launch.json b/scripts/1.4.0/data/2_update_road_data_无需执行/.vscode/launch.json new file mode 100644 index 00000000..3a3fcba2 --- /dev/null +++ b/scripts/1.4.0/data/2_update_road_data_无需执行/.vscode/launch.json @@ -0,0 +1,17 @@ +{ + // 使用 IntelliSense 了解相关属性。 + // 悬停以查看现有属性的描述。 + // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "启动程序", + "skipFiles": [ + "/**" + ], + "program": "${workspaceFolder}\\index.js" + } + ] +} \ No newline at end of file diff --git a/scripts/1.4.0/data/2_update_road_data_无需执行/Dockerfile b/scripts/1.4.0/data/2_update_road_data_无需执行/Dockerfile new file mode 100644 index 00000000..d0293a8f --- /dev/null +++ b/scripts/1.4.0/data/2_update_road_data_无需执行/Dockerfile @@ -0,0 +1,11 @@ +FROM repository.anxinyun.cn/base-images/nodejs12:20.10.12.2 + +COPY . /var/app + +WORKDIR /var/app + +RUN npm cache clean -f +RUN rm -rf package-lock.json +RUN npm install --registry http://10.8.30.22:7000 + +CMD ["node", "index.js"] \ No newline at end of file diff --git a/scripts/1.4.0/data/2_update_road_data_无需执行/Dockerfilenew b/scripts/1.4.0/data/2_update_road_data_无需执行/Dockerfilenew new file mode 100644 index 00000000..dba16607 --- /dev/null +++ b/scripts/1.4.0/data/2_update_road_data_无需执行/Dockerfilenew @@ -0,0 +1,7 @@ +FROM repository.anxinyun.cn/base-images/nodejs12:20.10.12.2 +COPY ./scripts/1.3.1/data/1_insert_report_data /var/app +WORKDIR /var/app +RUN npm cache clean -f +RUN rm -rf package-lock.json +RUN npm install --registry https://nexus.ngaiot.com/repository/fs-npm/ +CMD ["node", "index.js"] \ No newline at end of file diff --git a/scripts/1.4.0/data/2_update_road_data_无需执行/data/乡道(新)(1).xlsx b/scripts/1.4.0/data/2_update_road_data_无需执行/data/乡道(新)(1).xlsx new file mode 100644 index 00000000..4b264b40 Binary files /dev/null and b/scripts/1.4.0/data/2_update_road_data_无需执行/data/乡道(新)(1).xlsx differ diff --git a/scripts/1.4.0/data/2_update_road_data_无需执行/index.js b/scripts/1.4.0/data/2_update_road_data_无需执行/index.js new file mode 100644 index 00000000..247cb847 --- /dev/null +++ b/scripts/1.4.0/data/2_update_road_data_无需执行/index.js @@ -0,0 +1,58 @@ +try { + const { Pool, Client } = require('pg') + const XLSX = require('xlsx') + const path = require('path') + const fs = require("fs"); + + // 测试环境 + const pool = new Pool({ + user: 'postgres', + host: '10.8.30.32', + database: 'highways4good', + password: '123', + port: 5432, + }) + + const fun = async () => { + // note: we don't try/catch this because if connecting throws an exception + // we don't need to dispose of the client (it will be undefined) + const client = await pool.connect() + try { + await client.query('BEGIN') + console.log(`开始`); + + // 读取数据文件 + let workbook = XLSX.readFile(path.join(__dirname, './data/乡道(新)(1).xlsx')); + let firstSheetName = workbook.SheetNames[0]; + let worksheet = workbook.Sheets[firstSheetName]; + let res = XLSX.utils.sheet_to_json(worksheet, { + defval: '' + }); + + for (let r of res) { + console.log(r); + fs.writeFileSync('AnswerOld.sql', `;\n`, 'utf-8'); + // let time = generateRandomTimeString() + // console.log(time); + // await client.query( + // `INSERT INTO report (report_type, project_type, road, time,content,user_id) VALUES($1, $2, $3, $4, $5, $6) `, + // ['conserve', 'road', r['养护道路'], time, r['养护内容'], userId]) + // // break + } + + // await client.query('ROLLBACK') + await client.query('COMMIT') + console.log('执行完毕~') + } catch (e) { + await client.query('ROLLBACK') + console.log('执行错误~') + throw e + } finally { + client.release(); + } + } + + fun() +} catch (error) { + console.error(error) +} diff --git a/scripts/1.4.0/data/2_update_road_data_无需执行/package.json b/scripts/1.4.0/data/2_update_road_data_无需执行/package.json new file mode 100644 index 00000000..7da06c06 --- /dev/null +++ b/scripts/1.4.0/data/2_update_road_data_无需执行/package.json @@ -0,0 +1,17 @@ +{ + "name": "appkey-generator", + "version": "1.0.0", + "description": "tool", + "main": "index.js", + "scripts": { + "test": "mocha", + "start": "set NODE_ENV=development&&node index" + }, + "author": "liu", + "license": "ISC", + "dependencies": { + "crypto-js": "^4.1.1", + "pg": "^7.18.2", + "xlsx": "^0.17.1" + } +} diff --git a/scripts/1.4.0/schema/5.update_road.sql b/scripts/1.4.0/schema/5.update_road.sql new file mode 100644 index 00000000..3d598635 --- /dev/null +++ b/scripts/1.4.0/schema/5.update_road.sql @@ -0,0 +1,9 @@ +alter table road + add del bool default false; + +alter table road + add spot bool default true; + +comment on column road.del is '标志道路是否被删除'; + +comment on column road.spot is '是否应该在抽查中被抽取'; \ No newline at end of file