diff --git a/backend/internal/model/mohong.go b/backend/internal/model/mohong.go index 5ecc3f0..5d2f6fd 100644 --- a/backend/internal/model/mohong.go +++ b/backend/internal/model/mohong.go @@ -6,7 +6,7 @@ import ( "gorm.io/datatypes" ) -// MohongCategory 摸大红商品分类。 +// MohongCategory 撞车商品分类。 type MohongCategory struct { ID uint64 `gorm:"primaryKey" json:"id"` Name string `gorm:"size:64;not null;uniqueIndex" json:"name"` @@ -31,7 +31,7 @@ func (MohongProductCategory) TableName() string { return "mohong_product_categories" } -// MohongProduct 摸大红商品。 +// MohongProduct 撞车商品。 type MohongProduct struct { ID uint64 `gorm:"primaryKey" json:"id"` CategoryID *uint64 `gorm:"column:category_id;index" json:"category_id"` // 主分类(展示用) @@ -55,7 +55,7 @@ func (MohongProduct) TableName() string { return "mohong_products" } -// MohongOrder 摸大红订单。 +// MohongOrder 撞车订单。 type MohongOrder struct { ID uint64 `gorm:"primaryKey" json:"id"` OrderNo string `gorm:"size:64;not null;uniqueIndex" json:"order_no"` diff --git a/backend/internal/modules/chat/conversation.go b/backend/internal/modules/chat/conversation.go index 98453d2..9568cd9 100644 --- a/backend/internal/modules/chat/conversation.go +++ b/backend/internal/modules/chat/conversation.go @@ -169,6 +169,22 @@ func (r *Repository) EnsureSupportConversation(ctx context.Context, userID uint6 _ = tx.Model(&existing).Update("support_scene", SupportSceneGeneral).Error } } + // 兼容旧摸大红场景码 mohong → crash + if existing.ID == 0 && scene == SupportSceneCrash { + err = tx.Table("chat_conversations AS c"). + Select("c.*"). + Joins("JOIN chat_participants AS cp ON cp.conversation_id = c.id"). + Where( + "c.type = ? AND c.support_scene = ? AND cp.participant_type = ? AND cp.participant_id = ?", + ConversationTypeGeneralSupport, SupportSceneMohong, "user", userID, + ). + Order("c.id ASC"). + Limit(1). + Find(&existing).Error + if err != nil { + return err + } + } if existing.ID > 0 { conversationID = existing.ID return nil diff --git a/backend/internal/modules/chat/dto.go b/backend/internal/modules/chat/dto.go index a1c0690..b5aa8d8 100644 --- a/backend/internal/modules/chat/dto.go +++ b/backend/internal/modules/chat/dto.go @@ -35,7 +35,7 @@ type ConversationDTO struct { // EnsureSupportRequest 创建/复用客服会话。 type EnsureSupportRequest struct { - // Scene 业务场景:general(默认)/ mohong(摸大红) + // Scene 业务场景:general(默认)/ crash(撞车,兼容旧值 mohong) Scene string `json:"scene"` } diff --git a/backend/internal/modules/chat/support_scene.go b/backend/internal/modules/chat/support_scene.go index 2f05773..c8287e7 100644 --- a/backend/internal/modules/chat/support_scene.go +++ b/backend/internal/modules/chat/support_scene.go @@ -11,18 +11,20 @@ import ( // 客服入口业务场景(与前端 POST /chats/support 的 scene 对齐)。 const ( SupportSceneGeneral = "general" - SupportSceneMohong = "mohong" + SupportSceneCrash = "crash" + // SupportSceneMohong 兼容旧 scene 值,与 crash 同一客服分组。 + SupportSceneMohong = "mohong" ) // resolveSupportScene 规范化场景并返回标题、客服分组 code、欢迎语。 // groupCode 为空时表示不走分组,使用默认客服选取逻辑。 func resolveSupportScene(raw string) (scene, title, groupCode, welcome string) { switch strings.ToLower(strings.TrimSpace(raw)) { - case SupportSceneMohong: - return SupportSceneMohong, - "摸大红客服", - supportgroup.GroupCodeMohong, - "您好,这里是摸大红客服。请直接描述问题,可将订单信息复制后发送。" + case SupportSceneCrash, SupportSceneMohong: + return SupportSceneCrash, + "撞车客服", + supportgroup.GroupCodeMohong, // 分组 code 仍为 mohong,后台可改显示名 + "您好,这里是撞车客服。请直接描述问题,可将订单信息复制后发送。" default: // 未知场景回落平台客服,避免随意 scene 绕开分配策略 return SupportSceneGeneral, diff --git a/backend/internal/modules/file/handler.go b/backend/internal/modules/file/handler.go index 831b27c..b258f66 100644 --- a/backend/internal/modules/file/handler.go +++ b/backend/internal/modules/file/handler.go @@ -70,7 +70,7 @@ func (h *Handler) writeObject(c *gin.Context, publicOnly bool) { !strings.HasPrefix(key, "avatar/") && !strings.HasPrefix(key, "payment-cert/") && !strings.HasPrefix(key, "announcement/") && - !strings.HasPrefix(key, "mohong/") { + !strings.HasPrefix(key, "mohong/") && !strings.HasPrefix(key, "crash/") { response.Error(c, http.StatusNotFound, "not_found", "文件不存在或暂不可访问") return } diff --git a/backend/internal/modules/file/service.go b/backend/internal/modules/file/service.go index 1a35798..4426ba2 100644 --- a/backend/internal/modules/file/service.go +++ b/backend/internal/modules/file/service.go @@ -106,7 +106,7 @@ func normalizeContentType(contentType string, data []byte) string { func fileURLForScene(scene string, key string) string { fileURL := "/api/files/object?key=" + url.QueryEscape(key) - if scene == "home-banner" || scene == "avatar" || scene == "payment-cert" || scene == "announcement" || scene == "mohong" { + if scene == "home-banner" || scene == "avatar" || scene == "payment-cert" || scene == "announcement" || scene == "mohong" || scene == "crash" { fileURL = "/api/public/files/object?key=" + url.QueryEscape(key) } return fileURL @@ -115,7 +115,7 @@ func fileURLForScene(scene string, key string) string { func normalizeScene(scene string) string { scene = strings.TrimSpace(strings.ToLower(scene)) switch scene { - case "listing", "handoff", "dispute", "realname", "avatar", "home-banner", "chat", "payment-cert", "announcement", "qrcode", "mohong": + case "listing", "handoff", "dispute", "realname", "avatar", "home-banner", "chat", "payment-cert", "announcement", "qrcode", "mohong", "crash": return scene default: return "misc" diff --git a/backend/internal/modules/mohong/config.go b/backend/internal/modules/mohong/config.go index e484fc6..d88f12f 100644 --- a/backend/internal/modules/mohong/config.go +++ b/backend/internal/modules/mohong/config.go @@ -14,7 +14,7 @@ const ( configKeyDefaultQrcodeURL = "mohong.default_qrcode_url" configKeyOrderCopyTemplate = "mohong.order_copy_template" - defaultOrderCopyTemplate = "【摸大红订单】\n订单号:{{order_no}}\n下单时间:{{created_at}}\n商品明细:\n{{items}}\n数量合计:{{quantity}}\n金额:{{amount}}\n下单人:{{buyer_name}}({{buyer_phone}})" + defaultOrderCopyTemplate = "【撞车订单】\n订单号:{{order_no}}\n下单时间:{{created_at}}\n商品明细:\n{{items}}\n数量合计:{{quantity}}\n金额:{{amount}}\n下单人:{{buyer_name}}({{buyer_phone}})" ) func (r *Repository) GetConfig(ctx context.Context) (*ConfigDTO, error) { @@ -42,12 +42,12 @@ func (r *Repository) UpdateConfig(ctx context.Context, req UpdateConfigRequest) } err := r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error { if req.DefaultQrcodeURL != nil { - if err := upsertConfig(tx, configKeyDefaultQrcodeURL, strings.TrimSpace(*req.DefaultQrcodeURL), "摸大红全局默认固定二维码图片URL"); err != nil { + if err := upsertConfig(tx, configKeyDefaultQrcodeURL, strings.TrimSpace(*req.DefaultQrcodeURL), "撞车全局默认固定二维码图片URL"); err != nil { return err } } if req.OrderCopyTemplate != nil { - if err := upsertConfig(tx, configKeyOrderCopyTemplate, strings.TrimSpace(*req.OrderCopyTemplate), "摸大红订单一键复制文案模板"); err != nil { + if err := upsertConfig(tx, configKeyOrderCopyTemplate, strings.TrimSpace(*req.OrderCopyTemplate), "撞车订单一键复制文案模板"); err != nil { return err } } diff --git a/backend/internal/modules/mohong/order_repo.go b/backend/internal/modules/mohong/order_repo.go index 5f71524..8dcc1ce 100644 --- a/backend/internal/modules/mohong/order_repo.go +++ b/backend/internal/modules/mohong/order_repo.go @@ -111,7 +111,7 @@ func (r *Repository) CreateOrder(ctx context.Context, userID uint64, req CreateO if err := notification.Append(tx, notification.Entry{ UserID: userID, Type: "order", - Title: "摸大红订单已创建", + Title: "撞车订单已创建", Content: "订单已创建,请在有效时间内完成支付。", BizType: "mohong_order", BizID: &orderID, @@ -311,8 +311,8 @@ func (r *Repository) AdminCompleteOrder(ctx context.Context, orderID uint64, rem return r.AdminFindOrder(ctx, orderID) } -// ConfirmPaidFromChannelTx 支付成功后推进摸大红订单:固化二维码快照与可复制文案。 -// 返回值固定为 0,兼容支付模块会话通知签名(摸大红无订单群)。 +// 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 { @@ -348,7 +348,7 @@ func (r *Repository) ConfirmPaidFromChannelTx(tx *gorm.DB, orderID uint64) (uint if err := notification.Append(tx, notification.Entry{ UserID: order.UserID, Type: "order", - Title: "摸大红订单支付成功", + Title: "撞车订单支付成功", Content: "支付已完成,请在订单详情扫码联系客服,并复制订单信息发送。", BizType: "mohong_order", BizID: &orderIDCopy, @@ -358,7 +358,7 @@ func (r *Repository) ConfirmPaidFromChannelTx(tx *gorm.DB, orderID uint64) (uint return 0, nil } -// NotifyNewConversation 兼容支付模块接口;摸大红不创建会话,空实现。 +// NotifyNewConversation 兼容支付模块接口;撞车不创建会话,空实现。 func (r *Repository) NotifyNewConversation(conversationID uint64) {} func (r *Repository) cancelPendingOrderTx(tx *gorm.DB, order *model.MohongOrder, reason string) error { diff --git a/backend/internal/modules/mohong/repository.go b/backend/internal/modules/mohong/repository.go index d2b495a..1163cab 100644 --- a/backend/internal/modules/mohong/repository.go +++ b/backend/internal/modules/mohong/repository.go @@ -2,7 +2,7 @@ package mohong import "gorm.io/gorm" -// Repository 摸大红数据访问。 +// Repository 撞车数据访问。 type Repository struct { db *gorm.DB } diff --git a/backend/internal/modules/payment/mohong_payment.go b/backend/internal/modules/payment/mohong_payment.go index 1d7a666..a8609fe 100644 --- a/backend/internal/modules/payment/mohong_payment.go +++ b/backend/internal/modules/payment/mohong_payment.go @@ -13,7 +13,7 @@ import ( const bizTypeMohongPay = "mohong_pay" -// StartMohong 发起摸大红订单支付。 +// StartMohong 发起撞车订单支付。 func (r *Repository) StartMohong(ctx context.Context, userID uint64, orderID uint64, req StartPaymentRequest, clientIP string) (*PaymentDTO, error) { req.PayWay = normalizePayWay(req.PayWay) defaultConfig, err := r.defaultRuntimeConfig(ctx, req.PayWay) @@ -73,7 +73,7 @@ func (r *Repository) StartMohong(ctx context.Context, userID uint64, orderID uin NotifyURL: runtimeConfig.NotifyURL, JumpURL: runtimeConfig.JumpURL, ClientIP: clientIP, - Body: "摸大红订单 " + orderRow.OrderNo, + Body: "撞车订单 " + orderRow.OrderNo, Attach: orderRow.OrderNo, }) if err != nil { @@ -202,7 +202,7 @@ func newMohongPayment(row model.MohongOrder, req StartPaymentRequest, runtimeCon return payment, nil } -// QueryMohong 查询摸大红订单支付状态。 +// QueryMohong 查询撞车订单支付状态。 func (r *Repository) QueryMohong(ctx context.Context, userID uint64, orderID uint64) (*PaymentDTO, error) { var payment model.PaymentOrder if err := r.db.WithContext(ctx). diff --git a/backend/internal/modules/payment/repository.go b/backend/internal/modules/payment/repository.go index 7b21744..3a9da8f 100644 --- a/backend/internal/modules/payment/repository.go +++ b/backend/internal/modules/payment/repository.go @@ -13,7 +13,7 @@ import ( "gorm.io/gorm" ) -// MohongOrderConfirmer 摸大红订单支付确认接口,避免 payment 与 mohong 循环依赖。 +// MohongOrderConfirmer 撞车订单支付确认接口,避免 payment 与 mohong 循环依赖。 type MohongOrderConfirmer interface { ConfirmPaidFromChannelTx(tx *gorm.DB, orderID uint64) (uint64, error) NotifyNewConversation(conversationID uint64) @@ -89,7 +89,7 @@ func WithLogger(logger *zap.Logger) RepositoryOption { } } -// WithMohongRepo 注入摸大红订单确认器。 +// WithMohongRepo 注入撞车订单确认器。 func WithMohongRepo(repo MohongOrderConfirmer) RepositoryOption { return func(r *Repository) { r.mohongRepo = repo diff --git a/backend/internal/router/router.go b/backend/internal/router/router.go index 6f8f722..d25aeb9 100644 --- a/backend/internal/router/router.go +++ b/backend/internal/router/router.go @@ -428,23 +428,26 @@ func New(cfg config.Config, deps Dependencies, logger *zap.Logger) *gin.Engine { sellerPickupRoutes.GET("", pickupHandler.ListForSeller) } - // 摸大红:商品公开,下单需登录+实名 + // 撞车(对外路径 /crash;兼容旧路径 /mohong):商品公开,下单需登录+实名 if mohongHandler != nil { - mohongPublic := api.Group("/mohong") - { - mohongPublic.GET("/categories", mohongHandler.ListCategories) - mohongPublic.GET("/products", mohongHandler.ListProducts) - mohongPublic.GET("/products/:id", mohongHandler.GetProduct) + registerCrashPublic := func(g *gin.RouterGroup) { + g.GET("/categories", mohongHandler.ListCategories) + g.GET("/products", mohongHandler.ListProducts) + g.GET("/products/:id", mohongHandler.GetProduct) } - mohongAuth := api.Group("/mohong", requireAuth) - { - mohongAuth.POST("/orders", requireRealname, mohongHandler.CreateOrder) - mohongAuth.GET("/orders", mohongHandler.ListMyOrders) - mohongAuth.GET("/orders/:id", mohongHandler.GetMyOrder) - mohongAuth.POST("/orders/:id/cancel", mohongHandler.CancelMyOrder) - mohongAuth.POST("/orders/:id/start-payment", requireRealname, paymentHandler.StartMohong) - mohongAuth.GET("/orders/:id/query-payment", paymentHandler.QueryMohong) + registerCrashAuth := func(g *gin.RouterGroup) { + g.POST("/orders", requireRealname, mohongHandler.CreateOrder) + g.GET("/orders", mohongHandler.ListMyOrders) + g.GET("/orders/:id", mohongHandler.GetMyOrder) + g.POST("/orders/:id/cancel", mohongHandler.CancelMyOrder) + g.POST("/orders/:id/start-payment", requireRealname, paymentHandler.StartMohong) + g.GET("/orders/:id/query-payment", paymentHandler.QueryMohong) } + registerCrashPublic(api.Group("/crash")) + registerCrashAuth(api.Group("/crash", requireAuth)) + // 兼容旧 API 前缀 + registerCrashPublic(api.Group("/mohong")) + registerCrashAuth(api.Group("/mohong", requireAuth)) } orderRoutes := api.Group("/orders", requireAuth) @@ -599,24 +602,28 @@ func New(cfg config.Config, deps Dependencies, logger *zap.Logger) *gin.Engine { adminRoutes.POST("/listings/:id/offline", requirePerm("listing:offline"), listingHandler.AdminOffline) adminRoutes.POST("/listings/:id/mark-abnormal", requirePerm("listing:offline"), listingHandler.AdminMarkAbnormal) - // 摸大红 + // 撞车后台(/admin/crash;兼容 /admin/mohong) if mohongHandler != nil { // 商品编辑需要拉分类列表,故 GET 用 product_view - adminRoutes.GET("/mohong/categories", requirePerm("mohong:product_view"), mohongHandler.AdminListCategories) - adminRoutes.POST("/mohong/categories", requirePerm("mohong:category"), mohongHandler.AdminCreateCategory) - adminRoutes.PUT("/mohong/categories/:id", requirePerm("mohong:category"), mohongHandler.AdminUpdateCategory) - adminRoutes.DELETE("/mohong/categories/:id", requirePerm("mohong:category"), mohongHandler.AdminDeleteCategory) - adminRoutes.GET("/mohong/products", requirePerm("mohong:product_view"), mohongHandler.AdminListProducts) - adminRoutes.GET("/mohong/products/:id", requirePerm("mohong:product_view"), mohongHandler.AdminGetProduct) - adminRoutes.POST("/mohong/products", requirePerm("mohong:product_manage"), mohongHandler.AdminCreateProduct) - adminRoutes.PUT("/mohong/products/:id", requirePerm("mohong:product_manage"), mohongHandler.AdminUpdateProduct) - adminRoutes.DELETE("/mohong/products/:id", requirePerm("mohong:product_manage"), mohongHandler.AdminDeleteProduct) - adminRoutes.GET("/mohong/orders", requirePerm("mohong:order_view"), mohongHandler.AdminListOrders) - adminRoutes.GET("/mohong/orders/:id", requirePerm("mohong:order_view"), mohongHandler.AdminGetOrder) - adminRoutes.POST("/mohong/orders/:id/complete", requirePerm("mohong:order_manage"), mohongHandler.AdminCompleteOrder) - adminRoutes.POST("/mohong/orders/:id/cancel", requirePerm("mohong:order_manage"), mohongHandler.AdminCancelOrder) - adminRoutes.GET("/mohong/config", requirePerm("mohong:config"), mohongHandler.AdminGetConfig) - adminRoutes.PUT("/mohong/config", requirePerm("mohong:config"), mohongHandler.AdminUpdateConfig) + registerCrashAdmin := func(prefix string) { + adminRoutes.GET(prefix+"/categories", requirePerm("mohong:product_view"), mohongHandler.AdminListCategories) + adminRoutes.POST(prefix+"/categories", requirePerm("mohong:category"), mohongHandler.AdminCreateCategory) + adminRoutes.PUT(prefix+"/categories/:id", requirePerm("mohong:category"), mohongHandler.AdminUpdateCategory) + adminRoutes.DELETE(prefix+"/categories/:id", requirePerm("mohong:category"), mohongHandler.AdminDeleteCategory) + adminRoutes.GET(prefix+"/products", requirePerm("mohong:product_view"), mohongHandler.AdminListProducts) + adminRoutes.GET(prefix+"/products/:id", requirePerm("mohong:product_view"), mohongHandler.AdminGetProduct) + adminRoutes.POST(prefix+"/products", requirePerm("mohong:product_manage"), mohongHandler.AdminCreateProduct) + adminRoutes.PUT(prefix+"/products/:id", requirePerm("mohong:product_manage"), mohongHandler.AdminUpdateProduct) + adminRoutes.DELETE(prefix+"/products/:id", requirePerm("mohong:product_manage"), mohongHandler.AdminDeleteProduct) + adminRoutes.GET(prefix+"/orders", requirePerm("mohong:order_view"), mohongHandler.AdminListOrders) + adminRoutes.GET(prefix+"/orders/:id", requirePerm("mohong:order_view"), mohongHandler.AdminGetOrder) + adminRoutes.POST(prefix+"/orders/:id/complete", requirePerm("mohong:order_manage"), mohongHandler.AdminCompleteOrder) + adminRoutes.POST(prefix+"/orders/:id/cancel", requirePerm("mohong:order_manage"), mohongHandler.AdminCancelOrder) + adminRoutes.GET(prefix+"/config", requirePerm("mohong:config"), mohongHandler.AdminGetConfig) + adminRoutes.PUT(prefix+"/config", requirePerm("mohong:config"), mohongHandler.AdminUpdateConfig) + } + registerCrashAdmin("/crash") + registerCrashAdmin("/mohong") } adminRoutes.GET("/disputes", requirePerm("dispute:view"), disputeHandler.AdminList) diff --git a/backend/migrations/000032_crash_branding.sql b/backend/migrations/000032_crash_branding.sql new file mode 100644 index 0000000..64bb2e8 --- /dev/null +++ b/backend/migrations/000032_crash_branding.sql @@ -0,0 +1,31 @@ +-- +goose Up + +UPDATE chat_support_groups +SET name = '撞车-客服', + description = '用户从撞车入口联系客服时,按本组成员在线与负载分配' +WHERE code = 'mohong'; + +UPDATE system_configs +SET description = REPLACE(description, '摸大红', '撞车'), + `value` = REPLACE(`value`, '摸大红', '撞车') +WHERE `key` LIKE 'mohong.%'; + +UPDATE permissions +SET name = REPLACE(name, '摸大红', '撞车') +WHERE code LIKE 'mohong:%'; + +-- +goose Down + +UPDATE chat_support_groups +SET name = '摸大红-客服', + description = '用户从摸大红入口联系客服时,按本组成员在线与负载分配' +WHERE code = 'mohong'; + +UPDATE system_configs +SET description = REPLACE(description, '撞车', '摸大红'), + `value` = REPLACE(`value`, '撞车', '摸大红') +WHERE `key` LIKE 'mohong.%'; + +UPDATE permissions +SET name = REPLACE(name, '撞车', '摸大红') +WHERE code LIKE 'mohong:%'; diff --git a/frontend/src/features/admin/views/AdminMohongCategoriesView.vue b/frontend/src/features/admin/views/AdminMohongCategoriesView.vue index 486800f..6374f52 100644 --- a/frontend/src/features/admin/views/AdminMohongCategoriesView.vue +++ b/frontend/src/features/admin/views/AdminMohongCategoriesView.vue @@ -96,7 +96,7 @@ async function handleDelete(item: MohongCategory) {
-

