update imgs src

This commit is contained in:
RainSun 2019-11-15 18:59:49 +08:00
parent fa4d598005
commit 7cbf57e146
17 changed files with 1430 additions and 38 deletions

12
app.js
View File

@ -20,11 +20,11 @@ App({
CustomBar: null,
bgIndex:null,
rpx:null,
bgs: ['https://uploadfile.bizhizu.cn/up/8a/8a/5c/8a8a5c23470344cb2abd24d52f9e2e7a.jpg',
'https://uploadfile.bizhizu.cn/up/ba/a1/40/baa1401b6e6744d8e29b6d5f1a058a30.jpg.source.jpg',
'https://uploadfile.bizhizu.cn/up/b5/6c/d6/b56cd6b931485f0aad80c44a6bd2144b.jpg.source.jpg',
'https://uploadfile.bizhizu.cn/up/6e/15/00/6e1500c4e6b135af47ec257b43640c5d.jpg.source.jpg',
'https://uploadfile.bizhizu.cn/up/f4/c7/ba/f4c7ba7cda104509a25043cc335c1a44.jpg',
'https://uploadfile.bizhizu.cn/2017/0913/319cdd716a5f5d6f9201dd44f5ca9755.jpg']
bgs: ['https://qrcode-1256486458.cos.ap-chengdu.myqcloud.com/bg/bg1.jpg',
'https://qrcode-1256486458.cos.ap-chengdu.myqcloud.com/bg/bg2.jpg',
'https://qrcode-1256486458.cos.ap-chengdu.myqcloud.com/bg/bg3.jpg',
'https://qrcode-1256486458.cos.ap-chengdu.myqcloud.com/bg/bg4.jpg',
'https://qrcode-1256486458.cos.ap-chengdu.myqcloud.com/bg/bg5.jpg',
'https://qrcode-1256486458.cos.ap-chengdu.myqcloud.com/bg/bg6.jpg',]
}
})

220
backEnd/README.md Normal file
View File

@ -0,0 +1,220 @@
# 收款码合成后端文档
## 目录结构
```
|-- lib
| |-- allFunction.py
| |-- db.py
| |-- login.py
| |-- pay.py
| |-- signature.py
|-- templates
| |-- 400.html
| |-- 404.html
| |-- 410.html
| |-- 500.html
| |-- qrcode.html
|-- hello.py
|-- README.md
```
## 接口列表及说明
```js
// $ 代表参数
// <> 代表数据类型
// 用户小程序登录
// 参数code , sign
/login
|-- manageLogin()
| |-- checkContent($code,$sign)
| | |-- getOpenid($code)
| | | |-- {'errmsg': '$openid', 'errcode': 200} // 请求成功
| | | |-- {'errmsg': '<str>', 'errcode': '<Num>'} // 请求失败
| | |
| | |-- False
| |
| |-- {'userInfo': findUser($openid), 'openid': 'str', 'errcode': 200} // 请求成功
| |-- {'errmsg': '<str>', 'errcode': '<Num>'} // 请求失败
| |-- False
|
|-- {'userInfo': findUser($openid), 'openid': 'str', 'errcode': 200} // 请求成功
|-- {'errmsg': '<str>', 'errcode': '<Num>'} // 请求失败
|-- 400
// 用户扫描二维码
// 参数 id
/qr
|-- findQR()
| |-- findCode($id)
| | |-- arr '<json -> Array>' //查询成功
| | |-- False // id不合法或者查询无结果
| |
| |-- arr '<json -> Array>' // 查询成功
| |-- False // id不合法或者查询无结果
|
|-- template('qrcode.html')
|-- 410
// 小程序刷新用户信息
// 参数 openId, sign
/reflash
|-- flash()
| |-- checkContent($openId, $sign)
| | |-- {'userInfo': findUser($openId) '<json -> Array>', 'errcode': 200} // 返回查询到的所有用户信息,可能为空数组
| | |-- False //openid不合法
| |
| |-- {'userInfo': findUser($openId) '<json -> Array>', 'errcode': 200}
| |-- False //openid不合法
|
|-- {'userInfo': findUser($openId) '<json -> Array>', 'errcode': 200}
|-- 400
// 小程序删除二维码
// 参数 id, sign
/del
|-- delQR()
| |-- checkContent($id, $sign)
| | |-- delCode($id)
| | | |-- {'errcode': 200, 'errmsg': 'ok'} //删除成功
| | | |-- False //id不合法
| | |
| | |-- {'errcode': 200, 'errmsg': 'ok'} //删除成功
| | |-- False
| |
| |-- {'errcode': 200, 'errmsg': 'ok'} //删除成功
| |-- False
|
|-- {'errcode': 200, 'errmsg': 'ok'} //删除成功
|-- 400
// 创建新的订单
// 参数 data, totalFee
/newOrder
|-- createOrder()
| |-- checkData($data)
| | |-- $param = createOrderParams($totalFee) // 创建订单详情
| | |-- $dataCache = createOrderCache($data, $params) // 把 out_trade_no 放进用户上传的data里边
| | |-- $res = insertOrderCache($dataCache) // 把 data放进cache 表里边
| | |-- {'params': params, 'errcode': 200} //上一步操作成功返回
| | |-- False //以上操作出问题
| |
| |-- {'params': params, 'errcode': 200}
| |-- False
|
|-- {'params': params, 'errcode': 200}
|-- 400
// 处理订单异步查询
/notify
|-- manageNotify()
| |-- checkNotify($form) //校验数据
| | |-- cache2Test($out_trade_no, payjs_order_id)
| | | |-- True //把缓存表中内容去出加上支付识别码放进正式表,在映射表建立 out_trade_no 到正式表 ObjectId 的映射
| | | |-- False //以上操作出错
| | |
| | |-- True
| | |-- False
| |
| |-- True
| |-- False
|
|-- True
|-- False
// 小程序查询订单状态
// 参数 out_trade_no
/checkOrder
|-- checkOrder()
| |-- findOrder($out_trade_no)
| | |-- order_id '<json -> String>' //查询映射表 out_trade_no 对应的 id
| | |-- False //查询无结果或者删除映射表的数据失败
| |
| |-- {'order_id': order_id, 'errcode': 200}
| |-- False
|
|-- {'order_id': order_id, 'errcode': 200}
|-- 500
```
## TODO
* MD5加解密 验证来源
## 配置环境
安装venv
`python3 -m venv venv`
启动venv
`. venv/bin/activate`
关闭venv
`deactivate`
查看现在已经安装的依赖
`pip3 list`
更新pip
`pip install --upgrade pip`
安装Flask
` pip install Flask`
安装最新的flask
`pip install -U https://github.com/pallets/flask/archive/master.tar.gz`
安装pymongo
` pip install pymongo`
安装requests
` pip install requests`
安装payjs
` pip install payjs`
设置全局变量
`export FLASK_APP=qrcode.py`
`export FLASK_ENV=development`
启动
`flask run --host=0.0.0.0`
在虚拟环境下安装gunicorn
`pip install gunicorn`
添加配置文件 gunicorn.conf
```
# 并行工作线程数
workers = 4
# 监听内网端口5000【按需要更改】
bind = '127.0.0.1:5000'
# 设置守护进程【关闭连接时,程序仍在运行】
daemon = True
# 设置超时时间120s默认为30s。按自己的需求进行设置
timeout = 120
# 设置访问日志和错误信息日志路径
# accesslog = './logs/acess.log'
# errorlog = './logs/error.log'
# 自动重启
autostart = True
```
启动gunicorn
`gunicorn qrcode:app -c gunicorn.conf`

