03fecf38 by 周伟奇

cms

1 parent 61b268cd
......@@ -1626,4 +1626,60 @@ CA_COMPARE_FIELD = {
DL_EN: (DL_OCR_FIELD, CA_DL_COMPARE_LOGIC, False),
}
# ------------------CMS--------------------------------------
BANK_INFO_MAP = (
('accountNo', 'bankAccountDetails.accountNo'),
('bankName', 'bankAccountDetails.bankName'),
('accountHolderName', 'bankAccountDetails.accountHolderName'),
)
VEHICLE_INFO_MAP = (
('vehicleStatus', 'vehicleStatus'),
('vinNo', 'vehicleInformation.vinNo'),
('dealer', 'dealerName'),
('vehicleTransactionAmount', 'totalFinanceAmount'),
)
CORPORATE_INFO_MAP = (
('firstIdType', ),
('firstIdNo', ),
('companyName', ),
('legalRepName', ),
('businessLicenseNo', ),
('organizationCreditCode', ),
('taxRegistrationCertificateNo', ),
('establishmentDate', ),
('businessLicenseDueDate', ),
)
INDIVIDUAL_INFO_MAP = (
('applicantType', 'applicantInformation.applicantType'),
('customerType', 'applicantInformation.customersubType'),
('idType', 'applicantInformation.IDInformation.idType'),
('customerName', 'applicantInformation.name'),
('idNum', 'applicantInformation.IDInformation.idNum'),
('dateOfBirth', 'applicantInformation.dateOfBirth'),
('idExpiryDate', 'applicantInformation.IDInformation.idExpiryDate'),
('hukouProvince', ),
('hukouCity', ),
('secondIdType', 'applicantInformation.IDInformation.idType'),
('secondIdNum', 'applicantInformation.IDInformation.idNum'),
('companyName', ),
('registeredCapital', ),
('selfEmployedSubType', ),
)
CMS_TO_POS = [
('bank_info', BANK_INFO_MAP),
('vehicle_info', VEHICLE_INFO_MAP),
('corporate_cus_info', CORPORATE_INFO_MAP),
('individual_cus_info', INDIVIDUAL_INFO_MAP),
]
TENANT_MAP = {
AFC_PREFIX: 1,
HIL_PREFIX: 2,
}
\ No newline at end of file
......
......@@ -13,9 +13,14 @@ class OCR2Exception(Exception):
class OCR4Exception(Exception):
pass
class LTGTException(Exception):
pass
class GCAPException(Exception):
pass
class CMSException(Exception):
pass
......
import requests
from settings import conf
from common.redis_cache import redis_handler as rh
from apps.doc.exceptions import CMSException
class CMS:
def __init__(self):
self.oauth_url = conf.CMS_OAUTH_URL
self.url = conf.CMS_URL
self.oauth_payload = {
'grant_type': 'client_credentials',
'client_id': conf.CMS_OAUTH_ID,
'client_secret': conf.CMS_OAUTH_SECRET,
'scope': conf.CMS_OAUTH_SCOPE
}
self.token_type = 'bearer'
self.token = None
self.token_key = 'access_token'
self.expires_key = 'expires_in'
self.token_type_key = 'token_type'
def update_token(self):
response = requests.post(self.oauth_url, data=self.oauth_payload, files=[])
if response.status_code != 200:
raise CMSException('CMS Oauth response with code: {0}'.format(response.status_code))
token = response.json().get(self.token_key)
if not isinstance(token, str):
raise CMSException('CMS Oauth can not get token: {0}'.format(response.json()))
self.token = token
self.token_type = response.json().get(self.token_type_key, self.token_type)
expires = response.json().get(self.expires_key, 3600)
rh.set_cms_token(self.token, expires)
def get_token(self):
if self.token is None:
self.token = rh.get_cms_token()
if self.token is None:
self.update_token()
return self.token
def send(self, payload):
token = self.get_token()
headers = {
'Authorization': '{0} {1}'.format(self.token_type.capitalize(), token),
'Content-Type': 'application/json',
}
response = requests.post(self.url, headers=headers, json=payload)
if response.status_code != 200:
raise CMSException('CMS Oauth response with code: {0}'.format(response.status_code))
return response.json()
cms = CMS()
......@@ -1092,6 +1092,7 @@ class SECMSView(GenericView):
@use_args(se_cms_args, location='data')
def post(self, request, args):
# 触发比对
compare.apply_async((application_id, business_type, uniq_seq, None, False, True),
queue='queue_compare')
......
......@@ -25,6 +25,7 @@ from apps.doc.models import (
)
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 common.tools.comparison import cp
......@@ -35,6 +36,27 @@ empty_str = ''
empty_error_type = 1000
class FakePOS:
def __init__(self,
application_id,
first_submmison_date,
application_version,
customer_type,
individual_cus_info,
corporate_cus_info,
vehicle_info,
bank_info):
self.application_id = application_id
self.first_submmison_date = first_submmison_date
self.application_version = application_version
self.customer_type = customer_type
self.individual_cus_info = individual_cus_info
self.corporate_cus_info = corporate_cus_info
self.vehicle_info = vehicle_info
self.bank_info = bank_info
def name_check(ocr_res_dict, second_ocr_field, second_compare_list, second_id_num, name):
id_field = second_compare_list[1][1]
name_field = second_compare_list[0][1]
......@@ -881,7 +903,7 @@ def get_se_compare_info(last_obj, application_entity, detect_list):
return compare_info, is_gsyh
def cms_get_se_compare_info(last_obj, application_entity, detect_list):
def rebuild_compare_info(last_obj):
# {
# "content": {
# "financeCompany": "宝马汽车金融有限公司",
......@@ -982,7 +1004,15 @@ def cms_get_se_compare_info(last_obj, application_entity, detect_list):
# }
# }
# }
pass
return FakePOS(application_id,
first_submmison_date,
application_version,
customer_type,
individual_cus_info,
corporate_cus_info,
vehicle_info,
bank_info)
def se_compare_license(license_en, ocr_res_dict, field_list):
......@@ -1205,9 +1235,8 @@ def se_compare(application_id, application_entity, ocr_res_id, last_obj, ocr_res
start_time = datetime.now()
detect_list = se_result_detect(ocr_res_dict)
if is_cms:
compare_info, is_gsyh = cms_get_se_compare_info(last_obj, application_entity, detect_list)
else:
compare_info, is_gsyh = get_se_compare_info(last_obj, application_entity, detect_list)
last_obj = rebuild_compare_info(last_obj)
compare_info, is_gsyh = get_se_compare_info(last_obj, application_entity, detect_list)
compare_result, total_fields, failed_count, successful_at_this_level, failure_reason_str = se_compare_process(
compare_info, ocr_res_dict, is_gsyh)
compare_log.info('{0} [SE] [compare success] [entity={1}] [id={2}] [ocr_res_id={3}] [result={4}]'.format(
......@@ -1264,7 +1293,30 @@ def se_compare(application_id, application_entity, ocr_res_id, last_obj, ocr_res
traceback.format_exc()))
# cms结果发送
if is_cms:
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",
"Failure_Reason": failure_reason_str,
"Application_Number": application_id,
"Bank_Statement": "",
"Link_URL": application_link,
"OCR_Version": 1,
"Origin": consts.INFO_SOURCE[1]
}
}
response = cms.send(data)
except Exception as e:
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()))
else:
compare_log.info('{0} [SE] [cms success] [entity={1}] [id={2}] [ocr_res_id={3}] [response={4}]'.format(
log_base, application_entity, application_id, ocr_res_id, response))
@app.task
def compare(application_id, application_entity, uniq_seq, ocr_res_id, is_ca=True, is_cms=False):
......
......@@ -36,6 +36,7 @@ class RedisHandler:
self.common_queue_key = '{0}:common_queue'.format(self.prefix)
self.priority_queue_key = '{0}:priority_queue'.format(self.prefix)
self.session_id_key = '{0}:session_id'.format(self.prefix)
self.cms_token_key = '{0}:cms_token'.format(self.prefix)
def enqueue(self, tasks, is_priority=False):
# 1
......@@ -57,3 +58,9 @@ class RedisHandler:
def get_session_id(self):
return self.redis.get(self.session_id_key)
def get_cms_token(self):
return self.redis.get(self.cms_token_key)
def set_cms_token(self, token, expires=None):
return self.redis.set(self.cms_token_key, token, expires)
......
from Crypto.Cipher import DES3
from Crypto.Hash import MD5
import struct
import base64
import codecs
def mds_hash(target_str):
h = MD5.new()
h.update(target_str.encode('utf-8'))
return h.digest()
def des_pad(data):
data = data.encode('utf-8')
e = len(data)
x = (e + 4) % 8
y = 0 if x == 0 else 8 - x
size_byte = struct.pack('>I', e)
result_byte = list(range(len(size_byte) + e + y))
result_byte[0:4] = size_byte
result_byte[4:4 + e] = data
for i in range(0, y):
result_byte[e + 4 + i] = 0
result_str = bytearray(result_byte).decode('utf-8')
return result_str
# DES3加密数据
def encode_des(to_encode_str, des_key):
"""
DES3加密数据
Args:
to_encode_str(str): 要被加密的原字符串,这里的字符串需要被des_pad一下
des_key(str): 加密的key
Returns:
"""
key = mds_hash(des_key)
des3 = DES3.new(key, DES3.MODE_ECB)
data = des3.encrypt(des_pad(to_encode_str))
data = codecs.encode(data, 'hex')
return data
def un_des_pad(data):
result_byte = data[0:4]
e = struct.unpack('>I', result_byte)[0]
x = (e + 4) % 8
y = 0 if x == 0 else 8 - x
return data[4:] if y == 0 else data[4:-y]
def decode_des(to_decode_str, des_key):
"""
解密数据
Args:
to_decode_str(str): 要解密的原字符串
des_key(str): 解密的key
Returns:
"""
key = mds_hash(des_key)
des3 = DES3.new(key, DES3.MODE_ECB)
param = base64.b64decode(to_decode_str)
param = des3.decrypt(param)
param = un_des_pad(param).decode('utf-8')
return param
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!