'use strict'; const { QueryTypes } = require('sequelize'); const moment = require('moment'); async function reportList(ctx) { try { const models = ctx.fs.dc.models; const { limit, page, startTime, endTime, keyword, userId, reportType, isTop, asc, projectType, handleState = '', performerId = '', codeRoad } = ctx.query const { userInfo } = ctx.fs.api const sequelize = ctx.fs.dc.orm; let findUsers = [] if ( userInfo.loginSource == 'wx' && userInfo.isAdmin && userInfo.phone != 'SuperAdmin' && (!performerId && !handleState) ) { // 是管理员但不是超管 查自己部门及下级部门的所有用户的信息 const sqlStr = ` WITH RECURSIVE sub_departments AS ( SELECT id, dependence FROM department WHERE id = ${userInfo.departmentId} UNION ALL SELECT d.id, d.dependence FROM sub_departments sd JOIN department d ON sd.id = d.dependence ) SELECT u.id FROM "user" AS u JOIN sub_departments sd ON u.department_id = sd.id WHERE u.delete = false; ` const res = await sequelize.query(sqlStr, { type: QueryTypes.SELECT }) findUsers = res.map(item => { return item.id }) findUsers.push(-1) } let findOption = { where: { }, attributes: ['id', 'road', 'time', 'projectType', 'roadSectionStart', 'performerId', 'roadSectionEnd', 'reportType', 'address', 'content', 'longitude', 'latitude', 'projectName', 'handleState', 'codeRoad', 'handleContent', 'handlePic', 'videoUrl'], include: [{ model: models.User, attributes: ['name'] }], //order: [['time', asc ? 'ASC' : 'DESC']], order: [['time', 'DESC']], } if (limit) { findOption.limit = limit } if (page && limit) { findOption.offset = page * limit } if (startTime && endTime) { findOption.where = { time: { '$between': [startTime, endTime] } } } if (keyword) { if (reportType == 'road') { findOption.where.projectName = { '$like': `%${keyword}%` } } else { findOption.where.road = { '$like': `%${keyword}%` } } } if (userId) { findOption.where.userId = { $in: userId.split(',').map(Number) } } if (findUsers.length) { findOption.where.userId = { $in: findUsers } } if (reportType) { findOption.where.reportType = reportType } if (projectType) { findOption.where.projectType = projectType } if (performerId) { let performerIds = performerId.split(',') findOption.where.performerId = { $in: performerIds } } if (handleState) { let handleStates = handleState.split(',') findOption.where.handleState = { $in: handleStates } } if (codeRoad) { findOption.where.codeRoad = codeRoad } let reportRes = null; if (isTop) { const sqlStr = ` select NR.*, "user".name as user_name from (SELECT R.*, "row_number"() OVER (PARTITION BY R.user_id ORDER BY R."time" DESC) AS NEWINDEX FROM report AS R ${reportType ? ` where report_type = '${reportType}' `: '' } ) AS NR left join "user" on "user".id = NR.user_id WHERE NEWINDEX = 1 order by id desc; ` reportRes = await sequelize.query(sqlStr, { type: QueryTypes.SELECT }); if (reportType == 'road') { const projectNameArr = reportRes.map(item => item.project_name).filter(item => item) const projectRes = projectNameArr.length ? await models.Project.findAll({ where: { entryName: { $in: projectNameArr } } }) : [] for (let r of reportRes) { let corProject = projectRes.find(item => item.entryName == r.project_name) if (corProject) { r.project = corProject.dataValues } } } } else { reportRes = await models.Report.findAll(findOption) } ctx.status = 200; ctx.body = reportRes } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); ctx.status = 400; ctx.body = { message: typeof error == 'string' ? error : undefined } } } async function reportPosition(ctx) { try { const models = ctx.fs.dc.models; const { startTime, endTime, userId, reportType } = ctx.query const sequelize = ctx.fs.dc.ORM; let findMxTimeOption = { attributes: [ 'userId', [sequelize.fn('MAX', sequelize.col('time')), 'maxTime'], ], where: { }, group: ['report.user_id'], } if (startTime && endTime) { findMxTimeOption.where = { time: { '$between': [startTime, endTime] } } } if (userId) { findMxTimeOption.where.userId = userId } if (reportType) { findMxTimeOption.where.reportType = reportType } const reportMaxTimeRes = await models.Report.findAll(findMxTimeOption) const timeArr = reportMaxTimeRes.map(item => item.dataValues.maxTime) const reportRes = await models.Report.findAll({ where: { time: { '$in': timeArr } } }) ctx.status = 200; ctx.body = reportRes } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); ctx.status = 400; ctx.body = { message: typeof error == 'string' ? error : undefined } } } async function reportDetail(ctx) { try { const models = ctx.fs.dc.models; const { reportId } = ctx.params const reportRes = await models.Report.findOne({ where: { id: reportId } }) ctx.status = 200; ctx.body = reportRes } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); ctx.status = 400; ctx.body = { message: typeof error == 'string' ? error : undefined } } } async function reportHandle(ctx) { try { const { models } = ctx.fs.dc; const { reportId } = ctx.params const { handleState } = ctx.request.body const data = ctx.request.body /** * data = { * handleState, * handleContent, * handlePic * } */ await models.Report.update(data, { where: { id: reportId } }) ctx.status = 200; } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); ctx.status = 400; ctx.body = { message: typeof error == 'string' ? error : undefined } } } async function createReport(ctx) { try { const { userId } = ctx.fs.api const models = ctx.fs.dc.models; const data = ctx.request.body; await models.Report.create({ ...data, userId, time: new Date(), }) ctx.status = 204 } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); ctx.status = 400; ctx.body = { message: typeof error == 'string' ? error : undefined } } } async function deleteReport(ctx) { try { const models = ctx.fs.dc.models; const { reportId } = ctx.params; await models.Report.destroy({ where: { id: reportId } }) ctx.status = 204 } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); ctx.status = 400; ctx.body = { message: typeof error == 'string' ? error : undefined } } } // TODO 小程序填写道路名称的时候的道路筛选 是一起都返回 还是不断传关键字搜索返回 async function spotPrepare(ctx) { try { const { models } = ctx.fs.dc; const sequelize = ctx.fs.dc.orm; const { percentage } = ctx.request.body; const departmentIdRes = await models.Department.findAll({ attributes: ['id', 'name'], where: { dependence: null, delete: false, } }) let lukyDepartment = '' if (departmentIdRes.length) { lukyDepartment = departmentIdRes[(Math.round(Math.random() * departmentIdRes.length) || 1) - 1] } else { throw `暂无乡镇信息` } const sqlStr = ` WITH RECURSIVE sub_departments AS ( SELECT id, dependence FROM department WHERE id = ${lukyDepartment.id} UNION ALL SELECT d.id, d.dependence FROM sub_departments sd JOIN department d ON sd.id = d.dependence ) SELECT u.id FROM "user" AS u JOIN sub_departments sd ON u.department_id = sd.id WHERE u.delete = false; ` const userRes = await sequelize.query(sqlStr, { type: QueryTypes.SELECT }) let findUsers = [] findUsers = userRes.map(item => { return item.id }) const reportCount = findUsers.length ? await models.Report.count({ where: { reportType: 'conserve', userId: { $in: findUsers } } }) : 0 const previewRes = await models.ReportSpotCheckPreview.create({ percentage: percentage, departmentId: lukyDepartment.id, date: moment().format(), reportCount: reportCount, checked: false, }) ctx.status = 200; ctx.body = { lukyDepartment, reportCount, previewId: previewRes.id } } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); ctx.status = 400; ctx.body = { message: typeof error == 'string' ? error : undefined } } } async function spotCheck(ctx) { const transaction = await ctx.fs.dc.orm.transaction(); try { const { models } = ctx.fs.dc; const sequelize = ctx.fs.dc.orm; const { previewId } = ctx.query if (!previewId) { throw '参数错误' } const prepareRes = await models.ReportSpotCheckPreview.findOne({ where: { id: previewId } }) const sqlStr = ` WITH RECURSIVE sub_departments AS ( SELECT id, dependence FROM department WHERE id = ${prepareRes.departmentId} UNION ALL SELECT d.id, d.dependence FROM sub_departments sd JOIN department d ON sd.id = d.dependence ) SELECT u.id FROM "user" AS u JOIN sub_departments sd ON u.department_id = sd.id WHERE u.delete = false; ` const userRes = await sequelize.query(sqlStr, { type: QueryTypes.SELECT }) let findUsers = [] findUsers = userRes.map(item => { return item.id }) let checkCount = Math.ceil(prepareRes.reportCount * (prepareRes.percentage / 100)) const reportRes = 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 } })) } await transaction.commit(); ctx.status = 200; ctx.body = reportRes } 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 console.log('txc1', ctx.query) const { startTime, endTime } = ctx.query try { const res = await models.ReportSpotCheck.findAll({ include: [{ model: models.Report, where: { reportType: 'conserve' },//只查养护数据 include: [{ model: models.User, attributes: ['name'] }] }], // offset: pageSize * currentIndex, // limit: Number(pageSize), where: { spotDate: { $between: [moment(startTime).format('YYYY-MM-DD'), moment(endTime).format('YYYY-MM-DD')] } }, order: [['id', 'DESC']] }) 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 } } } module.exports = { reportList, reportPosition, reportDetail, createReport, deleteReport, reportHandle, spotPrepare, spotCheck, spotCheckDetail };