feat(distribution): 分站发布群只使用自己的二维码池

主站单独维护分站码池,池空时不再借用主站或其他分站,并去掉已停用的固定二维码入口。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
yml2213
2026-10-04 18:35:34 +08:00
co-authored by Cursor
parent 951d428364
commit 1d21b3f548
11 changed files with 1123 additions and 250 deletions
@@ -258,3 +258,168 @@ func (h *Handler) DeleteQrCodeHandler(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": "删除成功"})
}
func (h *Handler) siteIDParam(c *gin.Context) (uint64, bool) {
siteID, err := strconv.ParseUint(c.Param("id"), 10, 64)
if err != nil || siteID == 0 {
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的分站"})
return 0, false
}
return siteID, true
}
func writeSiteQrCodeError(c *gin.Context, err error) bool {
switch {
case errors.Is(err, ErrQrCodeSiteNotFound):
c.JSON(http.StatusNotFound, gin.H{"error": "分销站点不存在"})
case errors.Is(err, ErrQrCodeNotFound):
c.JSON(http.StatusNotFound, gin.H{"error": "二维码不存在"})
case errors.Is(err, ErrQrCodeCannotReenable):
c.JSON(http.StatusBadRequest, gin.H{"error": "已发放的二维码不能改回待用"})
default:
if err != nil && err.Error() == "无效的状态值" {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return true
}
return false
}
return true
}
func (h *Handler) ListSiteQrCodesHandler(c *gin.Context) {
siteID, ok := h.siteIDParam(c)
if !ok {
return
}
var req QrCodeListRequest
if err := c.ShouldBindQuery(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
qrcodes, total, err := h.service.repo.ListSiteQrCodes(c.Request.Context(), siteID, req)
if err != nil {
if writeSiteQrCodeError(c, err) {
return
}
response.RecordError(c, err)
response.InternalServerError(c, "聊天二维码服务暂时不可用")
return
}
c.JSON(http.StatusOK, gin.H{
"data": PaginatedResult{
Items: qrcodes,
Total: total,
Page: req.Page,
PageSize: req.Limit,
},
})
}
func (h *Handler) GetSiteQrCodeStatsHandler(c *gin.Context) {
siteID, ok := h.siteIDParam(c)
if !ok {
return
}
stats, err := h.service.repo.GetSiteQrCodeStats(c.Request.Context(), siteID)
if err != nil {
if writeSiteQrCodeError(c, err) {
return
}
response.RecordError(c, err)
response.InternalServerError(c, "聊天二维码服务暂时不可用")
return
}
c.JSON(http.StatusOK, gin.H{"data": stats})
}
func (h *Handler) BatchCreateSiteQrCodeHandler(c *gin.Context) {
siteID, ok := h.siteIDParam(c)
if !ok {
return
}
var req BatchCreateQrCodeRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
adminID := c.GetUint64("admin_id")
qrcodes, err := h.service.repo.BatchCreateSiteQrCode(c.Request.Context(), adminID, siteID, req)
if err != nil {
if writeSiteQrCodeError(c, err) {
return
}
response.RecordError(c, err)
response.InternalServerError(c, "聊天二维码服务暂时不可用")
return
}
c.JSON(http.StatusOK, gin.H{"data": qrcodes})
}
func (h *Handler) UpdateSiteQrCodeHandler(c *gin.Context) {
siteID, ok := h.siteIDParam(c)
if !ok {
return
}
id, err := strconv.ParseUint(c.Param("qrcodeId"), 10, 64)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的ID"})
return
}
var req UpdateQrCodeRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if err := h.service.repo.UpdateSiteQrCode(c.Request.Context(), siteID, id, req); err != nil {
if writeSiteQrCodeError(c, err) {
return
}
response.RecordError(c, err)
response.InternalServerError(c, "聊天二维码服务暂时不可用")
return
}
c.JSON(http.StatusOK, gin.H{"message": "更新成功"})
}
func (h *Handler) DeleteSiteQrCodeHandler(c *gin.Context) {
siteID, ok := h.siteIDParam(c)
if !ok {
return
}
id, err := strconv.ParseUint(c.Param("qrcodeId"), 10, 64)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的ID"})
return
}
if err := h.service.repo.DeleteSiteQrCode(c.Request.Context(), siteID, id); err != nil {
if writeSiteQrCodeError(c, err) {
return
}
response.RecordError(c, err)
response.InternalServerError(c, "聊天二维码服务暂时不可用")
return
}
c.JSON(http.StatusOK, gin.H{"message": "删除成功"})
}
func (h *Handler) BatchDeleteSiteQrCodeHandler(c *gin.Context) {
siteID, ok := h.siteIDParam(c)
if !ok {
return
}
var req BatchDeleteQrCodeRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
deleted, err := h.service.repo.BatchDeleteSiteQrCodes(c.Request.Context(), siteID, req.IDs)
if err != nil {
if writeSiteQrCodeError(c, err) {
return
}
response.RecordError(c, err)
response.InternalServerError(c, "聊天二维码服务暂时不可用")
return
}
c.JSON(http.StatusOK, gin.H{"data": gin.H{"deleted": deleted}})
}