152 lines
5.8 KiB
Python
152 lines
5.8 KiB
Python
import json
|
|
import logging
|
|
from odoo import fields, models, api
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
def _strip_face_template(message_data_str):
|
|
"""移除 message_data JSON 中的 face_template 字段(图片base64太长)"""
|
|
if not message_data_str:
|
|
return message_data_str
|
|
try:
|
|
data = json.loads(message_data_str)
|
|
if isinstance(data, dict) and 'face_template' in data:
|
|
data.pop('face_template')
|
|
_logger.info("已移除 face_template 字段")
|
|
return json.dumps(data, ensure_ascii=False)
|
|
if isinstance(data, list):
|
|
changed = False
|
|
for item in data:
|
|
if isinstance(item, dict) and 'face_template' in item:
|
|
item.pop('face_template')
|
|
changed = True
|
|
if changed:
|
|
_logger.info("已移除列表中的 face_template 字段")
|
|
return json.dumps(data, ensure_ascii=False)
|
|
return message_data_str
|
|
except (json.JSONDecodeError, TypeError):
|
|
return message_data_str
|
|
|
|
|
|
class IotMessage(models.Model):
|
|
_name = 'iot.message'
|
|
_description = 'mqtt 消息,发送和接收'
|
|
|
|
name = fields.Char(string='消息')
|
|
topic = fields.Char(string='设备订阅主题')
|
|
device_sn = fields.Char(string='设备编码')
|
|
model = fields.Many2one('ir.model', string='模型')
|
|
id = fields.Integer(string='模型id')
|
|
message_data = fields.Text(string='message 数据')
|
|
state = fields.Selection(
|
|
[('draft', '待下发'), ('waiting', '下发完成等待结果'), ('done', '完成'), ('exception', '异常')], string='状态',
|
|
default='draft')
|
|
# 响应信息
|
|
res_data = fields.Text(string='发送后的响应信息')
|
|
face_data = fields.Text(string='照片数据')
|
|
|
|
@api.model_create_multi
|
|
def create(self, vals_list):
|
|
# 保留全部数据(含 face_template),MQTT 下发时需要原样发给设备
|
|
records = super().create(vals_list)
|
|
# 从 message_data 提取 face_template 存入单独字段,并在 message_data 中移除
|
|
for rec in records:
|
|
if rec.message_data:
|
|
try:
|
|
data = json.loads(rec.message_data)
|
|
if isinstance(data, dict) and 'face_template' in data:
|
|
face_tpl = data.pop('face_template')
|
|
rec.write({
|
|
'face_data': face_tpl,
|
|
'message_data': json.dumps(data, ensure_ascii=False),
|
|
})
|
|
except (json.JSONDecodeError, TypeError):
|
|
pass
|
|
# 创建设备日志时同步更新关联设备的最后更新时间
|
|
if rec.device_sn:
|
|
devices = self.env['attendance.iot'].sudo().search([('name', '=', rec.device_sn)], limit=1)
|
|
if devices:
|
|
devices.touch_last_update()
|
|
return records
|
|
|
|
def write(self, vals):
|
|
return super().write(vals)
|
|
|
|
def action_clear_face_template(self):
|
|
"""批量清除已有记录的 face_template 参数"""
|
|
count = 0
|
|
for record in self:
|
|
if not record.message_data:
|
|
continue
|
|
try:
|
|
data = json.loads(record.message_data)
|
|
changed = False
|
|
if isinstance(data, dict) and 'face_template' in data:
|
|
data.pop('face_template')
|
|
changed = True
|
|
elif isinstance(data, list):
|
|
for item in data:
|
|
if isinstance(item, dict) and 'face_template' in item:
|
|
item.pop('face_template')
|
|
changed = True
|
|
if changed:
|
|
record.write({'message_data': json.dumps(data, ensure_ascii=False)})
|
|
count += 1
|
|
except (json.JSONDecodeError, TypeError):
|
|
continue
|
|
_logger.info(f"已清理 {count} 条记录的 face_template")
|
|
return {
|
|
'type': 'ir.actions.client',
|
|
'tag': 'display_notification',
|
|
'params': {
|
|
'title': '完成',
|
|
'message': f'已清理 {count} 条记录的 face_template',
|
|
'sticky': False,
|
|
'type': 'success',
|
|
}
|
|
}
|
|
|
|
@api.model
|
|
def to_reply(self, data):
|
|
_logger.info(f'返回消息:{data}')
|
|
id = int(data.get('to'))
|
|
if id:
|
|
record = self.browse(id)
|
|
if record:
|
|
if data.get('data').get('code') == 0:
|
|
record.write({
|
|
'state': 'done',
|
|
'res_data': json.dumps(data, ensure_ascii=False)
|
|
})
|
|
else:
|
|
record.write({
|
|
'state': 'exception',
|
|
'res_data': json.dumps(data, ensure_ascii=False)
|
|
})
|
|
return data
|
|
|
|
@api.model
|
|
def get_draft_records(self):
|
|
records = self.search([('state', '=', 'draft')], offset=0, limit=10)
|
|
|
|
result = []
|
|
for record in records:
|
|
msg_data = record.message_data
|
|
# 如果有独立存的面部照片,重新拼回去下发
|
|
if record.face_data:
|
|
try:
|
|
data = json.loads(msg_data) if msg_data else {}
|
|
if isinstance(data, dict):
|
|
data['face_template'] = record.face_data
|
|
msg_data = json.dumps(data, ensure_ascii=False)
|
|
except (json.JSONDecodeError, TypeError):
|
|
pass
|
|
result.append({
|
|
'id': record.id,
|
|
'topic': record.topic,
|
|
'message_data': msg_data
|
|
})
|
|
records.write({'state': 'waiting'})
|
|
return result
|