"""扫描所有转账邮件,完成全部待入账转账""" env = request._run_ns debug(f'transfer_check.dspy: checking all mails') try: provider = env.PROVIDERS.get('transfer') if provider is None: return {"widgettype": "Message", "options": {"timeout": 3, "title": "错误", "message": "转账渠道未初始化"}} ec = EmailClient(provider.pop3server, provider.email, provider.password) count, _ = ec.stat() debug(f'transfer_check: got {count} mails') db = DBPools() dbname = get_module_dbname('unipay') processed = [] skipped = [] for i in range(count, 0, -1): try: mail = ec.get_mail(i) if mail.mailfrom != '95555@message.cmbchina.com': continue if not mail.body.startswith('动账业务通知'): continue data = provider.get_transfer_data(mail) if data is None: continue code = str(data.code) amount = data.amount debug(f'transfer_check: mail[{i}] code={code} amount={amount}') async with db.sqlorContext(dbname) as sor: recs = await sor.R('transfercode', {'tcode': code, 'status': '0'}) if len(recs) < 1: skipped.append(f'转账码{code} (已处理/不存在)') continue tc = recs[0] diff = abs(float(amount) - float(tc.amount)) if diff > 0.01: await sor.U('transfercode', {'id': tc.id, 'status': '9', 'remark': f'金额不匹配: 到账{amount} 期望{tc.amount}'}) skipped.append(f'转账码{code} (金额不匹配: {amount}≠{tc.amount})') continue biz_date = await env.get_business_date(sor) await sor.U('transfercode', {'id': tc.id, 'status': '1'}) recs2 = await sor.R('payment_log', {'id': tc.id, 'payment_status': '0'}) if len(recs2) > 0: plog = recs2[0] await env.recharge_accounting(sor, plog.customerid, 'RECHARGE', plog.id, biz_date, plog.amount_total, plog.pay_feerate) await sor.U('payment_log', { 'id': plog.id, 'payment_status': '1', 'payed_timestamp': timestampstr() }) processed.append(f'转账码{code} 到账{amount}元') except Exception as e2: debug(f'transfer_check: mail[{i}] error: {e2}') msg = f'处理完成: {len(processed)} 笔入账' if processed: msg += '\n' + '\n'.join(processed) if skipped: msg += '\n跳过: ' + ', '.join(skipped) return {"widgettype": "Message", "options": {"timeout": 5, "title": "转账检查结果", "message": msg}} except Exception as e: exception(f'transfer_check.dspy error: {e}') return {"widgettype": "Message", "options": {"timeout": 5, "title": "错误", "message": f"处理失败: {e}"}