OcrChannelController.ts 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
  2. import PaginationService from 'App/Services/PaginationService'
  3. import OcrChannel from 'App/Models/OcrChannel'
  4. import { schema } from '@ioc:Adonis/Core/Validator'
  5. import { DateTime } from 'luxon'
  6. import OcrDevice from 'App/Models/OcrDevice'
  7. import OcrRecord from 'App/Models/OcrRecord'
  8. import * as console from 'node:console'
  9. import Database from '@ioc:Adonis/Lucid/Database'
  10. export default class OcrChannelController {
  11. private paginationService = new PaginationService(OcrChannel)
  12. public async index({ request, bouncer }: HttpContextContract) {
  13. return await this.paginationService.paginate(request.all())
  14. }
  15. public async store({ request, bouncer }: HttpContextContract) {
  16. await request.validate({
  17. schema: schema.create({
  18. name: schema.string.optional(),
  19. deviceNum: schema.number(),
  20. recordNum: schema.number(),
  21. scanNum: schema.number()
  22. })
  23. })
  24. return await OcrChannel.create(request.all())
  25. }
  26. public async show({ params, bouncer }: HttpContextContract) {
  27. await bouncer.authorize('admin')
  28. return await OcrChannel.findOrFail(params.id)
  29. }
  30. public async update({ params, request, bouncer }: HttpContextContract) {
  31. await bouncer.authorize('admin')
  32. const ocrChannel = await OcrChannel.findOrFail(params.id)
  33. const data = await request.validate({
  34. schema: schema.create({
  35. name: schema.string.optional(),
  36. deviceNum: schema.number.optional(),
  37. recordNum: schema.number.optional(),
  38. scanNum: schema.number.optional()
  39. })
  40. })
  41. return await ocrChannel.merge(data).save()
  42. }
  43. public async findApiChannel({ auth, response }: HttpContextContract) {
  44. if (!auth.user) {
  45. return response.unauthorized({ message: 'unauthorized' })
  46. }
  47. return await OcrChannel.findBy('name', auth.user.username)
  48. }
  49. public async plusDeviceNum({ request, response }: HttpContextContract) {
  50. try {
  51. const ocrChannel = await OcrChannel.findBy('id', request.param('id'))
  52. if (!ocrChannel) {
  53. return response.notFound({ message: `未找到ID为 ${request.param('id')} 的OCR渠道` })
  54. }
  55. ocrChannel.deviceNum += 1
  56. await ocrChannel.save()
  57. return ocrChannel
  58. } catch (error) {
  59. return response.internalServerError({
  60. message: '更新设备数量时发生错误',
  61. error: error.message
  62. })
  63. }
  64. }
  65. public async plusRecordNum({ request, response }: HttpContextContract) {
  66. try {
  67. const ocrChannel = await OcrChannel.findBy('id', request.param('id'))
  68. if (!ocrChannel) {
  69. return response.notFound({ message: `未找到ID为 ${request.param('id')} 的OCR渠道` })
  70. }
  71. ocrChannel.recordNum += 1
  72. await ocrChannel.save()
  73. return ocrChannel
  74. } catch (error) {
  75. return response.internalServerError({
  76. message: '更新记录数量时发生错误',
  77. error: error.message
  78. })
  79. }
  80. }
  81. public async plusScanNum({ request, response }: HttpContextContract) {
  82. const scanCount = Number(request.param('scanCount'))
  83. if (isNaN(scanCount)) {
  84. return response.badRequest({ message: 'scanCount 参数必须是有效数字' })
  85. }
  86. try {
  87. const ocrChannel = await OcrChannel.findBy('id', request.param('id'))
  88. if (!ocrChannel) {
  89. return response.notFound({
  90. message: `未找到 ID 为 ${request.param('id')} 的 OCR 渠道`
  91. })
  92. }
  93. ocrChannel.scanNum = (Number(ocrChannel.scanNum) || 0) + scanCount
  94. await ocrChannel.save()
  95. return response.ok(ocrChannel)
  96. } catch (error) {
  97. return response.internalServerError({
  98. message: '更新扫描数量时发生错误',
  99. error: error.message
  100. })
  101. }
  102. }
  103. public async getStatistics({ request, response }: HttpContextContract) {
  104. try {
  105. const name = request.input('name')
  106. let query = Database.from('ocr_channels')
  107. if (name) {
  108. query = query.where('name', name)
  109. }
  110. const sevenDaysAgo = DateTime.now().minus({ days: 7 }).startOf('day').toSQL()
  111. const data = await query
  112. .where('created_at', '>=', sevenDaysAgo)
  113. .orderBy('created_at', 'asc')
  114. .select('created_at', 'device_num as deviceNum', 'record_num as recordNum', 'scan_num as scanNum')
  115. const result = {
  116. dates: data.map((item) => DateTime.fromISO(item.created_at).toFormat('yyyy-MM-dd')),
  117. deviceNum: data.map((item) => item.deviceNum),
  118. recordNum: data.map((item) => item.recordNum),
  119. scanNum: data.map((item) => item.scanNum)
  120. }
  121. return response.ok(result)
  122. } catch (error) {
  123. return response.internalServerError({
  124. message: '获取统计数据时发生错误',
  125. error: error.message
  126. })
  127. }
  128. }
  129. public async getChannelNames({ auth, response }: HttpContextContract) {
  130. try {
  131. const user = auth.user
  132. const role = user?.$attributes?.role
  133. // 验证管理员或操作员权限
  134. if (role !== 'admin' && role !== 'operator') {
  135. return response.forbidden({
  136. message: 'unauthorized'
  137. })
  138. }
  139. // 获取所有渠道名称
  140. const channels = await OcrChannel.query().select('name').orderBy('name', 'asc')
  141. return response.ok({
  142. data: channels.map((channel) => channel.name)
  143. })
  144. } catch (error) {
  145. return response.internalServerError({
  146. message: '获取渠道名称列表时发生错误',
  147. error: error.message
  148. })
  149. }
  150. }
  151. public async updateStatistics({ response }: HttpContextContract) {
  152. try {
  153. // 获取所有渠道
  154. const channels = await OcrChannel.all()
  155. const results: any[] = []
  156. for (const channel of channels) {
  157. // 使用Database查询生成器直接执行SQL查询
  158. // 获取设备数量
  159. const deviceCountResult = await Database.from('ocr_devices')
  160. .where('channel', channel.name)
  161. .count('* as total')
  162. console.log('deviceCountResult', deviceCountResult)
  163. // 获取记录数量
  164. const recordCountResult = await Database.from('ocr_records')
  165. .where('channel', channel.name)
  166. .count('* as total')
  167. // 获取扫描数量总和
  168. const scanSumResult = await Database.from('ocr_devices')
  169. .where('channel', channel.name)
  170. .sum('scanned as total')
  171. console.log('scanSumResult', scanSumResult)
  172. // 确保数值正确转换为数字
  173. const deviceNum = parseInt(deviceCountResult[0].total || '0', 10)
  174. const recordNum = parseInt(recordCountResult[0].total || '0', 10)
  175. const scanNum = parseInt(scanSumResult[0].total || '0', 10)
  176. // 更新渠道数据
  177. channel.deviceNum = deviceNum
  178. channel.recordNum = recordNum
  179. channel.scanNum = scanNum
  180. await channel.save()
  181. results.push({
  182. id: channel.id,
  183. name: channel.name,
  184. deviceNum: channel.deviceNum,
  185. recordNum: channel.recordNum,
  186. scanNum: channel.scanNum
  187. })
  188. }
  189. return response.ok({
  190. message: '所有渠道统计数据已更新',
  191. data: results
  192. })
  193. } catch (error) {
  194. return response.internalServerError({
  195. message: '更新所有渠道统计数据时发生错误',
  196. error: error.message
  197. })
  198. }
  199. }
  200. }