async def get_geocode(*, city: str, address: str, response: Response) -> Any: """ 根据名称获取具体位置信息 \n city: 城市名称 \n address: 具体地址 """ params = {"city": city, "address": address, "key": settings.GAODEMAP_KEY} base = "https://restapi.amap.com/v3/geocode/geo?output=JSON" try: response = requests.get(base, params, timeout=2) if response.status_code == 200: res = response.json() geocodes = res.get("geocodes") if not geocodes: message = "没有查找到具体位置信息" response.status_code = status.HTTP_404_NOT_FOUND return response_code.resp_error(message=message) else: geocode = geocodes[0] except (ReadTimeout, ConnectTimeout): message = "根据名称获取具体位置信息失败" response.status_code = status.HTTP_500_INTERNAL_SERVER_ERROR logger.error(message) return response_code.resp_error(message=message) finally: message = "获取具体位置信息成功" response.status_code = status.HTTP_200_OK return response_code.resp_ok(data={"geocode": geocode}, message=message)
async def get_weather(*, city: str, response: Response) -> Any: """ 根据城市名称获取具体位置信息\n city: 城市名称(包括 省、市、区、县) """ params = {"city": city, "key": settings.GAODEMAP_KEY} base = "https://restapi.amap.com/v3/weather/weatherInfo?output=JSON" try: response = requests.get(base, params, timeout=2) if response.status_code == 200: res = response.json() lives = res.get("lives") if not lives: message = "没有查找到具体天气信息" response.status_code = status.HTTP_404_NOT_FOUND return response_code.resp_error(message) else: weather = lives[0] except (ReadTimeout, ConnectTimeout): message = "查询天气信息失败" response.status_code = status.HTTP_500_INTERNAL_SERVER_ERROR logger.error(message) return response_code.resp_error(message) finally: message = "查询天气信息成功" response.status_code = status.HTTP_200_OK return response_code.resp_ok(data={"weather": weather}, message=message)
async def set_follow( *, follow_in: schema_follow.FollowUpdateIn, decode_token: Optional[dict] = Depends(deps.check_jwt_token), request: Request, response: Response, db: Session = Depends(deps.get_db)) -> Any: """ 关注/取消关注(用户)\n token: 用户 token \n follow_userid: 被关注的用户 id \n status: 状态 0: 关注,1: 取消关注 \n return: 状态码, 关注id, 提示信息 """ follow, message = service_follow.set_follow(db, request, response, decode_token=decode_token, obj_in=follow_in) if not follow: return response_code.resp_error(message=message) return response_code.resp_ok(data={ "followid": follow.id, }, message=message)
async def get_messages( *, filter_spec: str = '[{"field": "id", "option": "==", "value": ""}]', sort_spec: str = '[{"field": "id", "direction": "desc"}]', paginate: str = '{"page_number": 1, "page_size": 10}', response: Response, db: Session = Depends(deps.get_db)) -> Any: """ 查询所有留言信息 \n filter_spec: 过滤查询的条件(field: 字段名称, option: 查找方式,value: 查找值)\n sort_spec: 排序(field: 字段名,direction: 排序方式) \n paginate: 分页(page_number: 当前页数,page_size: 每页显示的条数) \n return: 状态码, 留言信息列表, 总记录数, 总页数, 提示信息 """ message_boards, total, number_page, message = service_message.get_messages( db, response, filter_spec=filter_spec, paginate=paginate, sort_spec=sort_spec) if not message_boards: return response_code.resp_error(message=message) return response_code.resp_ok(data={ "message_boards": message_boards, "total": total, "number_page": number_page }, message=message)
async def set_collect( *, collect_in: schema_collect.CollectUpdateIn, decode_token: Optional[dict] = Depends(deps.check_jwt_token), request: Request, response: Response, db: Session = Depends(deps.get_db)) -> Any: """ 收藏/取消收藏(主贴)\n token: 用户 token \n topicid: 主贴 id \n status: 状态 0: 收藏,1: 取消收藏 \n return: 状态码, 收藏id, 提示信息 """ collect, message = service_collect.set_collect(db, request, response, decode_token=decode_token, obj_in=collect_in) if not collect: return response_code.resp_error(message=message) return response_code.resp_ok(data={ "collectid": collect.id, }, message=message)
async def create( *, reply_in: schema_reply.ReplyCreateIn, decode_token: Optional[dict] = Depends(deps.check_jwt_token), request: Request, response: Response, db: Session = Depends(deps.get_db)) -> Any: """ 创建回帖信息 \n token: 用户 token \n topicid: 主贴 id \n parent_comment_userid: 父级回帖的 userid(评论)\n reply_comment_id: 回复的回帖 id(回复)\n content: 回帖内容 \n file_path: 文件路径(图片、视频、文件等)\n return: 状态码, 回帖id, 提示信息 """ reply, message = service_reply.create(db, request, response, decode_token=decode_token, obj_in=reply_in) if not reply: return response_code.resp_error(message=message) return response_code.resp_ok(data={"replyid": reply.id}, message=message)
async def get_assistant(*, city: str, keywords: str, location: str, response: Response) -> Any: """ 根据名称查找所有相关的信息 \n city: 查询城市。可选值:城市中文、中文全拼 \n keywords: 查询关键词 \n location: 经度, 纬度 """ params = { "city": city, "keywords": keywords, "location": location, "key": settings.GAODEMAP_KEY } base = "https://restapi.amap.com/v3/assistant/inputtips?output=JSON&datatype=all" try: response = requests.get(base, params, timeout=2) if response.status_code == 200: res = response.json() assistant = res.get("tips") except (ReadTimeout, ConnectTimeout): message = "根据名称查找所有相关的信息失败" response.status_code = status.HTTP_500_INTERNAL_SERVER_ERROR logger.error(message) return response_code.resp_error(message=message) finally: message = "查找所有相关的信息成功" response.status_code = status.HTTP_200_OK return response_code.resp_ok(data={"assistant": assistant}, message=message)
async def add_job_to_scheduler(*, seconds: int = Body(120, title="循环间隔时间/秒,默认120s", embed=True), job_id: str = Body(..., title="任务id", embed=True), response: Response): # ------------------------------------------------------------------------- # 简易的任务调度演示 可自行参考文档 https://apscheduler.readthedocs.io/en/stable/ # 三种模式 # date: 当您想在某个时间点仅运行一次作业时使用 # interval: 当您要以固定的时间间隔运行作业时使用 # cron: 当您想在一天中的特定时间定期运行作业时使用 # ------------------------------------------------------------------------- res = schedule.get_job(job_id=job_id) if res: response.status_code = status.HTTP_400_BAD_REQUEST return response_code.resp_error(message=f"{job_id} 工作已经存在") schedule_job = schedule.add_job( demo_task, # 执行方法 'interval', # 方法的参数 args=(job_id, ), # 执行模式 seconds=seconds, # 循环间隔时间 秒 id=job_id, # job ID next_run_time=datetime.now() # 立即执行 ) response.status_code = status.HTTP_200_OK return response_code.resp_ok(data={"id": schedule_job.id})
async def remove_schedule(*, job_id: str = Body(..., title="job_id", embed=True), response: Response): res = schedule.get_job(job_id=job_id) if not res: response.status_code = status.HTTP_404_NOT_FOUND return response_code.resp_error(message=f"找不到工作 {job_id}") schedule.remove_job(job_id) response.status_code = status.HTTP_200_OK return response_code.resp_200()
async def all_exception_handler(request: Request): """ 全局所有异常 :param request: :param exc: :return: """ logger.error( f"全局异常\n{request.method}URL:{request.url}\nHeaders:{request.headers}\n{traceback.format_exc()}" ) return response_code.resp_error()
async def request_validation_exception_handler( request: Request, exc: RequestValidationError): """ 请求参数验证异常 :param request: :param exc: :return: """ logger.error( f"请求参数格式错误\nURL:{request.method}{request.url}\nHeaders:{request.headers}\n{traceback.format_exc()}" ) return response_code.resp_error(message=exc.errors())
async def signout( *, response: Response, decode_token: Optional[dict] = Depends(deps.check_jwt_token), ) -> Any: """ 退出登录 \n return: 状态码, 用户id, 提示信息 """ userid, message = service_user.signout(response, decode_token=decode_token) if not userid: return response_code.resp_error(message=message) return response_code.resp_ok(data={"userid": userid}, message=message)
async def get_like_by_id( *, id: int = Query(...), response: Response, db: Session = Depends(deps.get_db)) -> Any: """ 通过 点赞id 查询点赞信息 \n id: 点赞id \n return: 状态码, 点赞信息, 提示信息 """ like, message = service_like.get_like_by_id(db, response, id=id) if not like: return response_code.resp_error(message=message) return response_code.resp_ok(data={"like": like}, message=message)
async def get_section_by_id( *, id: int = Query(...), response: Response, db: Session = Depends(deps.get_db)) -> Any: """ 通过 板块id 查询板块信息 \n id: id 板块id \n return: 状态码, 板块信息, 提示信息 """ section, message = service_section.get_section_by_id(db, response, id=id) if not section: return response_code.resp_error(message=message) return response_code.resp_ok(data={"section": section}, message=message)
async def get_topic_by_id( *, id: int = Query(...), response: Response, db: Session = Depends(deps.get_db)) -> Any: """ 通过 主贴id 查询主贴信息 \n id: 主贴id \n return: 状态码, 主贴信息, 提示信息 """ topic, message = service_topic.get_topic_by_id(db, response, id=id) if not topic: return response_code.resp_error(message=message) return response_code.resp_ok(data={"topic": topic}, message=message)
async def delete( *, id: int = Query(...), response: Response, db: Session = Depends(deps.get_db)) -> Any: """ 通过 主贴id 删除主贴信息(删除 主贴 及所有关联的 评论/回复 信息) \n id: 主贴 id \n return: 状态码, 主贴id, 提示信息 """ topic, message = service_topic.delete(db, response, id=id) if not topic: return response_code.resp_error(message=message) return response_code.resp_ok(data={"topicid": topic.id}, message=message)
async def delete( *, id: int = Query(...), response: Response, db: Session = Depends(deps.get_db)) -> Any: """ 通过 回帖id 删除回帖信息(删除 评论/回复 及所有关联的 回复 信息) \n id: 回帖 id \n return: 状态码, 回帖id, 提示信息 """ reply, message = service_reply.delete(db, response, id=id) if not reply: return response_code.resp_error(message=message) return response_code.resp_ok(data={"replyid": reply.id}, message=message)
async def get_reply_by_id( *, id: int = Query(...), response: Response, db: Session = Depends(deps.get_db)) -> Any: """ 通过 回帖id 查询回帖信息 \n id: id 回帖id \n return: 状态码, 回帖信息, 提示信息 """ reply, message = service_reply.get_reply_by_id(db, response, id=id) if not reply: return response_code.resp_error(message=message) return response_code.resp_ok(data={"reply": reply}, message=message)
async def logoff( *, decode_token: Optional[dict] = Depends(deps.check_jwt_token), response: Response, db: Session = Depends(deps.get_db) ) -> Any: """ 用户注销 \n return: 状态码, 用户id, 提示信息 """ user, message = service_user.logoff(db, response, decode_token=decode_token) if not user: return response_code.resp_error(message=message) return response_code.resp_ok(data={"userid": user.id}, message=message)
async def delete( *, id: int = Query(...), response: Response, db: Session = Depends(deps.get_db)) -> Any: """ 通过 收藏id 删除收藏信息 \n id: 收藏 id \n return: 状态码, 提示信息 """ result, message = service_collect.delete(db, response, id=id) if not result: return response_code.resp_error(message=message) return response_code.resp_ok(message=message)
async def get_verify_code( *, response: Response, account: Optional[str] = Query(...)) -> Optional[str]: """ 获取 手机/邮箱 验证码 \n account: 手机/邮箱 \n return: 状态码, 提示信息 """ random_code = "".join(random.sample(string.digits, k=6)) # 自动生成6位随机数(手机/邮箱验证码) code = None if re.match(RE_PHONE, account): # 手机号 phone_code, message = verify_code.get_phone_code( phone=account, phone_code=random_code) if phone_code: code = phone_code redis_client.set( account, phone_code, ex=settings.PHONE_CODE_EXPIRE_SECONDS) # 存储手机验证码于 redis 中 elif re.match(RE_EMAIL, account): # 邮箱 email_code, message = verify_code.get_email_code( email=account, email_code=random_code) if email_code: code = email_code redis_client.set( account, email_code, ex=settings.EMAIL_CODE_EXPIRE_SECONDS) # 存储邮箱验证码于 redis 中 else: message = "账号信息格式不正确" response.status_code = status.HTTP_422_UNPROCESSABLE_ENTITY logger.error(message) return response_code.resp_error(message=message) if not code: response.status_code = status.HTTP_500_INTERNAL_SERVER_ERROR return response_code.resp_error(message=message) response.status_code = status.HTTP_200_OK return response_code.resp_ok(message=message)
async def delete_file( *, id: int = Query(...), response: Response, db: Session = Depends(deps.get_db) ) -> Any: """ 通过 文件id 删除文件信息 \n id: 文件 id \n return: 状态码, 文件id, 提示信息 """ file, message = service_file.delete_file(db, response, id=id) if not file: return response_code.resp_error(message=message) return response_code.resp_ok(data={"fileid": file.id}, message=message)
async def get_file_by_id( *, id: int = Query(...), response: Response, db: Session = Depends(deps.get_db) ) -> Any: """ 通过 文件id 查询文件信息 \n id: 文件 id \n return: 状态码, 文件信息, 提示信息 """ file, message = service_file.get_file_by_id(db, response, id=id) if not file: return response_code.resp_error(message=message) return response_code.resp_ok(data={"file": file}, message=message)
async def delete( *, id: int = Query(...), response: Response, db: Session = Depends(deps.get_db)) -> Any: """ 通过 板块id 删除板块信息(删除 板块 及所有关联的 主贴 和 评论/回复 信息) \n id: 板块 id \n return: 状态码, 板块id, 提示信息 """ section, message = service_section.delete(db, response, id=id) if not section: return response_code.resp_error(message=message) return response_code.resp_ok(data={"sectionid": section.id}, message=message)
async def get_user_by_account( *, account: str, response: Response, db: Session = Depends(deps.get_db) ) -> Any: """ 通过 账号(手机号/邮箱/用户名) 查询用户信息 \n account: 手机号/邮箱/用户名 \n return: 状态码, 用户信息, 提示信息 """ user, message = service_user.get_user_by_account(db, response, account=account) if not user: return response_code.resp_error(message=message) return response_code.resp_ok(data={"user": user}, message=message)
async def delete( *, id: int = Query(...), response: Response, db: Session = Depends(deps.get_db)) -> Any: """ 通过 留言id 删除留言 \n id: 留言 id \n return: 状态码, 留言id, 提示信息 """ message_board, message = service_message.delete(db, response, id=id) if not message_board: return response_code.resp_error(message=message) return response_code.resp_ok(data={"message_boardid": message_board.id}, message=message)
async def get_user_by_id( *, id: int, response: Response, db: Session = Depends(deps.get_db) ) -> Any: """ 通过 用户id 查询用户信息 \n id: 用户id \n return: 状态码, 用户信息, 提示信息 """ user, message = service_user.get_user_by_id(db, response, id=id) if not user: return response_code.resp_error(message=message) return response_code.resp_ok(data={"user": user}, message=message)
async def get_collect_by_id( *, id: int = Query(...), response: Response, db: Session = Depends(deps.get_db)) -> Any: """ 通过 收藏id 查询收藏信息 \n id: 收藏id \n return: 状态码, 收藏信息, 提示信息 """ collect, message = service_collect.get_collect_by_id(db, response, id=id) if not collect: return response_code.resp_error(message=message) return response_code.resp_ok(data={ "collect": collect, }, message=message)
async def upload_avatar( *, file: UploadFile = File(...), decode_token: Optional[dict] = Depends(deps.check_jwt_token), response: Response, db: Session = Depends(deps.get_db) ) -> Any: """ 上传/更新 头像 \n file: 上传的文件 \n return: 状态码, 用户id, 头像地址, 提示信息 """ user, avatar_url, message = service_user.upload_avatar(db, response, decode_token=decode_token, file=file) if not avatar_url: return response_code.resp_error(message=message) return response_code.resp_ok(data={"userid": user.id, "avatar_url": avatar_url}, message=message)
async def get_follow_by_id( *, id: int = Query(...), response: Response, db: Session = Depends(deps.get_db)) -> Any: """ 通过 关注id 查询关注信息 \n id: id 关注id \n return: 状态码, 关注信息, 提示信息 """ follow, message = service_follow.get_follow_by_id(db, response, id=id) if not follow: return response_code.resp_error(message=message) return response_code.resp_ok(data={ "follow": follow, }, message=message)