diff --git a/src/apps/doc/models.py b/src/apps/doc/models.py index c9fd2de..e3a0fc8 100644 --- a/src/apps/doc/models.py +++ b/src/apps/doc/models.py @@ -978,3 +978,22 @@ class GenericOCRReport(models.Model): class Meta: managed = False db_table = 'generic_ocr_report' + + +class InterfaceReport(models.Model): + id = models.AutoField(primary_key=True, verbose_name="id") # 主键 + + source = models.CharField(max_length=64, verbose_name="来源") + target = models.CharField(max_length=64, verbose_name="目标") + + body = models.TextField(null=True, verbose_name="请求体") + response = models.TextField(null=True, verbose_name="响应") + + status = models.BooleanField(default=True, verbose_name="是否成功") + retry_times = models.SmallIntegerField(default=0, verbose_name="重试次数") + duration = models.IntegerField(verbose_name='处理时长') + create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') + + class Meta: + managed = False + db_table = 'interface_report' diff --git a/src/apps/doc/named_enum.py b/src/apps/doc/named_enum.py index 6834f67..9623ad7 100644 --- a/src/apps/doc/named_enum.py +++ b/src/apps/doc/named_enum.py @@ -95,3 +95,14 @@ class BSCheckResult(NamedEnum): class OfflineFailureReason(NamedEnum): OS_ERROR = (0, 'OS_ERROR') PROCESS_ERROR = (1, 'PROCESS_ERROR') + + +class SystemName(NamedEnum): + POS = (0, 'POS') + EAPP = (1, 'EAPP') + ECONTRACT = (2, 'ECONTRACT') + GCAP = (3, 'GCAP') + CMS = (4, 'CMS') + MPOS = (5, 'MPOS') + UNKNOWN = (6, 'Unknown') + OCR = (7, 'OCR') diff --git a/src/apps/doc/views.py b/src/apps/doc/views.py index e0c865a..9a2f409 100644 --- a/src/apps/doc/views.py +++ b/src/apps/doc/views.py @@ -47,8 +47,9 @@ from .models import ( AFCbankVerification, MposReport, GenericOCRReport, + InterfaceReport, ) -from .named_enum import ErrorType, AutoResult, WholeResult, RPAResult +from .named_enum import ErrorType, AutoResult, WholeResult, RPAResult, SystemName from .mixins import DocHandler, MPOSHandler, PreSEHandler from . import consts from apps.account.authentication import OAuth2AuthenticationWithUser @@ -551,7 +552,9 @@ class UploadDocView(GenericView, DocHandler): # 上传(接收)文件接口 @use_args(doc_upload_args, location='data') - def post(self, request, args): + def post(self, request, args): # interface_report pos/eapp/econtract to ocr + start_time = time.time() + application_data = args.get('applicationData') # applicant_data = args.get('applicantData') document = args.get('document') @@ -560,37 +563,9 @@ class UploadDocView(GenericView, DocHandler): document_scheme = document.get('documentScheme') data_source = document.get('dataSource') document_name = document.get('documentName', '') - # main_name = self.get_name(applicant_data, 'mainApplicantName', 16) - # co_name = self.get_name(applicant_data, 'coApplicantName', 16) - # g1_name = self.get_name(applicant_data, 'guarantor1Name', 16) - # g2_name = self.get_name(applicant_data, 'guarantor2Name', 16) - - # try: - # # 1. 上传信息记录 - # UploadDocRecords.objects.create( - # metadata_version_id=document.get('metadataVersionId'), - # application_id=application_id, - # main_applicant='main_name', - # co_applicant='co_name', - # guarantor_1='g1_name', - # guarantor_2='g2_name', - # document_name=document_name, - # document_scheme=document_scheme, - # business_type=business_type, - # data_source=data_source, - # upload_finish_time=document.get('uploadFinishTime'), - # ) - # except Exception as e: - # self.running_log.info('[doc upload success] [same file skip] [args={0}]'.format(args)) - # # self.invalid_params(msg='metadataVersionId repeat') - # return response.ok() data_source = self.fix_data_source(data_source) document_scheme = self.fix_scheme(document_scheme) - - # if document_name.endswith('.zip'): - # self.running_log.info('[doc upload success] [zip file skip] [args={0}]'.format(args)) - # return response.ok() if data_source == consts.DATA_SOURCE_LIST[1]: if document_name.endswith('-证书.pdf') or document_name.endswith('-证书'): @@ -602,10 +577,6 @@ class UploadDocView(GenericView, DocHandler): doc = doc_class.objects.create( metadata_version_id=document.get('metadataVersionId'), application_id=application_id, - # main_applicant=applicant_data.get('mainApplicantName'), - # co_applicant=applicant_data.get('coApplicantName'), - # guarantor_1=applicant_data.get('guarantor1Name'), - # guarantor_2=applicant_data.get('guarantor2Name'), document_name=document_name, document_scheme=document_scheme, data_source=data_source, @@ -632,6 +603,22 @@ class UploadDocView(GenericView, DocHandler): self.running_log.info('[doc upload success] [args={0}] [business_type={1}] [doc_id={2}] ' '[is_priority={3}] [enqueue_res={4}]'.format(args, prefix, doc.id, is_priority, enqueue_res)) + + try: + end_time = time.time() + duration_second = int(end_time - start_time) + InterfaceReport.objects.create( + source=data_source, + target=SystemName.OCR.name, + body=json.dumps(args), + response=None, + status=True, + # retry_times=None, + duration=duration_second, + ) + except Exception as e: + self.exception_log.exception('[upload view] [db save failed] [error={0}]'.format(traceback.format_exc())) + return response.ok() post.openapi_doc = ''' @@ -660,7 +647,9 @@ class PriorityDocView(GenericView, DocHandler): # 优先级订单接口 @use_args(priority_doc_args, location='data') - def post(self, request, args): + def post(self, request, args): # interface_report gcap to ocr + start_time = time.time() + application_info = args.get('APPLICATION_INFORMATION') application_id = application_info.get('APPLICATION_ID') submit_datetime = application_info.get('SUBMIT_DATETIME') @@ -696,6 +685,22 @@ class PriorityDocView(GenericView, DocHandler): enqueue_res = rh.enqueue(tasks_list, is_priority=True) # TODO 可能把压缩文件放入优先队列 self.running_log.info('[priority doc success] [args={0}] [tasks_list={1}] [enqueue_res={2}]'.format( args, tasks_list, enqueue_res)) + + try: + end_time = time.time() + duration_second = int(end_time - start_time) + InterfaceReport.objects.create( + source=SystemName.GCAP.name, + target=SystemName.OCR.name, + body=json.dumps(args), + response=None, + status=True, + # retry_times=None, + duration=duration_second, + ) + except Exception as e: + self.exception_log.exception('[gcap view] [db save failed] [error={0}]'.format(traceback.format_exc())) + return response.ok() post.openapi_doc = ''' @@ -724,7 +729,9 @@ class CompareView(GenericView): # pos上传比对信息接口 CA @use_args(compare_args, location='data') - def post(self, request, args): + def post(self, request, args): # interface_report pos to ocr + start_time = time.time() + # 存库 content = args.get('content', {}) uniq_seq = content.get('uniqSeq') @@ -748,6 +755,22 @@ class CompareView(GenericView): # 触发比对 compare.apply_async((application_id, business_type, uniq_seq, None, True, False), queue='queue_compare') + + try: + end_time = time.time() + duration_second = int(end_time - start_time) + InterfaceReport.objects.create( + source=SystemName.POS.name, + target=SystemName.OCR.name, + body=json.dumps(args), + response=None, + status=True, + # retry_times=None, + duration=duration_second, + ) + except Exception as e: + self.exception_log.exception('[pos ca view] [db save failed] [error={0}]'.format(traceback.format_exc())) + return response.ok() post.openapi_doc = ''' @@ -776,9 +799,10 @@ class SECompareView(GenericView, PreSEHandler): # SE preSettlement @use_args(se_compare_args, location='data') - def post(self, request, args): + def post(self, request, args): # interface_report pos to ocr + start_time = time.time() log_base = '[prese]' - + # 存库 content = args.get('content', {}) business_type = content.get('applicationEntity') application_id = content.get('applicationId') @@ -810,6 +834,21 @@ class SECompareView(GenericView, PreSEHandler): self.running_log.info('{0} [prese completed] [applicationEntity={1}] [application_id={2}] [uniq_seq={3}] ' '[result={4}]'.format(log_base, business_type, application_id, uniq_seq, compare_result)) + try: + end_time = time.time() + duration_second = int(end_time - start_time) + InterfaceReport.objects.create( + source=SystemName.POS.name, + target=SystemName.OCR.name, + body=json.dumps(args), + response=json.dumps(compare_result), + status=True, + # retry_times=None, + duration=duration_second, + ) + except Exception as e: + self.exception_log.exception('[pos pre view] [db save failed] [error={0}]'.format(traceback.format_exc())) + return response.ok(data=compare_result) post.openapi_doc = ''' @@ -1263,7 +1302,9 @@ class SECMSView(GenericView): # CMS上传比对信息接口 SE # @use_args(se_cms_args, location='data') - def post(self, request): + def post(self, request): # interface_report cms to ocr + start_time = time.time() + args = request.data cms_info = args.get('content', {}) business_type = consts.AFC_PREFIX if cms_info.get('financeCompany', '').startswith('宝马') else consts.HIL_PREFIX @@ -1305,6 +1346,21 @@ class SECMSView(GenericView): compare.apply_async((application_id, business_type, None, None, False, True), queue='queue_compare') + try: + end_time = time.time() + duration_second = int(end_time - start_time) + InterfaceReport.objects.create( + source=SystemName.CMS.name, + target=SystemName.OCR.name, + body=json.dumps(args), + response=None, + status=True, + # retry_times=None, + duration=duration_second, + ) + except Exception as e: + self.exception_log.exception('[cms view] [db save failed] [error={0}]'.format(traceback.format_exc())) + return response.ok() post.openapi_doc = ''' @@ -1497,7 +1553,7 @@ class MPOSView(GenericView, MPOSHandler): # MPOS @use_args(mpos_args, location='data') - def post(self, request, args): + def post(self, request, args): # interface_report mpos to ocr start_time = time.time() classify = args.get('type') @@ -1530,6 +1586,19 @@ class MPOSView(GenericView, MPOSHandler): except Exception as e: self.exception_log.exception('[mpos view] [db save failed] [error={0}]'.format(traceback.format_exc())) + try: + InterfaceReport.objects.create( + source=SystemName.MPOS.name, + target=SystemName.OCR.name, + body=None, + response=json.dumps(result_list), + status=True, + # retry_times=None, + duration=duration_second, + ) + except Exception as e: + self.exception_log.exception('[go view] [db save failed] [error={0}]'.format(traceback.format_exc())) + return response.ok(data=result_list) @@ -1538,7 +1607,7 @@ class GoView(GenericView): authentication_classes = [OAuth2AuthenticationWithUser] @use_args(go_args, location='files') - def post(self, request, args): + def post(self, request, args): # interface_report unknown to ocr result = None is_success = False start_time = time.time() @@ -1566,6 +1635,19 @@ class GoView(GenericView): except Exception as e: self.exception_log.exception('[go view] [db save failed] [error={0}]'.format(traceback.format_exc())) + try: + InterfaceReport.objects.create( + source=SystemName.UNKNOWN.name, + target=SystemName.OCR.name, + body=None, + response=json.dumps(result) if is_success else None, + status=is_success, + # retry_times=None, + duration=duration_second, + ) + except Exception as e: + self.exception_log.exception('[go view] [db save failed] [error={0}]'.format(traceback.format_exc())) + if is_success: return response.ok(data=result) else: diff --git a/src/celery_compare/tasks.py b/src/celery_compare/tasks.py index 8be38a5..504e8bf 100644 --- a/src/celery_compare/tasks.py +++ b/src/celery_compare/tasks.py @@ -31,12 +31,13 @@ from apps.doc.models import ( AFCAutoSettlement, HILbankVerification, AFCbankVerification, + InterfaceReport, ) from apps.doc import consts from apps.doc.ocr.gcap import gcap from apps.doc.ocr.cms import cms from apps.doc.exceptions import GCAPException -from apps.doc.named_enum import RequestTeam, RequestTrigger, ProcessName, ErrorType +from apps.doc.named_enum import RequestTeam, RequestTrigger, ProcessName, ErrorType, SystemName from common.tools.comparison import cp from common.tools.des import decode_des @@ -748,16 +749,20 @@ def ca_compare(application_id, application_entity, ocr_res_id, last_obj, ocr_res time.sleep(5) # 将比对结果发送GCAP + start_time = time.time() try: data = gcap.dict_to_xml(comparison_res) except Exception as e: compare_log.error('{0} [CA] [dict to xml failed] [entity={1}] [id={2}] [ocr_res_id={3}] [error={4}]'.format( log_base, application_entity, application_id, ocr_res_id, traceback.format_exc())) else: + final_times = 0 + is_success = True try: for times in range(consts.RETRY_TIMES): + final_times = times try: - res_text = gcap.send(data) + res_text = gcap.send(data) # interface_report ocr to gcap except Exception as e: gcap_exc = str(e) else: @@ -765,6 +770,7 @@ def ca_compare(application_id, application_entity, ocr_res_id, last_obj, ocr_res else: raise GCAPException(gcap_exc) except Exception as e: + is_success = False compare_log.error('{0} [CA] [gcap failed] [entity={1}] [id={2}] [ocr_res_id={3}] [error={4}]'.format( log_base, application_entity, application_id, ocr_res_id, traceback.format_exc())) else: @@ -772,6 +778,21 @@ def ca_compare(application_id, application_entity, ocr_res_id, last_obj, ocr_res log_base, application_entity, application_id, ocr_res_id, res_text)) compare_log.info('{0} [CA] [task success] [entity={1}] [id={2}] [ocr_res_id={3}]'.format( log_base, application_entity, application_id, ocr_res_id)) + finally: + end_time = time.time() + duration_second = int(end_time - start_time) + try: + InterfaceReport.objects.create( + source=SystemName.OCR.name, + target=SystemName.GCAP.name, + body=data, + response=res_text if is_success else None, + status=is_success, + retry_times=final_times, + duration=duration_second, + ) + except Exception as e: + compare_log.error('{0} [CA] [db save failed] [error={1}]'.format(log_base, traceback.format_exc())) # report try: @@ -3087,24 +3108,28 @@ def se_compare(application_id, application_entity, ocr_res_id, last_obj, ocr_res compare_log.info('{0} [SE] [cms closed] [entity={1}] [id={2}] [ocr_res_id={3}]'.format( log_base, application_entity, application_id, ocr_res_id)) return successful_at_this_level - try: - application_link = '{0}/showList/showList?entity={1}&scheme={2}&case_id={3}'.format( - conf.BASE_URL, application_entity, consts.COMPARE_DOC_SCHEME_LIST[1], application_id) - data = { - "SubtenantId": consts.TENANT_MAP[application_entity], - "Data": { - "Result_Message": "Pass" if successful_at_this_level else "Fail", - "AutoCheckResult": "Pass" if auto_result else "Fail", - "Failure_Reason": cn_failure_reason_str, - "Application_Number": application_id, - "Bank_Statement": bs_failure_reason_str, - "Link_URL": application_link, - "OCR_Version": 1, - "Origin": consts.INFO_SOURCE[1] - } + + is_success = True + start_time = time.time() + application_link = '{0}/showList/showList?entity={1}&scheme={2}&case_id={3}'.format( + conf.BASE_URL, application_entity, consts.COMPARE_DOC_SCHEME_LIST[1], application_id) + data = { + "SubtenantId": consts.TENANT_MAP[application_entity], + "Data": { + "Result_Message": "Pass" if successful_at_this_level else "Fail", + "AutoCheckResult": "Pass" if auto_result else "Fail", + "Failure_Reason": cn_failure_reason_str, + "Application_Number": application_id, + "Bank_Statement": bs_failure_reason_str, + "Link_URL": application_link, + "OCR_Version": 1, + "Origin": consts.INFO_SOURCE[1] } - response = cms.send(data) + } + try: + response = cms.send(data) # interface_report ocr to cms except Exception as e: + is_success = False compare_log.error('{0} [SE] [cms error] [entity={1}] [id={2}] [ocr_res_id={3}] ' '[error={4}]'.format(log_base, application_entity, application_id, ocr_res_id, traceback.format_exc())) @@ -3112,6 +3137,21 @@ def se_compare(application_id, application_entity, ocr_res_id, last_obj, ocr_res compare_log.info('{0} [SE] [cms success] [entity={1}] [id={2}] [ocr_res_id={3}] [data={4}] ' '[response={5}]'.format(log_base, application_entity, application_id, ocr_res_id, data, response)) + finally: + end_time = time.time() + duration_second = int(end_time - start_time) + try: + InterfaceReport.objects.create( + source=SystemName.OCR.name, + target=SystemName.CMS.name, + body=json.dumps(data), + response=json.dumps(response) if is_success else None, + status=is_success, + # retry_times=None, + duration=duration_second, + ) + except Exception as e: + compare_log.error('{0} [SE] [db save failed] [error={1}]'.format(log_base, traceback.format_exc())) return successful_at_this_level diff --git a/src/common/tools/mssql_script21.py b/src/common/tools/mssql_script21.py new file mode 100644 index 0000000..94479bf --- /dev/null +++ b/src/common/tools/mssql_script21.py @@ -0,0 +1,36 @@ +import pyodbc + +hil_sql = """ + create table interface_report + ( + id bigint identity primary key, + source nvarchar(64) not null, + target nvarchar(64) not null, + body nvarchar(max), + response nvarchar(max), + status bit default 1 not null, + retry_times tinyint default 0 not null, + duration smallint not null, + create_time datetime not null + ); +""" + +afc_sql = """ + +""" + +hil_cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};', autocommit=True) + +hil_cursor = hil_cnxn.cursor() +hil_cursor.execute(hil_sql) + +hil_cursor.close() +hil_cnxn.close() + +afc_cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};', autocommit=True) + +afc_cursor = afc_cnxn.cursor() +afc_cursor.execute(afc_sql) + +afc_cursor.close() +afc_cnxn.close()