268
backEnd/lib/allFunction.py Normal file
View File

@ -0,0 +1,268 @@
from db import findUser, findCode, delCode, insertOrderCache, cache2Test, findOrder
from login import getOpenid
from pay import checkNotify, createOrderParams
import re
import json
import time
# 主函数
# 处理登录操作 debug完成
def manageLogin(request):
if checkContent(request.form['code'],request.form['sign']): # 校验
res = getOpenid(request.form['code']) # 获取openid
if res['errcode'] == 200: # 获取成功返回用户信息
return {'userInfo': findUser(res['errmsg']['openid']), 'openid': res['errmsg']['openid'], 'errcode': 200}
else: # 获取失败返回失败信息
return res
else:
return False # 参数不全或者没通过校验
# 用户扫描二维码付款 debug完成
def findQR(request):
# 这里做不了加密验证,防止攻击
# 已知ObjectId只包含数字和字母且长度为24位使用isalnum
codeId = str(request.args.get('id'))
if(len(codeId) == 24): # 长度校验
if(codeId.isalnum()): # 内容校验
return findCode(codeId) # 返回code信息
else:
return False
else:
return False
# 小程序刷新用户信息 debug完成
def flash(request):
# 正常的加解密校验
# 已知openId只包含-、_、数字和字母且长度为28位使用正则
if checkContent(request.form['openId'],request.form['sign']): # 校验
openId = str(request.form['openId'])
if(len(openId) == 28): # 长度校验
pattern = re.compile(r'[^\w-]')
if(pattern.search(openId)): # 内容校验
return False
else:
return {'userInfo': findUser(openId), 'errcode': 200} # 返回用户信息
else:
return False
else:
return False # 参数不全或者没通过校验
# 用户删除二维码 debug完成
def delQR(request):
# 正常加解密校验
# 和findQR一样校验objectId
if checkContent(request.form['id'],request.form['sign']): # 校验
codeId = str(request.form['id'])
if(len(codeId) == 24): # 长度校验
if(codeId.isalnum()): # 内容校验
return delCode(codeId) # 返回code信息
else:
return False
else:
return False
else:
return False
# 微信小程序创建订单 debug完成
def createOrder(request):
# 先就不加MD5校验了
# 校验所有内容,目前策略微信支付宝取网址后边的东西校验qq转义
# 需要接收的内容 data : wxcode alcode qqcode username openId node; totalFee
# 判断过程先看是否为空不是空进行校验报错返回False
dataCache = json.loads(request.form['data']) # josn化应该能当dist用
checked = checkData(dataCache) # 校验所有用户上传的内容
if checked:
params = createOrderParams(request.form['totalFee']) # 获取到订单信息
dataCache = createOrderCache(dataCache, params) # 处理要放进缓存表的数据
res = insertOrderCache(dataCache) # 放进缓存表
if res:
return {'params': params, 'errcode': 200}
else:
return False
else:
return False
# 处理订单异步通知 debug完成
def manageNotify(request):
check = checkNotify(request.form.to_dict()) # 回调验证
if check:
res = cache2Test(request.form['out_trade_no'],request.form['payjs_order_id']) # 转移到Test
if res: # 转移成功返回id
return True
else:
return False
else:
return False
# 小程序查询订单状况 debug完成
def checkOrder(request):
order_id = findOrder(request.form['out_trade_no']) # 查询到的映射id
if order_id: # 后端还没收到反馈
order_id = json.loads(order_id)['$oid']
if order_id: # 查询删除都成功了
return {'order_id': order_id, 'errcode': 200}
else:
return False
else:
return False
# 工具函数---------------------------------------------------------------------------------
# 在这里进行解密对照
def checkContent(row,rsa):
# 回头再写先默认返回true
# 用那个MD5
# 应该和MD5放在一个文件里
return True
# 判断str转换完是否为空
def isKong(arg):
if arg == 'None' or arg == '' or arg == None:
return True
else:
return False
# 上传参数校验
def checkData(data):
hrefCount = 0
usernameCount = 0
openIdCount = 0
timeoutCount = 0
# 可能的参数
# wxp://f2f0e4PCkhToyNDT-zfA-Nn6zoAgPKvK9HUl
# https://qr.alipay.com/fkx03165mn5e2hx4gygpx04
# HTTPS://QR.ALIPAY.COM/FKX01227ZSFRLWLKZSHL9C
# https://payapp.weixin.qq.com/qr/AQEGbDUlzvPBxYKSJst3hENW?t=GAAG#wechat_pay
# https://payapp.weixin.qq.com/qr/AQHoz2ywjCZbBKqDrvUuHDqG?t=GAAG#wechat_pay
# 微信验证
# 微信为36位长度只包含-、_、数字和字母使用正则
wxp = re.compile(r'[^\w-]')
wxcode = str(data['wxcode'])
if isKong(wxcode):
wxcode = ''
else:
wxCache1 = re.findall(r"wxp://(.+)",wxcode)
wxCache2 = re.findall(r"https://payapp.weixin.qq.com/qr/(.+)\?t",wxcode)
if wxCache1:
# 第一种
if(len(wxCache1[0]) == 36):
if not (wxp.search(wxCache1[0])):
hrefCount = hrefCount + 1
else:
return False
else:
return False
elif wxCache2:
# 第二种
if(len(wxCache2[0]) == 24):
if not (wxp.search(wxCache2[0])):
hrefCount = hrefCount + 1
else:
return False
else:
return False
else:
# 都不是
return False
# openId验证
# openId为28位长度只包含-、_、数字和字母使用正则
openId = str(data['openId'])
if isKong(openId):
openId = ''
else:
if(len(openId) == 28):
if not (wxp.search(openId)):
openIdCount = 1
else:
return False
else:
return False
# 支付宝验证
# 支付宝为23位或22位长度只有数字和字母使用isalnum
alcode = str(data['alcode'])
alCache1 = re.findall(r"https://qr.alipay.com/(.+)",alcode)
alCache2 = re.findall(r"HTTPS://QR.ALIPAY.COM/(.+)",alcode)
if isKong(alcode):
alcode = ''
else:
if alCache1:
# 第一种
if len(alCache1[0]) == 23:
if alCache1[0].isalnum():
hrefCount = hrefCount + 1
else:
return False
else:
return False
elif alCache2:
# 第二种
if len(alCache2[0]) == 22:
if alCache2[0].isalnum():
hrefCount = hrefCount + 1
else:
return False
else:
return False
else:
return False
# QQ验证
# QQ 一定包含 'qianbao.qq.com',使用正则
# *!()_-.% 字母 数字 ,正则写不明白了woc
qqp = re.compile(r'qianbao.qq.com')
qqcode = str(data['qqcode'])
if isKong(qqcode):
qqcode = ''
else:
if(qqp.search(qqcode)):
hrefCount = hrefCount + 1
else:
return False
# 用户名验证
# 正则替换掉引号,$
username = str(data['username'])
if(not isKong(username)):
username = username.replace('"','')
username = username.replace("'",'')
username = username.replace('$','')
usernameCount = 1
else:
return False
# 备注验证
# 正则替换掉引号,$
node = str(data['node'])
if(not isKong(node)):
node = node.replace('"','')
node = node.replace("'",'')
node = node.replace('$','')
else:
node = ''
# 过期时间验证
timeout = str(data['timeout'])
if(not isKong(timeout)):
if len(timeout) == 13:
timeoutCount = 1
else:
return False
else:
return False
if hrefCount >= 2 and usernameCount and openIdCount and timeoutCount:
return {'username': username, 'node': node, 'wxcode': wxcode, 'alcode': alcode, 'qqcode': qqcode, 'openId': openId, 'timeout': timeout}
else:
return False
# 创建订单详情 Cache
def createOrderCache(data,params):
data['out_trade_no'] = params['out_trade_no']
data['create_time'] = int(time.time())
return data

