积分开奖台
上证指数 × 深证成指,倒序取号,快速核验。
""" 积分抽奖 Web 应用 """ from flask import Flask, request, render_template_string, jsonify from datetime import datetime from urllib import request as urlrequest import re app = Flask(__name__, static_folder='static') # ============ 计算逻辑 ============ def _fetch_text(url, headers=None, timeout=6): req = urlrequest.Request(url, headers=headers or {}) with urlrequest.urlopen(req, timeout=timeout) as resp: raw = resp.read() return raw.decode('gbk', errors='ignore') def fetch_tencent_indices(): text = _fetch_text( 'https://qt.gtimg.cn/q=s_sh000001,s_sz399001', headers={'User-Agent': 'Mozilla/5.0'} ) values = {} for code, payload in re.findall(r'v_s_(sh000001|sz399001)="([^"]*)"', text): parts = payload.split('~') if len(parts) > 3 and parts[3]: values[code] = { 'name': parts[1], 'value': parts[3], 'change': parts[4] if len(parts) > 4 else '', 'percent': parts[5] if len(parts) > 5 else '' } if 'sh000001' not in values or 'sz399001' not in values: raise ValueError('腾讯行情返回格式异常') return { 'source': '腾讯行情', 'shangzheng': values['sh000001']['value'], 'shenzheng': values['sz399001']['value'], 'items': values } def fetch_sina_indices(): text = _fetch_text( 'https://hq.sinajs.cn/list=s_sh000001,s_sz399001', headers={ 'User-Agent': 'Mozilla/5.0', 'Referer': 'https://finance.sina.com.cn/' } ) values = {} for code, payload in re.findall(r'hq_str_s_(sh000001|sz399001)="([^"]*)"', text): parts = payload.split(',') if len(parts) > 1 and parts[1]: values[code] = { 'name': parts[0], 'value': parts[1], 'change': parts[2] if len(parts) > 2 else '', 'percent': parts[3] if len(parts) > 3 else '' } if 'sh000001' not in values or 'sz399001' not in values: raise ValueError('新浪行情返回格式异常') return { 'source': '新浪行情', 'shangzheng': values['sh000001']['value'], 'shenzheng': values['sz399001']['value'], 'items': values } def fetch_indices(): errors = [] for fetcher in (fetch_tencent_indices, fetch_sina_indices): try: data = fetcher() data['fetched_at'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S') return data except Exception as exc: errors.append(f'{fetcher.__name__}: {exc}') raise RuntimeError('; '.join(errors)) def calc_lottery(shangzheng, shenzheng, draw_date=None): """ 计算中奖号码 shangzheng: 上证指数(如 2025.50) shenzheng: 深证成指(如 7217.65) draw_date: 开奖日期,格式 YYYY-MM-DD 或 YYYY-MM """ if not draw_date: draw_date = datetime.now().strftime('%Y-%m-%d') # 解析日期 if '-' in str(draw_date): parts = str(draw_date).split('-') month = parts[1].zfill(2) if len(parts) > 1 and parts[1] else '01' day = parts[2].zfill(2) if len(parts) > 2 and parts[2] else '01' else: month = '01' day = '01' # 步骤展示 steps = [] # 第1步:乘法 product_raw = float(shangzheng) * float(shenzheng) product_str = str(product_raw) steps.append({ 'step': 1, 'desc': f'上证指数 × 深证成指', 'formula': f'{shangzheng} × {shenzheng}', 'result': product_str }) # 第2步:去小数点 product_no_dot = product_str.replace('.', '') steps.append({ 'step': 2, 'desc': '去除小数点', 'formula': f'{product_str} → 去除"."', 'result': product_no_dot }) # 第3步:倒序 reversed_str = product_no_dot[::-1] steps.append({ 'step': 3, 'desc': '数字倒序排列', 'formula': f'{product_no_dot} → 倒序', 'result': reversed_str }) # 第4步:提取各等奖 # 一等奖:第1-4位 prize1 = reversed_str[0:4] # 二等奖:第2-5位、第3-6位 prize2 = [reversed_str[1:5], reversed_str[2:6]] # 三等奖:第4-7位、第5-8位、第6-9位 prize3 = [reversed_str[3:7], reversed_str[4:8], reversed_str[5:9]] # 幸运奖:0000-9999 lucky = [f'{i:04d}' for i in range(10)] # 幸福奖:只命中两位日期,不看月份。 # 如11月20日:20XX、X20X、XX20;11月3日使用03。 happy_patterns = [f'{day}XX', f'X{day}X', f'XX{day}'] steps.append({ 'step': 4, 'desc': '提取各等奖号码', 'prize1': prize1, 'prize2': prize2, 'prize3': prize3, 'lucky': lucky, 'happy': happy_patterns, 'happy_day': day, 'date_info': {'month': month, 'day': day, 'date_str': f'{month}月{day}日'} }) return { 'base': reversed_str, 'prize1': prize1, 'prize2': prize2, 'prize3': prize3, 'lucky': lucky, 'happy': happy_patterns, 'happy_day': day, 'date_info': {'month': month, 'day': day, 'date_str': f'{month}月{day}日'}, 'steps': steps, 'raw_input': {'shangzheng': shangzheng, 'shenzheng': shenzheng, 'draw_date': draw_date} } def check_lottery(user_numbers, result): """ 验证用户号码是否中奖 user_numbers: 如 "9613,9483,7484,8628,5208" """ # 拆分号码 raw = user_numbers.replace(' ', '').replace(',', ',') codes = [c.strip() for c in raw.split(',') if c.strip()] all_4digit = [] for code in codes: # 每4位一组 for i in range(0, len(code), 4): chunk = code[i:i+4] if len(chunk) == 4: all_4digit.append(chunk) prize1 = result['prize1'] prize2 = result['prize2'] prize3 = result['prize3'] lucky = result['lucky'] happy_day = result['happy_day'] matched = [] for num in all_4digit: hit = {'number': num, 'prizes': []} if num == prize1: hit['prizes'].append(f'一等奖!') if num in prize2: hit['prizes'].append(f'二等奖!') if num in prize3: hit['prizes'].append(f'三等奖!') if num in lucky: hit['prizes'].append(f'幸运奖!') if num[0:2] == happy_day or num[1:3] == happy_day or num[2:4] == happy_day: hit['prizes'].append(f'幸福奖!') if hit['prizes']: hit['status'] = '命中' else: hit['status'] = '未命中' matched.append(hit) return matched # ============ 路由 ============ @app.route('/') def index(): return render_template_string(HTML_TEMPLATE) @app.route('/calc', methods=['POST']) def calc(): data = request.get_json(silent=True) or {} shangzheng = data.get('shangzheng', '') shenzheng = data.get('shenzheng', '') draw_date = data.get('draw_date', '') if not shangzheng or not shenzheng: return jsonify({'error': '请提供上证和深证指数'}) try: result = calc_lottery(shangzheng, shenzheng, draw_date) return jsonify(result) except Exception as e: return jsonify({'error': str(e)}) @app.route('/check', methods=['POST']) def check(): data = request.get_json(silent=True) or {} user_numbers = data.get('numbers', '') shangzheng = data.get('shangzheng', '') shenzheng = data.get('shenzheng', '') draw_date = data.get('draw_date', '') if not shangzheng or not shenzheng: return jsonify({'error': '请提供上证和深证指数'}) try: result = calc_lottery(shangzheng, shenzheng, draw_date) matched = check_lottery(user_numbers, result) return jsonify({ 'result': result, 'matched': matched, 'has_numbers': bool(user_numbers.strip()) }) except Exception as e: return jsonify({'error': str(e)}) @app.route('/indices') def indices(): try: return jsonify(fetch_indices()) except Exception as e: return jsonify({ 'error': '自动获取指数失败,请手动输入', 'details': str(e) }), 502 HTML_TEMPLATE = '''
上证指数 × 深证成指,倒序取号,快速核验。