03fecf38 by 周伟奇

cms

1 parent 61b268cd
...@@ -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', ),
1629 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 ]
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
......
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,8 +1235,7 @@ def se_compare(application_id, application_entity, ocr_res_id, last_obj, ocr_res ...@@ -1205,8 +1235,7 @@ 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:
1210 compare_info, is_gsyh = get_se_compare_info(last_obj, application_entity, detect_list) 1239 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)
...@@ -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
......
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
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!