From dd4383130d54e8076ca617596cbf912b3a515c35 Mon Sep 17 00:00:00 2001 From: doudou201703 <84085676+doudou201703@users.noreply.github.com> Date: Fri, 21 Aug 2026 23:48:29 +0800 Subject: [PATCH] six_005 --- django_app/views.py | 6 +- django_app/小程序发券接口.py | 2 + .../小程序用户地址定位地图路由列表.py | 3 +- .../接收微信的code回调.py | 16 +-- django_邮件/邮件发送工具包.py | 10 +- sixGuoDjango/urls.py | 2 +- .../小程序前端分享页面/主面分享页面接口.py | 6 +- .../小程序用户的位置接口.py | 1 - wechat_token/token工具包.py | 18 +-- .../六果公司支付类.py | 131 ++++++++++++------ .../小程序用户接口/小程序用户登陆接口.py | 5 +- wechat_接口/微信支付接口/微信支付测试接口.py | 89 ++---------- wechat_数据库/用户数据库/小程序登陆用户.py | 33 ++--- wechat_项目工具包/企业微信工具包/客户管理.py | 10 -- .../小程序管理后API/非对称密钥私钥.txt | 27 ---- .../微信支付工具包/微信支付类.py | 8 +- .../数据库的工具包/更新用户积分.py | 3 - wechat_项目授权/企业微信消息服务器授权接口.py | 5 +- 数据库初始化.py | 24 ++++ 测试数据库.py | 21 +-- 20 files changed, 179 insertions(+), 241 deletions(-) delete mode 100644 wechat_项目工具包/小程序管理后API/非对称密钥私钥.txt diff --git a/django_app/views.py b/django_app/views.py index 1191273..a528511 100644 --- a/django_app/views.py +++ b/django_app/views.py @@ -16,7 +16,6 @@ from rest_framework.viewsets import ViewSet from django_jwt_token.jwt认证接口 import Jwt身份认证 from sixGuoDjango import BaseResponse, ResData, redis_5 -from wechat_token.token工具包 import sixToken default_channel_layer = cast(BaseChannelLayer, get_channel_layer(alias="default")) @@ -37,7 +36,7 @@ def sync_lock(lock): class DemoXiaoViewSets(ViewSet): - lock = threading.Lock() # 所有请求 共享这一个 lock对象 + lock_sync_lock = threading.Lock() # 所有请求 共享这一个 lock对象 @action(detail=False, methods=["get", "post", "put", "delete"], url_path="zizi") def 只用于初始化项目测试接口(self, request: Request): @@ -103,7 +102,8 @@ class DemoXiaoViewSets(ViewSet): @action(detail=False, methods=["get", "post", "put", "delete"], url_path="中文", ) def 中文(self, request: Request): xiaozizi = request.data.get("xiaozizi", None) - return Response(data={"msg": xiaozizi}) + print(xiaozizi) + return Response(data={"data_uri": "0909090"}, status=status.HTTP_200_OK) DemoXiaoViewSetsDemoRouter = DefaultRouter() diff --git a/django_app/小程序发券接口.py b/django_app/小程序发券接口.py index 81d2bf2..1f4758c 100644 --- a/django_app/小程序发券接口.py +++ b/django_app/小程序发券接口.py @@ -45,12 +45,14 @@ class 小程序发优惠券到钱包接口ViewSets(ViewSet): # 查询数据库,看看用户当前有没有券已发了但是还没有领取的状态 # stock发券数据 = stock发送代金券功能(stock_id_代金券批次号="22512292").send发券并返回前端需要的数据() stock发券数据 = stock发送代金券功能(stock_id_代金券批次号="22625737", stock券的状态="待领券").send发券并返回前端需要的数据(self_mini_openid=self_mini_openid, self_mini_unionid=self_mini_unionid) + print(stock发券数据) # 4. 生成签名 # return Response(data=stock发券数据) return Response(data={"stock券状态": "待领券", "stock领券数据": stock发券数据}) else: pass print("查询是这里生效了啦") + print({"stock券状态": stock查询数据.stock_use_券状态, "stock领券数据": stock查询数据.stock_未领取券的数据}) return Response(data={"stock券状态": stock查询数据.stock_use_券状态, "stock领券数据": stock查询数据.stock_未领取券的数据}) @action(detail=False, methods=["get", "post", "put", "delete"], url_path="领券后更新当前券的状态") diff --git a/django_routes/小程序用户地址定位地图路由列表.py b/django_routes/小程序用户地址定位地图路由列表.py index 94e5aa9..11dbb31 100644 --- a/django_routes/小程序用户地址定位地图路由列表.py +++ b/django_routes/小程序用户地址定位地图路由列表.py @@ -5,5 +5,4 @@ from wechat_mini_服务端接口目录.小程序用户地址定位.小程序用 小程序用户地址定位地图Router = DefaultRouter() 小程序用户地址定位地图Router.register(prefix="delivery", viewset=用户配送地址ViewSets, basename="用户配送地址ViewSets") -小程序用户地址定位地图Router.register(prefix="map", viewset=小程序用户的位置接口ViewSets, - basename="小程序用户的位置接口ViewSets") +小程序用户地址定位地图Router.register(prefix="map", viewset=小程序用户的位置接口ViewSets, basename="小程序用户的位置接口ViewSets") diff --git a/django_web_微信开放平台应用用户登陆/接收微信的code回调.py b/django_web_微信开放平台应用用户登陆/接收微信的code回调.py index 6768a6c..09bc3df 100644 --- a/django_web_微信开放平台应用用户登陆/接收微信的code回调.py +++ b/django_web_微信开放平台应用用户登陆/接收微信的code回调.py @@ -26,9 +26,9 @@ def sync_lock_线程锁(lock): def wrapper(*args, **kwargs): with lock: return fn(*args, **kwargs) - + return wrapper - + return decorator @@ -39,10 +39,9 @@ class AllowMyAppRedirect(HttpResponseRedirect): class 接收微信的code回调ViewSets(ViewSet): lock = threading.Lock() private_key_pem_私钥 = Path(settings.BASE_DIR).joinpath("django_jwt_token/private.pem").read_bytes() - + def jwt_生成token(self, openid, uniond): # 读取私钥的 bytes字符串 - # 创建一个 JWT对象 jwt对象实例 = JWT() # 创建对象 # 创建 payload @@ -57,7 +56,7 @@ class 接收微信的code回调ViewSets(ViewSet): signing_key = jwk_from_pem(pem_content=私钥对象, ) token = jwt对象实例.encode(payload=message, key=signing_key, alg="RS256") return token - + def get网站授权access_token(self, code, state): uri = "https://api.weixin.qq.com/sns/oauth2/access_token" postData = requests.post(url=uri, params={ @@ -72,8 +71,9 @@ class 接收微信的code回调ViewSets(ViewSet): openid = pydash.get(obj=postData, path="openid") scope = pydash.get(obj=postData, path="scope") unionid = pydash.get(obj=postData, path="unionid") + print(postData, "00000000000000000000") return postData - + def get获取用户个人信息(self, code, state): uri = f"https://api.weixin.qq.com/sns/userinfo" token, is创建 = weitoken.objects.update_or_create(token_name="web_token") @@ -110,7 +110,7 @@ class 接收微信的code回调ViewSets(ViewSet): getData = requests.get(url=uri, params={"access_token": access_token, "openid": openid}) res = orjson.loads(getData.content.decode(encoding="utf-8")) return res - + @action(detail=False, methods=["get", ], url_path="get_code", ) # @sync_lock_线程锁( lock=lock ) def get_code(self, request: Request): @@ -126,7 +126,7 @@ class 接收微信的code回调ViewSets(ViewSet): openid = pydash.get(obj=user_info_用户信息, path="openid") unionid = pydash.get(obj=user_info_用户信息, path="unionid") print("为什么没有值了呢", openid, unionid) - token = self.jwt_生成token(openid=openid, uniond=unionid) + token = self.jwt_生成token(openid=openid, uniond=unionid) # 前端带着code进来, setData = pydash.set_(obj=user_info_用户信息, path="token", value=token) query_string = urlencode(setData, ) uri = f"myapp://open/home?{query_string}" diff --git a/django_邮件/邮件发送工具包.py b/django_邮件/邮件发送工具包.py index acb6ba9..688b909 100644 --- a/django_邮件/邮件发送工具包.py +++ b/django_邮件/邮件发送工具包.py @@ -267,12 +267,12 @@ html = """ # SMTP服务器: smtp.163.com -def send_email_bcc_only(emSubject主题, emBody内容, to_emails): +def send_email_bcc_only(emSubject主题, emBody内容, to_emails_收件人列表): """只有 BCC 收件人,TO 字段为空""" from_email = "792282@qq.com" password = "epagsnfwzrkrbgfa" display_name = "六果科技" - + msg = MIMEMultipart() msg["From"] = formataddr(pair=("免费小程序已送达", "792282@qq.com"), charset="utf-8") msg["To"] = "" # 不显示任何收件人(这时达成的效果, 也就是相当于秘密抄送,无需要显示就行了) @@ -283,12 +283,12 @@ def send_email_bcc_only(emSubject主题, emBody内容, to_emails): with smtplib.SMTP_SSL("smtp.qq.com", 465) as emServer: emServer.login(from_email, password) # ✅ 所有收件人都在 to_addrs 中,但不会显示在邮件头 - emServer.sendmail(from_email, to_emails, msg.as_string()) - print(f"邮件已密送给 {len(to_emails)} 位收件人") + emServer.sendmail(from_email, to_emails_收件人列表, msg.as_string()) + print(f"邮件已密送给 {len(to_emails_收件人列表)} 位收件人") except Exception as e: print(f"发送失败: {e}") # 使用 recipients = ["xiao@xiao.band", "13382551360@163.com"] -send_email_bcc_only(emSubject主题="数字化", emBody内容="邮件的内容", to_emails=["xiao@xiao.band", ]) +send_email_bcc_only(emSubject主题="数字化", emBody内容="邮件的内容", to_emails_收件人列表=["792282@qq.com", ]) diff --git a/sixGuoDjango/urls.py b/sixGuoDjango/urls.py index 7957696..6d595bb 100644 --- a/sixGuoDjango/urls.py +++ b/sixGuoDjango/urls.py @@ -43,7 +43,7 @@ from wechat_项目授权.服务号认证接口 import sixwechat # 注册子路由 urlpatterns = [ - path("api-auth/", include("rest_framework.urls")), + # path("api-auth/", include("rest_framework.urls")), path(route="six/", view=include(arg=业务订单接口ViewSetsViewSetsRouter.urls)), path(route="", view=htmlViewSets.as_view({"get": "home"})), # 项目首页 # path( route="lucky/", view=include( arg=拼团业务接口ViewSetsRouter.urls ) ), # 幸运拼团的业务demo接口 diff --git a/wechat_mini_服务端接口目录/小程序前端分享页面/主面分享页面接口.py b/wechat_mini_服务端接口目录/小程序前端分享页面/主面分享页面接口.py index b57fe18..0a1a79c 100644 --- a/wechat_mini_服务端接口目录/小程序前端分享页面/主面分享页面接口.py +++ b/wechat_mini_服务端接口目录/小程序前端分享页面/主面分享页面接口.py @@ -9,7 +9,7 @@ from sixGuoDjango import BaseResponse, ResData class 主页分享页面接口ViewSets(ViewSet): img_主页面分享时的图片 = "https://hudie.sixgou.com/six/aa35a95a5be61ba1bc38f856fabf3978.png" - + @action(detail=False, methods=["post", ], url_path="onShareAppMessage") def 主页群分享接口(self, request: Request): """""" @@ -31,13 +31,13 @@ class 主页分享页面接口ViewSets(ViewSet): } httpResData = BaseResponse(resData=ResData(listData=[""], dictData=messageData), ).model_dump() return Response(data=httpResData, status=status.HTTP_200_OK) - + @action(detail=False, methods=["post"], url_path="onShareTimeline") def 主页朋友圈分享的功能接口(self, request: Request): """""" self_mini_openid = request.data.get("self_mini_openid", None) self_mini_unionid = request.data.get("self_mini_unionid", None) - + page_path = request.data.get("page_path", None) # 如果需要携带参数, 需要在路由的后面 ? 添加 key=value的格式 messageData = { diff --git a/wechat_mini_服务端接口目录/小程序用户地址定位/小程序用户的位置接口.py b/wechat_mini_服务端接口目录/小程序用户地址定位/小程序用户的位置接口.py index 6704781..551fcdf 100644 --- a/wechat_mini_服务端接口目录/小程序用户地址定位/小程序用户的位置接口.py +++ b/wechat_mini_服务端接口目录/小程序用户地址定位/小程序用户的位置接口.py @@ -29,7 +29,6 @@ class 小程序用户的位置接口ViewSets(ViewSet): 经度 = pydash.get(obj=result, path="longitude") print("\n🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 用户的定位的数据", result) 地图解析结果 = wei地图工具.经纬度转换为地址(location=f"{纬度},{经度}") - print(地图解析结果, "=============") 省 = pydash.get(obj=地图解析结果, path="result.address_component.province") 市 = pydash.get(obj=地图解析结果, path="result.address_component.city") 区 = pydash.get(obj=地图解析结果, path="result.address_component.district") diff --git a/wechat_token/token工具包.py b/wechat_token/token工具包.py index 708246a..95fee4d 100644 --- a/wechat_token/token工具包.py +++ b/wechat_token/token工具包.py @@ -1,10 +1,12 @@ """ + Author: xiao 792282@qq.com Date: 2025-08-10 11:36:05 LastEditors: xiao 792282@qq.com LastEditTime: 2025-08-17 13:38:39 FilePath: django_公共认证接口/微信TOKEN.py Description: 这是默认设置,可以在设置》工具》File Description中进行配置 + """ import os @@ -93,7 +95,6 @@ class sixToken: :return: :rtype: """ - print("是不是每次都在调用的吗") 查询对象, 是否存在 = weitoken.objects.get_or_create(token_name="mini_token") if 查询对象.token_value is None: 创建的新对象 = cls.mini_token() @@ -115,10 +116,7 @@ class sixToken: params = {"appid": cls.wechat_appid, "secret": cls.wechat_appsecret, "grant_type": "client_credential", "force_refresh": False, } token_data = requests.post(url="https://api.weixin.qq.com/cgi-bin/stable_token", json=params) token: dict = token_data.json() - print(token) wechat_token服务号 = token.get("access_token") - print("服务 号的token", wechat_token服务号) - # return wechat_token jsapo_url = f"https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={wechat_token服务号}&type=jsapi" json_data = requests.get(url=jsapo_url).json() ticket服务号 = pydash.get(obj=json_data, path="ticket", default=None) @@ -216,17 +214,7 @@ class sixToken: "grant_type": "authorization_code", # "code": code "code": code, # 填写第一步获取的code参数 } - # 返回值 = """ - # { - # "access_token":"ACCESS_TOKEN", - # "expires_in":7200, - # "refresh_token":"REFRESH_TOKEN", - # "openid":"OPENID", - # "scope":"SCOPE", - # "is_snapshotuser": 1, - # "unionid": "UNIONID" - # } - # """ + oauth_token_url = f"https://api.weixin.qq.com/sns/oauth2/access_token" oauth_token_data = requests.get(url=oauth_token_url, params=params) # oauth_token: dict = oauth_token_data.json() diff --git a/wechat_微信支付证书/江苏六果科技有限公司支付证书/六果公司支付类.py b/wechat_微信支付证书/江苏六果科技有限公司支付证书/六果公司支付类.py index ba69adf..0d0f412 100644 --- a/wechat_微信支付证书/江苏六果科技有限公司支付证书/六果公司支付类.py +++ b/wechat_微信支付证书/江苏六果科技有限公司支付证书/六果公司支付类.py @@ -6,13 +6,14 @@ import re import secrets from datetime import datetime from pathlib import Path -from typing import Literal, Optional +from typing import Literal from zoneinfo import ZoneInfo import django import orjson import pydash import requests +import xmltodict from Crypto.Cipher import AES from Crypto.Hash import SHA256 from Crypto.PublicKey import RSA @@ -46,59 +47,102 @@ class sixWechatPay六果泡泡支付(BaseModel): # ---------- 微信支付公钥(用于验签和加密敏感字段) ---------- wechatpay_public_key_id: str = Field(default="PUB_KEY_ID_0117003834192026080500181856002000", alias="微信支付公钥ID") wechatpay_public_key_pem: str = Field(default=Path(settings.BASE_DIR).joinpath("wechat_微信支付证书/江苏六果科技有限公司支付证书/微信支付公钥.pem").read_text(), alias="微信支付公钥PEM", description="pub_key.pem 内容") + # ---------- 平台证书(灰度过渡期备用) ---------- - platform_cert_pem: Optional[ - str] = Field(default=Path(settings.BASE_DIR).joinpath("wechat_微信支付证书/江苏六果科技有限公司支付证书/sixgou_ping_tai_zheng_shu_cert.pem").read_text(), alias="平台证书PEM", description="wechatpay.pem 内容") - pay_uri: str | None = Field(None, ) - pay_请求体: dict | bytes | str | None = Field(None, description="发请求签名时需要的请求体") + platform_cert_pem: str = Field(default=Path(settings.BASE_DIR).joinpath("wechat_微信支付证书/江苏六果科技有限公司支付证书/sixgou_ping_tai_zheng_shu_cert.pem").read_text(), alias="平台证书PEM", + description="wechatpay.pem 内容") + platform_cert_pem_id: str = Field(default="11D762828E947104028F2D045DE78FA806D0D4F2", description="平台证书的证收序列号ID") + pay_uri: str | None = Field(default=None, description="请求支付时需要的微信的url地址") + pay_请求体: dict = Field(default=None, description="发请求签名时需要的请求体") pay_methon方法: Literal["GET", "POST", "PATCH"] = Field(default="POST", description="发请求签名时需要的请求体") + pay_Headers: dict = Field(default={}, description="生成的初始化请求头") def model_post_init(self, __context): pass + """""" + if self.pay_uri is None or self.pay_uri == "": + return None + url_data = re.search(r'/v3.*', string=self.pay_uri).group() + utc_unix_timestamp = int(datetime.now(tz=ZoneInfo("utc")).timestamp()) + random_str = secrets.token_hex(nbytes=16) # 随机字符串 + if isinstance(self.pay_请求体, str): + body_inner = self.pay_请求体 + elif isinstance(self.pay_请求体, dict): + body_inner = json.dumps(self.pay_请求体) + elif self.pay_请求体 is None: + body_inner = "" + elif isinstance(self.pay_请求体, bytes): + body_inner = self.pay_请求体.decode() + else: + raise TypeError(f"不支持的请求体类型: {type(self.pay_请求体)}") + pay_signaturestring创建成功的签名串 = f"{self.pay_methon方法}\n{url_data}\n{utc_unix_timestamp}\n{random_str}\n{body_inner}\n" + # 构造一个哈希对象 + hash_obj = SHA256.new(pay_signaturestring创建成功的签名串.encode(encoding="utf-8")) + # 加载商户私钥 + # 调用了 RSA.import_key() 方法,它会从字符串或文件中导入一个 PEM 格式的 RSA 私钥,并返回一个 RsaKey 类型的对象 + private_key: RsaKey = RSA.import_key(self.merchant_private_key_pem) # 用私钥来加密 + # 生成签名 使用商户的 私钥进行签名 + signature = pkcs1_15.new(rsa_key=private_key).sign(msg_hash=hash_obj) + # 对签名进行Base64编码,符合微信支付API要求 + encoded_signature = base64.b64encode(s=signature).decode(encoding="utf-8") + # 组装成微信官方需要的数据; + data = { + "mchid": self.mchid, + "nonce_str": random_str, + "serial_no": self.serial_no商户证书的序列号, + "timestamp": utc_unix_timestamp, + "signature": encoded_signature, + } # 组装好的字典数据; + ftr = "WECHATPAY2-SHA256-RSA2048" + s_with_space = ftr.ljust(len(ftr) + 1) # 将字符串长度 +1(填充空格) + str_list = pydash.join(array=[f'{key}="{value}"' for key, value in data.items()], separator=",") + # 生成请求头 + Authorization = f"{s_with_space}{str_list}" + headers = {"Content-Type": "application/json", "Authorization": Authorization, } + headers.update({"Wechatpay-Serial": self.wechatpay_public_key_id}) + self.pay_Headers = headers + return None def 验证签名串(self, response_headers, response_data: dict, ): - """ - @param response_headers: - @type response_headers: - @param response_data: - @type response_data: - @return: - @rtype: - """ - public_key = RSA.import_key(self.platform_cert_pem) + """ 注释 """ + public_key = RSA.import_key(self.wechatpay_public_key_pem) # 在这里需要使用最新的微信支付公钥证书 Wechatpay_Timestamp = pydash.get(response_headers, "Wechatpay-Timestamp") Wechatpay_Nonce = pydash.get(response_headers, "Wechatpay-Nonce") Wechatpay_Signa = pydash.get(response_headers, "Wechatpay-Signature") + Wechatpay_Serial = pydash.get(response_headers, "Wechatpay-Serial") response_data_str = orjson.dumps(response_data, ).decode(encoding="utf-8") + string_to_verify = f"{Wechatpay_Timestamp}\n{Wechatpay_Nonce}\n{response_data_str}\n" # 构造验签名串 hash_obj = SHA256.new(string_to_verify.encode()) - # 6. 验证签名 + if Wechatpay_Serial == self.platform_cert_pem_id: + public_key = RSA.import_key(self.platform_cert_pem) + # 6. 验证签名 + if Wechatpay_Serial == self.wechatpay_public_key_id: + public_key = RSA.import_key(self.wechatpay_public_key_pem) # 在这里需要使用最新的微信支付公钥证书 try: pkcs1_15.new(public_key).verify(msg_hash=hash_obj, signature=base64.b64decode(Wechatpay_Signa)) return True # 签名验证成功 except (ValueError, TypeError) as e: - raise e # 签名验证失败 + print(e, "捕获了签名串验证不通过的错误") # 签名验证失败 + raise "捕获了签名串验证不通过的错误" def gouzhao构造签名串(self, ): - """ - - """ + """注释""" url_data = re.search(r'/v3.*', string=self.pay_uri).group() utc_unix_timestamp = int(datetime.now(tz=ZoneInfo("utc")).timestamp()) random_str = secrets.token_hex(nbytes=16) # 随机字符串 - pay_signaturestring创建成功的签名串 = "" - # 创建签名请求参数 + # 统一处理请求体,得到 body_inner 字符串 if isinstance(self.pay_请求体, str): - pay_signaturestring创建成功的签名串 = f"{self.pay_methon方法}\n{url_data}\n{utc_unix_timestamp}\n{random_str}\n{self.pay_请求体}\n" - if isinstance(self.pay_请求体, dict): - body_inner = json.dumps(obj=self.pay_请求体) - pay_signaturestring创建成功的签名串 = f"{self.pay_methon方法}\n{url_data}\n{utc_unix_timestamp}\n{random_str}\n{body_inner}\n" - if self.pay_请求体 is None: + body_inner = self.pay_请求体 + elif isinstance(self.pay_请求体, dict): + body_inner = json.dumps(self.pay_请求体) + elif self.pay_请求体 is None: body_inner = "" - pay_signaturestring创建成功的签名串 = f"{self.pay_methon方法}\n{url_data}\n{utc_unix_timestamp}\n{random_str}\n{body_inner}\n" - if isinstance(self.pay_请求体, bytes): + elif isinstance(self.pay_请求体, bytes): body_inner = self.pay_请求体.decode() - pay_signaturestring创建成功的签名串 = f"{self.pay_methon方法}\n{url_data}\n{utc_unix_timestamp}\n{random_str}\n{body_inner}\n" + else: + raise TypeError(f"不支持的请求体类型: {type(self.pay_请求体)}") + pay_signaturestring创建成功的签名串 = f"{self.pay_methon方法}\n{url_data}\n{utc_unix_timestamp}\n{random_str}\n{body_inner}\n" # 构造一个哈希对象 hash_obj = SHA256.new(pay_signaturestring创建成功的签名串.encode(encoding="utf-8")) @@ -160,9 +204,8 @@ class sixWechatPay六果泡泡支付(BaseModel): } def getpay_jsapi发起支付(self, ): - headers = self.gouzhao构造签名串() # 发送请求 - response: Response = requests.post(url=self.pay_uri, json=self.pay_请求体, headers=headers) + response: Response = requests.post(url=self.pay_uri, json=self.pay_请求体, headers=self.pay_Headers) prepay_id = pydash.get(obj=response.json(), path="prepay_id", default=None) # 验证请求后返回的数据是否为微信官方所发送; 验证签名结果 = self.验证签名串(response_data=response.json(), response_headers=response.headers) @@ -225,21 +268,29 @@ class sixWechatPay六果泡泡支付(BaseModel): 生成的支付链接 = response.json() return 生成的支付链接 - def v2签名返回XML(self, ): + def v2签名返回XML(self, sign_data): """v2版本的签名:将扫码支付的body转换为微信支付所要求的数据类型""" - sorted_dict = dict(pydash.sort_by(collection=self.pay_请求体.items(), iteratee=0)) + sorted_dict = dict(pydash.sort_by(collection=sign_data.items(), iteratee=0)) # 拼接字符串: (将密钥添加到最末尾) params_list_str = pydash.join(array=[f"{k}={v}" for k, v in sorted_dict.items()], separator="&") + "&key=" + self.api_v2_key # 得到params_str就是需要 参与 签名的字符串 signature = hashlib.md5(string=params_list_str.encode()).hexdigest().upper() # 使用MD5加密模式 - update后的数据 = pydash.set_(obj=self.pay_请求体, path="sign", value=signature) + update后的数据 = pydash.set_(obj=sign_data, path="sign", value=signature) xml = dicttoxml(obj=update后的数据, custom_root="xml", xml_declaration=False, attr_type=False, cdata=True) - print(type(xml)) - headers = self.gouzhao构造签名串() - response = requests.post(url=self.pay_uri, data=xml, headers=headers) - print(response.text) - print(response.json()) - return + return xml + + def getpay_code扫用户付款码(self, body_data, ) -> dict: + """ """ + xml = self.v2签名返回XML(sign_data=body_data) + fu_kuan_url = "https://api.mch.weixin.qq.com/pay/micropay" + res = requests.post(url=fu_kuan_url, data=xml) + # 返回的数据 是 ISO-8859-1 类型 + responseStr = res.text.encode("ISO-8859-1") + # 将请求得到的数据 转换为字典格式; + xml_dict = xmltodict.parse(responseStr.decode()) + # 得到请求结果并进行解密 + print(xml_dict) + return xml_dict def 解密群号(self, encryptedData, iv, sessionKey): """ diff --git a/wechat_接口/小程序用户接口/小程序用户登陆接口.py b/wechat_接口/小程序用户接口/小程序用户登陆接口.py index 81f0778..f070bd1 100644 --- a/wechat_接口/小程序用户接口/小程序用户登陆接口.py +++ b/wechat_接口/小程序用户接口/小程序用户登陆接口.py @@ -36,6 +36,7 @@ class 六果科技小程序用户登陆(ViewSet): """""" encryptedData = request.data.get("encryptedData", None) # 解密群号所需要的参数 iv = request.data.get("iv", None) # 解密群号所需要的参数 iv + user_手机设备参数 = request.data.get("user_手机设备参数", None) code: str = request.data.get("code", "") # superior_openid = request.data.get( "superior_openid", ) # 如果上级是默认的值 则说明是没有上级的, superior_unionid = request.data.get("superior_unionid", 上级分享者的默认值) # 如果上级是默认的值 则说明是没有上级的, @@ -52,8 +53,8 @@ class 六果科技小程序用户登陆(ViewSet): share分享者对象, share分享者对象是新创建 = weiuser.objects.update_or_create(unionid=superior_unionid, ) # 首次进来的用户要全部的添加上默认的 用户 角色 click点击者对象, self_bool = weiuser.objects.update_or_create(unionid=self_unionid, - defaults={"mini_openid": self_openid}) - + defaults={"mini_openid": self_openid, "user_手机设备参数": user_手机设备参数}) + print("-----------------------------------", user_手机设备参数) six六果对象, sixBool = weiuser.objects.get_or_create(unionid="六果") if superior_unionid == 上级分享者的默认值: share分享者对象 = six六果对象 diff --git a/wechat_接口/微信支付接口/微信支付测试接口.py b/wechat_接口/微信支付接口/微信支付测试接口.py index b84721f..51a32ae 100644 --- a/wechat_接口/微信支付接口/微信支付测试接口.py +++ b/wechat_接口/微信支付接口/微信支付测试接口.py @@ -13,7 +13,7 @@ from ulid import ULID from sixGuoDjango import BaseResponse, ResData from wechat_微信支付证书.江苏六果科技有限公司支付证书.六果公司支付类 import sixWechatPay六果泡泡支付 from wechat_数据库.雪花算法.雪花算法工具 import generator -from wechat_项目工具包.微信支付工具包.微信支付类 import paymentCategory, wechatPay +from wechat_项目工具包.微信支付工具包.微信支付类 import paymentCategory class 微信支付ViewSets(ViewSet): @@ -41,8 +41,6 @@ class 微信支付ViewSets(ViewSet): }, } # 请求的数据 wechat_pay_data = sixWechatPay六果泡泡支付(pay_methon方法="POST", pay_请求体=body_支付数据, pay_uri=url_pay).getpay_jsapi发起支付() - print(wechat_pay_data) - httpResData = BaseResponse(resData=ResData(listData=[""], dictData=wechat_pay_data), ).model_dump() return Response(data=httpResData, status=status.HTTP_200_OK) @@ -78,7 +76,7 @@ class 微信支付ViewSets(ViewSet): return Response(data=httpResData, status=status.HTTP_200_OK, ) @action(detail=False, methods=["post"], url_path="qrCode") - def 付款码支付(self, request: Request): + def 扫用户付款码支付(self, request: Request): """ 扫用户付款码的测试接口 :param request: @@ -97,41 +95,18 @@ class 微信支付ViewSets(ViewSet): "auth_code": auth_code, "total_fee": 1, # 订单总金额,单位为分,只能为整数,详见支付金额(必填) } - wechat_data = wechatPay(payment=paymentCategory).getpay_code扫用户付款码(body_data=fu_kuan_data) - print(wechat_data) - # return_code 通信返回码:'SUCCESS' 表示与微信服务器通信成功,'FAIL' 表示通信失败(如网络或参数错误) - return_code = jmespath.search(data=wechat_data, expression="xml.return_code") - # return_msg 通信返回信息:当 return_code 为 'FAIL' 时,此字段包含错误描述;成功时通常为 'OK' - return_msg = jmespath.search(data=wechat_data, expression="xml.return_msg") - # result_code 业务结果码:'SUCCESS' 表示支付成功,'FAIL' 表示支付失败(需结合 err_code 分析,但此处未提取) - result_code = jmespath.search(data=wechat_data, expression="xml.result_code") - # mch_id 商户号(MCH ID):微信支付分配给商户的唯一标识 - mch_id = jmespath.search(data=wechat_data, expression="xml.mch_id") - # appid 公众号或小程序的 AppID:发起支付的应用身份标识 - appid = jmespath.search(data=wechat_data, expression="xml.appid") - # nonce_str 随机字符串:用于防止重放攻击,由商户生成并随请求发送,微信原样返回 - nonce_str = jmespath.search(data=wechat_data, expression="xml.nonce_str") - # openid 用户在当前 AppID 下的唯一标识(OpenID):可用于关联用户账户 - openid = jmespath.search(data=wechat_data, expression="xml.openid") - # total_fee 订单总金额(单位:分):例如 '1' 表示 0.01 元 - total_fee = jmespath.search(data=wechat_data, expression="xml.total_fee") - # cash_fee_type 现金支付币种:目前微信支付仅支持 'CNY'(人民币) - cash_fee_type = jmespath.search(data=wechat_data, expression="xml.cash_fee_type") - # transaction_id 微信支付系统生成的唯一交易单号:用于对账、退款、查询等操作 - transaction_id = jmespath.search(data=wechat_data, expression="xml.transaction_id") - # 商户系统内部订单号:由商户在调用支付接口时传入,用于关联自身业务订单 - out_trade_no = jmespath.search(data=wechat_data, expression="xml.out_trade_no") - # 附加数据:商户在支付请求中可自定义传入,微信原样返回(常用于传递门店ID、商品类型等) - attach = jmespath.search(data=wechat_data, expression="xml.attach") - # time_end 支付完成时间:格式为 yyyyMMddHHmmss,例如 '20260304233708' 表示 2026年03月04日 23:37:08 - time_end = jmespath.search(data=wechat_data, expression="xml.time_end") + # wechat_data = wechatPay(payment=paymentCategory).getpay_code扫用户付款码(body_data=fu_kuan_data) + # print(wechat_data) + wechat_data = sixWechatPay六果泡泡支付().getpay_code扫用户付款码(body_data=fu_kuan_data) httpResData = BaseResponse(resData=ResData(listData=[""], dictData={"demo": "xiaozizi"}), ).model_dump() return Response(data=httpResData, status=status.HTTP_200_OK) @action(detail=False, methods=["post"], url_path="jsapi_callback") def jsapi支付回调测试接口(self, request: Request) -> Response: """ 微信支付成功后的回调接口 """ - wechat_data支付回调数据 = sixWechatPay六果泡泡支付(pay_uri="", pay_请求体={}, pay_methon方法="POST").callBack回调解密(headers=request.headers, response_body=request.data) + print("回调的请求体", request.data) + print("回调的请求体", request.headers) + wechat_data支付回调数据 = sixWechatPay六果泡泡支付(pay_uri=None, pay_请求体={}, pay_methon方法="POST").callBack回调解密(headers=request.headers, response_body=request.data) print("\n🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 \n", wechat_data支付回调数据, "\n🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 \n") httpResData = BaseResponse(resData=ResData(listData=[""], dictData={"demo": "xiaozizi"}), ).model_dump() @@ -140,55 +115,9 @@ class 微信支付ViewSets(ViewSet): @action(detail=False, methods=["post"], url_path="callback_navite") def 二维码支付回调(self, request: Request): """注释""" - wechat_data支付回调数据 = sixWechatPay六果泡泡支付(pay_uri="", pay_请求体={}, pay_methon方法="POST").callBack回调解密(headers=request.headers, response_body=request.data) + wechat_data支付回调数据 = sixWechatPay六果泡泡支付().callBack回调解密(headers=request.headers, response_body=request.data) print("二维码支付回调二维码支付回调二维码支付回调二维码支付回调二维码支付回调") return Response(data={"msg": "success"}) - - @action(detail=False, methods=["get", "post", "put", "delete"], url_path="xml_code") - def 扫用户的付款码收钱(self, request: Request): - pass - - auth_code = request.data.get("auth_code", None) - data_扫用户付款码数据 = { - "appid": sixWechatPay六果泡泡支付().appid, # 微信分配的公众账号ID(企业号corpid即为此appId) - "attach": "订单额外描述", # 附加数据,在查询API和支付通知中原样返回,可作为自定义参数 - "auth_code": "143893528965089", # 授权码,扫码支付时的付款码(条形码/二维码) - "body": "付款码支付测试", # 商品描述,商品简单描述(如:腾讯充值中心-QQ会员充值) - "device_info": "1000", # 设备号,终端设备号(门店号或收银设备ID),自定义参数 - "goods_tag": "", # 商品标记,代金券或立减优惠功能的参数,可为空 - "mch_id": "10000100", # 商户号,微信支付分配的商户号 - "nonce_str": f"{ULID()}", # 随机字符串,长度不超过32位,保证签名不可预测 - "out_trade_no": f"{ULID()}", # 商户订单号,商户系统内部订单号,要求32个字符内,且在同一个商户号下唯一 - "total_fee": "1", # 订单总金额,单位为分,只能为整数(此处为1分钱) - } - wechat_pay_data = sixWechatPay六果泡泡支付(pay_methon方法="POST", pay_请求体=data_扫用户付款码数据, pay_uri="https://api.mch.weixin.qq.com/pay/micropay").v2签名返回XML() - print(wechat_pay_data) - return Response(data={}) - - @action(detail=False, methods=["get", "post", "put", "delete"], url_path="add") - def 添加商品数据(self, request: Request): - pass - out_refund_no商家侧生成的退款订单号 = f"{ULID()}" - refund_request = { - "transaction_id": "1217752501201407033233368018", # 微信支付订单号(与 out_trade_no 二选一) - # "out_trade_no": "1217752501201407033233368018", # 商户订单号(与 transaction_id 二选一) - "out_refund_no": out_refund_no商家侧生成的退款订单号, # 商户退款单号,唯一 - "reason": "商品已售完", # 退款原因(选填) - "notify_url": "https://xiao.sixgou.com/demopay/退款/", # 异步接收微信支付退款结果通知的回调地址 - "funds_account": "AVAILABLE", # 退款资金来源:AVAILABLE-可用余额,UNSETTLED-未结算资金 - "amount": { - "refund": 1, # 退款金额,单位:分 - "from": [ - { - "account": "AVAILABLE", # 出资账户类型 - "amount": 444 # 出资金额 - } - ], - "total": 1, # 原订单金额 - "currency": "CNY" # 货币类型 - }, - } - return Response(data={}) 微信支付ViewSetsRouter = DefaultRouter() diff --git a/wechat_数据库/用户数据库/小程序登陆用户.py b/wechat_数据库/用户数据库/小程序登陆用户.py index 9d8b3be..9533620 100644 --- a/wechat_数据库/用户数据库/小程序登陆用户.py +++ b/wechat_数据库/用户数据库/小程序登陆用户.py @@ -1,8 +1,5 @@ """注释""" from django.db import models -from uuid6 import uuid8 - -from wechat_数据库.雪花算法.雪花算法工具 import generator """ 输入 :当前用户实例(self) @@ -45,13 +42,13 @@ class weiuser用户角色表choicesStatus(models.TextChoices): class weiuser(models.Model): """用户基础信息表""" objects = models.Manager() # - + class ChoicesStatus(models.TextChoices): """商家转账订单状态""" 推广员 = "推广员", gettext_lazy("推广员") 企微员工 = "企微员工", gettext_lazy("企微员工") 无状态 = "无状态", gettext_lazy("无状态") - + unionid = models.CharField(primary_key=True, max_length=120) user_角色权限 = models.CharField(choices=weiuser用户角色表choicesStatus, default=weiuser用户角色表choicesStatus.普通会员) user_企微角色权限 = models.CharField(max_length=128, null=True, blank=True, ) @@ -71,6 +68,7 @@ class weiuser(models.Model): user_绑定企微usrID账号 = models.CharField(max_length=128, null=True, blank=True, ) user_绑定企微UNIONID = models.CharField(max_length=128, null=True, blank=True, ) user_IP地址 = models.GenericIPAddressField(null=True, blank=True, ) + user_手机设备参数 = models.JSONField(null=True, blank=True, ) user_绑定用工关系 = models.CharField(max_length=128, null=True, blank=True, ) codeConfigId = models.TextField(blank=True, null=True, ) # 企微的标签ID codeQrCode = models.TextField(blank=True, null=True, ) # 企微的二维码 @@ -80,12 +78,12 @@ class weiuser(models.Model): add_time = models.DateTimeField(null=True, blank=True, db_comment="用户添加好友的时间") dateAndTime = models.DateTimeField(auto_now_add=True, db_comment="创建时间") # 数据创建时间 updateTime = models.DateTimeField(auto_now=True, db_comment="更新时间") # 更新时间(需要用 save() ) - + class Meta: db_table = "weiuser" # 给数据表自定义一个名称;默认的会是在 应用名+类名 app_label = models_app_name ordering = ["-dateAndTime", "-updateTime"] - + def get_all_subordinates(self): """递归获取所有下级(包括间接下级)""" subs = [] @@ -93,7 +91,7 @@ class weiuser(models.Model): subs.append(sub) subs.extend(sub.get_all_subordinates()) return subs - + # ↓↓↓ 新增方法:获取所有上级(递归实现)↓↓↓ def get_all_superiors(self): """ @@ -106,7 +104,7 @@ class weiuser(models.Model): # 递归获取上级的上级 superiors.extend(self.parent.get_all_superiors()) return superiors - + def get_nth_level_superior(self, n): """ 获取第n级上级 @@ -120,7 +118,7 @@ class weiuser(models.Model): """ if n < 1: raise ValueError("n 必须大于或等于 1") - + current = self # 循环向上查询 n 次 for _ in range(n): @@ -128,7 +126,7 @@ class weiuser(models.Model): return None # 没有父级时提前终止 current = current.parent return current - + """ 这种实现方式更加简洁,但需要注意: 它使用了链式递归调用,可能会增加递归深度 @@ -140,7 +138,7 @@ class weiuser(models.Model): 内存使用:递归会占用更多栈空间 在大多数实际应用中,树结构的深度不会超过100层,因此递归实现通常是可行的。但如果预期树结构会非常深(如超过1000层),建议使用循环实现或混合实现。 """ - + def find_ancestor_by_field(self, field_name, target_value, include_self=False): """ 从当前用户向上查找,找到第一个指定字段等于目标值的祖先 @@ -152,11 +150,11 @@ class weiuser(models.Model): # 验证字段名是否有效 - 修复方法 if not hasattr(self, field_name): raise ValueError(f"无效字段名: {field_name}") - + # 如果包含自身且满足条件,直接返回 if include_self and getattr(self, field_name) == target_value: return self - + # 向上遍历祖先 current = self.parent while current: @@ -164,7 +162,7 @@ class weiuser(models.Model): return current current = current.parent return None - + def find查找指定的上级(self, field_name, target_value, include_self=False): """ 从当前用户向上查找,找到第一个指定字段等于目标值的祖先 @@ -176,11 +174,11 @@ class weiuser(models.Model): # 验证字段名是否有效 - 修复方法 if not hasattr(self, field_name): raise ValueError(f"无效字段名: {field_name}") - + # 如果包含自身且满足条件,直接返回 if include_self and getattr(self, field_name) == target_value: return self - + # 向上遍历祖先 current = self.parent while current: @@ -189,7 +187,6 @@ class weiuser(models.Model): current = current.parent return None - # class weiuser用户角色表(models.Model): # """城市信息表""" # objects = models.Manager() # diff --git a/wechat_项目工具包/企业微信工具包/客户管理.py b/wechat_项目工具包/企业微信工具包/客户管理.py index 347c33c..6249392 100644 --- a/wechat_项目工具包/企业微信工具包/客户管理.py +++ b/wechat_项目工具包/企业微信工具包/客户管理.py @@ -62,16 +62,6 @@ class wecomData获取客户详情响应(BaseModel): follow_user: List[wecomData跟进成员信息] = [] -six六果对象xiao, six是否新创建值 = weiuser.objects.update_or_create(unionid="六果", - defaults={ - "user_IP地址": None, "user_昵称": "六果", "user_用户当前的等级": 0, "user_省份": "六果", "user_城市": "六果", "user_区县": "六果", - "user_街道信息": "六果", "user_头像": "https://hudie.xiao.band/%E6%9C%AA%E5%91%BD%E5%90%8D.png", "user_绑定企微usrID账号": "六果", "user_角色权限": "六果", "external_userid": "六果", - "parent_id": "六果", "mini_openid": "wxf612e825377328f0", "wechat_openid": "六果", "wecom_openid": "wwbe6369dc26a9d83a", "codeConfigId": "六果", "codeRemark": "六果", - "codeQrCode": "https://hudie.xiao.band/mini.jpg", - "user_企微角色权限": "六果", "user_绑定企微UNIONID": "六果" - }) - - class wecom客户好友管理(BaseModel): # demo_必填: int = Field(..., description="描述") # 必传属发生 # demo_可选: Optional[int] = None # 可选值 diff --git a/wechat_项目工具包/小程序管理后API/非对称密钥私钥.txt b/wechat_项目工具包/小程序管理后API/非对称密钥私钥.txt deleted file mode 100644 index 6f92e62..0000000 --- a/wechat_项目工具包/小程序管理后API/非对称密钥私钥.txt +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEA+7fWfsUk5JceJXIG8a3JZu30KdKv3uFVP+vJtYDiTspiOd1z -l2D7fzTeZ3BNLlW29OGNDFlUEUJGoVSVzh9ZgKm4ZCpjQYSy03VH25kJHCjVZLX9 -aBy0DuRUN2Jwq/ma1Z9lgrJuo5Kou2oQQJgqXON20030CqNkiQA/bMJJnN1MYJZi -I7eHdW/HIC42wB31YW0ZNACEP1UfQ4o54zJzbi6xNus9OyD2DtjV3Q0ZRjuRRUU5 -krBWeV2kK2XQrKJ0T5TF9q0N+QqJETA6iY33ScRqt25SDcpjc4dVuwSveL6fPj5J -zrwfRkTtYwDlwfLz7yChJD4aJQ+NWvmyOMVWxQIDAQABAoIBAGIvDAh4p3JOi6C5 -gIHmcqema1Wg6565MAJ120Dj2+I1yOifO4YxewfcPGAGiuRm5K1SCS1m7oao3lnx -X1l+GvA3w0e2zO5ybzpSBcxfPhFw0AOvhP+GKqmgYEUWLbK28rEesn6vUL6W5x/r -OBmqAOQoiWHUhztbDkzt/s9SXVpEpYxoEikg2M8QBGHTY+IuHFWMKSSltWh845zK -MtSARPszxlU10WXH8xZIfTGK5EvZ6U5GHoWlDVnEJjzC5NAvf2tcrFP3suMEjEic -PPEmZXR/FNAr7MNF118hsZ8FckUlt4ngaTwT0dmSqcutCc4ye9v4YpxFOyQPoBB3 -SnfsbMUCgYEA/gIWSKt4PBsBpWvDIHBEjwYCMwZM/xOqtjnAe1gVR1SDb/fMOr/6 -FDW14841I75ez6/GZxHTDzbkxsJ7NVcRrXxKGyxL0+J50qEPnFairyGVd501Dktd -TghTGP5iffesPtRqs36oFURGCPaKetD8Ar33LjXhIzttsPCoJIs0ZbsCgYEA/bEn -VeUicXqwRdarixCgvihMem9Jm0fSyaQc7aeN1xzbI4OEuwq0tWGwJ6UmZOJcbdxx -lc7Z8Y6/U6Gv6oxFgHcOtB4cTHpBSOsKMzXcJNjVVkXzEuq6cvRIEYHZEdzN82t/ -2uMUh9DRyIzNDFJ4/+OEaiRQDT3yS8Z8/KLfLX8CgYEAv1cjIirIr75IRyweGNl5 -S6PjFDyy05MlDZADhuabYNgxCq9HkRn8cCzlj21OalaFZT2r3wh2TQe03mSyG0Qz -dNQjnsSHel0oF5psAADjG7nYtfoedV4gMx/iOPmnh+yCO/IXTo8iXqLHfwj41/uF -Wytuf8jmh3vE7XzbrGuQVPECgYAD9cL2bUg3W0HrJSmyVwUbUse21Yvhl6JrsVse -PpJRPEsTZ9cnkEg32JmGVOafhoUI1fsT6pGuWpsT9B8p2xyun60kFKA+dV4VhE25 -dOrFzHiwCxF7Rxy39KY3V76Kr9arKQ9q3EaSxCiyJ7h/q73lyKhle8GgI0pn8mY7 -D1PKgwKBgCxqlcRlHbQ3pv1NM5efI2bEdg1Dz5zuxL7DU/lBoE10dvlyJgJRbRNZ -x49nykTmM3cWjZStQBvxuqzo8XMOVvZaq9DuR0sDbNUDDI61Og/cAhtyThYsiPpL -HzgEN+3o4mVn5+0w//t1JJNpEpmSA8h4aZ0esa8E3wNe+ZMfZ4ti ------END RSA PRIVATE KEY----- diff --git a/wechat_项目工具包/微信支付工具包/微信支付类.py b/wechat_项目工具包/微信支付工具包/微信支付类.py index a515abf..1886726 100644 --- a/wechat_项目工具包/微信支付工具包/微信支付类.py +++ b/wechat_项目工具包/微信支付工具包/微信支付类.py @@ -336,13 +336,7 @@ class wechatPay(BaseModel): return xml def getpay_code扫用户付款码(self, body_data, ) -> dict: - """ - 商家扫用户的付款码,收款 - :param body_data: - :type body_data: - :return: - :rtype: - """ + """ """ xml = self.v2签名返回XML(sign_data=body_data) fu_kuan_url = "https://api.mch.weixin.qq.com/pay/micropay" res = post(url=fu_kuan_url, data=xml) diff --git a/wechat_项目工具包/数据库的工具包/更新用户积分.py b/wechat_项目工具包/数据库的工具包/更新用户积分.py index 2dba5e7..5e9035c 100644 --- a/wechat_项目工具包/数据库的工具包/更新用户积分.py +++ b/wechat_项目工具包/数据库的工具包/更新用户积分.py @@ -50,9 +50,6 @@ class miniUser积分(BaseModel): click点击者unionidID: str = Field(..., description="点击者的的openid") bind绑定的企微unionidID: str = Field(default="", description="click绑定的企微unionidID") - def update更新用户头像(self): - pass - def add添加每日积分(self, share积分类型: Literal["每日签到"], share分享者积分值: int, ): pass # 注意,这里的每日签到: 分享者 同时 也是点击者 diff --git a/wechat_项目授权/企业微信消息服务器授权接口.py b/wechat_项目授权/企业微信消息服务器授权接口.py index 6128572..3246416 100644 --- a/wechat_项目授权/企业微信消息服务器授权接口.py +++ b/wechat_项目授权/企业微信消息服务器授权接口.py @@ -114,7 +114,7 @@ class sixwecom(ViewSet): img_file = requests.get(url=avatar).content src = oss上传腾讯云图片.上传图片(key=f"{userid}/{name}.png", file=io.BytesIO(img_file), ) avatar = src - 企微用户关系对象, 企微用户是否为首次 = wecom企微用户.objects.update_or_create(wecom企微ID=UserID, ) + 企微用户关系对象, 企微用户是否为首次 = wecom企微用户.objects.update_or_create(wecom企微ID=UserID, wecom好友的ID=ExternalUserID) 企微用户关系对象.wecom企微状态State = State 企微用户关系对象.wecom好友的ID = external_userid 企微用户关系对象.wecom好友UNIONID = unionid @@ -179,6 +179,9 @@ class sixwecom(ViewSet): 企微用户关系对象, 企微用户是否为首次 = wecom企微用户.objects.get_or_create(wecom企微ID=UserID, wecom好友的ID=ExternalUserID) if 企微用户是否为首次: pass + 企微用户关系对象.wecom好友关系状态 = ChangeType + 企微用户关系对象.wecom好友的ID = ExternalUserID + 企微用户关系对象.save() else: 企微用户关系对象.wecom好友关系状态 = ChangeType 企微用户关系对象.save() diff --git a/数据库初始化.py b/数据库初始化.py index e69de29..6480d7a 100644 --- a/数据库初始化.py +++ b/数据库初始化.py @@ -0,0 +1,24 @@ +# + +import os + +import django + +from sixGuoDjango.settings import base_dir_name + +os.environ.setdefault(key="DJANGO_SETTINGS_MODULE", value=f"{base_dir_name}.settings") +django.setup() + +from wechat_数据库.用户数据库.小程序登陆用户 import weiuser + +six六果对象xiao, six是否新创建值 = weiuser.objects.update_or_create(unionid="六果", + defaults={ + "user_IP地址": None, "user_昵称": "六果", "user_用户当前的等级": 0, "user_省份": "六果", "user_城市": "六果", "user_区县": "六果", + "user_街道信息": "六果", "user_头像": "https://hudie.xiao.band/%E6%9C%AA%E5%91%BD%E5%90%8D.png", "user_绑定企微usrID账号": "六果", "user_角色权限": "六果", "external_userid": "六果", + "parent_id": "六果", "mini_openid": "wxf612e825377328f0", "wechat_openid": "六果", "wecom_openid": "wwbe6369dc26a9d83a", "codeConfigId": "六果", "codeRemark": "六果", + "codeQrCode": "https://hudie.xiao.band/mini.jpg", + "user_企微角色权限": "六果", "user_绑定企微UNIONID": "六果" + }) + +if __name__ == "__main__": + pass diff --git a/测试数据库.py b/测试数据库.py index b55dfae..91862b0 100644 --- a/测试数据库.py +++ b/测试数据库.py @@ -1,25 +1,16 @@ import os -from datetime import datetime -from zoneinfo import ZoneInfo import django -from pydantic import BaseModel from sixGuoDjango.settings import base_dir_name os.environ.setdefault(key="DJANGO_SETTINGS_MODULE", value=f"{base_dir_name}.settings") django.setup() -utc_unix_timestamp = int(datetime.now(tz=ZoneInfo("utc")).timestamp()) -from wechat_token.token工具包 import sixToken +import segno -class emsParameters(BaseModel): - wecom_token: str = sixToken.get_wecom_token() - - def xiao(self): - pass - - -if __name__ == "__main__": - pass - print(emsParameters().wecom_token) +# segno 直接支持输出为 bytes +qr = segno.make_micro("xiaozizi") +print(qr.png_data_uri()) +code = segno.make('Penny Lane', error='h') +print(code.svg_data_uri())