Files
junhong_cmp_fiber/internal/routes/employee_collection.go
break 4330b8a40c
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
新增设备类型选项接口
2026-09-22 12:35:26 +08:00

162 lines
9.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package routes
import (
"github.com/gofiber/fiber/v2"
"github.com/break/junhong_cmp_fiber/internal/handler/admin"
"github.com/break/junhong_cmp_fiber/internal/model/dto"
"github.com/break/junhong_cmp_fiber/pkg/constants"
"github.com/break/junhong_cmp_fiber/pkg/errors"
"github.com/break/junhong_cmp_fiber/pkg/middleware"
"github.com/break/junhong_cmp_fiber/pkg/openapi"
)
// requireEmployeeCollectionConfigAccess 限制线下收款方式字典维护仅超级管理员可用,
// 非超级管理员与其他不可见资源返回同一禁止访问错误,避免可枚举差异。
func requireEmployeeCollectionConfigAccess(handler fiber.Handler) fiber.Handler {
return func(c *fiber.Ctx) error {
if middleware.GetUserTypeFromContext(c.UserContext()) != constants.UserTypeSuperAdmin {
return errors.New(errors.CodeForbidden, "无权限操作该资源或资源不存在")
}
return handler(c)
}
}
func registerEmployeeCollectionRoutes(router fiber.Router, handler *admin.EmployeeCollectionHandler, doc *openapi.Generator, basePath string) {
// 路由前缀必须交给 GroupRegister 的 basePath 只用于生成 OpenAPI 文档,不参与路由注册,
// 否则相对路径会落到 /api/admin 根上并抢占同层后续路由。
group := router.Group("/employee-collection-payment-methods")
paymentMethodPath := basePath + "/employee-collection-payment-methods"
wrap := requireEmployeeCollectionConfigAccess
Register(group, doc, paymentMethodPath, "GET", "", handler.ListPaymentMethods, RouteSpec{
Summary: "查询线下收款方式",
Description: "超级管理员可查询全部字典项;其他后台账号仅返回启用项,用于新核销申请选择收款方式。",
Tags: []string{"员工代收款"},
Input: new(dto.EmployeeCollectionPaymentMethodListRequest),
Output: new(dto.EmployeeCollectionPaymentMethodListResponse),
Auth: true,
})
Register(group, doc, paymentMethodPath, "POST", "", wrap(handler.CreatePaymentMethod), RouteSpec{
Summary: "创建线下收款方式",
Description: "仅超级管理员。稳定编码在未删除记录中唯一。",
Tags: []string{"员工代收款"},
Input: new(dto.CreateEmployeeCollectionPaymentMethodRequest),
Output: new(dto.EmployeeCollectionPaymentMethodResponse),
Auth: true,
})
Register(group, doc, paymentMethodPath, "PUT", "/:id", wrap(handler.UpdatePaymentMethod), RouteSpec{
Summary: "更新线下收款方式",
Description: "仅超级管理员。可修改名称、排序、启停与备注;已被核销申请引用时不允许修改稳定编码。",
Tags: []string{"员工代收款"},
Input: new(dto.IDReq),
Body: new(dto.UpdateEmployeeCollectionPaymentMethodRequest),
Output: new(dto.EmployeeCollectionPaymentMethodResponse),
Auth: true,
})
Register(group, doc, paymentMethodPath, "DELETE", "/:id", wrap(handler.DeletePaymentMethod), RouteSpec{
Summary: "删除线下收款方式",
Description: "仅超级管理员。已被核销申请引用的字典项不可物理删除,只能停用。",
Tags: []string{"员工代收款"},
Input: new(dto.IDReq),
Output: nil,
Auth: true,
})
}
// registerEmployeeCollectionBillRoutes 注册员工代收款账单查询、统计与关闭路由。
// 账单可见性由应用层强制:欠款人仅见本人账单,超级管理员见全部。
func registerEmployeeCollectionBillRoutes(router fiber.Router, handler *admin.EmployeeCollectionHandler, doc *openapi.Generator, basePath string) {
group := router.Group("/employee-collection-bills")
billPath := basePath + "/employee-collection-bills"
adminOnly := requireEmployeeCollectionConfigAccess
Register(group, doc, billPath, "GET", "", handler.ListBills, RouteSpec{
Summary: "查询员工代收款账单",
Description: "欠款人仅返回本人欠款账单,超级管理员返回全部;支持账单编号(即账单记录标识)、来源、状态、" +
"欠款人姓名或账号(子串模糊)、客户名称(子串模糊)、产生时间与核销通过时间筛选与分页。" +
"产生时间参数为 `start_time`/`end_time`,核销通过时间为 `decided_start_time`/`decided_end_time`" +
"两类均为带显式时区的 RFC3339 秒级闭区间(含两端);旧参数名 `created_from`/`created_to` 与旧日期格式一律以参数非法拒绝。" +
"核销通过时间取该账单已通过分摊关联的申请表审批终态时间。" +
"响应并列返回未核销金额(应收减已核销)与剩余可核销金额(应收减已核销减审批中预占),已关闭账单两者为零。",
Tags: []string{"员工代收款"},
Input: new(dto.EmployeeCollectionBillListRequest),
Output: new(dto.EmployeeCollectionBillListResponse),
Auth: true,
})
// 统计必须先于 /:id 注册,保证路径按字面量优先匹配。
Register(group, doc, billPath, "GET", "/statistics", handler.StatisticsBills, RouteSpec{
Summary: "查询员工代收款账单统计",
Description: "与账单列表使用相同筛选条件(含核销通过时间与模糊筛选)与可见性范围," +
"返回应收、已核销、未核销金额合计与待处理账单数;不接受分页参数。",
Tags: []string{"员工代收款"},
Input: new(dto.EmployeeCollectionBillStatisticsRequest),
Output: new(dto.EmployeeCollectionBillStatisticsResponse),
Auth: true,
})
Register(group, doc, billPath, "GET", "/:id", handler.GetBill, RouteSpec{
Summary: "查询员工代收款账单详情",
Description: "返回账单、来源退款冲销、分摊、核销申请与企业微信审批历史,并返回操作日志安全投影" +
"(动作、操作账号名称、时间与前后值摘要,不含凭证内容与完整收款原文)与来源订单快照" +
"(来源单号、业务类型、来源金额、来源创建时间、资产标识;来源不可读时字段为空值且不阻断详情)。" +
"附件只返回对象键引用。无权限与不存在返回同一错误。",
Tags: []string{"员工代收款"},
Input: new(dto.IDReq),
Output: new(dto.EmployeeCollectionBillDetailResponse),
Auth: true,
})
Register(group, doc, billPath, "POST", "/:id/close", adminOnly(handler.CloseBill), RouteSpec{
Summary: "关闭员工代收款账单",
Description: "仅超级管理员。仅允许关闭待核销或部分核销且不存在审批中分摊的账单;关闭只作废未核销余额并保留已核销金额。",
Tags: []string{"员工代收款"},
Input: new(dto.IDReq),
Body: new(dto.CloseEmployeeCollectionBillRequest),
Output: new(dto.EmployeeCollectionBillResponse),
Auth: true,
})
}
// registerEmployeeCollectionApplicationRoutes 注册核销申请的创建、重提与受控查询路由。
// 可见性与代办权限由应用层强制:非超级管理员只能为本人账单操作,超级管理员代办必须填写原因。
func registerEmployeeCollectionApplicationRoutes(router fiber.Router, handler *admin.EmployeeCollectionHandler, doc *openapi.Generator, basePath string) {
group := router.Group("/employee-collection-applications")
applicationPath := basePath + "/employee-collection-applications"
Register(group, doc, applicationPath, "POST", "", handler.CreateApplication, RouteSpec{
Summary: "创建核销申请",
Description: "员工为本人可见账单创建;超级管理员可为账单欠款人代办且必须填写 acting_reason。服务端按账单可核销余额与付款金额校验分摊任一失败不保存申请与预占。",
Tags: []string{"员工代收款"},
Input: new(dto.SubmitEmployeeCollectionApplicationRequest),
Output: new(dto.EmployeeCollectionApplicationSubmitResponse),
Auth: true,
})
Register(group, doc, applicationPath, "GET", "", handler.ListApplications, RouteSpec{
Summary: "查询核销申请",
Description: "非超级管理员仅返回本人申请,超级管理员返回全部;支持状态、收款方式、申请人与创建时间筛选和分页。",
Tags: []string{"员工代收款"},
Input: new(dto.EmployeeCollectionApplicationListRequest),
Output: new(dto.EmployeeCollectionApplicationListResponse),
Auth: true,
})
Register(group, doc, applicationPath, "GET", "/:id", handler.GetApplication, RouteSpec{
Summary: "查询核销申请详情",
Description: "返回申请事实、账单分摊与全部审批尝试历史;附件只返回对象键引用。无权限与不存在返回同一错误。",
Tags: []string{"员工代收款"},
Input: new(dto.IDReq),
Output: new(dto.EmployeeCollectionApplicationDetailResponse),
Auth: true,
})
Register(group, doc, applicationPath, "PUT", "/:id", handler.ResubmitApplication, RouteSpec{
Summary: "修改并重提核销申请",
Description: "仅申请人或被代办的超级管理员,且仅已驳回申请可修改;重提新增一条审批尝试记录与新的企业微信审批实例,历史材料不被覆盖。",
Tags: []string{"员工代收款"},
Input: new(dto.IDReq),
Body: new(dto.SubmitEmployeeCollectionApplicationRequest),
Output: new(dto.EmployeeCollectionApplicationSubmitResponse),
Auth: true,
})
Register(group, doc, applicationPath, "POST", "/:id/recover-approval", handler.RecoverApplication, RouteSpec{
Summary: "恢复核销原审批", Description: "复用最新审批尝试与原审批实例,按企业微信提交事实恢复或查询确认,不创建新审批。", Tags: []string{"员工代收款"}, Input: new(dto.IDReq), Output: new(dto.EmployeeCollectionApplicationRecoveryResponse), Auth: true,
})
}