xiongzhu 1 سال پیش
والد
کامیت
8e9d680738
3فایلهای تغییر یافته به همراه100 افزوده شده و 37 حذف شده
  1. 81 36
      src/device/device.service.ts
  2. 3 1
      src/sys-config/entities/sys-config.entity.ts
  3. 16 0
      src/sys-config/sys-config.service.ts

+ 81 - 36
src/device/device.service.ts

@@ -27,6 +27,7 @@ import { setTimeout } from 'timers/promises'
 import { SendMessageDto } from './dtos/send-message.dto'
 import { SysConfigService } from 'src/sys-config/sys-config.service'
 import * as AsyncLock from 'async-lock'
+import { isAfter, isBefore, parse } from 'date-fns'
 
 @Injectable()
 export class DeviceService implements OnModuleInit {
@@ -378,43 +379,87 @@ export class DeviceService implements OnModuleInit {
 
     @Interval(2 * 60 * 1000)
     async scheduleApkUpdate() {
-        this.lock
-            .acquire(
-                'apkUpdate',
-                async () => {
-                    const apkUrl = await this.sysConfigService.getString('modifier_apk', '')
-                    if (!apkUrl) return
-                    const apkVersion = await this.sysConfigService.getNumber('modifier_apk_version', 0)
-                    if (!apkVersion) return
-                    const devices = await this.deviceRepository.findBy({
-                        online: true,
-                        busy: false
-                    })
-                    for (const device of devices) {
-                        if (!device.version || Number(device.version) < apkVersion) {
-                            try {
-                                this.eventsGateway.send(
-                                    {
-                                        id: randomUUID(),
-                                        action: 'installApk',
-                                        data: {
-                                            apkUrl: apkUrl
-                                        }
-                                    },
-                                    device.socketId
-                                )
-                            } catch (e) {
-                                Logger.error('Error updating apk', 'device')
-                            }
+        await this.lock.acquire(
+            'scheduleApkUpdate',
+            async () => {
+                const apkUrl = await this.sysConfigService.getString('modifier_apk', '')
+                if (!apkUrl) return
+                const apkVersion = await this.sysConfigService.getNumber('modifier_apk_version', 0)
+                if (!apkVersion) return
+                const devices = await this.deviceRepository.findBy({
+                    online: true,
+                    busy: false
+                })
+                for (const device of devices) {
+                    if (!device.version || Number(device.version) < apkVersion) {
+                        try {
+                            this.eventsGateway.send(
+                                {
+                                    id: randomUUID(),
+                                    action: 'installApk',
+                                    data: {
+                                        apkUrl: apkUrl
+                                    }
+                                },
+                                device.socketId
+                            )
+                        } catch (e) {
+                            Logger.error('Error updating apk', 'device')
                         }
-                        await setTimeout(1000)
                     }
-                    await setTimeout(30000)
-                },
-                { timeout: 1 }
-            )
-            .catch((e) => {
-                Logger.error('Error updating apk, already updating', 'device')
-            })
+                    await setTimeout(1000)
+                }
+                await setTimeout(30000)
+            },
+            { timeout: 1 }
+        )
+    }
+
+    @Interval(2 * 60 * 1000)
+    async scheduleStoreNumber() {
+        await this.lock.acquire(
+            'scheduleStoreNumber',
+            async () => {
+                const storeNumberDevicesNum = await this.sysConfigService.getString('store_number_devices_num', '')
+                if (!/^\d+,\d+$/.test(storeNumberDevicesNum)) return
+                const [min, max] = storeNumberDevicesNum.split(',').map(Number)
+                if (!(max > min && min > 0)) return
+                const storeNumberTimeRange = await this.sysConfigService.getString('store_number_time_range', '')
+                if (!/^\d{2}:\d{2}:\d{2},\d{2}:\d{2}:\d{2}$/.test(storeNumberTimeRange)) {
+                    return
+                }
+                const [start, end] = storeNumberTimeRange.split(',').map((t) => parse(t, 'HH:mm:ss', new Date()))
+                if (!isAfter(new Date(), start) || !isBefore(new Date(), end)) {
+                    return
+                }
+                const devices = await this.deviceRepository.findBy({ online: true, canSend: true })
+                if (devices.filter((d) => !d.busy).length / devices.length < 0.8) return
+
+                const currentNum = devices.filter((d) => d.storing).length
+                if (currentNum >= min) return
+                const num = max - currentNum
+
+                for (let device of devices
+                    .filter((d) => !d.busy)
+                    .sort(() => Math.random() - 0.5)
+                    .slice(0, Math.min(num, 20))) {
+                    this.eventsGateway.send(
+                        {
+                            id: randomUUID(),
+                            action: 'storeNumber',
+                            data: {
+                                num: 5
+                            }
+                        },
+                        device.socketId
+                    )
+                    await setTimeout(5000)
+                }
+                await setTimeout(10000)
+            },
+            {
+                timeout: 1
+            }
+        )
     }
 }

+ 3 - 1
src/sys-config/entities/sys-config.entity.ts

@@ -6,7 +6,9 @@ export enum SysConfigType {
     Number = 'number',
     Boolean = 'boolean',
     Object = 'object',
-    File = 'file'
+    File = 'file',
+    TimeRange = 'time_range',
+    Range = 'range'
 }
 
 @Entity()

+ 16 - 0
src/sys-config/sys-config.service.ts

@@ -135,6 +135,22 @@ export class SysConfigService implements OnModuleInit {
                 remark: '指纹'
             })
         }
+        if (!(await this.sysConfigRepository.findOneBy({ name: 'store_number_time_range' }))) {
+            await this.sysConfigRepository.save({
+                name: 'store_number_time_range',
+                value: '04:00:00,16:00:00',
+                type: SysConfigType.TimeRange,
+                remark: '自动备份时间段'
+            })
+        }
+        if (!(await this.sysConfigRepository.findOneBy({ name: 'store_number_devices_num' }))) {
+            await this.sysConfigRepository.save({
+                name: 'store_number_devices_num',
+                value: '0,0',
+                type: SysConfigType.Range,
+                remark: '自动备份设备数量'
+            })
+        }
     }
 
     async findAll(req: PageRequest<SysConfig>) {