|
|
@@ -7,19 +7,87 @@ import OcrChannel from 'App/Models/OcrChannel'
|
|
|
import { DateTime } from 'luxon'
|
|
|
import * as console from 'node:console'
|
|
|
import Database from '@ioc:Adonis/Lucid/Database'
|
|
|
+import { UserRoles } from 'App/Models/User'
|
|
|
+import UserService from 'App/Services/UserService'
|
|
|
|
|
|
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'
|
|
|
+ public async index({ request, response, auth }: HttpContextContract) {
|
|
|
+ try {
|
|
|
+ const { page = 1, size = 20, id, deviceId, channel } = request.qs()
|
|
|
+ const user = auth.user
|
|
|
+ const role = user?.$attributes?.role
|
|
|
+
|
|
|
+ if (!role) {
|
|
|
+ return response.forbidden({
|
|
|
+ error: 'Forbidden',
|
|
|
+ message: 'Unauthorized access'
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ let userChannel: string | undefined
|
|
|
+
|
|
|
+ if (role === UserRoles.Api) {
|
|
|
+ userChannel = user!.username
|
|
|
+ } else if (['admin', 'operator'].includes(role)) {
|
|
|
+ const apiUsers = await UserService.findReferredUsers(user!.id)
|
|
|
+ const allowedChannels = apiUsers.map((user) => user.username as string)
|
|
|
+
|
|
|
+ // 如果请求中指定了channel,检查是否在允许的channel列表中
|
|
|
+ if (channel) {
|
|
|
+ if (!allowedChannels.includes(channel)) {
|
|
|
+ return response.ok({
|
|
|
+ data: [],
|
|
|
+ meta: {
|
|
|
+ total: 0,
|
|
|
+ per_page: Number(size),
|
|
|
+ current_page: Number(page),
|
|
|
+ last_page: 0,
|
|
|
+ first_page: 1,
|
|
|
+ first_page_url: '/?page=1',
|
|
|
+ last_page_url: '/?page=0',
|
|
|
+ next_page_url: null,
|
|
|
+ previous_page_url: null
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ userChannel = channel
|
|
|
+ } else {
|
|
|
+ userChannel = allowedChannels.join(',')
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return response.forbidden({
|
|
|
+ error: 'Forbidden',
|
|
|
+ message: 'You are not authorized to access this resource'
|
|
|
+ })
|
|
|
+ }
|
|
|
|
|
|
- const requestData = request.all()
|
|
|
- if (isApiUser) {
|
|
|
- requestData.channel = user.username
|
|
|
+ // 构建查询条件
|
|
|
+ const query = OcrDevice.query()
|
|
|
+
|
|
|
+ if (id) {
|
|
|
+ query.where('id', id)
|
|
|
+ }
|
|
|
+
|
|
|
+ if (deviceId) {
|
|
|
+ query.where('id', deviceId)
|
|
|
+ }
|
|
|
+
|
|
|
+ if (userChannel) {
|
|
|
+ query.whereIn('channel', userChannel.split(','))
|
|
|
+ }
|
|
|
+
|
|
|
+ // 执行分页查询
|
|
|
+ const result = await query.orderBy('created_at', 'desc').paginate(page, size)
|
|
|
+
|
|
|
+ return response.ok(result)
|
|
|
+ } catch (error) {
|
|
|
+ return response.internalServerError({
|
|
|
+ message: '获取OCR设备列表时发生错误',
|
|
|
+ error: error.message
|
|
|
+ })
|
|
|
}
|
|
|
- return await this.paginationService.paginate(request.all())
|
|
|
}
|
|
|
|
|
|
public async store({ request, bouncer }: HttpContextContract) {
|
|
|
@@ -126,7 +194,44 @@ export default class OcrDevicesController {
|
|
|
public async getStatistics({ request, response, auth }: HttpContextContract) {
|
|
|
try {
|
|
|
const user = auth.user
|
|
|
- const isApiUser = user?.$attributes?.role === 'api'
|
|
|
+ const role = user?.$attributes?.role
|
|
|
+
|
|
|
+ if (!role) {
|
|
|
+ return response.forbidden({
|
|
|
+ error: 'Forbidden',
|
|
|
+ message: 'Unauthorized access'
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ let userChannel: string | undefined
|
|
|
+
|
|
|
+ if (role === UserRoles.Api) {
|
|
|
+ userChannel = user!.username
|
|
|
+ } else if (['admin', 'operator'].includes(role)) {
|
|
|
+ const apiUsers = await UserService.findReferredUsers(user!.id)
|
|
|
+ const allowedChannels = apiUsers.map((user) => user.username as string)
|
|
|
+
|
|
|
+ // 如果请求中指定了channel,检查是否在允许的channel列表中
|
|
|
+ const requestChannel = request.input('channel')
|
|
|
+ if (requestChannel) {
|
|
|
+ if (!allowedChannels.includes(requestChannel)) {
|
|
|
+ return response.ok({
|
|
|
+ dates: [],
|
|
|
+ total: [],
|
|
|
+ scanned: [],
|
|
|
+ deviceCount: []
|
|
|
+ })
|
|
|
+ }
|
|
|
+ userChannel = requestChannel
|
|
|
+ } else {
|
|
|
+ userChannel = allowedChannels.join(',')
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return response.forbidden({
|
|
|
+ error: 'Forbidden',
|
|
|
+ message: 'You are not authorized to access this resource'
|
|
|
+ })
|
|
|
+ }
|
|
|
|
|
|
// 获取开始日期和结束日期,默认为不包括今天的最近七天
|
|
|
let startDate = request.input(
|
|
|
@@ -200,14 +305,6 @@ export default class OcrDevicesController {
|
|
|
}
|
|
|
|
|
|
// 准备查询条件
|
|
|
- let channelCondition = {}
|
|
|
- if (isApiUser) {
|
|
|
- channelCondition = { channel: user.username }
|
|
|
- } else if (request.input('channel')) {
|
|
|
- channelCondition = { channel: request.input('channel') }
|
|
|
- }
|
|
|
-
|
|
|
- // 使用SQL直接获取每日设备统计数据
|
|
|
const deviceStatsQuery = Database.from('ocr_devices')
|
|
|
.select(
|
|
|
Database.raw("DATE_FORMAT(created_at, '%Y-%m-%d') as date"),
|
|
|
@@ -215,14 +312,10 @@ export default class OcrDevicesController {
|
|
|
Database.raw('SUM(scanned) as scanned_count')
|
|
|
)
|
|
|
.whereBetween('created_at', [startDate, endDate])
|
|
|
+ .whereIn('channel', userChannel!.split(','))
|
|
|
.groupBy('date')
|
|
|
.orderBy('date', 'asc')
|
|
|
|
|
|
- // 添加渠道条件
|
|
|
- if (Object.keys(channelCondition).length > 0) {
|
|
|
- deviceStatsQuery.where(channelCondition)
|
|
|
- }
|
|
|
-
|
|
|
const deviceStats = await deviceStatsQuery
|
|
|
|
|
|
// 使用SQL直接获取每日记录统计数据
|
|
|
@@ -232,14 +325,10 @@ export default class OcrDevicesController {
|
|
|
Database.raw('COUNT(id) as record_count')
|
|
|
)
|
|
|
.whereBetween('created_at', [startDate, endDate])
|
|
|
+ .whereIn('channel', userChannel!.split(','))
|
|
|
.groupBy('date')
|
|
|
.orderBy('date', 'asc')
|
|
|
|
|
|
- // 添加渠道条件
|
|
|
- if (Object.keys(channelCondition).length > 0) {
|
|
|
- recordStatsQuery.where(channelCondition)
|
|
|
- }
|
|
|
-
|
|
|
const recordStats = await recordStatsQuery
|
|
|
|
|
|
// 合并结果
|
|
|
@@ -291,18 +380,43 @@ export default class OcrDevicesController {
|
|
|
public async getTodayStatistics({ request, response, auth }: HttpContextContract) {
|
|
|
try {
|
|
|
const user = auth.user
|
|
|
- const isApiUser = user?.$attributes?.role === 'api'
|
|
|
- const deviceQuery = OcrDevice.query()
|
|
|
+ const role = user?.$attributes?.role
|
|
|
|
|
|
- // 如果是API用户,强制使用其username作为channel
|
|
|
- if (isApiUser) {
|
|
|
- deviceQuery.where('channel', user.username)
|
|
|
- } else {
|
|
|
- // 如果不是API用户,则使用请求中的channel参数
|
|
|
- const channel = request.input('channel')
|
|
|
- if (channel) {
|
|
|
- deviceQuery.where('channel', channel)
|
|
|
+ if (!role) {
|
|
|
+ return response.forbidden({
|
|
|
+ error: 'Forbidden',
|
|
|
+ message: 'Unauthorized access'
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ let userChannel: string | undefined
|
|
|
+
|
|
|
+ if (role === UserRoles.Api) {
|
|
|
+ userChannel = user!.username
|
|
|
+ } else if (['admin', 'operator'].includes(role)) {
|
|
|
+ const apiUsers = await UserService.findReferredUsers(user!.id)
|
|
|
+ const allowedChannels = apiUsers.map((user) => user.username as string)
|
|
|
+
|
|
|
+ // 如果请求中指定了channel,检查是否在允许的channel列表中
|
|
|
+ const requestChannel = request.input('channel')
|
|
|
+ if (requestChannel) {
|
|
|
+ if (!allowedChannels.includes(requestChannel)) {
|
|
|
+ return response.ok({
|
|
|
+ date: request.input('date', DateTime.now().toFormat('yyyy-MM-dd')),
|
|
|
+ total: 0,
|
|
|
+ scanned: 0,
|
|
|
+ deviceCount: 0
|
|
|
+ })
|
|
|
+ }
|
|
|
+ userChannel = requestChannel
|
|
|
+ } else {
|
|
|
+ userChannel = allowedChannels.join(',')
|
|
|
}
|
|
|
+ } else {
|
|
|
+ return response.forbidden({
|
|
|
+ error: 'Forbidden',
|
|
|
+ message: 'You are not authorized to access this resource'
|
|
|
+ })
|
|
|
}
|
|
|
|
|
|
// 获取指定日期的数据,默认为今天
|
|
|
@@ -311,29 +425,21 @@ export default class OcrDevicesController {
|
|
|
const dayEnd = DateTime.fromFormat(targetDate, 'yyyy-MM-dd').endOf('day').toSQL()
|
|
|
|
|
|
// 获取设备数据
|
|
|
- const deviceData = await deviceQuery
|
|
|
- .where('createdAt', '>=', dayStart)
|
|
|
- .where('createdAt', '<=', dayEnd)
|
|
|
+ const deviceData = await Database.from('ocr_devices')
|
|
|
+ .where('created_at', '>=', dayStart)
|
|
|
+ .where('created_at', '<=', dayEnd)
|
|
|
+ .whereIn('channel', userChannel!.split(','))
|
|
|
.select('scanned')
|
|
|
|
|
|
// 获取OcrRecord数据
|
|
|
const recordCount = await Database.from('ocr_records')
|
|
|
.where('created_at', '>=', dayStart)
|
|
|
.where('created_at', '<=', dayEnd)
|
|
|
- .where(function (query) {
|
|
|
- if (isApiUser) {
|
|
|
- query.where('channel', user.username)
|
|
|
- } else {
|
|
|
- const channel = request.input('channel')
|
|
|
- if (channel) {
|
|
|
- query.where('channel', channel)
|
|
|
- }
|
|
|
- }
|
|
|
- })
|
|
|
+ .whereIn('channel', userChannel!.split(','))
|
|
|
.count('* as total')
|
|
|
|
|
|
// 计算统计数据
|
|
|
- const scanned = deviceData.reduce((acc, item) => acc + item.scanned, 0)
|
|
|
+ const scanned = deviceData.reduce((acc, item) => acc + Number(item.scanned || 0), 0)
|
|
|
const total = Number(recordCount[0].total) || 0
|
|
|
const deviceCount = deviceData.length
|
|
|
|