<<>> === config.php === 'https://duoptgl.sbs', 'database' => [ 'host' => '127.0.0.1', 'port' => 3306, 'name' => 'sql_duoptgl_sbs', 'user' => 'sql_duoptgl_sbs', 'password' => '959318a3dd5bd8', ], // Choose a private, random string of at least 24 characters for installation. // This is not the administrator password. Remove it after installation. 'setup_key' => 'd0c7eb0bd9074c503b259785ac65ab184b49f688606132ed', 'allow_http_local' => false, ]; === app.py (routes) === 1: import json 2: import logging 3: import os 4: from sqlite_runtime import sqlite3 5: import mimetypes 6: from http.cookies import SimpleCookie 7: from pathlib import Path 8: from urllib.parse import parse_qs, urlparse 9: from core import Service, Error, ROOT, DEFAULTS, dumps, text, digest, verify_password 10: from reporting import generate, export_archive 11: from wechat import WeChat, create_recharge, apply_success 13: def load_config(): 19: def __init__(self,config=None,service=None): 21: self.payment=WeChat(self.config,ROOT);self.report_dir=Path(self.service.database).parent/'reports' 22: def public(self): 27: def state(self,actor,query): 48: result['orders']=[];result['recharges']=[];result['requests']=[];result['settlements']=[];result['transfers']=[];result['reports']=[];result['audit']=[];result['users']=[] 57: result['reports']=[dict(r) for r in c.execute('SELECT * FROM reports'+condition+' ORDER BY created_at DESC LIMIT 100',args)] 63: def __call__(self,environ,start_response): 69: except (KeyError,ValueError,TypeError):status=400;content=dumps({'error':'请求字段缺失或格式不正确'}).encode();headers.append(('Content-Type','application/json; charset 72: reason={200:'OK',400:'Bad Request',401:'Unauthorized',403:'Forbidden',404:'Not Found',409:'Conflict',413:'Payload Too Large',429:'Too Many Requests',500:'Internal Server Error',502 74: def route(self,e): 93: # Origin check covers cookie login and mutations; native mini-program requests have no Origin. 95: if path=='/api/login' and method=='POST': 96: session=self.service.login(body.get('kind','staff'),body.get('username',''),body.get('password',''),e.get('REMOTE_ADDR','unknown')) 97: cookie=f'salon_session={session["token"]}; Path=/; HttpOnly; SameSite=Strict; Max-Age=28800' 100: bearer=e.get('HTTP_AUTHORIZATION','');cookie=SimpleCookie();cookie.load(e.get('HTTP_COOKIE','')) 101: token=bearer[7:] if bearer.startswith('Bearer ') else (cookie['salon_session'].value if 'salon_session' in cookie else '') 102: if path=='/api/mini/login' and method=='POST': 112: # Use the same persisted attempt limit as ordinary member login when linking a pre-existing account. 113: checked=self.service.login('member',phone,body.get('password',''),e.get('REMOTE_ADDR','unknown')) 114: with self.service.tx() as write:write.execute('DELETE FROM sessions WHERE token_hash=?',(digest(checked['token']),)) 121: if existing['openid'] or not verify_password(body.get('password',''),existing['pin_hash']):raise Error('绑定已有手机号须提供正确会员密码',401) 123: else:mid=self.service._member(c,body.get('name','微信会员'),phone,body.get('password',''),openid) 125: session=self.service.session(c,mid,'member');self.service.audit(c,mid,'mini.login',mid,{}) 127: actor=self.service.actor(token) 128: if method=='POST' and not bearer.startswith('Bearer ') and e.get('HTTP_X_CSRF_TOKEN')!=actor['csrf']:raise Error('请求校验失败,请刷新页面',403) 131: with self.service.tx() as c:c.execute('DELETE FROM sessions WHERE token_hash=?',(digest(token),)) 133: if path=='/api/export' and method=='POST': 134: return 200,export_archive(self.service,actor),[('Content-Type','application/zip'),('Content-Disposition','attachment; filename="membership-business-export.zip"')] 135: if method=='GET' and path.startswith('/api/report/'): 137: with self.service.db() as c:r=self.service.row(c,'reports',path.split('/')[-1]) 139: data=(self.report_dir/r['filename']).read_bytes();return 200,data,[('Content-Type','application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'),('Content-Disposition','atta 140: if method=='POST' and path=='/api/report/generate': 143: result=generate(self.service,body['month'],self.report_dir,store) 146: def action(c,a,b):return create_recharge(self.service,c,a,b,self.payment) 147: result=self.service.mutate(actor,e.get('HTTP_IDEMPOTENCY_KEY',''),body,action) 158: actions={'/api/stores':self.service.create_store,'/api/stores/status':self.service.toggle_store,'/api/users':self.service.create_user,'/api/users/update':self.service.update_user,' 160: result=self.service.mutate(actor,e.get('HTTP_IDEMPOTENCY_KEY',''),body,actions[path]);return 200,dumps(result).encode(),response_headers === storage dir === .htaccess 19b install.lock 0b runtime.php 397b worker.lock 0b <<>> 红果Ai短剧 看剧就来这看 这看不烧心 特爽快《最好使用wifi 移动容易屏蔽》 - al成人高清无码视频在线观看古代剧 现代剧 穿越剧 重生剧应有尽有
红果一区
欧美精品
国产乱淫
麻豆传媒
网曝门
主播网红
呦童学生
最新黑料
巨乳尤物
更多视频
红果二区
校花班花
TS专区
探花系列
日本无码
红果短剧
套套短剧
人妻淫乱
收租老头
红楼短剧
红果三区
OnlyFans
国产传媒
探花系列
主播秀色
迷奸嫂嫂
无毛女大
熊猫短剧
系统剧
外围探花
红果四区
网爆黑料
美乳巨乳
少女萝莉
抖音视频
职院女大
穿越古代
后宫爽剧
魔都剧
热播短剧

热门搜索

网曝门 · 筛选