feat(distribution): 分站发布群只使用自己的二维码池
主站单独维护分站码池,池空时不再借用主站或其他分站,并去掉已停用的固定二维码入口。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -480,7 +480,7 @@ func TestBatchCreateQrCodeDeliversPendingTask(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnsureListingConversationUsesSiteFixedQrcode(t *testing.T) {
|
||||
func TestEnsureListingConversationIgnoresFixedQrAndUsesSitePool(t *testing.T) {
|
||||
db := setupQrCodeTestDB(t)
|
||||
site := model.DistributionSite{
|
||||
SiteCode: "fx_qr_fixed",
|
||||
@@ -521,26 +521,25 @@ func TestEnsureListingConversationUsesSiteFixedQrcode(t *testing.T) {
|
||||
|
||||
var message model.ChatMessage
|
||||
if err := db.Where("conversation_id = ? AND content_type = ?", conv.ID, "image").First(&message).Error; err != nil {
|
||||
t.Fatalf("未发送固定二维码: %v", err)
|
||||
t.Fatalf("未发送分站池二维码: %v", err)
|
||||
}
|
||||
if !strings.Contains(string(message.AttachmentURLS), "site-fixed.png") {
|
||||
t.Fatalf("二维码附件 = %s, want 分站固定码", message.AttachmentURLS)
|
||||
if strings.Contains(string(message.AttachmentURLS), "site-fixed.png") || !strings.Contains(string(message.AttachmentURLS), "site-pool.png") {
|
||||
t.Fatalf("二维码附件 = %s, want 分站码池而不是固定图", message.AttachmentURLS)
|
||||
}
|
||||
|
||||
var unusedCount int64
|
||||
if err := db.Model(&model.ChatQrCode{}).Where("status = ?", QrCodeStatusUnused).Count(&unusedCount).Error; err != nil {
|
||||
t.Fatalf("统计码池失败: %v", err)
|
||||
var siteQR model.ChatQrCode
|
||||
if err := db.Where("distribution_site_id = ?", siteID).First(&siteQR).Error; err != nil {
|
||||
t.Fatalf("查询分站码失败: %v", err)
|
||||
}
|
||||
if unusedCount != 2 {
|
||||
t.Fatalf("固定码仍应保留码池库存, unused = %d, want 2", unusedCount)
|
||||
if siteQR.Status != QrCodeStatusUsed {
|
||||
t.Fatalf("分站码应被消耗, status = %q", siteQR.Status)
|
||||
}
|
||||
|
||||
var taskCount int64
|
||||
if err := db.Model(&model.ChatQrCodeDeliveryTask{}).Count(&taskCount).Error; err != nil {
|
||||
t.Fatalf("统计补发任务失败: %v", err)
|
||||
var mainQR model.ChatQrCode
|
||||
if err := db.Where("distribution_site_id IS NULL").First(&mainQR).Error; err != nil {
|
||||
t.Fatalf("查询主站码失败: %v", err)
|
||||
}
|
||||
if taskCount != 0 {
|
||||
t.Fatalf("固定码场景不应创建补发任务, got %d", taskCount)
|
||||
if mainQR.Status != QrCodeStatusUnused {
|
||||
t.Fatalf("分站建群不得消耗主站码, status = %q", mainQR.Status)
|
||||
}
|
||||
|
||||
listing2 := model.RentalListing{
|
||||
@@ -555,11 +554,18 @@ func TestEnsureListingConversationUsesSiteFixedQrcode(t *testing.T) {
|
||||
}); err != nil {
|
||||
t.Fatalf("第二次建发布群失败: %v", err)
|
||||
}
|
||||
if err := db.Model(&model.ChatQrCode{}).Where("status = ?", QrCodeStatusUnused).Count(&unusedCount).Error; err != nil {
|
||||
t.Fatalf("再次统计码池失败: %v", err)
|
||||
if err := db.First(&mainQR, mainQR.ID).Error; err != nil {
|
||||
t.Fatalf("再次查询主站码失败: %v", err)
|
||||
}
|
||||
if unusedCount != 2 {
|
||||
t.Fatalf("同一分站固定码应可复用, unused = %d, want 2", unusedCount)
|
||||
if mainQR.Status != QrCodeStatusUnused {
|
||||
t.Fatalf("分站池空了仍不得借用主站码, status = %q", mainQR.Status)
|
||||
}
|
||||
var taskCount int64
|
||||
if err := db.Model(&model.ChatQrCodeDeliveryTask{}).Where("status = ?", "pending").Count(&taskCount).Error; err != nil {
|
||||
t.Fatalf("统计补发任务失败: %v", err)
|
||||
}
|
||||
if taskCount != 1 {
|
||||
t.Fatalf("分站池空时应留下补发任务, got %d", taskCount)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -621,3 +627,93 @@ func TestEnsureListingConversationSiteWithoutFixedQrUsesSitePool(t *testing.T) {
|
||||
t.Fatalf("分站上架不得消耗主站码池, status = %q", mainQR.Status)
|
||||
}
|
||||
}
|
||||
|
||||
func TestListQrCodesExcludesSitePool(t *testing.T) {
|
||||
db := setupQrCodeTestDB(t)
|
||||
repo := NewRepository(db, nil, nil)
|
||||
site := model.DistributionSite{
|
||||
SiteCode: "fx_qr_hidden",
|
||||
SiteName: "隐藏码池站",
|
||||
Domain: "hidden-qr.example.com",
|
||||
Status: "active",
|
||||
}
|
||||
if err := db.Create(&site).Error; err != nil {
|
||||
t.Fatalf("创建分销站点失败: %v", err)
|
||||
}
|
||||
siteID := site.ID
|
||||
pool := []model.ChatQrCode{
|
||||
{ImageURL: "/api/files/object?key=qrcode/main-only.png", Status: QrCodeStatusUnused, GroupName: "主站群"},
|
||||
{ImageURL: "/api/files/object?key=qrcode/site-only.png", Status: QrCodeStatusUnused, GroupName: "分站群", DistributionSiteID: &siteID},
|
||||
}
|
||||
if err := db.Create(&pool).Error; err != nil {
|
||||
t.Fatalf("创建码池失败: %v", err)
|
||||
}
|
||||
|
||||
items, total, err := repo.ListQrCodes(t.Context(), QrCodeListRequest{Page: 1, Limit: 20})
|
||||
if err != nil {
|
||||
t.Fatalf("查询主站码池失败: %v", err)
|
||||
}
|
||||
if total != 1 || len(items) != 1 || items[0].GroupName != "主站群" {
|
||||
t.Fatalf("主站码池 = %+v total %d, want 只有主站群", items, total)
|
||||
}
|
||||
|
||||
siteItems, siteTotal, err := repo.ListSiteQrCodes(t.Context(), siteID, QrCodeListRequest{Page: 1, Limit: 20})
|
||||
if err != nil {
|
||||
t.Fatalf("查询分站码池失败: %v", err)
|
||||
}
|
||||
if siteTotal != 1 || len(siteItems) != 1 || siteItems[0].GroupName != "分站群" {
|
||||
t.Fatalf("分站码池 = %+v total %d, want 只有分站群", siteItems, siteTotal)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeliverPendingUsesOwnSitePool(t *testing.T) {
|
||||
db := setupQrCodeTestDB(t)
|
||||
repo := NewRepository(db, nil, nil)
|
||||
site := model.DistributionSite{
|
||||
SiteCode: "fx_qr_pending",
|
||||
SiteName: "待补发站",
|
||||
Domain: "pending-qr.example.com",
|
||||
Status: "active",
|
||||
}
|
||||
if err := db.Create(&site).Error; err != nil {
|
||||
t.Fatalf("创建分销站点失败: %v", err)
|
||||
}
|
||||
siteID := site.ID
|
||||
conversation := model.ChatConversation{
|
||||
Type: ConversationTypeListingGroup,
|
||||
Title: "分站发布群",
|
||||
Status: "active",
|
||||
DistributionSiteID: &siteID,
|
||||
}
|
||||
if err := db.Create(&conversation).Error; err != nil {
|
||||
t.Fatalf("创建群聊失败: %v", err)
|
||||
}
|
||||
task := model.ChatQrCodeDeliveryTask{ConversationID: conversation.ID, Status: "pending"}
|
||||
if err := db.Create(&task).Error; err != nil {
|
||||
t.Fatalf("创建补发任务失败: %v", err)
|
||||
}
|
||||
mainQR := model.ChatQrCode{ImageURL: "/api/files/object?key=qrcode/main-pending.png", Status: QrCodeStatusUnused}
|
||||
if err := db.Create(&mainQR).Error; err != nil {
|
||||
t.Fatalf("创建主站码失败: %v", err)
|
||||
}
|
||||
|
||||
if _, err := repo.BatchCreateSiteQrCode(t.Context(), 1, siteID, BatchCreateQrCodeRequest{
|
||||
Items: []CreateQrCodeRequest{{ImageURL: "/api/files/object?key=qrcode/site-pending.png", GroupName: "分站补发"}},
|
||||
}); err != nil {
|
||||
t.Fatalf("补充分站码失败: %v", err)
|
||||
}
|
||||
|
||||
var savedTask model.ChatQrCodeDeliveryTask
|
||||
if err := db.First(&savedTask, task.ID).Error; err != nil {
|
||||
t.Fatalf("查询补发任务失败: %v", err)
|
||||
}
|
||||
if savedTask.Status != "sent" {
|
||||
t.Fatalf("分站补发任务状态 = %q, want sent", savedTask.Status)
|
||||
}
|
||||
if err := db.First(&mainQR, mainQR.ID).Error; err != nil {
|
||||
t.Fatalf("查询主站码失败: %v", err)
|
||||
}
|
||||
if mainQR.Status != QrCodeStatusUnused {
|
||||
t.Fatalf("补发分站群不得消耗主站码, status = %q", mainQR.Status)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user