108
backEnd/lib/db.py Normal file
View File

@ -0,0 +1,108 @@
from pymongo import MongoClient
from bson import ObjectId, json_util
# 主环境
setting = 'test'
# 获取数据集
def col(arg: str = None):
conn = MongoClient('mongodb://yingbo:623910ert@localhost:12236/yingbo')
param = None
if arg:
param = arg
else:
param = setting
if param == 'test':
return conn.yingbo.test
elif param == 'order':
return conn.yingbo.order
elif param == 'cache':
return conn.yingbo.cache
# 查找该用户所有信息
def findUser(openid):
arr = []
for i in col().find({'openId': openid}):
arr.append(i)
return json_util.dumps(arr)
# 查找该二维码所有信息
def findCode(id):
arr = []
try:
for i in col().find({"_id" : ObjectId(id)}):
arr.append(i)
except Exception as e:
# id不合法
return False
if(len(arr) == 0):
# 查询无结果
return False
return json_util.dumps(arr)
# 删除该二维码
def delCode(id):
try:
col().remove({"_id" : ObjectId(id)})
except Exception as e:
# id不合法
return False
return {'errcode': 200, 'errmsg': 'ok'}
# 用户上传进入缓存表
def insertOrderCache(data):
try:
col('cache').insert_one(data)
except Exception as e:
# 失败
return False
return True
# 用户付款回调 从缓存写进正式表
def cache2Test(out_trade_no,payjs_order_id):
try:
# 取出缓存表数据
cache = col('cache').find_one({"out_trade_no" : out_trade_no})
# 删除缓存表数据
col('cache').remove({"out_trade_no" : out_trade_no},1)
except Exception as e:
# 失败
return False
# 判断有没有,去重逻辑
if cache:
# 向原始数据中添加支付识别码
cache['payjs_order_id'] = payjs_order_id
# 插入到正式表
res = col().insert_one(cache)
# 返回插入的正式表id
inserted_id = res.inserted_id
# 放进order表建立 out_trade_no 到 objectId的 映射
try:
col('order').insert_one({'out_trade_no': out_trade_no, 'inserted_id': inserted_id})
except Exception as e:
# 失败
return False
return True
else:
return True
# 小程序端查询支付结果
def findOrder(out_trade_no):
arr = []
try:
for i in col('order').find({"out_trade_no" : out_trade_no}):
arr.append(i)
except Exception as e:
# 失败
return False
if(len(arr) == 0):
# 查询无结果
return False
else:
# 删除order中的记录
try:
col('order').remove({"out_trade_no" : out_trade_no})
except Exception as e:
# 失败
return False
return json_util.dumps(arr[0]['inserted_id'])

