comparison part
Showing
9 changed files
with
351 additions
and
1537 deletions
| ... | @@ -1003,3 +1003,4 @@ APPLICANT_TYPE = ['COAPP', 'CUSTR', 'GAUTR1', 'GAUTR2'] | ... | @@ -1003,3 +1003,4 @@ APPLICANT_TYPE = ['COAPP', 'CUSTR', 'GAUTR1', 'GAUTR2'] |
| 1003 | ID_TYPE = ['ITARI', 'ITHKM', 'ITPRC', 'ITPSP', 'ITRES', 'ITTID', 'ITUSC', 'ITCCU'] | 1003 | ID_TYPE = ['ITARI', 'ITHKM', 'ITPRC', 'ITPSP', 'ITRES', 'ITTID', 'ITUSC', 'ITCCU'] |
| 1004 | SECOND_ID_TYPE = ['ITARI', 'ITHKM', 'ITPRC', 'ITPSP', 'ITRES', 'ITTID'] | 1004 | SECOND_ID_TYPE = ['ITARI', 'ITHKM', 'ITPRC', 'ITPSP', 'ITRES', 'ITTID'] |
| 1005 | SUB_TYPE = ['CSIBM', 'CSOTH', 'CSSME'] | 1005 | SUB_TYPE = ['CSIBM', 'CSOTH', 'CSSME'] |
| 1006 | ... | ... |
src/apps/doc/consts_bak.py
deleted
100644 → 0
| 1 | PAGE_DEFAULT = 1 | ||
| 2 | PAGE_SIZE_DEFAULT = 10 | ||
| 3 | |||
| 4 | FIXED_APPLICATION_ID_PREFIX = 'CH-S' | ||
| 5 | |||
| 6 | DOC_SCHEME_LIST = ['ACCEPTANCE', 'SETTLEMENT', 'CONTRACT MANAGEMENT'] | ||
| 7 | DATA_SOURCE_LIST = ['POS', 'EAPP', 'ECONTRACT'] | ||
| 8 | |||
| 9 | HIL_PREFIX = 'HIL' | ||
| 10 | AFC_PREFIX = 'AFC' | ||
| 11 | SPLIT_STR = '_' | ||
| 12 | BUSINESS_TYPE_LIST = [HIL_PREFIX, AFC_PREFIX] | ||
| 13 | HIL_SET = {'HIL', 'HIl', 'HiL', 'Hil', 'hIL', 'hIl', 'hiL', 'hil', 'CO00002'} | ||
| 14 | |||
| 15 | # -------EDMS相关--------------------------------------------------------------------------------------------------- | ||
| 16 | |||
| 17 | SESSION_PREFIX = 'FHLSID' | ||
| 18 | CUSTOM_CLIENT = 'CustomClient' | ||
| 19 | FIXED_TOKEN = '00000000-0000-0000-0000-000000000000' | ||
| 20 | FIXED_FILE_SIZE = 0 | ||
| 21 | DOWNLOAD_ACTION_TYPE = 'Downloaded' | ||
| 22 | |||
| 23 | DOC_SCHEMA_ID_FILL = { | ||
| 24 | 'ACCEPTANCE': (1, 'DFE-AutoFilingScript'), | ||
| 25 | 'SETTLEMENT': (20, 'DFE-AutoFilingScript'), | ||
| 26 | 'CONTRACT MANAGEMENT': (86, 'Schema-Based') | ||
| 27 | } | ||
| 28 | BUSINESS_TYPE_DICT = { | ||
| 29 | HIL_PREFIX: 'CO00002', | ||
| 30 | AFC_PREFIX: 'CO00001' | ||
| 31 | } | ||
| 32 | DOC_SCHEMA_TYPE = 'ElectronicRecord' | ||
| 33 | APPLICATION_ID_META_FIELD_id = 1 | ||
| 34 | DEALER_CODE_META_FIELD_id = 13 | ||
| 35 | BUSINESS_TYPE_META_FIELD_id = 93 | ||
| 36 | DEALER_CODE = 'ocr_situ_group' | ||
| 37 | |||
| 38 | RETRY_TIMES = 3 | ||
| 39 | |||
| 40 | # ---------银行流水模板相关-------------------------------------------------------------------------------------------- | ||
| 41 | |||
| 42 | TRANS_MAP = { | ||
| 43 | 'C': "0", | ||
| 44 | 'c': "0", | ||
| 45 | '(': "0", | ||
| 46 | 'o': "0", | ||
| 47 | 'O': "0", | ||
| 48 | 'D': "0", | ||
| 49 | |||
| 50 | '[': "1", | ||
| 51 | ']': "1", | ||
| 52 | 'l': "1", | ||
| 53 | 'L': "1", | ||
| 54 | |||
| 55 | 'A': "4", | ||
| 56 | |||
| 57 | 's': "5", | ||
| 58 | 'S': "5", | ||
| 59 | |||
| 60 | 'b': "6", | ||
| 61 | |||
| 62 | 'g': "9", | ||
| 63 | 'E': "9", | ||
| 64 | |||
| 65 | 'B': "13", | ||
| 66 | } | ||
| 67 | TRANS = str.maketrans(TRANS_MAP) | ||
| 68 | ERROR_CHARS = {'.', '。', ':', ':', '•', '·', ',', ','} | ||
| 69 | SKIP_IMG_SHEET_NAME = '未处理图片' | ||
| 70 | SKIP_IMG_SHEET_HEADER = ('页码', '序号') | ||
| 71 | |||
| 72 | CARD_RATIO = 0.9 | ||
| 73 | UNKNOWN_CARD = '未知卡号' | ||
| 74 | UNKNOWN_ROLE = '未知户名' | ||
| 75 | DATE_FORMAT = ['%Y年%m月%d日', '%Y/%m/%d', '%Y-%m-%d', '%Y%m%d'] | ||
| 76 | |||
| 77 | PROOF_COL_TITLE = '核对结果' | ||
| 78 | PROOF_RES = ('对', '错') | ||
| 79 | META_SHEET_TITLE = '关键信息提取和展示' | ||
| 80 | |||
| 81 | FIXED_HEADERS = ('记账日期', '记账时间', '金额', '余额', '交易名称', '附言', '对方账户名', '对方卡号/账号', | ||
| 82 | '对方开户行', '核对结果', '借贷', '收入', '支出') | ||
| 83 | FIXED_COL_AMOUNT = len(FIXED_HEADERS) | ||
| 84 | BASE_HEADERS_MAPPING = {label: idx + 1 for idx, label in enumerate(FIXED_HEADERS)} | ||
| 85 | BORROW_HEADER_COL = BASE_HEADERS_MAPPING['借贷'] | ||
| 86 | INCOME_HEADER_COL = BASE_HEADERS_MAPPING['收入'] | ||
| 87 | OUTLAY_HEADER_COL = BASE_HEADERS_MAPPING['支出'] | ||
| 88 | RESULT_HEADER_COL = BASE_HEADERS_MAPPING['核对结果'] | ||
| 89 | BORROW_IDX = BORROW_HEADER_COL - 1 | ||
| 90 | INCOME_IDX = INCOME_HEADER_COL - 1 | ||
| 91 | OUTLAY_IDX = OUTLAY_HEADER_COL - 1 | ||
| 92 | SUMMARY_IDX = FIXED_HEADERS.index('附言') | ||
| 93 | DATE_IDX = FIXED_HEADERS.index('记账日期') | ||
| 94 | AMOUNT_IDX = FIXED_HEADERS.index('金额') | ||
| 95 | OVER_IDX = FIXED_HEADERS.index('余额') | ||
| 96 | RESULT_IDX = FIXED_HEADERS.index('核对结果') | ||
| 97 | # '借贷': ('贷', '借'), # 竖版-无表格-广发银行 | ||
| 98 | # '借贷状态': ('贷', '借'), # 竖版-特殊-交通银行 | ||
| 99 | # '收/支': ('收入', '支出'), # 横版-表格-北京银行 | ||
| 100 | BORROW_HEADERS_SET = {'借贷', '借贷状态', '收/支'} | ||
| 101 | BORROW_INCOME_SET = {'贷', '收入'} | ||
| 102 | BORROW_OUTLAY_SET = {'借', '支出'} | ||
| 103 | INCOME_HEADERS_SET = {'收入金额', '收入', '存入', '存入金额(贷)', '存入金额(贷)'} | ||
| 104 | OUTLAY_HEADERS_SET = {'支出金额', '支出', '支取金额(借)', '支取金额(借)'} | ||
| 105 | |||
| 106 | # ------------------普通打印-全格线-------------------------------------------------------------------------------------- | ||
| 107 | HEADERS_MAPPING = {} | ||
| 108 | # 横版-表格-中国银行(不规则) | ||
| 109 | HEADERS_MAPPING.update( | ||
| 110 | { | ||
| 111 | '记账日期': BASE_HEADERS_MAPPING['记账日期'], | ||
| 112 | '记账时间': BASE_HEADERS_MAPPING['记账时间'], | ||
| 113 | '金额': BASE_HEADERS_MAPPING['金额'], | ||
| 114 | '余额': BASE_HEADERS_MAPPING['余额'], | ||
| 115 | '交易名称': BASE_HEADERS_MAPPING['交易名称'], | ||
| 116 | '附言': BASE_HEADERS_MAPPING['附言'], | ||
| 117 | '对方账户名': BASE_HEADERS_MAPPING['对方账户名'], | ||
| 118 | '对方卡号/账号': BASE_HEADERS_MAPPING['对方卡号/账号'], | ||
| 119 | '对方开户行': BASE_HEADERS_MAPPING['对方开户行'], | ||
| 120 | } | ||
| 121 | ) | ||
| 122 | # 横版-表格-农业银行-中国农业银行个人账户明细 | ||
| 123 | HEADERS_MAPPING.update( | ||
| 124 | { | ||
| 125 | '交易日期': BASE_HEADERS_MAPPING['记账日期'], | ||
| 126 | # '存入': BASE_HEADERS_MAPPING['金额'], | ||
| 127 | '对方账号': BASE_HEADERS_MAPPING['对方卡号/账号'], | ||
| 128 | '对方名称': BASE_HEADERS_MAPPING['对方账户名'], | ||
| 129 | '摘要': BASE_HEADERS_MAPPING['附言'], | ||
| 130 | } | ||
| 131 | ) | ||
| 132 | # 横版-表格-北京银行 | ||
| 133 | HEADERS_MAPPING.update( | ||
| 134 | { | ||
| 135 | '业务摘要': BASE_HEADERS_MAPPING['附言'], | ||
| 136 | '发生额': BASE_HEADERS_MAPPING['金额'], | ||
| 137 | '对方户名': BASE_HEADERS_MAPPING['对方账户名'], | ||
| 138 | } | ||
| 139 | ) | ||
| 140 | # 横版-表格-工商银行 借记卡账户历史明细清单 | ||
| 141 | # 横版-表格-工商银行-机打验证码 借记卡账户历史明细清单 | ||
| 142 | # 横版-表格-工商银行CH-B008802400 | ||
| 143 | # 横版-表格-工商银行 工资明细清单 | ||
| 144 | # 工商银行历史明细(申请单号:20042501303039397888) | ||
| 145 | HEADERS_MAPPING.update( | ||
| 146 | { | ||
| 147 | '收入/支出金额': BASE_HEADERS_MAPPING['金额'], | ||
| 148 | '工作日期': BASE_HEADERS_MAPPING['记账日期'], | ||
| 149 | } | ||
| 150 | ) | ||
| 151 | |||
| 152 | # 横版-表格-建设银行-个人活期账户交易明细 | ||
| 153 | # 竖版-表格-建设银行-个人活期账户交易明细 CH-B005832604 | ||
| 154 | # 竖版-表格-建设银行-工资账单CH-B008786812 | ||
| 155 | # 竖版-表格-建设银行-个人活期账户交易明细 CH-B005832604 (2) | ||
| 156 | HEADERS_MAPPING.update( | ||
| 157 | { | ||
| 158 | '交易金额': BASE_HEADERS_MAPPING['金额'], | ||
| 159 | '账户余额': BASE_HEADERS_MAPPING['余额'], | ||
| 160 | '对方账号与户名': BASE_HEADERS_MAPPING['对方卡号/账号'], | ||
| 161 | } | ||
| 162 | ) | ||
| 163 | # 微信 | ||
| 164 | HEADERS_MAPPING.update( | ||
| 165 | { | ||
| 166 | '交易时间': BASE_HEADERS_MAPPING['记账时间'], | ||
| 167 | '交易类型': BASE_HEADERS_MAPPING['附言'], | ||
| 168 | '金额(元)': BASE_HEADERS_MAPPING['金额'], | ||
| 169 | '金额(元)': BASE_HEADERS_MAPPING['金额'], | ||
| 170 | '交易对方': BASE_HEADERS_MAPPING['对方账户名'], | ||
| 171 | } | ||
| 172 | ) | ||
| 173 | # 支付宝 | ||
| 174 | HEADERS_MAPPING.update( | ||
| 175 | { | ||
| 176 | '时间': BASE_HEADERS_MAPPING['记账日期'], | ||
| 177 | '名称/备注': BASE_HEADERS_MAPPING['附言'], | ||
| 178 | } | ||
| 179 | ) | ||
| 180 | |||
| 181 | # ------------普通打印-部分格线------------------------------------------------------------------------------------------- | ||
| 182 | |||
| 183 | # 竖版-无表格-农业银行 | ||
| 184 | # 竖版-无表格-农业银行CH-B008805428 | ||
| 185 | HEADERS_MAPPING.update( | ||
| 186 | { | ||
| 187 | '摘要/附言': BASE_HEADERS_MAPPING['附言'], | ||
| 188 | '交易地点/对方账号和户名': BASE_HEADERS_MAPPING['对方卡号/账号'], | ||
| 189 | } | ||
| 190 | ) | ||
| 191 | # 农业银行-窄页 | ||
| 192 | HEADERS_MAPPING.update( | ||
| 193 | { | ||
| 194 | '交易对手账号': BASE_HEADERS_MAPPING['对方卡号/账号'], | ||
| 195 | } | ||
| 196 | ) | ||
| 197 | # 竖版-特殊-农商行 | ||
| 198 | HEADERS_MAPPING.update( | ||
| 199 | { | ||
| 200 | '交易发生额': BASE_HEADERS_MAPPING['金额'], | ||
| 201 | } | ||
| 202 | ) | ||
| 203 | # 横版-特殊-中信银行-账户交易明细 | ||
| 204 | HEADERS_MAPPING.update( | ||
| 205 | { | ||
| 206 | '对方银行': BASE_HEADERS_MAPPING['对方开户行'], | ||
| 207 | '交易摘要': BASE_HEADERS_MAPPING['附言'], | ||
| 208 | } | ||
| 209 | ) | ||
| 210 | # 平安电子账单 | ||
| 211 | HEADERS_MAPPING.update( | ||
| 212 | { | ||
| 213 | '借贷发生额(借:-贷:+)': BASE_HEADERS_MAPPING['金额'], | ||
| 214 | } | ||
| 215 | ) | ||
| 216 | |||
| 217 | # ------------普通打印-无格线-------------------------------------------------------------------------------------------- | ||
| 218 | |||
| 219 | # 竖版-无表格-招商银行(略歪) | ||
| 220 | # 竖版-无表格-招商银行账户历史交易明细表 | ||
| 221 | HEADERS_MAPPING.update( | ||
| 222 | { | ||
| 223 | '联机余额': BASE_HEADERS_MAPPING['余额'], | ||
| 224 | } | ||
| 225 | ) | ||
| 226 | # 竖版-无表格-邮储银行-账户对账单 含有对手方户名 对手方账户 | ||
| 227 | # 竖版-无表格-邮储银行 账户对账单 | ||
| 228 | # 竖版-无表格-邮储银行-电子章 邮储银行 账户对账单 | ||
| 229 | HEADERS_MAPPING.update( | ||
| 230 | { | ||
| 231 | '交易金额(元)': BASE_HEADERS_MAPPING['金额'], | ||
| 232 | '交易金额(元)': BASE_HEADERS_MAPPING['金额'], | ||
| 233 | '账户余额(元)': BASE_HEADERS_MAPPING['余额'], | ||
| 234 | '账户余额(元)': BASE_HEADERS_MAPPING['余额'], | ||
| 235 | '对手方户名': BASE_HEADERS_MAPPING['对方账户名'], | ||
| 236 | '对手方账户': BASE_HEADERS_MAPPING['对方卡号/账号'], | ||
| 237 | } | ||
| 238 | ) | ||
| 239 | # 横版-无表格-广发银行-账户交易历史 --> 已废弃 | ||
| 240 | # 竖版-无表格-广发银行-账户交易历史 --> 已废弃 | ||
| 241 | HEADERS_MAPPING.update( | ||
| 242 | { | ||
| 243 | '会计日期': BASE_HEADERS_MAPPING['记账日期'], | ||
| 244 | '对手户名': BASE_HEADERS_MAPPING['对方账户名'], | ||
| 245 | '对手账号': BASE_HEADERS_MAPPING['对方卡号/账号'], | ||
| 246 | } | ||
| 247 | ) | ||
| 248 | # 招行电子账单 TODO 有英文,需测试 | ||
| 249 | HEADERS_MAPPING.update( | ||
| 250 | { | ||
| 251 | '对手信息': BASE_HEADERS_MAPPING['对方账户名'], | ||
| 252 | '摘要代码': BASE_HEADERS_MAPPING['附言'], | ||
| 253 | } | ||
| 254 | ) | ||
| 255 | # 横版-无表格-民生银行-中国民生银行个人账户对账单(客户卡号) | ||
| 256 | # 横版-无表格-民生银行-无标题(客户账户) | ||
| 257 | # 横版-无表格-民生银行 | ||
| 258 | HEADERS_MAPPING.update( | ||
| 259 | { | ||
| 260 | '摘要信息': BASE_HEADERS_MAPPING['附言'], | ||
| 261 | '对方行名': BASE_HEADERS_MAPPING['对方开户行'], | ||
| 262 | } | ||
| 263 | ) | ||
| 264 | # 竖版-无表格-农业银行整数 | ||
| 265 | # 竖版-无表格-农业银行-中国农业银行银行卡交易明细清单 | ||
| 266 | HEADERS_MAPPING.update( | ||
| 267 | { | ||
| 268 | '对方账号和户名': BASE_HEADERS_MAPPING['对方卡号/账号'], | ||
| 269 | } | ||
| 270 | ) | ||
| 271 | # 竖版-无表格-农业银行-中国农业银行银行卡活期存折交易明细清单.pdf | ||
| 272 | # 竖版-无表格-农业银行-扩张.pdf | ||
| 273 | # 竖版-无表格-农业银行-缩进.pdf | ||
| 274 | HEADERS_MAPPING.update( | ||
| 275 | { | ||
| 276 | '日期': BASE_HEADERS_MAPPING['记账日期'], | ||
| 277 | '短摘要': BASE_HEADERS_MAPPING['附言'], | ||
| 278 | '本次余额': BASE_HEADERS_MAPPING['余额'], | ||
| 279 | } | ||
| 280 | ) | ||
| 281 | # 竖版-无表格-农业银行-无标题(对手帐号) | ||
| 282 | HEADERS_MAPPING.update( | ||
| 283 | { | ||
| 284 | '交易后余额': BASE_HEADERS_MAPPING['余额'], | ||
| 285 | '对手帐号': BASE_HEADERS_MAPPING['对方卡号/账号'], | ||
| 286 | } | ||
| 287 | ) | ||
| 288 | # 竖版-无表格-农商行(非常规) | ||
| 289 | HEADERS_MAPPING.update( | ||
| 290 | { | ||
| 291 | '交易说明': BASE_HEADERS_MAPPING['附言'], | ||
| 292 | } | ||
| 293 | ) | ||
| 294 | # 竖版-无表格-工商银行 抬头三行 活期历史明细清单 | ||
| 295 | HEADERS_MAPPING.update( | ||
| 296 | { | ||
| 297 | '对方账户': BASE_HEADERS_MAPPING['对方卡号/账号'], | ||
| 298 | } | ||
| 299 | ) | ||
| 300 | |||
| 301 | # -----------针式打印-全格线-------------------------------------------------------------------------------------------- | ||
| 302 | # 竖版-表格-建设银行-中国建设银行活期账户交易明细 | ||
| 303 | # 竖版-表格-建设银行-中国建设银行活期账户明细清单 | ||
| 304 | # 竖版-表格-建设银行-对私活期账户明细- (1).pdf | ||
| 305 | HEADERS_MAPPING.update( | ||
| 306 | { | ||
| 307 | '帐户余额': BASE_HEADERS_MAPPING['余额'], | ||
| 308 | '对方帐户名称': BASE_HEADERS_MAPPING['对方账户名'], | ||
| 309 | } | ||
| 310 | ) | ||
| 311 | # 竖版-特殊-交通银行 零售客户交易清单 5000以上交易记录 | ||
| 312 | HEADERS_MAPPING.update( | ||
| 313 | { | ||
| 314 | '交易日期 记账日期': BASE_HEADERS_MAPPING['记账日期'], | ||
| 315 | } | ||
| 316 | ) | ||
| 317 | |||
| 318 | # ----------针式打印-部分格线------------------------------------------------------------------------------------------ | ||
| 319 | # 竖版-特殊-邮储银行-一本通绿卡通交易明细(客户) | ||
| 320 | # 竖版-特殊-邮储银行-账户交易明细(客户) | ||
| 321 | HEADERS_MAPPING.update( | ||
| 322 | { | ||
| 323 | '对方账号/卡号/汇票号': BASE_HEADERS_MAPPING['对方卡号/账号'], | ||
| 324 | } | ||
| 325 | ) | ||
| 326 | |||
| 327 | # -------------------------------------------------------------------------------------------------------------------- | ||
| 328 | |||
| 329 | # ('记账日期', '记账时间', '金额', '余额', '交易名称', '附言', '对方账户名', '对方卡号/账号', '对方开户行', '核对结果', '借贷', '收入', '支出') | ||
| 330 | # CLASSIFY_LIST = [ | ||
| 331 | # # --------------普通打印:全格线--------------------------------- | ||
| 332 | # # 中国银行:记账日期 记账时间 币别 金额 余额 交易名称 渠道 网点名称 附言 对方账户名 对方卡号/账号 对方开户行 | ||
| 333 | # ('中国银行', (1, 2, 4, 5, 6, 9, 10, 11, 12, None, None, None, None)), # 横版-表格-中国银行(不规则) | ||
| 334 | # | ||
| 335 | # # 农业银行:交易日期 交易网点 存入 支出 余额 对方账号 对方名称 摘要 渠道 附言 | ||
| 336 | # ('农业银行-10', (1, None, None, 5, None, 8, 7, 6, None, None, None, 3, 4)), # 横版-表格-农业银行-中国农业银行个人账户明细 | ||
| 337 | # | ||
| 338 | # # 农业银行:序号 日期 摘要 交易金额 余额 对方账号 对方名称 交易地点 渠道 附言 | ||
| 339 | # ('农业银行-10-1', (2, None, 4, 5, None, 3, 7, 6, None, None, None, None, None)), | ||
| 340 | # | ||
| 341 | # # 农业银行:交易日期 摘要 交易金额 余额 交易渠道 交易网点 对方账号 对方名称 附言 | ||
| 342 | # ('农业银行-9', (1, None, 3, 4, None, 2, 8, 7, None, None, None, None, None)), | ||
| 343 | # | ||
| 344 | # # 北京银行:交易日期 业务摘要 收/支 发生额 余额 对方户名 对方账号 交易渠道 | ||
| 345 | # ('北京银行', (1, None, 4, 5, None, 2, 6, 7, None, None, 3, None, None)), # 横版-表格-北京银行 | ||
| 346 | # | ||
| 347 | # # 工商银行:交易日期 账号 储种 序号 币种 钞汇 摘要 地区 收入/支出金额 余额 渠道 | ||
| 348 | # ('工商银行', (1, None, 9, 10, None, 7, None, None, None, None, None, None, None)), | ||
| 349 | # | ||
| 350 | # # 工商银行:交易日期 账号 储种 序号 币种 钞汇 摘要 地区 收入/支出金额 余额 对方户名 对方账号 渠道 | ||
| 351 | # ('工商银行-电子账单', (1, None, 9, 10, None, 7, 11, 12, None, None, None, None, None)), | ||
| 352 | # | ||
| 353 | # # 建设银行:空 摘要 交易日期 交易金额 账户余额 商户/网点号及其名称 对方账号与户名 --> 竖版-表格-建设银行 | ||
| 354 | # # 序号 摘要 币别 钞汇 交易日期 交易金额 账户余额 交易地点附言 对方账号与户名 --> 横版-表格-建设银行 | ||
| 355 | # ('建设银行-竖版', (3, None, 4, 5, None, 2, None, 7, None, None, None, None, None)), | ||
| 356 | # ('建设银行-横版', (5, None, 6, 7, None, 2, None, 9, None, None, None, None, None)), | ||
| 357 | # | ||
| 358 | # # 微信:交易单号 交易时间 交易类型 收/支/其他 交易方式 金额(元) 交易对方 商户单号 | ||
| 359 | # ('微信', (2, None, 6, None, None, 3, 7, None, None, None, None, None, None)), | ||
| 360 | # | ||
| 361 | # # 支付宝:流水号 时间 名称/备注 收入 支出 账户余额 资金渠道 | ||
| 362 | # ('支付宝', (2, None, None, 6, None, 3, None, None, None, None, None, 4, 5)), | ||
| 363 | # | ||
| 364 | # # -----------------普通打印:部分格线-------------------------------- | ||
| 365 | # | ||
| 366 | # # 农业银行:交易日期 摘要/附言 交易金额 余额 交易地点/对方账号和户名 | ||
| 367 | # ('农业银行-5', (1, None, 3, 4, None, 2, None, 5, None, None, None, None, None)), | ||
| 368 | # | ||
| 369 | # # 农业银行:日期 地点 摘要 存入 支出 余额 对方账号 对方户名 | ||
| 370 | # ('农业银行-8', (1, None, None, 6, None, 3, 8, 7, None, None, None, 4, 5)), | ||
| 371 | |||
| 372 | # # 农业银行:日期 摘要 交易金额 余额 地点 交易对手账号 对方户名 | ||
| 373 | # ('农业银行-窄页', (1, None, 3, 4, None, 2, 7, 6, None, None, None, None, None)), | ||
| 374 | # | ||
| 375 | # # 农商行:交易日期 交易发生额 账户余额 对方账号 对方户名 摘要 备注 | ||
| 376 | # ('农商行', (1, None, 2, 3, None, 6, 5, 4, None, None, None, None, None)), | ||
| 377 | # | ||
| 378 | # # 中信银行:交易日期 交易摘要 收入金额 支出金额 账户余额 对方户名 对方账号 对方银行 交易流水号 | ||
| 379 | # ('中信银行', (1, None, None, 5, None, 2, 6, 7, 8, None, None, 3, 4)), | ||
| 380 | # | ||
| 381 | # # 平安电子账单:序号 交易日期 交易网点 摘要 借贷发生额(借:-贷:+) 账户余额 | ||
| 382 | # ('平安电子账单', (2, None, 5, 6, None, 4, None, None, None, None, None, None, None)), | ||
| 383 | |||
| 384 | # # 建设银行:序号 摘要 币别 钞汇 交易日期 交易金额 账户余额 交易地点附言 对方账号与户名 | ||
| 385 | # ('建设银行-电子账单', (5, None, 6, 7, None, 2, None, 9, None, None, None, None, None)), | ||
| 386 | # | ||
| 387 | # # -----------------普通打印:无格线------------------------------------- | ||
| 388 | # | ||
| 389 | # # 招商银行:记账日期 货币 交易金额 联机余额 冲补账 交易摘要 | ||
| 390 | # ('招商银行', (1, None, 3, 4, None, 6, None, None, None, None, None, None, None)), | ||
| 391 | # | ||
| 392 | # # 邮储银行:交易日期、交易类型 交易币种 交易金额(元) 账户余额(元) [对手方户名 对手方账户 收支类型] --> 竖版-无表格-邮储银行-账户对账单 含有对手方户名 对手方账户 | ||
| 393 | # # 交易日期、交易类型 交易金额(元) 账户余额(元) 操作柜员 --> 竖版-无表格-邮储银行 账户对账单 | ||
| 394 | # ('邮储银行-8', (1, None, 4, 5, None, 2, 6, 7, None, None, None, None, None)), | ||
| 395 | # ('邮储银行-5', (1, None, 3, 4, None, 2, None, None, None, None, None, None, None)), | ||
| 396 | # | ||
| 397 | # # 工商银行电子版:交易日期 账号 储种 序号 币种 妙汇 摘要 地区 收入/支出金额 余额 [对方户名 对方账号] 渠道 | ||
| 398 | # ('工商银行电子版', (1, None, 9, 10, None, 7, None, None, None, None, None, None, None)), | ||
| 399 | # | ||
| 400 | # # 招商银行电子版:记账日期 货币 交易金额 联机余额 交易摘要 对手信息 | ||
| 401 | # ('招商银行电子版', (1, None, 3, 4, None, 5, 6, None, None, None, None, None, None)), | ||
| 402 | # | ||
| 403 | # # 民生银行:凭证类型 凭证号码 摘要信息 交易时间 交易金额 账户余额 现转标志 交易渠道 交易机构 对方户名 对方行名 --> 横版-无表格-民生银行-中国民生银行个人账户对账单(客户卡号) | ||
| 404 | # # 凭证类型 凭证号码 交易时间 摘要 交易金额 账户余额 现转标志 交易渠道 交易机构 对方户名 对方行名 --> 横版-无表格-民生银行 | ||
| 405 | # ('民生银行', (None, None, 5, 6, None, None, 7, None, 8, None, None, None, None)), | ||
| 406 | # | ||
| 407 | # # 农业银行:交易日期 摘要/附言 交易金额 对方账号和户名 | ||
| 408 | # ('农业银行-整数', (1, None, 3, None, None, 2, None, 4, None, None, None, None, None)), | ||
| 409 | # | ||
| 410 | # # 农业银行:交易日期 摘要/附言 交易金额 余额 交易地点/对方账号和户名 | ||
| 411 | # ('农业银行', (1, None, 3, 4, None, 2, None, 5, None, None, None, None, None)), | ||
| 412 | # | ||
| 413 | # # 农业银行:日期、时间、短摘要、交易金额、本次余额、交易网点、渠道、附言 | ||
| 414 | # # 农业银行:日期、时间、日志号、短摘要、交易金额、本次余额、交易网点、渠道、附言 | ||
| 415 | # ('农业银行', (1, 2, 4, 5, None, 3, None, None, None, None, None, None, None)), | ||
| 416 | # ('农业银行-扩张缩进', (1, 2, 5, 6, None, 4, None, None, None, None, None, None, None)), | ||
| 417 | # | ||
| 418 | # # 交通银行:交易日期 记账日期、交易地点、交易类型、借贷状态、交易金额、余额 | ||
| 419 | # ('交通银行', (1, None, 5, 6, None, 3, None, None, None, None, 4, None, None)), | ||
| 420 | # | ||
| 421 | # | ||
| 422 | # # ================针式打印:有格线=================== | ||
| 423 | # | ||
| 424 | # # 建设银行: 摘要、交易日期、交易金额、账户余额、商户/网点号及其名称、对方账号、对方户名 --> 竖版-表格-建设银行-中国建设银行活期账户明细清单 | ||
| 425 | # # 交易日期、摘要、 币种、 钞汇、 交易金额、 帐户余额、对方账号、 对方帐户名称 --> 竖版-表格-建设银行-对私活期账户明细- (1) | ||
| 426 | # ('建设银行', (None, None, None, None, None, None, None, None, None, None, None, None, None)), | ||
| 427 | # | ||
| 428 | # | ||
| 429 | # # ================针式打印:无格线=================== | ||
| 430 | # | ||
| 431 | # # 邮储银行:序号、交易日期、交易渠道、摘要、交易金额、账户余额、对方账号/卡号/汇票号、原子账号、交易机构名称 | ||
| 432 | # ('邮储银行', (2, None, 5, 6, None, 4, None, 7, None, None, None, None, None)), | ||
| 433 | # ] | ||
| 434 | |||
| 435 | OTHER_TUPLE = (None, None, None, None, None, None, None, None, None, None, None, None, None) | ||
| 436 | |||
| 437 | # { | ||
| 438 | # "0":"其他", | ||
| 439 | # "1":"普通打印-全表格-中国农业银行", | ||
| 440 | # "2":"普通打印-全表格-中国银行", | ||
| 441 | # "3":"普通打印-全表格-北京银行", | ||
| 442 | # "4":"普通打印-全表格-工商银行", | ||
| 443 | # "5":"普通打印-全表格-建设银行", | ||
| 444 | # "6":"普通打印-全表格-微信账单", | ||
| 445 | # "7":"普通打印-全表格-支付宝账单", | ||
| 446 | # "8":"普通打印-无格线-中国邮政储蓄银行", | ||
| 447 | |||
| 448 | # "9":"普通打印-无格线-交通银行", | ||
| 449 | # "10":"普通打印-无格线-农业银行整数", | ||
| 450 | # "11":"普通打印-无格线-农业银行银行活期扩张缩进", | ||
| 451 | # "12":"普通打印-无格线-招商银行", | ||
| 452 | # "13":"普通打印-无格线-招行电子账单", | ||
| 453 | # "14":"普通打印-无格线-民生银行", | ||
| 454 | |||
| 455 | # "15":"普通打印-部分格线-横版-中信银行", | ||
| 456 | # "16":"普通打印-部分格线-竖版-中国农业银行分账户窄页", | ||
| 457 | # "17":"普通打印-部分格线-竖版-农业银行", | ||
| 458 | # "18":"普通打印-部分格线-竖版-农业银行银行卡交易明细", | ||
| 459 | # "19":"普通打印-部分格线-竖版-平安电子账单", | ||
| 460 | |||
| 461 | # "20":"针式打印-全格线-建设银行", | ||
| 462 | # "21":"针式打印-部分格线-竖版-邮储银行账户交易", | ||
| 463 | # "22":"针式打印-部分格线-邮储银行一本通绿卡" | ||
| 464 | # } | ||
| 465 | |||
| 466 | # CLASSIFY_LIST = [ | ||
| 467 | # ('其他', OTHER_TUPLE), | ||
| 468 | # ('农业银行', (1, None, 3, 5, None, 8, 7, 6, None, None, None, None, None)), | ||
| 469 | # ('中国银行', (1, 2, 4, 5, 6, 9, 10, 11, 12, None, None, None, None)), | ||
| 470 | # ('北京银行', (1, None, 4, 5, None, 2, 6, 7, None, None, 3, None, None)), | ||
| 471 | # ('工商银行', (1, None, 9, 10, None, 7, None, None, None, None, None, None, None)), | ||
| 472 | # ('建设银行', (None, None, None, None, None, 2, None, None, None, None, None, None, None)), | ||
| 473 | # ('微信', (2, None, 6, None, None, 3, 7, None, None, None, None, None, None)), | ||
| 474 | # ('支付宝', (2, None, None, 6, None, 3, None, None, None, None, None, 4, 5)), | ||
| 475 | # | ||
| 476 | # ('交通银行', (1, None, 5, 6, None, 3, None, None, None, None, 4, None, None)), | ||
| 477 | # ('农业银行', (1, None, 3, None, None, 2, None, 4, None, None, None, None, None)), | ||
| 478 | # ('农业银行', (1, 2, None, None, None, None, None, None, None, None, None, None, None)), | ||
| 479 | # ('招商银行', (1, None, 3, 4, None, 6, None, None, None, None, None, None, None)), | ||
| 480 | # ('招商银行电子版', (1, None, 3, 4, None, 5, 6, None, None, None, None, None, None)), | ||
| 481 | # ('民生银行', (None, None, 5, 6, None, None, 7, None, 8, None, None, None, None)), | ||
| 482 | # | ||
| 483 | # ('中信银行', (1, None, None, 5, None, 2, 6, 7, 8, None, None, 3, 4)), | ||
| 484 | # ('农业银行', (1, None, 3, 4, None, 2, None, 5, None, None, None, None, None)), | ||
| 485 | # ('农业银行', (1, None, 3, 4, None, 2, None, 5, None, None, None, None, None)), | ||
| 486 | # ('农业银行', (1, None, 3, 4, None, 2, None, 5, None, None, None, None, None)), | ||
| 487 | # ('平安电子账单', (2, None, 5, 6, None, 4, None, None, None, None, None, None, None)), | ||
| 488 | # | ||
| 489 | # ('建设银行', (None, None, None, None, None, None, None, None, None, None, None, None, None)), | ||
| 490 | # ('邮储银行', (2, None, 5, 6, None, 4, None, 7, None, None, None, None, None)), | ||
| 491 | # ('邮储银行', (2, None, 5, 6, None, 4, None, 7, None, None, None, None, None)), | ||
| 492 | # ] | ||
| 493 | |||
| 494 | # "4":"普通打印-全表格-中国银行", | ||
| 495 | # "5":"普通打印-全表格-农业银行-10列", | ||
| 496 | # "6":"普通打印-全表格-农业银行-10列-1", | ||
| 497 | # "7":"普通打印-全表格-农业银行-9列", | ||
| 498 | # "8":"普通打印-全表格-北京银行", | ||
| 499 | # "9":"普通打印-全表格-工商银行", | ||
| 500 | # "10":"普通打印-全表格-工商银行-电子账单", | ||
| 501 | # "11":"普通打印-全表格-建设银行", | ||
| 502 | # "12":"普通打印-全表格-微信账单", | ||
| 503 | # "13":"普通打印-全表格-支付宝账单", | ||
| 504 | |||
| 505 | # "14":"普通打印-无格线-交通银行", | ||
| 506 | # "15":"普通打印-无格线-储蓄银行-5列", | ||
| 507 | # "16":"普通打印-无格线-储蓄银行-8列", | ||
| 508 | # "17":"普通打印-无格线-农业银行-扩张缩进", | ||
| 509 | # "18":"普通打印-无格线-农业银行-整数", | ||
| 510 | # "19":"普通打印-无格线-招商银行", | ||
| 511 | # "20":"普通打印-无格线-招商银行-电子账单", | ||
| 512 | # "21":"普通打印-无格线-民生银行", | ||
| 513 | |||
| 514 | # "22":"普通打印-部分格线-横版-中信银行", | ||
| 515 | # "23":"普通打印-部分格线-竖版-农业银行-5列", | ||
| 516 | # "24":"普通打印-部分格线-竖版-农业银行-8列", | ||
| 517 | # "25":"普通打印-部分格线-竖版-农业银行-窄页", | ||
| 518 | # "26":"普通打印-部分格线-竖版-平安电子账单", | ||
| 519 | # "27":"普通打印-部分格线-竖版-建设银行-电子账单", | ||
| 520 | |||
| 521 | # "34":"针式打印-全格线-建设银行", | ||
| 522 | # "35":"针式打印-部分格线-竖版-邮储银行", | ||
| 523 | # "36":"针式打印-部分格线-竖版-邮储银行-绿卡", | ||
| 524 | |||
| 525 | CLASSIFY_LIST = [ | ||
| 526 | ('其他', OTHER_TUPLE), | ||
| 527 | ('其他', OTHER_TUPLE), | ||
| 528 | ('其他', OTHER_TUPLE), | ||
| 529 | ('其他', OTHER_TUPLE), | ||
| 530 | ('普通打印-全表格-中国银行', (1, 2, 4, 5, 6, 9, 10, 11, 12, None, None, None, None)), | ||
| 531 | ('普通打印-全表格-农业银行-10列', (1, None, None, 5, None, 8, 7, 6, None, None, None, 3, 4)), | ||
| 532 | ('普通打印-全表格-农业银行-10列-1', (2, None, 4, 5, None, 3, 7, 6, None, None, None, None, None)), | ||
| 533 | ('普通打印-全表格-农业银行-9列', (1, None, 3, 4, None, 2, 8, 7, None, None, None, None, None)), | ||
| 534 | ('普通打印-全表格-北京银行', (1, None, 4, 5, None, 2, 6, 7, None, None, 3, None, None)), | ||
| 535 | ('普通打印-全表格-工商银行', (1, None, 9, 10, None, 7, None, None, None, None, None, None, None)), | ||
| 536 | ('普通打印-全表格-工商银行-电子账单', (1, None, 9, 10, None, 7, 11, 12, None, None, None, None, None)), | ||
| 537 | ('普通打印-全表格-建设银行', (3, None, 4, 5, None, 2, None, 7, None, None, None, None, None)), | ||
| 538 | ('普通打印-全表格-微信账单', (2, None, 6, None, None, 3, 7, None, None, None, None, None, None)), | ||
| 539 | ('普通打印-全表格-支付宝账单', (2, None, None, 6, None, 3, None, None, None, None, None, 4, 5)), | ||
| 540 | |||
| 541 | ('普通打印-无格线-交通银行', (1, None, 5, 6, None, 3, None, None, None, None, 4, None, None)), | ||
| 542 | ('普通打印-无格线-储蓄银行-5列', (1, None, 3, 4, None, 2, None, None, None, None, None, None, None)), | ||
| 543 | ('普通打印-无格线-储蓄银行-8列', (1, None, 4, 5, None, 2, 6, 7, None, None, None, None, None)), | ||
| 544 | ('普通打印-无格线-农业银行-扩张缩进', (1, 2, 5, 6, None, 4, None, None, None, None, None, None, None)), | ||
| 545 | ('普通打印-无格线-农业银行-整数', (1, None, 3, None, None, 2, None, 4, None, None, None, None, None)), | ||
| 546 | ('普通打印-无格线-招商银行', (1, None, 3, 4, None, 6, None, None, None, None, None, None, None)), | ||
| 547 | ('普通打印-无格线-招商银行-电子账单', (1, None, 3, 4, None, 5, 6, None, None, None, None, None, None)), | ||
| 548 | ('普通打印-无格线-民生银行', (None, None, 5, 6, None, None, 7, None, 8, None, None, None, None)), | ||
| 549 | |||
| 550 | ('普通打印-部分格线-横版-中信银行', (1, None, None, 5, None, 2, 6, 7, 8, None, None, 3, 4)), | ||
| 551 | ('普通打印-部分格线-竖版-农业银行-5列', (1, None, 3, 4, None, 2, None, 5, None, None, None, None, None)), | ||
| 552 | ('普通打印-部分格线-竖版-农业银行-8列', (1, None, None, 6, None, 3, 8, 7, None, None, None, 4, 5)), | ||
| 553 | ('普通打印-部分格线-竖版-农业银行-窄页', (1, None, 3, 4, None, 2, 7, 6, None, None, None, None, None)), | ||
| 554 | ('普通打印-部分格线-竖版-平安电子账单', (2, None, 5, 6, None, 4, None, None, None, None, None, None, None)), | ||
| 555 | ('普通打印-部分格线-竖版-建设银行-电子账单', (5, None, 6, 7, None, 2, None, 9, None, None, None, None, None)), | ||
| 556 | ('其他', OTHER_TUPLE), | ||
| 557 | ('其他', OTHER_TUPLE), | ||
| 558 | ('其他', OTHER_TUPLE), | ||
| 559 | ('其他', OTHER_TUPLE), | ||
| 560 | ('其他', OTHER_TUPLE), | ||
| 561 | ('其他', OTHER_TUPLE), | ||
| 562 | ('针式打印-全格线-建设银行', OTHER_TUPLE), | ||
| 563 | ('针式打印-部分格线-竖版-邮储银行', (2, None, 5, 6, None, 4, None, 7, None, None, None, None, None)), | ||
| 564 | ('针式打印-部分格线-竖版-邮储银行-绿卡', (2, None, 5, 6, None, 4, None, 7, None, None, None, None, None)), | ||
| 565 | ('其他', OTHER_TUPLE), | ||
| 566 | ] | ||
| 567 | |||
| 568 | # ----------license相关------------------------------------------------------------------------------------------------ | ||
| 569 | |||
| 570 | # "0":"AVT Invioce", | ||
| 571 | # "1":"二手车发票", | ||
| 572 | # "2":"其他", | ||
| 573 | # "3":"护照", | ||
| 574 | # "28":"机动车登记证", | ||
| 575 | # "29":"机动车销售统一发票", | ||
| 576 | # "30":"港澳通行证", | ||
| 577 | # "31":"营业执照", | ||
| 578 | # "32":"行驶证", | ||
| 579 | # "33":"身份证", | ||
| 580 | # "37":"银行卡" | ||
| 581 | |||
| 582 | # 其他 | ||
| 583 | OTHER_CLASSIFY = 2 | ||
| 584 | |||
| 585 | # 身份证 | ||
| 586 | IC_CN_NAME = '身份证' | ||
| 587 | IC_CLASSIFY = 33 | ||
| 588 | IC_FIELD_ORDER_0 = (('姓名', '姓名'), | ||
| 589 | ('公民身份号码', '公民身份号码'), | ||
| 590 | ('出生年月', '出生年月'), | ||
| 591 | ('住址', '住址'), | ||
| 592 | ('性别', '性别'), | ||
| 593 | ('民族', '民族'),) | ||
| 594 | IC_FIELD_ORDER_1 = (('有效期限', '有效期限'), ('签发机关', '签发机关'),) | ||
| 595 | # 居住证 | ||
| 596 | RP_CN_NAME = '居住证' | ||
| 597 | RP_CLASSIFY = 10087 | ||
| 598 | RP_FIELD_ORDER_0 = (('姓名', '姓名'), | ||
| 599 | ('公民身份号码', '公民身份号码'), | ||
| 600 | ('出生年月', '出生年月'), | ||
| 601 | ('住址', '住址'), | ||
| 602 | ('性别', '性别'),) | ||
| 603 | RP_FIELD_ORDER_1 = IC_FIELD_ORDER_1 | ||
| 604 | # 增值税发票 | ||
| 605 | VAT_CN_NAME = 'VAT普票' | ||
| 606 | VAT_CLASSIFY = 0 | ||
| 607 | VAT_FIELD_ORDER = (('发票代码', '发票代码'), | ||
| 608 | ('发票代码(开具)', '发票代码(开具)'), | ||
| 609 | ('发票号码', '发票号码'), | ||
| 610 | ('发票号码(开具)', '发票号码(开具)'), | ||
| 611 | ('开票日期', '开票日期'), | ||
| 612 | ('校验码', '校验码'), | ||
| 613 | ('货物或应税劳务、服务名称', '货物或应税劳务、服务名称'), | ||
| 614 | ('金额合计', '开具金额合计(不含税)'), | ||
| 615 | ('税率', '税率'), | ||
| 616 | ('税额合计', '税额合计'), | ||
| 617 | ('价税合计小写', '价税合计(小写)'), | ||
| 618 | ('价税合计大写', '价税合计(大写)'), | ||
| 619 | ('购方名称', '购买方名称'), | ||
| 620 | ('购方纳税人识别号', '购买方纳税人识别号'), | ||
| 621 | ('购方地址、电话', '购买方地址、电话'), | ||
| 622 | ('购方开户行及账号', '购买方开户行及账号'), | ||
| 623 | ('销方名称', '销售方名称'), | ||
| 624 | ('销方纳税人识别号', '销售方纳税人识别号'), | ||
| 625 | ('销方地址、电话', '销售方地址、电话'), | ||
| 626 | ('销方开户行及账号', '销售方开户行及账号'), | ||
| 627 | ('销售方:(章)', '销售方:(章)'), | ||
| 628 | ('备注', '备注'),) | ||
| 629 | # 机动车登记证书 | ||
| 630 | MVC_CN_NAME = '机动车登记证书' | ||
| 631 | MVC_CLASSIFY = 28 | ||
| 632 | MVC_CLASSIFY_SE = 10086 | ||
| 633 | MVC_FIELD_ORDER_1_2 = (('1.机动车所有人/身份证名称/号码', '机动车所有人/身份证明名称/号码'), | ||
| 634 | ('3.登记日期', '登记日期'), | ||
| 635 | ('9.车辆识别代号/车架号', '车辆识别代号/车架号'), | ||
| 636 | ('32.车辆出厂日期', '车辆出厂日期'), | ||
| 637 | ('34.发证日期', '发证日期'), | ||
| 638 | ('30.使用性质', '使用性质'), | ||
| 639 | ('31.车辆获得方式', '车辆获得方式'), | ||
| 640 | ('4.机动车登记编号', '机动车登记编号'), | ||
| 641 | ('空行占位', None), | ||
| 642 | ('5.车辆类型', '车辆类型'), | ||
| 643 | ('6.车辆品牌', '车辆品牌'), | ||
| 644 | ('7.车辆型号', '车辆型号'), | ||
| 645 | ('8.车身颜色', '车身颜色'), | ||
| 646 | ('10.国产/进口', '国产/进口'), | ||
| 647 | ('11.发动机号', '发动机号'), | ||
| 648 | ('12.发动机型号', '发动机型号'), | ||
| 649 | ('15.制造厂名称', '制造厂名称'), | ||
| 650 | ('2.登记机关', '登记机关'), | ||
| 651 | ('编号', '机动车登记证书编号'),) | ||
| 652 | MVC_FIELD_ORDER_3_4 = ( | ||
| 653 | ('姓名/名称', '姓名/名称'), | ||
| 654 | ('身份证明名称/号码', '身份证明名称/号码'), | ||
| 655 | ('转移登记日期', '转移登记日期'), | ||
| 656 | ) | ||
| 657 | MVC_SE_FIELD_ORDER_1_2 = (('9.车辆识别代号/车架号', '车辆识别代号/车架号'), | ||
| 658 | ('1.机动车所有人/身份证名称/号码', '机动车所有人/身份证明名称/号码'), | ||
| 659 | ('空行占位', None), | ||
| 660 | ('3.登记日期', '登记日期'), | ||
| 661 | ('32.车辆出厂日期', '车辆出厂日期'), | ||
| 662 | ('34.发证日期', '发证日期'), | ||
| 663 | ('30.使用性质', '使用性质'), | ||
| 664 | ('31.车辆获得方式', '车辆获得方式'), | ||
| 665 | ('5.车辆类型', '车辆类型'), | ||
| 666 | ('6.车辆品牌', '车辆品牌'), | ||
| 667 | ('7.车辆型号', '车辆型号'), | ||
| 668 | ('8.车身颜色', '车身颜色'), | ||
| 669 | ('10.国产/进口', '国产/进口'), | ||
| 670 | ('11.发动机号', '发动机号'), | ||
| 671 | ('12.发动机型号', '发动机型号'), | ||
| 672 | ('13.燃料种类', '燃料种类'), | ||
| 673 | ('14.排量/功率', '排量/功率'), | ||
| 674 | ('15.制造厂名称', '制造厂名称'), | ||
| 675 | ('16.转向形式', '转向形式'), | ||
| 676 | ('17.轮距', '轮距'), | ||
| 677 | ('18.轮胎数', '轮胎数'), | ||
| 678 | ('19.轮胎规格', '轮胎规格'), | ||
| 679 | ('20.钢板弹簧片数', '钢板弹簧片数'), | ||
| 680 | ('21.轴距', '轴距'), | ||
| 681 | ('22.轴数', '轴数'), | ||
| 682 | ('23.外廓尺寸', '外廓尺寸'), | ||
| 683 | ('24.货厢内部尺寸', '货厢内部尺寸'), | ||
| 684 | ('25.总质量', '总质量'), | ||
| 685 | ('26.核定载质量', '核定载质量'), | ||
| 686 | ('27.核定载客', '核定载客'), | ||
| 687 | ('28.准牵引总质量', '准牵引总质量'), | ||
| 688 | ('29.驾驶室载客', '驾驶室载客'), | ||
| 689 | ('2.登记机关', '登记机关'), | ||
| 690 | ('4.机动车登记编号', '机动车登记编号'), | ||
| 691 | ('编号', '机动车登记证书编号'),) | ||
| 692 | MVC_SE_FIELD_ORDER_3_4 = ( | ||
| 693 | ('姓名/名称', '姓名/名称'), | ||
| 694 | ('身份证明名称/号码', '身份证明名称/号码'), | ||
| 695 | ('转移登记日期', '转移登记日期'), | ||
| 696 | ) | ||
| 697 | # 机动车销售统一发票 | ||
| 698 | MVI_CN_NAME = '机动车销售统一发票' | ||
| 699 | MVI_CLASSIFY = 29 | ||
| 700 | MVI_FIELD_ORDER = (('发票代码', '发票代码'), | ||
| 701 | ('发票号码', '发票号码'), | ||
| 702 | ('开票日期', '开票日期'), | ||
| 703 | ('不含税价', '不含税价'), | ||
| 704 | ('发票类型', '发票联'), | ||
| 705 | ('购方名称', '购买方名称'), | ||
| 706 | ('购买方身份证号或组织机构代码', '购买方证件号码'), | ||
| 707 | ('纳税人识别号', '纳税人识别号'), # nodo | ||
| 708 | ('车辆识别代码', '车架号'), | ||
| 709 | ('价税合计小写', '价税合计小写'), | ||
| 710 | ('销方名称', '销货单位名称'), | ||
| 711 | ('增值税税额', '增值税税额'), | ||
| 712 | ('增值税税率', '增值税税率'), # nodo | ||
| 713 | ('发票章有无', '发票章有无'), # nodo 全国统一发票监制章 销售单位章 | ||
| 714 | ('价税合计大写', '价税合计大写'), # nodo | ||
| 715 | ('', None), | ||
| 716 | ('发动机号码', '发动机号'), | ||
| 717 | ('车辆类型', '车辆类型'), # nodo | ||
| 718 | ('厂牌型号', '厂牌型号'), # nodo | ||
| 719 | ('产地', '产地'), # nodo | ||
| 720 | ('合格证号', '合格证号'), # nodo | ||
| 721 | ('进口证明书号', '进口证明书号'), # nodo | ||
| 722 | ('商检单号', '商检单号'), # nodo | ||
| 723 | ('电话', '电话'), # nodo | ||
| 724 | ('销方纳税人识别号', '销货方纳税人识别号'), | ||
| 725 | ('账号', '账号'), # nodo | ||
| 726 | ('地址', '地址'), # nodo | ||
| 727 | ('开户银行', '开户银行'), # nodo | ||
| 728 | ('主管税务机关及代码', '主管税务机关及代码'), # nodo | ||
| 729 | ('吨位', '吨位'), # nodo | ||
| 730 | ('限乘人数', '限乘人数'),) # nodo | ||
| 731 | IC_PID = VAT_PID = MVC_PID = MVI_PID = None | ||
| 732 | |||
| 733 | # 营业执照 | ||
| 734 | BL_CN_NAME = '营业执照' | ||
| 735 | BL_CLASSIFY = 31 | ||
| 736 | BL_PID = 41 | ||
| 737 | BL_FIELD_ORDER = (('注册号', '统一社会信用代码'), | ||
| 738 | ('企业名称', '名称'), | ||
| 739 | ('企业类型', '类型'), | ||
| 740 | ('经营者姓名', '法定代表人'), | ||
| 741 | ('成立日期', '成立日期'), | ||
| 742 | ('营业期限', '营业期限'), | ||
| 743 | ('注册资本', '注册资本'), | ||
| 744 | ('地址', '住所'), | ||
| 745 | ('经营范围', '经营范围'),) | ||
| 746 | # 二手车发票 | ||
| 747 | UCI_CN_NAME = '二手车发票' | ||
| 748 | UCI_CLASSIFY = 1 | ||
| 749 | UCI_PID = 60 | ||
| 750 | UCI_FIELD_ORDER = (('发票代码', '发票代码'), | ||
| 751 | ('发票号码', '发票号码'), | ||
| 752 | ('开票日期', '开票日期'), | ||
| 753 | ('车价合计', '车价合计小写'), | ||
| 754 | ('发票联', '发票联'), | ||
| 755 | ('购方单位', '买方单位/个人'), | ||
| 756 | ('购方号码', '买方单位代码/身份证号码'), | ||
| 757 | ('车架号码', '车架号'), | ||
| 758 | ('车价合计大写', '车价合计大写'), | ||
| 759 | ('二手车市场', '二手车市场'), | ||
| 760 | ('发票章有无', '发票章有无'), | ||
| 761 | ('空行占位', None), | ||
| 762 | ('车牌照号', '车牌照号'), | ||
| 763 | ('登记证号', '登记证号'), | ||
| 764 | ('购方地址', '买方单位/住址'), | ||
| 765 | ('车辆类型', '车辆类型'), | ||
| 766 | ('厂牌型号', '厂牌型号'), | ||
| 767 | ('车管所名称', '转入地车辆管理所名称'), | ||
| 768 | ('销方名称', '卖方单位/个人'), | ||
| 769 | ('销方号码', '卖方单位代码/身份证号码'), | ||
| 770 | ('销方地址', '卖方单位/个人住址'),) | ||
| 771 | # 港澳台通行证 | ||
| 772 | EEP_CN_NAME = '港澳台通行证' | ||
| 773 | EEP_CLASSIFY = 30 | ||
| 774 | EEP_PID = 1018 | ||
| 775 | EEP_FIELD_ORDER = (('中文名', '姓名'), # 英文名 | ||
| 776 | ('证件号码', '证件号码'), | ||
| 777 | ('签发次数', '换证次数(签发次数)'), | ||
| 778 | ('有效期限', '有效期限'), | ||
| 779 | ('出生日期', '出生日期'), | ||
| 780 | ('性别', '性别'), | ||
| 781 | ('签发机关', '签发机关'), | ||
| 782 | ('签发地点', '签发地点'),) | ||
| 783 | # 行驶证 | ||
| 784 | DL_CN_NAME = '行驶证' | ||
| 785 | DL_CLASSIFY = 32 | ||
| 786 | DL_PID = 5 | ||
| 787 | DL_FIELD_ORDER_0 = (('号牌号码', '1 号牌号码'), | ||
| 788 | ('所有人', '3 所有人'), | ||
| 789 | ('使用性质', '5 使用性质'), | ||
| 790 | ('车辆识别代码', '7 车辆识别代号'), | ||
| 791 | ('注册日期', '9 注册日期'), | ||
| 792 | ('发证日期', '10 发证日期'), | ||
| 793 | ('车辆类型', '2 车辆类型'), | ||
| 794 | ('地址', '4 住址'), | ||
| 795 | ('品牌型号', '6 品牌型号'), | ||
| 796 | ('发动机号', '8 发动机号码'),) | ||
| 797 | DL_FIELD_ORDER_1 = (('号牌号码', '1 号牌号码'), | ||
| 798 | ('档案编号', '11 档案编号'), | ||
| 799 | ('核定载人数', '12 核定载人数'), | ||
| 800 | ('总质量', '13 总质量'), | ||
| 801 | ('整备质量', '14 整备质量'), | ||
| 802 | ('核定载质量', '15 核对载质量'), | ||
| 803 | ('外廓尺寸', '16 外廓尺寸'), | ||
| 804 | ('准牵引总质量', '17 准牵引总质量'),) | ||
| 805 | # 护照 | ||
| 806 | PP_CN_NAME = '护照' | ||
| 807 | PP_CLASSIFY = 3 | ||
| 808 | PP_PID = 8 | ||
| 809 | PP_FIELD_ORDER = (('类型', '类型/Type'), | ||
| 810 | ('英文姓名', '姓名/Name'), | ||
| 811 | ('护照号码', '护照号码/Passport No'), | ||
| 812 | ('有效期至', '有效期至/Date of expiry'), | ||
| 813 | ('签发日期', '签发日期/Date of issue'), | ||
| 814 | ('国家码', '国家码/Country Code'), | ||
| 815 | ('性别', '性别/Sex'), | ||
| 816 | ('国籍', '国籍/Nationality'), | ||
| 817 | ('出生日期', '出生日期/Date of birth'), | ||
| 818 | ('出生地点', '出生地点/Place of birth'), | ||
| 819 | ('签发地点', '签发地点/Place of issue'),) | ||
| 820 | # 银行卡 | ||
| 821 | BC_CN_NAME = '银行卡' | ||
| 822 | BC_CLASSIFY = 37 | ||
| 823 | BC_PID = 4 | ||
| 824 | # BC_FIELD = (('CardNum', '银行卡号'), | ||
| 825 | # ('BankName', '发卡行名称'), | ||
| 826 | # ('CardName', '银行卡名称'), | ||
| 827 | # ('BankCode', '发卡行代号'), | ||
| 828 | # ('CardType', '银行卡类型'), | ||
| 829 | # ('Date', '日期')) | ||
| 830 | BC_FIELD_ORDER = (('BankName', '发卡行名称'), | ||
| 831 | ('CardNum', '银行卡号'), | ||
| 832 | ('CardType', '银行卡类型'),) | ||
| 833 | |||
| 834 | SUCCESS_CODE_SET = {'0', 0} | ||
| 835 | |||
| 836 | FIELD_ORDER_MAP = { | ||
| 837 | IC_CLASSIFY: ('有效期限', IC_FIELD_ORDER_1, IC_FIELD_ORDER_0), | ||
| 838 | RP_CLASSIFY: ('有效期限', RP_FIELD_ORDER_1, RP_FIELD_ORDER_0), | ||
| 839 | DL_CLASSIFY: ('档案编号', DL_FIELD_ORDER_1, DL_FIELD_ORDER_0), | ||
| 840 | MVC_CLASSIFY: ('转移登记日期', MVC_FIELD_ORDER_3_4, MVC_FIELD_ORDER_1_2), | ||
| 841 | MVC_CLASSIFY_SE: ('转移登记日期', MVC_SE_FIELD_ORDER_3_4, MVC_SE_FIELD_ORDER_1_2) | ||
| 842 | } | ||
| 843 | |||
| 844 | LICENSE_ORDER = ((MVI_CLASSIFY, (MVI_PID, MVI_CN_NAME, MVI_FIELD_ORDER, False, False)), | ||
| 845 | (IC_CLASSIFY, (IC_PID, IC_CN_NAME, None, True, False)), | ||
| 846 | (RP_CLASSIFY, (None, RP_CN_NAME, None, True, False)), | ||
| 847 | (BC_CLASSIFY, (BC_PID, BC_CN_NAME, BC_FIELD_ORDER, False, False)), | ||
| 848 | (BL_CLASSIFY, (BL_PID, BL_CN_NAME, BL_FIELD_ORDER, False, False)), | ||
| 849 | (UCI_CLASSIFY, (UCI_PID, UCI_CN_NAME, UCI_FIELD_ORDER, False, False)), | ||
| 850 | (EEP_CLASSIFY, (EEP_PID, EEP_CN_NAME, EEP_FIELD_ORDER, False, False)), | ||
| 851 | (DL_CLASSIFY, (DL_PID, DL_CN_NAME, None, True, False)), | ||
| 852 | (PP_CLASSIFY, (PP_PID, PP_CN_NAME, PP_FIELD_ORDER, False, False)), | ||
| 853 | (MVC_CLASSIFY, (MVC_PID, MVC_CN_NAME, None, True, True)), | ||
| 854 | (VAT_CLASSIFY, (VAT_PID, VAT_CN_NAME, VAT_FIELD_ORDER, False, False))) | ||
| 855 | |||
| 856 | LICENSE_CLASSIFY_MAPPING = dict(LICENSE_ORDER) | ||
| 857 | |||
| 858 | OTHER_CLASSIFY_SET = {OTHER_CLASSIFY} | ||
| 859 | LICENSE_CLASSIFY_SET_1 = {IC_CLASSIFY, VAT_CLASSIFY, MVC_CLASSIFY, MVI_CLASSIFY} | ||
| 860 | LICENSE_CLASSIFY_SET_2 = {BL_CLASSIFY, UCI_CLASSIFY, EEP_CLASSIFY, DL_CLASSIFY, PP_CLASSIFY, BC_CLASSIFY} |
| ... | @@ -4,8 +4,6 @@ import json | ... | @@ -4,8 +4,6 @@ import json |
| 4 | import shutil | 4 | import shutil |
| 5 | import base64 | 5 | import base64 |
| 6 | import signal | 6 | import signal |
| 7 | import asyncio | ||
| 8 | import aiohttp | ||
| 9 | import difflib | 7 | import difflib |
| 10 | import requests | 8 | import requests |
| 11 | import traceback | 9 | import traceback |
| ... | @@ -24,8 +22,9 @@ from apps.doc import consts | ... | @@ -24,8 +22,9 @@ from apps.doc import consts |
| 24 | from apps.doc.ocr.edms import EDMS, rh | 22 | from apps.doc.ocr.edms import EDMS, rh |
| 25 | from apps.doc.named_enum import KeywordsType | 23 | from apps.doc.named_enum import KeywordsType |
| 26 | from apps.doc.exceptions import EDMSException, OCR1Exception, OCR2Exception, OCR4Exception | 24 | from apps.doc.exceptions import EDMSException, OCR1Exception, OCR2Exception, OCR4Exception |
| 27 | from apps.doc.ocr.wb import BSWorkbook, Workbook | 25 | from apps.doc.ocr.wb import BSWorkbook |
| 28 | from apps.doc.models import DocStatus, HILDoc, AFCDoc, Keywords | 26 | from apps.doc.models import DocStatus, HILDoc, AFCDoc, Keywords |
| 27 | from celery_compare.tasks import compare | ||
| 29 | 28 | ||
| 30 | 29 | ||
| 31 | class Command(BaseCommand, LoggerMixin): | 30 | class Command(BaseCommand, LoggerMixin): |
| ... | @@ -545,7 +544,7 @@ class Command(BaseCommand, LoggerMixin): | ... | @@ -545,7 +544,7 @@ class Command(BaseCommand, LoggerMixin): |
| 545 | self.cronjob_log.warn('{0} [process failed (pdf_2_img_2_queue)] [task={1}] ' | 544 | self.cronjob_log.warn('{0} [process failed (pdf_2_img_2_queue)] [task={1}] ' |
| 546 | '[error={2}]'.format(self.log_base, task_str, traceback.format_exc())) | 545 | '[error={2}]'.format(self.log_base, task_str, traceback.format_exc())) |
| 547 | except Exception as e: | 546 | except Exception as e: |
| 548 | self.cronjob_log.error('{0} [process error (db save 1)] [error={1}]'.format( | 547 | self.cronjob_log.error('{0} [process error (db save)] [error={1}]'.format( |
| 549 | self.log_base, traceback.format_exc())) | 548 | self.log_base, traceback.format_exc())) |
| 550 | error_list.append(1) | 549 | error_list.append(1) |
| 551 | return | 550 | return |
| ... | @@ -595,27 +594,27 @@ class Command(BaseCommand, LoggerMixin): | ... | @@ -595,27 +594,27 @@ class Command(BaseCommand, LoggerMixin): |
| 595 | except Exception as e: | 594 | except Exception as e: |
| 596 | self.cronjob_log.error('{0} [process error (ocr fetch)] [img_path={1}] [error={2}]'.format( | 595 | self.cronjob_log.error('{0} [process error (ocr fetch)] [img_path={1}] [error={2}]'.format( |
| 597 | self.log_base, img_path, traceback.format_exc())) | 596 | self.log_base, img_path, traceback.format_exc())) |
| 597 | else: | ||
| 598 | try: | ||
| 599 | del json_data_1 | ||
| 600 | # /data/bmw-ocr-data/AFC/tmp/6/img/page_0_img_0.jpeg | ||
| 601 | # AFC_2 | ||
| 602 | path_split = img_path.split('/') | ||
| 603 | task_str = consts.SPLIT_STR.join((path_split[-5], path_split[-3])) | ||
| 598 | 604 | ||
| 599 | try: | 605 | with lock: |
| 600 | del json_data_1 | 606 | doc_res_dict = res_dict.setdefault(task_str, {}) |
| 601 | # /data/bmw-ocr-data/AFC/tmp/6/img/page_0_img_0.jpeg | 607 | doc_res_dict[img_path] = ocr_1_res |
| 602 | # AFC_2 | 608 | res_dict[task_str] = doc_res_dict |
| 603 | path_split = img_path.split('/') | 609 | todo_count = todo_count_dict.get(task_str) |
| 604 | task_str = consts.SPLIT_STR.join((path_split[-5], path_split[-3])) | 610 | if todo_count == 1: |
| 605 | 611 | finish_queue.put(task_str) | |
| 606 | with lock: | 612 | del todo_count_dict[task_str] |
| 607 | doc_res_dict = res_dict.setdefault(task_str, {}) | 613 | else: |
| 608 | doc_res_dict[img_path] = ocr_1_res | 614 | todo_count_dict[task_str] = todo_count - 1 |
| 609 | res_dict[task_str] = doc_res_dict | 615 | except Exception as e: |
| 610 | todo_count = todo_count_dict.get(task_str) | 616 | self.cronjob_log.error('{0} [process error (store ocr res)] [img_path={1}] [error={2}]'.format( |
| 611 | if todo_count == 1: | 617 | self.log_base, img_path, traceback.format_exc())) |
| 612 | finish_queue.put(task_str) | ||
| 613 | del todo_count_dict[task_str] | ||
| 614 | else: | ||
| 615 | todo_count_dict[task_str] = todo_count - 1 | ||
| 616 | except Exception as e: | ||
| 617 | self.cronjob_log.error('{0} [process error (store ocr res)] [img_path={1}] [error={2}]'.format( | ||
| 618 | self.log_base, img_path, traceback.format_exc())) | ||
| 619 | 618 | ||
| 620 | def res_2_wb(self, res_dict, img_queue, finish_queue, lock, error_list): | 619 | def res_2_wb(self, res_dict, img_queue, finish_queue, lock, error_list): |
| 621 | while len(error_list) == 0 or not img_queue.empty() or not finish_queue.empty(): | 620 | while len(error_list) == 0 or not img_queue.empty() or not finish_queue.empty(): |
| ... | @@ -626,221 +625,220 @@ class Command(BaseCommand, LoggerMixin): | ... | @@ -626,221 +625,220 @@ class Command(BaseCommand, LoggerMixin): |
| 626 | time.sleep(self.sleep_time_task_get) | 625 | time.sleep(self.sleep_time_task_get) |
| 627 | continue | 626 | continue |
| 628 | else: | 627 | else: |
| 628 | self.cronjob_log.info('{0} [res_2_wb] [get task] [task={1}]'.format(self.log_base, task_str)) | ||
| 629 | ocr_1_res = res_dict.pop(task_str, {}) | ||
| 630 | |||
| 631 | business_type, doc_id_str = task_str.split(consts.SPLIT_STR) | ||
| 632 | doc_id = int(doc_id_str) | ||
| 633 | doc_class = HILDoc if business_type == consts.HIL_PREFIX else AFCDoc | ||
| 634 | |||
| 635 | doc_data_path = os.path.join(self.data_dir, business_type, consts.TMP_DIR_NAME, doc_id_str) | ||
| 636 | excel_path = os.path.join(doc_data_path, '{0}.xlsx'.format(doc_id_str)) | ||
| 637 | |||
| 629 | try: | 638 | try: |
| 630 | self.cronjob_log.info('{0} [res_2_wb] [get task] [task={1}]'.format(self.log_base, task_str)) | 639 | doc = doc_class.objects.filter(id=doc_id).first() |
| 631 | ocr_1_res = res_dict.get(task_str, {}) | 640 | except Exception as e: |
| 632 | # self.cronjob_log.info('{0} [res_2_wb] [get task res] [task={1}]'.format( | 641 | self.cronjob_log.error('{0} [process error (db filter)] [task={1}] [error={2}]'.format( |
| 633 | # self.log_base, task_str)) | 642 | self.log_base, task_str, traceback.format_exc())) |
| 634 | 643 | else: | |
| 635 | # 4.OCR结果并且构建excel文件 | 644 | try: |
| 636 | bs_summary = {} | 645 | # 4.OCR结果并且构建excel文件 |
| 637 | license_summary = {} | 646 | bs_summary = {} |
| 638 | unknown_summary = {} | 647 | unknown_summary = {} |
| 639 | res_list = [] | 648 | license_summary = {} |
| 640 | interest_keyword = Keywords.objects.filter( | 649 | res_list = [] |
| 641 | type=KeywordsType.INTEREST.value, on_off=True).values_list('keyword', flat=True) | 650 | interest_keyword = Keywords.objects.filter( |
| 642 | salary_keyword = Keywords.objects.filter( | 651 | type=KeywordsType.INTEREST.value, on_off=True).values_list('keyword', flat=True) |
| 643 | type=KeywordsType.SALARY.value, on_off=True).values_list('keyword', flat=True) | 652 | salary_keyword = Keywords.objects.filter( |
| 644 | loan_keyword = Keywords.objects.filter( | 653 | type=KeywordsType.SALARY.value, on_off=True).values_list('keyword', flat=True) |
| 645 | type=KeywordsType.LOAN.value, on_off=True).values_list('keyword', flat=True) | 654 | loan_keyword = Keywords.objects.filter( |
| 646 | wechat_keyword = Keywords.objects.filter( | 655 | type=KeywordsType.LOAN.value, on_off=True).values_list('keyword', flat=True) |
| 647 | type=KeywordsType.ALI_WECHART.value, on_off=True).values_list('keyword', flat=True) | 656 | wechat_keyword = Keywords.objects.filter( |
| 648 | wb = BSWorkbook(interest_keyword, salary_keyword, loan_keyword, wechat_keyword) | 657 | type=KeywordsType.ALI_WECHART.value, on_off=True).values_list('keyword', flat=True) |
| 649 | for img_path, res in ocr_1_res.items(): | 658 | wb = BSWorkbook(interest_keyword, salary_keyword, loan_keyword, wechat_keyword) |
| 650 | pno, ino = self.parse_img_path(img_path) | 659 | for img_path, res in ocr_1_res.items(): |
| 651 | part_idx = 1 | 660 | pno, ino = self.parse_img_path(img_path) |
| 652 | if res.get('code') == 1: | 661 | part_idx = 1 |
| 653 | ocr_data_list = res.get('data', []) | 662 | if res.get('code') == 1: |
| 654 | if not isinstance(ocr_data_list, list): | 663 | ocr_data_list = res.get('data', []) |
| 655 | res_list.append((pno, ino, part_idx, consts.RES_FAILED_3)) | 664 | if not isinstance(ocr_data_list, list): |
| 656 | self.cronjob_log.warn('{0} [ocr_1 res error] [img={1}]'.format(self.log_base, img_path)) | 665 | res_list.append((pno, ino, part_idx, consts.RES_FAILED_3)) |
| 657 | else: | 666 | self.cronjob_log.warn('{0} [ocr_1 res error] [img={1}]'.format(self.log_base, img_path)) |
| 658 | for part_idx, ocr_data in enumerate(ocr_data_list): | 667 | else: |
| 659 | part_idx = part_idx + 1 | 668 | for part_idx, ocr_data in enumerate(ocr_data_list): |
| 660 | classify = ocr_data.get('classify') | 669 | part_idx = part_idx + 1 |
| 661 | if classify is None: | 670 | classify = ocr_data.get('classify') |
| 662 | res_list.append((pno, ino, part_idx, consts.RES_FAILED_3)) | 671 | if classify is None: |
| 663 | self.cronjob_log.warn('{0} [ocr_1 res error] [img={1}]'.format( | 672 | res_list.append((pno, ino, part_idx, consts.RES_FAILED_3)) |
| 664 | self.log_base, img_path)) | 673 | self.cronjob_log.warn('{0} [ocr_1 res error] [img={1}]'.format( |
| 665 | continue | 674 | self.log_base, img_path)) |
| 666 | elif classify in consts.OTHER_CLASSIFY_SET: # 其他类 | 675 | continue |
| 667 | res_list.append((pno, ino, part_idx, consts.RES_SUCCESS_OTHER)) | 676 | elif classify in consts.OTHER_CLASSIFY_SET: # 其他类 |
| 668 | continue | 677 | res_list.append((pno, ino, part_idx, consts.RES_SUCCESS_OTHER)) |
| 669 | elif classify in consts.LICENSE_CLASSIFY_SET_1: # 证件1 | 678 | continue |
| 670 | self.license1_process(ocr_data, license_summary, classify, res_list, | 679 | elif classify in consts.LICENSE_CLASSIFY_SET_1: # 证件1 |
| 671 | pno, ino, part_idx, img_path) | 680 | self.license1_process(ocr_data, license_summary, classify, res_list, |
| 672 | elif classify in consts.LICENSE_CLASSIFY_SET_2: # 证件2 | 681 | pno, ino, part_idx, img_path) |
| 673 | pid, _, _, _, _, _ = consts.LICENSE_CLASSIFY_MAPPING.get(classify) | 682 | elif classify in consts.LICENSE_CLASSIFY_SET_2: # 证件2 |
| 674 | file_data = ocr_data.get('section_img') | 683 | pid, _, _, _, _, _ = consts.LICENSE_CLASSIFY_MAPPING.get(classify) |
| 675 | if file_data is None: | 684 | file_data = ocr_data.get('section_img') |
| 676 | with open(img_path, 'rb') as f: | 685 | if file_data is None: |
| 677 | base64_data = base64.b64encode(f.read()) | 686 | with open(img_path, 'rb') as f: |
| 678 | # 获取解码后的base64值 | 687 | base64_data = base64.b64encode(f.read()) |
| 679 | file_data = base64_data.decode() | 688 | # 获取解码后的base64值 |
| 680 | json_data_2 = { | 689 | file_data = base64_data.decode() |
| 681 | "pid": str(pid), | 690 | json_data_2 = { |
| 682 | "filedata": file_data | 691 | "pid": str(pid), |
| 683 | } | 692 | "filedata": file_data |
| 684 | 693 | } | |
| 685 | for times in range(consts.RETRY_TIMES): | 694 | |
| 686 | try: | 695 | for times in range(consts.RETRY_TIMES): |
| 687 | start_time = time.time() | 696 | try: |
| 688 | ocr_2_response = requests.post(self.ocr_url_2, data=json_data_2) | 697 | start_time = time.time() |
| 689 | if ocr_2_response.status_code != 200: | 698 | ocr_2_response = requests.post(self.ocr_url_2, data=json_data_2) |
| 690 | raise OCR2Exception('ocr_2 status code: {0}'.format(ocr_2_response.status_code)) | 699 | if ocr_2_response.status_code != 200: |
| 691 | except Exception as e: | 700 | raise OCR2Exception('ocr_2 status code: {0}'.format(ocr_2_response.status_code)) |
| 692 | self.cronjob_log.warn( | 701 | except Exception as e: |
| 693 | '{0} [ocr_2 failed] [times={1}] [img_path={2}] [error={3}]'.format( | 702 | self.cronjob_log.warn( |
| 694 | self.log_base, times, img_path, traceback.format_exc())) | 703 | '{0} [ocr_2 failed] [times={1}] [img_path={2}] [error={3}]'.format( |
| 704 | self.log_base, times, img_path, traceback.format_exc())) | ||
| 705 | else: | ||
| 706 | ocr_2_res = json.loads(ocr_2_response.text) | ||
| 707 | end_time = time.time() | ||
| 708 | speed_time = int(end_time - start_time) | ||
| 709 | self.cronjob_log.info( | ||
| 710 | '{0} [ocr_2 success] [img={1}] [speed_time={2}]'.format( | ||
| 711 | self.log_base, img_path, speed_time)) | ||
| 712 | |||
| 713 | if classify == consts.BC_CLASSIFY: | ||
| 714 | name = '有' | ||
| 715 | json_data_3 = { | ||
| 716 | "file": file_data, | ||
| 717 | 'card_res': ocr_2_res | ||
| 718 | } | ||
| 719 | card_name_response = requests.post(self.ocr_url_3, json_data_3) | ||
| 720 | if card_name_response.status_code == 200: | ||
| 721 | card_name_res = card_name_response.json() | ||
| 722 | if isinstance(card_name_res, dict) and \ | ||
| 723 | card_name_res.get('data', {}).get('is_exists_name') == 0: | ||
| 724 | name = '无' | ||
| 725 | ocr_2_res['Name'] = name | ||
| 726 | self.license2_process(ocr_2_res, license_summary, pid, classify, res_list, pno, ino, part_idx) | ||
| 727 | break | ||
| 695 | else: | 728 | else: |
| 696 | ocr_2_res = json.loads(ocr_2_response.text) | 729 | res_list.append((pno, ino, part_idx, consts.RES_FAILED_2)) |
| 697 | end_time = time.time() | 730 | self.cronjob_log.warn( |
| 698 | speed_time = int(end_time - start_time) | 731 | '{0} [ocr_2 failed] [img_path={1}]'.format(self.log_base, img_path)) |
| 699 | self.cronjob_log.info( | 732 | else: # 流水处理 |
| 700 | '{0} [ocr_2 success] [img={1}] [speed_time={2}]'.format( | 733 | self.bs_process(wb, ocr_data, bs_summary, unknown_summary, classify, res_list, pno, ino, part_idx) |
| 701 | self.log_base, img_path, speed_time)) | 734 | else: |
| 702 | 735 | res_list.append((pno, ino, part_idx, consts.RES_FAILED_1)) | |
| 703 | if classify == consts.BC_CLASSIFY: | 736 | self.cronjob_log.info('{0} [ocr_1 res error] [img={1}]'.format(self.log_base, img_path)) |
| 704 | name = '有' | ||
| 705 | json_data_3 = { | ||
| 706 | "file": file_data, | ||
| 707 | 'card_res': ocr_2_res | ||
| 708 | } | ||
| 709 | card_name_response = requests.post(self.ocr_url_3, json_data_3) | ||
| 710 | if card_name_response.status_code == 200: | ||
| 711 | card_name_res = card_name_response.json() | ||
| 712 | if isinstance(card_name_res, dict) and \ | ||
| 713 | card_name_res.get('data', {}).get('is_exists_name') == 0: | ||
| 714 | name = '无' | ||
| 715 | ocr_2_res['Name'] = name | ||
| 716 | self.license2_process(ocr_2_res, license_summary, pid, classify, res_list, pno, ino, part_idx) | ||
| 717 | break | ||
| 718 | else: | ||
| 719 | res_list.append((pno, ino, part_idx, consts.RES_FAILED_2)) | ||
| 720 | self.cronjob_log.warn( | ||
| 721 | '{0} [ocr_2 failed] [img_path={1}]'.format(self.log_base, img_path)) | ||
| 722 | else: # 流水处理 | ||
| 723 | self.bs_process(wb, ocr_data, bs_summary, unknown_summary, classify, res_list, pno, ino, part_idx) | ||
| 724 | else: | ||
| 725 | res_list.append((pno, ino, part_idx, consts.RES_FAILED_1)) | ||
| 726 | self.cronjob_log.info('{0} [ocr_1 res error] [img={1}]'.format(self.log_base, img_path)) | ||
| 727 | |||
| 728 | with lock: | ||
| 729 | del res_dict[task_str] | ||
| 730 | # self.cronjob_log.info('{0} [res_dict record] [res_dict={1}]'.format( | ||
| 731 | # self.log_base, res_dict)) | ||
| 732 | 737 | ||
| 733 | self.cronjob_log.info('{0} [task={1}] [bs_summary={2}] [unknown_summary={3}] ' | 738 | self.cronjob_log.info('{0} [task={1}] [bs_summary={2}] [unknown_summary={3}] ' |
| 734 | '[license_summary={4}]'.format(self.log_base, task_str, bs_summary, | 739 | '[license_summary={4}]'.format(self.log_base, task_str, bs_summary, |
| 735 | unknown_summary, license_summary)) | 740 | unknown_summary, license_summary)) |
| 736 | 741 | ||
| 737 | self.license_log.info('[task={0}] [license_summary={1}]'.format(task_str, license_summary)) | 742 | self.license_log.info('[task={0}] [license_summary={1}]'.format(task_str, license_summary)) |
| 738 | idcard_list = license_summary.get(consts.IC_CLASSIFY) | 743 | idcard_list = license_summary.get(consts.IC_CLASSIFY) |
| 739 | if idcard_list: | 744 | if idcard_list: |
| 740 | self.idcard_log.info('[task={0}] [idcard={1}]'.format(task_str, idcard_list)) | 745 | self.idcard_log.info('[task={0}] [idcard={1}]'.format(task_str, idcard_list)) |
| 741 | 746 | ||
| 742 | merged_bs_summary = self.rebuild_bs_summary(bs_summary, unknown_summary) | 747 | merged_bs_summary = self.rebuild_bs_summary(bs_summary, unknown_summary) |
| 743 | 748 | ||
| 744 | self.bs_log.info('[task={0}] [bs_summary={1}]'.format(task_str, merged_bs_summary)) | 749 | self.bs_log.info('[task={0}] [bs_summary={1}]'.format(task_str, merged_bs_summary)) |
| 745 | 750 | ||
| 746 | self.cronjob_log.info('{0} [task={1}] [merged_bs_summary={2}] [unknown_summary={3}] ' | 751 | self.cronjob_log.info('{0} [task={1}] [merged_bs_summary={2}] [unknown_summary={3}] ' |
| 747 | '[res_list={4}]'.format(self.log_base, task_str, merged_bs_summary, | 752 | '[res_list={4}]'.format(self.log_base, task_str, merged_bs_summary, |
| 748 | unknown_summary, res_list)) | 753 | unknown_summary, res_list)) |
| 749 | del unknown_summary | 754 | del unknown_summary |
| 750 | 755 | ||
| 751 | # 4.2 重构Excel文件 | ||
| 752 | # doc, business_type = self.get_doc_object(task_str) | ||
| 753 | business_type, doc_id_str = task_str.split(consts.SPLIT_STR) | ||
| 754 | doc_id = int(doc_id_str) | ||
| 755 | doc_class = HILDoc if business_type == consts.HIL_PREFIX else AFCDoc | ||
| 756 | doc = doc_class.objects.filter(id=doc_id).first() | ||
| 757 | doc_data_path = os.path.join(self.data_dir, business_type, consts.TMP_DIR_NAME, str(doc.id)) | ||
| 758 | excel_path = os.path.join(doc_data_path, '{0}.xlsx'.format(doc.id)) | ||
| 759 | # src_excel_path = os.path.join(doc_data_path, 'src.xlsx') | ||
| 760 | # wb.save(src_excel_path) | ||
| 761 | count_list = wb.rebuild(merged_bs_summary, license_summary, res_list, doc.document_scheme) | ||
| 762 | wb.save(excel_path) | ||
| 763 | except Exception as e: | ||
| 764 | try: | ||
| 765 | with lock: | ||
| 766 | if task_str in res_dict: | ||
| 767 | del res_dict[task_str] | ||
| 768 | # doc, business_type = self.get_doc_object(task_str) | ||
| 769 | business_type, doc_id_str = task_str.split(consts.SPLIT_STR) | ||
| 770 | doc_id = int(doc_id_str) | ||
| 771 | doc_class = HILDoc if business_type == consts.HIL_PREFIX else AFCDoc | ||
| 772 | doc = doc_class.objects.filter(id=doc_id).first() | ||
| 773 | doc.status = DocStatus.PROCESS_FAILED.value | ||
| 774 | doc.save() | ||
| 775 | self.cronjob_log.warn('{0} [process failed (res to wb)] [task={1}] [error={2}]'.format( | ||
| 776 | self.log_base, task_str, traceback.format_exc())) | ||
| 777 | except Exception as e: | 756 | except Exception as e: |
| 778 | self.cronjob_log.error('{0} [process error (wb end)] [task={1}] [error={2}]'.format( | ||
| 779 | self.log_base, task_str, traceback.format_exc())) | ||
| 780 | 757 | ||
| 781 | try: | 758 | self.cronjob_log.warn('{0} [process failed (res conformity)] [task={1}] [error={2}]'.format( |
| 782 | doc_data_path = os.path.join(self.data_dir, business_type, consts.TMP_DIR_NAME, str(doc.id)) | ||
| 783 | img_save_path = os.path.join(doc_data_path, 'img') | ||
| 784 | shutil.rmtree(img_save_path, ignore_errors=True) | ||
| 785 | pdf_path = os.path.join(doc_data_path, '{0}.pdf'.format(doc.id)) | ||
| 786 | os.remove(pdf_path) | ||
| 787 | except Exception as e: | ||
| 788 | self.cronjob_log.error('{0} [process error (file remove 1)] [task={1}] [error={2}]'.format( | ||
| 789 | self.log_base, task_str, traceback.format_exc())) | 759 | self.log_base, task_str, traceback.format_exc())) |
| 790 | else: | 760 | |
| 791 | try: | ||
| 792 | img_save_path = os.path.join(doc_data_path, 'img') | ||
| 793 | write_zip_file(img_save_path, os.path.join(doc_data_path, '{0}_img.zip'.format(doc.id))) | ||
| 794 | shutil.rmtree(img_save_path, ignore_errors=True) | ||
| 795 | pdf_path = os.path.join(doc_data_path, '{0}.pdf'.format(doc.id)) | ||
| 796 | os.remove(pdf_path) | ||
| 797 | # os.remove(src_excel_path) | ||
| 798 | except Exception as e: | ||
| 799 | self.cronjob_log.error('{0} [process error (file remove 2)] [task={1}] [error={2}]'.format( | ||
| 800 | self.log_base, task_str, traceback.format_exc())) | ||
| 801 | try: | ||
| 802 | # 5.上传至EDMS | ||
| 803 | for times in range(consts.RETRY_TIMES): | ||
| 804 | try: | ||
| 805 | self.edms.upload(excel_path, doc, business_type) | ||
| 806 | except Exception as e: | ||
| 807 | self.cronjob_log.warn( | ||
| 808 | '{0} [edms upload failed] [times={1}] [task={2}] [error={3}]'.format( | ||
| 809 | self.log_base, times, task_str, traceback.format_exc())) | ||
| 810 | edms_exc = str(e) | ||
| 811 | else: | ||
| 812 | break | ||
| 813 | else: | ||
| 814 | raise EDMSException(edms_exc) | ||
| 815 | except Exception as e: | ||
| 816 | try: | 761 | try: |
| 817 | doc.status = DocStatus.UPLOAD_FAILED.value | 762 | doc.status = DocStatus.PROCESS_FAILED.value |
| 818 | doc.end_time = timezone.now() | ||
| 819 | doc.duration = min((doc.end_time - doc.start_time).seconds, 32760) | ||
| 820 | for field, count in count_list: | ||
| 821 | if hasattr(doc, field): | ||
| 822 | setattr(doc, field, count) | ||
| 823 | doc.save() | 763 | doc.save() |
| 824 | self.cronjob_log.warn('{0} [process failed (edms upload)] [task={1}] [error={2}]'.format( | ||
| 825 | self.log_base, task_str, traceback.format_exc())) | ||
| 826 | except Exception as e: | 764 | except Exception as e: |
| 827 | self.cronjob_log.error('{0} [process error (edms upload)] [task={1}] [error={2}]'.format( | 765 | self.cronjob_log.error('{0} [process error (db save)] [task={1}] [error={2}]'.format( |
| 828 | self.log_base, task_str, traceback.format_exc())) | 766 | self.log_base, task_str, traceback.format_exc())) |
| 767 | |||
| 829 | else: | 768 | else: |
| 769 | |||
| 830 | try: | 770 | try: |
| 831 | doc.status = DocStatus.COMPLETE.value | 771 | # 重构Excel文件 |
| 832 | doc.end_time = timezone.now() | 772 | # src_excel_path = os.path.join(doc_data_path, 'src.xlsx') |
| 833 | doc.duration = min((doc.end_time - doc.start_time).seconds, 32760) | 773 | # wb.save(src_excel_path) |
| 834 | for field, count in count_list: | 774 | count_list = wb.rebuild(merged_bs_summary, license_summary, res_list, doc.document_scheme) |
| 835 | if hasattr(doc, field): | 775 | wb.save(excel_path) |
| 836 | setattr(doc, field, count) | 776 | |
| 837 | doc.save() | ||
| 838 | self.cronjob_log.info('{0} [process complete] [task={1}]'.format(self.log_base, task_str)) | ||
| 839 | os.remove(excel_path) | ||
| 840 | except Exception as e: | 777 | except Exception as e: |
| 841 | self.cronjob_log.error('{0} [process error (completed)] [task={1}] [error={2}]'.format( | 778 | |
| 779 | self.cronjob_log.warn('{0} [process failed (wb rebuild)] [task={1}] [error={2}]'.format( | ||
| 842 | self.log_base, task_str, traceback.format_exc())) | 780 | self.log_base, task_str, traceback.format_exc())) |
| 843 | 781 | ||
| 782 | try: | ||
| 783 | doc.status = DocStatus.PROCESS_FAILED.value | ||
| 784 | doc.save() | ||
| 785 | except Exception as e: | ||
| 786 | self.cronjob_log.error('{0} [process error (db save)] [task={1}] [error={2}]'.format( | ||
| 787 | self.log_base, task_str, traceback.format_exc())) | ||
| 788 | |||
| 789 | else: | ||
| 790 | try: | ||
| 791 | # 上传至EDMS | ||
| 792 | for times in range(consts.RETRY_TIMES): | ||
| 793 | try: | ||
| 794 | self.edms.upload(excel_path, doc, business_type) | ||
| 795 | except Exception as e: | ||
| 796 | self.cronjob_log.warn( | ||
| 797 | '{0} [edms upload failed] [times={1}] [task={2}] [error={3}]'.format( | ||
| 798 | self.log_base, times, task_str, traceback.format_exc())) | ||
| 799 | edms_exc = str(e) | ||
| 800 | else: | ||
| 801 | break | ||
| 802 | else: | ||
| 803 | raise EDMSException(edms_exc) | ||
| 804 | except Exception as e: | ||
| 805 | doc.status = DocStatus.UPLOAD_FAILED.value | ||
| 806 | self.cronjob_log.warn('{0} [process failed (edms upload)] [task={1}] [error={2}]'.format( | ||
| 807 | self.log_base, task_str, traceback.format_exc())) | ||
| 808 | else: | ||
| 809 | doc.status = DocStatus.COMPLETE.value | ||
| 810 | self.cronjob_log.info('{0} [edms upload success] [task={1}]'.format(self.log_base, task_str)) | ||
| 811 | finally: | ||
| 812 | try: | ||
| 813 | doc.end_time = timezone.now() | ||
| 814 | doc.duration = min((doc.end_time - doc.start_time).seconds, 32760) | ||
| 815 | for field, count in count_list: | ||
| 816 | if hasattr(doc, field): | ||
| 817 | setattr(doc, field, count) | ||
| 818 | doc.save() | ||
| 819 | except Exception as e: | ||
| 820 | self.cronjob_log.error('{0} [process error (db save)] [task={1}] [error={2}]'.format( | ||
| 821 | self.log_base, task_str, traceback.format_exc())) | ||
| 822 | else: | ||
| 823 | self.cronjob_log.info('{0} [process complete] [task={1}]'.format(self.log_base, task_str)) | ||
| 824 | os.remove(excel_path) | ||
| 825 | finally: | ||
| 826 | # TODO 识别结果存一张表,方便跑报表 | ||
| 827 | # 更新OCR累计识别结果表 | ||
| 828 | |||
| 829 | # 触发比对 | ||
| 830 | compare.apply_async((doc.application_id, business_type, None, ocr_res_id), queue='queue_compare') | ||
| 831 | finally: | ||
| 832 | try: | ||
| 833 | img_save_path = os.path.join(doc_data_path, 'img') | ||
| 834 | write_zip_file(img_save_path, os.path.join(doc_data_path, '{0}_img.zip'.format(doc_id_str))) | ||
| 835 | shutil.rmtree(img_save_path, ignore_errors=True) | ||
| 836 | pdf_path = os.path.join(doc_data_path, '{0}.pdf'.format(doc_id_str)) | ||
| 837 | os.remove(pdf_path) | ||
| 838 | except Exception as e: | ||
| 839 | self.cronjob_log.error('{0} [process error (pdf & img remove)] [task={1}] [error={2}]'.format( | ||
| 840 | self.log_base, task_str, traceback.format_exc())) | ||
| 841 | |||
| 844 | def handle(self, *args, **kwargs): | 842 | def handle(self, *args, **kwargs): |
| 845 | db.close_old_connections() | 843 | db.close_old_connections() |
| 846 | lock = Lock() | 844 | lock = Lock() | ... | ... |
| ... | @@ -165,3 +165,107 @@ class Configs(models.Model): | ... | @@ -165,3 +165,107 @@ class Configs(models.Model): |
| 165 | verbose_name = '配置信息' | 165 | verbose_name = '配置信息' |
| 166 | verbose_name_plural = verbose_name | 166 | verbose_name_plural = verbose_name |
| 167 | 167 | ||
| 168 | |||
| 169 | # 比对信息表 | ||
| 170 | class AFCComparisonInfo(models.Model): | ||
| 171 | id = models.BigAutoField(primary_key=True, verbose_name="id") # 主键 | ||
| 172 | uniq_seq = models.CharField(max_length=128, verbose_name="唯一序列号") # 索引? | ||
| 173 | application_id = models.CharField(max_length=64, verbose_name="申请id") # 索引 | ||
| 174 | # CUSTOMER_TYPE = ['TCCOR', 'TCDAS', 'TCFRE', 'TCIAS', 'TCIND', 'TCSEP', 'TCURE'] | ||
| 175 | customer_type = models.CharField(max_length=16, verbose_name="顾客类型") | ||
| 176 | application_version = models.SmallIntegerField(default=0, verbose_name="应用版本") | ||
| 177 | vehicle_status = models.CharField(max_length=16, verbose_name="车辆状况") # VEHICLE_STATUS = ['PCUSD', 'PCNEW'] | ||
| 178 | |||
| 179 | individual_cus_info = models.TextField(verbose_name="个人信息") | ||
| 180 | |||
| 181 | usedcar_info = models.TextField(null=True, verbose_name="二手车信息") | ||
| 182 | |||
| 183 | corporate_cus_info = models.TextField(null=True, verbose_name="企业信息") | ||
| 184 | |||
| 185 | update_time = models.DateTimeField(auto_now=True, verbose_name='修改时间') | ||
| 186 | create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') # 索引 | ||
| 187 | |||
| 188 | class Meta: | ||
| 189 | managed = False | ||
| 190 | db_table = 'afc_comparison_info' | ||
| 191 | situ_db_label = 'afc' | ||
| 192 | |||
| 193 | |||
| 194 | # 比对信息表 | ||
| 195 | class HILComparisonInfo(models.Model): | ||
| 196 | id = models.BigAutoField(primary_key=True, verbose_name="id") # 主键 | ||
| 197 | uniq_seq = models.CharField(max_length=128, verbose_name="唯一序列号") # 索引? | ||
| 198 | application_id = models.CharField(max_length=64, verbose_name="申请id") # 索引 | ||
| 199 | # CUSTOMER_TYPE = ['TCCOR', 'TCDAS', 'TCFRE', 'TCIAS', 'TCIND', 'TCSEP', 'TCURE'] | ||
| 200 | customer_type = models.CharField(max_length=16, verbose_name="顾客类型") | ||
| 201 | application_version = models.SmallIntegerField(default=0, verbose_name="应用版本") | ||
| 202 | vehicle_status = models.CharField(max_length=16, verbose_name="车辆状况") # VEHICLE_STATUS = ['PCUSD', 'PCNEW'] | ||
| 203 | |||
| 204 | individual_cus_info = models.TextField(verbose_name="个人信息") | ||
| 205 | |||
| 206 | usedcar_info = models.TextField(null=True, verbose_name="二手车信息") | ||
| 207 | |||
| 208 | corporate_cus_info = models.TextField(null=True, verbose_name="企业信息") | ||
| 209 | |||
| 210 | update_time = models.DateTimeField(auto_now=True, verbose_name='修改时间') | ||
| 211 | create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') # 索引 | ||
| 212 | |||
| 213 | class Meta: | ||
| 214 | managed = False | ||
| 215 | db_table = 'hil_comparison_info' | ||
| 216 | situ_db_label = 'hil' | ||
| 217 | |||
| 218 | |||
| 219 | # OCR结果累计表 | ||
| 220 | class AFCOCRResult(models.Model): | ||
| 221 | id = models.AutoField(primary_key=True, verbose_name="id") # 主键 | ||
| 222 | application_id = models.CharField(max_length=64, verbose_name="申请id") # 索引 | ||
| 223 | |||
| 224 | bs_ocr = models.TextField(null=True, verbose_name="银行流水") | ||
| 225 | mvi_ocr = models.TextField(null=True, verbose_name="机动车销售统一发票") | ||
| 226 | ic_ocr = models.TextField(null=True, verbose_name="身份证") | ||
| 227 | rp_ocr = models.TextField(null=True, verbose_name="居住证") | ||
| 228 | bc_ocr = models.TextField(null=True, verbose_name="银行卡") | ||
| 229 | bl_ocr = models.TextField(null=True, verbose_name="营业执照") | ||
| 230 | uci_ocr = models.TextField(null=True, verbose_name="二手车发票") | ||
| 231 | eep_ocr = models.TextField(null=True, verbose_name="港澳台通行证") | ||
| 232 | dl_ocr = models.TextField(null=True, verbose_name="行驶证") | ||
| 233 | pp_ocr = models.TextField(null=True, verbose_name="护照") | ||
| 234 | mvc_ocr = models.TextField(null=True, verbose_name="机动车登记证") | ||
| 235 | vat_ocr = models.TextField(null=True, verbose_name="增值税发票") | ||
| 236 | |||
| 237 | update_time = models.DateTimeField(auto_now=True, verbose_name='修改时间') | ||
| 238 | create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') | ||
| 239 | |||
| 240 | class Meta: | ||
| 241 | managed = False | ||
| 242 | db_table = 'afc_ocr_result' | ||
| 243 | situ_db_label = 'afc' | ||
| 244 | |||
| 245 | |||
| 246 | # OCR结果累计表 | ||
| 247 | class HILOCRResult(models.Model): | ||
| 248 | id = models.AutoField(primary_key=True, verbose_name="id") # 主键 | ||
| 249 | application_id = models.CharField(max_length=64, verbose_name="申请id") # 索引 | ||
| 250 | |||
| 251 | bs_ocr = models.TextField(null=True, verbose_name="银行流水") | ||
| 252 | mvi_ocr = models.TextField(null=True, verbose_name="机动车销售统一发票") | ||
| 253 | ic_ocr = models.TextField(null=True, verbose_name="身份证") | ||
| 254 | rp_ocr = models.TextField(null=True, verbose_name="居住证") | ||
| 255 | bc_ocr = models.TextField(null=True, verbose_name="银行卡") | ||
| 256 | bl_ocr = models.TextField(null=True, verbose_name="营业执照") | ||
| 257 | uci_ocr = models.TextField(null=True, verbose_name="二手车发票") | ||
| 258 | eep_ocr = models.TextField(null=True, verbose_name="港澳台通行证") | ||
| 259 | dl_ocr = models.TextField(null=True, verbose_name="行驶证") | ||
| 260 | pp_ocr = models.TextField(null=True, verbose_name="护照") | ||
| 261 | mvc_ocr = models.TextField(null=True, verbose_name="机动车登记证") | ||
| 262 | vat_ocr = models.TextField(null=True, verbose_name="增值税发票") | ||
| 263 | |||
| 264 | update_time = models.DateTimeField(auto_now=True, verbose_name='修改时间') | ||
| 265 | create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') | ||
| 266 | |||
| 267 | class Meta: | ||
| 268 | managed = False | ||
| 269 | db_table = 'hil_ocr_result' | ||
| 270 | situ_db_label = 'hil' | ||
| 271 | ... | ... |
src/apps/doc/ocr/wb_bak.py
deleted
100644 → 0
| 1 | import locale | ||
| 2 | import numpy as np | ||
| 3 | from pandas._libs import tslib | ||
| 4 | from pandas._libs.tslibs.nattype import NaTType | ||
| 5 | from pandas.core.indexes.datetimes import DatetimeIndex | ||
| 6 | from openpyxl import Workbook | ||
| 7 | from openpyxl.styles import Border, Side, PatternFill, numbers | ||
| 8 | from openpyxl.utils import get_column_letter | ||
| 9 | from apps.doc import consts | ||
| 10 | |||
| 11 | |||
| 12 | class BSWorkbook(Workbook): | ||
| 13 | |||
| 14 | def __init__(self, interest_keyword, salary_keyword, loan_keyword, *args, **kwargs): | ||
| 15 | super().__init__(*args, **kwargs) | ||
| 16 | locale.setlocale(locale.LC_NUMERIC, 'en_US.UTF-8') | ||
| 17 | self.meta_sheet_title = '关键信息提取和展示' | ||
| 18 | self.blank_row = (None,) | ||
| 19 | self.code_header = ('页数', '电子回单验证码') | ||
| 20 | self.date_header = ('打印时间', '起始日期', '终止日期', '流水区间结果') | ||
| 21 | self.keyword_header = ('关键词', '记账日期', '金额') | ||
| 22 | self.interest_keyword = interest_keyword | ||
| 23 | self.salary_keyword = salary_keyword | ||
| 24 | self.loan_keyword = loan_keyword | ||
| 25 | self.proof_res = ('对', '错') | ||
| 26 | self.loan_fill = PatternFill("solid", fgColor="00FFCC00") | ||
| 27 | self.amount_fill = PatternFill("solid", fgColor="00FFFF00") | ||
| 28 | # self.bd = Side(style='thin', color="000000") | ||
| 29 | # self.border = Border(left=self.bd, top=self.bd, right=self.bd, bottom=self.bd) | ||
| 30 | self.MAX_MEAN = 31 | ||
| 31 | |||
| 32 | @staticmethod | ||
| 33 | def sheet_prune(ws, classify): | ||
| 34 | ws.insert_cols(1, amount=consts.FIXED_COL_AMOUNT) | ||
| 35 | moved_col_set = set() | ||
| 36 | header_col_set = set() | ||
| 37 | # 根据第一行关键词排列 | ||
| 38 | for col in range(consts.FIXED_COL_AMOUNT + 1, ws.max_column + 1): | ||
| 39 | header_value = ws.cell(1, col).value | ||
| 40 | header_col = consts.HEADERS_MAPPING.get(header_value) | ||
| 41 | if header_col is not None and header_col not in header_col_set: | ||
| 42 | letter = get_column_letter(col) | ||
| 43 | ws.move_range("{0}1:{0}{1}".format(letter, ws.max_row), cols=header_col - col) | ||
| 44 | moved_col_set.add(col) | ||
| 45 | header_col_set.add(header_col) | ||
| 46 | elif header_value in consts.BORROW_HEADERS_SET: | ||
| 47 | letter = get_column_letter(col) | ||
| 48 | ws.move_range("{0}1:{0}{1}".format(letter, ws.max_row), cols=consts.BORROW_HEADER_COL - col) | ||
| 49 | moved_col_set.add(col) | ||
| 50 | header_col_set.add(consts.BORROW_HEADER_COL) | ||
| 51 | elif header_value in consts.INCOME_HEADERS_SET: | ||
| 52 | letter = get_column_letter(col) | ||
| 53 | ws.move_range("{0}1:{0}{1}".format(letter, ws.max_row), cols=consts.INCOME_HEADER_COL - col) | ||
| 54 | moved_col_set.add(col) | ||
| 55 | header_col_set.add(consts.INCOME_HEADER_COL) | ||
| 56 | elif header_value in consts.OUTLAY_HEADERS_SET: | ||
| 57 | letter = get_column_letter(col) | ||
| 58 | ws.move_range("{0}1:{0}{1}".format(letter, ws.max_row), cols=consts.OUTLAY_HEADER_COL - col) | ||
| 59 | moved_col_set.add(col) | ||
| 60 | header_col_set.add(consts.OUTLAY_HEADER_COL) | ||
| 61 | |||
| 62 | # 缺失表头再次查找 | ||
| 63 | for header_col in range(1, consts.FIXED_COL_AMOUNT + 1): | ||
| 64 | if header_col in header_col_set or header_col == consts.RESULT_HEADER_COL: | ||
| 65 | continue | ||
| 66 | fix_col = consts.CLASSIFY_LIST[classify][1][header_col - 1] | ||
| 67 | if fix_col is None: | ||
| 68 | continue | ||
| 69 | fix_col = fix_col + consts.FIXED_COL_AMOUNT | ||
| 70 | if fix_col in moved_col_set: | ||
| 71 | break | ||
| 72 | letter = get_column_letter(fix_col) | ||
| 73 | ws.move_range("{0}1:{0}{1}".format(letter, ws.max_row), cols=header_col - fix_col) | ||
| 74 | |||
| 75 | ws.delete_cols(consts.FIXED_COL_AMOUNT + 1, amount=ws.max_column) | ||
| 76 | min_row = 1 if len(moved_col_set) == 0 else 2 | ||
| 77 | return min_row | ||
| 78 | |||
| 79 | @staticmethod | ||
| 80 | def month_split(dti, date_list, date_statistics): | ||
| 81 | month_list = [] | ||
| 82 | idx_list = [] | ||
| 83 | month_pre = None | ||
| 84 | for idx, month_str in enumerate(dti.strftime('%Y-%m')): | ||
| 85 | if isinstance(month_str, float): | ||
| 86 | continue | ||
| 87 | if month_str != month_pre: | ||
| 88 | month_list.append(month_str) | ||
| 89 | if month_pre is None: | ||
| 90 | if date_statistics: | ||
| 91 | date_list.append(dti[idx].date()) | ||
| 92 | idx = 0 | ||
| 93 | idx_list.append(idx) | ||
| 94 | month_pre = month_str | ||
| 95 | if date_statistics: | ||
| 96 | for idx in range(len(dti) - 1, -1, -1): | ||
| 97 | if isinstance(dti[idx], NaTType): | ||
| 98 | continue | ||
| 99 | date_list.append(dti[idx].date()) | ||
| 100 | break | ||
| 101 | return month_list, idx_list | ||
| 102 | |||
| 103 | @staticmethod | ||
| 104 | def get_reverse_trend(day_idx, idx_list): | ||
| 105 | reverse_trend = 0 | ||
| 106 | pre_day = None | ||
| 107 | for idx, day in enumerate(day_idx): | ||
| 108 | if np.isnan(day): | ||
| 109 | continue | ||
| 110 | if idx in idx_list or pre_day is None: | ||
| 111 | pre_day = day | ||
| 112 | continue | ||
| 113 | if day < pre_day: | ||
| 114 | reverse_trend += 1 | ||
| 115 | pre_day = day | ||
| 116 | elif day > pre_day: | ||
| 117 | reverse_trend -= 1 | ||
| 118 | pre_day = day | ||
| 119 | if reverse_trend > 0: | ||
| 120 | reverse_trend = 1 | ||
| 121 | elif reverse_trend < 0: | ||
| 122 | reverse_trend = -1 | ||
| 123 | return reverse_trend | ||
| 124 | |||
| 125 | def sheet_split(self, ws, month_mapping, reverse_trend_list, min_row, date_list, date_statistics): | ||
| 126 | for date_tuple_src in ws.iter_cols(min_col=1, max_col=1, min_row=min_row, values_only=True): | ||
| 127 | date_tuple = [date[:10] if isinstance(date, str) else date for date in date_tuple_src] | ||
| 128 | dt_array, tz_parsed = tslib.array_to_datetime( | ||
| 129 | np.array(date_tuple, copy=False, dtype=np.object_), | ||
| 130 | errors="coerce", | ||
| 131 | utc=False, | ||
| 132 | dayfirst=False, | ||
| 133 | yearfirst=False, | ||
| 134 | require_iso8601=True, | ||
| 135 | ) | ||
| 136 | dti = DatetimeIndex(dt_array, tz=None, name=None) | ||
| 137 | |||
| 138 | month_list, idx_list = self.month_split(dti, date_list, date_statistics) | ||
| 139 | |||
| 140 | if len(month_list) == 0: | ||
| 141 | # month_info process | ||
| 142 | month_info = month_mapping.setdefault('xxxx-xx', []) | ||
| 143 | month_info.append((ws.title, min_row, ws.max_row, 0)) | ||
| 144 | else: | ||
| 145 | # reverse_trend_list process | ||
| 146 | reverse_trend = self.get_reverse_trend(dti.day, idx_list) | ||
| 147 | reverse_trend_list.append(reverse_trend) | ||
| 148 | # month_info process | ||
| 149 | day_idx = dti.day | ||
| 150 | idx_list_max_idx = len(idx_list) - 1 | ||
| 151 | for i, item in enumerate(month_list): | ||
| 152 | if i == idx_list_max_idx: | ||
| 153 | day_mean = np.mean(day_idx[idx_list[i]:].dropna()) | ||
| 154 | month_mapping.setdefault(item, []).append( | ||
| 155 | (ws.title, idx_list[i] + min_row, ws.max_row, day_mean)) | ||
| 156 | else: | ||
| 157 | day_mean = np.mean(day_idx[idx_list[i]: idx_list[i + 1]].dropna()) | ||
| 158 | month_mapping.setdefault(item, []).append( | ||
| 159 | (ws.title, idx_list[i] + min_row, idx_list[i + 1] + min_row - 1, day_mean)) | ||
| 160 | |||
| 161 | def build_metadata_rows(self, confidence, code, print_time, start_date, end_date): | ||
| 162 | if start_date is None or end_date is None: | ||
| 163 | timedelta = None | ||
| 164 | else: | ||
| 165 | timedelta = (end_date - start_date).days | ||
| 166 | metadata_rows = [ | ||
| 167 | ('流水识别置信度', confidence), | ||
| 168 | self.blank_row, | ||
| 169 | self.code_header, | ||
| 170 | ] | ||
| 171 | metadata_rows.extend(code) | ||
| 172 | metadata_rows.extend( | ||
| 173 | [self.blank_row, | ||
| 174 | self.date_header, | ||
| 175 | (print_time, start_date, end_date, timedelta), | ||
| 176 | self.blank_row, | ||
| 177 | self.keyword_header] | ||
| 178 | ) | ||
| 179 | return metadata_rows | ||
| 180 | |||
| 181 | def create_meta_sheet(self, card): | ||
| 182 | if self.worksheets[0].title == 'Sheet': | ||
| 183 | ms = self.worksheets[0] | ||
| 184 | ms.title = '{0}({1})'.format(self.meta_sheet_title, card[-6:]) | ||
| 185 | else: | ||
| 186 | ms = self.create_sheet('{0}({1})'.format(self.meta_sheet_title, card[-6:])) | ||
| 187 | return ms | ||
| 188 | |||
| 189 | def build_meta_sheet(self, card, confidence, code, print_time, start_date, end_date): | ||
| 190 | metadata_rows = self.build_metadata_rows(confidence, code, print_time, start_date, end_date) | ||
| 191 | ms = self.create_meta_sheet(card) | ||
| 192 | for row in metadata_rows: | ||
| 193 | ms.append(row) | ||
| 194 | return ms | ||
| 195 | |||
| 196 | @staticmethod | ||
| 197 | def amount_format(amount_str): | ||
| 198 | if not isinstance(amount_str, str) or amount_str == '': | ||
| 199 | return amount_str | ||
| 200 | # 1.替换 | ||
| 201 | res_str = amount_str.translate(consts.TRANS) | ||
| 202 | # 2.首字符处理 | ||
| 203 | first_char = res_str[0] | ||
| 204 | if first_char in consts.ERROR_CHARS: | ||
| 205 | first_char = '-' | ||
| 206 | # 3.删除多余的- | ||
| 207 | res_str = first_char + res_str[1:].replace('-', '') | ||
| 208 | # 4.逗号与句号处理 | ||
| 209 | if len(res_str) >= 4: | ||
| 210 | period_idx = len(res_str) - 3 | ||
| 211 | if res_str[period_idx] == '.' and res_str[period_idx - 1] == ',': | ||
| 212 | res_str = '{0}{1}'.format(res_str[:period_idx - 1], res_str[period_idx:]) | ||
| 213 | elif res_str[period_idx] == ',': | ||
| 214 | res_str = '{0}.{1}'.format(res_str[:period_idx], res_str[period_idx + 1:]) | ||
| 215 | return res_str | ||
| 216 | |||
| 217 | def build_month_sheet(self, card, month_mapping, ms, is_reverse): | ||
| 218 | tmp_ws = self.create_sheet('tmp_ws') | ||
| 219 | for month in sorted(month_mapping.keys()): | ||
| 220 | # 3.1.拷贝数据 | ||
| 221 | parts = month_mapping.get(month) | ||
| 222 | new_ws = self.create_sheet('{0}({1})'.format(month, card[-6:])) | ||
| 223 | new_ws.append(consts.FIXED_HEADERS) | ||
| 224 | for part in parts: | ||
| 225 | ws = self.get_sheet_by_name(part[0]) | ||
| 226 | for row_value in ws.iter_rows(min_row=part[1], max_row=part[2], values_only=True): | ||
| 227 | new_ws.append(row_value) | ||
| 228 | # 3.2.提取信息、高亮 | ||
| 229 | amount_mapping = {} | ||
| 230 | amount_fill_row = set() | ||
| 231 | for rows in new_ws.iter_rows(min_row=2): | ||
| 232 | summary_cell = rows[consts.SUMMARY_IDX] | ||
| 233 | date_cell = rows[consts.DATE_IDX] | ||
| 234 | amount_cell = rows[consts.AMOUNT_IDX] | ||
| 235 | row = summary_cell.row | ||
| 236 | # 关键词1提取 | ||
| 237 | if summary_cell.value in self.interest_keyword: | ||
| 238 | ms.append((summary_cell.value, date_cell.value, amount_cell.value)) | ||
| 239 | # 关键词2提取至临时表 | ||
| 240 | elif summary_cell.value in self.salary_keyword: | ||
| 241 | tmp_ws.append((summary_cell.value, date_cell.value, amount_cell.value)) | ||
| 242 | # 贷款关键词高亮 | ||
| 243 | elif summary_cell.value in self.loan_keyword: | ||
| 244 | summary_cell.fill = self.loan_fill | ||
| 245 | |||
| 246 | amount_error = False | ||
| 247 | # 3.3.余额转数值 | ||
| 248 | over_cell = rows[consts.OVER_IDX] | ||
| 249 | try: | ||
| 250 | over_cell.value = locale.atof(self.amount_format(over_cell.value)) | ||
| 251 | except Exception as e: | ||
| 252 | amount_error = True | ||
| 253 | else: | ||
| 254 | over_cell.number_format = numbers.FORMAT_NUMBER_00 | ||
| 255 | |||
| 256 | # 3.4.金额转数值 | ||
| 257 | try: | ||
| 258 | try: | ||
| 259 | amount_cell.value = locale.atof(self.amount_format(amount_cell.value)) | ||
| 260 | except Exception as e: | ||
| 261 | try: | ||
| 262 | amount_cell.value = locale.atof(self.amount_format(rows[consts.INCOME_IDX].value)) | ||
| 263 | if amount_cell.value == 0: | ||
| 264 | raise | ||
| 265 | elif amount_cell.value < 0: | ||
| 266 | amount_cell.value = -amount_cell.value | ||
| 267 | except Exception as e: | ||
| 268 | amount_cell.value = locale.atof(self.amount_format(rows[consts.OUTLAY_IDX].value)) | ||
| 269 | if amount_cell.value > 0: | ||
| 270 | amount_cell.value = -amount_cell.value | ||
| 271 | except Exception as e: | ||
| 272 | amount_error = True | ||
| 273 | else: | ||
| 274 | if rows[consts.BORROW_IDX].value in consts.BORROW_OUTLAY_SET: | ||
| 275 | amount_cell.value = -amount_cell.value | ||
| 276 | amount_cell.number_format = numbers.FORMAT_NUMBER_00 | ||
| 277 | same_amount_mapping = amount_mapping.get(date_cell.value, {}) | ||
| 278 | fill_rows = same_amount_mapping.get(-amount_cell.value) | ||
| 279 | if fill_rows: | ||
| 280 | amount_fill_row.add(row) | ||
| 281 | amount_fill_row.update(fill_rows) | ||
| 282 | amount_mapping.setdefault(date_cell.value, {}).setdefault( | ||
| 283 | amount_cell.value, []).append(row) | ||
| 284 | |||
| 285 | # 3.5.核对结果 | ||
| 286 | if row > 2 and not amount_error: | ||
| 287 | if is_reverse: | ||
| 288 | rows[consts.RESULT_IDX].value = '=IF(D{0}=ROUND(SUM(D{1},C{0}),2), "{2}", "{3}")'.format( | ||
| 289 | row - 1, row, *self.proof_res) | ||
| 290 | else: | ||
| 291 | rows[consts.RESULT_IDX].value = '=IF(D{0}=ROUND(SUM(D{1},C{0}),2), "{2}", "{3}")'.format( | ||
| 292 | row, row - 1, *self.proof_res) | ||
| 293 | |||
| 294 | # 删除金额辅助列 | ||
| 295 | new_ws.delete_cols(consts.BORROW_HEADER_COL, amount=new_ws.max_column) | ||
| 296 | |||
| 297 | # 3.6.同一天相同进出账高亮 | ||
| 298 | del amount_mapping | ||
| 299 | for row in amount_fill_row: | ||
| 300 | new_ws[row][consts.AMOUNT_IDX].fill = self.amount_fill | ||
| 301 | |||
| 302 | # 关键词2信息提取 | ||
| 303 | ms.append(self.blank_row) | ||
| 304 | ms.append(self.keyword_header) | ||
| 305 | for row in tmp_ws.iter_rows(values_only=True): | ||
| 306 | ms.append(row) | ||
| 307 | self.remove(tmp_ws) | ||
| 308 | |||
| 309 | def bs_rebuild(self, bs_summary): | ||
| 310 | # bs_summary = { | ||
| 311 | # '卡号': { | ||
| 312 | # 'classify': 0, | ||
| 313 | # 'confidence': 0.9, | ||
| 314 | # 'role': '柳雪', | ||
| 315 | # 'code': [('page', 'code')], | ||
| 316 | # 'print_time': 'datetime', | ||
| 317 | # 'start_date': 'datetime', | ||
| 318 | # 'end_date': 'datetime', | ||
| 319 | # 'sheet': ['sheet_name'] | ||
| 320 | # } | ||
| 321 | # } | ||
| 322 | for card, summary in bs_summary.items(): | ||
| 323 | # 1.原表修剪、排列、按照月份分割 | ||
| 324 | start_date = summary.get('start_date') | ||
| 325 | end_date = summary.get('end_date') | ||
| 326 | date_statistics = False | ||
| 327 | if start_date is None or end_date is None: | ||
| 328 | date_statistics = True | ||
| 329 | date_list = [] | ||
| 330 | month_mapping = {} | ||
| 331 | reverse_trend_list = [] | ||
| 332 | for sheet in summary.get('sheet', []): | ||
| 333 | ws = self.get_sheet_by_name(sheet) | ||
| 334 | # 1.1.删除多余列、排列 | ||
| 335 | min_row = self.sheet_prune(ws, summary.get('classify', 0)) | ||
| 336 | # 1.2.按月份分割 | ||
| 337 | self.sheet_split(ws, month_mapping, reverse_trend_list, min_row, date_list, date_statistics) | ||
| 338 | |||
| 339 | if date_statistics is True and len(date_list) > 1: | ||
| 340 | start_date = min(date_list) if start_date is None else start_date | ||
| 341 | end_date = max(date_list) if end_date is None else end_date | ||
| 342 | |||
| 343 | # 2.元信息提取表 | ||
| 344 | ms = self.build_meta_sheet(card, | ||
| 345 | summary.get('confidence', 1), | ||
| 346 | summary.get('code'), | ||
| 347 | summary.get('print_time'), | ||
| 348 | start_date, | ||
| 349 | end_date) | ||
| 350 | |||
| 351 | # 3.创建月份表、提取/高亮关键行 | ||
| 352 | # 倒序处理 | ||
| 353 | is_reverse = True if sum(reverse_trend_list) > 0 else False | ||
| 354 | for month_list in month_mapping.values(): | ||
| 355 | month_list.sort(key=lambda x: x[-1], reverse=is_reverse) | ||
| 356 | |||
| 357 | self.build_month_sheet(card, month_mapping, ms, is_reverse) | ||
| 358 | |||
| 359 | # 4.删除原表 | ||
| 360 | for sheet in summary.get('sheet'): | ||
| 361 | self.remove(self.get_sheet_by_name(sheet)) | ||
| 362 | |||
| 363 | def license_rebuild(self, license_summary, document_scheme): | ||
| 364 | for classify, (_, name, field_order, side_diff, scheme_diff) in consts.LICENSE_ORDER: | ||
| 365 | license_list = license_summary.get(classify) | ||
| 366 | if not license_list: | ||
| 367 | continue | ||
| 368 | ws = self.create_sheet(name) | ||
| 369 | if scheme_diff and document_scheme == consts.DOC_SCHEME_LIST[1]: | ||
| 370 | classify = consts.MVC_CLASSIFY_SE | ||
| 371 | for license_dict in license_list: | ||
| 372 | if classify == consts.IC_CLASSIFY and license_dict.get('类别') == '1': | ||
| 373 | license_summary.setdefault(consts.RP_CLASSIFY, []).append(license_dict) | ||
| 374 | continue | ||
| 375 | if side_diff: | ||
| 376 | key, field_order_yes, field_order_no = consts.FIELD_ORDER_MAP.get(classify) | ||
| 377 | field_order = field_order_yes if key in license_dict else field_order_no | ||
| 378 | for search_field, write_field in field_order: | ||
| 379 | ws.append((write_field, license_dict.get(search_field, ''))) | ||
| 380 | ws.append((None, )) | ||
| 381 | |||
| 382 | def skip_img_sheet(self, skip_img): | ||
| 383 | if skip_img: | ||
| 384 | ws = self.create_sheet(consts.SKIP_IMG_SHEET_NAME) | ||
| 385 | ws.append(consts.SKIP_IMG_SHEET_HEADER) | ||
| 386 | for img_tuple in skip_img: | ||
| 387 | ws.append(img_tuple) | ||
| 388 | |||
| 389 | def rebuild(self, bs_summary, license_summary, skip_img, document_scheme): | ||
| 390 | self.bs_rebuild(bs_summary) | ||
| 391 | self.license_rebuild(license_summary, document_scheme) | ||
| 392 | self.skip_img_sheet(skip_img) |
| ... | @@ -15,11 +15,11 @@ from common import response | ... | @@ -15,11 +15,11 @@ from common import response |
| 15 | from common.mixins import GenericView | 15 | from common.mixins import GenericView |
| 16 | from common.tools.file_tools import file_write | 16 | from common.tools.file_tools import file_write |
| 17 | from common.redis_cache import redis_handler as rh | 17 | from common.redis_cache import redis_handler as rh |
| 18 | from .models import UploadDocRecords, DocStatus, PriorityApplication, GCAPRecords | 18 | from .models import UploadDocRecords, DocStatus, PriorityApplication, GCAPRecords, AFCComparisonInfo, HILComparisonInfo |
| 19 | from .mixins import DocHandler | 19 | from .mixins import DocHandler |
| 20 | from . import consts | 20 | from . import consts |
| 21 | from apps.account.authentication import OAuth2AuthenticationWithUser | 21 | from apps.account.authentication import OAuth2AuthenticationWithUser |
| 22 | from celery_compare.tasks import test | 22 | from celery_compare.tasks import compare |
| 23 | 23 | ||
| 24 | 24 | ||
| 25 | # restframework将request.body封装至request.data, webargs从request.data中获取参数 | 25 | # restframework将request.body封装至request.data, webargs从request.data中获取参数 |
| ... | @@ -312,8 +312,23 @@ class CompareView(GenericView): | ... | @@ -312,8 +312,23 @@ class CompareView(GenericView): |
| 312 | # pos上传比对信息接口 | 312 | # pos上传比对信息接口 |
| 313 | @use_args(compare_args, location='data') | 313 | @use_args(compare_args, location='data') |
| 314 | def post(self, request, args): | 314 | def post(self, request, args): |
| 315 | self.running_log.info('in') | 315 | # 存库 |
| 316 | test.apply_async((args, ), queue='queue_compare') | 316 | uniq_seq = args.get('uniqSeq') |
| 317 | business_type = args.get('applicationEntity') | ||
| 318 | application_id = args.get('applicationId') | ||
| 319 | comparison_class = HILComparisonInfo if business_type in consts.HIL_SET else AFCComparisonInfo | ||
| 320 | comparison_class.objects.create( | ||
| 321 | uniq_seq=uniq_seq, | ||
| 322 | application_id=application_id, | ||
| 323 | customer_type=args.get('customerType'), | ||
| 324 | application_version=args.get('applicationVersion'), | ||
| 325 | vehicle_status=args.get('vehicleStatus'), | ||
| 326 | individual_cus_info=None, | ||
| 327 | usedcar_info=None, | ||
| 328 | corporate_cus_info=None, | ||
| 329 | ) | ||
| 330 | # 触发比对 | ||
| 331 | compare.apply_async((application_id, business_type, uniq_seq, None), queue='queue_compare') | ||
| 317 | return response.ok() | 332 | return response.ok() |
| 318 | 333 | ||
| 319 | post.openapi_doc = ''' | 334 | post.openapi_doc = ''' | ... | ... |
| ... | @@ -8,4 +8,4 @@ broker = conf.CELERY_BROKER_URL | ... | @@ -8,4 +8,4 @@ broker = conf.CELERY_BROKER_URL |
| 8 | 8 | ||
| 9 | app = Celery('celery_compare', broker=broker, include=['celery_compare.tasks']) | 9 | app = Celery('celery_compare', broker=broker, include=['celery_compare.tasks']) |
| 10 | 10 | ||
| 11 | app.conf.update(worker_max_tasks_per_child=5, timezone='Asia/Shanghai') | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 11 | app.conf.update(worker_max_tasks_per_child=5, timezone='Asia/Shanghai') | ... | ... |
| ... | @@ -6,7 +6,12 @@ compare_log = logging.getLogger('compare') | ... | @@ -6,7 +6,12 @@ compare_log = logging.getLogger('compare') |
| 6 | 6 | ||
| 7 | 7 | ||
| 8 | @app.task | 8 | @app.task |
| 9 | def test(info): | 9 | def compare(application_id, application_entity, uniq_seq, ocr_res_id): |
| 10 | doc = AFCDoc.objects.filter(id=1).first() | 10 | # POS: application_id, application_entity, uniq_seq, None |
| 11 | compare_log.info(doc.id) | 11 | # OCR: application_id, business_type(application_entity), None, ocr_res_id |
| 12 | compare_log.info(info) | 12 | |
| 13 | # 根据application_id查找最新的比对信息,如果没有,结束 | ||
| 14 | # 分析比对信息,需要比对的license | ||
| 15 | # 根据application_id查找OCR累计结果指定license字段,如果没有,结束 | ||
| 16 | # 比对信息,将比对结果发送GCAP | ||
| 17 | pass | ... | ... |
src/common/tools/mail.py
deleted
100644 → 0
| 1 | import os | ||
| 2 | import smtplib | ||
| 3 | from email import encoders | ||
| 4 | from email.header import Header | ||
| 5 | from email.mime.base import MIMEBase | ||
| 6 | from email.mime.multipart import MIMEMultipart | ||
| 7 | from email.mime.text import MIMEText | ||
| 8 | |||
| 9 | MAIL_SERVER_HOST = 'smtp.exmail.qq.com' | ||
| 10 | MAIL_SERVER_PORT = 25 | ||
| 11 | |||
| 12 | TIME_OUT = 50 | ||
| 13 | |||
| 14 | |||
| 15 | class MailSender: | ||
| 16 | |||
| 17 | def __init__(self, sender, pwd): | ||
| 18 | self.sender = sender | ||
| 19 | self.pwd = pwd | ||
| 20 | self.server = smtplib.SMTP(timeout=TIME_OUT) | ||
| 21 | self.server.debuglevel = 0 | ||
| 22 | self.server.connect(host=MAIL_SERVER_HOST, | ||
| 23 | port=MAIL_SERVER_PORT,) | ||
| 24 | self.server.login(self.sender, self.pwd) | ||
| 25 | |||
| 26 | def close(self): | ||
| 27 | self.server.close() | ||
| 28 | |||
| 29 | def send(self, to_addrs, subject, content, file_list=[]): | ||
| 30 | msg = MIMEMultipart() | ||
| 31 | |||
| 32 | for att_file in file_list: | ||
| 33 | att = MIMEBase('application', 'octet-stream') | ||
| 34 | att.set_payload(open(att_file, 'rb').read()) | ||
| 35 | encoders.encode_base64(att) | ||
| 36 | att.add_header('Content-Disposition', | ||
| 37 | 'attachment', | ||
| 38 | filename=Header(os.path.basename(att_file), 'utf-8').encode()) | ||
| 39 | msg.attach(att) | ||
| 40 | |||
| 41 | msg['Subject'] = Header(subject, 'utf-8') | ||
| 42 | msg['From'] = self.sender | ||
| 43 | msg['To'] = ','.join(to_addrs) | ||
| 44 | |||
| 45 | content = u'Hi:<br><br>' + \ | ||
| 46 | content + \ | ||
| 47 | u'<br><br>祝好!<br><br><br>本邮件为系统自动发送,请勿直接回复!<hr>' | ||
| 48 | |||
| 49 | msg.attach(MIMEText(content.encode('utf-8'), 'html', 'utf-8')) | ||
| 50 | self.server.sendmail(self.sender, to_addrs, msg.as_string()) | ||
| 51 | # smtplib.SMTPServerDisconnected | ||
| 52 | |||
| 53 | |||
| 54 | # if __name__ == '__main__': | ||
| 55 | # mail_sender = MailSender() | ||
| 56 | # mail_sender.send(['1304057458@qq.com'], 'hello', 'world.', []) | ||
| 57 | # mail_sender.close() |
-
Please register or sign in to post a comment