Commit f3e40046 authored by xianyang's avatar xianyang

Merge branch 'development' into develop/xp

# Conflicts:
#	app/api/account/views.py
#	app/api/role/schemas.py
#	app/api/role/views.py
#	app/api/statement/views.py
#	libs/token_verify.py
parents 2e34a867 484d146e
......@@ -6,7 +6,7 @@
<excludeFolder url="file://$MODULE_DIR$/fs-env" />
<excludeFolder url="file://$MODULE_DIR$/venv" />
</content>
<orderEntry type="jdk" jdkName="Python 3.8 (financial_system)" jdkType="Python SDK" />
<orderEntry type="jdk" jdkName="Python 3.8 (financial-system)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="PyDocumentationSettings">
......
......@@ -3,5 +3,5 @@
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8 (financial_system)" project-jdk-type="Python SDK" />
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8 (financial-system)" project-jdk-type="Python SDK" />
</project>
\ No newline at end of file
FROM python:3.8.8
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple && rm -rf requirements.txt
RUN mkdir /financial-system
WORKDIR /financial-system
\ No newline at end of file
from datetime import datetime
import pandas as pd
from sqlalchemy import and_
from sqlalchemy import and_, func
from sqlalchemy.orm import Session
from app.api.account import schemas
from libs.functions import wrapper_out
from libs.orm import QueryAllData
from models import account as models
from models.account import AccountFinance, AccountFinanceDetails
from models.account import AccountFinance, AccountFinanceDetails, AccountType
def get_account(db: Session, name: str):
......@@ -17,16 +18,17 @@ def get_id_to_authority(db: Session, role_id: int):
return db.query(models.Account).filter(models.Account.id == role_id).first()
@wrapper_out()
def get_account_list(db: Session, param):
"""列表"""
result_list = []
if param.name:
query_res = db.query(models.Account).filter(models.Account.name.like(f'%{param.name}%')).\
offset((int(param.page) - 1) * param.size).limit(param.page * param.size).all()
count = db.query(func.count(models.Account.id)).filter(models.Account.name.like(f'%{param.name}%')).scalar()
query_res = db.query(models.Account).filter(models.Account.name.like(f'%{param.name}%')).order_by(models.Account.id.desc()).\
offset((int(param.page) - 1) * param.size).limit(param.size).all()
else:
query_res = db.query(models.Account).offset((int(param.page) - 1) * param.size).limit(param.page * param.size).all()
count = db.query(func.count(models.Account.id)).scalar()
query_res = db.query(models.Account).order_by(models.Account.id.desc()).offset((int(param.page) - 1) * param.size).limit(param.size).all()
if not query_res:
return []
for i in query_res:
......@@ -42,7 +44,7 @@ def get_account_list(db: Session, param):
else:
serializer_info['output'] = []
result_list.append(serializer_info)
return result_list
return result_list, count
def get_gift_type(db: Session):
......@@ -79,18 +81,11 @@ def create_account(db: Session, param: schemas.AccountCreate):
def update_account_info(db: Session, old_data):
"""修改"""
if old_data.name:
db.query(models.Account).filter(models.Account.id == old_data.id).update(
{models.Account.name: old_data.name})
if old_data.remark:
db.query(models.Account).filter(models.Account.id == old_data.id).update(
{models.Account.remark: old_data.remark})
if old_data.income:
db.query(models.Account).filter(models.Account.id == old_data.id).update(
{models.Account.income: ','.join(map(str, old_data.income))})
if old_data.output:
db.query(models.Account).filter(models.Account.id == old_data.id).update(
{models.Account.output: ','.join(map(str, old_data.output))})
db.query(models.Account).filter(models.Account.id == old_data.id).update(
{models.Account.name: old_data.name,
models.Account.remark: old_data.remark,
models.Account.income: ','.join(map(str, old_data.income)),
models.Account.output: ','.join(map(str, old_data.output))})
db.commit()
......@@ -138,8 +133,60 @@ def get_finance_details(db, data, is_list=None):
return [], 0, 0 if is_list else []
# 判断是列表还是导出接口
if is_list:
if not serial_info:
return [], 0, 0
df = pd.DataFrame(serial_info)
count = df['amount'].apply(lambda x: x).sum()
return serial_info[(int(data.page) - 1) * data.size:data.size * data.page], len(serial_info), count
else:
return serial_info
def get_account_type(db: Session, data):
"""礼物类型配置列表"""
finance_filters = []
if data.get("key_name"):
finance_filters.append(AccountType.key_name == data.get("key_name"))
if data.get("key_value"):
finance_filters.append(AccountType.key_value == data.get("key_value"))
if data.get("type") or data.get("type") == 0:
finance_filters.append(AccountType.type == data.get("type"))
if data.get("start_time"):
finance_filters.append(AccountType.create_time >= data.get("start_time") + " 00:00:00")
if data.get("end_time"):
finance_filters.append(AccountType.create_time <= data.get("end_time") + " 23:59:59")
querydata, count = QueryAllData(db, AccountType, data, finance_filters).query_data()
data = [QueryAllData.serialization(item) for item in querydata]
return data, count
def update_account_type(db: Session, data):
"""修改账目类型"""
try:
db.query(AccountType).filter(AccountType.id == data.id).update({AccountType.key_name: data.key_name,
AccountType.key_value: data.key_value,
AccountType.type: data.type})
db.commit()
return True
except Exception as e:
print(e)
return False
def get_account_type_value(db: Session, key):
"""新建类型 查询是否有重复数据"""
return db.query(AccountType).filter(AccountType.key_value == key).first()
def create_type(db: Session, data):
"""创建新账目类型"""
try:
db_type = AccountType(key_name=data.key_name, key_value=data.key_value, type=data.type,
create_time=datetime.now())
db.add(db_type)
db.commit()
db.refresh(db_type)
except Exception as e:
print(e)
return {}
return db_type
......@@ -45,16 +45,34 @@ class FixTable(BaseModel):
type: int
account_id: int
money: float
amount_type: str
amount_type: str = ""
remark: str
class AccountTypeUpdate(BaseModel):
id: int = None
key_name: str = ""
key_value: str = ""
type: int = None
class AccountTypeList(AccountTypeUpdate):
page: int = None
size: int = None
class CreateType(BaseModel):
key_name: str
key_value: str
type: int
class Recovery_fix(PublicModel):
uuid: Optional[str] = None
uuid: Optional[str] = None
class RecoveryTable(BaseModel):
uuid:Optional[str] = None
uuid: Optional[str] = None
type: Optional[int] = None
out_money: Optional[int] = None
entry_money: Optional[float] = None
......@@ -63,4 +81,4 @@ class RecoveryTable(BaseModel):
class RecoveryupdateTable(RecoveryTable):
id:int
\ No newline at end of file
id: int
\ No newline at end of file
from fastapi import Depends, APIRouter
from fastapi import Depends, APIRouter, Request
from sqlalchemy.orm import Session
from app import get_db
from app.api.account import schemas, crud
......@@ -24,8 +24,8 @@ def create_account(data: schemas.AccountCreate, token=Depends(login_required),db
@router.post("/list")
def user_list(data: schemas.AccountList, token=Depends(login_required),db: Session = Depends(get_db)):
"""账户列表"""
result = crud.get_account_list(db, data)
return HttpResultResponse(total=len(result), data=result)
result, num = crud.get_account_list(db, data)
return HttpResultResponse(total=num, data=result)
@router.get("/gift/type")
......@@ -38,6 +38,8 @@ def gift_type_list(db: Session = Depends(get_db)):
@router.post("/update")
def read_account(data: schemas.AccountUpdate, token=Depends(login_required),db: Session = Depends(get_db)):
"""账户修改"""
if not data.name:
return HttpResultResponse(code=500, msg="账户名不能为空")
crud.update_account_info(db, data)
return HttpResultResponse()
......@@ -50,10 +52,11 @@ def finance_information(data: schemas.FinanceInfo,token=Depends(login_required),
@router.post("/finance/info/excel")
def finance_info_excel(data: schemas.FinanceInfo,token=Depends(login_required), db: Session = Depends(get_db)):
def finance_info_excel(data: schemas.FinanceInfo, request: Request, db: Session = Depends(get_db)):
"""账户财务信息导出"""
headers = request.get("headers")
statement_list = crud.get_finance_info(db, data)
return statement_crud.data_to_file(statement_list, "财务信息")
return statement_crud.data_to_file(db, statement_list, "财务信息", headers)
@router.post("/finance/details")
......@@ -64,7 +67,36 @@ def finance_details(data: schemas.FinanceDetails,token=Depends(login_required),
@router.post("/finance/details/excel")
def finance_info_excel(data: schemas.FinanceDetails,token=Depends(login_required), db: Session = Depends(get_db)):
def finance_info_excel(data: schemas.FinanceDetails, request: Request, db: Session = Depends(get_db)):
"""账户财务明细导出"""
headers = request.get("headers")
statement_list = crud.get_finance_details(db, data)
return statement_crud.data_to_file(statement_list, "财务明细")
return statement_crud.data_to_file(db, statement_list, "财务明细", headers)
@router.post("/type")
def finance_fix(data: schemas.AccountTypeList, db: Session = Depends(get_db)):
"""出入账目配置列表"""
res, num = crud.get_account_type(db, data.dict(exclude_none=True))
return HttpResultResponse(total=num, data=res)
@router.post("/type/update")
def finance_fix(data: schemas.AccountTypeList, db: Session = Depends(get_db)):
"""出入账目类型修改"""
res = crud.update_account_type(db, data)
if res:
return HttpResultResponse()
return HttpResultResponse(code=422, msg='修改失败')
@router.post("/create/type")
def create_user(data: schemas.CreateType, db: Session = Depends(get_db)):
"""添加账目类型"""
res_type = crud.get_account_type_value(db, data.key_value)
if res_type:
return HttpResultResponse(code=400, msg=HttpMessage.TYPE_EXIST)
res = crud.create_type(db, data)
if not res:
return HttpResultResponse(code=500, msg=res)
return HttpResultResponse(data=res.id)
......@@ -4,6 +4,7 @@ from app.api.statement import views as s_view
from app.api.role import views as r_view
from app.api.account import views as a_view
from app.api.margin import views as m_view
from app.api.export import views as e_view
api_router = APIRouter()
api_router.include_router(u_view.router, prefix="/users", tags=["users"])
......@@ -11,3 +12,4 @@ api_router.include_router(s_view.router, prefix="/statement", tags=["statement"]
api_router.include_router(r_view.router, prefix="/role", tags=["role"])
api_router.include_router(a_view.router, prefix="/account", tags=["account"])
api_router.include_router(m_view.router, prefix="/margin", tags=["margin"])
api_router.include_router(e_view.router, prefix="/export", tags=["export"])
from concurrent.futures.thread import ThreadPoolExecutor
from sqlalchemy.orm import Session
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.orm import QueryAllData
from models.export import ExportFile
import pandas as pd
from starlette.responses import StreamingResponse
def get_export_list(db: Session, param):
"""导出列表"""
export_filters = []
if param.get("source"):
export_filters.append(ExportFile.source == param.get("source"))
if param.get("start_time"):
export_filters.append(ExportFile.create_time >= param.get("start_time"))
if param.get("end_time"):
export_filters.append(ExportFile.create_time <= param.get("end_time"))
querydata, count = QueryAllData(db, ExportFile, param, export_filters).query_data()
data = [QueryAllData.serialization(item) for item in querydata]
return data, count
def update_export(db: Session, data):
try:
db.query(ExportFile).filter(ExportFile.id == data.id).update({ExportFile.remark: data.remark})
db.commit()
except Exception as e:
print(e)
return False
return True
def delete_export(db: Session, export_id):
"""删除导出记录"""
try:
db.query(ExportFile).filter(ExportFile.id == export_id).delete()
db.commit()
except Exception as e:
print(e)
return False
return True
def create_export_data(db: Session, export, operator):
"""创建导出记录"""
try:
db_export = ExportFile(operator=operator.get("username"), source=export.get("source"), method=export.get("method"),
create_time=get_now_datetime(), update_time=get_now_datetime(), status=export.get("status"))
db.add(db_export)
db.commit()
db.refresh(db_export)
except Exception as e:
print(e)
return {}
return db_export
def get_source_data(db):
res = db.query(ExportFile.source).filter().group_by('source').all()
return [i[0] for i in res]
class CalculationMonthlyBill(object):
"""月度计算,出入账目"""
def __init__(self):
self.structure_list = []
self.structure_key = []
def month_statistics_task(self, date, key_type, page, size):
"""主函数"""
db = env.MysqlDB
db["database"] = env.DB_HISTORY
if key_type:
sql = f"SELECT reference_type, type, SUM(cast(amount as decimal(20,6)))/1000 as money FROM {date} where reference_type='{key_type}' GROUP BY reference_type, type ORDER BY reference_type"
else:
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"
try:
res_data = LinkMysql(db).query_mysql(sql)
except Exception as e:
return [], 0
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=2) 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
@staticmethod
def query_error_data(date, reference_type):
database = env.MysqlDB
database["database"] = env.DB_HISTORY
group_sql = f"SELECT order_id, COUNT(order_id) as num FROM {date} where reference_type='{reference_type}' GROUP BY order_id"
result = LinkMysql(database).query_mysql(group_sql)
error_list = [str(i.get("order_id")) for i in result if i.get("num") != 2]
if len(error_list) == 1:
sql = f"SELECT uuid,reference_type,order_number,order_id,type,cast(amount as decimal(20,6))/1000 as money,amount_type,create_time FROM {date} where order_id={error_list[0]}"
if len(error_list) > 1:
sql = f"SELECT uuid,reference_type,order_number,order_id,type,cast(amount as decimal(20,6))/1000 as money,amount_type,create_time FROM {date} where order_id in({','.join(error_list)})"
if len(error_list) == 0:
return []
result = LinkMysql(database).query_mysql(sql)
return result
class MonthDataDerive(object):
"""月度导出"""
def __init__(self):
self.derive_key = []
self.derive_list = []
@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 derive_data(self, date, key_type):
db = env.MysqlDB
db["database"] = env.DB_HISTORY
if key_type:
sql = f"SELECT reference_type, type, SUM(cast(amount as decimal(20,6)))/1000 as money FROM {date} where reference_type='{key_type}' GROUP BY reference_type, type ORDER BY reference_type"
else:
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"
try:
res_data = LinkMysql(db).query_mysql(sql)
except Exception as e:
return [], 0
for res in res_data:
if res["reference_type"] in self.derive_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.derive_key.append(res["reference_type"])
self.derive_list.append(a)
return self.data_to_table(self.derive_list)
from typing import Optional
from pydantic import BaseModel, validator
from pydantic import ValidationError
class ExportList(BaseModel):
source: Optional[str] = ""
start_time: Optional[str] = ""
end_time: Optional[str] = ""
page: Optional[int] = None
size: Optional[int] = None
class ExportUpdateData(BaseModel):
id: int
remark: str = ""
class MonthStatistics(BaseModel):
date: str = ""
type: str = ""
page: int = None
size: int = None
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 sqlalchemy.orm import Session
from app import get_db
from app.api.export import schemas, crud
from libs.result_format import HttpResultResponse, HttpMessage
router = APIRouter()
@router.post("/list")
def export_list(data: schemas.ExportList, db: Session = Depends(get_db)):
"""导出记录列表"""
result, total = crud.get_export_list(db, data.dict(exclude_none=True))
return HttpResultResponse(total=total, data=result)
@router.post("/update")
def update_export_list(data: schemas.ExportUpdateData, db: Session = Depends(get_db)):
"""导出记录修改"""
result = crud.update_export(db, data)
if result:
return HttpResultResponse()
return HttpResultResponse(code=422, msg=HttpMessage.LOSE)
@router.delete("/delete/{id}")
def delete_export_one(id:int, db: Session = Depends(get_db)):
"""导出记录删除"""
is_delete = crud.delete_export(db, id)
if is_delete:
return HttpResultResponse()
return HttpResultResponse(code=422, msg=HttpMessage.DELETE_LOSE)
@router.get("/source")
def export_source_query(db: Session = Depends(get_db)):
"""导出来源查询"""
result = crud.get_source_data(db)
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.type,
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)
@router.post("/error/data")
def month_query_error_data(param: schemas.MonthDetails):
"""月度计算,异常数据"""
if not param.date:
return HttpResultResponse(msg='查询月份不能为空')
result = crud.CalculationMonthlyDetails().query_error_data('assets_log_' + param.date, param.key)
return HttpResultResponse(total=len(result), data=result)
@router.post("/month")
def month_to_export(param: schemas.MonthStatistics):
"""月度表导出"""
if not param.date:
return HttpResultResponse(msg='查询月份不能为空')
result = crud.MonthDataDerive().derive_data('assets_log_' + param.date, param.type)
return result
from sqlalchemy import and_
from sqlalchemy.orm import Session
from libs.functions import wrapper_out
from libs.functions import get_now_datetime
from libs.orm import QueryAllData
from models.margin import GuildMargin
from models.guild import Guild, GuildPledgeRecord
from models.margin import GuildMargin
@wrapper_out()
def get_margin(db: Session, param):
"""保证金列表,查询"""
guild_filters = []
if param.guild_id:
guild_filters.append(GuildMargin.guild_id == param.guild_id)
if param.status:
guild_filters.append(GuildMargin.status == param.status)
if param.start_time:
guild_filters.append(GuildMargin.create_time >= param.start_time)
if param.end_time:
guild_filters.append(GuildMargin.create_time <= param.end_time)
if not guild_filters:
query_res = db.query(GuildMargin).all()
return [i.to_dict() for i in query_res][::-1]
else:
get_user_orm_sql = db.query(GuildMargin).filter(and_(*guild_filters))
query_res = db.execute(get_user_orm_sql).fetchall()
return [i[0].to_dict() for i in query_res][::-1]
if param.get("guild_id"):
guild_filters.append(GuildMargin.guild_id == param.get("guild_id"))
if param.get("status"):
guild_filters.append(GuildMargin.status == param.get("status"))
if param.get("start_time"):
guild_filters.append(GuildMargin.create_time >= param.get("start_time") + " 00:00:00")
if param.get("end_time"):
guild_filters.append(GuildMargin.create_time <= param.get("end_time") + " 23:59:59")
querydata, count = QueryAllData(db, GuildMargin, param, guild_filters).query_data()
data = [QueryAllData.serialization(item) for item in querydata]
return data, count
def margin_dispose(db: Session, param):
# 查询公会
guid_info = db.query(Guild).filter(Guild.id == param.get("guild_id")).first()
if not guid_info:
return '公会不存在'
# 拒绝
if param.get("examine_status") == -1:
db.query(GuildMargin).filter(GuildMargin.id == param.get("id")).update({GuildMargin.status: 5})
db.commit()
return '拒绝成功'
try:
# 修改公会保证金记录 状态
db.query(GuildMargin).filter(GuildMargin.id == param.get("id")).update({GuildMargin.status: 4})
db.commit()
except Exception as e:
print(e)
# 给公会添加保证金
db.query(Guild).filter(Guild.id == param.get("guild_id")).update({Guild.margin: guid_info.margin + param.get("amount")})
# 添加保证金添加记录
try:
gpr = GuildPledgeRecord(guild_id=param.get("guild_id"), before_pears=guid_info.margin, after_pears=guid_info.margin + param.get("amount"),
create_time=get_now_datetime(), update_time=get_now_datetime(), tixian_id=0,
is_handle=1, pledge_pearl=0, margin=param.get("amount"))
db.add(gpr)
db.commit()
db.refresh(gpr)
except Exception as e:
print(e)
......@@ -7,5 +7,12 @@ class GuildMarginList(BaseModel):
size: Optional[int] = None
guild_id: Optional[int] = None
status: Optional[int] = None
start_time: Optional[int] = None
end_time: Optional[int] = None
start_time: Optional[str] = ""
end_time: Optional[str] = ""
class MarginExamine(BaseModel):
id: int
guild_id: int
examine_status: int
amount: float
......@@ -11,8 +11,12 @@ router = APIRouter()
@router.post("/list")
def guild_margin_list(data: schemas.GuildMarginList,token=Depends(login_required), db: Session = Depends(get_db)):
"""保证金列表"""
result = crud.get_margin(db, data)
return HttpResultResponse(total=len(result), data=result[int(data.page-1)*data.size:data.page*data.size])
result, total = crud.get_margin(db, data.dict(exclude_none=True))
return HttpResultResponse(total=total, data=result)
@router.post("/examine")
def margin_examine(data: schemas.MarginExamine, db: Session = Depends(get_db)):
"""保证金确认,拒绝"""
result = crud.margin_dispose(db, data.dict(exclude_none=True))
return HttpResultResponse(msg=result)
from datetime import datetime
from fastapi import HTTPException, status
from sqlalchemy.orm import Session
from sqlalchemy import func
from app.api.role import schemas
from libs.functions import wrapper_out
from models import roles as models
......@@ -14,17 +15,18 @@ def get_id_to_authority(db: Session, role_id: int):
return db.query(models.Role).filter(models.Role.id == role_id).first()
@wrapper_out()
def get_roles(db: Session, param):
result_list = []
name = param.role_name if param.role_name else ""
if name:
query_res = db.query(models.Role).filter(models.Role.role_name.like(f'%{name}%')).\
query_res = db.query(models.Role).filter(models.Role.role_name.like(f'%{name}%')).order_by(models.Role.id.desc()).\
offset((int(param.page) - 1) * param.size).limit(param.page * param.size).all()
count = db.query(func.count(models.Role.id)).filter(models.Role.role_name.like(f'%{name}%')).scalar()
else:
query_res = db.query(models.Role).offset((int(param.page) - 1) * param.size).limit(param.page * param.size).all()
query_res = db.query(models.Role).order_by(models.Role.id.desc()).offset((int(param.page) - 1) * param.size).limit(param.size).all()
count = db.query(func.count(models.Role.id)).scalar()
if not query_res:
return []
return [], 0
for i in query_res:
serializer_info = i.to_dict(only=('id', 'role_name', 'authority', 'remark', 'create_time'))
if i.authority:
......@@ -33,7 +35,7 @@ def get_roles(db: Session, param):
else:
serializer_info['authority'] = []
result_list.append(serializer_info)
return result_list
return result_list, count
def create_role(db: Session, user: schemas.RoleCreate):
......@@ -51,15 +53,11 @@ def create_role(db: Session, user: schemas.RoleCreate):
def update_role(db: Session, role_info):
if role_info.role_name:
db.query(models.Role).filter(models.Role.id == role_info.id).update(
{models.Role.role_name: role_info.role_name})
if role_info.remark:
db.query(models.Role).filter(models.Role.id == role_info.id).update(
{models.Role.remark: role_info.remark})
if role_info.authority:
db.query(models.Role).filter(models.Role.id == role_info.id).update(
{models.Role.authority: ','.join(map(str, role_info.authority))})
db.query(models.Role).filter(models.Role.id == role_info.id).update(
{models.Role.role_name: role_info.role_name,
models.Role.authority: ','.join(map(str, role_info.authority)),
models.Role.remark: role_info.remark})
db.commit()
......
......@@ -5,7 +5,7 @@ from typing import Optional
class RoleCreate(BaseModel):
role_name: str
authority: list
remark: Optional[int] = None
remark: Optional[str] = ""
class RoleUpdate(RoleCreate):
......
......@@ -16,7 +16,7 @@ def create_user(data: schemas.RoleCreate,token=Depends(login_required), db: Sess
return HttpResultResponse(code=400, msg=HttpMessage.ROLE_EXIST)
res = crud.create_role(db=db, user=data)
if not res:
return HttpResultResponse(code=500, msg=res)
return HttpResultResponse(code=500, msg=HttpMessage.LOSE)
return HttpResultResponse(data=res.id)
......@@ -37,7 +37,7 @@ def delete_user(role_id: int,token=Depends(login_required), db: Session = Depend
@router.post("/list")
def role_list(data: schemas.RoleList,token=Depends(login_required), db: Session = Depends(get_db)):
"""用户列表"""
result = crud.get_roles(db, data)
return HttpResultResponse(total=len(result), data=result)
def role_list(data: schemas.RoleList, token=Depends(login_required), db: Session = Depends(get_db)):
"""角色列表"""
result, total = crud.get_roles(db, data)
return HttpResultResponse(total=total, data=result)
import math
import threading
import pandas as pd
from sqlalchemy import and_, or_, func
from core.config.env import env
from libs.db_link import LinkMysql
from sqlalchemy import and_, func
from app.api.statement.guild import query_token
from starlette.responses import StreamingResponse
from sqlalchemy.orm import Session
from libs.functions import wrapper_out
from app.api.export import crud
from libs.orm import QueryAllData
from models.recharge import Recharge, UserWC, GuildWC, FinanceFixLog
locka = threading.Lock()
# 写入文件
def data_to_file(data, name):
bk = pd.DataFrame(data)
with pd.ExcelWriter(f'static/{name}.xlsx') as writer:
bk.to_excel(writer, sheet_name='Sheet1', index=False)
file = open(writer, 'rb')
return StreamingResponse(file, media_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
def data_to_file(db, data, name, header):
# 获取操作人
user = query_token(db, header)
params = {"source": name, "method": "data_to_file", "status": 1}
if len(data) == 0:
params["status"] = 3
try:
bk = pd.DataFrame(data)
with pd.ExcelWriter(f'static/{name}.xlsx') as writer:
bk.to_excel(writer, sheet_name='Sheet1', index=False)
file = open(writer, 'rb')
# 记录导出
crud.create_export_data(db, params, user)
return StreamingResponse(file, media_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
except Exception as e:
print(e)
params["status"] = 2
crud.create_export_data(db, params, user)
class RechargeStatement(object):
......@@ -65,7 +75,7 @@ class RechargeStatement(object):
not_null_filters.append(Recharge.user_id == param.user_id)
if param.sid:
not_null_filters.append(Recharge.sid.like(param.sid))
if param.paychannel:
if param.pay_channel:
not_null_filters.append(Recharge.pay_channel.like(param.pay_channel))
if param.start_time:
not_null_filters.append(Recharge.current >= param.start_time)
......@@ -127,8 +137,8 @@ class WithdrawStatement(object):
def get_user_withdraw_cash(self, db: Session, param):
"""用户提现"""
is_filters = []
if param.user_id:
is_filters.append(UserWC.user_id == param.user_id)
if param.name:
is_filters.append(UserWC.nick_name.like(f'%{param.name}%'))
if param.status or param.status == 0:
is_filters.append(UserWC.status == param.status)
if param.start_time:
......@@ -215,9 +225,17 @@ class WithdrawStatement(object):
class FinanceFix(object):
@staticmethod
@wrapper_out()
def get_finance_fix_data(db: Session, data):
"""财务修复"""
total = db.query(func.count(FinanceFixLog.id)).scalar()
output = db.query(FinanceFixLog).limit(data.page * data.size).offset((data.page - 1) * data.size).all()
return [i.to_dict() for i in output], total
# total = db.query(func.count(FinanceFixLog.id)).scalar()
# output = db.query(FinanceFixLog).order_by(FinanceFixLog.id.desc()).offset((data.page - 1) *
# data.size).limit(data.size).all()
# return [i.to_dict() for i in output], total
finance_filters = []
if data.get("start_time"):
finance_filters.append(FinanceFixLog.create_time >= data.get("start_time") + " 00:00:00")
if data.get("end_time"):
finance_filters.append(FinanceFixLog.create_time <= data.get("end_time") + " 23:59:59")
querydata, count = QueryAllData(db, FinanceFixLog, data, finance_filters).query_data()
data = [QueryAllData.serialization(item) for item in querydata]
return data, count
......@@ -6,10 +6,11 @@ from sqlalchemy.orm import Session
from libs.functions import get_now_timestamp, get_now_datetime
from libs.orm import QueryAllData
from libs.token_verify import get_current_user
from models.recharge import Settlement, Fitransferlog, FinanceFixLog, Fiaccount, Account_log
from models.users import V2User
from models.recharge import Settlement, Fitransferlog, FinanceFixLog, Account_log
from models.guild import Guild
from models.account import Account
from models.users import V2User
from models.guild import Guild
locka = threading.Lock()
......@@ -61,7 +62,6 @@ class GuildSet(object):
else:
guild_info = self.query_guild_data(db)
except Exception as e:
print(e)
return [], 0
# 判断是列表还是导出接口
guild_info.reverse()
......@@ -108,24 +108,15 @@ def outon_account_data(db: Session, dbname, params):
def accout_list_data(db: Session, dbname, params):
accout_filters = []
if params.get("id"):
accout_filters.append(dbname.guild_id == params.get("guild_id"))
if params.get("transfer_id"):
accout_filters.append(dbname.transfer_id == params.get("transfer_id"))
if params.get("dst_id"):
accout_filters.append(dbname.dst_id == params.get("dst_id"))
if params.get("cont"):
accout_filters.append(dbname.cont == params.get("cont"))
if params.get("money"):
accout_filters.append(dbname.money == params.get("money"))
if params.get("url"):
accout_filters.append(dbname.url == params.get("url"))
if params.get("uuid"):
accout_filters.append(dbname.uuid == params.get("uuid"))
if params.get("start_time"):
accout_filters.append(dbname.create_time >= params.get("start_time"))
accout_filters.append(dbname.create_time >= params.get("start_time") + " 00:00:00")
if params.get("end_time"):
accout_filters.append(dbname.create_time <= params.get("end_time"))
accout_filters.append(dbname.create_time <= params.get("end_time") + " 23:59:59")
querydata, count = QueryAllData(db, dbname, params, accout_filters).query_data()
data = [QueryAllData.serialization(item) for item in querydata]
return data, count
......@@ -139,16 +130,16 @@ def query_uuid_or_user_number(db: Session, param):
guild = db.query(Guild).filter(Guild.uuid == param.uuid).first()
if not guild:
return {}
return {"nick_name": "(公会)" + guild.guild_name, "user_number": guild.id}
return {"nick_name": user.nick_name, "user_number": user.user_id}
return {"nick_name": "(公会)" + guild.guild_name, "uuid": guild.uuid, "is_guild": 1, "id": guild.id}
return {"nick_name": user.nick_name, "uuid": user.uuid, "is_guild": 0, "id": user.user_id}
if param.user_number:
user = db.query(V2User).filter(V2User.user_number == param.user_number).first()
return {"nick_name": user.nick_name, "user_id": user.user_id, "uuid": user.uuid}
account = db.query(Account).filter(Account.uuid == param.user_number).first()
return {"nick_name": account.name, "user_id": account.unique_tag, "uuid": account.uuid, "id": account.id}
def account_money(db: Session, param):
"""查询账户余额"""
account = db.query(Account).filter(Account.id == param.id).first()
account = db.query(Account).filter(Account.uuid == param.id).first()
if not account:
return 0
return account.consumable if account.consumable else 0
......@@ -171,16 +162,37 @@ def query_token(db, h_list):
def transfer_money(db: Session, param, h_list):
"""转账"""
user = query_token(db, h_list)
if param.type == 0:
out = db.query(Account).filter(Account.uuid == param.dst_id).first()
income = db.query(Account).filter(Account.uuid == param.transfer_id).first()
dst_name = out.name
transfer_name = income.name
if param.type == 1:
out = db.query(Account).filter(Account.uuid == param.dst_id).first()
income = db.query(V2User).filter(V2User.uuid == param.transfer_id).first()
transfer_name = income.nick_name if income else ""
if not income:
income = db.query(Guild).filter(Guild.uuid == param.transfer_id).first()
transfer_name = income.guild_name if income else ""
dst_name = out.name if income else ""
if param.type == 2:
out = db.query(V2User).filter(V2User.uuid == param.dst_id).first()
dst_name = out.nick_name if out else ""
if not out:
out = db.query(Guild).filter(Guild.uuid == param.dst_id).first()
dst_name = out.guild_name if out else ""
income = db.query(Account).filter(Account.uuid == param.transfer_id).first()
transfer_name = income.name if income else ""
try:
present = Fitransferlog(dst_id=param.dst_id, amount=param.amount, type=param.type,
present = Fitransferlog(dst_id=param.dst_id, dst_name=dst_name, amount=param.amount, type=param.type,
transfer_id=param.transfer_id, nick_name=param.nick_name, remark=param.remark,
operator=user.get("username"), transfer_type=param.transfer_type,
create_time=get_now_timestamp())
create_time=get_now_datetime(), transfer_name=transfer_name)
db.add(present)
db.commit()
db.refresh(present)
except Exception as e:
print(e)
return {}
return present
......@@ -188,6 +200,8 @@ def transfer_money(db: Session, param, h_list):
def create_fix_table(db: Session, param, h_list):
"""增加修复报表"""
user = query_token(db, h_list)
if param.type == 0:
param.amount_type = 'consumable'
try:
present = FinanceFixLog(type=param.type, account_id=param.account_id, money=param.money,
remark=param.remark, operator=user.get("username"), amount_type=param.amount_type,
......@@ -196,12 +210,10 @@ def create_fix_table(db: Session, param, h_list):
db.commit()
db.refresh(present)
except Exception as e:
print(e)
return {}
return present
def recovery_fix_data(db: Session, dbname, params):
recovery_list = []
if params.get("uuid"):
......@@ -212,20 +224,18 @@ def recovery_fix_data(db: Session, dbname, params):
recovery_list.append(dbname.create_time <= params.get("end_time"))
querydata, count = QueryAllData(db, dbname, params, recovery_list).query_data()
data = [QueryAllData.serialization(item) for item in querydata]
for item in data:
for item in data:
accout_filters = []
accout_filters.append(dbname.uuid == item.get("uuid"))
names=QueryAllData(db, Fiaccount,{},accout_filters).query_filter()
names = QueryAllData(db, Account, {}, accout_filters).query_filter()
if names:
item['name']=names.name
item['uuid']=names.uuid
item['name'] = names.name
item['uuid'] = names.uuid
else:
item['name']=''
item['name'] = ''
return data, count
def create_recovery_table(db: Session, param):
"""增加修复报表"""
try:
......
......@@ -23,7 +23,7 @@ class StatementList(BaseModel):
order_number: Optional[str] = ""
user_id: Optional[str] = ""
sid: Optional[str] = ""
paychannel: Optional[str] = ""
pay_channel: Optional[str] = ""
class Statement(StatementBase):
......@@ -39,7 +39,7 @@ class UserWithdrawalList(BaseModel):
start_time: Optional[str] = ""
end_time: Optional[str] = ""
status: Optional[int] = None
user_id: Optional[int] = None
name: Optional[str] = ""
class GuildWithdrawalList(BaseModel):
......@@ -108,9 +108,11 @@ class UserNumber(BaseModel):
class CreateBill(BaseModel):
dst_id: int
dst_id: str
dst_name: str = ""
amount: float
transfer_id: int
transfer_id: str
transfer_name: str = ""
remark: str
type: int
nick_name: Optional[str] = ""
......
......@@ -13,6 +13,7 @@ from libs.img_code import new_upload_file, random_number
from libs.result_format import HttpResultResponse
from libs.token_verify import login_required
from models.recharge import Paymentlog, Fiaccount, Fitransferlog, Account_log
from models.account import Account
router = APIRouter()
......@@ -25,10 +26,11 @@ def statement_recharge_list(data: schemas.StatementList,token=Depends(login_requ
@router.post("/derive/excel")
def statement_derive_excel(data: schemas.StatementList,token=Depends(login_required), db: Session = Depends(get_db)):
def statement_derive_excel(data: schemas.StatementList, request: Request, db: Session = Depends(get_db)):
"""充值报表导出"""
header_list = request.get("headers")
statement_list = RechargeStatement().get_statements(db, data)
return crud.data_to_file(statement_list, "充值报表")
return crud.data_to_file(db, statement_list, "充值报表", header_list)
@router.post("/userWithdrawal/list")
......@@ -63,14 +65,16 @@ def guild_payment_list(data:PaymentWithdrawalList,token=Depends(login_required),
async def uploadFile(a_file: bytes = File(...),token=Depends(login_required),):
a_content = a_file
image_name = random_number()
cos_path = new_upload_file(a_content,image_name)
cos_path = new_upload_file(a_content, image_name)
if not cos_path:
return HttpResultResponse(code=500, msg="上传失败,请检查cos是否正常")
return HttpResultResponse(data=cos_path)
@router.post("/payment/add")
def guild_payment_list(data:PaymentAdd,token=Depends(login_required),db: Session = Depends(get_db)):
"""提交打款"""
dataPayment = Paymentlog(uuid=data.uuid,money=data.money,cont=data.cont,url=data.url,create_time=datetime.now())
dataPayment = Paymentlog(uuid=data.uuid, money=data.money, cont=data.cont,url=data.url,create_time=datetime.now())
db.add(dataPayment)
db.commit()
db.refresh(dataPayment)
......@@ -81,7 +85,7 @@ def guild_payment_list(data:PaymentAdd,token=Depends(login_required),db: Session
@router.get("/onaccount")
def outon_account(db: Session = Depends(get_db),token=Depends(login_required)):
"""转出和转入账户人员列表"""
account_list, total = outon_account_data(db, Fiaccount,{})
account_list, total = outon_account_data(db, Account, {})
return HttpResultResponse(total=total, data=account_list)
......@@ -111,6 +115,8 @@ def account_transfer_money(data: CreateBill, request: Request, db: Session = Dep
"""账户转账"""
header_list = request.get("headers")
res_info = transfer_money(db, data, header_list)
if not res_info:
return HttpResultResponse(code=500, msg='创建失败')
return HttpResultResponse(data=res_info.id)
......@@ -124,7 +130,7 @@ def guild_update_list(data: schemas.GuildUpdate, db: Session = Depends(get_db)):
@router.post("/finance/fix")
def finance_fix(data: acc_schemas.PublicModel, db: Session = Depends(get_db)):
"""账户修复报表"""
res, num = crud.FinanceFix.get_finance_fix_data(db, data)
res, num = crud.FinanceFix.get_finance_fix_data(db, data.dict(exclude_none=True))
return HttpResultResponse(total=num, data=res)
......@@ -136,17 +142,15 @@ def finance_fix(data: acc_schemas.FixTable, request: Request, db: Session = Depe
return HttpResultResponse(data=res.id)
@router.post("/data/recovery")
def recovery_fix(data: acc_schemas.Recovery_fix, db: Session = Depends(get_db)):
"""异常数据修复"""
recovery_list, total = guild.recovery_fix_data(db, Account_log,data.dict(exclude_none=True))
recovery_list, total = guild.recovery_fix_data(db, Account_log, data.dict(exclude_none=True))
return HttpResultResponse(total=total, data=recovery_list)
@router.post("/submit/recovery")
def finance_fix(data: acc_schemas.RecoveryTable,db: Session = Depends(get_db)):
def finance_fix(data: acc_schemas.RecoveryTable, db: Session = Depends(get_db)):
"""新增异常数据修复"""
res = guild.create_recovery_table(db, data)
return HttpResultResponse(data=res.id)
......@@ -155,5 +159,5 @@ def finance_fix(data: acc_schemas.RecoveryTable,db: Session = Depends(get_db)):
@router.post("/recovery/fix")
def recovery_fix(data: acc_schemas.RecoveryupdateTable, db: Session = Depends(get_db)):
"""异常数据修复"""
res = guild.update_recovery_table(db,data.dict(exclude_none=True))
return HttpResultResponse(data=res.get("id"))
\ No newline at end of file
res = guild.update_recovery_table(db, data.dict(exclude_none=True))
return HttpResultResponse(data=res.get("id"))
import random
from datetime import datetime
from sqlalchemy import func
from sqlalchemy.orm import Session
from app.api.role.crud import get_id_to_authority
from app.api.users import schemas
......@@ -12,7 +14,6 @@ def get_user_by_name(db: Session, username: str):
return db.query(models.User).filter(models.User.username == username).first()
@wrapper_out()
def get_users(db: Session, param):
"""
分组统计求和 from sqlalchemy import func as fc
......@@ -22,10 +23,12 @@ def get_users(db: Session, param):
username = param.username if param.username else ""
if username:
res = db.query(models.User).filter(models.User.username.like(f'%{username}%')).order_by(models.User.id.desc()).offset((int(param.page) - 1) * param.size).limit(param.page * param.size)
count = db.query(func.count(models.User.id)).filter(models.User.username.like(f'%{username}%')).scalar()
else:
res = db.query(models.User).order_by(models.User.id.desc()).offset((int(param.page) - 1) * param.size).limit(param.page * param.size)
count = db.query(func.count(models.User.id)).scalar()
if not res:
return []
return [], 0
result_list = []
for i in res:
serializer_info = i.to_dict()
......@@ -39,7 +42,7 @@ def get_users(db: Session, param):
else:
serializer_info['role_name'] = ''
result_list.append(serializer_info)
return result_list
return result_list, count
def generate_random_str():
......@@ -78,3 +81,21 @@ def delete_user(db: Session, user_id: int):
db.query(models.User).filter(models.User.id == user_id).delete()
db.commit()
def update_user_info(db: Session, param, user_info):
res = {"state": True}
individual_info = db.query(models.User).filter(models.User.id == user_info.get("user_id")).first()
if param.old_pwd != individual_info.hashed_password:
res["state"] = False
res["data"] = "原密码错误!"
return res
if param.new_pwd != param.confirm_pwd:
res["state"] = False
res["data"] = "两次密码不一致!"
return res
db.query(models.User).filter(models.User.id == user_info.get("user_id")).update({models.User.username: param.username,
models.User.hashed_password: param.new_pwd})
db.commit()
return res
......@@ -46,3 +46,10 @@ class UserList(BaseModel):
page: Optional[int] = None
size: Optional[int] = None
username: Optional[str] = ""
class UserUpdate(BaseModel):
username: str
old_pwd: str
new_pwd: str
confirm_pwd: str
import pyotp
from typing import List
from fastapi import Depends, APIRouter
from fastapi import Depends, APIRouter, Request
from datetime import timedelta
from sqlalchemy.orm import Session
from app import get_db
from app.api.statement.guild import query_token
from app.api.users import crud, schemas
from app.api.users.login_verification import authenticate_user, create_access_token, get_user, authenticate_pwd
from app.api.users.schemas import UserLoginForm, GoogleCode, GoogleLogin
......@@ -55,6 +56,8 @@ def google_login(data: GoogleLogin, db: Session = Depends(get_db)):
@router.get("/tokenUser")
def token_user(token=Depends(auth_token), db: Session = Depends(get_db)):
"""通过token,获取登录用户信息"""
if not token:
return HttpResultResponse(code=401, msg="登录已过期")
user_data = get_current_user(db=db, token=token)
return HttpResultResponse(code=200, data=user_data)
......@@ -82,8 +85,8 @@ def read_user(data: schemas.PermissionCreate,token=Depends(login_required), db:
@router.post("/list")
def user_list(data: schemas.UserList,token=Depends(login_required), db: Session = Depends(get_db)):
"""用户列表"""
result = crud.get_users(db, data)
return HttpResultResponse(total=len(result), data=result)
result, total = crud.get_users(db, data)
return HttpResultResponse(total=total, data=result)
@router.delete("/delete/{user_id}")
......@@ -91,3 +94,14 @@ def delete_user(user_id: int,token=Depends(login_required), db: Session = Depend
"""用户删除"""
crud.delete_user(db, user_id)
return HttpResultResponse()
@router.post("/update")
def update_individual_info(param: schemas.UserUpdate, request: Request, db: Session = Depends(get_db)):
"""个人信息修改"""
headers = request.get("headers")
user = query_token(db, headers)
res = crud.update_user_info(db, param, user)
if res.get("state"):
return HttpResultResponse()
return HttpResultResponse(code=500, msg=res.get("data"))
......@@ -30,6 +30,7 @@ client = CosS3Client(config)
COS_PATH ='https://fj-dc-test-1256890024.cos.ap-guangzhou.myqcloud.com' #测试
COS_RERURN_PATH='/images/'
class Env(BaseSettings):
DEBUG: bool = True
TESTING: bool = False
......@@ -46,7 +47,7 @@ class Env(BaseSettings):
SECRET_KEY: str = "09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7"
ALGORITHM: str = "HS256"
PASSWORD: str = "fj123456"
DB_HISTORY = "3y_history"
class TestingEnv(Env):
......
#version: "3"
#services:
# app:
# restart: always
# container_name: financial-system
# build: .
# ports:
# - "8001:8001"
# volumes:
# - /www/wwwroot/financial-system/:/financial-system/
# stdin_open: true
# command: python main.py
version: "3"
services:
financial-system:
restart: always
container_name: financial-system
build:
context: ./../_base/python-38/
image: python-38
ports:
- "8009:8009"
deploy:
resources:
limits:
cpus: "4.00"
memory: 16G
reservations:
memory: 500M
volumes:
- /www/python-38/site-packages/financial-system/:/usr/local/lib/python3.8/site-packages
- /www/wwwroot/financial-system/:/var/www/
logging:
driver: json-file
options:
max-size: "20m"
max-file: "10"
stdin_open: true
command: >
sh -c "python -m ensurepip &&
python -m pip install --upgrade pip &&
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple &&
python main.py"
\ No newline at end of file
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": "翻译付费",
"userWithdrawal_dec": "用户提现扣除项",
}
......@@ -65,22 +65,24 @@ class imageCode():
return img.decode('utf-8')
def new_upload_file(file_object,filename):
'''图片上传cos'''
filename=COS_RERURN_PATH+filename+'.png'
response = client.put_object(
Bucket=Bucket,
Body=file_object,
Key=filename,
)
filename = COS_RERURN_PATH+filename+'.png'
try:
response = client.put_object(
Bucket=Bucket,
Body=file_object,
Key=filename,
)
except Exception as e:
print("上传失败")
return ""
if response is None:
print("上传成功")
cos_path =COS_PATH + filename
cos_path = COS_PATH + filename
return cos_path
def random_number():
randomId = ''.join([str(random.randint(1, 999999)).zfill(3) for _ in range(2)])
return randomId
\ No newline at end of file
......@@ -23,13 +23,15 @@ class QueryAllData:
'''
if self.params == {}:
queryData = self.db.query(self.dbname).filter().order_by(self.dbname.id.desc()).all()
count = self.db.query(func.count(self.dbname.id)).scalar()
elif self.params_list == None:
queryData = self.db.query(self.dbname).filter().order_by(self.dbname.id.desc()).offset(
(int(self.page) - 1) * self.limit).limit(self.limit).all()
count = self.db.query(func.count(self.dbname.id)).scalar()
else:
queryData = self.db.query(self.dbname).filter(and_(*self.params_list)).order_by(
self.dbname.id.desc()).offset((int(self.page) - 1) * self.limit).limit(self.limit).all()
count = self.db.query(func.count(self.dbname.id)).scalar()
count = self.db.query(func.count(self.dbname.id)).filter(and_(*self.params_list)).scalar()
return queryData, count
def query_filter(self):
......
......@@ -14,6 +14,10 @@ class HttpMessage(object):
NO_DELETE_ROLE = "不能删除已绑定用户的角色!"
ACCOUNT_EXIST = "账号已存在"
TYPE_EXIST = "类目标识已存在"
DELETE_LOSE = '删除失败'
LOSE = '操作失败'
class DecimalEncoder(json.JSONEncoder):
......@@ -27,12 +31,12 @@ class HttpResultResponse(Response):
def __init__(self, code=None, msg=None, **kwargs):
result_dict = {
'code': code if code else status.HTTP_200_OK,
'msg': msg if code else HttpMessage.SUCCESS
'msg': msg if msg else HttpMessage.SUCCESS
}
result_dict = {**result_dict, **kwargs}
super().__init__(
content=json.dumps(result_dict,cls=DecimalEncoder),
content=json.dumps(result_dict, cls=DecimalEncoder),
media_type="application/json",
status_code=result_dict.get('code')
)
\ No newline at end of file
)
import datetime
from libs.functions import md5
from jose.exceptions import JWEError
import json
from sqlalchemy.orm import Session
from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
from jose import jwt, JWTError, ExpiredSignatureError
from app import get_db
from jose import jwt, JWTError
from app.api.role.crud import get_id_to_authority
from app.api.users import crud
from app.api.users.login_verification import get_user
from core.config.env import env
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
def auth_token(token: str = Depends(oauth2_scheme)):
try:
# 解密tokens
payload = jwt.decode(token,env.SECRET_KEY, algorithms=[env.ALGORITHM])
payload = jwt.decode(token, env.SECRET_KEY, algorithms=[env.ALGORITHM])
# 从tokens的载荷payload中获取用户名
username: str = payload.get('username')
# 如果没有获取到,抛出异常
......@@ -28,7 +28,8 @@ def auth_token(token: str = Depends(oauth2_scheme)):
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail='token过期')
return token
except JWTError as e:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=f'{e}')
# raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail='登录过期')
return ''
def get_current_user(db: Session, token: str = Depends(oauth2_scheme)):
......@@ -49,6 +50,7 @@ def get_current_user(db: Session, token: str = Depends(oauth2_scheme)):
role_info = get_id_to_authority(db, user_info.role_id)
auth_list = role_info.authority.split(',')
json_data = {
"user_id": user_data.id,
"username": user_data.username,
"authority": [int(i) for i in auth_list],
"type": 0 if '0' in auth_list else 1
......@@ -57,7 +59,6 @@ def get_current_user(db: Session, token: str = Depends(oauth2_scheme)):
except JWTError as e:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=f'{e}')
def judgeToken(token):
"""
判断token
......
......@@ -19,4 +19,4 @@ app.include_router(api_router, prefix="/api") # 路由
if __name__ == '__main__':
uvicorn.run(app=app, host="0.0.0.0", port=8001)
uvicorn.run(app=app, host="0.0.0.0", port=8009)
from core.storage.db import engine
from models import users, roles, recharge, account, margin
from models import users, roles, recharge, account, margin, guild, export
# 映射模型表
users.Base.metadata.create_all(bind=engine)
......@@ -7,3 +7,5 @@ roles.Base.metadata.create_all(bind=engine)
recharge.Base.metadata.create_all(bind=engine)
account.Base.metadata.create_all(bind=engine)
margin.Base.metadata.create_all(bind=engine)
guild.Base.metadata.create_all(bind=engine)
export.Base.metadata.create_all(bind=engine)
from sqlalchemy import Column, Integer, String, Text, DateTime, Float
from core.storage.db import Base
from sqlalchemy_serializer import SerializerMixin
class ExportFile(Base, SerializerMixin):
"""账户表"""
__tablename__ = "export_record"
id = Column(Integer, primary_key=True, index=True)
operator = Column(String(10), comment="操作人")
source = Column(String(50), comment="请求来源标识,方便扩展,比如财务后台、总后台、公会后台等")
method = Column(String(50), comment="哪个方法进行的导出")
params = Column(Text, comment="json格式的请求参数")
identify = Column(String(32), comment="md5的params值,用于和method一起做查询")
status = Column(Integer, default=0, comment="执行状态 0:待执行 1:成功 2:失败,3:无数据导出")
remark = Column(Text, comment="备注")
url = Column(String(200), comment="文件地址")
create_time = Column(DateTime, comment="创建时间")
update_time = Column(DateTime, comment="更新时间")
__table_args__ = {'comment': '导出文件记录'}
......@@ -113,3 +113,20 @@ class Guild(Base, SerializerMixin):
operation_pwd = Column(String(255), default=0, comment="操作密码")
__table_args__ = {'comment': '公会表'}
class GuildPledgeRecord(Base, SerializerMixin):
"""公会质押记录表"""
__tablename__ = 'guild_pledge_record'
id = Column(Integer, primary_key=True, index=True)
guild_id = Column(Integer, default=0, comment="公会id")
before_pears = Column(Float, comment="变动前金额(元)")
after_pears = Column(Float, comment="变动后金额(元)")
create_time = Column(DateTime, comment="创建时间")
update_time = Column(DateTime, comment="修改时间")
tixian_id = Column(Integer, comment="提现id")
is_handle = Column(Integer, default=2, comment="是否处理 2表示未处理 1为处理")
pledge_pearl = Column(Float, default=0.00, comment="质押金(元)")
margin = Column(Float, default=0.00, comment="保证金(元)")
__table_args__ = {'comment': '公会质押记录表'}
......@@ -16,6 +16,6 @@ class GuildMargin(Base, SerializerMixin):
violate_images = Column(String(255), comment="违规图片地址")
deduction_images = Column(String(255), comment="扣减图片地址")
status = Column(Integer, comment="3表示未处理 4表示成功 5表示拒绝")
create_time = Column(Integer, comment="添加时间")
create_time = Column(DateTime, comment="添加时间")
__table_args__ = {'comment': '公会保证金记录'}
......@@ -97,25 +97,6 @@ class Paymentlog(Base, SerializerMixin):
__table_args__ = {'comment': '打款记录表'}
class Fiaccount(Base, SerializerMixin):
'''
账户
'''
__tablename__ = "fi_account"
id = Column(Integer, primary_key=True, index=True)
name = Column(String(100), comment="账户名称")
unique_tag = Column(String(100), comment="唯一标记")
beneficiary = Column(String(100), comment="受益人")
description = Column(String(100), comment="描述信息")
uuid = Column(String(60), comment="用户id", index=True)
create_time = Column(Integer, comment="创建时间")
config_key = Column(String(150), comment="配置key,和api接口约定好的标识")
income = Column(Text, comment="入账")
output = Column(Text, comment="出账")
operator = Column(String(255), comment="")
operator_id = Column(Integer, comment="操作id")
class Fitransferlog(Base, SerializerMixin):
'''
转账列表, 商量说存id
......@@ -123,9 +104,11 @@ class Fitransferlog(Base, SerializerMixin):
__tablename__ = "fi_transfer_log"
id = Column(Integer, primary_key=True, index=True)
amount = Column(DECIMAL(20, 6), comment="转入金额")
dst_id = Column(Integer, comment="转出账户id")
dst_id = Column(String(100), comment="转出账户id")
dst_name = Column(String(100), comment="转出账户名称")
create_time = Column(Integer, comment="创建时间")
transfer_id = Column(Integer, comment="转入账户id")
transfer_id = Column(String(100), comment="转入账户id")
transfer_name = Column(String(100), comment="转入账户名称")
type = Column(Integer, comment="转账类型(0:对企业,1:对个人)")
nick_name = Column(String(100), comment="用户昵称")
remark = Column(String(255), comment="转账备注")
......
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