'use strict'; const { QueryTypes } = require('sequelize'); async function reportList (ctx) { try { const models = ctx.fs.dc.models; const { limit, page, startTime, endTime, keyword, userId, reportType, isTop, asc, projectType, handleState = '', performerId = '' } = 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', 'content', 'longitude', 'latitude', 'projectName', 'handleState', 'codeRoad'], include: [{ model: models.User, attributes: ['name'] }], order: [['time', asc ? 'ASC' : '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 = userId } 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) { findOption.where.handleState = handleState } let reportRes = null; if (isTop) { const sqlStr = 'select * from (SELECT R.*, "row_number"() OVER(PARTITION BY R.user_id ORDER BY R."time" DESC) AS NEWINDEX FROM report AS R ) AS NR WHERE NEWINDEX = 1' reportRes = await sequelize.query(sqlStr, { type: QueryTypes.SELECT }); } 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 小程序填写道路名称的时候的道路筛选 是一起都返回 还是不断传关键字搜索返回 module.exports = { reportList, reportPosition, reportDetail, createReport, deleteReport, reportHandle };