From 9ec5ffc0f1188d72178f2276f3cd030ca484a6ce Mon Sep 17 00:00:00 2001 From: hackrobot Date: Wed, 20 Mar 2024 19:10:14 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=B0=86flask=E6=94=B9=E9=80=A0?= =?UTF-8?q?=E6=88=90fastapi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- WXBotDemo.py | 6 +- __init__.py | 0 __pycache__/crud.cpython-312.pyc | Bin 0 -> 2352 bytes __pycache__/database.cpython-312.pyc | Bin 0 -> 575 bytes __pycache__/main.cpython-310.pyc | Bin 0 -> 584 bytes __pycache__/main.cpython-312.pyc | Bin 0 -> 15532 bytes __pycache__/models.cpython-312.pyc | Bin 0 -> 994 bytes __pycache__/planet.cpython-312.pyc | Bin 0 -> 13497 bytes __pycache__/schemas.cpython-312.pyc | Bin 0 -> 1063 bytes app.db | Bin 0 -> 12288 bytes crud.py | 41 ++++ database.py | 13 ++ kunpeng.db | Bin 0 -> 24576 bytes main.py | 321 +++++++++++++++++++++++++++ models.py | 22 ++ schemas.py | 28 +++ 16 files changed, 430 insertions(+), 1 deletion(-) create mode 100644 __init__.py create mode 100644 __pycache__/crud.cpython-312.pyc create mode 100644 __pycache__/database.cpython-312.pyc create mode 100644 __pycache__/main.cpython-310.pyc create mode 100644 __pycache__/main.cpython-312.pyc create mode 100644 __pycache__/models.cpython-312.pyc create mode 100644 __pycache__/planet.cpython-312.pyc create mode 100644 __pycache__/schemas.cpython-312.pyc create mode 100644 app.db create mode 100644 crud.py create mode 100644 database.py create mode 100644 kunpeng.db create mode 100644 main.py create mode 100644 models.py create mode 100644 schemas.py diff --git a/WXBotDemo.py b/WXBotDemo.py index 4bf2b94..e3421f7 100644 --- a/WXBotDemo.py +++ b/WXBotDemo.py @@ -25,8 +25,8 @@ def hello(): return json.dumps({"Code": 0}) +# 发送小程序模版,建议远程更新 def sendminiProgram(data, account_wxid, wxid, msgXml): - # 发送小程序 if data.get('isSender') != 1: root = ET.fromstring(msgXml) #xml-字符串形式 @@ -163,6 +163,10 @@ def kp(event_data): xml_msg.get('encryptusername'), xml_msg.get('ticket'), xml_msg.get('scene')) + newFriendWxid=xml_msg.get('alias') + # 将好友信息=>保存到数据库 + newFriendDict=WXBotService.get_friend_info(account_wxid, newFriendWxid) + elif msg_type == 42: # 42 名片消息 xml_msg = ET.fromstring(msg) kp_log = f'{type_str} 企业微信名片消息 {xml_msg.get("nickname")}({xml_msg.get("username")})' diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/__pycache__/crud.cpython-312.pyc b/__pycache__/crud.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d9b7e3e117fb82ede4d827ad58eff8a0960724e1 GIT binary patch literal 2352 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 SaOJn!5|&=w{R7yeO#cfDECmDr literal 0 HcmV?d00001 diff --git a/__pycache__/planet.cpython-312.pyc b/__pycache__/planet.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..971014e315f29ad853146e92c1a045716d2a27e5 GIT binary patch literal 13497 zcmeI3&2QX96u=We6%F*p9}t36sS;X`J^ol1XG7YGrVuD4saj~N)z~v$JF&fv?fuG) zk0S>ze27bLNc;x~ap%B)z!gfbm3r%mH{P{(yRO;LO0e-}rS-gdeq+!3dFJi-+56kM zb1O^m`89aV?#W9_fAC87Ssn?GUIyXYCA##<(qQ?*3!T@%(Aenv-fEXcvD*&T*TfoH z+i0v-`Lkm9ajV)c{`S&l5jg5inB|b988PZc%t{P_pLSlT7omWwBuR+n%uOHv zb5;c?Sq}`028q-0O@0Y6QZytX5g{bYCPuP8s!2%3byX!u=Nc^8iY{_VmMPJZrKPf} z*aXW2w33Xms$dDL7-JnuMWU*#N?21RiDKA`5yqesu>xNNI)p`4#UNu@Rlrh)wz3Ml zkc<>jMs>vHv}Z_x?pX?^Izomp+5gO`W0td__*7|F%(5u8!F?O6ur*bi>I!&P~i877F>vIPMTB5s|C5;m!Yq%pBkgJoHs~Bl zQWL{h)I_9`fXoo4 zY$`H9ayQDLP&W=eGDx|UlM^onX zEPVk=*1*VPjPd%N%U3pcH}5s#iHwkO`1iBmu;TP=q&47gT1;EA|=7V%szPv!cidsI6NU8`mV zLVVOr70obc2{N{J!mamqE?pgLUDpn`SclO1rFXY)-cWDpuBqMFwp$;&)}VWJw;Q@< zciXk19rQlgbqNka@9>IwE84zxd&lnIXocH&(>2BYtNUB~*FAkxP-V2y>o;vbS%-6- z@Ad7d?XOD+rE~d-E|+`8)6I~8b;e$CO)R(pW&Po{<|MwC9y2#yEk9uFkceHIh&8BL zj5bZ8tE8?YQ_@%+?yjj=XA;vCn-YoWlBnc&42s?y`jZ`Zjz?cPl<=Uns6W@GP_heY zEMOR(4TZ00^FULtYedp?3$ptbiJC6g;kiIMIZyl=xD<*ZEbja%hXRW= zSig2%i=`6?GAmP>Y=TvG4bu#`jLGbVQ2Fq=6~)T;$y+M9AHamU={ zZ?VAO$i(T!Rjrppft+RJc1gl~7RPYM!08lp)x=VOVhE=Rxg1Km3^{%MG#&b5DE!tu zPdBDd$z)lCCu4jgi;#nQ!l0V-X5`fvN^G%U7*7>GKPHt!$y7#` zkrWp%IhipiLV*#JK08b!Zz^TB3sdG$QU<5AX3cmoM(!grrKm$0FC-y81gh5Z=8%pB+06F(QeOAQTi=kdh*bQV^sNK}-Q@EK8^5Zj+pRzBRk&I9Fdl z(9xyg1yCMhb1C^Sw`Xi|J;mb{*!y%unN->f1vGsN=Tk&c4~M8{>>+AWE5xe4Mn;9q3RxAhE96wDRw1`S^$ImAG*_Xf zLRrh3myJC^`4*=nrP3V{AtsE6(wZDcp>)`YCOe@t1wEFvfQ^%sXTaj@C`tk<>w=AW zKwqR>x?_+@vk{0SQ7}lz5W02xCP$A^@JUC)-T?<=D3%ZBd{SvZar zZu+54P6(>i(inc@*>?Q!z-{s6QAdaPfnE z5{p4!1cy*ttc^0RdaX?jfY=1{1{L!+^4+4*%6E!pJAYc#oB5NXwU9q61MS7UTO!TV zN6l+5o^<*0rQnrDTi{h|`Vh>28f`<%b))q-nJ`Y)nW3{#&&h1hk(T-}X+Rt5k?={7 zMo08Y8JJ|frVFtBD-+_LnHiorn^OX7TP)d+4qkRWi!TC?ca*saM!Jj-)vHs!qBY*Q;GuG$R<0TM(1hE5>53XxGHK64XW&6^aZ! zaOd*vqTR`#|FN*W{0o683n?~S9cC^INs>kZSO222ky`2M)o1QTIYyiOKJe5FiB&K^ fO^oqZbmzR;#GMZ-=Loj*RU0qATmOw<)5ZP*e_{Ds literal 0 HcmV?d00001 diff --git a/app.db b/app.db new file mode 100644 index 0000000000000000000000000000000000000000..2c38aca97c479aa4a86225ef18eb16f3d636494c GIT binary patch literal 12288 zcmeI#K}*9h6bJC66Je9X-lUFjO zILRn}h@xZiyXH+7?{ihxbQvWgYi`Z*c2-o=YDteG9SlXf-tnz{}fB*y_009U<00Izz00bbg!2*7BHq`$c{D*Ng2tWV=5P$##AOHaf LKmY;|fB<9P5ExMN literal 0 HcmV?d00001 diff --git a/crud.py b/crud.py new file mode 100644 index 0000000..af462f3 --- /dev/null +++ b/crud.py @@ -0,0 +1,41 @@ +from sqlalchemy.orm import Session + +# from . import models, schemas +import models, schemas + + +# 通过id获取用户 +def get_user(db: Session, user_id: int): + return db.query(models.User).filter(models.User.id == user_id).first() + + +# 通过openId岔村用户 +def get_user_by_openId(db: Session, openId: str): + return db.query(models.User).filter(models.User.openId == openId).first() + + +# 分页查询-用户all +def get_users(db: Session, skip: int = 0, limit: int = 100): + return db.query(models.User).offset(skip).limit(limit).all() + + +# 创建用户 +# user:schemas.UserCreate +def create_user(db: Session, user:schemas.UserCreate): + db_user = models.User( + wxid=user.wxid, + openId=user.openId, + sex=user.sex, + country=user.country, + province=user.province, + sourceStr=user.sourceStr, + usertype=user.usertype, + nickname=user.nickname, + wxaccount=user.wxaccount, + remark=user.remark, + smallhead=user.smallhead, + ) + db.add(db_user) + db.commit() + db.refresh(db_user) + return db_user diff --git a/database.py b/database.py new file mode 100644 index 0000000..23bb2c2 --- /dev/null +++ b/database.py @@ -0,0 +1,13 @@ +from sqlalchemy import create_engine +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import sessionmaker + +SQLALCHEMY_DATABASE_URL = "sqlite:///./kunpeng.db" +# SQLALCHEMY_DATABASE_URL = "postgresql://user:password@postgresserver/db" + +engine = create_engine( + SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False} +) +SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) + +Base = declarative_base() \ No newline at end of file diff --git a/kunpeng.db b/kunpeng.db new file mode 100644 index 0000000000000000000000000000000000000000..efbb3973f2ba7896b76cd100aa7c3efea8d2ad22 GIT binary patch literal 24576 zcmeI&(Qnc~90%|g1`3l^Lk!`;hyOwQRuL!X$ zYhAUhYH8KhRJ$D?)xm7`^5lx+y7f5tRZt1`#<{g|zS!^lzG4KrAOHafKmY;|fB*y_ z009VGTi{bBTY6Tqzw)5ZW_;FF%bju5?X##S_(bwBFoA5%qt!Mgb@vVZKrTxoO_!Kd zvY8lMQA?X|m6FX?%S$dt%w%USFKiMLCCzJHY^zi%*=N4=KgR`3m9@A^yZX98m($4S zcwbGpO?RnB+-94&okrsk$>$cu-&eib+p4Dni3yWLI6MuQ=>9FDQ}@04yQ+6c_UIwm zegtBOd}>Dlb%=CU!T7sCqE*txNWKPrZrF7i- zK_>y8$kQ%yNi$BneAF&K3dY6snWxm*%j_-P^ZoE*&x%-Ft#CP+3ZKpt!;(h54ks+A zuS6m?OD6QfX&}Ws8JdXj3lDlM8H>WH=&_a*$)KK%oKIE~1Kt}3{&*#JI`ezxeUgKP zA`!!6BpUmp(J}K^rdw;et+rQHUk}o0QLokA-y;`4+d{sg*XAi_ns%nn&ujmQVITw` z009U<00Izz00bZa0SG_<0z{} zfB*y_009U<00Izz00bcL9}8sCj{PK+OP6zte-`Nb|LRBo*dPD_2tWV=5P$##AOHaf zKmY;|xWNK>eQj9(-{4Oemj(d{KmY;|fB*y_009U<00I!OEUf?WEr0+7AOHafKmY;| OfB*y_009Wxe1Sh!eKZUJ literal 0 HcmV?d00001 diff --git a/main.py b/main.py new file mode 100644 index 0000000..ca7325e --- /dev/null +++ b/main.py @@ -0,0 +1,321 @@ +from fastapi import Depends, FastAPI, HTTPException +from sqlalchemy.orm import Session + +# from . import crud, models, schemas +import crud, models, schemas +from database import SessionLocal, engine +# from .database import SessionLocal, engine + +import json +import os +import threading +import time + +from flask import request, Flask +try: + import xml.etree.cElementTree as ET +except ImportError: + import xml.etree.ElementTree as ET + +import WXBotService +from planet import planetXml +from lxml import etree +import xml.dom.minidom +from pydantic import BaseModel + + +models.Base.metadata.create_all(bind=engine) + +app = FastAPI() + + +# Dependency +def get_db(): + db = SessionLocal() + try: + yield db + finally: + db.close() + + +# 默认首页 +@app.get("/") +async def root(): + return {"message": "Hello World"} + + +# 创建用户 +@app.post("/users/") +# schemas.UserCreate决定了swagger文档 +def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)): + db_user = crud.create_user(db, user) + if db_user: + raise HTTPException(status_code=400, + detail="openId already registered") + return crud.create_user(db=db, user=user) + + +# 分页查询-用户 +@app.get("/users/") +def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)): + users = crud.get_users(db, skip=skip, limit=limit) + return users + + +# 根据openId查询用户 +@app.get("/users/{openId}") +def read_user(openId, db: Session = Depends(get_db)): + db_user = crud.get_user_by_openId(db, openId=openId) + if db_user is None: + raise HTTPException(status_code=404, detail="User not found") + return db_user + + +@app.get("/wxbot") +def helloget(q:dict): + data = q + t = threading.Thread(target=kp, args=(data, )) # 通过当前线程开启新的线程去执行 + t.start() + return json.dumps({"Code": 0}) + +@app.post("/wxbot") +# def hellopost(requestData:schemas.User): +def hellopost(requestData:dict): + + # data = request.get_json() + print('requestData---',requestData) + data = requestData + t = threading.Thread(target=kp, args=(data, )) # 通过当前线程开启新的线程去执行 + t.start() + return json.dumps({"Code": 0}) + + +# 发送小程序模版,建议远程更新 +def sendminiProgram(data, account_wxid, wxid, msgXml): + # 发送小程序 + if data.get('isSender') != 1: + root = ET.fromstring(msgXml) #xml-字符串形式 + + #打开xml文档 + # current_dir = os.path.dirname(os.path.abspath(__file__)) + # print('current_dir+/planet.xml',current_dir+'\planet.xml') + # tree = ET.parse(current_dir+'\planet.xml') + # root = tree.getroot() + + # 微信好友的wxid + # wxid='wxid_w2imh7ki5s4q12' + for pagepath in root.iter('pagepath'): + print(pagepath.text) # 打印名字 + pagepath.text = pagepath.text + f'?wxid={wxid}' + print('修改path', pagepath.text) # 打印名字 + + # 修改后的xml转成string , method='xml' + msgXml = ET.tostring(root, encoding='utf-8').decode('utf-8') + WXBotService.send_xml_message( + account_wxid, wxid, msgXml + # account_wxid, "wxid_w2imh7ki5s4q12", planetXml + ) + + +def kp(event_data): + # unicode [\\uxxxxx] 转 emoji 表情 + event_data = json.loads( + WXBotService.unicode_to_emoji( + json.dumps(event_data, ensure_ascii=False), 'json')) + + kp_log = '' # 定义鲲鹏日志消息 + event_type = event_data.get('event_type') #事件类型 + account_wxid = event_data.get('account_wxid') #机器人id + data = event_data.get('data') + msg_type = data.get('msgtype') #消息类型 + msg = data.get('content') + to_wxid = data.get('to_wxid') #发送给 + to_name = data.get('to_name') + filepath = data.get("filepath") + subtype = data.get('subtype') #类型 + thumbpath = data.get('thumbpath') #图片,存在电脑绝对路径 + + wxid = data.get('final_from_wxid') #消息来源用户 + wx_name = data.get('final_from_name') + + group = None if data.get('from_wxid') == wxid else data.get('from_wxid') + group_name = None if data.get('from_name') == wx_name else data.get( + 'from_name') + '''event类型判断''' + if event_type == 1001: # 1001 创建WeChat进程成功,通讯连接成功 + kp_log = f'创建WeChat进程成功,通讯连接成功' + elif event_type == 1002: # 1002 登录成功 + kp_log = f'登录成功 {data.get("nickname")}({data.get("wxid")})' + elif event_type == 1003: # 1003 账号注销登录 + kp_log = f'账号注销登录 {data.get("wxid")} {data.get("reason")}' + elif event_type == 1004: # 1004 切换聊天对象事件 + kp_log = f'切换聊天对象事件 {data.get("nickname")}({data.get("wxid")})' + elif event_type == 1005: # 1005 切换联系人事件 + kp_log = f'切换联系人事件 {data.get("nickname")}({data.get("wxid")})' + elif event_type == 1007: # 1005 二维码刷新事件 + kp_log = f'二维码刷新事件 {data.get("qrcode")}' + elif event_type == 1008: # 1008 连接断开 + kp_log = f'连接断开' + elif event_type == 1009: # 1009 群员退群通知 + member_list = [] + for member in data.get('memberlist'): + member_list.append( + f'{member.get("nickname")}({member.get("wxid")})') + kp_log = f'群员退群通知 {",".join(member_list)} 退出了群聊 {data.get("roomname")}({data.get("roomid")}) ' \ + f'人数:{data.get("membercount")}' + elif event_type == 1010: # 1010 群员进群通知 + member_list = [] + for member in data.get('memberlist'): + member_list.append( + f'{member.get("nickName")}({member.get("userName")})') + kp_log = f'群员进群通知 {",".join(member_list)} 加入了群聊 {data.get("roomname")}({data.get("roomid")})' + elif event_type == 1011: # 1011 收款消息 + pay_msg = ET.fromstring(msg).find('paymsg') + pay_msg_type = pay_msg.findtext('PayMsgType') + if pay_msg_type == '9': # 二维码收款 + status = pay_msg.findtext('status') + username = pay_msg.findtext('username') + display_name = pay_msg.findtext('displayname') + fee = pay_msg.findtext('fee') + if status == '0': + kp_log = f'收款消息 {display_name}({username}) 扫描收款二维码' + elif status == '1': + kp_log = f'收款消息 {display_name}({username}) 付款成功 {int(fee) / 100} 元' + elif status == '2': + kp_log = f'收款消息 {display_name}({username}) 取消付款' + elif pay_msg_type == '45': # 貌似有未收款转账或转账红包过期会触发 42 和 45 类型 + pass # kp_log = f'收款消息 {pay_msg.findtext("fromusername")} {pay_msg.findtext("content")}' + elif event_type == 1040: # 1040 撤回消息事件 + if not group: + kp_log = f'撤回消息事件 {wx_name}({wxid}) 撤回了 {msg}' + else: + kp_log = f'撤回消息事件 {wx_name}({wxid}) 从群 {group_name}({group}) 撤回了 {msg}' + elif event_type == 1100: # 1100 同步消息 + if group: + type_str = f'同步消息 群聊消息 群聊:{group_name}({group}) 发送者:{wx_name}({wxid})' + elif 'gh_' in wxid: + type_str = f'同步消息 公众号消息 {wx_name}({wxid})' + elif '@openim' in wxid: + type_str = f'同步消息 企业微信消息 {wx_name}({wxid})' + else: + type_str = f'同步消息 私聊消息 {wx_name}({wxid})' + + if data.get('isSender') == 1: + # 手机发送还是电脑发送这里判断不是很准确 + if to_wxid == account_wxid: + type_str = f'机器人手机端 发送的 ' + type_str + else: + type_str = f'机器人电脑端 发送的 ' + type_str + + if msg_type == 1: # 1 文本消息/自带表情 + kp_log = f'{type_str} 文本消息 内容:{msg}' + elif msg_type == 3: # 3 图片消息 + kp_log = f'{type_str} 图片消息 内容:{filepath}' + # 本地dat图片解密 + decrypt_path = WXBotService.local_decrypt_image( + filepath, os.path.join(os.getcwd(), '解密图片')) + print(f'{type_str} 图片消息 解密路径:{decrypt_path}') + elif msg_type == 34: # 34 语言消息(需要在设置中打开语言自动转文字) + xml_msg = ET.fromstring(msg) + kp_log = f'{type_str} 语音消息 内容:{xml_msg.find("voicetrans").get("transtext")}' + elif msg_type == 37: # 37 好友请求 + xml_msg = ET.fromstring(msg) + kp_log = f'同步消息 好友请求 {xml_msg.get("fromnickname")}({xml_msg.get("fromusername")}) ' \ + f'验证内容:{xml_msg.get("content")}' + # 同意好友请求 + WXBotService.agree_friend_request(account_wxid, + xml_msg.get('alias'), + xml_msg.get('encryptusername'), + xml_msg.get('ticket'), + xml_msg.get('scene')) + newFriendWxid=xml_msg.get('alias') + # 将好友信息=>保存到数据库 + newFriendDict=WXBotService.get_friend_info(account_wxid, newFriendWxid) + + elif msg_type == 42: # 42 名片消息 + xml_msg = ET.fromstring(msg) + kp_log = f'{type_str} 企业微信名片消息 {xml_msg.get("nickname")}({xml_msg.get("username")})' + elif msg_type == 43: # 43 视频消息 + kp_log = f'{type_str} 视频消息 内容:{filepath}' + elif msg_type == 47: # 47 表情包 + kp_log = f'{type_str} 表情包消息 网址:{ET.fromstring(msg).find("emoji").get("cdnurl".replace("amp;", ""))}' + # 本地下载图片 + down_path = WXBotService.local_download_image( + msg, os.path.join(os.getcwd(), '下载图片')) + print(f'{type_str} 表情包消息 下载路径:{down_path}') + elif msg_type == 48: # 48 地理位置 + kp_log = f'{type_str} 地理位置 内容:{msg}' + + elif msg_type == 49: # 49 xml消息 + # 获取根节点 + root = ET.fromstring(msg) + xml_appmsg = root.find('appmsg') + + xml_title = xml_appmsg.findtext('title') + xml_type = xml_appmsg.findtext('type') + xml_des = xml_appmsg.findtext('des') + xml_url = xml_appmsg.findtext('url') + + if xml_type == '1': # 1 文本 + kp_log = f'收到 {wxid} xml文本消息' + elif xml_type == '3': # 3 歌曲 + kp_log = f'{type_str} 音乐消息 歌曲:{xml_title} 歌手:{xml_des} 网址:{xml_url}' + elif xml_type == '5': # 5 链接 + kp_log = f'{type_str} 链接消息 标题:{xml_title} 内容:{xml_des} 网址:{xml_url}' + print("kp_log--------------------------------", msg) + # 本身也是系统消息-link,会无线循环 + # 判断是不是自己发的消息 + # if data.get('isSender') != 1: + # WXBotService.send_link_message( + # account_wxid, "wxid_w2imh7ki5s4q12", "title", "dec", + # "https://www.baidu.com", + # "https://p1-q.mafengwo.net/s17/M00/E3/9C/CoUBXl_cawCAQWMcAAGGhEoBcRU77.jpeg") + + elif xml_type == '6': # 6 文件 + kp_log = f'{type_str} 文件消息 文件名:{xml_title} 文件大小:{xml_des} 文件路径:{filepath}' + elif xml_type == '19': # 19 合并转发聊天记录 + kp_log = f'{type_str} 合并转发聊天记录 文件名:{xml_title} 文件大小:{xml_des} 文件路径:{filepath}' + elif xml_type == '33': # 33 小程序 + kp_log = f'{type_str} 小程序消息 小程序名:{xml_appmsg.findtext("sourcedisplayname")} 标题:{xml_title} ' \ + f'appid:{xml_appmsg.findtext("weappinfo/appid")} ' \ + f'pagepath:{xml_appmsg.findtext("weappinfo/pagepath")}' + print("---------------------------kp_log", msg) + # 发送小程序 + sendminiProgram(data, account_wxid, wxid, planetXml) + + elif xml_type == '57': # 引用消息 + kp_log = f'{type_str} 引用消息 内容:{msg}' + elif xml_type == '2000': # 2000 转账消息 + money = xml_appmsg.findtext('wcpayinfo/feedesc').replace( + '¥', '') + pay_subtype = xml_appmsg.findtext('wcpayinfo/paysubtype') + transfer_id = xml_appmsg.findtext('wcpayinfo/transferid') + if pay_subtype == '1': + kp_log = f'{type_str} 转账消息 {money} 元' + # 自动接收转账 + WXBotService.transfer_receipt(account_wxid, wxid, + transfer_id) + elif pay_subtype == '3': + kp_log = f'{type_str} 已收款 {money} 元 转账' + elif msg_type == 66: # 66 企业微信名片消息 + xml_msg = ET.fromstring(msg) + kp_log = f'企业微信名片消息 {xml_msg.get("nickname")}({xml_msg.get("username")})' + elif msg_type == 10000: # 10000 系统消息 + kp_log = f'系统消息 {wx_name}({wxid}) {msg}' + + #获取通讯录 + # allFriends=WXBotService.get_address_list(account_wxid) + # print('allFriends',allFriends) + # 发送H5链接 + + if not kp_log: + print( + '====================================================================================' + ) + print(event_data) + print( + '====================================================================================' + ) + else: + print(kp_log) + diff --git a/models.py b/models.py new file mode 100644 index 0000000..7bc5a26 --- /dev/null +++ b/models.py @@ -0,0 +1,22 @@ +from sqlalchemy import Boolean, Column, ForeignKey, Integer, String +from sqlalchemy.orm import relationship + +from database import Base +# from .database import Base + +class User(Base): + __tablename__ = "users" + + id = Column(Integer, primary_key=True) + wxid = Column(String) + openId = Column(String) + sex = Column(String) #性别 + country = Column(String) #"CN" + province = Column(String) #"Hubei" + sourceStr = Column(String) #:"通过朋友验证消息添加" + usertype = Column(String) + nickname = Column(String) #昵称 + wxaccount = Column(String) #微信号 + remark = Column(String) #备注 + smallhead = Column(String) #头像 + diff --git a/schemas.py b/schemas.py new file mode 100644 index 0000000..d7c3fab --- /dev/null +++ b/schemas.py @@ -0,0 +1,28 @@ +from pydantic import BaseModel + + + + +# 用户信息 +class UserCreate(BaseModel): + password: str + wxid: str + openId: str + sex: str + country: str + province: str + sourceStr: str + usertype: str + nickname: str + wxaccount: str + remark: str + smallhead: str + + + +class User(UserCreate): + id: int + is_active: bool + + class Config: + orm_mode = True \ No newline at end of file