<template>
    <view class="bg">
        <view class="status_bar">  
            <view class="top_view"></view>  
        </view>  
        <view class="title" @click="debug">
            智能内镜储存柜
            <p class="sub-title">
                INTELLIGENT ENDOSCOPE STORAGE CABINET
            </p>
        </view>
        <view class="btn">
            <view class="ant-btn ant-btn-lg" @click="toIndex">
                <uni-icons type="gear-filled" size="30"></uni-icons>
                进入
            </view>		
        </view>
		<uni-popup ref="popup" type="bottom" :mask-click="false">
            <view class="debug-btn-group">
                <view class="ant-btn ant-btn-lg" @click="toModbus">
                    modbus调试
                </view>
                <view class="ant-btn ant-btn-lg" @click="toSqlite">
                    sqlite调试
                </view>
                <view class="ant-btn ant-btn-lg" @click="cleanStorage">
                    清除缓存
                </view>
                <uni-icons @click="closePop" class="close-debug" type="close" size="40" color="#fff"></uni-icons>
            </view>
        </uni-popup>
        <input-num-pop ref="inputPop" @submit="inputModalSubmit" />
    </view>
</template>

<script>
// #ifdef APP
import * as db from '@/db/sqlite.js'
// #endif
import storage from '@/utils/storage.js'
import InputNumPop from '@/components/InputNumPop.vue';
import cmd from '@/utils/cmd.js'
import { formatDateTime, delay, getTimeDifference } from "@/utils/common.js"
import * as Api from '@/api/index.js'
import beeper from '@/utils/beeper.js';
import { compareTimes } from '../utils/common';
import store from '../store';

