v1.0.0
This commit is contained in:
@@ -17,24 +17,30 @@ import (
|
||||
|
||||
// FinanceHandler 财务HTTP处理器
|
||||
type FinanceHandler struct {
|
||||
appService finance.FinanceApplicationService
|
||||
responseBuilder interfaces.ResponseBuilder
|
||||
validator interfaces.RequestValidator
|
||||
logger *zap.Logger
|
||||
appService finance.FinanceApplicationService
|
||||
invoiceAppService finance.InvoiceApplicationService
|
||||
adminInvoiceAppService finance.AdminInvoiceApplicationService
|
||||
responseBuilder interfaces.ResponseBuilder
|
||||
validator interfaces.RequestValidator
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
// NewFinanceHandler 创建财务HTTP处理器
|
||||
func NewFinanceHandler(
|
||||
appService finance.FinanceApplicationService,
|
||||
invoiceAppService finance.InvoiceApplicationService,
|
||||
adminInvoiceAppService finance.AdminInvoiceApplicationService,
|
||||
responseBuilder interfaces.ResponseBuilder,
|
||||
validator interfaces.RequestValidator,
|
||||
logger *zap.Logger,
|
||||
) *FinanceHandler {
|
||||
return &FinanceHandler{
|
||||
appService: appService,
|
||||
responseBuilder: responseBuilder,
|
||||
validator: validator,
|
||||
logger: logger,
|
||||
appService: appService,
|
||||
invoiceAppService: invoiceAppService,
|
||||
adminInvoiceAppService: adminInvoiceAppService,
|
||||
responseBuilder: responseBuilder,
|
||||
validator: validator,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -554,3 +560,381 @@ func (h *FinanceHandler) GetAlipayOrderStatus(c *gin.Context) {
|
||||
|
||||
h.responseBuilder.Success(c, result, "获取订单状态成功")
|
||||
}
|
||||
|
||||
// ==================== 发票相关Handler方法 ====================
|
||||
|
||||
// ApplyInvoice 申请开票
|
||||
// @Summary 申请开票
|
||||
// @Description 用户申请开票
|
||||
// @Tags 发票管理
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param request body finance.ApplyInvoiceRequest true "申请开票请求"
|
||||
// @Success 200 {object} response.Response{data=finance.InvoiceApplicationResponse}
|
||||
// @Failure 400 {object} response.Response
|
||||
// @Failure 500 {object} response.Response
|
||||
// @Router /api/v1/invoices/apply [post]
|
||||
func (h *FinanceHandler) ApplyInvoice(c *gin.Context) {
|
||||
var req finance.ApplyInvoiceRequest
|
||||
if err := h.validator.BindAndValidate(c, &req); err != nil {
|
||||
h.responseBuilder.BadRequest(c, "请求参数错误", err)
|
||||
return
|
||||
}
|
||||
|
||||
userID := c.GetString("user_id") // 从JWT中获取用户ID
|
||||
if userID == "" {
|
||||
h.responseBuilder.Unauthorized(c, "用户未登录")
|
||||
return
|
||||
}
|
||||
|
||||
result, err := h.invoiceAppService.ApplyInvoice(c.Request.Context(), userID, req)
|
||||
if err != nil {
|
||||
h.responseBuilder.InternalError(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
h.responseBuilder.Success(c, result, "申请开票成功")
|
||||
}
|
||||
|
||||
// GetUserInvoiceInfo 获取用户发票信息
|
||||
// @Summary 获取用户发票信息
|
||||
// @Description 获取用户的发票信息
|
||||
// @Tags 发票管理
|
||||
// @Produce json
|
||||
// @Success 200 {object} response.Response{data=finance.InvoiceInfoResponse}
|
||||
// @Failure 400 {object} response.Response
|
||||
// @Failure 500 {object} response.Response
|
||||
// @Router /api/v1/invoices/info [get]
|
||||
func (h *FinanceHandler) GetUserInvoiceInfo(c *gin.Context) {
|
||||
userID := c.GetString("user_id")
|
||||
if userID == "" {
|
||||
h.responseBuilder.Unauthorized(c, "用户未登录")
|
||||
return
|
||||
}
|
||||
|
||||
result, err := h.invoiceAppService.GetUserInvoiceInfo(c.Request.Context(), userID)
|
||||
if err != nil {
|
||||
h.responseBuilder.InternalError(c, "获取发票信息失败")
|
||||
return
|
||||
}
|
||||
|
||||
h.responseBuilder.Success(c, result, "获取发票信息成功")
|
||||
}
|
||||
|
||||
// UpdateUserInvoiceInfo 更新用户发票信息
|
||||
// @Summary 更新用户发票信息
|
||||
// @Description 更新用户的发票信息
|
||||
// @Tags 发票管理
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param request body finance.UpdateInvoiceInfoRequest true "更新发票信息请求"
|
||||
// @Success 200 {object} response.Response
|
||||
// @Failure 400 {object} response.Response
|
||||
// @Failure 500 {object} response.Response
|
||||
// @Router /api/v1/invoices/info [put]
|
||||
func (h *FinanceHandler) UpdateUserInvoiceInfo(c *gin.Context) {
|
||||
var req finance.UpdateInvoiceInfoRequest
|
||||
if err := h.validator.BindAndValidate(c, &req); err != nil {
|
||||
h.responseBuilder.BadRequest(c, "请求参数错误", err)
|
||||
return
|
||||
}
|
||||
|
||||
userID := c.GetString("user_id")
|
||||
if userID == "" {
|
||||
h.responseBuilder.Unauthorized(c, "用户未登录")
|
||||
return
|
||||
}
|
||||
|
||||
err := h.invoiceAppService.UpdateUserInvoiceInfo(c.Request.Context(), userID, req)
|
||||
if err != nil {
|
||||
h.responseBuilder.InternalError(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
h.responseBuilder.Success(c, nil, "更新发票信息成功")
|
||||
}
|
||||
|
||||
// GetUserInvoiceRecords 获取用户开票记录
|
||||
// @Summary 获取用户开票记录
|
||||
// @Description 获取用户的开票记录列表
|
||||
// @Tags 发票管理
|
||||
// @Produce json
|
||||
// @Param page query int false "页码" default(1)
|
||||
// @Param page_size query int false "每页数量" default(10)
|
||||
// @Param status query string false "状态筛选"
|
||||
// @Success 200 {object} response.Response{data=finance.InvoiceRecordsResponse}
|
||||
// @Failure 400 {object} response.Response
|
||||
// @Failure 500 {object} response.Response
|
||||
// @Router /api/v1/invoices/records [get]
|
||||
func (h *FinanceHandler) GetUserInvoiceRecords(c *gin.Context) {
|
||||
userID := c.GetString("user_id")
|
||||
if userID == "" {
|
||||
h.responseBuilder.Unauthorized(c, "用户未登录")
|
||||
return
|
||||
}
|
||||
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "10"))
|
||||
status := c.Query("status")
|
||||
startTime := c.Query("start_time")
|
||||
endTime := c.Query("end_time")
|
||||
|
||||
req := finance.GetInvoiceRecordsRequest{
|
||||
Page: page,
|
||||
PageSize: pageSize,
|
||||
Status: status,
|
||||
StartTime: startTime,
|
||||
EndTime: endTime,
|
||||
}
|
||||
|
||||
result, err := h.invoiceAppService.GetUserInvoiceRecords(c.Request.Context(), userID, req)
|
||||
if err != nil {
|
||||
h.responseBuilder.InternalError(c, "获取开票记录失败")
|
||||
return
|
||||
}
|
||||
|
||||
h.responseBuilder.Success(c, result, "获取开票记录成功")
|
||||
}
|
||||
|
||||
// DownloadInvoiceFile 下载发票文件
|
||||
// @Summary 下载发票文件
|
||||
// @Description 下载指定发票的文件
|
||||
// @Tags 发票管理
|
||||
// @Produce application/octet-stream
|
||||
// @Param application_id path string true "申请ID"
|
||||
// @Success 200 {file} file
|
||||
// @Failure 400 {object} response.Response
|
||||
// @Failure 500 {object} response.Response
|
||||
// @Router /api/v1/invoices/{application_id}/download [get]
|
||||
func (h *FinanceHandler) DownloadInvoiceFile(c *gin.Context) {
|
||||
userID := c.GetString("user_id")
|
||||
if userID == "" {
|
||||
h.responseBuilder.Unauthorized(c, "用户未登录")
|
||||
return
|
||||
}
|
||||
|
||||
applicationID := c.Param("application_id")
|
||||
if applicationID == "" {
|
||||
h.responseBuilder.BadRequest(c, "申请ID不能为空")
|
||||
return
|
||||
}
|
||||
|
||||
result, err := h.invoiceAppService.DownloadInvoiceFile(c.Request.Context(), userID, applicationID)
|
||||
if err != nil {
|
||||
h.responseBuilder.InternalError(c, "下载发票文件失败")
|
||||
return
|
||||
}
|
||||
|
||||
// 设置响应头
|
||||
c.Header("Content-Type", "application/pdf")
|
||||
c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", result.FileName))
|
||||
c.Header("Content-Length", fmt.Sprintf("%d", len(result.FileContent)))
|
||||
|
||||
// 直接返回文件内容
|
||||
c.Data(http.StatusOK, "application/pdf", result.FileContent)
|
||||
}
|
||||
|
||||
// GetAvailableAmount 获取可开票金额
|
||||
// @Summary 获取可开票金额
|
||||
// @Description 获取用户当前可开票的金额
|
||||
// @Tags 发票管理
|
||||
// @Produce json
|
||||
// @Success 200 {object} response.Response{data=finance.AvailableAmountResponse}
|
||||
// @Failure 400 {object} response.Response
|
||||
// @Failure 500 {object} response.Response
|
||||
// @Router /api/v1/invoices/available-amount [get]
|
||||
func (h *FinanceHandler) GetAvailableAmount(c *gin.Context) {
|
||||
userID := c.GetString("user_id")
|
||||
if userID == "" {
|
||||
h.responseBuilder.Unauthorized(c, "用户未登录")
|
||||
return
|
||||
}
|
||||
|
||||
result, err := h.invoiceAppService.GetAvailableAmount(c.Request.Context(), userID)
|
||||
if err != nil {
|
||||
h.responseBuilder.InternalError(c, "获取可开票金额失败")
|
||||
return
|
||||
}
|
||||
|
||||
h.responseBuilder.Success(c, result, "获取可开票金额成功")
|
||||
}
|
||||
|
||||
// ==================== 管理员发票相关Handler方法 ====================
|
||||
|
||||
// GetPendingApplications 获取发票申请列表(支持筛选)
|
||||
// @Summary 获取发票申请列表
|
||||
// @Description 管理员获取发票申请列表,支持状态和时间范围筛选
|
||||
// @Tags 管理员-发票管理
|
||||
// @Produce json
|
||||
// @Param page query int false "页码" default(1)
|
||||
// @Param page_size query int false "每页数量" default(10)
|
||||
// @Param status query string false "状态筛选:pending/completed/rejected"
|
||||
// @Param start_time query string false "开始时间 (格式: 2006-01-02 15:04:05)"
|
||||
// @Param end_time query string false "结束时间 (格式: 2006-01-02 15:04:05)"
|
||||
// @Success 200 {object} response.Response{data=finance.PendingApplicationsResponse}
|
||||
// @Failure 400 {object} response.Response
|
||||
// @Failure 500 {object} response.Response
|
||||
// @Router /api/v1/admin/invoices/pending [get]
|
||||
func (h *FinanceHandler) GetPendingApplications(c *gin.Context) {
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "10"))
|
||||
status := c.Query("status")
|
||||
startTime := c.Query("start_time")
|
||||
endTime := c.Query("end_time")
|
||||
|
||||
req := finance.GetPendingApplicationsRequest{
|
||||
Page: page,
|
||||
PageSize: pageSize,
|
||||
Status: status,
|
||||
StartTime: startTime,
|
||||
EndTime: endTime,
|
||||
}
|
||||
|
||||
result, err := h.adminInvoiceAppService.GetPendingApplications(c.Request.Context(), req)
|
||||
if err != nil {
|
||||
h.responseBuilder.InternalError(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
h.responseBuilder.Success(c, result, "获取发票申请列表成功")
|
||||
}
|
||||
|
||||
// ApproveInvoiceApplication 通过发票申请(上传发票)
|
||||
// @Summary 通过发票申请
|
||||
// @Description 管理员通过发票申请并上传发票文件
|
||||
// @Tags 管理员-发票管理
|
||||
// @Accept multipart/form-data
|
||||
// @Produce json
|
||||
// @Param application_id path string true "申请ID"
|
||||
// @Param file formData file true "发票文件"
|
||||
// @Param admin_notes formData string false "管理员备注"
|
||||
// @Success 200 {object} response.Response
|
||||
// @Failure 400 {object} response.Response
|
||||
// @Failure 500 {object} response.Response
|
||||
// @Router /api/v1/admin/invoices/{application_id}/approve [post]
|
||||
func (h *FinanceHandler) ApproveInvoiceApplication(c *gin.Context) {
|
||||
applicationID := c.Param("application_id")
|
||||
if applicationID == "" {
|
||||
h.responseBuilder.BadRequest(c, "申请ID不能为空")
|
||||
return
|
||||
}
|
||||
|
||||
// 获取上传的文件
|
||||
file, err := c.FormFile("file")
|
||||
if err != nil {
|
||||
h.responseBuilder.BadRequest(c, "请选择要上传的发票文件")
|
||||
return
|
||||
}
|
||||
|
||||
// 打开文件
|
||||
fileHandle, err := file.Open()
|
||||
if err != nil {
|
||||
h.responseBuilder.InternalError(c, "文件打开失败")
|
||||
return
|
||||
}
|
||||
defer fileHandle.Close()
|
||||
|
||||
// 获取管理员备注
|
||||
adminNotes := c.PostForm("admin_notes")
|
||||
|
||||
req := finance.ApproveInvoiceRequest{
|
||||
AdminNotes: adminNotes,
|
||||
}
|
||||
|
||||
err = h.adminInvoiceAppService.ApproveInvoiceApplication(c.Request.Context(), applicationID, fileHandle, req)
|
||||
if err != nil {
|
||||
h.responseBuilder.InternalError(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
|
||||
h.responseBuilder.Success(c, nil, "通过发票申请成功")
|
||||
}
|
||||
|
||||
// RejectInvoiceApplication 拒绝发票申请
|
||||
// @Summary 拒绝发票申请
|
||||
// @Description 管理员拒绝发票申请
|
||||
// @Tags 管理员-发票管理
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param application_id path string true "申请ID"
|
||||
// @Param request body finance.RejectInvoiceRequest true "拒绝申请请求"
|
||||
// @Success 200 {object} response.Response
|
||||
// @Failure 400 {object} response.Response
|
||||
// @Failure 500 {object} response.Response
|
||||
// @Router /api/v1/admin/invoices/{application_id}/reject [post]
|
||||
func (h *FinanceHandler) RejectInvoiceApplication(c *gin.Context) {
|
||||
applicationID := c.Param("application_id")
|
||||
if applicationID == "" {
|
||||
h.responseBuilder.BadRequest(c, "申请ID不能为空")
|
||||
return
|
||||
}
|
||||
|
||||
var req finance.RejectInvoiceRequest
|
||||
if err := h.validator.BindAndValidate(c, &req); err != nil {
|
||||
h.responseBuilder.BadRequest(c, "请求参数错误", err)
|
||||
return
|
||||
}
|
||||
|
||||
err := h.adminInvoiceAppService.RejectInvoiceApplication(c.Request.Context(), applicationID, req)
|
||||
if err != nil {
|
||||
h.responseBuilder.InternalError(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
h.responseBuilder.Success(c, nil, "拒绝发票申请成功")
|
||||
}
|
||||
|
||||
// AdminDownloadInvoiceFile 管理员下载发票文件
|
||||
// @Summary 管理员下载发票文件
|
||||
// @Description 管理员下载指定发票的文件
|
||||
// @Tags 管理员-发票管理
|
||||
// @Produce application/octet-stream
|
||||
// @Param application_id path string true "申请ID"
|
||||
// @Success 200 {file} file
|
||||
// @Failure 400 {object} response.Response
|
||||
// @Failure 500 {object} response.Response
|
||||
// @Router /api/v1/admin/invoices/{application_id}/download [get]
|
||||
func (h *FinanceHandler) AdminDownloadInvoiceFile(c *gin.Context) {
|
||||
applicationID := c.Param("application_id")
|
||||
if applicationID == "" {
|
||||
h.responseBuilder.BadRequest(c, "申请ID不能为空")
|
||||
return
|
||||
}
|
||||
|
||||
result, err := h.adminInvoiceAppService.DownloadInvoiceFile(c.Request.Context(), applicationID)
|
||||
if err != nil {
|
||||
h.responseBuilder.InternalError(c, "下载发票文件失败")
|
||||
return
|
||||
}
|
||||
|
||||
// 设置响应头
|
||||
c.Header("Content-Type", "application/pdf")
|
||||
c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", result.FileName))
|
||||
c.Header("Content-Length", fmt.Sprintf("%d", len(result.FileContent)))
|
||||
|
||||
// 直接返回文件内容
|
||||
c.Data(http.StatusOK, "application/pdf", result.FileContent)
|
||||
}
|
||||
|
||||
// DebugEventSystem 调试事件系统状态
|
||||
// @Summary 调试事件系统状态
|
||||
// @Description 获取事件系统的调试信息
|
||||
// @Tags 调试
|
||||
// @Produce json
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /api/v1/debug/events [get]
|
||||
func (h *FinanceHandler) DebugEventSystem(c *gin.Context) {
|
||||
h.logger.Info("🔍 请求事件系统调试信息")
|
||||
|
||||
// 这里可以添加事件系统的状态信息
|
||||
// 暂时返回基本信息
|
||||
debugInfo := map[string]interface{}{
|
||||
"timestamp": time.Now().Format("2006-01-02 15:04:05"),
|
||||
"message": "事件系统调试端点已启用",
|
||||
"handler": "FinanceHandler",
|
||||
}
|
||||
|
||||
h.responseBuilder.Success(c, debugInfo, "事件系统调试信息")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user