| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
- import PaginationService from 'App/Services/PaginationService'
- import { schema } from '@ioc:Adonis/Core/Validator'
- import OcrDevice from 'App/Models/OcrDevice'
- import OcrRecord from 'App/Models/OcrRecord'
- import { DateTime } from 'luxon'
- import * as console from 'node:console'
- import Database from '@ioc:Adonis/Lucid/Database'
- export default class OcrDevicesController {
- private paginationService = new PaginationService(OcrDevice)
- public async index({ request, auth }: HttpContextContract) {
- const user = auth.user
- const isApiUser = user?.$attributes?.role === 'api'
- const requestData = request.all()
- if (isApiUser) {
- requestData.channel = user.username
- }
- return await this.paginationService.paginate(request.all())
- }
- public async store({ request, bouncer }: HttpContextContract) {
- // await bouncer.authorize('admin')
- const data = await request.validate({
- schema: schema.create({
- id: schema.string(),
- platform: schema.string(),
- channel: schema.string(),
- deviceInfo: schema.string.optional(),
- total: schema.number(),
- scanned: schema.number(),
- ipAddress: schema.string.optional()
- })
- })
- const clientIp = request.ip()
- if (!data.ipAddress) {
- data.ipAddress = clientIp
- }
- const device = await OcrDevice.findBy('id', data.id)
- if (device) {
- device.merge(data)
- return await device.save()
- } else {
- return await OcrDevice.create(data)
- }
- }
- public async show({ params, bouncer }: HttpContextContract) {
- await bouncer.authorize('admin')
- return await OcrDevice.findOrFail(params.id)
- }
- public async plusTotal({ request, response }: HttpContextContract) {
- try {
- const device = await OcrDevice.findBy('id', request.param('id'))
- if (!device) {
- return response.notFound({ message: `未找到ID为 ${request.param('id')} 的OCR设备` })
- }
- device.total += 1
- await device.save()
- return response.ok(device)
- } catch (error) {
- return response.internalServerError({
- message: '更新设备记录数量时发生错误',
- error: error.message
- })
- }
- }
- public async plusScanned({ request, response }: HttpContextContract) {
- const scanCount = Number(request.param('scanCount'))
- if (isNaN(scanCount)) {
- return response.badRequest({ message: 'scanCount 参数必须是有效数字' })
- }
- try {
- const device = await OcrDevice.findBy('id', request.param('id'))
- if (!device) {
- return response.notFound({
- message: `未找到 ID 为 ${request.param('id')} 的 OCR 设备`
- })
- }
- device.scanned += scanCount
- await device.save()
- return response.ok(device)
- } catch (error) {
- return response.internalServerError({
- message: '更新设备扫描数量时发生错误',
- error: error.message
- })
- }
- }
- public async getStatistics({ request, response, auth }: HttpContextContract) {
- try {
- const user = auth.user
- const isApiUser = user?.$attributes?.role === 'api'
- const deviceQuery = OcrDevice.query()
- const recordQuery = OcrRecord.query()
- if (isApiUser) {
- deviceQuery.where('channel', user.username)
- recordQuery.where('channel', user.username)
- } else {
- const channel = request.input('channel')
- if (channel) {
- deviceQuery.where('channel', channel)
- recordQuery.where('channel', channel)
- }
- }
- // 获取近7天的数据
- const sevenDaysAgo = DateTime.now().minus({ days: 7 }).startOf('day').toSQL()
- const devices = await deviceQuery
- .where('createdAt', '>=', sevenDaysAgo)
- .select('id', 'total', 'scanned', 'createdAt', 'channel')
- // 过去7天的日期数组
- const dates: string[] = []
- for (let i = 6; i >= 0; i--) {
- const date = DateTime.now().minus({ days: i }).toFormat('yyyy-MM-dd')
- dates.push(date)
- }
- const dailyStats: Record<
- string,
- { total: number; scanned: number; deviceCount: number }
- > = {}
- dates.forEach((date) => {
- dailyStats[date] = {
- total: 0,
- scanned: 0,
- deviceCount: 0
- }
- })
- // 按设备创建日期统计数据 scanned和deviceCount
- for (const device of devices) {
- const dateStr = device.createdAt.toFormat('yyyy-MM-dd')
- if (dailyStats[dateStr]) {
- dailyStats[dateStr].scanned += device.scanned
- dailyStats[dateStr].deviceCount += 1
- }
- }
- // 获取OcrRecord的每日数量
- for (const date of dates) {
- const startDate = DateTime.fromFormat(date, 'yyyy-MM-dd').startOf('day').toSQL()
- const endDate = DateTime.fromFormat(date, 'yyyy-MM-dd').endOf('day').toSQL()
- const recordCount = await Database.from('ocr_records')
- .where('created_at', '>=', startDate)
- .where('created_at', '<=', endDate)
- .count('* as total')
- dailyStats[date].total = Number(recordCount[0].total) || 0
- }
- // 转换为前端需要的数组格式
- const totals = dates.map((date) => dailyStats[date].total)
- const scanned = dates.map((date) => dailyStats[date].scanned)
- const deviceCounts = dates.map((date) => dailyStats[date].deviceCount)
- return response.ok({
- dates,
- total: totals,
- scanned: scanned,
- deviceCount: deviceCounts
- })
- } catch (error) {
- return response.internalServerError({
- message: '获取设备统计数据时发生错误',
- error: error.message
- })
- }
- }
- public async getTodayStatistics({ request, response, auth }: HttpContextContract) {
- try {
- const user = auth.user
- const isApiUser = user?.$attributes?.role === 'api'
- const deviceQuery = OcrDevice.query()
- const recordQuery = OcrRecord.query()
- // 如果是 API 用户,强制使用其 username 作为 channel
- if (isApiUser) {
- deviceQuery.where('channel', user.username)
- recordQuery.where('channel', user.username)
- } else {
- // 如果不是 API 用户,则使用请求中的 channel 参数
- const channel = request.input('channel')
- if (channel) {
- deviceQuery.where('channel', channel)
- recordQuery.where('channel', channel)
- }
- }
- // 获取今天的数据
- const today = DateTime.now().startOf('day').toSQL()
- const todayEnd = DateTime.now().endOf('day').toSQL()
- // 获取设备数据
- const deviceData = await deviceQuery.where('createdAt', '>=', today).select('scanned')
- // 获取OcrRecord数据
- const recordCount = await Database.from('ocr_records')
- .where('created_at', '>=', today)
- .where('created_at', '<=', todayEnd)
- .count('* as total')
- // 计算今日统计数据
- const scanned = deviceData.reduce((acc, item) => acc + item.scanned, 0)
- const total = Number(recordCount[0].total) || 0
- const deviceCount = deviceData.length
- return response.ok({
- date: DateTime.now().toFormat('yyyy-MM-dd'),
- total,
- scanned,
- deviceCount
- })
- } catch (error) {
- return response.internalServerError({
- message: '获取今日统计数据时发生错误',
- error: error.message
- })
- }
- }
- }
|