27
backEnd/lib/login.py Normal file
View File

@ -0,0 +1,27 @@
from requests import request
import json
def getOpenid(code):
url = 'https://api.weixin.qq.com/sns/jscode2session?appid=wx0df150c438e4c8f0&secret=e43b9f0356a29c8e5b39e79bb27376f1&js_code='+ code +'&grant_type=authorization_code'
response=request('GET',url)
if(response.status_code != 200):
return {
'errcode': response.status_code,
'errmsg': 'openid获取失败'
}
if('errcode' in response.json().keys()):
return {
'errcode': response.json()['errcode'],
'errmsg': response.json()['errmsg']
}
return {
'errcode': 200,
'errmsg': response.json()
}
#print(response.status_code) #返回状态码200
#print(response.encoding) #返回编码
#print(response.text) #返回响应的内容以unicode表示
#print(response.headers) #返回头信息
#print(response.cookies) #返回cookies CookieJar
#print(response.json()) #返回json数据

105
backEnd/lib/pay.py Normal file
View File

@ -0,0 +1,105 @@
from payjs import PayJS # 也可根据个人习惯选择使用 Payjs/PAYJS/payjs
from payjs import PayJSNotify # 也可根据个人习惯选择使用 PayjsNotify/PAYJSNotify
from signature import get_signature
import random
import time
MCHID = '1561399401'
KEY = 'C0vy3IlwgWn3TxJD'
# 初始化
p = PayJS(MCHID, KEY)
# 订单查询
def checkOrder():
res = p.check_status(payjs_order_id=r.payjs_order_id)
if res:
return res.paid # 是否已支付
else:
return {'errMsg': s.error_msg, 'err': s} # 错误信息
# 回调验证
def checkNotify(str):
return PayJSNotify(KEY, str)
# 创建微信小程序 Params
def createOrderParams(totalFee):
body = '收款码合并服务费' # 用户订单标题
nonce = random.randint(100000,999999) # 随机数
timestamp = int(time.time()) # 当前时间戳
outTradeNo = 'QR-WXPay-' + str(timestamp) + '-' + str(nonce) # 商户端订单号
notifyUrl = 'https://qr.powerrain.cn/notify' # 异步通知地址
attach = 'from wx' # 异步通知附加数据
paramsObject = {
'mchid': MCHID,
'total_fee': totalFee,
'out_trade_no': outTradeNo,
'body': body,
'attach': attach,
'notify_url': notifyUrl,
'nonce': nonce
}
sign = get_signature(KEY, paramsObject) # MD5签名算法签名
paramsObject['sign'] = sign
return paramsObject
# 扫码支付
# OUT_TRADE_NO = '2017TEST' # 外部订单号(自己的支付系统的订单号,请保证唯一)
# TOTAL_FEE = 1 # 支付金额,单位为分,金额最低 0.01 元最多 10000 元
# BODY = '测试支付' # 订单标题
# NOTIFY_URL = 'https://pay.singee.site/empty/' # Notify 网址
# ATTACH = 'info' # Notify 内容
# r = p.QRPay(out_trade_no=OUT_TRADE_NO, total_fee=TOTAL_FEE, body=BODY, notify_url=NOTIFY_URL, attach=ATTACH)
# if r:
# print(r.code_url) # 二维码地址weixin:// 开头,请使用此地址构建二维码)
# print(r.qrcode) # 二维码地址https:// 开头,为二维码图片的地址)
# print(r.payjs_order_id) # 订单号PAYJS 的)
# else:
# print(r.STATUS_CODE) # HTTP 请求状态码
# print(r.ERROR_NO) # 错误码
# print(r.error_msg) # 错误信息
# print(r)
# 构造收银台支付网址(仅构造链接,请使用浏览器 302 到这个网址,无法预检查调用是否成功)
# c = p.get_cashier_url(out_trade_no=OUT_TRADE_NO, total_fee=TOTAL_FEE, body=BODY, callback_url=CALLBACK_URL, notify_url=NOTIFY_URL, attach=ATTACH)
# print(c)
# JSApi 支付
# OPENID = '这里填写支付用户的 OpenID' # 支付用户在 PayJS 端的 OpenID可通过 get_openid 获取
# j = p.JSApiPay(out_trade_no=OUT_TRADE_NO, total_fee=TOTAL_FEE, openid=OPENID, body=BODY, notify_url=NOTIFY_URL, attach=ATTACH)
# if j:
# print(j.jsapi) # 用于发起支付的支付参数
# else:
# print(j.STATUS_CODE) # HTTP 请求状态码
# print(j.ERROR_NO) # 错误码
# print(j.error_msg) # 错误信息
# print(j)
# 刷卡支付
# AUTH_CODE = '这里填写用户侧 18 位数字' # 用户的支付条码或二维码所对应的数字
# m = p.MicroPay(out_trade_no=OUT_TRADE_NO, total_fee=TOTAL_FEE, auth_code=AUTH_CODE, body=BODY)
# print(m)
# 订单关闭
# def closeOrder():
# res = p.close(r.payjs_order_id)
# if res:
# return {'errMsg': 'ok', 'errCode': 200}
# else:
# return {'errMsg': res.return_msg, 'errCode': 500}
# # 订单退款
# def refundOrder():
# res = p.refund(r.payjs_order_id)
# if res:
# return {'errMsg': 'ok', 'errCode': 200}
# else:
# return {'errMsg': res.return_msg, 'errCode': 500}
# # 获取用户 OpenId
# def getOpenId():
# return p.get_openid(callback_url=CALLBACK_URL)

