controller.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. from typing import Annotated, Any, Optional, Dict
  2. from fastapi import APIRouter, Body, Depends, Path, Query
  3. from fastapi.responses import JSONResponse
  4. from app.api.v1.module_system.auth.schema import AuthSchema
  5. from app.common.response import ResponseSchema, SuccessResponse
  6. from app.core.dependencies import AuthPermission
  7. from app.core.logger import log
  8. from app.core.router_class import OperationLogRoute
  9. from app.core.base_params import PaginationQueryParam
  10. from .schema import (
  11. AccountAuthorizeApplySchema,
  12. AccountAuthorizeApplyOutSchema,
  13. AccountCreateSchema,
  14. AccountDepositSchema,
  15. AccountDepositOutSchema,
  16. AccountOperationOutSchema,
  17. AccountQuerySchema,
  18. AccountTransferSchema,
  19. TransferListOutSchema,
  20. TransferOutSchema,
  21. TransferTaskOutSchema,
  22. ConsumeDetailOutSchema,
  23. )
  24. from .service import AccountService
  25. AccountRouter = APIRouter(
  26. route_class=OperationLogRoute,
  27. prefix="/account",
  28. tags=["资金专户"],
  29. )
  30. @AccountRouter.post(
  31. "/authorize/apply",
  32. summary="申请转账授权签约",
  33. description="申请转账授权签约",
  34. response_model=ResponseSchema[AccountAuthorizeApplyOutSchema],
  35. )
  36. async def authorize_apply_controller(
  37. data: AccountAuthorizeApplySchema,
  38. auth: Annotated[AuthSchema, Depends(AuthPermission(["module_payment:account:authorize"]))],
  39. ) -> JSONResponse:
  40. """申请转账授权签约"""
  41. result = await AccountService.authorize_apply_service(auth=auth, data=data)
  42. log.info(f"申请转账授权签约成功: {data.enterprise_id}")
  43. return SuccessResponse(data=result, msg="申请转账授权签约成功")
  44. @AccountRouter.post(
  45. "",
  46. summary="开通资金专户",
  47. description="开通资金专户",
  48. response_model=ResponseSchema[AccountOperationOutSchema],
  49. )
  50. async def create_account_controller(
  51. data: AccountCreateSchema,
  52. auth: Annotated[AuthSchema, Depends(AuthPermission(["module_payment:account:create"]))],
  53. ) -> JSONResponse:
  54. """开通资金专户"""
  55. result = await AccountService.create_account_service(auth=auth, data=data)
  56. log.info(f"开通资金专户成功: {data.enterprise_id}")
  57. return SuccessResponse(data=result, msg="开通资金专户成功")
  58. @AccountRouter.get(
  59. "/query/{enterprise_id}",
  60. summary="查询资金专户",
  61. description="根据企业ID查询资金专户(调用支付宝接口)",
  62. response_model=ResponseSchema[list[Any]],
  63. )
  64. async def query_account_controller(
  65. # data: AccountQuerySchema,
  66. enterprise_id: Annotated[str, Path(description="企业ID")],
  67. auth: Annotated[AuthSchema, Depends(AuthPermission(["module_payment:account:detail"]))],
  68. ) -> JSONResponse:
  69. """查询资金专户"""
  70. result = await AccountService.query_account_service(auth=auth, data=AccountQuerySchema(enterprise_id=enterprise_id))
  71. log.info(f"查询资金专户成功: {enterprise_id}")
  72. return SuccessResponse(data=result, msg="查询资金专户成功")
  73. @AccountRouter.post(
  74. "/deposit",
  75. summary="资金专户充值",
  76. description="从支付宝余额向资金专户充值",
  77. response_model=ResponseSchema[AccountDepositOutSchema],
  78. )
  79. async def deposit_controller(
  80. data: AccountDepositSchema,
  81. auth: Annotated[AuthSchema, Depends(AuthPermission(["module_payment:account:deposit"]))],
  82. ) -> JSONResponse:
  83. """资金专户充值"""
  84. result = await AccountService.deposit_service(auth=auth, data=data)
  85. log.info(f"资金专户充值发起成功: {data.enterprise_id} -> {str(data.amount)}")
  86. return SuccessResponse(data=result, msg="充值页面获取成功,请跳转完成支付")
  87. @AccountRouter.post(
  88. "/transfer",
  89. summary="资金专户转账",
  90. description="从资金专户转账到支付宝账户/银行卡/资金专户",
  91. response_model=ResponseSchema[TransferTaskOutSchema],
  92. )
  93. async def transfer_controller(
  94. data: AccountTransferSchema,
  95. auth: Annotated[AuthSchema, Depends(AuthPermission(["module_payment:account:transfer"]))],
  96. ) -> JSONResponse:
  97. """资金专户转账"""
  98. result = await AccountService.transfer_service(auth=auth, data=data)
  99. log.info(f"资金专户转账发起成功: 企业: {data.enterprise_id}, 金额: {data.amount}")
  100. return SuccessResponse(data=result, msg="转账申请已提交")
  101. # @AccountRouter.post(
  102. # "/withdraw",
  103. # summary="资金专户提现",
  104. # description="从资金专户向支付宝余额提现",
  105. # response_model=ResponseSchema[AccountOperationOutSchema],
  106. # )
  107. # async def withdraw_controller(
  108. # data: AccountWithdrawSchema,
  109. # auth: Annotated[AuthSchema, Depends(AuthPermission(["module_payment:account:withdraw"]))],
  110. # ) -> JSONResponse:
  111. # """资金专户提现"""
  112. # result = await AccountService.withdraw_service(auth=auth, data=data)
  113. # log.info(f"资金专户提现发起成功: {data.out_biz_no} -> {data.amount}")
  114. # return SuccessResponse(data=result, msg="提现申请已提交")
  115. @AccountRouter.get(
  116. "/transfer/{out_biz_no}",
  117. summary="查询转账记录详情",
  118. description="根据订单号查询转账记录",
  119. response_model=ResponseSchema[TransferOutSchema],
  120. )
  121. async def transfer_detail_controller(
  122. out_biz_no: Annotated[str, Path(description="商家侧订单号")],
  123. auth: Annotated[AuthSchema, Depends(AuthPermission(["module_payment:account:transfer:detail"]))],
  124. ) -> JSONResponse:
  125. """查询转账记录详情"""
  126. result = await AccountService.transfer_detail_service(auth=auth, out_biz_no=out_biz_no)
  127. log.info(f"查询转账记录详情成功: {out_biz_no}")
  128. return SuccessResponse(data=result, msg="查询转账记录详情成功")
  129. @AccountRouter.get(
  130. "/transfer",
  131. summary="查询转账记录列表",
  132. description="分页查询转账记录列表",
  133. response_model=ResponseSchema[TransferListOutSchema],
  134. )
  135. async def transfer_list_controller(
  136. auth: Annotated[AuthSchema, Depends(AuthPermission(["module_payment:account:transfer:list"]))],
  137. page_no: Annotated[int, Query(description="页码")] = 1,
  138. page_size: Annotated[int, Query(description="每页数量")] = 20,
  139. out_biz_no: Annotated[str | None, Query(description="订单号")] = None,
  140. status: Annotated[str | None, Query(description="状态")] = None,
  141. ) -> JSONResponse:
  142. """查询转账记录列表"""
  143. search = {}
  144. if out_biz_no:
  145. search["out_biz_no"] = out_biz_no
  146. if status:
  147. search["status"] = status
  148. result = await AccountService.transfer_list_service(
  149. auth=auth, page_no=page_no, page_size=page_size, search=search
  150. )
  151. return SuccessResponse(data=result, msg="查询转账记录列表成功")
  152. @AccountRouter.get(
  153. "/consume-detail",
  154. summary="账单详情查询",
  155. description="查询企业码账单详情,支持查询关联退款、订单、票据等信息",
  156. response_model=ResponseSchema[ConsumeDetailOutSchema],
  157. )
  158. async def consume_detail_query_controller(
  159. auth: Annotated[AuthSchema, Depends(AuthPermission(["module_payment:account:consume:detail"]))],
  160. pay_no: Annotated[str, Query(description="支付宝账单号")],
  161. enterprise_id: Annotated[str | None, Query(description="企业ID(2.0接口签约企业必填)")] = None,
  162. ant_shop_id: Annotated[str | None, Query(description="蚂蚁门店ID(商户服务商必填)")] = None,
  163. query_options: Annotated[str | None, Query(description="查询选项,多个用逗号分隔")] = None,
  164. ) -> JSONResponse:
  165. """
  166. 账单详情查询
  167. 调用: alipay.commerce.ec.consume.detail.query
  168. 用于查询企业码账单详情,支持查询关联退款、订单、票据等信息。
  169. - pay_no: 支付宝账单号(必填)
  170. - enterprise_id: 企业ID(2.0接口签约企业必填)
  171. - ant_shop_id: 蚂蚁门店ID(商户服务商必填)
  172. - query_options: 查询选项,支持 Refund/Order/Ticket,多个用逗号分隔
  173. """
  174. options_list = None
  175. if query_options:
  176. options_list = [opt.strip() for opt in query_options.split(",") if opt.strip()]
  177. result = await AccountService.consume_detail_query_service(
  178. auth=auth,
  179. pay_no=pay_no,
  180. enterprise_id=enterprise_id,
  181. ant_shop_id=ant_shop_id,
  182. query_options=options_list,
  183. )
  184. log.info(f"账单详情查询成功: {pay_no}")
  185. return SuccessResponse(data=result, msg="账单详情查询成功")
  186. # @AccountRouter.post(
  187. # "/receipt/apply",
  188. # summary="申请资金回单",
  189. # description="申请资金业务回单",
  190. # response_model=ResponseSchema[ReceiptApplyOutSchema],
  191. # )
  192. # async def receipt_apply_controller(
  193. # data: ReceiptApplySchema,
  194. # auth: Annotated[AuthSchema, Depends(AuthPermission(["module_payment:account:receipt"]))],
  195. # ) -> JSONResponse:
  196. # """申请资金回单"""
  197. # result = await AccountService.receipt_apply_service(auth=auth, data=data)
  198. # log.info(f"申请资金回单成功: {data.order_no}")
  199. # return SuccessResponse(data=result, msg="申请资金回单成功")
  200. # @AccountRouter.get(
  201. # "/receipt/{file_id}",
  202. # summary="查询资金回单",
  203. # description="查询资金业务回单状态",
  204. # response_model=ResponseSchema[ReceiptQueryOutSchema],
  205. # )
  206. # async def receipt_query_controller(
  207. # file_id: Annotated[str, Path(description="文件申请号")],
  208. # auth: Annotated[AuthSchema, Depends(AuthPermission(["module_payment:account:receipt"]))],
  209. # enterprise_id: Annotated[str, Query(description="企业ID")] = None,
  210. # ) -> JSONResponse:
  211. # """查询资金回单"""
  212. # if not enterprise_id:
  213. # enterprise_id = auth.enterprise_id or ""
  214. # result = await AccountService.receipt_query_service(
  215. # auth=auth, enterprise_id=enterprise_id, file_id=file_id
  216. # )
  217. # log.info(f"查询资金回单成功: {file_id}")
  218. # return SuccessResponse(data=result, msg="查询资金回单成功")
  219. # @AccountRouter.post(
  220. # "/transfer/batch",
  221. # summary="批量资金专户转账",
  222. # description="异步批量转账,先放入队列,后台处理",
  223. # response_model=ResponseSchema[AccountTransferBatchOutSchema],
  224. # )
  225. # async def batch_transfer_controller(
  226. # data: AccountTransferBatchSchema,
  227. # auth: Annotated[AuthSchema, Depends(AuthPermission(["module_payment:account:transfer"]))],
  228. # ) -> JSONResponse:
  229. # """批量资金专户转账(异步)"""
  230. # result = await AccountService.batch_transfer_service(auth=auth, data=data)
  231. # log.info(f"批量转账任务已提交: {result.batch_id}, 总笔数: {result.total}")
  232. # return SuccessResponse(data=result, msg="批量转账任务已提交,正在处理中")
  233. # @AccountRouter.get(
  234. # "/transfer/batch/{batch_id}",
  235. # summary="查询批量转账结果",
  236. # description="查询批量转账的处理状态和结果",
  237. # response_model=ResponseSchema[dict],
  238. # )
  239. # async def get_batch_result_controller(
  240. # batch_id: Annotated[str, Path(description="批次ID")],
  241. # auth: Annotated[AuthSchema, Depends(AuthPermission(["module_payment:account:transfer"]))],
  242. # ) -> JSONResponse:
  243. # """查询批量转账结果"""
  244. # result = await AccountService.get_batch_result_service(auth=auth, batch_id=batch_id)
  245. # log.info(f"查询批量转账结果成功: {batch_id}")
  246. # return SuccessResponse(data=result, msg="查询批量转账结果成功")