package user import ( "strings" "time" "git.apinb.com/bsm-sdk/core/errcode" "git.apinb.com/bsm-sdk/core/infra" "git.apinb.com/heqiapp/platforms/backend/api/internal/impl" common "git.apinb.com/heqiapp/platforms/backend/api/internal/logic/common" "git.apinb.com/heqiapp/platforms/backend/api/internal/models" "github.com/gin-gonic/gin" "gorm.io/gorm" ) // ListAddresses 返回当前用户未归档地址。 func ListAddresses(ctx *gin.Context) { account, ok := common.UserAccount(ctx) if !ok { return } var list []models.UserAddress if err := impl.DBService.Where("user_account_id = ? AND status <> ?", account.ID, common.StatusArchived).Order("is_default desc, created_at desc").Find(&list).Error; err != nil { infra.Response.Error(ctx, err) return } infra.Response.Success(ctx, common.ResourceResponse(list)) } // SaveAddress 新增地址,设为默认时原默认地址会在同一事务取消默认。 func SaveAddress(ctx *gin.Context) { account, ok := common.UserAccount(ctx) if !ok { return } var request struct { Address string `json:"address" binding:"required,max=255"` Longitude string `json:"longitude"` Latitude string `json:"latitude"` IsDefault bool `json:"is_default"` } if ctx.ShouldBindJSON(&request) != nil { infra.Response.Error(ctx, errcode.ErrInvalidArgument) return } address := models.UserAddress{ Entity: common.NewEntity(common.StatusEnable), UserAccountID: account.ID, Address: request.Address, Longitude: request.Longitude, Latitude: request.Latitude, IsDefault: request.IsDefault, } err := impl.DBService.Transaction(func(tx *gorm.DB) error { if request.IsDefault { if err := tx.Model(&models.UserAddress{}).Where("user_account_id = ?", account.ID).Update("is_default", false).Error; err != nil { return err } } return tx.Create(&address).Error }) if err != nil { infra.Response.Error(ctx, err) return } infra.Response.Success(ctx, gin.H{"identity": address.Identity}) } var userTicketCategories = map[string]bool{ "installation": true, "repair": true, "inspection": true, "reinspection": true, "customer_service": true, } // CreateTicket 创建工单,服务人员只能由后台分派。 func CreateTicket(ctx *gin.Context) { account, ok := common.UserAccount(ctx) if !ok { return } var request struct { RequestNo string `json:"request_no" binding:"required"` Category string `json:"category" binding:"required"` Description string `json:"description" binding:"required,max=2000"` AddressIdentity string `json:"address_identity"` AppointmentAt *time.Time `json:"appointment_at"` } if ctx.ShouldBindJSON(&request) != nil || !userTicketCategories[request.Category] { infra.Response.Error(ctx, errcode.ErrInvalidArgument) return } var relation models.UserServiceRelation _ = impl.DBService.Where("user_account_id = ? AND status = ?", account.ID, common.StatusEnable).First(&relation).Error addressText := "" if request.AddressIdentity != "" { var address models.UserAddress if impl.DBService.Where("identity = ? AND user_account_id = ? AND status <> ?", request.AddressIdentity, account.ID, common.StatusArchived).First(&address).Error != nil { infra.Response.Error(ctx, errcode.ErrRecordNotFound) return } addressText = address.Address } ticket := models.CsTicket{ Entity: common.NewEntity(common.StatusEnable), TicketStatus: 32, TicketNo: common.RecordNo("TK"), RequestNo: request.RequestNo, UserAccountID: account.ID, GasBasicID: relation.GasBasicID, DeliveryBasicID: relation.DeliveryBasicID, Category: request.Category, Priority: "normal", Description: strings.TrimSpace(request.Description), Address: addressText, AppointmentAt: request.AppointmentAt, OperatorIdentity: account.Identity, } if err := impl.DBService.Create(&ticket).Error; err != nil { infra.Response.Error(ctx, err) return } infra.Response.Success(ctx, gin.H{"identity": ticket.Identity, "ticket_no": ticket.TicketNo, "ticket_status": ticket.TicketStatus}) } // ListTickets 仅返回当前用户自己的工单。 func ListTickets(ctx *gin.Context) { account, ok := common.UserAccount(ctx) if !ok { return } var list []models.CsTicket if err := impl.DBService.Where("user_account_id = ? AND status <> ?", account.ID, common.StatusArchived).Order("created_at desc").Find(&list).Error; err != nil { infra.Response.Error(ctx, err) return } infra.Response.Success(ctx, common.ResourceResponse(list)) } // ConfirmTicket 用户确认工作人员提交的处理结果。 func ConfirmTicket(ctx *gin.Context) { account, ok := common.UserAccount(ctx) if !ok { return } now := time.Now() result := impl.DBService.Model(&models.CsTicket{}). Where("identity = ? AND user_account_id = ? AND ticket_status = ?", ctx.Param("identity"), account.ID, 34). Updates(map[string]any{"ticket_status": 23, "completed_at": &now, "operator_identity": account.Identity}) if result.Error != nil { infra.Response.Error(ctx, result.Error) return } if result.RowsAffected != 1 { infra.Response.Error(ctx, errcode.ErrInvalidArgument) return } infra.Response.Success(ctx, gin.H{"confirmed": true}) } // CancelTicket 取消尚未完成的本人工单。 func CancelTicket(ctx *gin.Context) { account, ok := common.UserAccount(ctx) if !ok { return } result := impl.DBService.Model(&models.CsTicket{}). Where("identity = ? AND user_account_id = ? AND ticket_status IN ?", ctx.Param("identity"), account.ID, []int{32, 18, 11, 21, 34}). Updates(map[string]any{"ticket_status": 22, "operator_identity": account.Identity}) if result.Error != nil { infra.Response.Error(ctx, result.Error) return } if result.RowsAffected != 1 { infra.Response.Error(ctx, errcode.ErrInvalidArgument) return } infra.Response.Success(ctx, gin.H{"cancelled": true}) }