export default {
    components: { InputNumPop },
	data() {
		return {
            clickTimes: 0,
            RS485: undefined,
            RS232: undefined,
            timer: null, // 定时器读取485接口数据
            taskTimer: null,
            leftDoorCycleTimer: null, // 左门循环定时器
            last485DataTime: null,   // 上次收到485数据的时间戳
            heartbeatTimer: null,     // 心跳检测定时器
            reconnectCount: 0,       // 重连次数计数器
            maxReconnect: 3,        // 最大重连次数
		}
	},
    computed: {
        cleanMode() {
            // 清洗状态 
            return this.$store.state.clean
        },
        autoDisinfect() {
            // 自动消毒状态 
            return this.$store.state.autoDisinfect
        },
        disinfectMode() {
            // 消毒状态 
            return this.$store.state.relay.disinfect
        },
        windMode() { 
            // 风机状态 
            return this.$store.state.relay.wind
        },
        vacuumMode() { 
            // 真空泵状态 
            return this.$store.state.relay.vacuum
        },
        doorStatus() { 
            // 门状态 
            return this.$store.state.relay.door
        },
        doorAlert() { 
            // 门报警
            return this.$store.state.timer.doorAlert
        },
        humi() { 
            // 当前湿度
            return this.$store.state.sensor.humi
        },
        temp() { 
            // 当前温度
            return this.$store.state.sensor.temp
        },
    },

	onLoad() {
        this.RS485 = getApp().globalData.RS485
        this.RS232 = getApp().globalData.RS232
		this.init()
        uni.$on('addLog', (data) => {
            this.addLog(data.name, data.action)
        })
        // 监听内镜存入事件
        uni.$on('storeEndoscope', (data) => {
            this.addLog(data.ic, '内镜存入')
        })
        // 监听内镜取出事件
        uni.$on('takeEndoscope', (data) => {
            this.addLog(data.ic, '内镜取出')
        })

        uni.$on('closeDoor', async (data) => { 
            try {
                cmd.LeftDoor(false)
                await delay(100)
                cmd.RightDoor(false)
                this.addLog('门', '触摸屏关门')
                // 触发关门事件
                this.closeDoorEvent()
            } catch (error) {
                this.addLog('手动关门错误', error)
            }
        })
		
	},
    onShow() {
        // 监听日志记录事件
    },
    onBackPress() {
        // 禁用返回按键
        return true;
    },
    onHide() {
        // 移除事件监听
        // uni.$off('addLog')
        // uni.$off('storeEndoscope')
        // uni.$off('takeEndoscope')
    },
    onUnload() {
        // 记录日志
        this.addLog('485通信', '页面销毁，已停止所有定时器')

        // 清理心跳定时器
        if (this.heartbeatTimer) {
            clearInterval(this.heartbeatTimer)
            this.heartbeatTimer = null
        }
        // 清理485轮询定时器
        if (this.timer) {
            clearInterval(this.timer)
            this.timer = null
        }
        // 清理任务定时器
        if (this.taskTimer) {
            clearInterval(this.taskTimer)
            this.taskTimer = null
        }
        // 清理左门循环定时器
        if (this.leftDoorCycleTimer) {
            clearInterval(this.leftDoorCycleTimer)
            this.leftDoorCycleTimer = null
        }
    },
	methods: {
        init() {
            // 初始化串口
            this.initSerialport()
            // 初始化本地存储
            this.initStorage()
            // 初始化网络时间
            this.initTime()
            // 监听运行状态
            this.initWatch()
			// 初始化本地数据库
			this.initDB()
        },
        initSerialport() { 
			try {
				this.startRS485()
				this.startRS232()

			} catch (e) {

				uni.showToast({
					title: '初始化串口失败',
					icon: 'error'
				})
			}
        },
        initTime() {
            // 初始化本地时间
            this.$store.state.time = formatDateTime()
            if (this.$store.state.apiUrl != '') {
                // 同步网络时间
                Api.time().then(res => { 
                    // console.log('time', res)
                    if (res && Date.parse(res) != NaN) {
                        this.$store.state.time = res
                        this.$store.state.connect = true
                    }
                })
            }
        },
        // 初始化监听器
        initWatch() {
			// 监听消毒状态
            this.$watch('disinfectMode', (newVal, oldVal) => { 
                if (newVal == true) {
                    // 消毒开启事件，记录时间
                    this.$store.state.timer.disinfect = formatDateTime()
                } 
                if (newVal == false) { 
                    // 消毒停止事件
                    let timer = this.$store.state.timer.disinfect
                    if (timer != '' && timer != null) { 
                        // 获取时间间隔
                        let diff = getTimeDifference(timer, formatDateTime())
                        let local = storage.get('disinfectRun') ? storage.get('disinfectRun') : 0
                        storage.set('disinfectRun', diff.minutes + local)
                    }
                }
            })
			// 风机状态
            this.$watch('windMode', (newVal, oldVal) => { 
                if (newVal == true && oldVal == false) {
                    // 分机开启事件，记录时间
                    this.$store.state.timer.wind = formatDateTime()
                } 
                if (newVal == false) { 
                    // 停止事件
                    let timer = this.$store.state.timer.wind
                    if (timer != '' && timer != null) { 
                        // 获取时间间隔
                        let diff = getTimeDifference(timer, formatDateTime())
                        let local = storage.get('windRun') ? storage.get('windRun') : 0
						// 存储风机总运行时间
                        storage.set('windRun', diff.minutes + local)
                    }
                }
            })
            // 监听温度高，启动风机
            this.$watch('humi', (newVal, oldVal) => { 
                // 湿度高启动风机，关闭状态，自动模式
                if (newVal > this.$store.state.run.humi && this.windMode == false) { 
                    // 启动风机
                    cmd.Wind(true)
                }
            })
            this.$watch('temp', (newVal, oldVal) => { 
                // 湿度高启动风机，关闭状态，自动模式
                if (newVal > this.$store.state.run.temp && this.windMode == false) { 
                    // 启动风机
                    cmd.Wind(true)
                }
            })
            // 监听开门
            this.$watch('doorStatus', (newVal, oldVal) => {
                // 监听门状态
                if (newVal == true) {
                    // 触发门打开事件，记录开门时间
					this.openDoorEvent()
                    this.$store.state.timer.door = formatDateTime()
                }
                if (newVal == false) {
                    // 触发门关闭事件
					this.closeDoorEvent()
                    // 记录关门日志（手动关门）
                    this.addLog('门', '手动关门')
                    this.$store.state.timer.door = ''
                    this.$store.state.timer.doorAlert = false
                }
            })
            // 监听开门报警事件
            this.$watch('doorAlert', (newVal, oldVal) => { 
                // 监听门报警
                if (newVal == true) { 
                    // 触发门报警事件
                    beeper.play()
                } 
                if (newVal == false) {
                    // 停止报警
                    beeper.stop()
                }
            })
            this.$watch('vacuumMode', (newVal, oldVal) => { 
                // 监听真空泵状态
                if (newVal == true) {
                    this.$store.state.timer.vacuumStart = formatDateTime()
                }
                if (newVal == false) { 
                    this.$store.state.timer.vacuumEnd = formatDateTime()
                }
            })
        },
        initStorage() {
            // 初始化本地配置存储
            let runStorage = storage.get('run')
            if (runStorage) {
                this.$store.commit('SET_RUN', { ...runStorage })
            }
            let baseStorage = storage.get('base')
            if (baseStorage) {
                this.$store.commit('SET_BASE', { ...baseStorage })
            }
            let config = storage.get('config')
            if (config) {
                this.$store.state.apiUrl = 'http://' + config.ip + ':' + config.port
            }
        },
		async initDB() {
			await db.isTable('user').then(res => {
				if (!res) {
					db.addUserTable()
				}
			})
			await db.isTable('log').then(res => {
				if (!res) {
					db.addLogTable()
				}
			})
			await db.isTable('endo').then(res => {
				if (!res) {
					db.addEndoTable()
				}
			})
			let scope = await db.isTable('scope')
			if (!scope) {
				await db.addScopeTable()
				for (let i = 0; i < 16; i++) {
					await db.addTabItem('scope', {
						name: '', ic: '', key: i,
					})
				}	
			}

		},
        startRS485() { 
            // 获取本地串口存储端口
            let rs485Conf = storage.get('rs485')
            if (rs485Conf) {
                // 设置串口和波特率
            } else {
				rs485Conf = {
					path: '/dev/ttyUSB2',
					baudrate: 9600
				}
			}
			this.RS485.setPath(rs485Conf.path)
			this.RS485.setBaudrate(rs485Conf.baudrate)
			// 打开串口
			const state = this.RS485.open();
			 if (state) {
			    uni.showToast({
			        title: '485已打开',
			        icon: 'none'
			    })
			    this.RS485.startAutoReadData((res) =>{ 
                    // console.log('485 data', res)
			        // 转换成十六进制字符串
			        let hex = this.RS485.byte2HexString(res)
			        this.handle485HexData(hex)
			    }) 
			    // 读取数据
			    clearInterval(this.timer)
			    this.readData()

                // 启动心跳检测
                this.startHeartbeat()

				// 串口打开成功后，重置重连计数器和时间戳
				this.reconnectCount = 0
				this.last485DataTime = Date.now()

				// 记录通信恢复日志
				// this.addLog('485通信', '通信已恢复（重连成功）')
			} else {
                // 确保心跳是关闭的
                this.stopHeartbeatIfNeeded()
                uni.showToast({
                    title: '485打开失败',
                    icon: 'error'
                })
            }
        },
        async startRS232() { 
            // 获取本地串口存储端口
            let rs232Conf = storage.get('rs232')
            if (rs232Conf) {
                // 设置串口和波特率
            } else {
				rs232Conf = {	
					path: '/dev/ttyUSB1',
					baudrate: 115200
				}
			}
			this.RS232.setPath(rs232Conf.path)
			this.RS232.setBaudrate(rs232Conf.baudrate)
			// 打开串口
			const state = this.RS232.open();
			if (state) {
			    uni.showToast({
			        title: '232已打开',
			        icon: 'none'
			    })
			    this.RS232.startAutoReadData((res) =>{ 
			        // 转换成十六进制字符串
			        let hex = this.RS232.byte2HexString(res)
			        this.handle232HexData(hex)
			    })
				this.startAutoTask()
			} 
        },
        stopRS485() {
            // 停止心跳检测
            this.stopHeartbeatIfNeeded()
            this.addLog('485通信', '串口关闭')
            this.RS485.stopReadPortData()
            this.RS485.close()
        },
        stopRS232() { 
            this.RS232.stopReadPortData()
            this.RS232.close()
            this.RS232 = undefined
        },

        // 启动心跳检测定时器
        startHeartbeat() {
            // 清除已有的心跳定时器
            if (this.heartbeatTimer) {
                clearInterval(this.heartbeatTimer)
                this.heartbeatTimer = null
            }
            // 记录日志
            this.addLog('485通信', '心跳检测已启动')

            // 每10秒检查一次485数据是否正常上报
            this.heartbeatTimer = setInterval(() => {
                this.check485Heartbeat()
            }, 10000)
        },
        //  停止心跳检测（安全方法，如果没运行也不会报错）
        stopHeartbeatIfNeeded() {
            if (!this.heartbeatTimer) {
                // 心跳未运行
                return
            }
            
            clearInterval(this.heartbeatTimer)
            this.heartbeatTimer = null            
            this.addLog('485通信', '心跳检测已停止')
        },

        // 检测485数据心跳，如果超时则触发重连
        check485Heartbeat() {
            // 如果还没有收到过数据，跳过检查（等待初始化完成）
            if (!this.last485DataTime) {
                return
            }

            const now = Date.now()
            const timeout = 30 * 1000 // 30秒超时阈值

            // 判断距离上次数据是否超过30秒
            if (now - this.last485DataTime > timeout) {
                // 检查重连次数是否超限
                if (this.reconnectCount >= this.maxReconnect) {
                    this.addLog('485通信', '重连' + this.maxReconnect + '次失败，请检查硬件')
                    uni.showToast({
                        title: '485通信中断，请检查硬件连接',
                        icon: 'none',
                        duration: 3000
                    })
                    return
                }

                // 记录日志
                this.addLog('485通信', '数据中断（第' + (this.reconnectCount + 1) + '次重连）')

                uni.showToast({
                    title: '485通信中断，正在恢复...',
                    icon: 'none',
                    duration: 2000
                })

                // 重置监听
                this.resetRS485()
            }
        },

        // 重置RS485监听：停止旧连接 → 重启新连接 → 恢复心跳
        async resetRS485() {
            try {
                this.reconnectCount++

                // 1. 暂停心跳检测（避免重置过程中重复触发）
                if (this.heartbeatTimer) {
                    clearInterval(this.heartbeatTimer)
                    this.heartbeatTimer = null
                }

                // 2. 停止并关闭当前RS485串口
                if (this.RS485) {
                    this.stopRS485()
                    // 等待一段时间确保串口完全关闭
                    await delay(1500)
                }

                // 3. 清除轮询定时器
                if (this.timer) {
                    clearInterval(this.timer)
                    this.timer = null
                }

                // 4. 重置时间戳
                this.last485DataTime = null

                // 5. 重新启动RS485通信
                this.startRS485()

            } catch (error) {
                this.addLog('485通信错误', error.message || '重置失败')

                // 失败后延迟重试
                await delay(5000)
                if (this.reconnectCount < this.maxReconnect) {
                    this.resetRS485()
                }
            }
        },

        readData() {
            this.timer = setInterval(async () => { 
                await cmd.getTemp()
                await delay(1000)
                await cmd.getPressure()
			}, 5000)
        },
        async handle485HexData(hex) {
            // 更新最后收到数据的时间戳
            this.last485DataTime = Date.now()

            // 处理485接口上报的数据
            // 温湿度temp, humi, 压差pressure, 门状态door
            let data = cmd.parse485Data(hex)
            // 将获取的数据赋值到状态
			if (data.hasOwnProperty('temp')) {
				this.$store.state.sensor.temp = data.temp
			}
			if (data.hasOwnProperty('humi')) {
				this.$store.state.sensor.humi = data.humi
			}
			if (data.hasOwnProperty('pressure')) {
				let pressure = parseFloat(data.pressure) + parseInt(this.$store.state.run.pressureCom)
				this.$store.state.sensor.pressure = pressure
			}

            // 处理门状态上报(功能码04,中盛IO控制器DI状态变化上报)
            // 注意: 门状态的修改统一由cmd.js的LeftDoor/RightDoor方法管理
            // 这里只处理收到上报后的自动逻辑,不修改门状态
            if (data.action == 'LeftDoor' && data.status == 'closed') {
                // 左门触点触发(关门)
                // 调用cmd.LeftDoor(false)来更新门状态
                cmd.LeftDoor(false)
                // 触发关门事件
                // this.closeDoorEvent()
                uni.showToast({
                    title: '左门已关闭',
                    icon: 'none'
                })
                this.addLog('左门触点触发', '左门已关闭')
            }
            if (data.action == 'RightDoor' && data.status == 'closed') {
                // 右门触点触发(关门)
                // 调用cmd.RightDoor(false)来更新门状态
                cmd.RightDoor(false)
                // 触发关门事件
                // this.closeDoorEvent()
                uni.showToast({
                    title: '右门已关闭',
                    icon: 'none'
                })
                this.addLog('右门触点触发', '右门已关闭')
            }
            if (data.action == 'door' && data.status == 'closed') {
                try {
                    await cmd.LeftDoor(false)
                    await delay(100)
                    await cmd.RightDoor(false)
                    // 触发关门事件
                    await this.closeDoorEvent()
                    uni.showToast({
                        title: '两门已关闭',
                        icon: 'none'
                    })
                } catch (error) {
                    this.addLog('门关闭错误', error.message || error)
                }
            }
        },
        handle232HexData(hex) {
            // 处理232接口上报的卡片数据
            // 数据格式说明：
            // - 卡存入: 20 01 00 08 04 00 00 00 [卡号4字节] [校验] 03 (14字节)
            // - 卡离开: 20 01 00 01 02 [校验] 03 (7字节)
            // - 卡号位置: 倒数4-8字节(字节位置6-9)
            // - 所有卡片通过同一通道读取,通过数据库比对判断卡片类型

            let data = cmd.parse232dData(hex)
            if (data == {}) return

            if (data.hasOwnProperty('number')) {
                // 收到卡号数据,发送卡号事件
                uni.$emit('ic', data.number)

                // 判断当前门状态
                if (store.state.relay.door == false) {
                    // 门关闭状态: 验证是否为人员卡
                    // 人员卡验证通过后弹窗选择开左门/开右门
                    this.checkPersonCard(data.number).then(res => {
                        if (res) {
                            // 验证通过,是人员卡
                            // 发送弹窗选择事件,让index页面弹窗选择开左门/开右门
                            uni.$emit('showDoorSelect', data.number)
                        } else {
                            // 验证失败,不是人员卡
                            // 继续验证是否为内镜卡
                            this.checkEndoCard(data.number).then(res => {
                                if (res) {
                                    // 是内镜卡,门关闭状态下不允许操作
                                    uni.showToast({
                                        title: '请先开门',
                                        icon: 'none'
                                    })
                                } else {
                                    // 既不是人员卡也不是内镜卡
                                    uni.showToast({
                                        title: '无效卡片',
                                        icon: 'none'
                                    })
                                }
                            })
                        }
                    })
                } else {
                    // 门打开状态: 验证是否为人员卡或内镜卡
                    // 人员卡验证通过后弹窗选择开左门/开右门
                    // 内镜卡验证通过后弹窗选择存入/取出
                    this.checkPersonCard(data.number).then(res => {
                        if (res) {
                            // 验证通过,是人员卡
                            // 发送弹窗选择事件,让index页面弹窗选择开左门/开右门
                            uni.$emit('showDoorSelect', data.number)
                        } else {
                            // 验证失败,不是人员卡
                            // 继续验证是否为内镜卡
                            this.checkEndoCard(data.number).then(res => {
                                if (res) {
                                    // 是内镜卡,门打开状态只能存入
                                    uni.$emit('showActionSelect', data.number)
                                } else {
                                    // 既不是人员卡也不是内镜卡
                                    uni.showToast({
                                        title: '无效卡片',
                                        icon: 'none'
                                    })
                                }
                            })
                        }
                    })
                }
            }
        },
        // handle232HexData(hex) {
        //     // 处理232接口上报的数据
        //     let data = cmd.parse232dData(hex)
        //     if (data == {}) return
        //     if (data.action == 'leave' && data.type == 'internal') {
        //         // 更新内镜数据
        //         let key = data.address - 1
        //         uni.$emit('notice', { title: data.address, content: '内镜取出'})
        //         this.updateScope(key, 'leave', '')
        //         // 添加日志数据
        //         this.addLog('位置'+key, '内镜取出')
        //      }
        //     if (data.action == 'enter' && data.type == 'internal') {
        //         // 验证内镜信息
        //         this.checkEndoCard(data.number).then(res => { 
        //             if (res) {
        //                 uni.$emit('notice', { title: data.number, content: '内镜存入'})
        //                 // 更新内镜数据
        //                 let key = data.address - 1
        //                 this.updateScope(key, 'enter', data.number)
        //                 // 添加日志数据
        //                 this.addLog(data.number, '内镜存入')
        //             } 
        //         })
        //         uni.$emit('ic', data.number)
        //     }
        //     if (data.action == 'enter' && data.type == 'person') { 
        //         // 验证人员信息
        //         this.checkPersonCard(data.number).then(res => { 
        //             if (res) {
        //                 // 开门事件
		// 				cmd.Door(true)
        //                 // this.openDoorEvent()
        //                 uni.$emit('notice', { title: data.number, content: '刷卡开门'})
        //                 // 添加日志数据
        //                 this.addLog(data.number, '刷卡开门')
        //             }
        //         })
        //         uni.$emit('ic', data.number)
        //     }
		// 	if (data.action == 'door') {
		// 		cmd.Door(false)
		// 	}
        // },
        // 密码框提交
        inputModalSubmit(val) { 
            let password = this.$store.state.base.screenPw
            this.$refs.inputPop.close()
            if (val == password) {
                uni.showToast({
                    title: '验证通过',
                    icon: 'none'
                })
                setTimeout(() => {
                    uni.navigateTo({
                        url: '/pages/index',
                        animationType: 'fade-in',
                    })
                }, 300)
            } else { 
                uni.showToast({
                    title: '密码错误',
                    icon: 'none',
                })
            }
        },
		toIndex() {
            let screenPw = this.$store.state.base.screenPw
            if(screenPw) {
                this.$refs.inputPop.show()
            } else { 
                uni.navigateTo({
                    url: '/pages/index',
                    animationType: 'fade-in',
                })
            }
		},
		toModbus() {
            try { 
                this.stopRS485()
                this.stopRS232()
            } catch (error) {
                // console.log(error)
            }
            this.closePop()
			uni.navigateTo({
				url: '/pages/modbus/modbus'
			})
		},
		toSqlite() {
            this.closePop()
			uni.navigateTo({
				url: '/pages/database/database'
			})
		},
        cleanStorage() {
            storage.clear()
            uni.showToast({
                title: '已清空缓存，重启应用生效',
                icon: 'none'
            })
        },
        // 调试弹窗
        debug() {
            this.clickTimes++
            if (this.clickTimes == 5) {
                this.clickTimes = 0
                this.$refs.popup.open()
            }
            setTimeout(() => {
                this.clickTimes = 0
            }, 3000)    
        },
        closePop() {
            this.$refs.popup.close()
        },
        send485Data(cmd) {
			this.RS485.sendDataString(cmd);
		},
		async send232Data(cmd) {
			await this.RS232.sendDataString(cmd);
		},
        // 开门事件
        async openDoorEvent() {
            // 关闭真空泵和消毒，打开照明，打开门锁，打开风机
            cmd.Vacuum(false)
            await delay(300)
            cmd.Light(true)
            await delay(300)
            cmd.Wind(true)
        },
        // 关门事件
        async closeDoorEvent() {
            // 关闭照明，打开真空泵、消毒
            cmd.Light(false) // 照明关闭指令
            await delay(300)
            cmd.Vacuum(true) //真空泵开启指令
            await delay(300)
            cmd.Wind(true)
        },
        // 验证人员卡是否可以开门
        async checkPersonCard(ic) {
            let res1 = await db.selectDataList('user', {'ic': ic})
            if (res1.length > 0) {
                return true
            }
            let res2 = await db.selectDataList('user', {'ic2': ic})
            if (res2.length > 0) {
                return true
            }
            return false
        },
        // 验证内镜卡是否可以
        async checkEndoCard(ic) {
            let res1 = await db.selectDataList('endo', {'ic': ic})
            if (res1.length > 0) {
                return true
            }
            let res2 = await db.selectDataList('endo', {'ic2': ic})
            if (res2.length > 0) {
                return true
            }
            return false
        },
        // /***
        //  * 更新内镜数据
        //  * @param {*} key 内镜位置编号 起始0
        //  * @param {*} action 操作类型 enter:进入 leave:离开
        //  * @param {*} sn 内镜编号
        //  * */
        // async updateScope(key, action, ic) {
        //     let data = {
		// 		name: action,
		// 		ic: ic,
		// 		time: formatDateTime(),
		// 	}
        //     try {
        //         await db.updateSQL('scope', data, 'key', key)
        //     } catch (error) {
        //         console.log(error)
        //     }
        // },
        // 添加日志数据
        async addLog(name, action) { 
            try {
				// 本地存储
                await db.addTabItem('log', {
                    name: name,
                    action: action,
                })
				// 网络同步
				// Api.logsync()
            } catch (error) {
                // console.log(error)
            }
        },

        /**
         * 任务
         * */
        startAutoTask() {
			// clearInterval(this.taskTimer)
            this.taskTimer = setInterval(() => { 
                // 检查开门时长
                this.checkDoorOpenTimer()
                // 真空泵运行任务
                this.vacuumTask()
                // 自动消毒任务
                this.disinfectTask()
				// 风机停止任务
				this.windCloseTask()
            }, 2000)
        },
		// 消毒任务
        async disinfectTask() { 
            // 启动自动触发任务
            let group = this.$store.state.run.group
            let now = formatDateTime()
            let nowTime = now.split(' ')[1]
            let time = nowTime.substring(0, nowTime.length - 3)
            let isStart = false
            for (let i = 0; i < group.length; i++) { 
                if (group[i].status) {
                    let start = group[i].start.h + ':' + group[i].start.m
                    let end = group[i].end.h + ':' + group[i].end.m
                    // 开始时间                  
                    if (compareTimes(start, time) == 1 && compareTimes(time, end) == 1) {
                        isStart = true
                        break;
                    }
                }
            }
            if (this.disinfectMode == false && isStart == true) {
                // 启动消毒
                cmd.Disinfect(true)
                await delay(100)
                cmd.Wind(true)
            }
            if (this.disinfectMode == true && isStart == false && this.autoDisinfect == true) {
                // 停止消毒
                cmd.Disinfect(false)
            }
        },
		// 真空泵任务
        async vacuumTask() {
            let start = this.$store.state.timer.vacuumStart
            if (start != '') {
				// 开始启动到当前时间
				let startM = getTimeDifference(start, formatDateTime())
				// 真空泵运行时长
				let runTime = this.$store.state.run.vacuumRunTime
				// 分钟单位
				if (startM.minutes >= runTime) {
					// 关闭真空泵
					this.$store.state.timer.vacuumStart = ''
					// 超过阈值 关闭
					cmd.Vacuum(false)
				}
            }
            let end = this.$store.state.timer.vacuumEnd
            if (end != '') {
				let endH = getTimeDifference(end, formatDateTime())
				// 间隔时长
				let perHour = this.$store.state.run.vacuumPerHour
				// 小时单位
				if (endH.hour >= perHour) {
					// 启动真空泵
					this.$store.state.timer.vacuumEnd = ''
					// 启动真空泵
					cmd.Vacuum(true)
					await delay(100)
					cmd.Wind(true)
				}
            }
        },
		async windCloseTask() {
			await delay(100)
			let { light, vacuum, disinfect, door } = this.$store.state.relay
			if (light || vacuum || disinfect || door ) {
                return;
            }
            if (this.$store.state.sensor.temp > this.$store.state.run.temp) {
                return;
            }
            if (this.$store.state.sensor.humi > this.$store.state.run.humi) {
                return;
            }
            cmd.Wind(false)
		},
        checkDoorOpenTimer() { 
            let openTime = this.$store.state.timer.door
            // 记录开门时间并且不是清洗模式
            if (openTime != '' && this.cleanMode == false) {
                let diff = getTimeDifference(formatDateTime(openTime), formatDateTime())   
                if (diff.minutes > 3) {
                    this.$store.state.timer.doorAlert = true
                    uni.$emit('notice', { title: '未关门', content: '请及时关闭'})
                }
            }
        },
		
	}
}
</script>

<style scoped>
.bg{
    position: relative;
    width: 100%;
    height: 100%;
    background-image: url("@/assets/bg.png");
    background-size: 100% 100%;
    background-position: center;
    background-repeat: no-repeat;
}

.title{
    position: absolute;
    top: 40%;
    left: 0;
    right: 0;
    margin: auto;
    height: 60px;
    font-size: 56px;
	color: #fff;
}
.sub-title{
    font-size: 14px;
    color: #777D90;
}
.btn{
    position: absolute;
    bottom: 125px;
    left: 0;
    right: 0;
    margin: auto;
    width: 200px;
}

.ant-btn.ant-btn-lg{
    font-size: 28px;
    height: 60px;
    /* line-height: 50px; */
    border-radius: 50px;
    width: 180px;
}

.debug-btn-group{
    margin-bottom: 40rpx;
    position: relative;
}
.debug-btn-group .ant-btn{
    margin: 0 10rpx;
    font-size: 20px;
    line-height: 40px;
    width:auto;
}
.close-debug{
    position: absolute;
    right: 10px;
}
</style>