feat (infra): Trae 完成 asset_helper_backend 微服务基础架构 V1 初始化
核心实现:搭建 Monorepo 架构,完成 shared 共享包、gateway、user-service 基础框架开发 技术落地:严格匹配指定技术栈版本,完成 Docker、gRPC、FastAPI、PostgreSQL、Redis 等配置,实现服务间基础连通 配套文件:生成 Makefile、环境变量模板、数据库 / 脚本初始化文件及启动验证文档 架构定位:仅搭建基础架构骨架,无任何业务逻辑、业务规则及业务相关字段,为后续业务开发提供支撑
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
import grpc
|
||||
from concurrent import futures
|
||||
from app.grpc_generated import user_pb2, user_pb2_grpc
|
||||
from app.db.models import User
|
||||
from app.db.session import AsyncSessionLocal
|
||||
from sqlalchemy import select
|
||||
from datetime import datetime
|
||||
|
||||
class UserService(user_pb2_grpc.UserServiceServicer):
|
||||
async def GetUser(self, request, context):
|
||||
async with AsyncSessionLocal() as session:
|
||||
result = await session.execute(select(User).where(User.id == request.id))
|
||||
user = result.scalar_one_or_none()
|
||||
if not user:
|
||||
context.set_code(grpc.StatusCode.NOT_FOUND)
|
||||
context.set_details("User not found")
|
||||
return user_pb2.UserResponse()
|
||||
|
||||
return user_pb2.UserResponse(
|
||||
user=user_pb2.User(
|
||||
id=user.id,
|
||||
username=user.username,
|
||||
password_hash=user.password_hash,
|
||||
created_at=user.created_at.isoformat(),
|
||||
updated_at=user.updated_at.isoformat()
|
||||
)
|
||||
)
|
||||
|
||||
async def CreateUser(self, request, context):
|
||||
async with AsyncSessionLocal() as session:
|
||||
user = User(
|
||||
username=request.username,
|
||||
password_hash=request.password_hash
|
||||
)
|
||||
session.add(user)
|
||||
await session.commit()
|
||||
await session.refresh(user)
|
||||
|
||||
return user_pb2.UserResponse(
|
||||
user=user_pb2.User(
|
||||
id=user.id,
|
||||
username=user.username,
|
||||
password_hash=user.password_hash,
|
||||
created_at=user.created_at.isoformat(),
|
||||
updated_at=user.updated_at.isoformat()
|
||||
)
|
||||
)
|
||||
|
||||
async def UpdateUser(self, request, context):
|
||||
async with AsyncSessionLocal() as session:
|
||||
result = await session.execute(select(User).where(User.id == request.id))
|
||||
user = result.scalar_one_or_none()
|
||||
if not user:
|
||||
context.set_code(grpc.StatusCode.NOT_FOUND)
|
||||
context.set_details("User not found")
|
||||
return user_pb2.UserResponse()
|
||||
|
||||
user.username = request.username
|
||||
user.password_hash = request.password_hash
|
||||
await session.commit()
|
||||
await session.refresh(user)
|
||||
|
||||
return user_pb2.UserResponse(
|
||||
user=user_pb2.User(
|
||||
id=user.id,
|
||||
username=user.username,
|
||||
password_hash=user.password_hash,
|
||||
created_at=user.created_at.isoformat(),
|
||||
updated_at=user.updated_at.isoformat()
|
||||
)
|
||||
)
|
||||
|
||||
async def DeleteUser(self, request, context):
|
||||
async with AsyncSessionLocal() as session:
|
||||
result = await session.execute(select(User).where(User.id == request.id))
|
||||
user = result.scalar_one_or_none()
|
||||
if not user:
|
||||
context.set_code(grpc.StatusCode.NOT_FOUND)
|
||||
context.set_details("User not found")
|
||||
return user_pb2.EmptyResponse()
|
||||
|
||||
await session.delete(user)
|
||||
await session.commit()
|
||||
|
||||
return user_pb2.EmptyResponse()
|
||||
|
||||
async def ListUsers(self, request, context):
|
||||
async with AsyncSessionLocal() as session:
|
||||
offset = (request.page - 1) * request.page_size
|
||||
result = await session.execute(
|
||||
select(User).offset(offset).limit(request.page_size)
|
||||
)
|
||||
users = result.scalars().all()
|
||||
|
||||
total_result = await session.execute(select(User))
|
||||
total = len(total_result.scalars().all())
|
||||
|
||||
user_list = [
|
||||
user_pb2.User(
|
||||
id=user.id,
|
||||
username=user.username,
|
||||
password_hash=user.password_hash,
|
||||
created_at=user.created_at.isoformat(),
|
||||
updated_at=user.updated_at.isoformat()
|
||||
)
|
||||
for user in users
|
||||
]
|
||||
|
||||
return user_pb2.UsersResponse(
|
||||
users=user_list,
|
||||
total=total
|
||||
)
|
||||
Reference in New Issue
Block a user