优化客服群聊订单信息展示

This commit is contained in:
yml
2026-06-18 00:44:45 +08:00
parent 0add23dedb
commit 272b2cb71e
15 changed files with 479 additions and 55 deletions
@@ -54,6 +54,7 @@ func (r *Repository) FindConversation(ctx context.Context, principal Principal,
dto := ConversationDTO{
ID: conversation.ID,
OrderID: conversation.OrderID,
ListingID: conversation.ListingID,
Type: conversation.Type,
Title: conversation.Title,
Status: conversation.Status,
+1
View File
@@ -10,6 +10,7 @@ type Principal struct {
type ConversationDTO struct {
ID uint64 `json:"id"`
OrderID *uint64 `json:"order_id"`
ListingID *uint64 `json:"listing_id"`
Type string `json:"type"`
Title string `json:"title"`
Status string `json:"status"`
+3 -1
View File
@@ -14,6 +14,7 @@ import (
type conversationRow struct {
ID uint64
OrderID *uint64
ListingID *uint64
Type string
Title string
Status string
@@ -28,7 +29,7 @@ type conversationRow struct {
func (r *Repository) conversationQuery(ctx context.Context, principal Principal) *gorm.DB {
return r.db.WithContext(ctx).Table("chat_conversations AS c").
Select(`c.id, c.order_id, c.type, c.title, c.status, c.last_message_id,
Select(`c.id, c.order_id, c.listing_id, c.type, c.title, c.status, c.last_message_id,
c.last_message_preview, c.last_message_at, c.created_at, c.updated_at, cp.role,
(
SELECT COUNT(1)
@@ -282,6 +283,7 @@ func (row conversationRow) toDTO(participants []ParticipantDTO) ConversationDTO
return ConversationDTO{
ID: row.ID,
OrderID: row.OrderID,
ListingID: row.ListingID,
Type: row.Type,
Title: row.Title,
Status: row.Status,
+1
View File
@@ -141,6 +141,7 @@ func (r *Repository) ListConversationsWithFilter(ctx context.Context, principal
items = append(items, ConversationDTO{
ID: conv.ID,
OrderID: conv.OrderID,
ListingID: conv.ListingID,
Type: conv.Type,
Title: conv.Title,
Status: conv.Status,
@@ -32,6 +32,19 @@ func (h *Handler) AdminDetail(c *gin.Context) {
response.OK(c, item)
}
func (h *Handler) AdminLatestByListing(c *gin.Context) {
id, ok := parseID(c)
if !ok {
return
}
item, err := h.service.FindLatestAdminByListing(c.Request.Context(), id)
if err != nil {
writeOrderError(c, err)
return
}
response.OK(c, item)
}
func (h *Handler) AdminHandoffRecords(c *gin.Context) {
id, ok := parseID(c)
if !ok {
+16
View File
@@ -80,6 +80,22 @@ func (r *Repository) FindAdmin(ctx context.Context, orderID uint64) (*OrderDTO,
return &dto, nil
}
func (r *Repository) FindLatestAdminByListing(ctx context.Context, listingID uint64) (*OrderDTO, error) {
var row orderRow
db := r.db.WithContext(ctx)
if err := r.adminQuery(ctx).
Where("o.listing_id = ?", listingID).
Order("o.id DESC").
First(&row).Error; err != nil {
return nil, err
}
dto := row.toAdminDTO()
applyPaymentDeadline(&dto, row.RentalOrder, pendingPaymentTimeoutMinutes(db))
dto.ActiveDispute = r.activeDisputeDTO(ctx, row.ID)
dto.Checkout = r.latestCheckoutAdminDTO(ctx, row.ID)
return &dto, nil
}
func (r *Repository) FindForUser(ctx context.Context, userID uint64, orderID uint64) (*OrderDTO, error) {
var row orderRow
db := r.db.WithContext(ctx)
+10
View File
@@ -159,6 +159,16 @@ func (s *Service) FindAdmin(ctx context.Context, orderID uint64) (*OrderDTO, err
return s.repo.FindAdmin(ctx, orderID)
}
func (s *Service) FindLatestAdminByListing(ctx context.Context, listingID uint64) (*OrderDTO, error) {
if s.repo == nil {
return nil, ErrDependencyUnavailable
}
if listingID == 0 {
return nil, ErrListingUnavailable
}
return s.repo.FindLatestAdminByListing(ctx, listingID)
}
func (s *Service) HandoffRecordsAdmin(ctx context.Context, orderID uint64) ([]HandoffRecordDTO, error) {
if s.repo == nil {
return nil, ErrDependencyUnavailable
+1
View File
@@ -489,6 +489,7 @@ func New(cfg config.Config, deps Dependencies, logger *zap.Logger) *gin.Engine {
adminRoutes.POST("/users/:id/deposit-free-quota", requirePerm("user:deposit_free"), adminUserHandler.SetDepositFreeQuota)
adminRoutes.POST("/users/:id/revoke-realname", requirePerm("user:revoke_realname"), adminUserHandler.RevokeRealname)
adminRoutes.GET("/orders", requirePerm("order:view"), orderHandler.AdminList)
adminRoutes.GET("/listing-orders/:id/latest", requirePerm("order:view"), orderHandler.AdminLatestByListing)
adminRoutes.GET("/orders/:id", requirePerm("order:view"), orderHandler.AdminDetail)
adminRoutes.GET("/orders/:id/handoff-records", requirePerm("order:view"), orderHandler.AdminHandoffRecords)
adminRoutes.POST("/orders/:id/close", requirePerm("order:close"), orderHandler.AdminClose)