From cdbc277a94911a7e23e206479ff1e33132bd8acf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E8=B5=93?= <1440513926@qq.com> Date: Tue, 15 Jul 2025 11:28:12 +0800 Subject: [PATCH 1/9] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=20Redis=20?= =?UTF-8?q?=E5=B7=A5=E5=85=B7=E4=B8=8E=E6=8E=A7=E5=88=B6=E5=99=A8=EF=BC=8C?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=90=8C=E6=AD=A5=E9=80=BB=E8=BE=91=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements.txt | 2 +- sf_mrs_connect/controllers/__init__.py | 1 + sf_mrs_connect/models/sync_common.py | 372 ++++++++++++++++--------- 3 files changed, 238 insertions(+), 137 deletions(-) diff --git a/requirements.txt b/requirements.txt index 5aabe0ef..8226420a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,4 +4,4 @@ wechatpy==1.8.18 pycryptodome==3.22.0 openupgradelib==3.10.0 opcua==0.98.13 -openpyxl \ No newline at end of file +openpyxl diff --git a/sf_mrs_connect/controllers/__init__.py b/sf_mrs_connect/controllers/__init__.py index e046e49f..df498650 100644 --- a/sf_mrs_connect/controllers/__init__.py +++ b/sf_mrs_connect/controllers/__init__.py @@ -1 +1,2 @@ from . import controllers +from . import sync_controller \ No newline at end of file diff --git a/sf_mrs_connect/models/sync_common.py b/sf_mrs_connect/models/sync_common.py index 1aac07e3..8bc52d5b 100644 --- a/sf_mrs_connect/models/sync_common.py +++ b/sf_mrs_connect/models/sync_common.py @@ -5,9 +5,11 @@ import base64 import traceback import requests -from odoo import models +from odoo import models,api,fields from odoo.exceptions import ValidationError -from odoo.addons.sf_base.commons.common import Common +from .redis_utils import RedisClient +from .common import Common +from odoo.addons.jikimo_sf.sf_base.commons.common import Common _logger = logging.getLogger(__name__) @@ -1506,149 +1508,157 @@ class SyncMulti_Mounting_Type(models.Model): raise ValidationError("联装类型认证未通过") -class SyncFixtureModel(models.Model): - _inherit = 'sf.fixture.model' - _description = '同步夹具型号列表' +# class SyncFixtureModel(models.Model): +# _inherit = 'sf.fixture.model' +# _description = '同步夹具型号列表' - url = '/api/fixture_model/list' +# url = '/api/fixture_model/list' - # 定时同步夹具型号列表 - def sync_fixture_model_yesterday(self): - config = self.env['res.config.settings'].get_values() - headers = Common.get_headers(self, config['token'], config['sf_secret_key']) - strUrl = config['sf_url'] + self.url - r = requests.post(strUrl, json={}, data=None, headers=headers) - r = r.json() - result = json.loads(r['result']) - if result['status'] == 1: - if result.get('fixture_model_yesterday_list'): - for item in result['fixture_model_yesterday_list']: - if item: - fixture_model = self.search([("code", '=', item['code']), ('active', 'in', [True, False])]) - val = { - "name": item['name'], - "code": item['code'], - "fixture_material_id": self.env['sf.fixture.material'].search( - [('code', '=', item['fixture_material_code'])]).id, - "multi_mounting_type_id": self.env['sf.multi_mounting.type'].search( - [('code', '=', item['multi_mounting_type_code'])]).id, - "brand_id": self.env['sf.machine.brand'].search([('code', '=', item['brand_code'])]).id, - "model_file": '' if not item['model_file'] else base64.b64decode(item['model_file']), - "status": item['status'], - "active": item['active'], - } - if not fixture_model: - self.create(val) - else: - fixture_model.write(val) +# # 定时同步夹具型号列表 +# def sync_fixture_model_yesterday(self): +# config = self.env['res.config.settings'].get_values() +# headers = Common.get_headers(self, config['token'], config['sf_secret_key']) +# strUrl = config['sf_url'] + self.url +# r = requests.post(strUrl, json={}, data=None, headers=headers) +# r = r.json() +# result = json.loads(r['result']) +# if result['status'] == 1: +# if result.get('fixture_model_yesterday_list'): +# for item in result['fixture_model_yesterday_list']: +# if item: +# fixture_model = self.search([("code", '=', item['code']), ('active', 'in', [True, False])]) +# val = { +# "name": item['name'], +# "code": item['code'], +# "fixture_material_id": self.env['sf.fixture.material'].search( +# [('code', '=', item['fixture_material_code'])]).id, +# "multi_mounting_type_id": self.env['sf.multi_mounting.type'].search( +# [('code', '=', item['multi_mounting_type_code'])]).id, +# "brand_id": self.env['sf.machine.brand'].search([('code', '=', item['brand_code'])]).id, +# "model_file": '' if not item['model_file'] else base64.b64decode(item['model_file']), +# "status": item['status'], +# "active": item['active'], +# } +# if not fixture_model: +# self.create(val) +# else: +# fixture_model.write(val) - else: - raise ValidationError("夹具型号认证未通过") +# else: +# raise ValidationError("夹具型号认证未通过") - # 定时同步所有夹具型号列表 - def sync_all_fixture_model(self): - config = self.env['res.config.settings'].get_values() - headers = Common.get_headers(self, config['token'], config['sf_secret_key']) - strUrl = config['sf_url'] + self.url - r = requests.post(strUrl, json={}, data=None, headers=headers) - r = r.json() - result = json.loads(r['result']) - # print('result:%s' % result) - if result['status'] == 1: - if result.get('fixture_model_all_list'): - for item in result['fixture_model_all_list']: - if item: - fixture_model = self.search([('code', '=', item['code']), ('active', 'in', [True, False])]) - val = { - "name": item['name'], - "code": item['code'], - "fixture_material_id": self.env['sf.fixture.material'].search( - [('code', '=', item['fixture_material_code'])]).id, - "multi_mounting_type_id": self.env['sf.multi_mounting.type'].search( - [('code', '=', item['multi_mounting_type_code'])]).id, - "brand_id": self.env['sf.machine.brand'].search([('code', '=', item['brand_code'])]).id, - "model_file": '' if not item['model_file'] else base64.b64decode(item['model_file']), - "status": item['status'], - "active": item['active'], - } - if not fixture_model: - self.create(val) - else: - fixture_model.write(val) - else: - raise ValidationError("夹具型号认证未通过") +# # 定时同步所有夹具型号列表 +# def sync_all_fixture_model(self): +# config = self.env['res.config.settings'].get_values() +# headers = Common.get_headers(self, config['token'], config['sf_secret_key']) +# strUrl = config['sf_url'] + self.url +# r = requests.post(strUrl, json={}, data=None, headers=headers) +# r = r.json() +# result = json.loads(r['result']) +# # print('result:%s' % result) +# if result['status'] == 1: +# if result.get('fixture_model_all_list'): +# for item in result['fixture_model_all_list']: +# if item: +# fixture_model = self.search([('code', '=', item['code']), ('active', 'in', [True, False])]) +# val = { +# "name": item['name'], +# "code": item['code'], +# "fixture_material_id": self.env['sf.fixture.material'].search( +# [('code', '=', item['fixture_material_code'])]).id, +# "multi_mounting_type_id": self.env['sf.multi_mounting.type'].search( +# [('code', '=', item['multi_mounting_type_code'])]).id, +# "brand_id": self.env['sf.machine.brand'].search([('code', '=', item['brand_code'])]).id, +# "model_file": '' if not item['model_file'] else base64.b64decode(item['model_file']), +# "status": item['status'], +# "active": item['active'], +# } +# if not fixture_model: +# self.create(val) +# else: +# fixture_model.write(val) +# else: +# raise ValidationError("夹具型号认证未通过") -class SyncfixtureMaterialsBasicParameters(models.Model): - _inherit = 'sf.fixture.materials.basic.parameters' - _description = '同步夹具型号基本参数列表' +# class SyncfixtureMaterialsBasicParameters(models.Model): +# _inherit = 'sf.fixture.materials.basic.parameters' +# _description = '同步夹具型号基本参数列表' - url = '/api/fixture_parameters/list' +# url = '/api/fixture_parameters/list' - # 定时同步夹具型号基本信息 - def sync_fixture_materials_basic_parameters_yesterday(self): - config = self.env['res.config.settings'].get_values() - headers = Common.get_headers(self, config['token'], config['sf_secret_key']) - strUrl = config['sf_url'] + self.url - r = requests.post(strUrl, json={}, data=None, headers=headers) - r = r.json() - result = json.loads(r['result']) - if result['status'] == 1: - if result.get('fixture_parameters_yesterday_list'): - all_list = result.get('fixture_parameters_yesterday_list') - if all_list.get('zero_chuck_all_list'): - self._write_or_create(all_list.get('zero_chuck_yesterday_list'), '零点卡盘') - if all_list.get('zero_tray_all_list'): - self._write_or_create(all_list.get('zero_tray_yesterday_list'), '零点托盘') - if all_list.get('pneumatic_fixture_all_list'): - self._write_or_create(all_list.get('pneumatic_fixture_yesterday_list'), '气动夹具') - if all_list.get('jaw_vice_all_list'): - self._write_or_create(all_list.get('jaw_vice_yesterday_list'), '虎钳夹具') - if all_list.get('magnet_fixture_all_list'): - self._write_or_create(all_list.get('magnet_fixture_yesterday_list'), '磁吸夹具') - if all_list.get('adapter_board_all_list'): - self._write_or_create(all_list.get('adapter_board_yesterday_list'), '转接板(锁板)夹具') - if all_list.get('scroll_chuck_all_list'): - self._write_or_create(all_list.get('scroll_chuck_yesterday_list'), '三爪卡盘') - else: - raise ValidationError("夹具型号基本参数认证未通过") +# # 定时同步夹具型号基本信息 +# def sync_fixture_materials_basic_parameters_yesterday(self): +# config = self.env['res.config.settings'].get_values() +# headers = Common.get_headers(self, config['token'], config['sf_secret_key']) +# strUrl = config['sf_url'] + self.url +# r = requests.post(strUrl, json={}, data=None, headers=headers) +# r = r.json() +# result = json.loads(r['result']) +# if result['status'] == 1: +# if result.get('fixture_parameters_yesterday_list'): +# all_list = result.get('fixture_parameters_yesterday_list') +# if all_list.get('zero_chuck_all_list'): +# self._write_or_create(all_list.get('zero_chuck_yesterday_list'), '零点卡盘') +# if all_list.get('zero_tray_all_list'): +# self._write_or_create(all_list.get('zero_tray_yesterday_list'), '零点托盘') +# if all_list.get('pneumatic_fixture_all_list'): +# self._write_or_create(all_list.get('pneumatic_fixture_yesterday_list'), '气动夹具') +# if all_list.get('jaw_vice_all_list'): +# self._write_or_create(all_list.get('jaw_vice_yesterday_list'), '虎钳夹具') +# if all_list.get('magnet_fixture_all_list'): +# self._write_or_create(all_list.get('magnet_fixture_yesterday_list'), '磁吸夹具') +# if all_list.get('adapter_board_all_list'): +# self._write_or_create(all_list.get('adapter_board_yesterday_list'), '转接板(锁板)夹具') +# if all_list.get('scroll_chuck_all_list'): +# self._write_or_create(all_list.get('scroll_chuck_yesterday_list'), '三爪卡盘') +# if all_list.get('air_tray_all_list'): +# self._write_or_create(all_list.get('air_tray_all_list'),'气吹托盘') +# if all_list.get('magnet_tray_all_list'): +# self._write_or_create(all_list.get('magnet_tray_all_list'),'磁吸托盘') +# else: +# raise ValidationError("夹具型号基本参数认证未通过") - # 定时同步所有夹具型号基本信息 - def sync_all_fixture_materials_basic_parameters(self): - config = self.env['res.config.settings'].get_values() - headers = Common.get_headers(self, config['token'], config['sf_secret_key']) - strUrl = config['sf_url'] + self.url - r = requests.post(strUrl, json={}, data=None, headers=headers) - r = r.json() - result = json.loads(r['result']) - if result['status'] == 1: - if result.get('fixture_parameters_all_list'): - all_list = result.get('fixture_parameters_all_list') - if all_list.get('zero_chuck_all_list'): - self._write_or_create(all_list.get('zero_chuck_all_list'), '零点卡盘') - if all_list.get('zero_tray_all_list'): - self._write_or_create(all_list.get('zero_tray_all_list'), '零点托盘') - if all_list.get('pneumatic_fixture_all_list'): - self._write_or_create(all_list.get('pneumatic_fixture_all_list'), '气动夹具') - if all_list.get('jaw_vice_all_list'): - self._write_or_create(all_list.get('jaw_vice_all_list'), '虎钳夹具') - if all_list.get('magnet_fixture_all_list'): - self._write_or_create(all_list.get('magnet_fixture_all_list'), '磁吸夹具') - if all_list.get('adapter_board_all_list'): - self._write_or_create(all_list.get('adapter_board_all_list'), '转接板(锁板)夹具') - if all_list.get('scroll_chuck_all_list'): - self._write_or_create(all_list.get('scroll_chuck_all_list'), '三爪卡盘') - else: - raise ValidationError("夹具型号基本参数认证未通过") +# # 定时同步所有夹具型号基本信息 +# def sync_all_fixture_materials_basic_parameters(self): +# config = self.env['res.config.settings'].get_values() +# headers = Common.get_headers(self, config['token'], config['sf_secret_key']) +# strUrl = config['sf_url'] + self.url +# r = requests.post(strUrl, json={}, data=None, headers=headers) +# r = r.json() +# result = json.loads(r['result']) +# if result['status'] == 1: +# if result.get('fixture_parameters_all_list'): +# all_list = result.get('fixture_parameters_all_list') +# if all_list.get('zero_chuck_all_list'): +# self._write_or_create(all_list.get('zero_chuck_all_list'), '零点卡盘') +# if all_list.get('zero_tray_all_list'): +# self._write_or_create(all_list.get('zero_tray_all_list'), '零点托盘') +# if all_list.get('pneumatic_fixture_all_list'): +# self._write_or_create(all_list.get('pneumatic_fixture_all_list'), '气动夹具') +# if all_list.get('jaw_vice_all_list'): +# self._write_or_create(all_list.get('jaw_vice_all_list'), '虎钳夹具') +# if all_list.get('magnet_fixture_all_list'): +# self._write_or_create(all_list.get('magnet_fixture_all_list'), '磁吸夹具') +# if all_list.get('adapter_board_all_list'): +# self._write_or_create(all_list.get('adapter_board_all_list'), '转接板(锁板)夹具') +# if all_list.get('scroll_chuck_all_list'): +# self._write_or_create(all_list.get('scroll_chuck_all_list'), '三爪卡盘') +# if all_list.get('air_tray_all_list'): +# self._write_or_create(all_list.get('air_tray_all_list'),'气吹托盘') +# if all_list.get('magnet_tray_all_list'): +# self._write_or_create(all_list.get('magnet_tray_all_list'),'磁吸托盘') +# else: +# raise ValidationError("夹具型号基本参数认证未通过") - def _write_or_create(self, fixture_parameters_list, material_name): - for item in fixture_parameters_list: - if item: - basic_parameters = self.search([('code', '=', item.get('code')), ('active', 'in', [True, False])]) - if not basic_parameters: - self.create(self._get_basic_parameters_list(item, material_name)) - else: - basic_parameters.write(self._get_basic_parameters_list(item, material_name)) +# def _write_or_create(self, fixture_parameters_list, material_name): +# for item in fixture_parameters_list: +# if item: +# basic_parameters = self.search([('code', '=', item.get('code')), ('active', 'in', [True, False])]) +# if not basic_parameters: +# self.create(self._get_basic_parameters_list(item, material_name)) +# else: +# basic_parameters.write(self._get_basic_parameters_list(item, material_name)) class SyncFunctionalFixtureType(models.Model): @@ -3230,4 +3240,94 @@ class EmbryoRedundancySync(models.Model): "height": item['height'], "active": item['active'], "remark": item['remark'], - }) \ No newline at end of file + }) + + + + + + +class SyncFixtureModel(models.Model): + _inherit = 'sf.fixture.model' + _description = 'Redis 优先同步夹具型号' + + def sync_all_fixture_model(self): + rc = RedisClient() + key = 'mrs:fixture_model_all_list' + all_list = rc.get_json(key) + if not all_list: + raise ValidationError(f"Redis 中未找到 key={key}") + + for item in all_list: + if not item or not item.get('code'): + continue + + record = self.search([('code', '=', item['code'])], limit=1) + vals = { + 'name': item['name'], + 'code': item['code'], + 'fixture_material_id': self.env['sf.fixture.material'] + .search([('code', '=', item['fixture_material_code'])], limit=1).id, + 'multi_mounting_type_id': self.env['sf.multi_mounting.type'] + .search([('code', '=', item['multi_mounting_type_code'])], limit=1).id, + 'brand_id': self.env['sf.machine.brand'] + .search([('code', '=', item['brand_code'])], limit=1).id, + 'model_file': base64.b64decode(item['model_file']) if item.get('model_file') else False, + 'status': item['status'], + 'active': item['active'], + } + if record: + record.write(vals) + else: + self.create(vals) + + +class SyncfixtureMaterialsBasicParameters(models.Model): + _inherit = 'sf.fixture.materials.basic.parameters' + _description = 'Redis 优先同步夹具基本参数' + + def sync_all_fixture_materials_basic_parameters(self): + rc = RedisClient() + key = 'mrs:fixture_param_all_list' + all_list = rc.get_json(key) + if not all_list: + raise ValidationError(f"Redis 中未找到 key={key}") + + def _sync_list(param_list, material_name): + for item in param_list or []: + if not item or not item.get('code'): + continue + record = self.search([('code', '=', item['code'])], limit=1) + vals = self._get_basic_parameters_list(item, material_name) + if record: + record.write(vals) + else: + self.create(vals) + + _sync_list(all_list.get('zero_chuck_all_list'), '零点卡盘') + _sync_list(all_list.get('zero_tray_all_list'), '零点托盘') + _sync_list(all_list.get('pneumatic_fixture_all_list'), '气动夹具') + _sync_list(all_list.get('jaw_vice_all_list'), '虎钳夹具') + _sync_list(all_list.get('magnet_fixture_all_list'), '磁吸夹具') + _sync_list(all_list.get('adapter_board_all_list'), '转接板(锁板)夹具') + _sync_list(all_list.get('scroll_chuck_all_list'), '三爪卡盘') + _sync_list(all_list.get('air_tray_all_list'), '气吹托盘') + _sync_list(all_list.get('magnet_tray_all_list'), '磁吸托盘') + + def _get_basic_parameters_list(self, item, material_name): + """ + 统一结构化 item 数据,供写入模型字段使用(你应当根据 material_name 自定义字段映射) + """ + return { + 'name': item.get('name'), + 'code': item.get('code'), + 'length': item.get('length'), + 'width': item.get('width'), + 'height': item.get('height'), + 'diameter': item.get('diameter'), + 'weight': item.get('weight'), + 'fixture_model_id': self.env['sf.fixture.model'].search([('code', '=', item.get('fixture_model_code'))], limit=1).id, + 'materials_model_id': self.env['sf.materials.model'].search([('code', '=', item.get('material_code'))], limit=1).id, + 'active': item.get('active', True), + # 你可以根据 material_name 判断类型并补充字段 + } \ No newline at end of file From 8e8f5eb8beccb0b5eb36b24ff55ed160435eb206 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E8=B5=93?= <1440513926@qq.com> Date: Tue, 15 Jul 2025 11:29:18 +0800 Subject: [PATCH 2/9] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=20Redis=20?= =?UTF-8?q?=E7=BC=93=E5=AD=98=E5=90=8C=E6=AD=A5=E7=9B=B8=E5=85=B3=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=E4=B8=8E=E6=8E=A7=E5=88=B6=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_mrs_connect/controllers/sync_controller.py | 22 ++++++++++++++ sf_mrs_connect/models/common.py | 14 +++++++++ sf_mrs_connect/models/redis_utils.py | 30 +++++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 sf_mrs_connect/controllers/sync_controller.py create mode 100644 sf_mrs_connect/models/common.py create mode 100644 sf_mrs_connect/models/redis_utils.py diff --git a/sf_mrs_connect/controllers/sync_controller.py b/sf_mrs_connect/controllers/sync_controller.py new file mode 100644 index 00000000..a70ae60c --- /dev/null +++ b/sf_mrs_connect/controllers/sync_controller.py @@ -0,0 +1,22 @@ +# study/jikimo_sf/sf_mrs_connect/controllers/sync_controller.py +from odoo import http +from odoo.http import request + +class FixtureSyncController(http.Controller): + + @http.route('/api/fixture_model/sync_from_mrs', type='json', auth='none', csrf=False) + def sync_model(self, **kw): + code = kw.get('code') + if not code: + return {'status':'fail','msg':'code missing'} + request.env['sf.fixture.model'].sudo().sync_from_mrs(code) + return {'status':'success'} + + @http.route('/api/fixture_param/sync_from_mrs', type='json', auth='none', csrf=False) + def sync_param(self, **kw): + code = kw.get('code') + if not code: + return {'status':'fail','msg':'code missing'} + request.env['sf.fixture.materials.basic.parameters']\ + .sudo().sync_from_mrs(code) + return {'status':'success'} diff --git a/sf_mrs_connect/models/common.py b/sf_mrs_connect/models/common.py new file mode 100644 index 00000000..320f6cac --- /dev/null +++ b/sf_mrs_connect/models/common.py @@ -0,0 +1,14 @@ +# study/jikimo_sf/sf_mrs_connect/models/common.py +import time, hashlib + +class Common: + @staticmethod + def get_headers(token, secret_key): + ts = str(int(time.time())) + sign = hashlib.sha256(f"{token}{secret_key}{ts}".encode()).hexdigest() + return { + "token": token, + "sign": sign, + "timestamp": ts, + "Content-Type": "application/json", + } diff --git a/sf_mrs_connect/models/redis_utils.py b/sf_mrs_connect/models/redis_utils.py new file mode 100644 index 00000000..24b679c2 --- /dev/null +++ b/sf_mrs_connect/models/redis_utils.py @@ -0,0 +1,30 @@ +# study/jikimo_sf/sf_mrs_connect/models/redis_utils.py +import redis, json, logging + +_logger = logging.getLogger(__name__) + +class RedisClient: + def __init__(self, host='localhost', port=6379, db=0): + try: + self.client = redis.Redis(host=host, port=port, db=db, decode_responses=True) + except Exception as e: + _logger.error(f"Redis init error: {e}") + self.client = None + + def get_json(self, key): + if not self.client: + return None + try: + data = self.client.get(key) + return json.loads(data) if data else None + except Exception as e: + _logger.error(f"Redis GET error [{key}]: {e}") + return None + + def set_json(self, key, value, ex=3600): + if not self.client: + return + try: + self.client.set(key, json.dumps(value, ensure_ascii=False), ex=ex) + except Exception as e: + _logger.error(f"Redis SET error [{key}]: {e}") From cdf6a36c30fb7dcc12765c45d72a5f3040792418 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E8=B5=93?= <1440513926@qq.com> Date: Wed, 16 Jul 2025 11:49:41 +0800 Subject: [PATCH 3/9] =?UTF-8?q?Redis=E5=90=8C=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_mrs_connect/controllers/__init__.py | 3 +- .../controllers/refresh_controller.py | 10 ++ sf_mrs_connect/controllers/sync_controller.py | 2 +- sf_mrs_connect/models/__init__.py | 2 + sf_mrs_connect/models/redis_utils.py | 2 +- sf_mrs_connect/models/sync_common.py | 141 +++++++++--------- 6 files changed, 89 insertions(+), 71 deletions(-) create mode 100644 sf_mrs_connect/controllers/refresh_controller.py diff --git a/sf_mrs_connect/controllers/__init__.py b/sf_mrs_connect/controllers/__init__.py index df498650..c57cd7f7 100644 --- a/sf_mrs_connect/controllers/__init__.py +++ b/sf_mrs_connect/controllers/__init__.py @@ -1,2 +1,3 @@ from . import controllers -from . import sync_controller \ No newline at end of file +from . import sync_controller +from . import refresh_controller \ No newline at end of file diff --git a/sf_mrs_connect/controllers/refresh_controller.py b/sf_mrs_connect/controllers/refresh_controller.py new file mode 100644 index 00000000..4a7bce1a --- /dev/null +++ b/sf_mrs_connect/controllers/refresh_controller.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +from odoo import http +from odoo.http import request + +class FixtureRedisRefreshController(http.Controller): + + @http.route('/api/refresh_redis/fixture_param', type='json', auth='none', csrf=False, methods=['POST']) + def refresh_fixture_param_redis(self, **kw): + request.env['mrs.basic_parameters.mixin'].sudo().refresh_all_param_redis() + return {'status': 'success', 'msg': 'Redis 缓存已刷新'} diff --git a/sf_mrs_connect/controllers/sync_controller.py b/sf_mrs_connect/controllers/sync_controller.py index a70ae60c..4a38510c 100644 --- a/sf_mrs_connect/controllers/sync_controller.py +++ b/sf_mrs_connect/controllers/sync_controller.py @@ -19,4 +19,4 @@ class FixtureSyncController(http.Controller): return {'status':'fail','msg':'code missing'} request.env['sf.fixture.materials.basic.parameters']\ .sudo().sync_from_mrs(code) - return {'status':'success'} + return {'status':'success'} \ No newline at end of file diff --git a/sf_mrs_connect/models/__init__.py b/sf_mrs_connect/models/__init__.py index 01498b21..7038b520 100644 --- a/sf_mrs_connect/models/__init__.py +++ b/sf_mrs_connect/models/__init__.py @@ -2,3 +2,5 @@ from . import ftp_operate from . import res_config_setting from . import sync_common from . import order_price +from . import redis_utils +from . import common \ No newline at end of file diff --git a/sf_mrs_connect/models/redis_utils.py b/sf_mrs_connect/models/redis_utils.py index 24b679c2..ce57685f 100644 --- a/sf_mrs_connect/models/redis_utils.py +++ b/sf_mrs_connect/models/redis_utils.py @@ -27,4 +27,4 @@ class RedisClient: try: self.client.set(key, json.dumps(value, ensure_ascii=False), ex=ex) except Exception as e: - _logger.error(f"Redis SET error [{key}]: {e}") + _logger.error(f"Redis SET error [{key}]: {e}") \ No newline at end of file diff --git a/sf_mrs_connect/models/sync_common.py b/sf_mrs_connect/models/sync_common.py index 8bc52d5b..b956d075 100644 --- a/sf_mrs_connect/models/sync_common.py +++ b/sf_mrs_connect/models/sync_common.py @@ -5,11 +5,9 @@ import base64 import traceback import requests -from odoo import models,api,fields +from odoo import models from odoo.exceptions import ValidationError -from .redis_utils import RedisClient -from .common import Common -from odoo.addons.jikimo_sf.sf_base.commons.common import Common +from odoo.addons.sf_base.commons.common import Common _logger = logging.getLogger(__name__) @@ -1548,7 +1546,7 @@ class SyncMulti_Mounting_Type(models.Model): # raise ValidationError("夹具型号认证未通过") # # 定时同步所有夹具型号列表 -# def sync_all_fixture_model(self): +# def sync_all_fixture_model(self): # config = self.env['res.config.settings'].get_values() # headers = Common.get_headers(self, config['token'], config['sf_secret_key']) # strUrl = config['sf_url'] + self.url @@ -1612,10 +1610,6 @@ class SyncMulti_Mounting_Type(models.Model): # self._write_or_create(all_list.get('adapter_board_yesterday_list'), '转接板(锁板)夹具') # if all_list.get('scroll_chuck_all_list'): # self._write_or_create(all_list.get('scroll_chuck_yesterday_list'), '三爪卡盘') -# if all_list.get('air_tray_all_list'): -# self._write_or_create(all_list.get('air_tray_all_list'),'气吹托盘') -# if all_list.get('magnet_tray_all_list'): -# self._write_or_create(all_list.get('magnet_tray_all_list'),'磁吸托盘') # else: # raise ValidationError("夹具型号基本参数认证未通过") @@ -1640,14 +1634,10 @@ class SyncMulti_Mounting_Type(models.Model): # self._write_or_create(all_list.get('jaw_vice_all_list'), '虎钳夹具') # if all_list.get('magnet_fixture_all_list'): # self._write_or_create(all_list.get('magnet_fixture_all_list'), '磁吸夹具') -# if all_list.get('adapter_board_all_list'): +# if all_list.get('adapter_board_all_list'): # self._write_or_create(all_list.get('adapter_board_all_list'), '转接板(锁板)夹具') # if all_list.get('scroll_chuck_all_list'): # self._write_or_create(all_list.get('scroll_chuck_all_list'), '三爪卡盘') -# if all_list.get('air_tray_all_list'): -# self._write_or_create(all_list.get('air_tray_all_list'),'气吹托盘') -# if all_list.get('magnet_tray_all_list'): -# self._write_or_create(all_list.get('magnet_tray_all_list'),'磁吸托盘') # else: # raise ValidationError("夹具型号基本参数认证未通过") @@ -3247,6 +3237,56 @@ class EmbryoRedundancySync(models.Model): +class SyncfixtureMaterialsBasicParameters(models.Model): + _inherit = 'sf.fixture.materials.basic.parameters' + _description = 'Redis 优先同步夹具基本参数' + + def sync_all_fixture_materials_basic_parameters(self): + rc = RedisClient() + key = 'mrs:fixture_param_all_list' + all_list = rc.get_json(key) + + # ✅ Redis 无数据时,请求 MRS 端刷新 Redis 缓存 + if not all_list: + config = self.env['res.config.settings'].get_values() + headers = Common.get_headers(config['token'], config['sf_secret_key']) + refresh_url = config['mrs_url'] + '/api/refresh_redis/fixture_param' + + try: + res = requests.post(refresh_url, headers=headers, json={}, timeout=10) + res.raise_for_status() + except Exception as e: + raise ValidationError(f"Redis 无数据,MRS 缓存刷新失败: {str(e)}") + + # 再次尝试从 Redis 获取 + all_list = rc.get_json(key) + if not all_list: + raise ValidationError("Redis 刷新后仍无数据,无法同步夹具基本参数") + + # ✅ 同步函数作为局部函数定义在方法体内部 + def _sync_list(param_list, material_name): + for item in param_list or []: + if not item or not item.get('code'): + continue + record = self.search([('code', '=', item['code'])], limit=1) + vals = self._get_basic_parameters_list(item, material_name) + if record: + record.write(vals) + else: + self.create(vals) + + # ✅ 各类夹具参数同步调用 + _sync_list(all_list.get('zero_chuck_all_list'), '零点卡盘') + _sync_list(all_list.get('zero_tray_all_list'), '零点托盘') + _sync_list(all_list.get('pneumatic_fixture_all_list'), '气动夹具') + _sync_list(all_list.get('jaw_vice_all_list'), '虎钳夹具') + _sync_list(all_list.get('magnet_fixture_all_list'), '磁吸夹具') + _sync_list(all_list.get('adapter_board_all_list'), '转接板(锁板)夹具') + _sync_list(all_list.get('scroll_chuck_all_list'), '三爪卡盘') + _sync_list(all_list.get('air_tray_all_list'), '气吹托盘') + _sync_list(all_list.get('magnet_tray_all_list'), '磁吸托盘') + + class SyncFixtureModel(models.Model): _inherit = 'sf.fixture.model' _description = 'Redis 优先同步夹具型号' @@ -3255,9 +3295,25 @@ class SyncFixtureModel(models.Model): rc = RedisClient() key = 'mrs:fixture_model_all_list' all_list = rc.get_json(key) - if not all_list: - raise ValidationError(f"Redis 中未找到 key={key}") + # ✅ Redis 没数据时,请求 MRS 接口刷新 + if not all_list: + config = self.env['res.config.settings'].get_values() + headers = Common.get_headers(config['token'], config['sf_secret_key']) + refresh_url = config['mrs_url'] + '/api/refresh_redis/fixture_model' + + try: + res = requests.post(refresh_url, headers=headers, json={}, timeout=10) + res.raise_for_status() + except Exception as e: + raise ValidationError(f"Redis 无数据,MRS 刷新失败: {str(e)}") + + # 再次尝试获取 Redis + all_list = rc.get_json(key) + if not all_list: + raise ValidationError("刷新后仍无 Redis 数据,无法同步夹具型号") + + # ✅ 开始同步夹具型号 for item in all_list: if not item or not item.get('code'): continue @@ -3279,55 +3335,4 @@ class SyncFixtureModel(models.Model): if record: record.write(vals) else: - self.create(vals) - - -class SyncfixtureMaterialsBasicParameters(models.Model): - _inherit = 'sf.fixture.materials.basic.parameters' - _description = 'Redis 优先同步夹具基本参数' - - def sync_all_fixture_materials_basic_parameters(self): - rc = RedisClient() - key = 'mrs:fixture_param_all_list' - all_list = rc.get_json(key) - if not all_list: - raise ValidationError(f"Redis 中未找到 key={key}") - - def _sync_list(param_list, material_name): - for item in param_list or []: - if not item or not item.get('code'): - continue - record = self.search([('code', '=', item['code'])], limit=1) - vals = self._get_basic_parameters_list(item, material_name) - if record: - record.write(vals) - else: - self.create(vals) - - _sync_list(all_list.get('zero_chuck_all_list'), '零点卡盘') - _sync_list(all_list.get('zero_tray_all_list'), '零点托盘') - _sync_list(all_list.get('pneumatic_fixture_all_list'), '气动夹具') - _sync_list(all_list.get('jaw_vice_all_list'), '虎钳夹具') - _sync_list(all_list.get('magnet_fixture_all_list'), '磁吸夹具') - _sync_list(all_list.get('adapter_board_all_list'), '转接板(锁板)夹具') - _sync_list(all_list.get('scroll_chuck_all_list'), '三爪卡盘') - _sync_list(all_list.get('air_tray_all_list'), '气吹托盘') - _sync_list(all_list.get('magnet_tray_all_list'), '磁吸托盘') - - def _get_basic_parameters_list(self, item, material_name): - """ - 统一结构化 item 数据,供写入模型字段使用(你应当根据 material_name 自定义字段映射) - """ - return { - 'name': item.get('name'), - 'code': item.get('code'), - 'length': item.get('length'), - 'width': item.get('width'), - 'height': item.get('height'), - 'diameter': item.get('diameter'), - 'weight': item.get('weight'), - 'fixture_model_id': self.env['sf.fixture.model'].search([('code', '=', item.get('fixture_model_code'))], limit=1).id, - 'materials_model_id': self.env['sf.materials.model'].search([('code', '=', item.get('material_code'))], limit=1).id, - 'active': item.get('active', True), - # 你可以根据 material_name 判断类型并补充字段 - } \ No newline at end of file + self.create(vals) \ No newline at end of file From f4829f57a120766787313cbfa22419b442d707c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E8=B5=93?= <1440513926@qq.com> Date: Thu, 17 Jul 2025 11:08:42 +0800 Subject: [PATCH 4/9] =?UTF-8?q?=E8=BF=98=E5=8E=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/refresh_controller.py | 10 -- sf_mrs_connect/controllers/sync_controller.py | 22 ---- sf_mrs_connect/models/common.py | 14 --- sf_mrs_connect/models/redis_utils.py | 30 ----- sf_mrs_connect/models/sync_common.py | 114 +++++++++++++++--- 5 files changed, 94 insertions(+), 96 deletions(-) delete mode 100644 sf_mrs_connect/controllers/refresh_controller.py delete mode 100644 sf_mrs_connect/controllers/sync_controller.py delete mode 100644 sf_mrs_connect/models/common.py delete mode 100644 sf_mrs_connect/models/redis_utils.py diff --git a/sf_mrs_connect/controllers/refresh_controller.py b/sf_mrs_connect/controllers/refresh_controller.py deleted file mode 100644 index 4a7bce1a..00000000 --- a/sf_mrs_connect/controllers/refresh_controller.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- -from odoo import http -from odoo.http import request - -class FixtureRedisRefreshController(http.Controller): - - @http.route('/api/refresh_redis/fixture_param', type='json', auth='none', csrf=False, methods=['POST']) - def refresh_fixture_param_redis(self, **kw): - request.env['mrs.basic_parameters.mixin'].sudo().refresh_all_param_redis() - return {'status': 'success', 'msg': 'Redis 缓存已刷新'} diff --git a/sf_mrs_connect/controllers/sync_controller.py b/sf_mrs_connect/controllers/sync_controller.py deleted file mode 100644 index 4a38510c..00000000 --- a/sf_mrs_connect/controllers/sync_controller.py +++ /dev/null @@ -1,22 +0,0 @@ -# study/jikimo_sf/sf_mrs_connect/controllers/sync_controller.py -from odoo import http -from odoo.http import request - -class FixtureSyncController(http.Controller): - - @http.route('/api/fixture_model/sync_from_mrs', type='json', auth='none', csrf=False) - def sync_model(self, **kw): - code = kw.get('code') - if not code: - return {'status':'fail','msg':'code missing'} - request.env['sf.fixture.model'].sudo().sync_from_mrs(code) - return {'status':'success'} - - @http.route('/api/fixture_param/sync_from_mrs', type='json', auth='none', csrf=False) - def sync_param(self, **kw): - code = kw.get('code') - if not code: - return {'status':'fail','msg':'code missing'} - request.env['sf.fixture.materials.basic.parameters']\ - .sudo().sync_from_mrs(code) - return {'status':'success'} \ No newline at end of file diff --git a/sf_mrs_connect/models/common.py b/sf_mrs_connect/models/common.py deleted file mode 100644 index 320f6cac..00000000 --- a/sf_mrs_connect/models/common.py +++ /dev/null @@ -1,14 +0,0 @@ -# study/jikimo_sf/sf_mrs_connect/models/common.py -import time, hashlib - -class Common: - @staticmethod - def get_headers(token, secret_key): - ts = str(int(time.time())) - sign = hashlib.sha256(f"{token}{secret_key}{ts}".encode()).hexdigest() - return { - "token": token, - "sign": sign, - "timestamp": ts, - "Content-Type": "application/json", - } diff --git a/sf_mrs_connect/models/redis_utils.py b/sf_mrs_connect/models/redis_utils.py deleted file mode 100644 index ce57685f..00000000 --- a/sf_mrs_connect/models/redis_utils.py +++ /dev/null @@ -1,30 +0,0 @@ -# study/jikimo_sf/sf_mrs_connect/models/redis_utils.py -import redis, json, logging - -_logger = logging.getLogger(__name__) - -class RedisClient: - def __init__(self, host='localhost', port=6379, db=0): - try: - self.client = redis.Redis(host=host, port=port, db=db, decode_responses=True) - except Exception as e: - _logger.error(f"Redis init error: {e}") - self.client = None - - def get_json(self, key): - if not self.client: - return None - try: - data = self.client.get(key) - return json.loads(data) if data else None - except Exception as e: - _logger.error(f"Redis GET error [{key}]: {e}") - return None - - def set_json(self, key, value, ex=3600): - if not self.client: - return - try: - self.client.set(key, json.dumps(value, ensure_ascii=False), ex=ex) - except Exception as e: - _logger.error(f"Redis SET error [{key}]: {e}") \ No newline at end of file diff --git a/sf_mrs_connect/models/sync_common.py b/sf_mrs_connect/models/sync_common.py index b956d075..d2b314de 100644 --- a/sf_mrs_connect/models/sync_common.py +++ b/sf_mrs_connect/models/sync_common.py @@ -8,6 +8,9 @@ import requests from odoo import models from odoo.exceptions import ValidationError from odoo.addons.sf_base.commons.common import Common +from odoo.addons.sf_mrs_connect.models.common import Common + + _logger = logging.getLogger(__name__) @@ -3242,28 +3245,22 @@ class SyncfixtureMaterialsBasicParameters(models.Model): _description = 'Redis 优先同步夹具基本参数' def sync_all_fixture_materials_basic_parameters(self): + # 你已有的批量同步方法不变 rc = RedisClient() key = 'mrs:fixture_param_all_list' all_list = rc.get_json(key) - - # ✅ Redis 无数据时,请求 MRS 端刷新 Redis 缓存 if not all_list: config = self.env['res.config.settings'].get_values() headers = Common.get_headers(config['token'], config['sf_secret_key']) refresh_url = config['mrs_url'] + '/api/refresh_redis/fixture_param' - try: res = requests.post(refresh_url, headers=headers, json={}, timeout=10) res.raise_for_status() except Exception as e: raise ValidationError(f"Redis 无数据,MRS 缓存刷新失败: {str(e)}") - - # 再次尝试从 Redis 获取 all_list = rc.get_json(key) if not all_list: raise ValidationError("Redis 刷新后仍无数据,无法同步夹具基本参数") - - # ✅ 同步函数作为局部函数定义在方法体内部 def _sync_list(param_list, material_name): for item in param_list or []: if not item or not item.get('code'): @@ -3274,8 +3271,6 @@ class SyncfixtureMaterialsBasicParameters(models.Model): record.write(vals) else: self.create(vals) - - # ✅ 各类夹具参数同步调用 _sync_list(all_list.get('zero_chuck_all_list'), '零点卡盘') _sync_list(all_list.get('zero_tray_all_list'), '零点托盘') _sync_list(all_list.get('pneumatic_fixture_all_list'), '气动夹具') @@ -3286,6 +3281,52 @@ class SyncfixtureMaterialsBasicParameters(models.Model): _sync_list(all_list.get('air_tray_all_list'), '气吹托盘') _sync_list(all_list.get('magnet_tray_all_list'), '磁吸托盘') + def sync_from_mrs(self, code): + rc = RedisClient() + key = 'mrs:fixture_param_all_list' + all_list = rc.get_json(key) or {} + if not all_list: + # Redis没数据,刷新一次 + config = self.env['res.config.settings'].get_values() + headers = Common.get_headers(config['token'], config['sf_secret_key']) + refresh_url = config['mrs_url'] + '/api/refresh_redis/fixture_param' + try: + res = requests.post(refresh_url, headers=headers, json={}, timeout=10) + res.raise_for_status() + except Exception as e: + raise ValidationError(f"Redis 无数据,MRS 缓存刷新失败: {str(e)}") + all_list = rc.get_json(key) or {} + if not all_list: + raise ValidationError("刷新后仍无 Redis 数据,无法同步夹具基本参数") + + # 遍历所有分类列表查找code匹配项 + for material_name, param_list in all_list.items(): + for item in param_list or []: + if item.get('code') == code: + vals = self._get_basic_parameters_list(item, material_name) + record = self.search([('code', '=', code)], limit=1) + if record: + record.write(vals) + else: + self.create(vals) + return True + return False + + def _get_basic_parameters_list(self, item, material_name): + # 请根据实际字段完善,这里给个示范 + return { + 'code': item.get('code'), + 'length': item.get('length'), + 'width': item.get('width'), + 'height': item.get('height'), + 'chucking_power_max': item.get('chucking_power_max'), + 'type_of_drive': item.get('type_of_drive'), + 'locking_method': item.get('locking_method'), + 'max_adsorp_force': item.get('max_adsorp_force'), + # 你可以加上 material_name 做记录或其它业务字段 + # 'material_name': material_name, + } + class SyncFixtureModel(models.Model): _inherit = 'sf.fixture.model' @@ -3295,39 +3336,32 @@ class SyncFixtureModel(models.Model): rc = RedisClient() key = 'mrs:fixture_model_all_list' all_list = rc.get_json(key) - - # ✅ Redis 没数据时,请求 MRS 接口刷新 if not all_list: config = self.env['res.config.settings'].get_values() headers = Common.get_headers(config['token'], config['sf_secret_key']) refresh_url = config['mrs_url'] + '/api/refresh_redis/fixture_model' - try: res = requests.post(refresh_url, headers=headers, json={}, timeout=10) res.raise_for_status() except Exception as e: raise ValidationError(f"Redis 无数据,MRS 刷新失败: {str(e)}") - - # 再次尝试获取 Redis all_list = rc.get_json(key) if not all_list: raise ValidationError("刷新后仍无 Redis 数据,无法同步夹具型号") - # ✅ 开始同步夹具型号 for item in all_list: if not item or not item.get('code'): continue - record = self.search([('code', '=', item['code'])], limit=1) vals = { 'name': item['name'], 'code': item['code'], 'fixture_material_id': self.env['sf.fixture.material'] - .search([('code', '=', item['fixture_material_code'])], limit=1).id, + .search([('code', '=', item.get('fixture_material_code'))], limit=1).id or False, 'multi_mounting_type_id': self.env['sf.multi_mounting.type'] - .search([('code', '=', item['multi_mounting_type_code'])], limit=1).id, + .search([('code', '=', item.get('multi_mounting_type_code'))], limit=1).id or False, 'brand_id': self.env['sf.machine.brand'] - .search([('code', '=', item['brand_code'])], limit=1).id, + .search([('code', '=', item.get('brand_code'))], limit=1).id or False, 'model_file': base64.b64decode(item['model_file']) if item.get('model_file') else False, 'status': item['status'], 'active': item['active'], @@ -3335,4 +3369,44 @@ class SyncFixtureModel(models.Model): if record: record.write(vals) else: - self.create(vals) \ No newline at end of file + self.create(vals) + + def sync_from_mrs(self, code): + rc = RedisClient() + key = 'mrs:fixture_model_all_list' + all_list = rc.get_json(key) or [] + if not all_list: + config = self.env['res.config.settings'].get_values() + headers = Common.get_headers(config['token'], config['sf_secret_key']) + refresh_url = config['mrs_url'] + '/api/refresh_redis/fixture_model' + try: + res = requests.post(refresh_url, headers=headers, json={}, timeout=10) + res.raise_for_status() + except Exception as e: + raise ValidationError(f"Redis 无数据,MRS 刷新失败: {str(e)}") + all_list = rc.get_json(key) or [] + if not all_list: + raise ValidationError("刷新后仍无 Redis 数据,无法同步夹具型号") + + for item in all_list: + if item.get('code') == code: + record = self.search([('code', '=', code)], limit=1) + vals = { + 'name': item['name'], + 'code': item['code'], + 'fixture_material_id': self.env['sf.fixture.material'] + .search([('code', '=', item.get('fixture_material_code'))], limit=1).id or False, + 'multi_mounting_type_id': self.env['sf.multi_mounting.type'] + .search([('code', '=', item.get('multi_mounting_type_code'))], limit=1).id or False, + 'brand_id': self.env['sf.machine.brand'] + .search([('code', '=', item.get('brand_code'))], limit=1).id or False, + 'model_file': base64.b64decode(item['model_file']) if item.get('model_file') else False, + 'status': item['status'], + 'active': item['active'], + } + if record: + record.write(vals) + else: + self.create(vals) + return True + return False From e73c0b15ead11a77717c531869d1cb483b4f15aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E8=B5=93?= <1440513926@qq.com> Date: Fri, 18 Jul 2025 09:26:30 +0800 Subject: [PATCH 5/9] =?UTF-8?q?=E5=A4=B9=E5=85=B7=E5=9E=8B=E5=8F=B7?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E6=95=B0=E6=8D=AE=E8=A1=A8=E7=9A=84=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_base/models/basic_parameters_fixture.py | 104 ++++ sf_base/models/fixture.py | 19 +- sf_base/views/fixture_view.xml | 46 ++ .../product_template_management_view.xml | 264 ++++++---- sf_manufacturing/models/product_template.py | 45 ++ sf_mrs_connect/models/__init__.py | 2 - sf_mrs_connect/models/sync_common.py | 450 ++++++------------ 7 files changed, 507 insertions(+), 423 deletions(-) diff --git a/sf_base/models/basic_parameters_fixture.py b/sf_base/models/basic_parameters_fixture.py index 868114e8..86432f7a 100644 --- a/sf_base/models/basic_parameters_fixture.py +++ b/sf_base/models/basic_parameters_fixture.py @@ -67,6 +67,52 @@ class BasicParametersFixture(models.Model): mounting_hole_depth = fields.Float('安装孔深度(mm)', digits=(16, 2)) centering_diameter = fields.Float('定心直径(mm)', digits=(16, 2)) + # ‘磁吸托盘’ 字段 + magnet_tray_length = fields.Float('磁吸托盘长度(mm)', digits=(16, 2)) + magnet_tray_width = fields.Float('磁吸托盘宽度(mm)', digits=(16, 2)) + magnet_tray_height = fields.Float('磁吸托盘厚度(mm)', digits=(16, 2)) + magnet_tray_diameter = fields.Float('磁吸托盘直径(mm)', digits=(16, 2)) + magnet_tray_weight = fields.Float('磁吸托盘重量(kg)', digits=(16, 2)) + + magnet_max_adsorp_length = fields.Float('磁吸托盘最大吸附长度(mm)', digits=(16, 2)) + magnet_max_adsorp_width = fields.Float('磁吸托盘最大吸附宽度(mm)', digits=(16, 2)) + magnet_max_adsorp_height = fields.Float('磁吸托盘最大吸附厚度(mm)', digits=(16, 2)) + magnet_max_adsorp_diameter = fields.Float('磁吸托盘最大吸附直径(mm)', digits=(16, 2)) + magnet_max_adsorp_force = fields.Float('磁吸托盘最大吸附力(N)', digits=(16, 2)) + + magnet_unlocking_method = fields.Selection( + [('手动', '手动'), ('气动', '气动'), ('液压', '液压'), ('电动', '电动'), ('其他', '其他')], + string='磁吸托盘锁紧方式' + ) + magnet_flatness = fields.Char('磁吸托盘平面精度(mm)', size=20) + magnet_max_load = fields.Float('磁吸托盘最大负载(kg)', digits=(16, 2)) + + # ‘气吸托盘’ 字段 + air_tray_length = fields.Float('气吸托盘长度(mm)', digits=(16, 2)) + air_tray_width = fields.Float('气吸托盘宽度(mm)', digits=(16, 2)) + air_tray_height = fields.Float('气吸托盘高度(mm)', digits=(16, 2)) + air_tray_diameter = fields.Float('气吸托盘直径(mm)', digits=(16, 2)) + air_tray_weight = fields.Float('气吸托盘重量(kg)', digits=(16, 2)) + + air_max_adsorp_length = fields.Float('气吸托盘最大吸附长度(mm)', digits=(16, 2)) + air_max_adsorp_width = fields.Float('气吸托盘最大吸附宽度(mm)', digits=(16, 2)) + air_max_adsorp_height = fields.Float('气吸托盘最大吸附厚度(mm)', digits=(16, 2)) + air_max_adsorp_diameter = fields.Float('气吸托盘最大吸附直径(mm)', digits=(16, 2)) + air_max_adsorp_force = fields.Float('气吸托盘最大吸附力(N)', digits=(16, 2)) + + air_unlocking_method = fields.Selection( + [('手动', '手动'), ('气动', '气动'), ('液压', '液压'), ('电动', '电动'), ('其他', '其他')], + string='气吸托盘锁紧方式' + ) + air_flatness = fields.Char('气吸托盘平面精度(mm)', size=20) + air_max_load = fields.Float('气吸托盘最大负载(kg)', digits=(16, 2)) + air_boolean_chip_blowing_function = fields.Boolean('气吸托盘是否有吹屑功能') + air_way_to_install = fields.Selection( + [('接口式', '接口式'), ('螺栓固定', '螺栓固定'), ('磁吸式', '磁吸式'), ('其他', '其他')], + string='气吸托盘安装方式' + ) + + code = fields.Char('编码') active = fields.Boolean('有效', default=True) @@ -85,6 +131,10 @@ class BasicParametersFixture(models.Model): return self._json_adapter_board_fixture_param(fixture_materials_data) elif fixture_materials_name == '三爪卡盘': return self._json_scroll_chuck_param(fixture_materials_data) + elif fixture_materials_name == '磁吸托盘': + return self._json_magnet_tray_param(fixture_materials_data) + elif fixture_materials_name == '气吸托盘': + return self._json_air_tray_param(fixture_materials_data) return {} def _json_zero_chuck_param(self, obj): @@ -284,3 +334,57 @@ class BasicParametersFixture(models.Model): 'centering_diameter': obj['centering_diameter'], 'type_of_drive': obj['type_of_drive'], 'active': obj['active']} + + def _json_magnet_tray_param(self, obj): + """磁吸托盘:将data数据转换成list数据""" + return { + 'code': obj['code'], + 'fixture_model_id': self.env['sf.fixture.model'].sudo().search( + [('code', '=', obj.get('fixture_model_code'))]).id, + 'name': obj['name'], + 'length': obj['length'], + 'width': obj['width'], + 'height': obj['height'], + 'diameter': obj['diameter'], + 'weight': obj['weight'], + 'max_adsorp_length': obj['max_adsorp_length'], + 'max_adsorp_width': obj['max_adsorp_width'], + 'max_adsorp_height': obj['max_adsorp_height'], + 'max_adsorp_diameter': obj.get('max_adsorp_diameter'), + 'max_adsorp_force': obj['max_adsorp_force'], + 'flatness': obj.get('flatness'), + 'max_load': obj.get('max_load'), + 'unlocking_method': obj.get('unlocking_method'), + 'materials_model_id': self.env['sf.materials.model'].sudo().search( + [('materials_no', '=', obj['materials_model_id']), ('active', '=', True)] + ).id if obj.get('materials_model_id') else False, + 'active': obj.get('active', True), + } + + def _json_air_tray_param(self, obj): + """气吸托盘:将data数据转换成list数据""" + return { + 'code': obj['code'], + 'fixture_model_id': self.env['sf.fixture.model'].sudo().search( + [('code', '=', obj.get('fixture_model_code'))]).id, + 'name': obj['name'], + 'length': obj['length'], + 'width': obj['width'], + 'height': obj['height'], + 'diameter': obj['diameter'], + 'weight': obj['weight'], + 'max_adsorp_length': obj['max_adsorp_length'], + 'max_adsorp_width': obj['max_adsorp_width'], + 'max_adsorp_height': obj['max_adsorp_height'], + 'max_adsorp_diameter': obj.get('max_adsorp_diameter'), + 'max_adsorp_force': obj['max_adsorp_force'], + 'flatness': obj.get('flatness'), + 'max_load': obj.get('max_load'), + 'unlocking_method': obj.get('unlocking_method'), + 'boolean_chip_blowing_function': obj.get('blowing_function', False), + 'way_to_install': obj.get('way_to_install'), + 'materials_model_id': self.env['sf.materials.model'].sudo().search( + [('materials_no', '=', obj['materials_model_id']), ('active', '=', True)] + ).id if obj.get('materials_model_id') else False, + 'active': obj.get('active', True), + } diff --git a/sf_base/models/fixture.py b/sf_base/models/fixture.py index 264878e9..82997a01 100644 --- a/sf_base/models/fixture.py +++ b/sf_base/models/fixture.py @@ -36,21 +36,24 @@ class FixtureModel(models.Model): status = fields.Boolean('状态') active = fields.Boolean('有效', default=False) - zero_chuck_ids = fields.One2many('sf.fixture.materials.basic.parameters', 'fixture_model_id', + zero_chuck_ids = fields.One2many('mrs.basic_parameters.zero.chuck', 'fixture_model_id', string='零点卡盘基本参数') - zero_tray_ids = fields.One2many('sf.fixture.materials.basic.parameters', 'fixture_model_id', + zero_tray_ids = fields.One2many('mrs.basic_parameters.zero.tray', 'fixture_model_id', string='零点托盘基本参数') - pneumatic_fixture_ids = fields.One2many('sf.fixture.materials.basic.parameters', 'fixture_model_id', + pneumatic_fixture_ids = fields.One2many('mrs.basic_parameters.pneumatic.fixture', 'fixture_model_id', string='气动夹具基本参数') - jaw_vice_fixture_ids = fields.One2many('sf.fixture.materials.basic.parameters', 'fixture_model_id', + jaw_vice_fixture_ids = fields.One2many('mrs.basic_parameters.jaw.vice.fixture', 'fixture_model_id', string='虎钳夹具基本参数') - magnet_fixture_ids = fields.One2many('sf.fixture.materials.basic.parameters', 'fixture_model_id', + magnet_fixture_ids = fields.One2many('mrs.basic_parameters.magnet.fixture', 'fixture_model_id', string='磁吸夹具基本参数') - adapter_board_fixture_ids = fields.One2many('sf.fixture.materials.basic.parameters', 'fixture_model_id', + magnet_tray_ids = fields.One2many('mrs.basic_parameters.magnet.tray', 'fixture_model_id', + string='磁吸托盘基本参数') + adapter_board_fixture_ids = fields.One2many('mrs.basic_parameters.adapter.board.fixture', 'fixture_model_id', string='转接板(锁板)夹具基本参数') - scroll_chuck_ids = fields.One2many('sf.fixture.materials.basic.parameters', 'fixture_model_id', + scroll_chuck_ids = fields.One2many('mrs.basic_parameters.scroll.chuck', 'fixture_model_id', string='三爪卡盘基本参数') - code = fields.Char(string='编码', readonly=True) + air_tray_ids = fields.One2many('mrs.basic_parameters.air.tray', 'fixture_model_id', + string='气吸托盘基本参数') # def _get_code(self, fixture_model_type_code): # fixture_model = self.env['sf.fixture.model'].sudo().search( diff --git a/sf_base/views/fixture_view.xml b/sf_base/views/fixture_view.xml index 1149875d..b7202eb3 100644 --- a/sf_base/views/fixture_view.xml +++ b/sf_base/views/fixture_view.xml @@ -328,6 +328,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sf_dlm_management/views/product_template_management_view.xml b/sf_dlm_management/views/product_template_management_view.xml index 75262611..eac5ecbf 100644 --- a/sf_dlm_management/views/product_template_management_view.xml +++ b/sf_dlm_management/views/product_template_management_view.xml @@ -513,112 +513,168 @@ - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/sf_manufacturing/models/product_template.py b/sf_manufacturing/models/product_template.py index 584399dc..8c0b95ac 100644 --- a/sf_manufacturing/models/product_template.py +++ b/sf_manufacturing/models/product_template.py @@ -1215,6 +1215,51 @@ class ResProductFixture(models.Model): mounting_hole_depth = fields.Float('安装孔深度(mm)', digits=(16, 2)) centering_diameter = fields.Float('定心直径(mm)', digits=(16, 2)) + # ‘磁吸托盘’ 字段 + magnet_tray_length = fields.Float('磁吸托盘长度(mm)', digits=(16, 2)) + magnet_tray_width = fields.Float('磁吸托盘宽度(mm)', digits=(16, 2)) + magnet_tray_height = fields.Float('磁吸托盘厚度(mm)', digits=(16, 2)) + magnet_tray_diameter = fields.Float('磁吸托盘直径(mm)', digits=(16, 2)) + magnet_tray_weight = fields.Float('磁吸托盘重量(kg)', digits=(16, 2)) + + magnet_max_adsorp_length = fields.Float('磁吸托盘最大吸附长度(mm)', digits=(16, 2)) + magnet_max_adsorp_width = fields.Float('磁吸托盘最大吸附宽度(mm)', digits=(16, 2)) + magnet_max_adsorp_height = fields.Float('磁吸托盘最大吸附厚度(mm)', digits=(16, 2)) + magnet_max_adsorp_diameter = fields.Float('磁吸托盘最大吸附直径(mm)', digits=(16, 2)) + magnet_max_adsorp_force = fields.Float('磁吸托盘最大吸附力(N)', digits=(16, 2)) + + magnet_unlocking_method = fields.Selection( + [('手动', '手动'), ('气动', '气动'), ('液压', '液压'), ('电动', '电动'), ('其他', '其他')], + string='磁吸托盘锁紧方式' + ) + magnet_flatness = fields.Char('磁吸托盘平面精度(mm)', size=20) + magnet_max_load = fields.Float('磁吸托盘最大负载(kg)', digits=(16, 2)) + + # ‘气吸托盘’ 字段 + air_tray_length = fields.Float('气吸托盘长度(mm)', digits=(16, 2)) + air_tray_width = fields.Float('气吸托盘宽度(mm)', digits=(16, 2)) + air_tray_height = fields.Float('气吸托盘高度(mm)', digits=(16, 2)) + air_tray_diameter = fields.Float('气吸托盘直径(mm)', digits=(16, 2)) + air_tray_weight = fields.Float('气吸托盘重量(kg)', digits=(16, 2)) + + air_max_adsorp_length = fields.Float('气吸托盘最大吸附长度(mm)', digits=(16, 2)) + air_max_adsorp_width = fields.Float('气吸托盘最大吸附宽度(mm)', digits=(16, 2)) + air_max_adsorp_height = fields.Float('气吸托盘最大吸附厚度(mm)', digits=(16, 2)) + air_max_adsorp_diameter = fields.Float('气吸托盘最大吸附直径(mm)', digits=(16, 2)) + air_max_adsorp_force = fields.Float('气吸托盘最大吸附力(N)', digits=(16, 2)) + + air_unlocking_method = fields.Selection( + [('手动', '手动'), ('气动', '气动'), ('液压', '液压'), ('电动', '电动'), ('其他', '其他')], + string='气吸托盘锁紧方式' + ) + air_flatness = fields.Char('气吸托盘平面精度(mm)', size=20) + air_max_load = fields.Float('气吸托盘最大负载(kg)', digits=(16, 2)) + air_boolean_chip_blowing_function = fields.Boolean('气吸托盘是否有吹屑功能') + air_way_to_install = fields.Selection( + [('接口式', '接口式'), ('螺栓固定', '螺栓固定'), ('磁吸式', '磁吸式'), ('其他', '其他')], + string='气吸托盘安装方式' + ) + @api.onchange('specification_fixture_id') def _onchange_specification_fixture_id(self): if self.specification_fixture_id: diff --git a/sf_mrs_connect/models/__init__.py b/sf_mrs_connect/models/__init__.py index 7038b520..01498b21 100644 --- a/sf_mrs_connect/models/__init__.py +++ b/sf_mrs_connect/models/__init__.py @@ -2,5 +2,3 @@ from . import ftp_operate from . import res_config_setting from . import sync_common from . import order_price -from . import redis_utils -from . import common \ No newline at end of file diff --git a/sf_mrs_connect/models/sync_common.py b/sf_mrs_connect/models/sync_common.py index d2b314de..3aad8090 100644 --- a/sf_mrs_connect/models/sync_common.py +++ b/sf_mrs_connect/models/sync_common.py @@ -1509,149 +1509,157 @@ class SyncMulti_Mounting_Type(models.Model): raise ValidationError("联装类型认证未通过") -# class SyncFixtureModel(models.Model): -# _inherit = 'sf.fixture.model' -# _description = '同步夹具型号列表' +class SyncFixtureModel(models.Model): + _inherit = 'sf.fixture.model' + _description = '同步夹具型号列表' -# url = '/api/fixture_model/list' + url = '/api/fixture_model/list' -# # 定时同步夹具型号列表 -# def sync_fixture_model_yesterday(self): -# config = self.env['res.config.settings'].get_values() -# headers = Common.get_headers(self, config['token'], config['sf_secret_key']) -# strUrl = config['sf_url'] + self.url -# r = requests.post(strUrl, json={}, data=None, headers=headers) -# r = r.json() -# result = json.loads(r['result']) -# if result['status'] == 1: -# if result.get('fixture_model_yesterday_list'): -# for item in result['fixture_model_yesterday_list']: -# if item: -# fixture_model = self.search([("code", '=', item['code']), ('active', 'in', [True, False])]) -# val = { -# "name": item['name'], -# "code": item['code'], -# "fixture_material_id": self.env['sf.fixture.material'].search( -# [('code', '=', item['fixture_material_code'])]).id, -# "multi_mounting_type_id": self.env['sf.multi_mounting.type'].search( -# [('code', '=', item['multi_mounting_type_code'])]).id, -# "brand_id": self.env['sf.machine.brand'].search([('code', '=', item['brand_code'])]).id, -# "model_file": '' if not item['model_file'] else base64.b64decode(item['model_file']), -# "status": item['status'], -# "active": item['active'], -# } -# if not fixture_model: -# self.create(val) -# else: -# fixture_model.write(val) + # 定时同步夹具型号列表 + def sync_fixture_model_yesterday(self): + config = self.env['res.config.settings'].get_values() + headers = Common.get_headers(self, config['token'], config['sf_secret_key']) + strUrl = config['sf_url'] + self.url + r = requests.post(strUrl, json={}, data=None, headers=headers) + r = r.json() + result = json.loads(r['result']) + if result['status'] == 1: + if result.get('fixture_model_yesterday_list'): + for item in result['fixture_model_yesterday_list']: + if item: + fixture_model = self.search([("code", '=', item['code']), ('active', 'in', [True, False])]) + val = { + "name": item['name'], + "code": item['code'], + "fixture_material_id": self.env['sf.fixture.material'].search( + [('code', '=', item['fixture_material_code'])]).id, + "multi_mounting_type_id": self.env['sf.multi_mounting.type'].search( + [('code', '=', item['multi_mounting_type_code'])]).id, + "brand_id": self.env['sf.machine.brand'].search([('code', '=', item['brand_code'])]).id, + "model_file": '' if not item['model_file'] else base64.b64decode(item['model_file']), + "status": item['status'], + "active": item['active'], + } + if not fixture_model: + self.create(val) + else: + fixture_model.write(val) -# else: -# raise ValidationError("夹具型号认证未通过") + else: + raise ValidationError("夹具型号认证未通过") -# # 定时同步所有夹具型号列表 -# def sync_all_fixture_model(self): -# config = self.env['res.config.settings'].get_values() -# headers = Common.get_headers(self, config['token'], config['sf_secret_key']) -# strUrl = config['sf_url'] + self.url -# r = requests.post(strUrl, json={}, data=None, headers=headers) -# r = r.json() -# result = json.loads(r['result']) -# # print('result:%s' % result) -# if result['status'] == 1: -# if result.get('fixture_model_all_list'): -# for item in result['fixture_model_all_list']: -# if item: -# fixture_model = self.search([('code', '=', item['code']), ('active', 'in', [True, False])]) -# val = { -# "name": item['name'], -# "code": item['code'], -# "fixture_material_id": self.env['sf.fixture.material'].search( -# [('code', '=', item['fixture_material_code'])]).id, -# "multi_mounting_type_id": self.env['sf.multi_mounting.type'].search( -# [('code', '=', item['multi_mounting_type_code'])]).id, -# "brand_id": self.env['sf.machine.brand'].search([('code', '=', item['brand_code'])]).id, -# "model_file": '' if not item['model_file'] else base64.b64decode(item['model_file']), -# "status": item['status'], -# "active": item['active'], -# } -# if not fixture_model: -# self.create(val) -# else: -# fixture_model.write(val) -# else: -# raise ValidationError("夹具型号认证未通过") + # 定时同步所有夹具型号列表 + def sync_all_fixture_model(self): + config = self.env['res.config.settings'].get_values() + headers = Common.get_headers(self, config['token'], config['sf_secret_key']) + strUrl = config['sf_url'] + self.url + r = requests.post(strUrl, json={}, data=None, headers=headers) + r = r.json() + result = json.loads(r['result']) + # print('result:%s' % result) + if result['status'] == 1: + if result.get('fixture_model_all_list'): + for item in result['fixture_model_all_list']: + if item: + fixture_model = self.search([('code', '=', item['code']), ('active', 'in', [True, False])]) + val = { + "name": item['name'], + "code": item['code'], + "fixture_material_id": self.env['sf.fixture.material'].search( + [('code', '=', item['fixture_material_code'])]).id, + "multi_mounting_type_id": self.env['sf.multi_mounting.type'].search( + [('code', '=', item['multi_mounting_type_code'])]).id, + "brand_id": self.env['sf.machine.brand'].search([('code', '=', item['brand_code'])]).id, + "model_file": '' if not item['model_file'] else base64.b64decode(item['model_file']), + "status": item['status'], + "active": item['active'], + } + if not fixture_model: + self.create(val) + else: + fixture_model.write(val) + else: + raise ValidationError("夹具型号认证未通过") -# class SyncfixtureMaterialsBasicParameters(models.Model): -# _inherit = 'sf.fixture.materials.basic.parameters' -# _description = '同步夹具型号基本参数列表' +class SyncfixtureMaterialsBasicParameters(models.Model): + _inherit = 'sf.fixture.materials.basic.parameters' + _description = '同步夹具型号基本参数列表' -# url = '/api/fixture_parameters/list' + url = '/api/fixture_parameters/list' -# # 定时同步夹具型号基本信息 -# def sync_fixture_materials_basic_parameters_yesterday(self): -# config = self.env['res.config.settings'].get_values() -# headers = Common.get_headers(self, config['token'], config['sf_secret_key']) -# strUrl = config['sf_url'] + self.url -# r = requests.post(strUrl, json={}, data=None, headers=headers) -# r = r.json() -# result = json.loads(r['result']) -# if result['status'] == 1: -# if result.get('fixture_parameters_yesterday_list'): -# all_list = result.get('fixture_parameters_yesterday_list') -# if all_list.get('zero_chuck_all_list'): -# self._write_or_create(all_list.get('zero_chuck_yesterday_list'), '零点卡盘') -# if all_list.get('zero_tray_all_list'): -# self._write_or_create(all_list.get('zero_tray_yesterday_list'), '零点托盘') -# if all_list.get('pneumatic_fixture_all_list'): -# self._write_or_create(all_list.get('pneumatic_fixture_yesterday_list'), '气动夹具') -# if all_list.get('jaw_vice_all_list'): -# self._write_or_create(all_list.get('jaw_vice_yesterday_list'), '虎钳夹具') -# if all_list.get('magnet_fixture_all_list'): -# self._write_or_create(all_list.get('magnet_fixture_yesterday_list'), '磁吸夹具') -# if all_list.get('adapter_board_all_list'): -# self._write_or_create(all_list.get('adapter_board_yesterday_list'), '转接板(锁板)夹具') -# if all_list.get('scroll_chuck_all_list'): -# self._write_or_create(all_list.get('scroll_chuck_yesterday_list'), '三爪卡盘') -# else: -# raise ValidationError("夹具型号基本参数认证未通过") + # 定时同步夹具型号基本信息 + def sync_fixture_materials_basic_parameters_yesterday(self): + config = self.env['res.config.settings'].get_values() + headers = Common.get_headers(self, config['token'], config['sf_secret_key']) + strUrl = config['sf_url'] + self.url + r = requests.post(strUrl, json={}, data=None, headers=headers) + r = r.json() + result = json.loads(r['result']) + if result['status'] == 1: + if result.get('fixture_parameters_yesterday_list'): + all_list = result.get('fixture_parameters_yesterday_list') + if all_list.get('zero_chuck_all_list'): + self._write_or_create(all_list.get('zero_chuck_yesterday_list'), '零点卡盘') + if all_list.get('zero_tray_all_list'): + self._write_or_create(all_list.get('zero_tray_yesterday_list'), '零点托盘') + if all_list.get('pneumatic_fixture_all_list'): + self._write_or_create(all_list.get('pneumatic_fixture_yesterday_list'), '气动夹具') + if all_list.get('jaw_vice_all_list'): + self._write_or_create(all_list.get('jaw_vice_yesterday_list'), '虎钳夹具') + if all_list.get('magnet_fixture_all_list'): + self._write_or_create(all_list.get('magnet_fixture_yesterday_list'), '磁吸夹具') + if all_list.get('adapter_board_all_list'): + self._write_or_create(all_list.get('adapter_board_yesterday_list'), '转接板(锁板)夹具') + if all_list.get('scroll_chuck_all_list'): + self._write_or_create(all_list.get('scroll_chuck_yesterday_list'), '三爪卡盘') + if all_list.get('air_blow_tray_all_list'): + self._write_or_create(all_list.get('air_tray_yesterday_list'), '气吸托盘') + if all_list.get('magnet_tray_all_list'): + self._write_or_create(all_list.get('magnet_tray_yesterday_list'), '磁吸托盘') + else: + raise ValidationError("夹具型号基本参数认证未通过") -# # 定时同步所有夹具型号基本信息 -# def sync_all_fixture_materials_basic_parameters(self): -# config = self.env['res.config.settings'].get_values() -# headers = Common.get_headers(self, config['token'], config['sf_secret_key']) -# strUrl = config['sf_url'] + self.url -# r = requests.post(strUrl, json={}, data=None, headers=headers) -# r = r.json() -# result = json.loads(r['result']) -# if result['status'] == 1: -# if result.get('fixture_parameters_all_list'): -# all_list = result.get('fixture_parameters_all_list') -# if all_list.get('zero_chuck_all_list'): -# self._write_or_create(all_list.get('zero_chuck_all_list'), '零点卡盘') -# if all_list.get('zero_tray_all_list'): -# self._write_or_create(all_list.get('zero_tray_all_list'), '零点托盘') -# if all_list.get('pneumatic_fixture_all_list'): -# self._write_or_create(all_list.get('pneumatic_fixture_all_list'), '气动夹具') -# if all_list.get('jaw_vice_all_list'): -# self._write_or_create(all_list.get('jaw_vice_all_list'), '虎钳夹具') -# if all_list.get('magnet_fixture_all_list'): -# self._write_or_create(all_list.get('magnet_fixture_all_list'), '磁吸夹具') -# if all_list.get('adapter_board_all_list'): -# self._write_or_create(all_list.get('adapter_board_all_list'), '转接板(锁板)夹具') -# if all_list.get('scroll_chuck_all_list'): -# self._write_or_create(all_list.get('scroll_chuck_all_list'), '三爪卡盘') -# else: -# raise ValidationError("夹具型号基本参数认证未通过") + # 定时同步所有夹具型号基本信息 + def sync_all_fixture_materials_basic_parameters(self): + config = self.env['res.config.settings'].get_values() + headers = Common.get_headers(self, config['token'], config['sf_secret_key']) + strUrl = config['sf_url'] + self.url + r = requests.post(strUrl, json={}, data=None, headers=headers) + r = r.json() + result = json.loads(r['result']) + if result['status'] == 1: + if result.get('fixture_parameters_all_list'): + all_list = result.get('fixture_parameters_all_list') + if all_list.get('zero_chuck_all_list'): + self._write_or_create(all_list.get('zero_chuck_all_list'), '零点卡盘') + if all_list.get('zero_tray_all_list'): + self._write_or_create(all_list.get('zero_tray_all_list'), '零点托盘') + if all_list.get('pneumatic_fixture_all_list'): + self._write_or_create(all_list.get('pneumatic_fixture_all_list'), '气动夹具') + if all_list.get('jaw_vice_all_list'): + self._write_or_create(all_list.get('jaw_vice_all_list'), '虎钳夹具') + if all_list.get('magnet_fixture_all_list'): + self._write_or_create(all_list.get('magnet_fixture_all_list'), '磁吸夹具') + if all_list.get('adapter_board_all_list'): + self._write_or_create(all_list.get('adapter_board_all_list'), '转接板(锁板)夹具') + if all_list.get('scroll_chuck_all_list'): + self._write_or_create(all_list.get('scroll_chuck_all_list'), '三爪卡盘') + if all_list.get('air_blow_tray_all_list'): + self._write_or_create(all_list.get('air_tray_all_list'), '气吸托盘') + if all_list.get('magnet_tray_all_list'): + self._write_or_create(all_list.get('magnet_tray_all_list'), '磁吸托盘') + else: + raise ValidationError("夹具型号基本参数认证未通过") -# def _write_or_create(self, fixture_parameters_list, material_name): -# for item in fixture_parameters_list: -# if item: -# basic_parameters = self.search([('code', '=', item.get('code')), ('active', 'in', [True, False])]) -# if not basic_parameters: -# self.create(self._get_basic_parameters_list(item, material_name)) -# else: -# basic_parameters.write(self._get_basic_parameters_list(item, material_name)) + def _write_or_create(self, fixture_parameters_list, material_name): + for item in fixture_parameters_list: + if item: + basic_parameters = self.search([('code', '=', item.get('code')), ('active', 'in', [True, False])]) + if not basic_parameters: + self.create(self._get_basic_parameters_list(item, material_name)) + else: + basic_parameters.write(self._get_basic_parameters_list(item, material_name)) class SyncFunctionalFixtureType(models.Model): @@ -3234,179 +3242,3 @@ class EmbryoRedundancySync(models.Model): "active": item['active'], "remark": item['remark'], }) - - - - - - -class SyncfixtureMaterialsBasicParameters(models.Model): - _inherit = 'sf.fixture.materials.basic.parameters' - _description = 'Redis 优先同步夹具基本参数' - - def sync_all_fixture_materials_basic_parameters(self): - # 你已有的批量同步方法不变 - rc = RedisClient() - key = 'mrs:fixture_param_all_list' - all_list = rc.get_json(key) - if not all_list: - config = self.env['res.config.settings'].get_values() - headers = Common.get_headers(config['token'], config['sf_secret_key']) - refresh_url = config['mrs_url'] + '/api/refresh_redis/fixture_param' - try: - res = requests.post(refresh_url, headers=headers, json={}, timeout=10) - res.raise_for_status() - except Exception as e: - raise ValidationError(f"Redis 无数据,MRS 缓存刷新失败: {str(e)}") - all_list = rc.get_json(key) - if not all_list: - raise ValidationError("Redis 刷新后仍无数据,无法同步夹具基本参数") - def _sync_list(param_list, material_name): - for item in param_list or []: - if not item or not item.get('code'): - continue - record = self.search([('code', '=', item['code'])], limit=1) - vals = self._get_basic_parameters_list(item, material_name) - if record: - record.write(vals) - else: - self.create(vals) - _sync_list(all_list.get('zero_chuck_all_list'), '零点卡盘') - _sync_list(all_list.get('zero_tray_all_list'), '零点托盘') - _sync_list(all_list.get('pneumatic_fixture_all_list'), '气动夹具') - _sync_list(all_list.get('jaw_vice_all_list'), '虎钳夹具') - _sync_list(all_list.get('magnet_fixture_all_list'), '磁吸夹具') - _sync_list(all_list.get('adapter_board_all_list'), '转接板(锁板)夹具') - _sync_list(all_list.get('scroll_chuck_all_list'), '三爪卡盘') - _sync_list(all_list.get('air_tray_all_list'), '气吹托盘') - _sync_list(all_list.get('magnet_tray_all_list'), '磁吸托盘') - - def sync_from_mrs(self, code): - rc = RedisClient() - key = 'mrs:fixture_param_all_list' - all_list = rc.get_json(key) or {} - if not all_list: - # Redis没数据,刷新一次 - config = self.env['res.config.settings'].get_values() - headers = Common.get_headers(config['token'], config['sf_secret_key']) - refresh_url = config['mrs_url'] + '/api/refresh_redis/fixture_param' - try: - res = requests.post(refresh_url, headers=headers, json={}, timeout=10) - res.raise_for_status() - except Exception as e: - raise ValidationError(f"Redis 无数据,MRS 缓存刷新失败: {str(e)}") - all_list = rc.get_json(key) or {} - if not all_list: - raise ValidationError("刷新后仍无 Redis 数据,无法同步夹具基本参数") - - # 遍历所有分类列表查找code匹配项 - for material_name, param_list in all_list.items(): - for item in param_list or []: - if item.get('code') == code: - vals = self._get_basic_parameters_list(item, material_name) - record = self.search([('code', '=', code)], limit=1) - if record: - record.write(vals) - else: - self.create(vals) - return True - return False - - def _get_basic_parameters_list(self, item, material_name): - # 请根据实际字段完善,这里给个示范 - return { - 'code': item.get('code'), - 'length': item.get('length'), - 'width': item.get('width'), - 'height': item.get('height'), - 'chucking_power_max': item.get('chucking_power_max'), - 'type_of_drive': item.get('type_of_drive'), - 'locking_method': item.get('locking_method'), - 'max_adsorp_force': item.get('max_adsorp_force'), - # 你可以加上 material_name 做记录或其它业务字段 - # 'material_name': material_name, - } - - -class SyncFixtureModel(models.Model): - _inherit = 'sf.fixture.model' - _description = 'Redis 优先同步夹具型号' - - def sync_all_fixture_model(self): - rc = RedisClient() - key = 'mrs:fixture_model_all_list' - all_list = rc.get_json(key) - if not all_list: - config = self.env['res.config.settings'].get_values() - headers = Common.get_headers(config['token'], config['sf_secret_key']) - refresh_url = config['mrs_url'] + '/api/refresh_redis/fixture_model' - try: - res = requests.post(refresh_url, headers=headers, json={}, timeout=10) - res.raise_for_status() - except Exception as e: - raise ValidationError(f"Redis 无数据,MRS 刷新失败: {str(e)}") - all_list = rc.get_json(key) - if not all_list: - raise ValidationError("刷新后仍无 Redis 数据,无法同步夹具型号") - - for item in all_list: - if not item or not item.get('code'): - continue - record = self.search([('code', '=', item['code'])], limit=1) - vals = { - 'name': item['name'], - 'code': item['code'], - 'fixture_material_id': self.env['sf.fixture.material'] - .search([('code', '=', item.get('fixture_material_code'))], limit=1).id or False, - 'multi_mounting_type_id': self.env['sf.multi_mounting.type'] - .search([('code', '=', item.get('multi_mounting_type_code'))], limit=1).id or False, - 'brand_id': self.env['sf.machine.brand'] - .search([('code', '=', item.get('brand_code'))], limit=1).id or False, - 'model_file': base64.b64decode(item['model_file']) if item.get('model_file') else False, - 'status': item['status'], - 'active': item['active'], - } - if record: - record.write(vals) - else: - self.create(vals) - - def sync_from_mrs(self, code): - rc = RedisClient() - key = 'mrs:fixture_model_all_list' - all_list = rc.get_json(key) or [] - if not all_list: - config = self.env['res.config.settings'].get_values() - headers = Common.get_headers(config['token'], config['sf_secret_key']) - refresh_url = config['mrs_url'] + '/api/refresh_redis/fixture_model' - try: - res = requests.post(refresh_url, headers=headers, json={}, timeout=10) - res.raise_for_status() - except Exception as e: - raise ValidationError(f"Redis 无数据,MRS 刷新失败: {str(e)}") - all_list = rc.get_json(key) or [] - if not all_list: - raise ValidationError("刷新后仍无 Redis 数据,无法同步夹具型号") - - for item in all_list: - if item.get('code') == code: - record = self.search([('code', '=', code)], limit=1) - vals = { - 'name': item['name'], - 'code': item['code'], - 'fixture_material_id': self.env['sf.fixture.material'] - .search([('code', '=', item.get('fixture_material_code'))], limit=1).id or False, - 'multi_mounting_type_id': self.env['sf.multi_mounting.type'] - .search([('code', '=', item.get('multi_mounting_type_code'))], limit=1).id or False, - 'brand_id': self.env['sf.machine.brand'] - .search([('code', '=', item.get('brand_code'))], limit=1).id or False, - 'model_file': base64.b64decode(item['model_file']) if item.get('model_file') else False, - 'status': item['status'], - 'active': item['active'], - } - if record: - record.write(vals) - else: - self.create(vals) - return True - return False From 4609ddfa7a15c6269943f1937cdd6d210ec21021 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E8=B5=93?= <1440513926@qq.com> Date: Fri, 18 Jul 2025 09:55:21 +0800 Subject: [PATCH 6/9] =?UTF-8?q?=E5=A4=B9=E5=85=B7=E5=9E=8B=E5=8F=B7?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E6=95=B0=E6=8D=AE=E8=A1=A8=E7=9A=84=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_base/models/fixture.py | 18 +++++++++--------- sf_mrs_connect/controllers/__init__.py | 2 -- sf_mrs_connect/models/sync_common.py | 2 -- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/sf_base/models/fixture.py b/sf_base/models/fixture.py index 82997a01..c344f978 100644 --- a/sf_base/models/fixture.py +++ b/sf_base/models/fixture.py @@ -36,23 +36,23 @@ class FixtureModel(models.Model): status = fields.Boolean('状态') active = fields.Boolean('有效', default=False) - zero_chuck_ids = fields.One2many('mrs.basic_parameters.zero.chuck', 'fixture_model_id', + zero_chuck_ids = fields.One2many('sf.fixture.materials.basic.parameters', 'fixture_model_id', string='零点卡盘基本参数') - zero_tray_ids = fields.One2many('mrs.basic_parameters.zero.tray', 'fixture_model_id', + zero_tray_ids = fields.One2many('sf.fixture.materials.basic.parameters', 'fixture_model_id', string='零点托盘基本参数') - pneumatic_fixture_ids = fields.One2many('mrs.basic_parameters.pneumatic.fixture', 'fixture_model_id', + pneumatic_fixture_ids = fields.One2many('sf.fixture.materials.basic.parameters', 'fixture_model_id', string='气动夹具基本参数') - jaw_vice_fixture_ids = fields.One2many('mrs.basic_parameters.jaw.vice.fixture', 'fixture_model_id', + jaw_vice_fixture_ids = fields.One2many('sf.fixture.materials.basic.parameters', 'fixture_model_id', string='虎钳夹具基本参数') - magnet_fixture_ids = fields.One2many('mrs.basic_parameters.magnet.fixture', 'fixture_model_id', + magnet_fixture_ids = fields.One2many('sf.fixture.materials.basic.parameters', 'fixture_model_id', string='磁吸夹具基本参数') - magnet_tray_ids = fields.One2many('mrs.basic_parameters.magnet.tray', 'fixture_model_id', + magnet_tray_ids = fields.One2many('sf.fixture.materials.basic.parameters', 'fixture_model_id', string='磁吸托盘基本参数') - adapter_board_fixture_ids = fields.One2many('mrs.basic_parameters.adapter.board.fixture', 'fixture_model_id', + adapter_board_fixture_ids = fields.One2many('sf.fixture.materials.basic.parameters', 'fixture_model_id', string='转接板(锁板)夹具基本参数') - scroll_chuck_ids = fields.One2many('mrs.basic_parameters.scroll.chuck', 'fixture_model_id', + scroll_chuck_ids = fields.One2many('sf.fixture.materials.basic.parameters', 'fixture_model_id', string='三爪卡盘基本参数') - air_tray_ids = fields.One2many('mrs.basic_parameters.air.tray', 'fixture_model_id', + air_tray_ids = fields.One2many('sf.fixture.materials.basic.parameters', 'fixture_model_id', string='气吸托盘基本参数') # def _get_code(self, fixture_model_type_code): diff --git a/sf_mrs_connect/controllers/__init__.py b/sf_mrs_connect/controllers/__init__.py index c57cd7f7..e046e49f 100644 --- a/sf_mrs_connect/controllers/__init__.py +++ b/sf_mrs_connect/controllers/__init__.py @@ -1,3 +1 @@ from . import controllers -from . import sync_controller -from . import refresh_controller \ No newline at end of file diff --git a/sf_mrs_connect/models/sync_common.py b/sf_mrs_connect/models/sync_common.py index 3aad8090..2dd8cfff 100644 --- a/sf_mrs_connect/models/sync_common.py +++ b/sf_mrs_connect/models/sync_common.py @@ -8,8 +8,6 @@ import requests from odoo import models from odoo.exceptions import ValidationError from odoo.addons.sf_base.commons.common import Common -from odoo.addons.sf_mrs_connect.models.common import Common - _logger = logging.getLogger(__name__) From a920d4b4b82f989400e9f34747868ed4b68d2477 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E8=B5=93?= <1440513926@qq.com> Date: Fri, 18 Jul 2025 09:58:44 +0800 Subject: [PATCH 7/9] =?UTF-8?q?=E5=A4=B9=E5=85=B7=E5=9E=8B=E5=8F=B7?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E6=95=B0=E6=8D=AE=E8=A1=A8=E7=9A=84=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_base/models/fixture.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sf_base/models/fixture.py b/sf_base/models/fixture.py index c344f978..777cf5cc 100644 --- a/sf_base/models/fixture.py +++ b/sf_base/models/fixture.py @@ -35,6 +35,7 @@ class FixtureModel(models.Model): glb_url = fields.Char(string="图片") status = fields.Boolean('状态') active = fields.Boolean('有效', default=False) + code = fields.Char(string='编码', readonly=True) zero_chuck_ids = fields.One2many('sf.fixture.materials.basic.parameters', 'fixture_model_id', string='零点卡盘基本参数') From 8434172fec94beb5965b013283a393e55c1e7e21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E8=B5=93?= <1440513926@qq.com> Date: Fri, 18 Jul 2025 11:10:50 +0800 Subject: [PATCH 8/9] =?UTF-8?q?=E5=A4=B9=E5=85=B7=E5=9E=8B=E5=8F=B7?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E6=95=B0=E6=8D=AE=E8=A1=A8=E7=9A=84=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product_template_management_view.xml | 64 +++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/sf_dlm_management/views/product_template_management_view.xml b/sf_dlm_management/views/product_template_management_view.xml index eac5ecbf..530ab7c1 100644 --- a/sf_dlm_management/views/product_template_management_view.xml +++ b/sf_dlm_management/views/product_template_management_view.xml @@ -524,12 +524,12 @@ + attrs="{'invisible': [('fixture_material_type', 'not in', ['零点卡盘', '零点托盘', '三爪卡盘', '磁吸托盘', '气吸托盘'])]}"/> + attrs="{'invisible': [('fixture_material_type', 'not in', ['磁吸夹具'])]}"/> @@ -579,7 +579,7 @@ + attrs="{'invisible': [('fixture_material_type', 'not in', ['零点托盘','气吸托盘', '磁吸托盘'])]}"/> @@ -597,70 +597,70 @@ + attrs="{'invisible': [('fixture_material_type', 'not in', ['磁吸托盘'])]}"/> + attrs="{'invisible': [('fixture_material_type', 'not in', ['磁吸托盘'])]}"/> + attrs="{'invisible': [('fixture_material_type', 'not in', ['磁吸托盘'])]}"/> + attrs="{'invisible': [('fixture_material_type', 'not in', ['磁吸托盘'])]}"/> + attrs="{'invisible': [('fixture_material_type', 'not in', ['磁吸托盘'])]}"/> + attrs="{'invisible': [('fixture_material_type', 'not in', ['磁吸托盘'])]}"/> + attrs="{'invisible': [('fixture_material_type', 'not in', ['磁吸托盘'])]}"/> + attrs="{'invisible': [('fixture_material_type', 'not in', ['磁吸托盘'])]}"/> + attrs="{'invisible': [('fixture_material_type', 'not in', ['磁吸托盘'])]}"/> + attrs="{'invisible': [('fixture_material_type', 'not in', ['磁吸托盘'])]}"/> + attrs="{'invisible': [('fixture_material_type', 'not in', ['磁吸托盘'])]}"/> + attrs="{'invisible': [('fixture_material_type', 'not in', ['磁吸托盘'])]}"/> + attrs="{'invisible': [('fixture_material_type', 'not in', ['磁吸托盘'])]}"/> + attrs="{'invisible': [('fixture_material_type', 'not in', ['气吸托盘'])]}"/> + attrs="{'invisible': [('fixture_material_type', 'not in', ['气吸托盘'])]}"/> + attrs="{'invisible': [('fixture_material_type', 'not in', ['气吸托盘'])]}"/> + attrs="{'invisible': [('fixture_material_type', 'not in', ['气吸托盘'])]}"/> + attrs="{'invisible': [('fixture_material_type', 'not in', ['气吸托盘'])]}"/> + attrs="{'invisible': [('fixture_material_type', 'not in', ['气吸托盘'])]}"/> + attrs="{'invisible': [('fixture_material_type', 'not in', ['气吸托盘'])]}"/> + attrs="{'invisible': [('fixture_material_type', 'not in', ['气吸托盘'])]}"/> + attrs="{'invisible': [('fixture_material_type', 'not in', ['气吸托盘'])]}"/> + attrs="{'invisible': [('fixture_material_type', 'not in', ['气吸托盘'])]}"/> + attrs="{'invisible': [('fixture_material_type', 'not in', ['气吸托盘'])]}"/> + attrs="{'invisible': [('fixture_material_type', 'not in', ['气吸托盘'])]}"/> + attrs="{'invisible': [('fixture_material_type', 'not in', ['气吸托盘'])]}"/> + attrs="{'invisible': [('fixture_material_type', 'not in', ['气吸托盘'])]}"/> + attrs="{'invisible': [('fixture_material_type', 'not in', ['气吸托盘'])]}"/> + attrs="{'invisible': [('fixture_material_type', 'not in', ['零点卡盘','零点托盘','气吸托盘', '磁吸托盘'])]}"/> Date: Fri, 18 Jul 2025 14:24:33 +0800 Subject: [PATCH 9/9] =?UTF-8?q?=E5=A4=B9=E5=85=B7=E5=9E=8B=E5=8F=B7?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E6=95=B0=E6=8D=AE=E8=A1=A8=E7=9A=84=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../views/product_template_management_view.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sf_dlm_management/views/product_template_management_view.xml b/sf_dlm_management/views/product_template_management_view.xml index 530ab7c1..4940b410 100644 --- a/sf_dlm_management/views/product_template_management_view.xml +++ b/sf_dlm_management/views/product_template_management_view.xml @@ -579,7 +579,7 @@ + attrs="{'invisible': [('fixture_material_type', 'not in', ['零点托盘','气吸托盘'])]}"/> @@ -660,7 +660,7 @@ attrs="{'invisible': [('fixture_material_type', 'not in', ['气吸托盘'])]}"/> + attrs="{'invisible': [('fixture_material_type', 'not in', ['零点卡盘','零点托盘','气吸托盘'])]}"/> + attrs="{'invisible': [('fixture_material_type', 'not in', ['零点卡盘','气吸托盘', '磁吸托盘'])]}"/>