From 22b1bbe5849d7928a50dfb3aef9b7a786819814a Mon Sep 17 00:00:00 2001 From: openclaw-314 Date: Sat, 8 Aug 2026 17:17:00 +0800 Subject: [PATCH] auto: sync OpenClaw config 2026-08-08 17:17 --- ...08112244---594d6278-1f39-4477-bc1c-0cea784c1f7a.xlsx | Bin 0 -> 14254 bytes .../e48ace9814f0-im-bot.context-tokens.json | 2 +- .../accounts/e48ace9814f0-im-bot.sync.json | 2 +- ...a2256aed2e9a395fe20ce5316511ff7a1.attested | 2 +- workspace-finances/MEMORY.md | 9 +++ workspace-finances/import_wangliping_july.py | 71 ++++++++++++++++++ workspace-finances/query_wlp_2026.py | 49 ++++++++++++ workspace-finances/query_wlp_heping.py | 37 +++++++++ workspace-finances/query_wlp_recurring.py | 48 ++++++++++++ workspace-finances/query_wlp_transfers.py | 23 ++++++ 10 files changed, 240 insertions(+), 3 deletions(-) create mode 100644 media/inbound/微信支付账单流水文件_20260701-20260731_20260808112244---594d6278-1f39-4477-bc1c-0cea784c1f7a.xlsx create mode 100644 workspace-finances/import_wangliping_july.py create mode 100644 workspace-finances/query_wlp_2026.py create mode 100644 workspace-finances/query_wlp_heping.py create mode 100644 workspace-finances/query_wlp_recurring.py create mode 100644 workspace-finances/query_wlp_transfers.py diff --git a/media/inbound/微信支付账单流水文件_20260701-20260731_20260808112244---594d6278-1f39-4477-bc1c-0cea784c1f7a.xlsx b/media/inbound/微信支付账单流水文件_20260701-20260731_20260808112244---594d6278-1f39-4477-bc1c-0cea784c1f7a.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..048e3343b35981a31fe71c07891018a2fc1b2384 GIT binary patch literal 14254 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 O;Ab${&bVBEKK(EJ=iJHw literal 0 HcmV?d00001 diff --git a/openclaw-weixin/accounts/e48ace9814f0-im-bot.context-tokens.json b/openclaw-weixin/accounts/e48ace9814f0-im-bot.context-tokens.json index 491a397..f29c033 100644 --- a/openclaw-weixin/accounts/e48ace9814f0-im-bot.context-tokens.json +++ b/openclaw-weixin/accounts/e48ace9814f0-im-bot.context-tokens.json @@ -1 +1 @@ -{"o9cq80w6ZnnPGItW-GGACkwd69bA@im.wechat":"AARzJWAFAAABAAAAAAAr3PqxbskjeYpnLxx1aiAAAAB+9905Q6UiugPBawU3n3cyzQX+LkN8ofRzsCZYN0mt7r8a9A/P+jazOZkC6OvTEXcIEtkOnVzYK4ml1u4NXP4xh0lm4TJa"} \ No newline at end of file +{"o9cq80w6ZnnPGItW-GGACkwd69bA@im.wechat":"AARzJWAFAAABAAAAAABDhnXp+HcBqTrwGd92aiAAAAB+9905Q6UiugPBawU3n3cyzQX+LkN8ofRzsCZYN0mt7kdOinFAoP67VCUjNL9AHsWrMsJukz0sfS1XeLn1+p0d/jUyg1h2"} \ No newline at end of file diff --git a/openclaw-weixin/accounts/e48ace9814f0-im-bot.sync.json b/openclaw-weixin/accounts/e48ace9814f0-im-bot.sync.json index 73b2af6..8c65319 100644 --- a/openclaw-weixin/accounts/e48ace9814f0-im-bot.sync.json +++ b/openclaw-weixin/accounts/e48ace9814f0-im-bot.sync.json @@ -1 +1 @@ -{"get_updates_buf":"ChAIOxDbydjL/TMYmp6chfYzEjplNDhhY2U5ODE0ZjBAaW0uYm90OjA2MDAwMGQ0ZmYwNzg5NWY2NDFlMmZjNmIzNGUzMzNkZDIwMjgx"} \ No newline at end of file +{"get_updates_buf":"ChAIQRCp+92C/jMYmp6chfYzEjplNDhhY2U5ODE0ZjBAaW0uYm90OjA2MDAwMGQ0ZmYwNzg5NWY2NDFlMmZjNmIzNGUzMzNkZDIwMjgx"} \ No newline at end of file diff --git a/workspace-attestations/bcbf8b4631832f347305c4974ee5a34a2256aed2e9a395fe20ce5316511ff7a1.attested b/workspace-attestations/bcbf8b4631832f347305c4974ee5a34a2256aed2e9a395fe20ce5316511ff7a1.attested index 051473c..1c16c47 100644 --- a/workspace-attestations/bcbf8b4631832f347305c4974ee5a34a2256aed2e9a395fe20ce5316511ff7a1.attested +++ b/workspace-attestations/bcbf8b4631832f347305c4974ee5a34a2256aed2e9a395fe20ce5316511ff7a1.attested @@ -1,4 +1,4 @@ openclaw-workspace-attestation:v1 -2026-07-30T01:34:39.891Z +2026-08-08T07:48:12.936Z generated:HEARTBEAT.md:ecce558615751a35aa173731e892ff3993f44bb4f5a1219c0a02994790c85528 generated:USER.md:e418ca9a680553b3ad8f54aecb0d403330810bb77826ab5251cc1dc13368fe16 diff --git a/workspace-finances/MEMORY.md b/workspace-finances/MEMORY.md index 9c1ef77..d7df40c 100644 --- a/workspace-finances/MEMORY.md +++ b/workspace-finances/MEMORY.md @@ -47,6 +47,15 @@ ## 2026年数据进展 +- **2026-07 汪礼平七月微信账单**(7/01–7/31,77笔) + - 支出74笔¥3,130.44 | 收入3笔¥610.00 + - 支出分类:餐饮/食品¥1,709.79 | 转账/红包¥900(杨小平400+老公200+红包给佳艳300)| 购物¥475.85(拼多多/抖音)| 其他¥40(三城寺香火5×10)| 交通¥4.8(铁塔能源) + - 单笔最大:红星扫码¥736(7/26,疑大宗采购) + - 收入:杨轩转账400、汪和平200、佳艳红包10 + - 主要支付方式:安徽农信储蓄卡(8043);零钱少量 + - 日常以菜市场/超市小摊为主(好想来、惠康、皖商、新皖韵),消费结构健康 + - 注:7/31 抖音@红星736已入餐饮分类,若属批量采购可复核 + - **2026-07-15**:导入杨轩2026上半年三张卡流水 - **工行交通卡2808**:64条流水,34笔外部支出¥3,774 - 火车票¥3,632 = 96%,滴滴¥101,共享单车¥15,停车费¥11,卡年费¥10 diff --git a/workspace-finances/import_wangliping_july.py b/workspace-finances/import_wangliping_july.py new file mode 100644 index 0000000..ef8f0c2 --- /dev/null +++ b/workspace-finances/import_wangliping_july.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +"""导入汪礼平2026年7月微信支付流水到 finances 数据库""" +import json, pymysql +from datetime import datetime + +cfg = json.load(open('db_config.json')) +conn = pymysql.connect(host=cfg['host'], port=cfg['port'], user=cfg['user'], + password=cfg['password'], database=cfg['database'], charset='utf8mb4') +cur = conn.cursor() + +MEMBER_ID = 1 # 汪礼平 + +def categorize(rec): + txn_type, peer, goods, direction = rec[1], rec[2], rec[3], rec[4] + # 转账/红包 + if '转账' in txn_type or '红包' in txn_type: + return '转账/红包' + if ('拼多多' in peer or '抖音' in peer): + return '购物' + # 超市/食品/生鲜/餐饮 + food_kw = ['超市', '生鲜', '好想来', '赵一鸣', '早餐', '早点', '包子', '米粉', + '豆腐', '猪肉', '水果', '果林', '食品', '金 华', '粥饼', '小铺', '餐厅'] + for kw in food_kw: + if kw in peer or (goods and kw in goods): + return '餐饮/食品' + # 交通/出行 + if '铁塔能源' in peer or '充电' in peer or '停车' in peer: + return '交通' + # 医疗 + if '药' in peer or '诊所' in peer or '医院' in peer: + return '医疗' + # 寺/香火/宗教 + if '寺' in peer: + return '其他' + # 其余扫码付款个人商户 -> 餐饮/食品(多数为买菜/小摊) + return '餐饮/食品' + +# 内嵌完整数据(来自会话消息) +DATA = __import__('json').loads(r'''{"headers":["交易时间","交易类型","交易对方","商品","收/支","金额(元)","支付方式","当前状态","交易单号","商户单号","备注"],"records":[["2026-07-31 19:55:44","商户消费","抖音电商商家","蟑螂蚂蚁通用杀蟑饵剂...","支出",7.9,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-31 17:52:25","商户消费","好想来","安庆宜秀区旺园小区店","支出",3.08,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-31 09:59:20","商户消费","安庆市宜秀区三城寺","安庆市宜秀区三城寺","支出",10,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-30 19:52:18","转账","杨小平 (杨平)","微信转账","支出",400,"零钱","对方已收钱","/","/","/"],["2026-07-30 19:51:14","转账","杨轩","微信转账","收入",400,"/","已存入零钱","/","/","/"],["2026-07-28 18:07:02","商户消费","拼多多平台商户","先用后付","支出",21.89,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-28 08:35:00","扫二维码付款","天顺1","二维码收款","支出",35,"安徽农信储蓄卡(8043)","已转账","/","/","/"],["2026-07-27 16:37:50","商户消费","抖音电商商家","保鲜膜套","支出",9.9,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-27 10:54:36","商户消费","贺强果林","巢尔苹果等","支出",21,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-26 10:13:36","扫二维码付款","丁韩燕","二维码收款","支出",35,"安徽农信储蓄卡(8043)","已转账","/","/","/"],["2026-07-26 09:43:19","商户消费","惠康超市","付款码支付","支出",5.22,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-26 09:34:33","扫二维码付款","红星","二维码收款","支出",736,"安徽农信储蓄卡(8043)","已转账","/","/","/"],["2026-07-25 09:59:06","商户消费","宜天鲜","宜天鲜生态农场直供会员店","支出",42,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-25 09:31:32","扫二维码付款","丁韩燕","二维码收款","支出",17,"安徽农信储蓄卡(8043)","已转账","/","/","/"],["2026-07-25 08:54:09","扫二维码付款","飘雪","二维码收款","支出",6,"安徽农信储蓄卡(8043)","已转账","/","/","/"],["2026-07-25 06:33:32","商户消费","粥饼小铺","/","支出",3.2,"零钱","支付成功","/","/","/"],["2026-07-24 09:53:38","扫二维码付款","梧桐","二维码收款","支出",4.3,"零钱","已转账","/","/","/"],["2026-07-24 07:34:44","微信红包","佳艳","/","收入",10,"/","已存入零钱","/","/","/"],["2026-07-23 14:09:03","扫二维码付款","潮贵金","二维码收款","支出",19.5,"安徽农信储蓄卡(8043)","已转账","/","/","/"],["2026-07-23 11:02:55","商户消费","安庆市宜秀区三城寺","安庆市宜秀区三城寺","支出",10,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-22 17:52:34","商户消费","铁塔能源有限公司安徽分公司","铁塔能源","支出",1.6,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-22 10:29:52","商户消费","皖商超市","付款码支付","支出",14.74,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-22 10:22:31","商户消费","杨爱美水果","杨爱美水果","支出",14.8,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-22 10:06:50","商户消费","赵一鸣","安庆市大观区辛增武食品经营部","支出",11.39,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-22 07:29:27","扫二维码付款","粱发兵","二维码收款","支出",3.5,"安徽农信储蓄卡(8043)","已转账","/","/","/"],["2026-07-22 07:28:25","商户消费","阿龙早点","/","支出",3.5,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-21 09:48:35","扫二维码付款","唐陶信","二维码收款","支出",5,"安徽农信储蓄卡(8043)","已转账","/","/","/"],["2026-07-21 08:07:24","扫二维码付款","晚星","二维码收款","支出",5,"安徽农信储蓄卡(8043)","已转账","/","/","/"],["2026-07-21 07:11:47","微信红包(单发)","发给佳艳","/","支出",100,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-21 07:11:23","微信红包(单发)","发给佳艳","/","支出",200,"零钱","支付成功","/","/","/"],["2026-07-20 18:24:05","转账","汪和平","微信转账","收入",200,"/","已存入零钱","/","/","/"],["2026-07-20 13:38:07","扫二维码付款","佰利鑫百货经营部丨宜秀店","二维码收款","支出",120,"安徽农信储蓄卡(8043)","已转账","/","/","/"],["2026-07-19 13:04:11","商户消费","抖音电商商家","染发膏","支出",19.9,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-19 12:51:50","商户消费","抖音电商商家","女包","支出",39.9,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-19 12:39:47","商户消费","抖音电商商家","百福缸钥匙扣","支出",9.9,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-19 10:01:54","扫二维码付款","桂林米粉","二维码收款","支出",15,"安徽农信储蓄卡(8043)","已转账","/","/","/"],["2026-07-18 08:53:07","商户消费","惠康超市","付款码支付","支出",111.6,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-17 10:01:57","扫二维码付款","轩记","二维码收款","支出",6.5,"安徽农信储蓄卡(8043)","已转账","/","/","/"],["2026-07-17 09:53:48","商户消费","惠康超市","付款码支付","支出",18.09,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-15 08:53:21","商户消费","惠康超市","付款码支付","支出",12.85,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-14 14:24:21","商户消费","浮生如梦","/","支出",5,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-14 08:35:53","扫二维码付款","天顺1","二维码收款","支出",35,"安徽农信储蓄卡(8043)","已转账","/","/","/"],["2026-07-13 17:37:41","商户消费","拼多多平台商户","先用后付","支出",130.9,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-13 17:37:24","商户消费","拼多多平台商户","先用后付","支出",108,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-13 17:21:38","扫二维码付款","老王","二维码收款","支出",25,"安徽农信储蓄卡(8043)","已转账","/","/","/"],["2026-07-13 17:15:33","商户消费","新皖韵生鲜超市","新皖韵生鲜超市","支出",32.3,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-13 11:28:13","商户消费","拼多多平台商户","先用后付","支出",3.76,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-13 10:55:45","扫二维码付款","晨曦","二维码收款","支出",35,"安徽农信储蓄卡(8043)","已转账","/","/","/"],["2026-07-13 10:41:19","商户消费","惠康超市","付款码支付","支出",19.81,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-13 08:16:16","商户消费","好想来","安庆宜秀区旺园小区店","支出",7.2,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-12 09:19:57","商户消费","安庆市宜秀区三城寺","安庆市宜秀区三城寺","支出",10,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-12 08:59:30","扫二维码付款","小高精品水果专卖","二维码收款","支出",29,"安徽农信储蓄卡(8043)","已转账","/","/","/"],["2026-07-12 07:59:09","转账","老公 (自然而然)","微信转账","支出",200,"安徽农信储蓄卡(8043)","对方已收钱","/","/","/"],["2026-07-12 07:38:12","扫二维码付款","老奶奶包子","二维码收款","支出",4.5,"安徽农信储蓄卡(8043)","已转账","/","/","/"],["2026-07-10 14:09:12","商户消费","拼多多平台商户","先用后付","支出",66,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-10 07:50:04","扫二维码付款","飘雪","二维码收款","支出",7,"安徽农信储蓄卡(8043)","已转账","/","/","/"],["2026-07-10 06:15:00","商户消费","二子","/","支出",7.2,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-09 11:35:54","商户消费","拼多多平台商户","先用后付","支出",39.9,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-09 07:51:39","扫二维码付款","梦想成真","二维码收款","支出",12,"安徽农信储蓄卡(8043)","已转账","/","/","/"],["2026-07-08 07:44:21","商户消费","赵一鸣","安庆市大观区辛增武食品经营部","支出",26.85,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-07 12:27:56","商户消费","拼多多平台商户","先用后付","支出",17.9,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-07 09:03:54","扫二维码付款","海之星游泳馆","二维码收款","支出",52,"安徽农信储蓄卡(8043)","已转账","/","/","/"],["2026-07-07 08:42:39","商户消费","金色华联购物中心","金色华联购物中心-大发店","支出",4.08,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-07 08:11:31","扫二维码付款","韩亚红","二维码收款","支出",2,"安徽农信储蓄卡(8043)","已转账","/","/","/"],["2026-07-06 11:10:18","商户消费","铁塔能源有限公司安徽分公司","铁塔能源","支出",1.6,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-06 07:41:19","商户消费","安庆小俩口(老面包子铺)","/","支出",6,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-05 10:50:23","扫二维码付款","乐乐奶奶","二维码收款","支出",10.7,"安徽农信储蓄卡(8043)","已转账","/","/","/"],["2026-07-05 10:46:18","扫二维码付款","平","二维码收款","支出",8.5,"安徽农信储蓄卡(8043)","已转账","/","/","/"],["2026-07-05 10:44:52","扫二维码付款","枞阳手工豆腐","二维码收款","支出",6,"安徽农信储蓄卡(8043)","已转账","/","/","/"],["2026-07-05 10:43:30","扫二维码付款","平","二维码收款","支出",11,"安徽农信储蓄卡(8043)","已转账","/","/","/"],["2026-07-05 10:41:52","扫二维码付款","晨曦","二维码收款","支出",26,"安徽农信储蓄卡(8043)","已转账","/","/","/"],["2026-07-03 10:19:40","商户消费","铁塔能源有限公司安徽分公司","铁塔能源","支出",1.6,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-03 10:00:53","商户消费","安庆安广顺电子商务有限公司","皖商超市","支出",22.93,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-02 10:27:07","扫二维码付款","卖菜朱女","二维码收款","支出",20,"安徽农信储蓄卡(8043)","已转账","/","/","/"],["2026-07-02 09:10:20","商户消费","安庆市宜秀区三城寺","安庆市宜秀区三城寺","支出",10,"安徽农信储蓄卡(8043)","支付成功","/","/","/"],["2026-07-01 10:10:59","扫二维码付款","思伟(皖味粉丝煲)","二维码收款","支出",12,"安徽农信储蓄卡(8043)","已转账","/","/","/"],["2026-07-01 08:53:07","商户消费","好想来","安庆宜秀区旺园小区店","支出",13.45,"安徽农信储蓄卡(8043)","支付成功","/","/","/"]]}''') + +def parse_dt(s): + return datetime.strptime(s, '%Y-%m-%d %H:%M:%S') + +inc_count = exp_count = 0 +inc_sum = 0.0 +exp_sum = 0.0 +cat_tot = {} + +for rec in DATA['records']: + dt = parse_dt(rec[0]) + direction = rec[4] + amount = float(rec[5]) + note = f"[微信] {rec[1]}|{rec[2]}|{rec[3] or '/'}" + if direction == '收入': + source = rec[2] + cur.execute("INSERT INTO income_records (member_id, source, amount, frequency, recorded_date, note) VALUES (%s,%s,%s,%s,%s,%s)", + (MEMBER_ID, source, amount, '一次性', dt.date(), note)) + inc_count += 1; inc_sum += amount + elif direction == '支出': + cat = categorize(rec) + cur.execute("INSERT INTO variable_expenses (member_id, category, amount, recorded_date, note) VALUES (%s,%s,%s,%s,%s)", + (MEMBER_ID, cat, amount, dt.date(), note)) + exp_count += 1; exp_sum += amount + cat_tot[cat] = cat_tot.get(cat, 0) + amount + +conn.commit() +print(f"收入 {inc_count} 笔, {inc_sum:.2f}") +print(f"支出 {exp_count} 笔, {exp_sum:.2f}") +print("分类:", {k: round(v,2) for k,v in sorted(cat_tot.items(), key=lambda x:-x[1])}) +conn.close() diff --git a/workspace-finances/query_wlp_2026.py b/workspace-finances/query_wlp_2026.py new file mode 100644 index 0000000..90ff7eb --- /dev/null +++ b/workspace-finances/query_wlp_2026.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +"""分析汪礼平2026年(1-7月)转账/红包往来""" +import json, pymysql, re +from collections import defaultdict +cfg = json.load(open('db_config.json')) +conn = pymysql.connect(host=cfg['host'], port=cfg['port'], user=cfg['user'], + password=str(cfg['password']), database=cfg['database'], charset='utf8mb4') +cur = conn.cursor() + +cur.execute(""" + SELECT recorded_date, amount, note FROM variable_expenses + WHERE member_id=1 AND recorded_date BETWEEN '2026-01-01' AND '2026-07-31' + AND (category='转账/红包' OR category LIKE '%红包%' OR note LIKE '%微信转账%' OR note LIKE '%微信红包%') + ORDER BY recorded_date +""") +rows = cur.fetchall() + +def peer_of(note): + parts = [p.strip() for p in note.replace('[微信] ', '').split('|')] + if len(parts) >= 2: + return parts[1] + return '(未知)' + +by_peer_month = defaultdict(set) +by_peer_total = defaultdict(float) +by_peer_count = defaultdict(int) +by_peer_amounts = defaultdict(list) + +for d, amt, note in rows: + p = peer_of(note) + m = d.strftime('%Y-%m') + a = float(amt) + by_peer_month[p].add(m) + by_peer_total[p] += a + by_peer_count[p] += 1 + by_peer_amounts[p].append((d.strftime('%m-%d'), a)) + +conn.close() + +print(f'2026年1-7月 转账/红包共 {len(rows)} 笔\n') +cands = [(by_peer_count[p], by_peer_total[p], p, sorted(by_peer_month[p]), by_peer_amounts[p]) + for p in by_peer_month] +cands.sort(key=lambda x: (-x[1])) +print('=== 按累计金额排序 ===') +for cnt, tot, p, months, amts in cands: + print(f'\n◆ {p} | {cnt}笔 | 累计 ¥{tot:,.0f} | {len(months)}个月 {months}') + details = '、'.join(f'{d}¥{a:.0f}' for d, a in amts) + print(f' 明细: {details}') diff --git a/workspace-finances/query_wlp_heping.py b/workspace-finances/query_wlp_heping.py new file mode 100644 index 0000000..c90f9f8 --- /dev/null +++ b/workspace-finances/query_wlp_heping.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +"""查询汪礼平与汪和平相关的全部转账/红包/收支记录""" +import json, pymysql +cfg = json.load(open('db_config.json')) +conn = pymysql.connect(host=cfg['host'], port=cfg['port'], user=cfg['user'], + password=cfg.get('password'), database=cfg['database'], charset='utf8mb4') +cur = conn.cursor() + +# 支出方向(微信转出给汪和平) +print('=== 汪礼平 → 汪和平(支出/转出) ===') +cur.execute(""" + SELECT recorded_date, amount, note FROM variable_expenses + WHERE member_id=1 AND note LIKE '%汪和平%' ORDER BY recorded_date +""") +for d, a, n in cur.fetchall(): + print(f' {d} ¥{float(a):>9.2f} {"支出" if "支出" in n else "转出"} {n}') + +# 收入方向(汪和平转入→汪礼平) +print() +print('=== 汪和平 → 汪礼平(收入/转入) ===') +cur.execute(""" + SELECT recorded_date, amount, source, note FROM income_records + WHERE member_id=1 AND (source LIKE '%汪和平%' OR note LIKE '%汪和平%') ORDER BY recorded_date +""") +rows = cur.fetchall() +if rows: + for d, a, s, n in rows: + print(f' {d} ¥{float(a):>9.2f} {"收入" if "收入" in n else "转入"} 来源:{s} {n}') +else: + # income_records 可能没有汪和平相关,检查所有收入 + cur.execute("SELECT recorded_date, amount, source, note FROM income_records WHERE member_id=1 ORDER BY recorded_date") + print(' (income_records 中未匹配,全部收入记录如下:)') + for d, a, s, n in cur.fetchall(): + print(f' {d} ¥{float(a):>9.2f} 来源:{s} {n or ""}') + +conn.close() diff --git a/workspace-finances/query_wlp_recurring.py b/workspace-finances/query_wlp_recurring.py new file mode 100644 index 0000000..05662cc --- /dev/null +++ b/workspace-finances/query_wlp_recurring.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +"""分析汪礼平跨月重复的转账/红包对象""" +import json, pymysql, re +from collections import defaultdict +cfg = json.load(open('db_config.json')) +conn = pymysql.connect(host=cfg['host'], port=cfg['port'], user=cfg['user'], + password=str(cfg['password']), database=cfg['database'], charset='utf8mb4') +cur = conn.cursor() + +cur.execute(""" + SELECT recorded_date, amount, note FROM variable_expenses + WHERE member_id=1 AND (category='转账/红包' OR category LIKE '%红包%' OR note LIKE '%微信转账%' OR note LIKE '%微信红包%') +""") +rows = cur.fetchall() + +def peer_of(note): + # note 形如 [微信] 转账|对方名|备注 或 转账 | 对方 | 备注 + parts = [p.strip() for p in note.replace('[微信] ', '').split('|')] + if len(parts) >= 2: + return parts[1] + m = re.search(r'转账\s*[:|]\s*([^|\s]+)', note) + return None + +# 按对方+月份统计 +by_peer_month = defaultdict(set) # peer -> set of 'YYYY-MM' +by_peer_total = defaultdict(float) +by_peer_count = defaultdict(int) + +for d, amt, note in rows: + p = peer_of(note) + if not p: + p = '(未知)' + month = d.strftime('%Y-%m') + by_peer_month[p].add(month) + by_peer_total[p] += float(amt) + by_peer_count[p] += 1 + +# 按月数排序,找出跨月重复的 +print('=== 转账对象出现月份数(>=2个月视为规律性) ===') +multi = [] +for p, months in by_peer_month.items(): + if len(months) >= 2: + multi.append((len(months), by_peer_count[p], by_peer_total[p], p, sorted(months))) +multi.sort(key=lambda x: (-x[0], -x[2])) +for nmon, ncnt, tot, p, months in multi: + print(f' {p:16s} 出现{nmon}个月共{ncnt}笔 累计¥{tot:.0f} 月:{months}') +conn.close() diff --git a/workspace-finances/query_wlp_transfers.py b/workspace-finances/query_wlp_transfers.py new file mode 100644 index 0000000..06029d3 --- /dev/null +++ b/workspace-finances/query_wlp_transfers.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +import json, pymysql +cfg = json.load(open('db_config.json')) +conn = pymysql.connect(host=cfg['host'], port=cfg['port'], user=cfg['user'], + password=str(cfg['password']), database=cfg['database'], charset='utf8mb4') +cur = conn.cursor() + +# 汪礼平所有转账/红包类支出 +cur.execute(""" + SELECT recorded_date, amount, note FROM variable_expenses + WHERE member_id=1 AND (category='转账/红包' OR category LIKE '%红包%' OR note LIKE '%微信转账%' OR note LIKE '%微信红包%') + ORDER BY recorded_date +""") +rows = cur.fetchall() +print(f'共{len(rows)}笔转账/红包类记录:') +for r in rows: + print(f' {r[0]} {r[1]:>8.2f} {r[2]}') +print() + +cur.execute("SELECT MIN(recorded_date), MAX(recorded_date) FROM variable_expenses WHERE member_id=1") +print('汪礼平支出日期范围:', cur.fetchone()) +conn.close()