package service import ( e "errors" "github.com/xuri/excelize/v2" "gold-shop/errors" "gold-shop/global" "gold-shop/model" "gold-shop/request" "gold-shop/request/manage" "gold-shop/utils" "gold-shop/utils/excel" "gorm.io/gorm" "time" ) var OrderService = orderService{} type orderService struct { } func (orderService) Order(orderRequest request.OrderRequest, user *model.User) (*model.Order, error) { product := &model.Product{} err := global.DB.Where("id", orderRequest.ProductID).First(product).Error if e.Is(err, gorm.ErrRecordNotFound) { return nil, errors.NewBusinessError("商品不存在") } totalAmount := float64(orderRequest.Num) * product.Price if user.Balance < totalAmount { return nil, errors.NewBusinessError("账号余额不足") } orderNo := utils.GenerateNo("order") tx := global.DB.Begin() order := model.Order{} order.OrderNo = orderNo order.Amount = totalAmount order.UserID = user.ID err = global.DB.Save(&order).Error if err != nil { tx.Rollback() return nil, errors.NewBusinessError("保存数据失败") } orderProduct := model.OrderProduct{} orderProduct.ProductID = orderRequest.ProductID orderProduct.OrderNo = orderNo orderProduct.Price = product.Price orderProduct.Amount = totalAmount orderProduct.Num = orderRequest.Num err = global.DB.Save(&orderProduct).Error if err != nil { tx.Rollback() return nil, errors.NewBusinessError("保存数据失败") } global.DB.Model(user).Update("balance", gorm.Expr("balance - ?", totalAmount)) tx.Commit() return &order, nil } func (orderService) GetUserOrders(userID, page, pageSize int) ([]model.Order, int64) { orders := make([]model.Order, pageSize) offset := (page - 1) * pageSize var total int64 global.DB.Where("user_id", userID).Preload("OrderProducts").Offset(offset).Limit(pageSize).Find(&orders) global.DB.Model(&model.Order{}).Where("user_id", userID).Count(&total) return orders, total } func (s *orderService) buildQuery(req manage.OrderQueryRequest) *gorm.DB { tx := global.DB if req.Mobile != "" { var userIds []int global.DB.Model(&model.User{}).Where("mobile", req.Mobile).Pluck("id", &userIds) tx = tx.Where("user_id", userIds) } if req.OrderNo != "" { tx = tx.Where("order_no", req.OrderNo) } if req.UserID != 0 { tx = tx.Where("user_id", req.UserID) } return tx } func (s *orderService) GetOrders(req manage.OrderQueryRequest) ([]model.Order, int64) { orders := make([]model.Order, req.PageSize) offset := (req.Page - 1) * req.PageSize var total int64 tx := s.buildQuery(req) tx.Preload("OrderProducts").Preload("User").Order("id desc").Offset(offset).Limit(req.PageSize).Find(&orders) tx.Model(&model.Order{}).Count(&total) return orders, total } func (s *orderService) GenerateOrdersExcel(req manage.OrderQueryRequest) *excelize.File { pageSize := 200 lastID := 0 tx := s.buildQuery(req) f := excel.NewFile() headers := []string{"订单号", "用户手机号", "购买份数", "订单总金额", "下单时间"} excel.SetSimpleHeaders(headers, "Sheet1", f) for { orders := make([]model.Order, pageSize) tx.Preload("OrderProducts").Preload("User").Where("id > ?", lastID).Limit(pageSize).Find(&orders) count := len(orders) if count == 0 { break } s.buildOrdersExcel(orders, "Sheet1", f) lastIndex := count - 1 lastID = orders[lastIndex].ID } return f } func (orderService) buildOrdersExcel(orders []model.Order, sheet string, f *excelize.File) { row := 2 for _, order := range orders { col := 0 num := 0 for _, orderProduct := range order.OrderProducts { num += orderProduct.Num } f.SetCellValue(sheet, excel.CellKey(row, &col), order.OrderNo) f.SetCellValue(sheet, excel.CellKey(row, &col), order.User.Mobile) f.SetCellValue(sheet, excel.CellKey(row, &col), num) f.SetCellValue(sheet, excel.CellKey(row, &col), order.Amount) f.SetCellValue(sheet, excel.CellKey(row, &col), order.CreatedAt.Format(time.DateTime)) row++ } }