146 lines
4.5 KiB
Python
146 lines
4.5 KiB
Python
from flask import Flask, request, jsonify
|
|
from models import database, Habit, CheckIn
|
|
from datetime import datetime
|
|
import os
|
|
from dotenv import load_dotenv
|
|
|
|
load_dotenv() # 加载 .env 文件中的环境变量
|
|
|
|
app = Flask(__name__)
|
|
app.config['SECRET_KEY'] = os.getenv('SECRET_KEY', 'default-secret-key')
|
|
|
|
@app.before_request
|
|
def before_request():
|
|
database.connect()
|
|
|
|
@app.after_request
|
|
def after_request(response):
|
|
database.close()
|
|
return response
|
|
|
|
# 1. 创建事项
|
|
@app.route('/api/v1/habits', methods=['POST'])
|
|
def create_habit():
|
|
data = request.json
|
|
try:
|
|
habit = Habit.create(
|
|
name=data['name'],
|
|
description=data.get('description', ''),
|
|
periodicity=data.get('periodicity', 'daily'),
|
|
reminder_time=data.get('reminder_time'),
|
|
icon=data.get('icon'),
|
|
color=data.get('color', '#000000')
|
|
)
|
|
return jsonify({
|
|
'id': habit.id,
|
|
'message': '创建成功'
|
|
}), 201
|
|
except Exception as e:
|
|
return jsonify({'error': str(e)}), 400
|
|
|
|
# 2. 获取所有事项
|
|
@app.route('/api/v1/habits', methods=['GET'])
|
|
def get_habits():
|
|
habits = [
|
|
{
|
|
'id': habit.id,
|
|
'name': habit.name,
|
|
'icon': habit.icon,
|
|
'color': habit.color,
|
|
'created_at': habit.created_at.isoformat()
|
|
}
|
|
for habit in Habit.select()
|
|
]
|
|
return jsonify(habits)
|
|
|
|
# 3. 打卡某事项
|
|
@app.route('/api/v1/habits/<int:habit_id>/checkins', methods=['POST'])
|
|
def check_in_habit(habit_id):
|
|
data = request.json
|
|
try:
|
|
habit = Habit.get_by_id(habit_id)
|
|
checkin_date = datetime.strptime(data['date'], '%Y-%m-%d').date()
|
|
|
|
CheckIn.create(
|
|
habit=habit,
|
|
date=checkin_date,
|
|
note=data.get('note', '')
|
|
)
|
|
return jsonify({'message': '打卡成功'})
|
|
except Habit.DoesNotExist:
|
|
return jsonify({'error': '事项不存在'}), 404
|
|
except Exception as e:
|
|
return jsonify({'error': str(e)}), 400
|
|
|
|
# 4. 获取某事项的打卡记录
|
|
@app.route('/api/v1/habits/<int:habit_id>/checkins', methods=['GET'])
|
|
def get_habit_checkins(habit_id):
|
|
try:
|
|
habit = Habit.get_by_id(habit_id)
|
|
from_date = request.args.get('from')
|
|
to_date = request.args.get('to')
|
|
|
|
query = CheckIn.select().where(CheckIn.habit == habit)
|
|
if from_date:
|
|
query = query.where(CheckIn.date >= datetime.strptime(from_date, '%Y-%m-%d').date())
|
|
if to_date:
|
|
query = query.where(CheckIn.date <= datetime.strptime(to_date, '%Y-%m-%d').date())
|
|
|
|
checkins = [
|
|
{
|
|
'date': checkin.date.isoformat(),
|
|
'note': checkin.note
|
|
}
|
|
for checkin in query
|
|
]
|
|
return jsonify(checkins)
|
|
except Habit.DoesNotExist:
|
|
return jsonify({'error': '事项不存在'}), 404
|
|
|
|
# 5. 获取统计信息
|
|
@app.route('/api/v1/habits/<int:habit_id>/stats', methods=['GET'])
|
|
def get_habit_stats(habit_id):
|
|
try:
|
|
habit = Habit.get_by_id(habit_id)
|
|
total_checkins = CheckIn.select().where(CheckIn.habit == habit).count()
|
|
|
|
# TODO: Implement streak calculations
|
|
return jsonify({
|
|
'total_checkins': total_checkins,
|
|
'current_streak': 0, # To be implemented
|
|
'longest_streak': 0 # To be implemented
|
|
})
|
|
except Habit.DoesNotExist:
|
|
return jsonify({'error': '事项不存在'}), 404
|
|
|
|
# 6. 删除事项
|
|
@app.route('/api/v1/habits/<int:habit_id>', methods=['DELETE'])
|
|
def delete_habit(habit_id):
|
|
try:
|
|
habit = Habit.get_by_id(habit_id)
|
|
habit.delete_instance(recursive=True) # This will also delete associated check-ins
|
|
return jsonify({'message': '删除成功'})
|
|
except Habit.DoesNotExist:
|
|
return jsonify({'error': '事项不存在'}), 404
|
|
|
|
# 7. 修改事项
|
|
@app.route('/api/v1/habits/<int:habit_id>', methods=['PUT'])
|
|
def update_habit(habit_id):
|
|
try:
|
|
habit = Habit.get_by_id(habit_id)
|
|
data = request.json
|
|
|
|
for field in ['name', 'description', 'periodicity', 'reminder_time', 'icon', 'color']:
|
|
if field in data:
|
|
setattr(habit, field, data[field])
|
|
|
|
habit.save()
|
|
return jsonify({'message': '更新成功'})
|
|
except Habit.DoesNotExist:
|
|
return jsonify({'error': '事项不存在'}), 404
|
|
except Exception as e:
|
|
return jsonify({'error': str(e)}), 400
|
|
|
|
if __name__ == '__main__':
|
|
app.run(debug=True)
|