api.go 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. package payment
  2. import (
  3. "strconv"
  4. "github.com/gin-gonic/gin"
  5. "wails-app/internal/dao"
  6. commonModel "wails-app/internal/model/common"
  7. "wails-app/internal/model/common/response"
  8. "wails-app/internal/model/vehicle/request"
  9. "wails-app/internal/modules/payment/repository"
  10. paymentService "wails-app/internal/modules/payment/service"
  11. utils "wails-app/internal/pkg"
  12. "wails-app/internal/service"
  13. )
  14. var vehicleSvc = service.ServiceGroupApp.VehicleServiceGroup.VehicleService
  15. var paymentSvc = paymentService.NewPaymentService()
  16. // ExitPreview 费用预览(只读,不修改数据库)
  17. func ExitPreview(c *gin.Context) {
  18. var req request.ExitPreviewRequest
  19. if err := c.ShouldBindJSON(&req); err != nil {
  20. response.FailWithMessage(err.Error(), c)
  21. return
  22. }
  23. resp, err := vehicleSvc.ExitPreview(req)
  24. if err != nil {
  25. response.FailWithMessage(err.Error(), c)
  26. return
  27. }
  28. response.OkWithData(resp, c)
  29. }
  30. // OperationContext 返回车辆当前应执行的进场或出场操作上下文。
  31. func OperationContext(c *gin.Context) {
  32. var req request.VehicleIdentityRequest
  33. if err := c.ShouldBindJSON(&req); err != nil {
  34. response.FailWithMessage(err.Error(), c)
  35. return
  36. }
  37. resp, err := vehicleSvc.GetOperationContext(req)
  38. if err != nil {
  39. response.FailWithMessage(err.Error(), c)
  40. return
  41. }
  42. response.OkWithData(resp, c)
  43. }
  44. // HandlePassage 统一处理人工、UHF 和摄像头触发的进出场与开闸。
  45. func HandlePassage(c *gin.Context) {
  46. var req commonModel.PassageRequest
  47. if err := c.ShouldBindJSON(&req); err != nil {
  48. response.FailWithMessage(err.Error(), c)
  49. return
  50. }
  51. req.OperatorID = utils.GetUserID(c)
  52. result, err := service.ServiceGroupApp.ParkingServiceGroup.PassageService.HandlePassage(req)
  53. if err != nil {
  54. if result != nil {
  55. response.FailWithDetailed(result, err.Error(), c)
  56. return
  57. }
  58. response.FailWithMessage(err.Error(), c)
  59. return
  60. }
  61. response.OkWithData(result, c)
  62. }
  63. // ExitConfirm 确认出场 + 支付
  64. func ExitConfirm(c *gin.Context) {
  65. var req request.ExitConfirmRequest
  66. if err := c.ShouldBindJSON(&req); err != nil {
  67. response.FailWithMessage(err.Error(), c)
  68. return
  69. }
  70. resp, err := vehicleSvc.ExitConfirm(req, utils.GetUserID(c))
  71. if err != nil {
  72. response.FailWithMessage(err.Error(), c)
  73. return
  74. }
  75. response.OkWithData(resp, c)
  76. }
  77. // ListPayments 收费记录列表
  78. func ListPayments(c *gin.Context) {
  79. var q repository.PaymentListQuery
  80. if err := c.ShouldBindQuery(&q); err != nil {
  81. response.FailWithMessage(err.Error(), c)
  82. return
  83. }
  84. list, total, err := paymentSvc.QueryPayments(q)
  85. if err != nil {
  86. response.FailWithMessage(err.Error(), c)
  87. return
  88. }
  89. response.OkWithDetailed(response.PageResult{
  90. List: list,
  91. Total: total,
  92. Page: q.Page,
  93. PageSize: q.PageSize,
  94. }, "查询成功", c)
  95. }
  96. // TodaySummary 当日收费汇总
  97. func TodaySummary(c *gin.Context) {
  98. s, err := paymentSvc.GetTodaySummary()
  99. if err != nil {
  100. response.FailWithMessage(err.Error(), c)
  101. return
  102. }
  103. response.OkWithData(s, c)
  104. }
  105. type methodStatusRequest struct {
  106. Enabled bool `json:"enabled"`
  107. }
  108. type methodOption struct {
  109. Code string `json:"code"`
  110. Name string `json:"name"`
  111. }
  112. type entryOption struct {
  113. Code string `json:"code"`
  114. Name string `json:"name"`
  115. }
  116. func ListMethods(c *gin.Context) {
  117. list, err := paymentSvc.ListMethods()
  118. if err != nil {
  119. response.FailWithMessage(err.Error(), c)
  120. return
  121. }
  122. response.OkWithData(list, c)
  123. }
  124. func ListEnabledMethods(c *gin.Context) {
  125. entryCode := c.Query("entry")
  126. if entryCode == "" {
  127. // Accept the old query name during the transition so older clients keep
  128. // working while the API now exposes the concept as a payment entry.
  129. entryCode = c.Query("scene")
  130. }
  131. list, err := paymentSvc.ListEnabledMethods(entryCode)
  132. if err != nil {
  133. response.FailWithMessage(err.Error(), c)
  134. return
  135. }
  136. response.OkWithData(list, c)
  137. }
  138. func ListMethodOptions(c *gin.Context) {
  139. list, err := paymentSvc.ListMethods()
  140. if err != nil {
  141. response.FailWithMessage(err.Error(), c)
  142. return
  143. }
  144. options := make([]methodOption, 0, len(list)+1)
  145. for _, method := range list {
  146. options = append(options, methodOption{Code: method.Code, Name: method.Name})
  147. }
  148. options = append(options, methodOption{Code: paymentService.PaymentFree, Name: "免密放行"})
  149. response.OkWithData(options, c)
  150. }
  151. func ListEntries(c *gin.Context) {
  152. list, err := paymentSvc.ListEntries()
  153. if err != nil {
  154. response.FailWithMessage(err.Error(), c)
  155. return
  156. }
  157. response.OkWithData(list, c)
  158. }
  159. func ListEnabledEntries(c *gin.Context) {
  160. list, err := paymentSvc.ListEnabledEntries()
  161. if err != nil {
  162. response.FailWithMessage(err.Error(), c)
  163. return
  164. }
  165. response.OkWithData(list, c)
  166. }
  167. func ListEntryOptions(c *gin.Context) {
  168. list, err := paymentSvc.ListEnabledEntries()
  169. if err != nil {
  170. response.FailWithMessage(err.Error(), c)
  171. return
  172. }
  173. options := make([]entryOption, 0, len(list))
  174. for _, entry := range list {
  175. options = append(options, entryOption{Code: entry.Code, Name: entry.Name})
  176. }
  177. response.OkWithData(options, c)
  178. }
  179. func CreateMethod(c *gin.Context) {
  180. var req dao.PaymentMethodConfig
  181. if err := c.ShouldBindJSON(&req); err != nil {
  182. response.FailWithMessage(err.Error(), c)
  183. return
  184. }
  185. if err := paymentSvc.CreateMethod(&req); err != nil {
  186. response.FailWithMessage(err.Error(), c)
  187. return
  188. }
  189. response.OkWithMessage("新增支付方式成功", c)
  190. }
  191. func UpdateMethod(c *gin.Context) {
  192. id, err := strconv.ParseUint(c.Param("id"), 10, 64)
  193. if err != nil || id == 0 {
  194. response.FailWithMessage("无效的支付方式ID", c)
  195. return
  196. }
  197. var req dao.PaymentMethodConfig
  198. if err := c.ShouldBindJSON(&req); err != nil {
  199. response.FailWithMessage(err.Error(), c)
  200. return
  201. }
  202. if err := paymentSvc.UpdateMethod(uint(id), &req); err != nil {
  203. response.FailWithMessage(err.Error(), c)
  204. return
  205. }
  206. response.OkWithMessage("更新支付方式成功", c)
  207. }
  208. func SetMethodStatus(c *gin.Context) {
  209. id, err := strconv.ParseUint(c.Param("id"), 10, 64)
  210. if err != nil || id == 0 {
  211. response.FailWithMessage("无效的支付方式ID", c)
  212. return
  213. }
  214. var req methodStatusRequest
  215. if err := c.ShouldBindJSON(&req); err != nil {
  216. response.FailWithMessage(err.Error(), c)
  217. return
  218. }
  219. if err := paymentSvc.SetMethodEnabled(uint(id), req.Enabled); err != nil {
  220. response.FailWithMessage(err.Error(), c)
  221. return
  222. }
  223. response.OkWithMessage("支付方式状态已更新", c)
  224. }
  225. func DeleteMethod(c *gin.Context) {
  226. id, err := strconv.ParseUint(c.Param("id"), 10, 64)
  227. if err != nil || id == 0 {
  228. response.FailWithMessage("无效的支付方式ID", c)
  229. return
  230. }
  231. if err := paymentSvc.DeleteMethod(uint(id)); err != nil {
  232. response.FailWithMessage(err.Error(), c)
  233. return
  234. }
  235. response.OkWithMessage("删除支付方式成功", c)
  236. }
  237. func CreateEntry(c *gin.Context) {
  238. var req dao.PaymentEntryConfig
  239. if err := c.ShouldBindJSON(&req); err != nil {
  240. response.FailWithMessage(err.Error(), c)
  241. return
  242. }
  243. if err := paymentSvc.CreateEntry(&req); err != nil {
  244. response.FailWithMessage(err.Error(), c)
  245. return
  246. }
  247. response.OkWithMessage("新增支付入口成功", c)
  248. }
  249. func UpdateEntry(c *gin.Context) {
  250. id, err := strconv.ParseUint(c.Param("id"), 10, 64)
  251. if err != nil || id == 0 {
  252. response.FailWithMessage("无效的支付入口ID", c)
  253. return
  254. }
  255. var req dao.PaymentEntryConfig
  256. if err := c.ShouldBindJSON(&req); err != nil {
  257. response.FailWithMessage(err.Error(), c)
  258. return
  259. }
  260. if err := paymentSvc.UpdateEntry(uint(id), &req); err != nil {
  261. response.FailWithMessage(err.Error(), c)
  262. return
  263. }
  264. response.OkWithMessage("更新支付入口成功", c)
  265. }
  266. func SetEntryStatus(c *gin.Context) {
  267. id, err := strconv.ParseUint(c.Param("id"), 10, 64)
  268. if err != nil || id == 0 {
  269. response.FailWithMessage("无效的支付入口ID", c)
  270. return
  271. }
  272. var req methodStatusRequest
  273. if err := c.ShouldBindJSON(&req); err != nil {
  274. response.FailWithMessage(err.Error(), c)
  275. return
  276. }
  277. if err := paymentSvc.SetEntryEnabled(uint(id), req.Enabled); err != nil {
  278. response.FailWithMessage(err.Error(), c)
  279. return
  280. }
  281. response.OkWithMessage("支付入口状态已更新", c)
  282. }
  283. func DeleteEntry(c *gin.Context) {
  284. id, err := strconv.ParseUint(c.Param("id"), 10, 64)
  285. if err != nil || id == 0 {
  286. response.FailWithMessage("无效的支付入口ID", c)
  287. return
  288. }
  289. if err := paymentSvc.DeleteEntry(uint(id)); err != nil {
  290. response.FailWithMessage(err.Error(), c)
  291. return
  292. }
  293. response.OkWithMessage("支付入口已删除", c)
  294. }
  295. // SetupPaymentRouter 注册支付相关路由
  296. func SetupPaymentRouter(router *gin.RouterGroup) {
  297. pg := router.Group("/payment")
  298. {
  299. pg.GET("/list", ListPayments)
  300. pg.GET("/today-summary", TodaySummary)
  301. pg.GET("/methods", ListMethods)
  302. pg.GET("/methods/enabled", ListEnabledMethods)
  303. pg.GET("/methods/options", ListMethodOptions)
  304. pg.POST("/methods", CreateMethod)
  305. pg.PUT("/methods/:id", UpdateMethod)
  306. pg.PATCH("/methods/:id/status", SetMethodStatus)
  307. pg.DELETE("/methods/:id", DeleteMethod)
  308. pg.GET("/entries", ListEntries)
  309. pg.GET("/entries/enabled", ListEnabledEntries)
  310. pg.GET("/entries/options", ListEntryOptions)
  311. pg.POST("/entries", CreateEntry)
  312. pg.PUT("/entries/:id", UpdateEntry)
  313. pg.PATCH("/entries/:id/status", SetEntryStatus)
  314. pg.DELETE("/entries/:id", DeleteEntry)
  315. }
  316. eg := router.Group("/vehicle")
  317. {
  318. eg.POST("/operation/context", OperationContext)
  319. eg.POST("/passage", HandlePassage)
  320. eg.POST("/exit/preview", ExitPreview)
  321. eg.POST("/exit/confirm", ExitConfirm)
  322. }
  323. }