This commit is contained in:
李鹏宇
2026-06-02 08:50:38 +08:00
parent bf8cd2963b
commit 608a65b0fc
6 changed files with 67 additions and 9 deletions
+16
View File
@@ -81,6 +81,10 @@ class BusController(Controller):
# 同步到同公司的其他设备
self._sync_to_other_devices(employee, attendance_iot_id, data.get('photo'))
_logger.info("-------------------------%s创建成功-------------------------------" % (employee.name))
# 更新设备最后触发时间 & 写日志
if attendance_iot_id:
attendance_iot_id.touch_last_update()
attendance_iot_id._log('人脸注册', f"员工 {employee.name} 注册到设备 {attendance_iot_id.name}")
return {"Result": 0, "Msg": "添加成功"}
@route('/api/v1/record/face', methods=['POST'], type='json', auth='none', csrf=False)
@@ -117,6 +121,10 @@ class BusController(Controller):
})
_logger.info(f"考勤机创建的数据:{details}")
_logger.info(f"---考勤机名称-id:{attendance_iot_id.name}-{attendance_iot_id.id}-===okokokokokokokokokokok==----")
# 更新设备最后触发时间 & 写日志
if attendance_iot_id:
attendance_iot_id.touch_last_update()
attendance_iot_id._log('打卡上报', f"员工 {employee_id.name} 在 {recog_time} 打卡")
return {"Result": 0, "Msg": "添加成功"}
@route('/api/v1/user/inf_photo', methods=['POST'], type='json', auth='none', csrf=False)
@@ -149,6 +157,10 @@ class BusController(Controller):
})
# 同步到同公司的其他设备
self._sync_to_other_devices(employee, iot_device, vl_photo)
# 更新设备最后触发时间 & 写日志
if iot_device:
iot_device.touch_last_update()
iot_device._log('用户信息更新', f"员工 {employee.name} 照片更新/注册")
return {"Result": 0, "Msg": "添加成功"}
@route('/api/v1/uploadFaceInfo', methods=['POST'], type='json', auth='none', csrf=False)
@@ -199,6 +211,10 @@ class BusController(Controller):
# 同步到同公司的其他设备(uploadFaceInfo 是设备主动发起的数据同步,同样需要推给其他设备)
self._sync_to_other_devices(employee, iot_device, u.get('photo'))
# 更新设备最后触发时间 & 写日志
if iot_device:
iot_device.touch_last_update()
iot_device._log('人脸数据同步', f"设备 {iot_device.name} 上报 {len(user_list)} 条用户数据")
return {"Result": 0, "Msg": "更新成功"}
@http.route('/phone/attendance/list', type='http', auth="none", csrf=False, cors='*')
+16 -2
View File
@@ -21,6 +21,7 @@ class AttendanceIot(models.Model):
remake = fields.Text(string='备注')
employee_ids = fields.Many2many('hr.employee', string="员工")
is_connected = fields.Boolean(string="连接状态", default=False)
last_update_time = fields.Datetime(string="最后更新时间")
def action_init_device(self):
'''
@@ -114,9 +115,22 @@ class AttendanceIot(models.Model):
return {
'name': '考勤机日志',
'type': 'ir.actions.act_window',
'res_model': 'iot.message',
'res_model': 'attendance.iot.log',
'view_mode': 'tree,form',
'domain': [('device_sn', '=', self.name)],
'domain': [('attendance_iot_id', '=', self.id)],
}
def touch_last_update(self):
"""更新最后触发时间(MQTT/API 每次触发时调用)"""
self.write({'last_update_time': fields.Datetime.now()})
def _log(self, event_type, content):
"""写入设备操作日志"""
self.ensure_one()
self.env['attendance.iot.log'].create({
'attendance_iot_id': self.id,
'event_type': event_type,
'content': content,
})
@@ -7,4 +7,5 @@ class AttendanceIotLog(models.Model):
_order = 'create_date desc'
attendance_iot_id = fields.Many2one('attendance.iot', string="考勤机设备", required=True, ondelete='cascade')
event_type = fields.Char(string="事件类型")
content = fields.Text(string="内容")
@@ -7,6 +7,7 @@
<field name="arch" type="xml">
<tree>
<field name="attendance_iot_id"/>
<field name="event_type"/>
<field name="create_date" string="创建日期"/>
<field name="content"/>
</tree>
+23 -3
View File
@@ -10,13 +10,12 @@
</header>
<field name="name"/>
<field name="attendance_address"/>
<!-- <field name="broker" optional="hide"/>-->
<!-- <field name="port" optional="hide"/>-->
<!-- <field name="id_valid" optional="hide"/>-->
<field name="create_date" string="创建日期"/>
<field name="company_id" column_invisible="1"/>
<field name="number"/>
<field name="remake" column_invisible="1"/>
<field name="is_connected"/>
<field name="last_update_time"/>
<button name="open_record" type="object" string="详情" class="btn btn-blue"/>
<button name="action_view_logs" type="object" string="日志" class="btn btn-blue"/>
<button name="action_send_sync_sigle" type="object" string="拉取设备数据" class="btn btn-blue"/>
@@ -31,4 +30,25 @@
<field name="res_model">attendance.iot</field>
<field name="view_mode">tree,form</field>
</record>
<record id="attendance_iot_form" model="ir.ui.view">
<field name="name">attendance.iot.form</field>
<field name="model">attendance.iot</field>
<field name="arch" type="xml">
<form>
<sheet>
<group>
<field name="name"/>
<field name="attendance_address"/>
<field name="company_id"/>
<field name="is_connected"/>
<field name="last_update_time"/>
<field name="create_date" string="创建日期"/>
<field name="number"/>
<field name="remake"/>
</group>
</sheet>
</form>
</field>
</record>
</odoo>
+10 -4
View File
@@ -1,7 +1,10 @@
# -*- coding: utf-8 -*-
import logging
import sys
from odoo import models, fields, api, SUPERUSER_ID
_logger_db = logging.getLogger('yuthon.db_log')
class SystemLogs(models.Model):
_name = 'system.logs'
@@ -29,16 +32,18 @@ class OdooDBLogHandler(logging.Handler):
db = odoo.sql_db.db_connect(db_name)
with db.cursor() as cr:
env = api.Environment(cr, SUPERUSER_ID, {})
msg = record.getMessage() or ''
env['system.logs'].create({
'name': record.getMessage()[:80] if record.getMessage() else '',
'name': msg[:80],
'date': fields.Datetime.now(),
'level': record.levelname,
'logger_name': record.name,
'content': record.getMessage(),
'content': msg,
})
cr.commit()
except Exception:
pass
except Exception as e:
# 写 DB 失败时 fallback 到 stderr,避免静默吞掉
sys.stderr.write(f"[system.logs] DB write failed: {e}\n")
# 注册 Handler(只注册一次)
@@ -49,3 +54,4 @@ if not any(getattr(h, 'name', None) == _handler_key for h in _root_logger.handle
handler.name = _handler_key
handler.setLevel(logging.INFO)
_root_logger.addHandler(handler)
sys.stderr.write("[system.logs] Handler registered\n")