Accept Merge Request #2045: (feature/6694 -> develop)
Merge Request: 增加日志界面 Created By: @胡尧 Accepted By: @胡尧 URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/2045?initial=true
This commit is contained in:
@@ -2,20 +2,22 @@ import json
|
|||||||
from odoo import http
|
from odoo import http
|
||||||
from odoo.http import request
|
from odoo.http import request
|
||||||
from odoo.addons.sf_machine_connect.models.ftp_operate import transfer_nc_files
|
from odoo.addons.sf_machine_connect.models.ftp_operate import transfer_nc_files
|
||||||
|
from odoo.addons.sf_base.decorators.api_log import api_log
|
||||||
|
|
||||||
class MainController(http.Controller):
|
class MainController(http.Controller):
|
||||||
|
|
||||||
@http.route('/api/manual_download_program', type='json', methods=['POST'], auth='public', cors='*')
|
@http.route('/api/manual_download_program', type='json', methods=['POST'], auth='public', cors='*')
|
||||||
|
@api_log('人工线下加工编程文件传输', requester='报工系统')
|
||||||
def manual_download_program(self):
|
def manual_download_program(self):
|
||||||
"""
|
"""
|
||||||
人工线下加工传输编程文件
|
人工线下加工传输编程文件
|
||||||
"""
|
"""
|
||||||
data = json.loads(request.httprequest.data)
|
data = json.loads(request.httprequest.data)
|
||||||
maintenance_equipment_name = data.get('maintenance_equipment_name')
|
maintenance_equipment_id = data.get('maintenance_equipment_id')
|
||||||
model_id = data.get('model_id')
|
model_id = data.get('model_id')
|
||||||
if not maintenance_equipment_name or not model_id:
|
if not maintenance_equipment_id or not model_id:
|
||||||
return {'code': 400, 'message': '参数错误'}
|
return {'code': 400, 'message': '参数错误'}
|
||||||
maintenance_equipment = request.env['maintenance.equipment'].sudo().search([('name', '=', maintenance_equipment_name)], limit=1)
|
maintenance_equipment = request.env['maintenance.equipment'].sudo().browse(int(maintenance_equipment_id))
|
||||||
if not maintenance_equipment:
|
if not maintenance_equipment:
|
||||||
return {'code': 400, 'message': '机台不存在,请扫描正确的机台二维码'}
|
return {'code': 400, 'message': '机台不存在,请扫描正确的机台二维码'}
|
||||||
product = request.env['product.template'].sudo().search([('model_id', '=', model_id)], limit=1)
|
product = request.env['product.template'].sudo().search([('model_id', '=', model_id)], limit=1)
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
from . import models
|
from . import models
|
||||||
from . import commons
|
from . import commons
|
||||||
from . import controllers
|
from . import controllers
|
||||||
|
from . import decorators
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
'views/menu_fixture_view.xml',
|
'views/menu_fixture_view.xml',
|
||||||
'views/change_base_view.xml',
|
'views/change_base_view.xml',
|
||||||
'views/Printer.xml',
|
'views/Printer.xml',
|
||||||
|
'views/api_log_views.xml',
|
||||||
],
|
],
|
||||||
'demo': [
|
'demo': [
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import logging
|
import logging
|
||||||
import json
|
import json
|
||||||
import base64
|
import logging
|
||||||
from odoo import http
|
from odoo import http
|
||||||
from odoo.http import request
|
from odoo.http import request
|
||||||
|
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
class Manufacturing_Connect(http.Controller):
|
class Manufacturing_Connect(http.Controller):
|
||||||
|
|
||||||
|
|||||||
1
sf_base/decorators/__init__.py
Normal file
1
sf_base/decorators/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
from . import api_log
|
||||||
59
sf_base/decorators/api_log.py
Normal file
59
sf_base/decorators/api_log.py
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
|
||||||
|
import functools
|
||||||
|
import json
|
||||||
|
import logging
|
||||||
|
from datetime import datetime
|
||||||
|
from odoo.http import request
|
||||||
|
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
def api_log(name=None, requester=None):
|
||||||
|
"""记录API请求日志的装饰器"""
|
||||||
|
def decorator(func):
|
||||||
|
@functools.wraps(func)
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
start_time = datetime.now()
|
||||||
|
|
||||||
|
# 获取请求信息
|
||||||
|
try:
|
||||||
|
# 获取请求数据
|
||||||
|
request_data = json.loads(request.httprequest.data) if request.httprequest.data else {}
|
||||||
|
# 获取请求路径
|
||||||
|
path = request.httprequest.path
|
||||||
|
# 获取请求方法
|
||||||
|
method = request.httprequest.method
|
||||||
|
# 获取客户端IP
|
||||||
|
remote_addr = request.httprequest.remote_addr
|
||||||
|
|
||||||
|
# 执行原始函数
|
||||||
|
result = func(*args, **kwargs)
|
||||||
|
|
||||||
|
# 计算响应时间
|
||||||
|
end_time = datetime.now()
|
||||||
|
response_time = (end_time - start_time).total_seconds()
|
||||||
|
|
||||||
|
# 创建日志记录
|
||||||
|
log_vals = {
|
||||||
|
'name': name or func.__name__,
|
||||||
|
'path': path,
|
||||||
|
'method': method,
|
||||||
|
'request_data': json.dumps(request_data, ensure_ascii=False),
|
||||||
|
'response_data': json.dumps(result, ensure_ascii=False),
|
||||||
|
'remote_addr': remote_addr,
|
||||||
|
'response_time': response_time,
|
||||||
|
'status': result.get('code', 500),
|
||||||
|
'requester': requester,
|
||||||
|
'responser': '智能工厂'
|
||||||
|
}
|
||||||
|
|
||||||
|
# 异步创建日志记录
|
||||||
|
request.env['api.request.log'].sudo().with_context(tracking_disable=True).create(log_vals)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
_logger.error(f"API日志记录失败: {str(e)}")
|
||||||
|
# 即使日志记录失败,也要返回原始结果
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
return wrapper
|
||||||
|
return decorator
|
||||||
@@ -6,3 +6,4 @@ from . import functional_fixture
|
|||||||
from . import tool_other_features
|
from . import tool_other_features
|
||||||
from . import basic_parameters_fixture
|
from . import basic_parameters_fixture
|
||||||
from . import ir_sequence
|
from . import ir_sequence
|
||||||
|
from . import api_log
|
||||||
|
|||||||
18
sf_base/models/api_log.py
Normal file
18
sf_base/models/api_log.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
from odoo import models, fields, api
|
||||||
|
|
||||||
|
|
||||||
|
class ApiRequestLog(models.Model):
|
||||||
|
_name = 'api.request.log'
|
||||||
|
_description = '接口请求日志'
|
||||||
|
_order = 'id desc'
|
||||||
|
|
||||||
|
name = fields.Char('接口名称')
|
||||||
|
path = fields.Char('请求路径')
|
||||||
|
method = fields.Char('请求方法')
|
||||||
|
request_data = fields.Text('请求数据')
|
||||||
|
response_data = fields.Text('响应数据')
|
||||||
|
remote_addr = fields.Char('客户端IP')
|
||||||
|
response_time = fields.Float('响应时间(秒)', digits=(16, 6))
|
||||||
|
status = fields.Integer('状态码')
|
||||||
|
requester = fields.Char('请求方')
|
||||||
|
responser = fields.Char('响应方')
|
||||||
@@ -254,3 +254,6 @@ access_sf_machining_accuracy_admin,sf_machining_accuracy_admin,model_sf_machinin
|
|||||||
|
|
||||||
access_sf_embryo_redundancy,sf_embryo_redundancy,model_sf_embryo_redundancy,base.group_user,1,0,0,0
|
access_sf_embryo_redundancy,sf_embryo_redundancy,model_sf_embryo_redundancy,base.group_user,1,0,0,0
|
||||||
access_sf_embryo_redundancy_admin,sf_embryo_redundancy_admin,model_sf_embryo_redundancy,base.group_system,1,0,0,0
|
access_sf_embryo_redundancy_admin,sf_embryo_redundancy_admin,model_sf_embryo_redundancy,base.group_system,1,0,0,0
|
||||||
|
|
||||||
|
access_api_request_log_user,api.request.log.user,model_api_request_log,base.group_user,1,0,0,0
|
||||||
|
access_api_request_log_admin,api.request.log.admin,model_api_request_log,base.group_system,1,1,1,1
|
||||||
|
62
sf_base/views/api_log_views.xml
Normal file
62
sf_base/views/api_log_views.xml
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<record id="view_api_request_log_tree" model="ir.ui.view">
|
||||||
|
<field name="name">api.request.log.tree</field>
|
||||||
|
<field name="model">api.request.log</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<tree>
|
||||||
|
<field name="create_date"/>
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="path"/>
|
||||||
|
<field name="method"/>
|
||||||
|
<field name="remote_addr"/>
|
||||||
|
<field name="response_time"/>
|
||||||
|
<field name="status"/>
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="view_api_request_log_form" model="ir.ui.view">
|
||||||
|
<field name="name">api.request.log.form</field>
|
||||||
|
<field name="model">api.request.log</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form>
|
||||||
|
<sheet>
|
||||||
|
<group>
|
||||||
|
<group>
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="path"/>
|
||||||
|
<field name="method"/>
|
||||||
|
<field name="remote_addr"/>
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="response_time"/>
|
||||||
|
<field name="status"/>
|
||||||
|
<field name="create_date" string="请求时间"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
<notebook>
|
||||||
|
<page string="请求数据">
|
||||||
|
<field name="request_data"/>
|
||||||
|
</page>
|
||||||
|
<page string="响应数据">
|
||||||
|
<field name="response_data"/>
|
||||||
|
</page>
|
||||||
|
</notebook>
|
||||||
|
</sheet>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="action_api_request_log" model="ir.actions.act_window">
|
||||||
|
<field name="name">API请求日志</field>
|
||||||
|
<field name="res_model">api.request.log</field>
|
||||||
|
<field name="view_mode">tree,form</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<menuitem id="menu_api_request_log"
|
||||||
|
name="API请求日志"
|
||||||
|
parent="base.next_id_9"
|
||||||
|
action="action_api_request_log"
|
||||||
|
sequence="100"/>
|
||||||
|
</odoo>
|
||||||
Reference in New Issue
Block a user