37
backEnd/lib/signature.py Normal file
View File

@ -0,0 +1,37 @@
from hashlib import md5
from urllib.parse import urlencode, unquote_plus
def get_signature(key: str, data: dict):
"""
签名过程如下
0. 忽略已经存在的 sign
1. 将所有参数名按照字典序排列并以 "参数1=值1&参数2=值2&参数3=值3" 的形式排序
2. 将上面的内容加上 "&key=KEY"KEY 为设置的商户密钥
3. 将组合后的字符串转换为大写 MD5
:param key: 商户密钥
:param data: 要签名的参数字典
:return: 签名后的字符串
:rtype: str
"""
d = data.copy()
# pop 掉 sign 字段
try:
d.pop('sign')
except KeyError:
pass
# pop 掉无效字段
p = sorted([x for x in d.items() if (x[1] or x[1] == 0)], key=lambda x: x[0])
p.append(('key', key))
p = unquote_plus(urlencode(p))
h = md5()
h.update(p.encode())
r = h.hexdigest().upper()
return r

98
backEnd/qrcode.py Normal file
View File

@ -0,0 +1,98 @@
import sys
sys.path.append('./lib')
import os
from flask import Flask, escape, url_for, request, render_template, redirect, abort, send_from_directory
from allFunction import manageLogin, findQR, flash, delQR, manageNotify, createOrder, checkOrder
app = Flask(__name__)
if __name__ == '__main__':
app.run()
# 用户小程序登录
@app.route('/login',methods=['POST'])
def login():
res = manageLogin(request)
if(res):
return res
else:
abort(400)
# 用户扫描二维码
@app.route('/qr',methods=['GET'])
def qr():
res = findQR(request)
if(res):
return render_template('qrcode.html',data = res)
else:
abort(410)
# 小程序刷新用户信息
@app.route('/reflash',methods=['POST'])
def reflash():
res = flash(request)
if(res):
return res
else:
abort(400)
# 用户删除二维码
@app.route('/del',methods=['POST'])
def delQRCode():
res = delQR(request)
if(res):
return res
else:
abort(400)
# 创建新的订单
@app.route('/newOrder',methods=['POST'])
def newOrder():
res = createOrder(request)
if(res):
return res
else:
abort(400)
# 处理订单异步通知
@app.route('/notify',methods=['POST'])
def notify():
manageNotify(request)
return 'ok'
# 小程序查询订单状态
@app.route('/checkOrder',methods=['POST'])
def check():
res = checkOrder(request)
print(res)
if res:
return res
else:
abort(500)
# 图标
@app.route('/favicon.ico')
def favicon():
return send_from_directory(os.path.join(app.root_path, 'static'),'favicon.ico', mimetype='image/vnd.microsoft.icon')
# 二维码查询失败重定向, 404
@app.errorhandler(404)
def page_not_found(e):
return render_template('404.html'), 404
@app.errorhandler(400)
def page_not_found(e):
return render_template('400.html'), 400
@app.errorhandler(500)
def page_not_found(e):
return render_template('500.html'), 500
@app.errorhandler(410)
def page_not_found(e):
return render_template('410.html'), 500
# 目前的安全模式依赖于限制post访问非对称加密校验对所有内容进行规则审查
# 主要还是防止有人恶意访问等到写密码本的时候尝试模拟ssl加密模式

