Commit 48ad50d8 authored by xianyang's avatar xianyang

月度统计接口

parent f0090492
from concurrent.futures.thread import ThreadPoolExecutor
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from app.api.export import schemas from core.config.env import env
from libs.business import TYPE_NAME
from libs.db_link import LinkMysql
from libs.functions import get_now_datetime from libs.functions import get_now_datetime
from libs.orm import QueryAllData from libs.orm import QueryAllData
from models.export import ExportFile from models.export import ExportFile
import pandas as pd
from starlette.responses import StreamingResponse
def get_export_list(db: Session, param): def get_export_list(db: Session, param):
...@@ -58,3 +64,76 @@ def create_export_data(db: Session, export, operator): ...@@ -58,3 +64,76 @@ def create_export_data(db: Session, export, operator):
def get_source_data(db): def get_source_data(db):
res = db.query(ExportFile.source).filter().group_by('source').all() res = db.query(ExportFile.source).filter().group_by('source').all()
return [i[0] for i in res] return [i[0] for i in res]
class CalculationMonthlyBill(object):
"""月度计算,出入账目"""
def __init__(self):
self.structure_list = []
self.structure_key = []
@staticmethod
def data_to_table(data):
"""数据导出"""
bk = pd.DataFrame(data)
with pd.ExcelWriter(f'static/业务类型月度汇总报表.xlsx') as writer:
bk.to_excel(writer, sheet_name='业务类型月度汇总', index=False)
file = open(writer, 'rb')
return StreamingResponse(file, media_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
def month_statistics_task(self, date, page, size):
"""主函数"""
db = env.MysqlDB
db["database"] = env.DB_HISTORY
sql = f"SELECT reference_type, type, SUM(cast(amount as decimal(20,6)))/1000 as money FROM {date} GROUP BY reference_type, type ORDER BY reference_type"
res_data = LinkMysql(db).query_mysql(sql)
for res in res_data:
if res["reference_type"] in self.structure_key:
continue
if res["reference_type"] in TYPE_NAME:
name = TYPE_NAME[res["reference_type"]]
else:
name = res["reference_type"]
out = [i['money'] for i in res_data if i['reference_type'] == res["reference_type"] and i['type'] == 0]
income = [i['money'] for i in res_data if i['reference_type'] == res["reference_type"] and i['type'] == 1]
out_value = float(out[0]) if out else 0
income_value = float(income[0]) if income else 0
a = {
"name": name,
"type": res["reference_type"],
"expenditure": out_value,
"income": income_value,
"is_error": 0 if out_value == income_value else 1,
"error_money": float('%.2f' % (out_value - income_value))
}
self.structure_key.append(res["reference_type"])
self.structure_list.append(a)
# return self.data_to_table(self.structure_list) # 导出接口
return self.structure_list[(page-1)*size:page*size], len(self.structure_list)
class CalculationMonthlyDetails(object):
@staticmethod
def data_query(db, date, reference_type, is_out, page, size):
sql = f"SELECT reference_type,order_number,type,cast(amount as decimal(20,6))/1000 as money,amount_type,create_time FROM {date} where reference_type='{reference_type}' and type={is_out} LIMIT {(page-1)*size},{size}"
res_data = LinkMysql(db).query_mysql(sql)
return res_data
@staticmethod
def acquired_total(db, date, reference_type, is_out,):
sql = f"SELECT reference_type FROM {date} where reference_type='{reference_type}' and type={is_out}"
result = LinkMysql(db).query_mysql(sql)
return len(result)
def statement_income_expenditure(self, param):
database = env.MysqlDB
database["database"] = env.DB_HISTORY
with ThreadPoolExecutor(max_workers=4) as pool:
future1 = pool.submit(self.data_query, database, 'assets_log_' + param.date, param.key, param.is_income, param.page, param.size)
future2 = pool.submit(self.acquired_total, database, 'assets_log_' + param.date, param.key, param.is_income)
data = future1.result()
num = future2.result()
return data, num
from typing import Optional from typing import Optional
from pydantic import BaseModel from pydantic import BaseModel, validator
from pydantic import ValidationError
class ExportList(BaseModel): class ExportList(BaseModel):
...@@ -13,3 +14,20 @@ class ExportList(BaseModel): ...@@ -13,3 +14,20 @@ class ExportList(BaseModel):
class ExportUpdateData(BaseModel): class ExportUpdateData(BaseModel):
id: int id: int
remark: str = "" remark: str = ""
class MonthStatistics(BaseModel):
date: str = ""
page: int
size: int
class MonthDetails(MonthStatistics):
key: str
is_income: int
# @validator('key')
# def key_must_contain_space(cls, v):
# if ' ' not in v:
# raise ValidationError('缺少必传参数key')
# return v.title()
from datetime import datetime
from dateutil.relativedelta import relativedelta
from fastapi import Depends, APIRouter from fastapi import Depends, APIRouter
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from app import get_db from app import get_db
...@@ -37,3 +39,22 @@ def export_source_query(db: Session = Depends(get_db)): ...@@ -37,3 +39,22 @@ def export_source_query(db: Session = Depends(get_db)):
"""导出来源查询""" """导出来源查询"""
result = crud.get_source_data(db) result = crud.get_source_data(db)
return HttpResultResponse(data=result) return HttpResultResponse(data=result)
@router.post("/month/total")
def month_query_total_export(param: schemas.MonthStatistics):
"""月度表计算"""
if not param.date:
month_date = datetime.now().date() - relativedelta(months=1)
param.date = month_date.strftime("%Y%m")
result, num = crud.CalculationMonthlyBill().month_statistics_task('assets_log_' + param.date, param.page, param.size)
return HttpResultResponse(total=num, data=result)
@router.post("/month/details")
def month_query_total_export(param: schemas.MonthDetails):
"""月度计算,详情"""
if not param.date:
return HttpResultResponse(msg='查询月份不能为空')
result, num = crud.CalculationMonthlyDetails().statement_income_expenditure(param)
return HttpResultResponse(total=num, data=result)
...@@ -30,6 +30,7 @@ client = CosS3Client(config) ...@@ -30,6 +30,7 @@ client = CosS3Client(config)
COS_PATH ='https://fj-dc-test-1256890024.cos.ap-guangzhou.myqcloud.com' #测试 COS_PATH ='https://fj-dc-test-1256890024.cos.ap-guangzhou.myqcloud.com' #测试
COS_RERURN_PATH='/images/' COS_RERURN_PATH='/images/'
class Env(BaseSettings): class Env(BaseSettings):
DEBUG: bool = True DEBUG: bool = True
TESTING: bool = False TESTING: bool = False
...@@ -46,7 +47,7 @@ class Env(BaseSettings): ...@@ -46,7 +47,7 @@ class Env(BaseSettings):
SECRET_KEY: str = "09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7" SECRET_KEY: str = "09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7"
ALGORITHM: str = "HS256" ALGORITHM: str = "HS256"
PASSWORD: str = "fj123456" PASSWORD: str = "fj123456"
DB_HISTORY = "3y_history"
class TestingEnv(Env): class TestingEnv(Env):
......
TYPE_NAME = {
"updateUserNameFee": "用户昵称修改",
"updateFamilyNameFee": "粉丝群名,家族名称修改",
"userExchange": "珍珠兑换钻石(用户)",
"userRecharge": "充值",
"pay_discount": "充值-折扣",
"studioGift": "背包/直播间送礼",
"turntableIncome": "转盘",
"turntableExpend": "转盘-中奖",
"recyclingGifts": "回收礼物",
"buyIdentity": "开贵族",
"buyGuard": "开守护",
"studioBarrage": "弹幕消费",
"buyProp": "购买道具",
"bei_to_change_account": "购买bei+",
"bei_to_cancel_account": "bei+订单退款",
"signInDeductMoney": "补签",
"signInReward": "钻石奖励",
"sign_in_backpack_account": "背包礼物奖励",
"live_support": "主播扶持分配",
"room_support": "直播间扶持 - 领取钻石奖励",
"lucky_gift_jackpot": "赠送幸运礼物",
"gameReward": "暴击奖励",
"userWithdrawal": "用户提现",
"sendRedBox": "发送红包",
"userRedBox": "领红包,退还红包",
"send_diamond_red_packet": "钻石红包发送",
"get_red_packet": "钻石红包领取",
"send_diamond_red_packet_back": "钻石红包退还",
"send_gift_red_packet": "礼物红包发送",
"get_gift_red_packet": "礼物红包领取",
"send_gift_red_packet_back": "礼物红包退还",
"first_recharge_gift": "首充礼包",
"user_clean_up": "用户余额清算(线上,线下)",
"cleargiftstore": "背包礼物过期",
"daily_task": "任务奖励发放钻石",
"voiceChatFee": "语聊消费",
"helpExchange": "用户打榜兑换投票次数",
"vip_recharge": "vip购买",
"PlatformLeakRepair": "平台补漏",
"voice": "用户上麦",
"MagicHegemony": "2021.11 魔法争霸赛活动",
"Points_mall_exchange": "商城积分兑换",
"privateMessageCharge": "私信收费",
"level_gift": "升级礼包",
"zhou_xing_backpack_account": "周星奖励发放",
"zhou_xing_consumable_account": "周星奖励发放",
"NamedGift": "冠名礼物",
"whoIsUndercoverJoin": "谁是卧底游戏",
"game:NDJ": "参与游戏-扭蛋机",
"gama:KMH": "参与游戏-开盲盒",
"game_transfer": "商城礼物盲盒-许愿池,八卦象",
"gama:ZJD": "参与游戏-砸金蛋",
"guildExchange": "公会兑换-出账",
"marginRecharge": "保证金缴纳",
"pledgeDeduction": "保证金扣减",
"guildExchangeDraw": "公会钻石结算",
"fanExpansion": "公会家族扩充",
"guildTrafficPromotion": "公会流量推广",
"guildWithdrawal": "公会提现",
"guildWithdrawal_ServiceFee": "公会提现",
"free_guild_profit_Exchange": "自由公会主播收礼后产生公会管理收益",
"subordinate_guild_ti_xian": "下级公会提现",
"investmentIncome": "招商收益",
"platformRecharge": "财务后台内部转账",
"currencyUpgrade": "旧币兑换(钻石)",
"PlatformDeduction": "平台扣除",
"thrid_game_transfer_user": "游戏转用户钻石(引流转盘)",
"blind_box_mall_account_recharge": "盲盒商城账户充值(人民币)",
"pk_season": "PK赛季奖励",
"finance_admin_fix": "财务系统修复",
"pk_shout_anonymity": "pk喊话",
"pk_shout": "pk喊话",
"GameConsumption": "五子棋游戏",
"fj_shop_withdraw": "商城提现",
"fj_shop_recharge": "商城订单结算",
"physical_blind_box_recharge": "实物盲盒 - 使用抽奖券并中奖",
"blind_box_redeem_points": "实物盲盒 - 兑换积分",
"blind_box_delivery": "实物盲盒 - 提货",
"physical_blind_box_refund": "实物盲盒-回收",
"zhou_xing_consume": "周星活动购买道具(创造营)",
"zhou_xing_award": "周星活动领奖",
"talentCertification": "达人认证缴费",
"Payment": "公会解约结算平台打款",
"guild_clear": "公会结算",
"shop_complete_payment": "积分商城改版 - 支付",
"points_mall_points_return": "积分商城改版 - 退款",
"cash_payment_money_return": "积分商城改版 - 退款",
"ConsignmentPaymentConfirmation_release": "用户发布转售动态",
"ConsignmentPaymentConfirmation_callback": "用户撤销转售",
"ConsignmentPaymentConfirmation": "【礼物】购买成功",
"ConsignmentPaymentConfirmation_withdraw": "【实物】确认收货",
"ConsignmentPaymentConfirmation_dress": "【转售装扮】购买成功",
"week_star_buy_dress": "购买限定装扮装扮",
"week_star_award_diamond": "榜单奖励领取",
"game_transfer_to_platform": "游戏账户向平台账户转账",
"recharge_bag_award": "超值礼包",
"HairSpotSong": "点歌功能付费",
"RetreatSpotSong": "点歌退款(主播拒绝、用户撤销)",
"BranchSpotSong": "点歌收益分配",
"guild_transfer_to_anchor": "公会转账给用户(用户得珍珠)",
"guild_transfer_to_anchor_trans_fee": "公会转账手续费支出",
"SmashGoldenEggs": "参与游戏-钻石",
"game_backpack_account": "游戏中奖",
"turntable_game_balance_add": "用户中奖",
"collection": "天外物舱-购买礼物使用权",
"fairy_star_consume": "①、3月仙女活动②、2022【贝洛的愿望】-道具购买",
"relic_buy_prop": "2022-11_遗迹修复活动-购买道具",
"relic_recharge": "2022-11_遗迹修复活动-活动充值",
"seven_country_award": "2022_七国游记活动-榜单奖励领取",
"time_detective_award": "时空侦探活动-榜单领奖",
"translate": "翻译付费",
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment