23 KiB
开发日志
- 日期: 2025-07-23
后端开发 (V1.0) - 用户登录/注册
1. 摘要
本次开发完成了 "食话食说" 应用后端的用户登录/注册核心功能。基于产品原型文档,使用 Python FastAPI 框架搭建了后端服务,实现了通过手机号和验证码进行用户身份验证的流程。
2. 技术选型
- Web 框架: FastAPI
- 数据库: SQLite
- ORM: SQLAlchemy
- 数据校验: Pydantic
- 认证机制: JWT (python-jose)
3. 项目结构
在项目根目录下创建了 shihuashishuo-api
目录,并采用模块化的结构:
main.py
: FastAPI 应用主入口,定义 API 路由。database.py
: 数据库连接与会话管理。models.py
: SQLAlchemy 数据库模型定义。schemas.py
: Pydantic 数据校验模型定义。crud.py
: 数据库增删改查操作封装。requirements.txt
: Python 依赖项列表。
4. API 设计
实现了两个核心 API 端点:
POST /send-code
:- 功能: 接收手机号,用于请求验证码。
- 实现: 当前版本仅做手机号格式(11位)校验,并返回成功信息,未实际发送短信。
POST /login
:- 功能: 接收手机号和验证码,完成登录或注册。
- 实现: 校验验证码是否为固定值 "111111"。验证通过后,查询用户是否存在,若不存在则自动创建新用户。最后,生成并返回 JWT 用于客户端的会话保持。
5. 遇到的主要挑战及解决方案
- 挑战: 在项目初始化阶段,由于在多个模块中使用了相对导入 (
from . import ...
),导致直接通过python -m uvicorn
启动应用时出现ImportError: attempted relative import with no known parent package
的错误。 - 解决方案: 系统性地将
main.py
,crud.py
,models.py
等文件中的相对导入全部修改为绝对导入 (import ...
),彻底解决了模块查找路径问题,使服务器能够成功启动和热重载。 - 挑战: 在实现
/login
接口时,忘记在 Pydantic 的UserCreate
模型中添加code
字段,导致无法从请求体中正确解析验证码。 - 解决方案: 修改了
schemas.py
文件,为UserCreate
模型增加了一个可选的code
字段,解决了数据校验层面的问题。
2025-07-23: 登录页面功能增强与后端逻辑对接
文件修改:
shihuashishuo-ui/src/views/通用基础页/LoginView-登录页-2.0.vue
主要更新:
- 获取验证码逻辑增强:
- 现在必须输入11位手机号后,“获取验证码”按钮才可用。
- 点击后,按钮会进入60秒倒计时,期间无法再次点击。
- 登录/注册逻辑实现:
- 增加了前端登录验证。
- 用户需输入11位手机号和正确的验证码才能登录。
- 为方便测试,验证码暂时硬编码为
111111
。
- 路由跳转:
- 验证成功后,页面将自动跳转到应用主页 (
/
)。
- 验证成功后,页面将自动跳转到应用主页 (
补充说明 (2025-07-23):
- 根据用户反馈,移除了登录验证失败时的
alert
弹窗,改为使用console.error
在控制台输出错误信息,以提升用户体验。
2025-07-23: 实现扫码功能前后端交互
1. 后端 API 开发 (FastAPI):
- 数据库模型 (
models.py
): 新增Food
模型,用于存储食品信息,包括barcode
,name
,brand
,ingredients
等字段。 - 数据结构 (
schemas.py
): 添加了FoodCreate
和Food
Pydantic 模型,用于数据验证和 API 响应。 - 数据库操作 (
crud.py
): 实现了create_food
和get_food_by_barcode
函数,用于处理食品数据的增删改查。 - API 路由 (
main.py
):- 创建了
POST /api/v1/food/
接口,用于创建新的食品条目。 - 创建了
GET /api/v1/food/{barcode}
接口,用于根据条形码查询食品信息。
- 创建了
2. 前端页面开发 (Vue.js):
- 扫码页面 (
ScanView-扫码页.vue
):- 修改了
scan
函数的逻辑,移除了模拟跳转。 - 现在,点击扫描按钮会触发一个
async
函数,该函数:- 使用
fetch
API 调用后端的POST /api/v1/food/
接口,创建一个用于测试的食品样本。 - 接着调用
GET /api/v1/food/{barcode}
接口,获取该食品的详细信息。 - 成功获取数据后,使用
vue-router
将用户导航到结果页面,并将食品的条形码作为参数传递。 - 添加了错误处理逻辑,以便在 API 调用失败时在控制台输出错误信息。
- 使用
- 修改了
3. 数据库:
- 确认了项目使用 SQLite 数据库,并且连接配置正确。
- 新的
Food
表已通过models.Base.metadata.create_all(bind=engine)
成功创建。
结论: 本次更新成功打通了从前端扫码到后端数据查询再到前端页面跳转的完整流程,为后续开发食品详情展示页和相关功能奠定了基础。
2025-07-23: 实现引导页用户偏好设置功能
1. 后端 API 开发 (FastAPI):
- 数据库模型 (
models.py
): 新增UserPreference
模型,用于存储用户的偏好选项,并通过外键与User
模型关联。 - 数据结构 (
schemas.py
): 添加了UserPreference
相关的 Pydantic schema,并创建了OnboardingPreferences
schema 用于统一接收前端引导页的完整数据。 - 数据库操作 (
crud.py
): 实现了create_user_preferences
函数,用于批量创建或更新用户的偏好设置。在写入新数据前会先清除旧数据,以保证幂等性。 - API 路由 (
main.py
):- 创建了
get_current_user
依赖项,通过解析 JWT 来实现用户身份验证。 - 创建了受保护的
POST /api/v1/users/me/preferences
接口,用于接收并保存当前登录用户的偏好设置。
- 创建了
2. 前端页面开发 (Vue.js):
- 状态管理 (
stores/auth.ts
):- 增强了
useAuthStore
,添加了对 JWTtoken
的存储和管理功能。
- 增强了
- 引导页 (
views/通用基础页/OnboardingView-引导页.vue
):- 修改了
finish
函数的逻辑,使其成为一个async
函数。 - 现在,点击“完成”按钮会触发一个 API 调用:
- 从
authStore
中获取认证token
。 - 收集用户选择的所有偏好,并构造成符合后端要求的 JSON
payload
。 - 使用
fetch
API 调用后端的POST /api/v1/users/me/preferences
接口,并在请求头中附带Authorization: Bearer <token>
。 - 请求成功后,调用
authStore.completeOnboarding()
来更新前端的引导完成状态。 - 最后,使用
vue-router
将用户导航到主页。
- 从
- 添加了
try...catch
块来处理 API 调用可能出现的错误。
- 修改了
结论: 本次更新成功打通了从前端引导页收集用户偏好,到后端进行认证、处理并持久化存储的完整流程。这为未来根据用户偏好进行个性化内容推荐奠定了坚实的数据基础。
2025-07-23: 实现首页搜索功能与历史记录
1. 后端 API 开发 (FastAPI):
- 数据库模型 (
models.py
): 新增SearchHistory
模型,用于存储用户的搜索记录,包含query
和可选的user_id
。 - 数据结构 (
schemas.py
): 添加了SearchHistory
相关的 Pydantic schema (SearchHistoryCreate
,SearchHistory
)。 - 数据库操作 (
crud.py
): 实现了create_search_history
函数,用于将搜索记录存入数据库。 - API 路由 (
main.py
):- 创建了
get_current_user_optional
依赖项,用于支持可选的用户认证。 - 创建了
POST /api/v1/search/history
接口,用于接收并保存搜索记录。如果用户已登录,则关联用户ID。
- 创建了
2. 前端页面开发 (Vue.js):
- 首页 (
views/HomeView-首页-2.0.vue
):- 移除了搜索输入框的
readonly
属性,允许用户直接输入。 - 使用
v-model
绑定了searchQuery
状态。 - 实现了
handleSearch
方法,该方法会在用户点击搜索按钮、热门标签或在输入框按回车时触发。 handleSearch
方法会:- 调用后端的
/api/v1/search/history
接口来保存搜索词,如果用户已登录,则请求会附带认证 Token。 - 使用
vue-router
将用户导航到搜索结果页 (/search-result
),并将搜索词作为查询参数q
传递。
- 调用后端的
- 移除了搜索输入框的
结论: 本次更新实现了完整的首页搜索功能。用户现在可以直接在首页进行搜索,搜索行为会被记录到数据库中(无论是否登录),并能正确跳转到搜索结果页面。
2025-07-24:实现登录后引导及全局路由守卫
开发者: 首席开发 (LD)
任务描述: 为了优化新用户体验,本次更新实现了用户登录后首先进入引导页(Onboarding)的功能,而不是直接进入应用首页。同时,重构了全局路由守卫,以统一处理认证、授权和页面跳转逻辑。
主要变更:
-
重构全局路由守卫 (
src/router/index.ts
):- 在
router.beforeEach
中实现了新的导航逻辑,以集中管理所有路由跳转。 - 未登录用户: 访问任何需要认证的页面时,将被自动重定向到登录页。
- 已登录但未完成引导的用户: 访问除引导页外的任何页面,都将被强制重定向到
/onboarding
,确保新用户完成初始化设置。 - 已登录且已完成引导的用户: 访问登录页或引导页时,将被自动重定向到应用首页 (
/app/home
),避免重复操作。
- 在
-
简化登录逻辑 (
src/views/通用基础页/LoginView-登录页-2.0.vue
):- 移除了登录成功后的条件跳转逻辑。
- 现在,登录成功后只需调用
router.push({ name: 'home' })
,后续的页面重定向完全由新的全局路由守卫处理,简化了组件代码并提高了逻辑的内聚性。
状态管理 (src/stores/auth.ts
):
- 确认
useAuthStore
中的isLoggedIn
和hasCompletedOnboarding
状态能够满足新逻辑的需求,未做修改。
成果: 通过本次更新,应用的用户流更加清晰和健壮。新用户能够被平滑地引导完成初次设置,而老用户则可以无缝地进入应用核心功能区。路由逻辑的集中化管理也为未来增加新的页面和路由规则提供了便利。
2025-07-24 (修正):修正登录后跳转逻辑
开发者: 首席开发 (LD)
任务描述: 根据用户反馈,对之前实现的登录流程进行修正。原有的实现虽然建立了全局路由守卫,但在登录页直接跳转到首页,导致新用户无法直接进入引导页,流程体验不佳。
主要变更:
-
还原登录页跳转逻辑 (
src/views/通用基础页/LoginView-登录页-2.0.vue
):- 恢复了
mainLogin
函数中的条件跳转逻辑。 - 现在,当用户登录成功后,程序会检查
authStore.hasCompletedOnboarding
的状态:- 如果为
false
(新用户),则直接使用router.push({ name: 'onboarding' })
导航到引导页。 - 如果为
true
(老用户),则使用router.push({ name: 'home' })
导航到首页。
- 如果为
- 恢复了
-
全局路由守卫 (
src/router/index.ts
):- 保留了重构后的全局路由守卫。它将继续作为保障,处理所有边缘情况下的路由跳转,例如用户手动输入URL等场景,确保系统的健壮性。
成果: 通过本次修正,新用户在登录后将直接、顺畅地进入引导页,符合预期的用户体验。同时,保留的全局路由守卫依然为整个应用的导航提供了坚实的保障。
2025-07-24: 用户认证与数据管理流程总结
开发者: 首席开发 (LD)
任务描述: 本文档旨在总结当前已实现的用户认证、密码管理及偏好设置功能的完整技术流程,涵盖数据存储、后端接口和前端实现。
1. 数据存储 (数据库模型):
所有用户相关数据都存储在后端的 SQLite 数据库 (shihuashishuo.db
) 中,通过 SQLAlchemy ORM 进行管理。
User
表 (shihuashishuo-api/models.py
):id
: 用户唯一标识。phone_number
: 用户手机号,唯一且作为主要登录凭据。hashed_password
: 存储用户加密后的密码,允许为空以兼容纯验证码登录的用户。created_at
: 用户创建时间。
UserPreference
表 (shihuashishuo-api/models.py
):- 通过
user_id
外键与User
表关联。 - 用于存储用户的个性化偏好,如“关注”和“过敏原”。
- 通过
2. 后端核心 API (shihuashishuo-api/main.py
):
后端使用 FastAPI 框架,所有认证相关的接口都位于 /api/v1/auth
路径下。
POST /send-verification-code
: 发送手机验证码(当前为模拟)。POST /login
: 手机验证码登录。验证通过后,如果用户不存在则自动注册,并返回 JWT (JSON Web Token)。POST /login/password
: 密码登录。验证手机号和密码,成功后返回 JWT。PUT /users/me/password
: 设置/修改密码。这是一个受保护的接口,必须在请求头中提供有效的 JWT 才能调用。POST /users/me/preferences
: 保存用户偏好。同样是受保护接口,用于将在引导页选择的偏好存入数据库。
3. 前端核心实现:
- 状态管理 (
shihuashishuo-ui/src/stores/auth.ts
):- 使用 Pinia (
useAuthStore
) 统一管理用户的登录状态 (isLoggedIn
)、JWT (token
) 和引导页完成状态 (hasCompletedOnboarding
)。 token
和hasCompletedOnboarding
状态会持久化到浏览器的localStorage
中。- 提供了
passwordLogin
和setPassword
等 actions,封装了与后端 API 的所有交互。
- 使用 Pinia (
- 页面路由与导航守卫 (
shihuashishuo-ui/src/router/index.ts
):- 页面路由:
/login
: 手机验证码登录页。/password-login
: 密码登录页。/set-password
: 设置/修改密码页。/onboarding
: 新用户引导页。
- 导航守卫 (
router.beforeEach
):- 实现了全局路由守卫,用于权限控制。
- 未登录用户访问受保护页面时,会被重定向到登录页。
- 已登录但未完成引导流程的用户,会被强制导航到引导页。
- 页面路由:
总结: 当前系统已形成一个完整的闭环:用户可以通过手机验证码或密码进行登录,登录成功后获得 JWT 用于身份认证。新用户会被引导完成偏好设置,所有偏好和密码信息都会被安全地存储在后端数据库中。
2025-07-24: 大规模后端功能扩展
开发者: 首席开发 (LD)
任务描述: 根据产品需求文档(PRD),对后端服务进行大规模的功能扩展,以支持项目第一、二、三阶段的核心功能。本次开发旨在构建一个全面的、可扩展的后端系统,为前端提供强大的数据支持。
技术栈:
- 框架: FastAPI
- 数据库: SQLite (通过 SQLAlchemy ORM)
- 数据校验: Pydantic
主要变更与实现模块:
-
健康档案系统 (
Family
&HealthProfile
):- 数据库 (
models.py
):- 新增
FamilyMember
模型,与User
建立一对多关系,用于管理家庭成员。 - 新增
HealthProfile
模型,与FamilyMember
关联,用于存储每个成员的过敏原、健康状况等个性化数据。
- 新增
- 数据接口 (
schemas.py
): 创建了FamilyMember
和HealthProfile
相关的Pydantic Schemas。 - 业务逻辑 (
crud.py
): 实现了对家庭成员和健康档案的完整CRUD操作。 - API (
main.py
): 新增/api/v1/family
路由,提供了创建、查询家庭成员及更新其健康档案的受保护端点。
- 数据库 (
-
增强版食品数据库 (
Food
,Ingredient
,Additive
):- 数据库 (
models.py
):- 重构了
Food
模型,增加了安全评级、营养评级等字段。 - 新增
Ingredient
和Additive
模型。 - 通过多对多关联表,建立了食品与成分、添加剂之间的复杂关系。
- 重构了
- 数据接口 (
schemas.py
): 创建了FoodDetails
,Ingredient
,Additive
等详细的Pydantic Schemas。 - API (
main.py
): 新增GET /api/v1/foods/{barcode}/details
端点,能够返回包含成分和添加剂详情的完整食品信息,并支持可选的用户认证以实现未来的个性化风险提示。
- 数据库 (
-
内容中心 - 健康知食 (
Article
):- 数据库 (
models.py
): 新增Article
模型,用于存储资讯和百科文章。 - 数据接口 (
schemas.py
): 创建了Article
相关的Pydantic Schemas。 - 业务逻辑 (
crud.py
): 实现了文章的创建和按分类查询的功能。 - API (
main.py
): 新增/api/v1/articles
路由,提供了获取文章列表和详情的公共端点。
- 数据库 (
-
健康厨房 - 智能食谱 (
Recipe
):- 数据库 (
models.py
):- 新增
Recipe
模型,用于存储食谱信息。 - 新增
RecipeIngredient
关联对象,用于记录食谱所需的食材及其用量。
- 新增
- 数据接口 (
schemas.py
): 创建了Recipe
和RecipeIngredient
相关的Pydantic Schemas。 - 业务逻辑 (
crud.py
): 实现了食谱的创建和详情查询功能。 - API (
main.py
): 新增/api/v1/recipes
路由,提供了创建、查询和个性化推荐食谱的端点。
- 数据库 (
-
互动社区 (
Post
,Comment
,Like
):- 数据库 (
models.py
): 新增Post
(评价),Comment
(评论),Like
(点赞) 模型,并与User
和Food
模型建立关联。 - 数据接口 (
schemas.py
): 创建了社区功能相关的Pydantic Schemas。 - 业务逻辑 (
crud.py
): 实现了发帖、评论、点赞/取消点赞的核心逻辑。 - API (
main.py
): 新增/api/v1
下的社区路由,提供了发布评价、获取评论、点赞等受保护的互动端点。
- 数据库 (
-
健康商城 (
Product
,Order
,Cart
):- 数据库 (
models.py
): 新增Product
,Order
,OrderItem
,CartItem
模型,为第三阶段的电商功能奠定了数据基础。 - 数据接口 (
schemas.py
): 创建了商城功能相关的Pydantic Schemas。 - 业务逻辑 (
crud.py
): 实现了商品查询、购物车管理和订单创建的基础逻辑。 - API (
main.py
): 新增/api/v1/mall
路由,提供了浏览商品、管理购物车和下单的端点。
- 数据库 (
成果: 本次更新成功地将一个基础的用户认证系统,扩展成了一个功能全面、层次清晰、高度可扩展的综合性后端服务。所有核心模块均已完成从数据库到API的贯通,为前端开发提供了稳定、完整的数据支持,也为项目的长远发展打下了坚实的基础。
2025-07-24: 弥补后端功能差距与重构
开发者: 首席开发 (LD)
任务描述: 本次开发旨在根据产品需求文档,识别并补充之前规划中遗漏的8个关键后端功能模块。同时,对现有的点赞功能进行重构,以提升系统的通用性和可维护性。
主要变更与实现模块:
-
OAuth第三方登录支持:
- 数据库 (
models.py
): 新增OAuthAccount
模型,用于存储第三方平台的openid
,并与User
模型建立一对多关联。 - 数据接口 (
schemas.py
): 创建了OAuthAccount
相关的Pydantic Schemas。 - 业务逻辑 (
crud.py
&security.py
): 实现了get_or_create_oauth_user
函数,以及模拟的authenticate_wechat_user
逻辑,完成了从code
到本地用户的身份关联流程。 - API (
main.py
):- 新增
POST /api/v1/auth/wechat/callback
端点,用于处理微信登录回调。 - 重构了
get_current_user
和get_current_user_optional
依赖,使其能够通过JWT中的user.id
来识别用户,兼容了手机号和OAuth两种登录方式。
- 新增
- 数据库 (
-
智能食谱推荐 (
“冰箱有什么”
):- 业务逻辑 (
crud.py
): 实现了suggest_recipes_by_ingredients
函数,该函数能根据用户提供的食材ID列表,查询出匹配度最高的食谱。 - API (
main.py
): 新增POST /api/v1/recipes/suggest-by-ingredients
端点,将推荐功能暴露给前端。
- 业务逻辑 (
-
用户提交新食品:
- 数据库 (
models.py
): 新增SubmittedFood
模型,用于暂存用户提交的食品信息,并包含审核状态status
字段。 - 数据接口 (
schemas.py
): 创建了SubmittedFood
相关的Pydantic Schemas。 - 业务逻辑 (
crud.py
): 实现了create_submitted_food
函数。 - API (
main.py
): 新增POST /api/v1/foods/submit
受保护端点,允许用户提交新食品。
- 数据库 (
-
社区话题功能:
- 数据库 (
models.py
):- 新增
Topic
模型,用于定义社区话题。 - 在
Post
模型中添加了topic_id
外键和topic
关系,将帖子与话题关联。
- 新增
- 数据接口 (
schemas.py
): 创建了Topic
相关的Pydantic Schemas。 - 业务逻辑 (
crud.py
): 实现了get_topics
和get_posts_by_topic
函数。 - API (
main.py
): 新增GET /api/v1/topics
和GET /api/v1/topics/{topic_id}/posts
端点,用于获取话题列表和话题下的帖子。
- 数据库 (
-
收藏/点赞功能重构:
- 数据库 (
models.py
):- 移除了原有的
Like
模型。 - 新增了通用的
Favorite
模型,通过entity_type
和entity_id
字段支持对多种内容(帖子、商品、食谱等)的收藏,并通过tag
字段区分收藏类型(如'like', 'favorite')。 - 更新了
User
和Post
模型中的 relationship,用favorites
替换了likes
。
- 移除了原有的
- 数据接口 (
schemas.py
): 移除了Like
Schema,新增了Favorite
相关 Schemas,并更新了Post
Schema。 - 业务逻辑 (
crud.py
): 移除了toggle_like
函数,并实现了通用的toggle_favorite
函数。
- 数据库 (
遇到的主要挑战及解决方案:
- 任务依赖管理: 在执行过程中多次遇到任务被前置依赖阻塞的情况。通过逐级追溯并完成最基础的依赖任务,成功疏通了任务链。
- 代码与规划不一致: 发现多个模型相关的任务(如
Food
,Recipe
,Post
等)在代码库中已被实现。通过仔细的代码审查,避免了重复开发,直接将这些任务验证并关闭。 - SQLAlchemy关系错误: 在实现社区话题功能时,由于错误地将外键添加到了不相关的模型上,导致了
NoForeignKeysError
。通过分析错误日志,定位并修正了模型定义,最终解决了问题。
成果:
本次大规模的更新和重构,极大地完善了后端的功能版图,使其更贴近产品需求。通过引入通用模型(如Favorite
),提升了代码的复用性和系统的可扩展性,为后续的开发工作奠定了更坚实的基础。