From e07532a188c1b14c2ae054b369b6799b58543dc6 Mon Sep 17 00:00:00 2001 From: yml2213 Date: Thu, 16 Jul 2026 19:52:40 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E6=91=B8=E5=A4=A7=E7=BA=A2?= =?UTF-8?q?=E6=94=AF=E4=BB=98=E5=90=8E=E5=BB=BA=E7=BE=A4=E9=80=BB=E8=BE=91?= =?UTF-8?q?=EF=BC=8C=E4=BB=85=E4=BF=9D=E7=95=99=E6=89=AB=E7=A0=81=E4=B8=8E?= =?UTF-8?q?=E5=A4=8D=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 支付成功只固化客服二维码与订单文案;同步清理迁移、配置与前后端相关字段。 --- backend/internal/model/chat.go | 1 - backend/internal/model/mohong.go | 1 - backend/internal/modules/mohong/config.go | 18 +-- backend/internal/modules/mohong/dto.go | 3 - backend/internal/modules/mohong/order_repo.go | 104 +----------------- backend/internal/modules/mohong/presenter.go | 1 - backend/internal/modules/mohong/repository.go | 12 +- backend/internal/router/router.go | 2 +- backend/migrations/000028_mohong.sql | 14 +-- .../000029_mohong_categories_and_seed.sql | 2 - .../admin/views/AdminMohongConfigView.vue | 7 +- .../admin/views/AdminMohongOrdersView.vue | 3 - frontend/src/features/mohong/api/mohong.ts | 2 - .../views/MobileMohongOrderDetailView.vue | 17 --- .../mohong/views/MohongDetailView.vue | 4 +- .../features/mohong/views/MohongListView.vue | 2 +- .../mohong/views/MohongOrderDetailView.vue | 15 --- 17 files changed, 16 insertions(+), 192 deletions(-) diff --git a/backend/internal/model/chat.go b/backend/internal/model/chat.go index d4b5a71..d4ca2f1 100644 --- a/backend/internal/model/chat.go +++ b/backend/internal/model/chat.go @@ -10,7 +10,6 @@ type ChatConversation struct { ID uint64 `gorm:"primaryKey" json:"id"` OrderID *uint64 `gorm:"uniqueIndex" json:"order_id"` ListingID *uint64 `gorm:"index" json:"listing_id"` - MohongOrderID *uint64 `gorm:"column:mohong_order_id;uniqueIndex" json:"mohong_order_id"` Type string `gorm:"size:32;not null;default:'order_group'" json:"type"` Title string `gorm:"size:128;not null" json:"title"` Status string `gorm:"size:32;not null;default:'active'" json:"status"` diff --git a/backend/internal/model/mohong.go b/backend/internal/model/mohong.go index f498d00..d14762f 100644 --- a/backend/internal/model/mohong.go +++ b/backend/internal/model/mohong.go @@ -68,7 +68,6 @@ type MohongOrder struct { ProductSnapshot datatypes.JSON `gorm:"column:product_snapshot" json:"product_snapshot"` QrcodeURLSnapshot string `gorm:"column:qrcode_url_snapshot;size:512;not null;default:''" json:"qrcode_url_snapshot"` CopyText string `gorm:"type:text;not null" json:"copy_text"` - ConversationID *uint64 `gorm:"column:conversation_id" json:"conversation_id"` PaidAt *time.Time `json:"paid_at"` CompletedAt *time.Time `json:"completed_at"` CancelledAt *time.Time `json:"cancelled_at"` diff --git a/backend/internal/modules/mohong/config.go b/backend/internal/modules/mohong/config.go index 84d89c7..436939b 100644 --- a/backend/internal/modules/mohong/config.go +++ b/backend/internal/modules/mohong/config.go @@ -12,10 +12,8 @@ import ( const ( configKeyDefaultQrcodeURL = "mohong.default_qrcode_url" - configKeyGroupWelcomeText = "mohong.group_welcome_text" configKeyOrderCopyTemplate = "mohong.order_copy_template" - defaultGroupWelcomeText = "订单已支付,请扫码联系客服,并将下方订单信息复制发送给客服。" defaultOrderCopyTemplate = "【摸大红订单】\n订单号:{{order_no}}\n下单时间:{{created_at}}\n商品:{{product_title}}\n数量:{{quantity}}\n金额:{{amount}}\n下单人:{{buyer_name}}({{buyer_phone}})" ) @@ -23,7 +21,7 @@ func (r *Repository) GetConfig(ctx context.Context) (*ConfigDTO, error) { if r.db == nil { return nil, ErrDependencyUnavailable } - keys := []string{configKeyDefaultQrcodeURL, configKeyGroupWelcomeText, configKeyOrderCopyTemplate} + keys := []string{configKeyDefaultQrcodeURL, configKeyOrderCopyTemplate} var rows []model.SystemConfig if err := r.db.WithContext(ctx).Where("`key` IN ?", keys).Find(&rows).Error; err != nil { return nil, err @@ -34,7 +32,6 @@ func (r *Repository) GetConfig(ctx context.Context) (*ConfigDTO, error) { } return &ConfigDTO{ DefaultQrcodeURL: strings.TrimSpace(values[configKeyDefaultQrcodeURL]), - GroupWelcomeText: firstNonEmpty(values[configKeyGroupWelcomeText], defaultGroupWelcomeText), OrderCopyTemplate: firstNonEmpty(values[configKeyOrderCopyTemplate], defaultOrderCopyTemplate), }, nil } @@ -49,11 +46,6 @@ func (r *Repository) UpdateConfig(ctx context.Context, req UpdateConfigRequest) return err } } - if req.GroupWelcomeText != nil { - if err := upsertConfig(tx, configKeyGroupWelcomeText, strings.TrimSpace(*req.GroupWelcomeText), "摸大红订单群欢迎语"); err != nil { - return err - } - } if req.OrderCopyTemplate != nil { if err := upsertConfig(tx, configKeyOrderCopyTemplate, strings.TrimSpace(*req.OrderCopyTemplate), "摸大红订单一键复制文案模板"); err != nil { return err @@ -100,14 +92,6 @@ func (r *Repository) resolveQrcodeURL(tx *gorm.DB, productQrcode string) string return "" } -func (r *Repository) loadWelcomeText(tx *gorm.DB) string { - var cfg model.SystemConfig - if err := tx.Where("`key` = ?", configKeyGroupWelcomeText).First(&cfg).Error; err == nil && strings.TrimSpace(cfg.Value) != "" { - return strings.TrimSpace(cfg.Value) - } - return defaultGroupWelcomeText -} - func (r *Repository) loadCopyTemplate(tx *gorm.DB) string { var cfg model.SystemConfig if err := tx.Where("`key` = ?", configKeyOrderCopyTemplate).First(&cfg).Error; err == nil && strings.TrimSpace(cfg.Value) != "" { diff --git a/backend/internal/modules/mohong/dto.go b/backend/internal/modules/mohong/dto.go index d108763..e05e9ae 100644 --- a/backend/internal/modules/mohong/dto.go +++ b/backend/internal/modules/mohong/dto.go @@ -108,7 +108,6 @@ type OrderDTO struct { ProductUnit string `json:"product_unit"` QrcodeURLSnapshot string `json:"qrcode_url_snapshot"` CopyText string `json:"copy_text"` - ConversationID *uint64 `json:"conversation_id"` BuyerNickname string `json:"buyer_nickname,omitempty"` BuyerPhone string `json:"buyer_phone,omitempty"` AdminRemark string `json:"admin_remark,omitempty"` @@ -138,13 +137,11 @@ type AdminCancelOrderRequest struct { type ConfigDTO struct { DefaultQrcodeURL string `json:"default_qrcode_url"` - GroupWelcomeText string `json:"group_welcome_text"` OrderCopyTemplate string `json:"order_copy_template"` } type UpdateConfigRequest struct { DefaultQrcodeURL *string `json:"default_qrcode_url"` - GroupWelcomeText *string `json:"group_welcome_text"` OrderCopyTemplate *string `json:"order_copy_template"` } diff --git a/backend/internal/modules/mohong/order_repo.go b/backend/internal/modules/mohong/order_repo.go index afd54b7..4666d9e 100644 --- a/backend/internal/modules/mohong/order_repo.go +++ b/backend/internal/modules/mohong/order_repo.go @@ -10,9 +10,7 @@ import ( "time" "hfb_sys/backend/internal/model" - "hfb_sys/backend/internal/modules/chat" "hfb_sys/backend/internal/modules/notification" - "hfb_sys/backend/internal/modules/supportgroup" "hfb_sys/backend/internal/timeutil" "hfb_sys/backend/pkg/money" @@ -21,8 +19,6 @@ import ( "gorm.io/gorm/clause" ) -const ConversationTypeMohongOrder = "mohong_order" - func (r *Repository) CreateOrder(ctx context.Context, userID uint64, req CreateOrderRequest) (*OrderDTO, error) { if userID == 0 || req.ProductID == 0 || req.Quantity < 1 || req.Quantity > 99 { return nil, ErrInvalidRequest @@ -257,7 +253,8 @@ func (r *Repository) AdminCompleteOrder(ctx context.Context, orderID uint64, rem return r.AdminFindOrder(ctx, orderID) } -// ConfirmPaidFromChannelTx 支付成功后推进摸大红订单:建群、发固定码、写复制文案。 +// ConfirmPaidFromChannelTx 支付成功后推进摸大红订单:固化二维码快照与可复制文案。 +// 返回值固定为 0,兼容支付模块会话通知签名(摸大红无订单群)。 func (r *Repository) ConfirmPaidFromChannelTx(tx *gorm.DB, orderID uint64) (uint64, error) { var order model.MohongOrder if err := tx.Clauses(clause.Locking{Strength: "UPDATE"}).First(&order, orderID).Error; err != nil { @@ -265,9 +262,6 @@ func (r *Repository) ConfirmPaidFromChannelTx(tx *gorm.DB, orderID uint64) (uint } if order.Status == model.MohongOrderStatusPaid || order.Status == model.MohongOrderStatusCompleted { - if order.ConversationID != nil { - return *order.ConversationID, nil - } return 0, nil } if order.Status != model.MohongOrderStatusPendingPayment { @@ -283,34 +277,10 @@ func (r *Repository) ConfirmPaidFromChannelTx(tx *gorm.DB, orderID uint64) (uint copyText := buildCopyText(r.loadCopyTemplate(tx), order, snap, user) now := time.Now() - conv, err := ensureMohongOrderConversation(tx, order, user) - if err != nil { - return 0, err - } - welcome := r.loadWelcomeText(tx) - if err := chat.SendSystemMessageForTx(tx, conv.ID, welcome); err != nil { - return 0, err - } - if qrcodeURL != "" { - if err := chat.SendImageMessageForTx(tx, conv.ID, "👇 请扫码联系客服", qrcodeURL); err != nil { - return 0, err - } - } else { - if err := chat.SendSystemMessageForTx(tx, conv.ID, "固定二维码尚未配置,请将下方订单信息复制后联系客服。"); err != nil { - return 0, err - } - } - if copyText != "" { - if err := chat.SendSystemMessageForTx(tx, conv.ID, copyText+"\n\n(长按/复制后发送给客服)"); err != nil { - return 0, err - } - } - order.Status = model.MohongOrderStatusPaid order.PaidAt = &now order.QrcodeURLSnapshot = qrcodeURL order.CopyText = copyText - order.ConversationID = &conv.ID if err := tx.Save(&order).Error; err != nil { return 0, err } @@ -320,20 +290,17 @@ func (r *Repository) ConfirmPaidFromChannelTx(tx *gorm.DB, orderID uint64) (uint UserID: order.UserID, Type: "order", Title: "摸大红订单支付成功", - Content: "支付已完成,请在群内查看二维码与订单信息。", + Content: "支付已完成,请在订单详情扫码联系客服,并复制订单信息发送。", BizType: "mohong_order", BizID: &orderIDCopy, }); err != nil { return 0, err } - return conv.ID, nil + return 0, nil } -func (r *Repository) NotifyNewConversation(conversationID uint64) { - if conversationID > 0 && r.chatNotifier != nil { - r.chatNotifier.NotifyNewConversation(conversationID) - } -} +// NotifyNewConversation 兼容支付模块接口;摸大红不创建会话,空实现。 +func (r *Repository) NotifyNewConversation(conversationID uint64) {} func (r *Repository) cancelPendingOrderTx(tx *gorm.DB, order *model.MohongOrder, reason string) error { // 归还预扣库存 @@ -367,65 +334,6 @@ func (r *Repository) orderDTO(ctx context.Context, row model.MohongOrder, includ return &dto, nil } -func ensureMohongOrderConversation(tx *gorm.DB, order model.MohongOrder, user model.User) (*model.ChatConversation, error) { - var existing model.ChatConversation - err := tx.Where("mohong_order_id = ?", order.ID).First(&existing).Error - if err == nil { - return &existing, nil - } - if err != gorm.ErrRecordNotFound { - return nil, err - } - - now := time.Now() - title := "摸大红 " + order.OrderNo - if name := strings.TrimSpace(user.Nickname); name != "" { - title = "摸大红-" + name - } - conversation := model.ChatConversation{ - MohongOrderID: &order.ID, - Type: ConversationTypeMohongOrder, - Title: title, - Status: "active", - } - if err := tx.Create(&conversation).Error; err != nil { - return nil, err - } - - participants := []model.ChatParticipant{ - { - ConversationID: conversation.ID, - ParticipantType: "user", - ParticipantID: order.UserID, - Role: "buyer", - JoinedAt: now, - LastReadAt: &now, - }, - } - supportID, err := supportgroup.PickSupportAdmin(tx, supportgroup.GroupCodeRenterHandoff) - if err != nil { - return nil, err - } - if supportID <= 0 { - supportID = chat.DefaultSupportAdminID(tx) - } - if supportID > 0 { - participants = append(participants, model.ChatParticipant{ - ConversationID: conversation.ID, - ParticipantType: "admin", - ParticipantID: supportID, - Role: "support", - JoinedAt: now, - }) - } - for _, p := range participants { - if err := tx.Clauses(clause.OnConflict{DoNothing: true}).Create(&p).Error; err != nil { - return nil, err - } - } - return &conversation, nil -} - func buildCopyText(template string, order model.MohongOrder, snap productSnapshot, user model.User) string { if strings.TrimSpace(template) == "" { template = defaultOrderCopyTemplate diff --git a/backend/internal/modules/mohong/presenter.go b/backend/internal/modules/mohong/presenter.go index 85c40d4..52c716c 100644 --- a/backend/internal/modules/mohong/presenter.go +++ b/backend/internal/modules/mohong/presenter.go @@ -59,7 +59,6 @@ func toOrderDTO(row model.MohongOrder, snap productSnapshot, buyerNickname, buye ProductUnit: snap.Unit, QrcodeURLSnapshot: row.QrcodeURLSnapshot, CopyText: row.CopyText, - ConversationID: row.ConversationID, CancelReason: row.CancelReason, PaidAt: row.PaidAt, CompletedAt: row.CompletedAt, diff --git a/backend/internal/modules/mohong/repository.go b/backend/internal/modules/mohong/repository.go index 18803f9..d2b495a 100644 --- a/backend/internal/modules/mohong/repository.go +++ b/backend/internal/modules/mohong/repository.go @@ -2,18 +2,12 @@ package mohong import "gorm.io/gorm" -// ChatNotifier 会话创建后的异步通知接口。 -type ChatNotifier interface { - NotifyNewConversation(conversationID uint64) -} - // Repository 摸大红数据访问。 type Repository struct { - db *gorm.DB - chatNotifier ChatNotifier + db *gorm.DB } // NewRepository 创建仓库。 -func NewRepository(db *gorm.DB, chatNotifier ChatNotifier) *Repository { - return &Repository{db: db, chatNotifier: chatNotifier} +func NewRepository(db *gorm.DB) *Repository { + return &Repository{db: db} } diff --git a/backend/internal/router/router.go b/backend/internal/router/router.go index f194501..6f8f722 100644 --- a/backend/internal/router/router.go +++ b/backend/internal/router/router.go @@ -259,7 +259,7 @@ func New(cfg config.Config, deps Dependencies, logger *zap.Logger) *gin.Engine { var mohongService *mohong.Service var mohongHandler *mohong.Handler if deps.DB != nil { - mohongRepo = mohong.NewRepository(deps.DB, chatRepo) + mohongRepo = mohong.NewRepository(deps.DB) mohongService = mohong.NewService(mohongRepo) mohongHandler = mohong.NewHandler(mohongService) } diff --git a/backend/migrations/000028_mohong.sql b/backend/migrations/000028_mohong.sql index 1a4fc81..2e696fe 100644 --- a/backend/migrations/000028_mohong.sql +++ b/backend/migrations/000028_mohong.sql @@ -21,7 +21,7 @@ CREATE TABLE IF NOT EXISTS mohong_products ( KEY idx_mohong_products_status_sort (status, sort_order, id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='摸大红商品'; --- 摸大红订单表 +-- 摸大红订单表(支付后展示固定二维码 + 可复制文案,不建群) CREATE TABLE IF NOT EXISTS mohong_orders ( id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, order_no VARCHAR(64) NOT NULL COMMENT '订单号', @@ -34,7 +34,6 @@ CREATE TABLE IF NOT EXISTS mohong_orders ( product_snapshot JSON NULL COMMENT '商品快照', qrcode_url_snapshot VARCHAR(512) NOT NULL DEFAULT '' COMMENT '支付时解析的二维码快照', copy_text TEXT NOT NULL COMMENT '可复制订单文案', - conversation_id BIGINT UNSIGNED NULL COMMENT '订单群会话ID', paid_at DATETIME NULL COMMENT '支付时间', completed_at DATETIME NULL COMMENT '完成时间', cancelled_at DATETIME NULL COMMENT '取消时间', @@ -48,15 +47,9 @@ CREATE TABLE IF NOT EXISTS mohong_orders ( KEY idx_mohong_orders_status_created (status, created_at) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='摸大红订单'; --- 会话表增加摸大红订单关联 -ALTER TABLE chat_conversations - ADD COLUMN mohong_order_id BIGINT UNSIGNED NULL COMMENT '摸大红订单ID' AFTER listing_id, - ADD UNIQUE KEY uk_chat_conversations_mohong_order_id (mohong_order_id); - -- 业务配置 INSERT INTO system_configs (`key`, `value`, description) VALUES ('mohong.default_qrcode_url', '', '摸大红全局默认固定二维码图片URL'), -('mohong.group_welcome_text', '订单已支付,请扫码联系客服,并将下方订单信息复制发送给客服。', '摸大红订单群欢迎语'), ('mohong.order_copy_template', '【摸大红订单】\n订单号:{{order_no}}\n下单时间:{{created_at}}\n商品:{{product_title}}\n数量:{{quantity}}\n金额:{{amount}}\n下单人:{{buyer_name}}({{buyer_phone}})', '摸大红订单一键复制文案模板') ON DUPLICATE KEY UPDATE description = VALUES(description); @@ -111,14 +104,9 @@ DELETE FROM permissions WHERE code IN ( DELETE FROM system_configs WHERE `key` IN ( 'mohong.default_qrcode_url', - 'mohong.group_welcome_text', 'mohong.order_copy_template' ); -ALTER TABLE chat_conversations - DROP INDEX uk_chat_conversations_mohong_order_id, - DROP COLUMN mohong_order_id; - DROP TABLE IF EXISTS mohong_orders; DROP TABLE IF EXISTS mohong_products; diff --git a/backend/migrations/000029_mohong_categories_and_seed.sql b/backend/migrations/000029_mohong_categories_and_seed.sql index 9e88e67..5dc0f08 100644 --- a/backend/migrations/000029_mohong_categories_and_seed.sql +++ b/backend/migrations/000029_mohong_categories_and_seed.sql @@ -2399,12 +2399,10 @@ WHERE p.title = '1亿哈弗币'; -- +goose StatementEnd -- +goose Down --- +goose StatementBegin -- 种子数据不回滚;仅移除关联表与权限(category_id 列保留) DROP TABLE IF EXISTS mohong_product_categories; DELETE rp FROM role_permissions rp JOIN permissions p ON p.id = rp.permission_id WHERE p.code = 'mohong:category'; DELETE FROM permissions WHERE code = 'mohong:category'; --- +goose StatementEnd diff --git a/frontend/src/features/admin/views/AdminMohongConfigView.vue b/frontend/src/features/admin/views/AdminMohongConfigView.vue index 8bda22a..c3adcbc 100644 --- a/frontend/src/features/admin/views/AdminMohongConfigView.vue +++ b/frontend/src/features/admin/views/AdminMohongConfigView.vue @@ -14,7 +14,6 @@ const loading = ref(false) const saving = ref(false) const form = reactive({ default_qrcode_url: '', - group_welcome_text: '', order_copy_template: '', }) @@ -37,7 +36,6 @@ async function handleSave() { try { const config = await updateAdminMohongConfig({ default_qrcode_url: form.default_qrcode_url, - group_welcome_text: form.group_welcome_text, order_copy_template: form.order_copy_template, }) Object.assign(form, config) @@ -66,7 +64,7 @@ async function uploadQrcode(file: File) {

摸大红配置

-

全局默认固定二维码、群欢迎语、订单复制模板。商品可覆盖默认二维码。

+

全局默认固定二维码与订单复制模板。商品可覆盖默认二维码;支付后用户在订单详情扫码并复制信息联系客服。

保存配置
@@ -88,9 +86,6 @@ async function uploadQrcode(file: File) { - - -
diff --git a/frontend/src/features/admin/views/AdminMohongOrdersView.vue b/frontend/src/features/admin/views/AdminMohongOrdersView.vue index afd8cf5..42e1042 100644 --- a/frontend/src/features/admin/views/AdminMohongOrdersView.vue +++ b/frontend/src/features/admin/views/AdminMohongOrdersView.vue @@ -174,9 +174,6 @@ async function copyText(text: string) { {{ detail.buyer_nickname }} {{ detail.buyer_phone }} - - {{ detail.conversation_id || '-' }} -
diff --git a/frontend/src/features/mohong/api/mohong.ts b/frontend/src/features/mohong/api/mohong.ts index ce97403..f2e13f0 100644 --- a/frontend/src/features/mohong/api/mohong.ts +++ b/frontend/src/features/mohong/api/mohong.ts @@ -50,7 +50,6 @@ export interface MohongOrder { product_unit: string qrcode_url_snapshot: string copy_text: string - conversation_id?: number | null buyer_nickname?: string buyer_phone?: string admin_remark?: string @@ -64,7 +63,6 @@ export interface MohongOrder { export interface MohongConfig { default_qrcode_url: string - group_welcome_text: string order_copy_template: string } diff --git a/frontend/src/features/mohong/views/MobileMohongOrderDetailView.vue b/frontend/src/features/mohong/views/MobileMohongOrderDetailView.vue index 3abae55..1850e96 100644 --- a/frontend/src/features/mohong/views/MobileMohongOrderDetailView.vue +++ b/frontend/src/features/mohong/views/MobileMohongOrderDetailView.vue @@ -102,13 +102,6 @@ async function copyText() { } } -function openChat() { - if (!order.value?.conversation_id) { - showToast({ message: '群聊尚未创建', icon: 'warning-o' }) - return - } - router.push(`/chats/${order.value.conversation_id}`) -}