feat: 增加食物记录相关 api
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
721a5f1aa8
commit
0353bbe7b4
|
@ -4,6 +4,7 @@ from app.api.v1.api import api
|
||||||
from app.api.v1.auth import auth
|
from app.api.v1.auth import auth
|
||||||
from app.api.v1.record import record
|
from app.api.v1.record import record
|
||||||
from app.api.v1.user import user
|
from app.api.v1.user import user
|
||||||
|
from app.api.v1.diet import diet
|
||||||
|
|
||||||
|
|
||||||
def create_v1():
|
def create_v1():
|
||||||
|
@ -12,6 +13,7 @@ def create_v1():
|
||||||
bp_v1.register_blueprint(auth, url_prefix='/auth')
|
bp_v1.register_blueprint(auth, url_prefix='/auth')
|
||||||
bp_v1.register_blueprint(record, url_prefix='/record')
|
bp_v1.register_blueprint(record, url_prefix='/record')
|
||||||
bp_v1.register_blueprint(user, url_prefix='/user')
|
bp_v1.register_blueprint(user, url_prefix='/user')
|
||||||
|
bp_v1.register_blueprint(diet, url_prefix='/diet')
|
||||||
return bp_v1
|
return bp_v1
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,22 +7,22 @@ from apiflask import APIBlueprint
|
||||||
from flask import session
|
from flask import session
|
||||||
|
|
||||||
from app import rpc
|
from app import rpc
|
||||||
from app.api.v1.exception.api import ImageUploadError, UserInfoError, ImageNotFound
|
from app.api.v1.exception.api import ImageUploadError, UserInfoError, ImageNotFound, DietCreationError
|
||||||
from app.api.v1.schema.api import ImageIn, ImagePreSignUrlOut, ImagePreSignUrlIn
|
from app.api.v1.schema.api import ImageIn, ImagePreSignUrlOut, ImagePreSignUrlIn, DietImageIn
|
||||||
from app.util.auth import login_required
|
from app.util.auth import login_required
|
||||||
|
|
||||||
api = APIBlueprint('api', __name__)
|
api = APIBlueprint('api', __name__)
|
||||||
|
|
||||||
|
|
||||||
@api.post('/images')
|
@api.post('/images')
|
||||||
@api.doc(summary='上传图片', description='上传图片')
|
@api.doc(summary='上传头像图片', description='上传头像图片')
|
||||||
@api.input(ImageIn, location='files')
|
@api.input(ImageIn, location='files')
|
||||||
@api.output(ImagePreSignUrlOut)
|
@api.output(ImagePreSignUrlOut)
|
||||||
@login_required
|
@login_required
|
||||||
def upload_image(files_data):
|
def upload_avatar_image(files_data):
|
||||||
f = files_data['image']
|
f = files_data['image']
|
||||||
try:
|
try:
|
||||||
result = rpc.storage.upload(file_name=str(session['user_id']+f'_{f.filename}'),
|
result = rpc.storage.upload(file_name=str(session['user_id'] + f'_{f.filename}'),
|
||||||
file_binary=f.read(),
|
file_binary=f.read(),
|
||||||
bucket='bodyrecord',
|
bucket='bodyrecord',
|
||||||
folder='avatar',
|
folder='avatar',
|
||||||
|
@ -49,6 +49,44 @@ def upload_image(files_data):
|
||||||
raise ImageUploadError()
|
raise ImageUploadError()
|
||||||
|
|
||||||
|
|
||||||
|
@api.post('/images/diet')
|
||||||
|
@api.doc(summary='上传食物图片', description='上传食物图片')
|
||||||
|
@api.input(DietImageIn, location='files')
|
||||||
|
@api.output(ImagePreSignUrlOut)
|
||||||
|
@login_required
|
||||||
|
def upload_diet_image(files_data):
|
||||||
|
f = files_data['image']
|
||||||
|
category = files_data['category'] # 食物类别
|
||||||
|
try:
|
||||||
|
result = rpc.storage.upload(file_name=str(session['user_id'] + f'_{f.filename}'),
|
||||||
|
file_binary=f.read(),
|
||||||
|
bucket='bodyrecord',
|
||||||
|
folder='diet',
|
||||||
|
app='bodyrecord')
|
||||||
|
except Exception as e:
|
||||||
|
raise ImageUploadError(extra_data={'error_docs': str(e)})
|
||||||
|
|
||||||
|
if result.get('status') and result['status'] == 'UPLOADED':
|
||||||
|
# 图片上传成功,处理业务逻辑
|
||||||
|
try:
|
||||||
|
rpc.diet.add(session['user_id'],
|
||||||
|
category=category,
|
||||||
|
diet_image_id=result['_id'])
|
||||||
|
except Exception as e:
|
||||||
|
raise DietCreationError(extra_data={'error_docs': str(e)})
|
||||||
|
|
||||||
|
try:
|
||||||
|
presign_url = rpc.storage.get_presign_url(result['_id'],
|
||||||
|
'bodyrecord',
|
||||||
|
bucket='bodyrecord')
|
||||||
|
except Exception as e:
|
||||||
|
raise ImageNotFound(extra_data={'error_docs': str(e)})
|
||||||
|
|
||||||
|
return {'image_presign_url': presign_url}
|
||||||
|
else:
|
||||||
|
raise ImageUploadError()
|
||||||
|
|
||||||
|
|
||||||
@api.get('/images/presign_url')
|
@api.get('/images/presign_url')
|
||||||
@api.input(ImagePreSignUrlIn, location='query')
|
@api.input(ImagePreSignUrlIn, location='query')
|
||||||
@api.output(ImagePreSignUrlOut)
|
@api.output(ImagePreSignUrlOut)
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
from apiflask import APIBlueprint
|
||||||
|
from flask import session
|
||||||
|
|
||||||
|
from app import rpc
|
||||||
|
from app.api.v1.exception.diet import DietRecordNotFound
|
||||||
|
from app.api.v1.schema.diet import DietRecordsIn, DietRecordsOut, DietRecordOut
|
||||||
|
|
||||||
|
from app.util.auth import login_required
|
||||||
|
|
||||||
|
diet = APIBlueprint('diet', __name__)
|
||||||
|
|
||||||
|
|
||||||
|
@diet.get('/list')
|
||||||
|
@diet.doc(summary='查询食物记录列表', description='查询食物记录列表')
|
||||||
|
@diet.input(DietRecordsIn, location='query')
|
||||||
|
@diet.output(DietRecordsOut)
|
||||||
|
@login_required
|
||||||
|
def get_diet_records(query_data):
|
||||||
|
try:
|
||||||
|
sort = query_data.get('sort', '-create_time')
|
||||||
|
current_date = query_data.get('current_date', None)
|
||||||
|
results = rpc.diet.get_all_by_user(session['user_id'],
|
||||||
|
sort=sort,
|
||||||
|
current_date=current_date)
|
||||||
|
except Exception as e:
|
||||||
|
raise DietRecordNotFound(extra_data={'error_docs': str(e)})
|
||||||
|
return {'records': results}
|
||||||
|
|
||||||
|
|
||||||
|
@diet.get('/<diet_id>')
|
||||||
|
@diet.doc(summary='查询单条食物记录', description='查询单条食物记录')
|
||||||
|
@diet.output(DietRecordOut)
|
||||||
|
@login_required
|
||||||
|
def get_diet_record(diet_id):
|
||||||
|
try:
|
||||||
|
result = rpc.diet.get_one(diet_id)
|
||||||
|
except Exception as e:
|
||||||
|
raise DietRecordNotFound(extra_data={'error_docs': str(e)})
|
||||||
|
return result
|
|
@ -11,6 +11,11 @@ class UserInfoError(HTTPError):
|
||||||
message = '设置用户信息失败'
|
message = '设置用户信息失败'
|
||||||
|
|
||||||
|
|
||||||
|
class DietCreationError(HTTPError):
|
||||||
|
status_code = 500
|
||||||
|
message = '添加食物记录失败'
|
||||||
|
|
||||||
|
|
||||||
class ImageNotFound(HTTPError):
|
class ImageNotFound(HTTPError):
|
||||||
status_code = 404
|
status_code = 404
|
||||||
message = '获取图片链接失败'
|
message = '获取图片链接失败'
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
from apiflask import HTTPError
|
||||||
|
|
||||||
|
|
||||||
|
class DietRecordNotFound(HTTPError):
|
||||||
|
status_code = 404
|
||||||
|
message = '找不到用户对应的食物记录'
|
|
@ -4,7 +4,7 @@ from flask import session
|
||||||
from app import rpc
|
from app import rpc
|
||||||
from app.api.v1.exception.record import AddBodyRecordError, BodyRecordNotFound, BodyRecordChartError
|
from app.api.v1.exception.record import AddBodyRecordError, BodyRecordNotFound, BodyRecordChartError
|
||||||
from app.api.v1.schema.record import BodyRecordIn, BodyRecordOut, BodyRecordsOut, BodyRecordsIn, BodyRecordChartIn, \
|
from app.api.v1.schema.record import BodyRecordIn, BodyRecordOut, BodyRecordsOut, BodyRecordsIn, BodyRecordChartIn, \
|
||||||
BodyRecordChartOut, BodyRecordIdIn
|
BodyRecordChartOut
|
||||||
from app.util.auth import login_required
|
from app.util.auth import login_required
|
||||||
|
|
||||||
record = APIBlueprint('record', __name__)
|
record = APIBlueprint('record', __name__)
|
||||||
|
|
|
@ -6,8 +6,13 @@ class ImageIn(Schema):
|
||||||
image = File()
|
image = File()
|
||||||
|
|
||||||
|
|
||||||
|
class DietImageIn(Schema):
|
||||||
|
image = File()
|
||||||
|
category = String()
|
||||||
|
|
||||||
|
|
||||||
class ImagePreSignUrlIn(Schema):
|
class ImagePreSignUrlIn(Schema):
|
||||||
avatar_id = String(required=True)
|
image_id = String(required=True)
|
||||||
expire_time = Integer()
|
expire_time = Integer()
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,3 +20,7 @@ class ImagePreSignUrlOut(Schema):
|
||||||
image_presign_url = URL()
|
image_presign_url = URL()
|
||||||
|
|
||||||
|
|
||||||
|
class ImageIdOut(Schema):
|
||||||
|
image_id = String()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
from apiflask import Schema
|
||||||
|
from apiflask import fields
|
||||||
|
|
||||||
|
|
||||||
|
class DietRecordsIn(Schema):
|
||||||
|
sort = fields.String()
|
||||||
|
current_date = fields.String()
|
||||||
|
|
||||||
|
|
||||||
|
class DietRecordOut(Schema):
|
||||||
|
diet_id = fields.String(attribute='_id')
|
||||||
|
category = fields.String()
|
||||||
|
diet_image_id = fields.String()
|
||||||
|
diet_image_url = fields.URL()
|
||||||
|
create_time = fields.String()
|
||||||
|
update_time = fields.String(allow_none=True)
|
||||||
|
|
||||||
|
|
||||||
|
class DietRecordsOut(Schema):
|
||||||
|
records = fields.List(fields.Nested(DietRecordOut))
|
Loading…
Reference in New Issue