BIN
backEnd/static/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -0,0 +1,59 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/>
<meta name="format-detection" content="telephone=no,email=no,date=no,address=no">
<title>参数错误</title>
<style type="text/css">
body{height:100%;width:100%;margin:0; padding:0; font-size:14px; font-family:"微软雅黑",Arial, Helvetica, sans-serif;color: #333;}
img{ border:0;outline: none;}
body {
background: #33065b;
-moz-user-select: none;
-khtml-user-select: none;
user-select: none;
}
.bg {
display: block;
height: auto;
width: 100%;
position: fixed;
bottom:0;
left: 0;
z-index: -1;
}
.title {
width: 80%;
margin: 0 auto;
font-size: 1rem;
color: #fff;
margin-top: 4rem;
}
.content {
width: 80%;
margin: 0 auto;
font-size: .625rem;
color:#fff;
margin-top:0.3rem;
}
</style>
<script type="text/javascript">
//px2rem
window.onresize = setHtmlFontSize
function setHtmlFontSize () {
const htmlWidth = document.documentElement.clientWidth || document.body.clientWidth
const htmlDom = document.getElementsByTagName('html')[0]
if(htmlWidth >= 500) htmlDom.style.fontSize = 500 / 10 + 'px'
else htmlDom.style.fontSize = htmlWidth / 10 + 'px'
}
setHtmlFontSize();
</script>
</head>
<body>
<img class="bg" src="https://gss0.baidu.com/9vo3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/b7003af33a87e950544a28181f385343fbf2b461.jpg" alt="">
<div class="title">主人~</div>
<div class="content">参数有点奇怪呢</div>
</body>
</html>

View File

@ -0,0 +1,59 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/>
<meta name="format-detection" content="telephone=no,email=no,date=no,address=no">
<title>页面走丢了</title>
<style type="text/css">
body{height:100%;width:100%;margin:0; padding:0; font-size:14px; font-family:"微软雅黑",Arial, Helvetica, sans-serif;color: #333;}
img{ border:0;outline: none;}
body {
background: #33065b;
-moz-user-select: none;
-khtml-user-select: none;
user-select: none;
}
.bg {
display: block;
height: auto;
width: 100%;
position: fixed;
bottom:0;
left: 0;
z-index: -1;
}
.title {
width: 80%;
margin: 0 auto;
font-size: 1rem;
color: #fff;
margin-top: 4rem;
}
.content {
width: 80%;
margin: 0 auto;
font-size: .625rem;
color:#fff;
margin-top:0.3rem;
}
</style>
<script type="text/javascript">
//px2rem
window.onresize = setHtmlFontSize
function setHtmlFontSize () {
const htmlWidth = document.documentElement.clientWidth || document.body.clientWidth
const htmlDom = document.getElementsByTagName('html')[0]
if(htmlWidth >= 500) htmlDom.style.fontSize = 500 / 10 + 'px'
else htmlDom.style.fontSize = htmlWidth / 10 + 'px'
}
setHtmlFontSize();
</script>
</head>
<body>
<img class="bg" src="https://gss0.baidu.com/9vo3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/b7003af33a87e950544a28181f385343fbf2b461.jpg" alt="">
<div class="title">抱歉,</div>
<div class="content">您访问的页面不存在</div>
</body>
</html>

View File

@ -0,0 +1,59 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/>
<meta name="format-detection" content="telephone=no,email=no,date=no,address=no">
<title>二维码已失效</title>
<style type="text/css">
body{height:100%;width:100%;margin:0; padding:0; font-size:14px; font-family:"微软雅黑",Arial, Helvetica, sans-serif;color: #333;}
img{ border:0;outline: none;}
body {
background: #33065b;
-moz-user-select: none;
-khtml-user-select: none;
user-select: none;
}
.bg {
display: block;
height: auto;
width: 100%;
position: fixed;
bottom:0;
left: 0;
z-index: -1;
}
.title {
width: 80%;
margin: 0 auto;
font-size: 1rem;
color: #fff;
margin-top: 4rem;
}
.content {
width: 80%;
margin: 0 auto;
font-size: .625rem;
color:#fff;
margin-top:0.3rem;
}
</style>
<script type="text/javascript">
//px2rem
window.onresize = setHtmlFontSize
function setHtmlFontSize () {
const htmlWidth = document.documentElement.clientWidth || document.body.clientWidth
const htmlDom = document.getElementsByTagName('html')[0]
if(htmlWidth >= 500) htmlDom.style.fontSize = 500 / 10 + 'px'
else htmlDom.style.fontSize = htmlWidth / 10 + 'px'
}
setHtmlFontSize();
</script>
</head>
<body>
<img class="bg" src="https://gss0.baidu.com/9vo3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/b7003af33a87e950544a28181f385343fbf2b461.jpg" alt="">
<div class="title">抱歉,</div>
<div class="content">该二维码已失效</div>
</body>
</html>

View File

@ -0,0 +1,59 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/>
<meta name="format-detection" content="telephone=no,email=no,date=no,address=no">
<title>服务器开小差了</title>
<style type="text/css">
body{height:100%;width:100%;margin:0; padding:0; font-size:14px; font-family:"微软雅黑",Arial, Helvetica, sans-serif;color: #333;}
img{ border:0;outline: none;}
body {
background: #33065b;
-moz-user-select: none;
-khtml-user-select: none;
user-select: none;
}
.bg {
display: block;
height: auto;
width: 100%;
position: fixed;
bottom:0;
left: 0;
z-index: -1;
}
.title {
width: 80%;
margin: 0 auto;
font-size: 1rem;
color: #fff;
margin-top: 4rem;
}
.content {
width: 80%;
margin: 0 auto;
font-size: .625rem;
color:#fff;
margin-top:0.3rem;
}
</style>
<script type="text/javascript">
//px2rem
window.onresize = setHtmlFontSize
function setHtmlFontSize () {
const htmlWidth = document.documentElement.clientWidth || document.body.clientWidth
const htmlDom = document.getElementsByTagName('html')[0]
if(htmlWidth >= 500) htmlDom.style.fontSize = 500 / 10 + 'px'
else htmlDom.style.fontSize = htmlWidth / 10 + 'px'
}
setHtmlFontSize();
</script>
</head>
<body>
<img class="bg" src="https://gss0.baidu.com/9vo3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/b7003af33a87e950544a28181f385343fbf2b461.jpg" alt="">
<div class="title">哎呀~</div>
<div class="content">服务器开小差了呢</div>
</body>
</html>

View File

@ -0,0 +1,317 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>收款码合成</title>
<meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/>
<meta name="format-detection" content="telephone=no,email=no,date=no,address=no">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<script type="text/javascript">
var setting = {
username:"",
qqpay: "",
wxpay: "",
alpay: "",
id:"",
qrcodeApi: "http://qr.topscan.com/api.php?text="
}
var bgs = ['https://qrcode-1256486458.cos.ap-chengdu.myqcloud.com/bg/bg1.jpg',
'https://qrcode-1256486458.cos.ap-chengdu.myqcloud.com/bg/bg2.jpg',
'https://qrcode-1256486458.cos.ap-chengdu.myqcloud.com/bg/bg3.jpg',
'https://qrcode-1256486458.cos.ap-chengdu.myqcloud.com/bg/bg4.jpg',
'https://qrcode-1256486458.cos.ap-chengdu.myqcloud.com/bg/bg5.jpg',
'https://qrcode-1256486458.cos.ap-chengdu.myqcloud.com/bg/bg6.jpg',]
//获取到后端信息
var data = {{data|tojson}};
//初始化
function init() {
data = JSON.parse(data);
data = data[0]
// 判断时间
var timeout = parseInt(data.timeout)
timeout = new Date(timeout)
var now = new Date()
if(timeout - now <= 0) window.location.replace("https://qr.powerrain.cn/qr");
// 换背景
ele('bg').src = bgs[Math.floor(Math.random()*bgs.length)]
setting.id = data._id.$oid
setting.alpay= data.alcode;
setting.qqpay=data.qqcode;
setting.wxpay=data.wxcode;
setting.username=data.username;
if(setting.qqpay)setting.qqpay = decodeURIComponent(setting.qqpay);
console.log(setting);
manangeUrl();
}
function ele(id) {
return document.getElementById(id);
}
function showIcon() {
if(setting.alpay){
ele("al").style.display = "block";
}
if(setting.wxpay){
ele("wx").style.display = "block";
}
if(setting.qqpay){
ele("qq").style.display = "block";
}
}
function urlEncode(String) {
return encodeURIComponent(String).replace(/'/g,"%27").replace(/"/g,"%22");
}
function noSupport(text,type) {
//遗留问题,等有了域名再说,微信访问会自带参数啥的生成一个超级复杂的二维码
console.log(window.location.hostname)
ele("qrcode").setAttribute("src",setting.qrcodeApi + urlEncode(window.location.href));
ele("all").style.display = "block";
ele("user").innerHTML=setting.username;
showIcon();
if(type === 1) alert("本二维码不支持" + text + "支付"); //其他浏览器是0
}
function manangeUrl(){
if(navigator.userAgent.match(/Alipay/i)) {
//支付宝扫码
if(setting.alpay){
window.location.href = setting.alpay;
}else{
//木有支付宝的链接
noSupport("支付宝",1);
}
} else if(navigator.userAgent.match(/MicroMessenger\//i)) {
if(setting.wxpay){
ele("qrcode1").setAttribute("src",setting.qrcodeApi + urlEncode(setting.wxpay));
ele("wq").style.display = "block";
ele("wq_b").setAttribute("class","wx_b");
ele("title").innerHTML="推荐使用微信支付";
ele("user1").innerHTML=setting.username;
ele("wq_pay").setAttribute("src","https://gss0.baidu.com/-4o3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/f7246b600c3387445f39938f5c0fd9f9d62aa041.jpg");
}else{
//木有微信的链接
noSupport("微信",1)
}
} else if(navigator.userAgent.match(/QQ\//i)) {
if(setting.qqpay){
ele("qrcode1").setAttribute("src",setting.qrcodeApi + urlEncode(setting.qqpay));
ele("wq").style.display = "block";
ele("wq_b").setAttribute("class","qq_b");
ele("title").innerHTML="推荐使用QQ支付";
ele("user1").innerHTML=setting.username;
ele("wq_pay").setAttribute("src","https://gss0.baidu.com/-vo3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/060828381f30e9243d5820c241086e061c95f741.jpg");
}else{
//木有QQ的链接
noSupport("QQ",1);
}
} else {
noSupport('',0);
}
}
window.onload = function() {
init();
}
</script>
<style type="text/css">
@charset "utf-8";
h1, h2, h3, h4, h5, h6,p, li, label, td, th {cursor: text;}
a:link, a:visited, a:hover, a:active { cursor: pointer;}
body{height:100%;width:100%;margin:0; padding:0; font-size:14px; font-family:"微软雅黑",Arial, Helvetica, sans-serif;color: #333;}
div,p,ul,ol,li,dl,dt,dd,h1,h2,h3,h4,h5,h6,form,input,select,textarea,table,td{ margin:0; padding:0;}
h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}
area{outline:none;}
img{ border:0;outline: none;}
ol,ul{list-style:none;}
a{ font-family:"微软雅黑",Arial, Helvetica, sans-serif;text-decoration:none;outline:none;}
a:hover{ text-decoration:none;}
.clearfix:after {content:"";display:block;height:0;clear:both;}
.clearfix {zoom:1;}
.all {
display: none;
width:100%;
height:100%;
}
.all .main {
display: flex;
max-width: 400px;
width:100%;
flex-direction: column;
margin:0 auto;
align-items: center;
position: relative;
}
.all .background {
height:100%;
width:100%;
position:absolute;
top:0;
}
.all .main .qrcode {
margin-top:30px;
width:80%;
}
.all .main .user {
font-size:25px;
color: #fff;
margin-top:30px;
font-weight: bold;
}
.all .main .title {
font-size:20px;
color: #fff;
margin-top:30px;
}
.all .main .imageBox {
margin-top: 30px;
height:50px;
width:80%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.all .imageBox>div {
height:50px;
width:52px;
background-image: url(https://gss0.baidu.com/9fo3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/b64543a98226cffc74a50341b4014a90f703eab2.jpg);
background-size: cover;
}
.all .imageBox .wx {
background-position-x:-12px;
display: none;
}
.all .imageBox .al {
display: none;
background-position-x:-276px;
}
.all .imageBox .qq {
display: none;
background-position-x:-138px;
}
.wq {
display: none;
height:100%;
width:100%;
}
.wq .wx_b {
height:100%;
width:100%;
position:absolute;
top:0;
background: #09bb07;
}
.wq .qq_b {
height:100%;
width:100%;
position:absolute;
top:0;
background-image:linear-gradient(180deg, #0088cc, #01cfff);
}
.wq .w {
display: flex;
max-width: 400px;
width:100%;
flex-direction: column;
margin:0 auto;
align-items: center;
position: relative;
}
.wq .footer {
position: fixed;
bottom: 0;
width:100%;
}
.wq .pay {
background: #fff;
max-width: 500px;
width:100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin: 0 auto;
}
.wq .pay>img {
width: 60%;
margin-top:20px;
margin-bottom: 20px;
}
.wq .title {
font-size: 35px;
color: #fff;
margin-top:30px;
letter-spacing:3px;
}
.wq .qrcode {
margin-top:30px;
width:80%;
}
.wq .user {
font-size:30px;
color: #fff;
margin-top:30px;
}
</style>
</head>
<body>
<div class="all" id="all">
<!-- <img class="background" src="https://gss0.baidu.com/94o3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/2934349b033b5bb5092b9c0d3bd3d539b700bc41.jpg"> -->
<img class="background" id="bg">
<div class='main'>
<image class='qrcode' id='qrcode' src=""></image>
<div class='user' id='user'></div>
<div class='title'>本二维码支持以下APP向我付款</div>
<div class='imageBox'>
<div class='wx' id='wx'></div>
<div class='al' id='al'></div>
<div class='qq' id='qq'></div>
</div>
</div>
</div>
<div class="wq" id="wq">
<div class="" id="wq_b"></div>
<div class="w">
<div class="title" id='title'></div>
<image class='qrcode' id='qrcode1' src=""></image>
<div class='user' id='user1'></div>
</div>
<div class="footer">
<div class="pay">
<img id="wq_pay" src="">
</div>
</div>
</div>
</body>
</html>

View File

@ -44,6 +44,7 @@ Page({
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
wx.hideShareMenu()
this.setData({
yiyan : wx.getStorageSync('yiyan'),
})
@ -289,8 +290,8 @@ Page({
qq: true,
al: true
}
var text = '英博'
var id = '5dc6d61074d52b3774ab3e25'
var text = '最佳案例'
var id = '5dcc19b74f5a926dc227431e'
}
else {
// 在这里还要完成页面的切换操作
@ -353,7 +354,7 @@ Page({
canvas.font = fontSet2;
canvas.fillText('本二维码支持以下APP向我付款', 316*rpx, 760*rpx)
wx.downloadFile({
url: 'https://gss0.baidu.com/9fo3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/b64543a98226cffc74a50341b4014a90f703eab2.jpg',
url: 'https://qrcode-1256486458.cos.ap-chengdu.myqcloud.com/sprite/sprite1.png',
success:function(res) {
canvasimgbg = res.tempFilePath
//先画左右,再画中间

View File

@ -20,6 +20,7 @@ Page({
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
wx.hideShareMenu()
this.init();
},
@ -74,8 +75,8 @@ Page({
//初始化
init : function() {
// 一共个进程
this.flag = 3
// 一共个进程
this.flag = 2
// 登录
var that = this
api.login(function(info,openid) {
@ -87,32 +88,6 @@ Page({
api.getyiyian(()=> {
that.flag = util.checkFlag('yiyan',that.flag,that.jumpToHome)
})
this.getSystemUserInfo()
},
//获取用户信息以及权限
getSystemUserInfo() {
var that = this;
wx.getSetting({
success(res) {
if (res.authSetting['scope.userInfo']) {
// 已经授权,可以直接调用 getUserInfo 获取头像昵称
wx.getUserInfo({
success(res) {
wx.setStorageSync('userInfo', res.userInfo);
that.setData({
showButton:false
})
that.flag = util.checkFlag('信息',that.flag,that.jumpToHome)
}
})
} else {
that.setData({
showButton:true
})
}
}
})
},
// 跳到主页

View File

@ -4,7 +4,7 @@
"ignore": []
},
"setting": {
"urlCheck": false,
"urlCheck": true,
"es6": true,
"postcss": true,
"minified": true,