摸大红分类

+

撞车分类

大红 / 四格大红 / 炫彩等分类,前台左侧筛选使用

diff --git a/frontend/src/features/admin/views/AdminMohongConfigView.vue b/frontend/src/features/admin/views/AdminMohongConfigView.vue index 9add081..bb62558 100644 --- a/frontend/src/features/admin/views/AdminMohongConfigView.vue +++ b/frontend/src/features/admin/views/AdminMohongConfigView.vue @@ -49,7 +49,7 @@ async function handleSave() { async function uploadQrcode(file: File) { try { - const uploaded = await uploadAdminFile(file, 'mohong') + const uploaded = await uploadAdminFile(file, 'crash') form.default_qrcode_url = uploaded.url ElMessage.success('上传成功') } catch (error) { @@ -63,7 +63,7 @@ async function uploadQrcode(file: File) {
-

摸大红配置

+

撞车配置

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

保存配置 diff --git a/frontend/src/features/admin/views/AdminMohongOrdersView.vue b/frontend/src/features/admin/views/AdminMohongOrdersView.vue index 5d4c5cc..80c0371 100644 --- a/frontend/src/features/admin/views/AdminMohongOrdersView.vue +++ b/frontend/src/features/admin/views/AdminMohongOrdersView.vue @@ -85,7 +85,7 @@ async function copyText(text: string) {
-

摸大红订单

+

撞车订单

查看订单、完成履约、复制用户订单信息

刷新 diff --git a/frontend/src/features/admin/views/AdminMohongProductsView.vue b/frontend/src/features/admin/views/AdminMohongProductsView.vue index 3abe240..d912471 100644 --- a/frontend/src/features/admin/views/AdminMohongProductsView.vue +++ b/frontend/src/features/admin/views/AdminMohongProductsView.vue @@ -177,7 +177,7 @@ async function handleDelete(item: MohongProduct) { async function uploadImage(file: File, target: 'cover' | 'gallery' | 'qrcode') { try { - const uploaded = await uploadAdminFile(file, 'mohong') + const uploaded = await uploadAdminFile(file, 'crash') if (target === 'cover') form.cover_url = uploaded.url else if (target === 'qrcode') form.qrcode_image_url = uploaded.url else form.image_urls.push(uploaded.url) @@ -197,7 +197,7 @@ function removeGallery(url: string) {
-

摸大红商品

+

撞车商品

管理商品图片、价格、库存与专属二维码

diff --git a/frontend/src/features/chats/api/chats.ts b/frontend/src/features/chats/api/chats.ts index c9cec47..c6df45e 100644 --- a/frontend/src/features/chats/api/chats.ts +++ b/frontend/src/features/chats/api/chats.ts @@ -14,7 +14,7 @@ export interface ChatParticipant { joined_at: string } -export type SupportScene = 'general' | 'mohong' +export type SupportScene = 'general' | 'crash' export interface ChatConversation { id: number @@ -42,15 +42,19 @@ export interface ChatConversation { updated_at: string } -/** 根据当前路由推断客服场景:摸大红页 → mohong,其它 → general */ +/** 根据当前路由推断客服场景:撞车页 → crash,其它 → general */ export function resolveSupportScene(path: string): SupportScene { if ( + path === '/crash' || + path.startsWith('/crash/') || + path === '/m/crash' || + path.startsWith('/m/crash/') || path === '/mohong' || path.startsWith('/mohong/') || path === '/m/mohong' || path.startsWith('/m/mohong/') ) { - return 'mohong' + return 'crash' } return 'general' } diff --git a/frontend/src/features/listings/views/HomeView.vue b/frontend/src/features/listings/views/HomeView.vue index abfb41b..2b6ae5e 100644 --- a/frontend/src/features/listings/views/HomeView.vue +++ b/frontend/src/features/listings/views/HomeView.vue @@ -260,8 +260,8 @@ loadHome() 租号大厅 高哈夫币 · 安全交接 · 随租随玩 - - 摸大红 NEW + + 撞车 NEW 选购商品 · 支付后进群联系客服
@@ -372,7 +372,7 @@ loadHome() font-size: 13px; } -.biz-entry.mohong strong em { +.biz-entry.crash strong em { margin-left: 6px; padding: 1px 6px; border-radius: 999px; diff --git a/frontend/src/features/listings/views/MobileHomeView.css b/frontend/src/features/listings/views/MobileHomeView.css index 48fa8f5..3ac0006 100644 --- a/frontend/src/features/listings/views/MobileHomeView.css +++ b/frontend/src/features/listings/views/MobileHomeView.css @@ -364,28 +364,6 @@ box-shadow: 0 4px 14px rgba(23, 35, 61, 0.04); } -.biz-entry-icon { - display: inline-flex; - align-items: center; - justify-content: center; - width: 30px; - height: 30px; - border-radius: 9px; - font-size: 13px; - font-weight: 800; - margin-bottom: 2px; -} - -.biz-entry-icon.rental { - background: #fff1e6; - color: #ff6a00; -} - -.biz-entry-icon.mohong { - background: #fee2e2; - color: #dc2626; -} - .biz-entry strong { color: #17233d; font-size: 15px; diff --git a/frontend/src/features/listings/views/MobileHomeView.vue b/frontend/src/features/listings/views/MobileHomeView.vue index 8ffcfe1..936ab85 100644 --- a/frontend/src/features/listings/views/MobileHomeView.vue +++ b/frontend/src/features/listings/views/MobileHomeView.vue @@ -818,13 +818,11 @@ syncMobileHomeQuery()
- 租号大厅 高哈夫币 · 随租随玩 - - - 摸大红 + + 撞车 选购商品 · 一键找客服 NEW diff --git a/frontend/src/features/mohong/api/mohong.ts b/frontend/src/features/mohong/api/mohong.ts index 2a23530..8d799fe 100644 --- a/frontend/src/features/mohong/api/mohong.ts +++ b/frontend/src/features/mohong/api/mohong.ts @@ -92,7 +92,7 @@ export interface Paginated { } export async function fetchMohongCategories() { - const { data } = await apiClient.get>('/mohong/categories') + const { data } = await apiClient.get>('/crash/categories') return data.data || [] } @@ -102,14 +102,14 @@ export async function fetchMohongProducts(params?: { page?: number page_size?: number }) { - const { data } = await apiClient.get>>('/mohong/products', { + const { data } = await apiClient.get>>('/crash/products', { params, }) return data.data } export async function fetchMohongProduct(id: number | string) { - const { data } = await apiClient.get>(`/mohong/products/${id}`) + const { data } = await apiClient.get>(`/crash/products/${id}`) return data.data } @@ -121,7 +121,7 @@ export async function createMohongOrder( const payload = Array.isArray(productIdOrItems) ? { items: productIdOrItems } : { product_id: productIdOrItems, quantity } - const { data } = await apiClient.post>('/mohong/orders', payload) + const { data } = await apiClient.post>('/crash/orders', payload) return data.data } @@ -130,19 +130,19 @@ export async function fetchMyMohongOrders(params?: { page?: number page_size?: number }) { - const { data } = await apiClient.get>>('/mohong/orders', { + const { data } = await apiClient.get>>('/crash/orders', { params, }) return data.data } export async function fetchMyMohongOrder(id: number | string) { - const { data } = await apiClient.get>(`/mohong/orders/${id}`) + const { data } = await apiClient.get>(`/crash/orders/${id}`) return data.data } export async function cancelMyMohongOrder(id: number | string, reason?: string) { - const { data } = await apiClient.post>(`/mohong/orders/${id}/cancel`, { + const { data } = await apiClient.post>(`/crash/orders/${id}/cancel`, { reason: reason || '', }) return data.data @@ -154,7 +154,7 @@ export async function startMohongPayment( jsPayFlag?: string ) { const { data } = await apiClient.post>( - `/mohong/orders/${orderId}/start-payment`, + `/crash/orders/${orderId}/start-payment`, { pay_way: payWay || 'ZFBZF', jspay_flag: jsPayFlag || '', @@ -165,14 +165,14 @@ export async function startMohongPayment( export async function queryMohongPayment(orderId: number) { const { data } = await apiClient.get>( - `/mohong/orders/${orderId}/query-payment` + `/crash/orders/${orderId}/query-payment` ) return data.data } // Admin APIs export async function fetchAdminMohongCategories() { - const { data } = await apiClient.get>('/admin/mohong/categories') + const { data } = await apiClient.get>('/admin/crash/categories') return data.data || [] } @@ -183,7 +183,7 @@ export async function createAdminMohongCategory(payload: { status?: string }) { const { data } = await apiClient.post>( - '/admin/mohong/categories', + '/admin/crash/categories', payload ) return data.data @@ -194,7 +194,7 @@ export async function updateAdminMohongCategory( payload: Partial<{ name: string; code: string; sort_order: number; status: string }> ) { const { data } = await apiClient.put>( - `/admin/mohong/categories/${id}`, + `/admin/crash/categories/${id}`, payload ) return data.data @@ -202,7 +202,7 @@ export async function updateAdminMohongCategory( export async function deleteAdminMohongCategory(id: number) { const { data } = await apiClient.delete>( - `/admin/mohong/categories/${id}` + `/admin/crash/categories/${id}` ) return data.data } @@ -215,25 +215,25 @@ export async function fetchAdminMohongProducts(params?: { page_size?: number }) { const { data } = await apiClient.get>>( - '/admin/mohong/products', + '/admin/crash/products', { params } ) return data.data } export async function fetchAdminMohongProduct(id: number | string) { - const { data } = await apiClient.get>(`/admin/mohong/products/${id}`) + const { data } = await apiClient.get>(`/admin/crash/products/${id}`) return data.data } export async function createAdminMohongProduct(payload: Partial & { title: string; price_cent: number }) { - const { data } = await apiClient.post>('/admin/mohong/products', payload) + const { data } = await apiClient.post>('/admin/crash/products', payload) return data.data } export async function updateAdminMohongProduct(id: number, payload: Record) { const { data } = await apiClient.put>( - `/admin/mohong/products/${id}`, + `/admin/crash/products/${id}`, payload ) return data.data @@ -241,7 +241,7 @@ export async function updateAdminMohongProduct(id: number, payload: Record>( - `/admin/mohong/products/${id}` + `/admin/crash/products/${id}` ) return data.data } @@ -252,20 +252,20 @@ export async function fetchAdminMohongOrders(params?: { page?: number page_size?: number }) { - const { data } = await apiClient.get>>('/admin/mohong/orders', { + const { data } = await apiClient.get>>('/admin/crash/orders', { params, }) return data.data } export async function fetchAdminMohongOrder(id: number | string) { - const { data } = await apiClient.get>(`/admin/mohong/orders/${id}`) + const { data } = await apiClient.get>(`/admin/crash/orders/${id}`) return data.data } export async function completeAdminMohongOrder(id: number, remark?: string) { const { data } = await apiClient.post>( - `/admin/mohong/orders/${id}/complete`, + `/admin/crash/orders/${id}/complete`, { remark: remark || '' } ) return data.data @@ -273,19 +273,19 @@ export async function completeAdminMohongOrder(id: number, remark?: string) { export async function cancelAdminMohongOrder(id: number, reason?: string) { const { data } = await apiClient.post>( - `/admin/mohong/orders/${id}/cancel`, + `/admin/crash/orders/${id}/cancel`, { reason: reason || '' } ) return data.data } export async function fetchAdminMohongConfig() { - const { data } = await apiClient.get>('/admin/mohong/config') + const { data } = await apiClient.get>('/admin/crash/config') return data.data } export async function updateAdminMohongConfig(payload: Partial) { - const { data } = await apiClient.put>('/admin/mohong/config', payload) + const { data } = await apiClient.put>('/admin/crash/config', payload) return data.data } diff --git a/frontend/src/features/mohong/components/MohongCartPanel.vue b/frontend/src/features/mohong/components/MohongCartPanel.vue index 1ad6dd5..2bd733f 100644 --- a/frontend/src/features/mohong/components/MohongCartPanel.vue +++ b/frontend/src/features/mohong/components/MohongCartPanel.vue @@ -69,7 +69,7 @@ async function handleCheckout() { clearCart() closeCart() const payment = await startMohongPayment(order.id, payWay) - const orderPath = props.mobile ? `/m/mohong/orders/${order.id}` : `/mohong/orders/${order.id}` + const orderPath = props.mobile ? `/m/crash/orders/${order.id}` : `/crash/orders/${order.id}` if (payment.paid || payment.status === 'paid') { ElMessage.success('支付成功') await router.push(orderPath) diff --git a/frontend/src/features/mohong/components/MohongProductCard.vue b/frontend/src/features/mohong/components/MohongProductCard.vue index 93f1c0d..514cdb8 100644 --- a/frontend/src/features/mohong/components/MohongProductCard.vue +++ b/frontend/src/features/mohong/components/MohongProductCard.vue @@ -18,7 +18,7 @@ const stockLabel = computed(() => {