cms
Showing
7 changed files
with
255 additions
and
6 deletions
| ... | @@ -1626,4 +1626,60 @@ CA_COMPARE_FIELD = { | ... | @@ -1626,4 +1626,60 @@ CA_COMPARE_FIELD = { |
| 1626 | DL_EN: (DL_OCR_FIELD, CA_DL_COMPARE_LOGIC, False), | 1626 | DL_EN: (DL_OCR_FIELD, CA_DL_COMPARE_LOGIC, False), |
| 1627 | } | 1627 | } |
| 1628 | 1628 | ||
| 1629 | # ------------------CMS-------------------------------------- | ||
| 1630 | BANK_INFO_MAP = ( | ||
| 1631 | ('accountNo', 'bankAccountDetails.accountNo'), | ||
| 1632 | ('bankName', 'bankAccountDetails.bankName'), | ||
| 1633 | ('accountHolderName', 'bankAccountDetails.accountHolderName'), | ||
| 1634 | ) | ||
| 1635 | |||
| 1636 | VEHICLE_INFO_MAP = ( | ||
| 1637 | ('vehicleStatus', 'vehicleStatus'), | ||
| 1638 | ('vinNo', 'vehicleInformation.vinNo'), | ||
| 1639 | ('dealer', 'dealerName'), | ||
| 1640 | ('vehicleTransactionAmount', 'totalFinanceAmount'), | ||
| 1641 | ) | ||
| 1642 | |||
| 1643 | CORPORATE_INFO_MAP = ( | ||
| 1644 | ('firstIdType', ), | ||
| 1645 | ('firstIdNo', ), | ||
| 1646 | ('companyName', ), | ||
| 1647 | ('legalRepName', ), | ||
| 1648 | ('businessLicenseNo', ), | ||
| 1649 | ('organizationCreditCode', ), | ||
| 1650 | ('taxRegistrationCertificateNo', ), | ||
| 1651 | ('establishmentDate', ), | ||
| 1652 | ('businessLicenseDueDate', ), | ||
| 1653 | ) | ||
| 1654 | |||
| 1655 | INDIVIDUAL_INFO_MAP = ( | ||
| 1656 | ('applicantType', 'applicantInformation.applicantType'), | ||
| 1657 | ('customerType', 'applicantInformation.customersubType'), | ||
| 1658 | |||
| 1659 | ('idType', 'applicantInformation.IDInformation.idType'), | ||
| 1660 | ('customerName', 'applicantInformation.name'), | ||
| 1661 | ('idNum', 'applicantInformation.IDInformation.idNum'), | ||
| 1662 | ('dateOfBirth', 'applicantInformation.dateOfBirth'), | ||
| 1663 | ('idExpiryDate', 'applicantInformation.IDInformation.idExpiryDate'), | ||
| 1664 | ('hukouProvince', ), | ||
| 1665 | ('hukouCity', ), | ||
| 1666 | |||
| 1667 | ('secondIdType', 'applicantInformation.IDInformation.idType'), | ||
| 1668 | ('secondIdNum', 'applicantInformation.IDInformation.idNum'), | ||
| 1669 | |||
| 1670 | ('companyName', ), | ||
| 1671 | ('registeredCapital', ), | ||
| 1672 | ('selfEmployedSubType', ), | ||
| 1673 | ) | ||
| 1674 | |||
| 1675 | CMS_TO_POS = [ | ||
| 1676 | ('bank_info', BANK_INFO_MAP), | ||
| 1677 | ('vehicle_info', VEHICLE_INFO_MAP), | ||
| 1678 | ('corporate_cus_info', CORPORATE_INFO_MAP), | ||
| 1679 | ('individual_cus_info', INDIVIDUAL_INFO_MAP), | ||
| 1680 | ] | ||
| 1629 | 1681 | ||
| 1682 | TENANT_MAP = { | ||
| 1683 | AFC_PREFIX: 1, | ||
| 1684 | HIL_PREFIX: 2, | ||
| 1685 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| ... | @@ -13,9 +13,14 @@ class OCR2Exception(Exception): | ... | @@ -13,9 +13,14 @@ class OCR2Exception(Exception): |
| 13 | class OCR4Exception(Exception): | 13 | class OCR4Exception(Exception): |
| 14 | pass | 14 | pass |
| 15 | 15 | ||
| 16 | |||
| 16 | class LTGTException(Exception): | 17 | class LTGTException(Exception): |
| 17 | pass | 18 | pass |
| 18 | 19 | ||
| 19 | 20 | ||
| 20 | class GCAPException(Exception): | 21 | class GCAPException(Exception): |
| 21 | pass | 22 | pass |
| 23 | |||
| 24 | |||
| 25 | class CMSException(Exception): | ||
| 26 | pass | ... | ... |
src/apps/doc/ocr/cms.py
0 → 100644
| 1 | import requests | ||
| 2 | from settings import conf | ||
| 3 | from common.redis_cache import redis_handler as rh | ||
| 4 | from apps.doc.exceptions import CMSException | ||
| 5 | |||
| 6 | |||
| 7 | class CMS: | ||
| 8 | |||
| 9 | def __init__(self): | ||
| 10 | self.oauth_url = conf.CMS_OAUTH_URL | ||
| 11 | self.url = conf.CMS_URL | ||
| 12 | self.oauth_payload = { | ||
| 13 | 'grant_type': 'client_credentials', | ||
| 14 | 'client_id': conf.CMS_OAUTH_ID, | ||
| 15 | 'client_secret': conf.CMS_OAUTH_SECRET, | ||
| 16 | 'scope': conf.CMS_OAUTH_SCOPE | ||
| 17 | } | ||
| 18 | self.token_type = 'bearer' | ||
| 19 | self.token = None | ||
| 20 | self.token_key = 'access_token' | ||
| 21 | self.expires_key = 'expires_in' | ||
| 22 | self.token_type_key = 'token_type' | ||
| 23 | |||
| 24 | def update_token(self): | ||
| 25 | response = requests.post(self.oauth_url, data=self.oauth_payload, files=[]) | ||
| 26 | if response.status_code != 200: | ||
| 27 | raise CMSException('CMS Oauth response with code: {0}'.format(response.status_code)) | ||
| 28 | token = response.json().get(self.token_key) | ||
| 29 | if not isinstance(token, str): | ||
| 30 | raise CMSException('CMS Oauth can not get token: {0}'.format(response.json())) | ||
| 31 | self.token = token | ||
| 32 | self.token_type = response.json().get(self.token_type_key, self.token_type) | ||
| 33 | expires = response.json().get(self.expires_key, 3600) | ||
| 34 | rh.set_cms_token(self.token, expires) | ||
| 35 | |||
| 36 | def get_token(self): | ||
| 37 | if self.token is None: | ||
| 38 | self.token = rh.get_cms_token() | ||
| 39 | if self.token is None: | ||
| 40 | self.update_token() | ||
| 41 | return self.token | ||
| 42 | |||
| 43 | def send(self, payload): | ||
| 44 | token = self.get_token() | ||
| 45 | headers = { | ||
| 46 | 'Authorization': '{0} {1}'.format(self.token_type.capitalize(), token), | ||
| 47 | 'Content-Type': 'application/json', | ||
| 48 | } | ||
| 49 | response = requests.post(self.url, headers=headers, json=payload) | ||
| 50 | if response.status_code != 200: | ||
| 51 | raise CMSException('CMS Oauth response with code: {0}'.format(response.status_code)) | ||
| 52 | return response.json() | ||
| 53 | |||
| 54 | |||
| 55 | cms = CMS() | ||
| 56 | |||
| 57 | |||
| 58 | |||
| 59 |
| ... | @@ -1092,6 +1092,7 @@ class SECMSView(GenericView): | ... | @@ -1092,6 +1092,7 @@ class SECMSView(GenericView): |
| 1092 | @use_args(se_cms_args, location='data') | 1092 | @use_args(se_cms_args, location='data') |
| 1093 | def post(self, request, args): | 1093 | def post(self, request, args): |
| 1094 | 1094 | ||
| 1095 | |||
| 1095 | # 触发比对 | 1096 | # 触发比对 |
| 1096 | compare.apply_async((application_id, business_type, uniq_seq, None, False, True), | 1097 | compare.apply_async((application_id, business_type, uniq_seq, None, False, True), |
| 1097 | queue='queue_compare') | 1098 | queue='queue_compare') | ... | ... |
| ... | @@ -25,6 +25,7 @@ from apps.doc.models import ( | ... | @@ -25,6 +25,7 @@ from apps.doc.models import ( |
| 25 | ) | 25 | ) |
| 26 | from apps.doc import consts | 26 | from apps.doc import consts |
| 27 | from apps.doc.ocr.gcap import gcap | 27 | from apps.doc.ocr.gcap import gcap |
| 28 | from apps.doc.ocr.cms import cms | ||
| 28 | from apps.doc.exceptions import GCAPException | 29 | from apps.doc.exceptions import GCAPException |
| 29 | from apps.doc.named_enum import RequestTeam, RequestTrigger, ProcessName, ErrorType | 30 | from apps.doc.named_enum import RequestTeam, RequestTrigger, ProcessName, ErrorType |
| 30 | from common.tools.comparison import cp | 31 | from common.tools.comparison import cp |
| ... | @@ -35,6 +36,27 @@ empty_str = '' | ... | @@ -35,6 +36,27 @@ empty_str = '' |
| 35 | empty_error_type = 1000 | 36 | empty_error_type = 1000 |
| 36 | 37 | ||
| 37 | 38 | ||
| 39 | class FakePOS: | ||
| 40 | |||
| 41 | def __init__(self, | ||
| 42 | application_id, | ||
| 43 | first_submmison_date, | ||
| 44 | application_version, | ||
| 45 | customer_type, | ||
| 46 | individual_cus_info, | ||
| 47 | corporate_cus_info, | ||
| 48 | vehicle_info, | ||
| 49 | bank_info): | ||
| 50 | self.application_id = application_id | ||
| 51 | self.first_submmison_date = first_submmison_date | ||
| 52 | self.application_version = application_version | ||
| 53 | self.customer_type = customer_type | ||
| 54 | self.individual_cus_info = individual_cus_info | ||
| 55 | self.corporate_cus_info = corporate_cus_info | ||
| 56 | self.vehicle_info = vehicle_info | ||
| 57 | self.bank_info = bank_info | ||
| 58 | |||
| 59 | |||
| 38 | def name_check(ocr_res_dict, second_ocr_field, second_compare_list, second_id_num, name): | 60 | def name_check(ocr_res_dict, second_ocr_field, second_compare_list, second_id_num, name): |
| 39 | id_field = second_compare_list[1][1] | 61 | id_field = second_compare_list[1][1] |
| 40 | name_field = second_compare_list[0][1] | 62 | name_field = second_compare_list[0][1] |
| ... | @@ -881,7 +903,7 @@ def get_se_compare_info(last_obj, application_entity, detect_list): | ... | @@ -881,7 +903,7 @@ def get_se_compare_info(last_obj, application_entity, detect_list): |
| 881 | return compare_info, is_gsyh | 903 | return compare_info, is_gsyh |
| 882 | 904 | ||
| 883 | 905 | ||
| 884 | def cms_get_se_compare_info(last_obj, application_entity, detect_list): | 906 | def rebuild_compare_info(last_obj): |
| 885 | # { | 907 | # { |
| 886 | # "content": { | 908 | # "content": { |
| 887 | # "financeCompany": "宝马汽车金融有限公司", | 909 | # "financeCompany": "宝马汽车金融有限公司", |
| ... | @@ -982,7 +1004,15 @@ def cms_get_se_compare_info(last_obj, application_entity, detect_list): | ... | @@ -982,7 +1004,15 @@ def cms_get_se_compare_info(last_obj, application_entity, detect_list): |
| 982 | # } | 1004 | # } |
| 983 | # } | 1005 | # } |
| 984 | # } | 1006 | # } |
| 985 | pass | 1007 | |
| 1008 | return FakePOS(application_id, | ||
| 1009 | first_submmison_date, | ||
| 1010 | application_version, | ||
| 1011 | customer_type, | ||
| 1012 | individual_cus_info, | ||
| 1013 | corporate_cus_info, | ||
| 1014 | vehicle_info, | ||
| 1015 | bank_info) | ||
| 986 | 1016 | ||
| 987 | 1017 | ||
| 988 | def se_compare_license(license_en, ocr_res_dict, field_list): | 1018 | 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 | ... | @@ -1205,9 +1235,8 @@ def se_compare(application_id, application_entity, ocr_res_id, last_obj, ocr_res |
| 1205 | start_time = datetime.now() | 1235 | start_time = datetime.now() |
| 1206 | detect_list = se_result_detect(ocr_res_dict) | 1236 | detect_list = se_result_detect(ocr_res_dict) |
| 1207 | if is_cms: | 1237 | if is_cms: |
| 1208 | compare_info, is_gsyh = cms_get_se_compare_info(last_obj, application_entity, detect_list) | 1238 | last_obj = rebuild_compare_info(last_obj) |
| 1209 | else: | 1239 | compare_info, is_gsyh = get_se_compare_info(last_obj, application_entity, detect_list) |
| 1210 | compare_info, is_gsyh = get_se_compare_info(last_obj, application_entity, detect_list) | ||
| 1211 | compare_result, total_fields, failed_count, successful_at_this_level, failure_reason_str = se_compare_process( | 1240 | compare_result, total_fields, failed_count, successful_at_this_level, failure_reason_str = se_compare_process( |
| 1212 | compare_info, ocr_res_dict, is_gsyh) | 1241 | compare_info, ocr_res_dict, is_gsyh) |
| 1213 | compare_log.info('{0} [SE] [compare success] [entity={1}] [id={2}] [ocr_res_id={3}] [result={4}]'.format( | 1242 | 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 | ... | @@ -1264,7 +1293,30 @@ def se_compare(application_id, application_entity, ocr_res_id, last_obj, ocr_res |
| 1264 | traceback.format_exc())) | 1293 | traceback.format_exc())) |
| 1265 | 1294 | ||
| 1266 | # cms结果发送 | 1295 | # cms结果发送 |
| 1267 | 1296 | if is_cms: | |
| 1297 | try: | ||
| 1298 | application_link = '{0}/showList/showList?entity={1}&scheme={2}&case_id={3}'.format( | ||
| 1299 | conf.BASE_URL, application_entity, consts.COMPARE_DOC_SCHEME_LIST[1], application_id) | ||
| 1300 | data = { | ||
| 1301 | "SubtenantId": consts.TENANT_MAP[application_entity], | ||
| 1302 | "Data": { | ||
| 1303 | "Result_Message": "Pass" if successful_at_this_level else "Fail", | ||
| 1304 | "Failure_Reason": failure_reason_str, | ||
| 1305 | "Application_Number": application_id, | ||
| 1306 | "Bank_Statement": "", | ||
| 1307 | "Link_URL": application_link, | ||
| 1308 | "OCR_Version": 1, | ||
| 1309 | "Origin": consts.INFO_SOURCE[1] | ||
| 1310 | } | ||
| 1311 | } | ||
| 1312 | response = cms.send(data) | ||
| 1313 | except Exception as e: | ||
| 1314 | compare_log.error('{0} [SE] [cms error] [entity={1}] [id={2}] [ocr_res_id={3}] ' | ||
| 1315 | '[error={4}]'.format(log_base, application_entity, application_id, ocr_res_id, | ||
| 1316 | traceback.format_exc())) | ||
| 1317 | else: | ||
| 1318 | compare_log.info('{0} [SE] [cms success] [entity={1}] [id={2}] [ocr_res_id={3}] [response={4}]'.format( | ||
| 1319 | log_base, application_entity, application_id, ocr_res_id, response)) | ||
| 1268 | 1320 | ||
| 1269 | @app.task | 1321 | @app.task |
| 1270 | def compare(application_id, application_entity, uniq_seq, ocr_res_id, is_ca=True, is_cms=False): | 1322 | def compare(application_id, application_entity, uniq_seq, ocr_res_id, is_ca=True, is_cms=False): | ... | ... |
| ... | @@ -36,6 +36,7 @@ class RedisHandler: | ... | @@ -36,6 +36,7 @@ class RedisHandler: |
| 36 | self.common_queue_key = '{0}:common_queue'.format(self.prefix) | 36 | self.common_queue_key = '{0}:common_queue'.format(self.prefix) |
| 37 | self.priority_queue_key = '{0}:priority_queue'.format(self.prefix) | 37 | self.priority_queue_key = '{0}:priority_queue'.format(self.prefix) |
| 38 | self.session_id_key = '{0}:session_id'.format(self.prefix) | 38 | self.session_id_key = '{0}:session_id'.format(self.prefix) |
| 39 | self.cms_token_key = '{0}:cms_token'.format(self.prefix) | ||
| 39 | 40 | ||
| 40 | def enqueue(self, tasks, is_priority=False): | 41 | def enqueue(self, tasks, is_priority=False): |
| 41 | # 1 | 42 | # 1 |
| ... | @@ -57,3 +58,9 @@ class RedisHandler: | ... | @@ -57,3 +58,9 @@ class RedisHandler: |
| 57 | def get_session_id(self): | 58 | def get_session_id(self): |
| 58 | return self.redis.get(self.session_id_key) | 59 | return self.redis.get(self.session_id_key) |
| 59 | 60 | ||
| 61 | def get_cms_token(self): | ||
| 62 | return self.redis.get(self.cms_token_key) | ||
| 63 | |||
| 64 | def set_cms_token(self, token, expires=None): | ||
| 65 | return self.redis.set(self.cms_token_key, token, expires) | ||
| 66 | ... | ... |
src/common/tools/3des.py
0 → 100644
| 1 | from Crypto.Cipher import DES3 | ||
| 2 | from Crypto.Hash import MD5 | ||
| 3 | import struct | ||
| 4 | import base64 | ||
| 5 | import codecs | ||
| 6 | |||
| 7 | |||
| 8 | def mds_hash(target_str): | ||
| 9 | h = MD5.new() | ||
| 10 | h.update(target_str.encode('utf-8')) | ||
| 11 | return h.digest() | ||
| 12 | |||
| 13 | |||
| 14 | def des_pad(data): | ||
| 15 | data = data.encode('utf-8') | ||
| 16 | e = len(data) | ||
| 17 | x = (e + 4) % 8 | ||
| 18 | y = 0 if x == 0 else 8 - x | ||
| 19 | size_byte = struct.pack('>I', e) | ||
| 20 | result_byte = list(range(len(size_byte) + e + y)) | ||
| 21 | result_byte[0:4] = size_byte | ||
| 22 | result_byte[4:4 + e] = data | ||
| 23 | for i in range(0, y): | ||
| 24 | result_byte[e + 4 + i] = 0 | ||
| 25 | result_str = bytearray(result_byte).decode('utf-8') | ||
| 26 | return result_str | ||
| 27 | |||
| 28 | |||
| 29 | # DES3加密数据 | ||
| 30 | def encode_des(to_encode_str, des_key): | ||
| 31 | """ | ||
| 32 | DES3加密数据 | ||
| 33 | Args: | ||
| 34 | to_encode_str(str): 要被加密的原字符串,这里的字符串需要被des_pad一下 | ||
| 35 | des_key(str): 加密的key | ||
| 36 | Returns: | ||
| 37 | |||
| 38 | """ | ||
| 39 | key = mds_hash(des_key) | ||
| 40 | des3 = DES3.new(key, DES3.MODE_ECB) | ||
| 41 | data = des3.encrypt(des_pad(to_encode_str)) | ||
| 42 | data = codecs.encode(data, 'hex') | ||
| 43 | return data | ||
| 44 | |||
| 45 | |||
| 46 | def un_des_pad(data): | ||
| 47 | result_byte = data[0:4] | ||
| 48 | e = struct.unpack('>I', result_byte)[0] | ||
| 49 | x = (e + 4) % 8 | ||
| 50 | y = 0 if x == 0 else 8 - x | ||
| 51 | return data[4:] if y == 0 else data[4:-y] | ||
| 52 | |||
| 53 | |||
| 54 | def decode_des(to_decode_str, des_key): | ||
| 55 | """ | ||
| 56 | 解密数据 | ||
| 57 | Args: | ||
| 58 | to_decode_str(str): 要解密的原字符串 | ||
| 59 | des_key(str): 解密的key | ||
| 60 | Returns: | ||
| 61 | |||
| 62 | """ | ||
| 63 | key = mds_hash(des_key) | ||
| 64 | des3 = DES3.new(key, DES3.MODE_ECB) | ||
| 65 | param = base64.b64decode(to_decode_str) | ||
| 66 | |||
| 67 | param = des3.decrypt(param) | ||
| 68 | param = un_des_pad(param).decode('utf-8') | ||
| 69 | return param |
-
Please register or sign in to post a comment