Files
rogee 7e41bcaaee
Build and push backend image / backend-image (push) Successful in 52s
chore: remove legacy booking flows and use local admin auth
2026-09-23 21:26:58 +08:00

182 lines
4.9 KiB
Go

package service
import (
"context"
"database/sql"
"strings"
"github.com/rogeecn/wxapp-kouqiang-guahao/backend/internal/db"
)
type AdminPriceInquiryRecord struct {
InquiryID string `json:"inquiry_id"`
Phone string `json:"phone"`
Province string `json:"province"`
City string `json:"city"`
District string `json:"district"`
Region string `json:"region"`
ProjectName string `json:"project_name"`
Status string `json:"status"`
StatusClass string `json:"status_class"`
StatusText string `json:"status_text"`
Remark string `json:"remark"`
LastSubmittedAt string `json:"last_submitted_at"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
}
type AdminPriceInquiryFilter struct {
Area string
Phone string
Status string
TimeFrom string
TimeTo string
}
type AdminPriceInquiryPage struct {
Records []AdminPriceInquiryRecord
Total int64
Page int
PageSize int
TotalPages int
HasPreviousPage bool
HasNextPage bool
PreviousPage int
NextPage int
}
func (s *Service) AdminPriceInquiryRecords(ctx context.Context, filter AdminPriceInquiryFilter, limit, offset int64) ([]AdminPriceInquiryRecord, error) {
if limit <= 0 || limit > 200 {
limit = 50
}
filter = normalizeAdminPriceInquiryFilter(filter)
inquiries, err := s.Q.ListPriceInquiries(ctx, db.ListPriceInquiriesParams{
Area: filter.Area,
Phone: filter.Phone,
Status: filter.Status,
TimeFrom: filter.TimeFrom,
TimeTo: filter.TimeTo,
Limit: limit,
Offset: offset,
})
if err != nil {
return nil, err
}
return adminPriceInquiryRecordsFromRows(inquiries), nil
}
func (s *Service) AdminPriceInquiryRecordsPage(ctx context.Context, filter AdminPriceInquiryFilter, page, pageSize int) (AdminPriceInquiryPage, error) {
filter = normalizeAdminPriceInquiryFilter(filter)
total, err := s.Q.CountPriceInquiries(ctx, db.CountPriceInquiriesParams{
Area: filter.Area,
Phone: filter.Phone,
Status: filter.Status,
TimeFrom: filter.TimeFrom,
TimeTo: filter.TimeTo,
})
if err != nil {
return AdminPriceInquiryPage{}, err
}
offset := int64((page - 1) * pageSize)
inquiries, err := s.Q.ListPriceInquiries(ctx, db.ListPriceInquiriesParams{
Area: filter.Area,
Phone: filter.Phone,
Status: filter.Status,
TimeFrom: filter.TimeFrom,
TimeTo: filter.TimeTo,
Limit: int64(pageSize),
Offset: offset,
})
if err != nil {
return AdminPriceInquiryPage{}, err
}
totalPages := 1
if total > 0 {
totalPages = int((total + int64(pageSize) - 1) / int64(pageSize))
}
result := AdminPriceInquiryPage{
Records: adminPriceInquiryRecordsFromRows(inquiries),
Total: total,
Page: page,
PageSize: pageSize,
TotalPages: totalPages,
HasPreviousPage: page > 1,
HasNextPage: page < totalPages,
}
if result.HasPreviousPage {
result.PreviousPage = page - 1
}
if result.HasNextPage {
result.NextPage = page + 1
}
return result, nil
}
func adminPriceInquiryRecordsFromRows(inquiries []db.PriceInquiry) []AdminPriceInquiryRecord {
records := make([]AdminPriceInquiryRecord, 0, len(inquiries))
for _, inquiry := range inquiries {
records = append(records, AdminPriceInquiryRecord{
InquiryID: inquiry.ID,
Phone: inquiry.Phone,
Province: inquiry.Province,
City: inquiry.City,
District: inquiry.District,
Region: inquiry.Province + " " + inquiry.City + " " + inquiry.District,
ProjectName: inquiry.ProjectName,
Status: inquiry.Status,
StatusClass: adminPriceInquiryStatusClass(inquiry.Status),
StatusText: adminPriceInquiryStatusText(inquiry.Status),
Remark: inquiry.Remark,
LastSubmittedAt: inquiry.LastSubmittedAt,
CreatedAt: inquiry.CreatedAt,
UpdatedAt: inquiry.UpdatedAt,
})
}
return records
}
func normalizeAdminPriceInquiryFilter(filter AdminPriceInquiryFilter) AdminPriceInquiryFilter {
return AdminPriceInquiryFilter{
Area: strings.TrimSpace(filter.Area),
Phone: strings.TrimSpace(filter.Phone),
Status: strings.TrimSpace(filter.Status),
TimeFrom: strings.TrimSpace(filter.TimeFrom),
TimeTo: strings.TrimSpace(filter.TimeTo),
}
}
func adminPriceInquiryStatusText(status string) string {
switch status {
case "pending":
return "待派单"
case "assigned":
return "已经派单"
case "completed":
return "已跟进"
default:
return status
}
}
func adminPriceInquiryStatusClass(status string) string {
switch status {
case "pending":
return "status-pending"
case "assigned":
return "status-assigned"
case "completed":
return "status-completed"
default:
return "status-unknown"
}
}
func nullString(value sql.NullString) string {
if !value.Valid {
return ""
}
return value.String
}