From 9c4e75d7490550a50aab4231919f3787b1e8c549 Mon Sep 17 00:00:00 2001 From: chenlin Date: Thu, 17 Jul 2025 11:06:49 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E7=A7=9F=E8=B5=81=E8=AE=A2=E5=8D=95?= =?UTF-8?q?=E5=BD=92=E8=BF=98=E5=A2=9E=E5=8A=A0"=E8=B6=85=E6=9C=9F?= =?UTF-8?q?=E5=A4=84=E7=90=86"=E7=9A=84=E9=80=BB=E8=BE=91=EF=BC=8C?= =?UTF-8?q?=E8=B6=85=E6=9C=9F=E5=A4=84=E7=90=86=E7=9A=84=E8=AE=A2=E5=8D=95?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E4=B8=BA7=EF=BC=8C=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E4=B8=AD=E4=BF=9D=E8=AF=81=E9=87=91=E6=B8=85?= =?UTF-8?q?=E9=9B=B6=EF=BC=8C=E4=B8=94mark=3D1=EF=BC=9B=202=E3=80=81?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=A7=9F=E8=B5=81=E8=AE=A2=E5=8D=95=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E5=88=97=E8=A1=A8=E6=8E=A5=E5=8F=A3=EF=BC=8C=E8=A7=A3?= =?UTF-8?q?=E5=86=B3=E6=9F=A5=E8=AF=A2=E6=85=A2=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=EF=BC=9B=E5=B7=B2=E5=AE=8C=E6=88=90=E7=8A=B6=E6=80=81=E6=94=B9?= =?UTF-8?q?=E4=B8=BA=EF=BC=884=EF=BC=8C7=EF=BC=89=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/admin/apis/ordermanage/order.go | 28 +++ app/admin/models/order.go | 343 +++++++++++++++++++++------- 2 files changed, 286 insertions(+), 85 deletions(-) diff --git a/app/admin/apis/ordermanage/order.go b/app/admin/apis/ordermanage/order.go index 3298936..7477320 100644 --- a/app/admin/apis/ordermanage/order.go +++ b/app/admin/apis/ordermanage/order.go @@ -122,6 +122,34 @@ func RevertGoods(c *gin.Context) { return } + if len(order.PhoneExt) != 4 { + app.Error(c, http.StatusBadRequest, errors.New("手机尾号填写有误(4位数字)"), + "手机尾号填写有误(4位数字)") + return + } + + if order.OverdueFlag == 1 { // 检查用户会员是否过期 + var orderInfo models.Order + err := orm.Eloquent.Table("order").Where("id", order.ID).Find(&orderInfo).Error + if err != nil { + app.Error(c, http.StatusBadRequest, err, err.Error()) + return + } + + userInfo, err := models.GetUserInfoByUid(uint32(orderInfo.Uid)) + if err != nil { + app.Error(c, http.StatusBadRequest, err, err.Error()) + return + } + + if userInfo.MemberLevel == 2 || userInfo.MemberLevel == 3 || userInfo.MemberLevel == 4 || + userInfo.MemberLevel == 5 { + app.Error(c, http.StatusBadRequest, errors.New("该用户会员还未过期,不能选择超期处理"), + "该用户会员还未过期,不能选择超期处理") + return + } + } + if order.RevertShopperCode != "" && !models.CheckCode(order.RevertShopperCode) { app.Error(c, http.StatusBadRequest, errors.New("order revert shopper code err"), "店员码错误") return diff --git a/app/admin/models/order.go b/app/admin/models/order.go index b445090..9394c18 100644 --- a/app/admin/models/order.go +++ b/app/admin/models/order.go @@ -23,12 +23,13 @@ import ( ) const ( - OrderCardStatusUnPick = 1 // 待取货中 - OrderCardStatusPlaying = 2 // 游玩中 - OrderCardStatusReturning = 3 // 归还中 - OrderCardStatusCompleted = 4 // 已完成 - OrderCardStatusCancel = 5 // 已取消 - OrderCardStatusRefund = 6 // 已退款 + OrderCardStatusUnPick = 1 // 待取货中 + OrderCardStatusPlaying = 2 // 游玩中 + OrderCardStatusReturning = 3 // 归还中 + OrderCardStatusCompleted = 4 // 已完成 + OrderCardStatusCancel = 5 // 已取消 + OrderCardStatusRefund = 6 // 已退款 + OrderCardStatusSystemReturn = 7 // 系统处理(超期卡) DeliveryTypeStorePick = 1 // 门店取货 DeliveryTypeExpress = 2 // 快递取货 @@ -79,9 +80,10 @@ type Order struct { GameCardSerialNumbers []string `json:"game_card_serial_numbers" gorm:"-"` OrderCards []OrderCard `json:"order_cards" gorm:"-"` - DeliverShopperCode string `json:"deliver_shopper_code" gorm:"-"` //发货店员码 - RevertShopperCode string `json:"revert_shopper_code" gorm:"-"` - PhoneExt string `json:"phone_ext" gorm:"-"` + DeliverShopperCode string `json:"deliver_shopper_code" gorm:"-"` // 发货店员码 + RevertShopperCode string `json:"revert_shopper_code" gorm:"-"` // 店员识别码 + PhoneExt string `json:"phone_ext" gorm:"-"` // 用户手机号后四位 + OverdueFlag uint32 `json:"overdue_flag" gorm:"-"` // 超期处理标志:1 User *UserInfo `json:"user" gorm:"foreignKey:uid;references:uid"` } @@ -229,20 +231,159 @@ func (m *OrderListReq) List(exportFlag int, c *gin.Context) ([]Order, int64, str return orders, count, filePath, nil } +//func (m *OrderListReq) queryListFormOrderCard(exportFlag int, c *gin.Context) ([]Order, int64, error) { +// var orderCards []OrderCard +// orders := make([]Order, 0) +// +// qs := orm.Eloquent.Table("order_card").Where("card_status=?", m.CardStatus) +// +// // 非管理员才判断所属门店 +// if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") { +// sysUser, err := GetSysUserByCtx(c) +// if err != nil { +// return nil, 0, err +// } +// +// // 返回sysUser未过期的门店id列表 +// storeList := GetValidStoreIDs(sysUser.StoreData) +// if m.StoreId != 0 { +// if !Contains(storeList, uint32(m.StoreId)) { +// return nil, 0, errors.New("您没有该门店权限") +// } +// } else { +// if len(storeList) > 0 { +// if len(storeList) == 1 { +// qs = qs.Where("store_id = ? OR revert_store_id = ?", storeList[0], storeList[0]) +// } else { +// qs = qs.Where("store_id IN (?) OR revert_store_id IN (?)", storeList, storeList) +// } +// } else { +// return nil, 0, errors.New("用户未绑定门店") +// } +// } +// } +// +// if m.SerialNumber != "" { +// qs = qs.Where("serial_number=?", m.SerialNumber) +// } +// +// if m.DeliveryType != 0 { // 共有 +// qs = qs.Where("delivery_type", m.DeliveryType) +// } +// +// if m.Uid != 0 { // 用户id,共有 +// qs = qs.Where("uid", m.Uid) +// } +// if m.GameCardId != 0 { // 游戏卡id,共有 +// qs = qs.Where("game_card_id", m.GameCardId) +// } +// +// if m.StoreId != 0 { // 门店id,共有 +// qs = qs.Where("store_id = ? OR revert_store_id = ?", m.StoreId, m.StoreId) +// } +// if !m.StartTime.IsZero() { // 共有 +// fmt.Println("起始时间:", m.StartTime.Unix()) +// qs = qs.Where("created_at > ?", m.StartTime) +// } +// if !m.EndTime.IsZero() { // 共有 +// fmt.Println("时间:", m.StartTime.Unix()) +// qs = qs.Where("created_at < ?", m.EndTime) +// } +// +// err := qs.Find(&orderCards).Error +// if err != nil { +// logger.Error("err:", logger.Field("err", err)) +// return nil, 0, err +// } +// +// orderIds := make([]uint32, 0) +// for i, _ := range orderCards { +// orderIds = append(orderIds, orderCards[i].OrderId) +// } +// +// orderQs := orm.Eloquent.Table("order").Where("pay_status", 2).Where("id in (?)", orderIds) +// var count int64 +// err = orderQs.Count(&count).Error +// if err != nil { +// logger.Errorf("err:", logger.Field("err", err)) +// return nil, 0, err +// } +// +// page := m.Page +// pageSize := m.PageSize +// page -= 1 +// if page < 0 { +// page = 0 +// } +// +// if exportFlag == 1 { //一次性导出excel +// orderQs = orderQs.Preload("User").Order("created_at DESC") +// } else { +// orderQs = orderQs.Preload("User").Order("created_at DESC").Offset(page * pageSize).Limit(pageSize) +// } +// err = orderQs.Find(&orders).Error +// if err != nil { +// logger.Errorf("err:", logger.Field("err", err)) +// return nil, 0, err +// } +// +// ids := make([]uint32, 0, len(orders)) +// for i, _ := range orders { +// ids = append(ids, uint32(orders[i].ID)) +// } +// if len(ids) == 0 { +// logger.Error("gameIds is nil") +// return nil, 0, err +// } +// +// err = orm.Eloquent.Table("order_card").Where("order_id in (?)", ids).Find(&orderCards).Error +// if err != nil { +// logger.Error("err:", logger.Field("err", err)) +// return nil, 0, err +// } +// orderCards = OrderCardListSetGameInfo(orderCards) +// orderCardsMap := make(map[uint32][]OrderCard, 0) +// for i, _ := range orderCards { +// if orderCards[i].CardStatus == OrderCardStatusSystemReturn { +// orderCards[i].CardStatus = OrderCardStatusCompleted +// } +// +// if orderCards[i].CardStatus == m.CardStatus { //卡片状态相同的租卡订单才返回,方便财务导出数据 +// orderCardsMap[orderCards[i].OrderId] = append(orderCardsMap[orderCards[i].OrderId], orderCards[i]) +// } +// } +// for i, _ := range orders { +// //2023-12-12 跟产品讨论后确认状态按原来的5种进行展示 +// //if orders[i].CardStatus == 2 || orders[i].CardStatus == 3 { +// // orders[i].CardStatus = 4 +// //} +// v, ok := orderCardsMap[orders[i].ID] +// if ok { +// orders[i].OrderCards = v +// } +// } +// +// return orders, count, nil +//} + func (m *OrderListReq) queryListFormOrderCard(exportFlag int, c *gin.Context) ([]Order, int64, error) { - var orderCards []OrderCard orders := make([]Order, 0) + var orderIds []uint32 - qs := orm.Eloquent.Table("order_card").Where("card_status=?", m.CardStatus) + // 初始 card 表查询 + cardQs := orm.Eloquent.Table("order_card").Select("DISTINCT order_id") + if m.CardStatus == OrderCardStatusCompleted { + cardQs = cardQs.Where("pay_status = 2 and card_status in (?)", []int{OrderCardStatusCompleted, OrderCardStatusSystemReturn}) + } else { + cardQs = cardQs.Where("pay_status = 2 and card_status = ?", m.CardStatus) + } - // 非管理员才判断所属门店 + // 权限控制 if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") { sysUser, err := GetSysUserByCtx(c) if err != nil { return nil, 0, err } - - // 返回sysUser未过期的门店id列表 storeList := GetValidStoreIDs(sysUser.StoreData) if m.StoreId != 0 { if !Contains(storeList, uint32(m.StoreId)) { @@ -251,9 +392,9 @@ func (m *OrderListReq) queryListFormOrderCard(exportFlag int, c *gin.Context) ([ } else { if len(storeList) > 0 { if len(storeList) == 1 { - qs = qs.Where("store_id = ? OR revert_store_id = ?", storeList[0], storeList[0]) + cardQs = cardQs.Where("store_id = ? OR revert_store_id = ?", storeList[0], storeList[0]) } else { - qs = qs.Where("store_id IN (?) OR revert_store_id IN (?)", storeList, storeList) + cardQs = cardQs.Where("store_id IN (?) OR revert_store_id IN (?)", storeList, storeList) } } else { return nil, 0, errors.New("用户未绑定门店") @@ -261,98 +402,106 @@ func (m *OrderListReq) queryListFormOrderCard(exportFlag int, c *gin.Context) ([ } } + // 其他筛选条件 if m.SerialNumber != "" { - qs = qs.Where("serial_number=?", m.SerialNumber) + cardQs = cardQs.Where("serial_number = ?", m.SerialNumber) + } + if m.DeliveryType != 0 { + cardQs = cardQs.Where("delivery_type = ?", m.DeliveryType) + } + if m.Uid != 0 { + cardQs = cardQs.Where("uid = ?", m.Uid) + } + if m.GameCardId != 0 { + cardQs = cardQs.Where("game_card_id = ?", m.GameCardId) + } + if m.StoreId != 0 { + cardQs = cardQs.Where("store_id = ? OR revert_store_id = ?", m.StoreId, m.StoreId) + } + if !m.StartTime.IsZero() { + cardQs = cardQs.Where("created_at > ?", m.StartTime) + } + if !m.EndTime.IsZero() { + cardQs = cardQs.Where("created_at < ?", m.EndTime) } - if m.DeliveryType != 0 { // 共有 - qs = qs.Where("delivery_type", m.DeliveryType) - } - - if m.Uid != 0 { // 用户id,共有 - qs = qs.Where("uid", m.Uid) - } - if m.GameCardId != 0 { // 游戏卡id,共有 - qs = qs.Where("game_card_id", m.GameCardId) - } - - if m.StoreId != 0 { // 门店id,共有 - qs = qs.Where("store_id = ? OR revert_store_id = ?", m.StoreId, m.StoreId) - } - if !m.StartTime.IsZero() { // 共有 - fmt.Println("起始时间:", m.StartTime.Unix()) - qs = qs.Where("created_at > ?", m.StartTime) - } - if !m.EndTime.IsZero() { // 共有 - fmt.Println("时间:", m.StartTime.Unix()) - qs = qs.Where("created_at < ?", m.EndTime) - } - - err := qs.Find(&orderCards).Error - if err != nil { - logger.Error("err:", logger.Field("err", err)) - return nil, 0, err - } - - orderIds := make([]uint32, 0) - for i, _ := range orderCards { - orderIds = append(orderIds, orderCards[i].OrderId) - } - - orderQs := orm.Eloquent.Table("order").Where("pay_status", 2).Where("id in (?)", orderIds) + // 统计总数(订单数) var count int64 - err = orderQs.Count(&count).Error + err := cardQs.Count(&count).Error if err != nil { - logger.Errorf("err:", logger.Field("err", err)) + logger.Error("统计订单数量失败:", logger.Field("err", err)) return nil, 0, err } + if count == 0 { + return []Order{}, 0, nil + } + // 分页参数 page := m.Page pageSize := m.PageSize - page -= 1 - if page < 0 { - page = 0 + if page < 1 { + page = 1 + } + offset := (page - 1) * pageSize + + // 查询分页的 order_id(distinct 结果) + cardQs = cardQs.Order("order_id DESC") + if exportFlag == 0 { + cardQs = cardQs.Offset(offset).Limit(pageSize) + } + err = cardQs.Pluck("order_id", &orderIds).Error + if err != nil { + logger.Error("分页查询 order_card 失败:", logger.Field("err", err)) + return nil, 0, err } - if exportFlag == 1 { //一次性导出excel - orderQs = orderQs.Preload("User").Order("created_at DESC") - } else { - orderQs = orderQs.Preload("User").Order("created_at DESC").Offset(page * pageSize).Limit(pageSize) + if len(orderIds) == 0 { + return []Order{}, count, nil } + + // 查询订单 + orderQs := orm.Eloquent.Table("order"). + Where("pay_status = ?", 2). + Where("id IN (?)", orderIds). + Preload("User"). + Order("created_at DESC") + err = orderQs.Find(&orders).Error if err != nil { - logger.Errorf("err:", logger.Field("err", err)) + logger.Error("查询 order 失败:", logger.Field("err", err)) return nil, 0, err } - ids := make([]uint32, 0, len(orders)) - for i, _ := range orders { - ids = append(ids, uint32(orders[i].ID)) - } - if len(ids) == 0 { - logger.Error("gameIds is nil") - return nil, 0, err + // 反查关联的卡片 + var orderCards []OrderCard + if m.CardStatus == OrderCardStatusCompleted { + err = orm.Eloquent.Table("order_card"). + Where("order_id IN (?) AND card_status IN (?)", orderIds, []int{OrderCardStatusCompleted, OrderCardStatusSystemReturn}). + Find(&orderCards).Error + } else { + err = orm.Eloquent.Table("order_card"). + Where("order_id IN (?) AND card_status = ?", orderIds, m.CardStatus). + Find(&orderCards).Error } - err = orm.Eloquent.Table("order_card").Where("order_id in (?)", ids).Find(&orderCards).Error if err != nil { - logger.Error("err:", logger.Field("err", err)) + logger.Error("查询 order_card 失败:", logger.Field("err", err)) return nil, 0, err } + orderCards = OrderCardListSetGameInfo(orderCards) - orderCardsMap := make(map[uint32][]OrderCard, 0) - for i, _ := range orderCards { - if orderCards[i].CardStatus == m.CardStatus { //卡片状态相同的租卡订单才返回,方便财务导出数据 - orderCardsMap[orderCards[i].OrderId] = append(orderCardsMap[orderCards[i].OrderId], orderCards[i]) + + // 绑定卡片到订单 + orderCardsMap := make(map[uint32][]OrderCard) + for _, oc := range orderCards { + if oc.CardStatus == OrderCardStatusSystemReturn { + oc.CardStatus = OrderCardStatusCompleted } + orderCardsMap[oc.OrderId] = append(orderCardsMap[oc.OrderId], oc) } - for i, _ := range orders { - //2023-12-12 跟产品讨论后确认状态按原来的5种进行展示 - //if orders[i].CardStatus == 2 || orders[i].CardStatus == 3 { - // orders[i].CardStatus = 4 - //} - v, ok := orderCardsMap[orders[i].ID] - if ok { + + for i := range orders { + if v, ok := orderCardsMap[orders[i].ID]; ok { orders[i].OrderCards = v } } @@ -495,6 +644,9 @@ func (m *OrderListReq) queryListFormOrder(exportFlag int, c *gin.Context) ([]Ord orderCards = OrderCardListSetGameInfo(orderCards) orderCardsMap := make(map[uint32][]OrderCard, 0) for i, _ := range orderCards { + if orderCards[i].CardStatus == OrderCardStatusSystemReturn { + orderCards[i].CardStatus = OrderCardStatusCompleted + } orderCardsMap[orderCards[i].OrderId] = append(orderCardsMap[orderCards[i].OrderId], orderCards[i]) } for i, _ := range orders { @@ -1094,6 +1246,13 @@ func (m *Order) Revert() error { logger.Error("order store id not game card goods store id") return errors.New("order store id not game card goods store id") } + + // 判断是否有超期还卡标志 + cardStatusFlag := OrderCardStatusCompleted + if m.OverdueFlag == 1 { + cardStatusFlag = OrderCardStatusSystemReturn + } + begin := orm.Eloquent.Begin() var eg errgroup.Group //eg.Go(func() error { @@ -1226,7 +1385,7 @@ func (m *Order) Revert() error { if m.RevertExpressNo != "" { // 物流单号不为空则记录到数据库;2024/2/1 产品新需求,解决用户物流归还但小程序不提交归还信息,店员要输入手机号的问题 err = begin.Table("order_card").Where("id=?", orderCard.ID).Updates(&map[string]interface{}{ //"store_id": m.StoreId, - "card_status": OrderCardStatusCompleted, + "card_status": cardStatusFlag, "revert_store_id": m.RevertStoreId, "revert_time": time.Now(), "revert_shopper_code": m.RevertShopperCode, @@ -1239,7 +1398,7 @@ func (m *Order) Revert() error { } else { err = begin.Table("order_card").Where("id=?", orderCard.ID).Updates(&map[string]interface{}{ //"store_id": m.StoreId, - "card_status": OrderCardStatusCompleted, + "card_status": cardStatusFlag, "revert_store_id": m.RevertStoreId, "revert_time": time.Now(), "revert_shopper_code": m.RevertShopperCode, @@ -1281,7 +1440,21 @@ func (m *Order) Revert() error { } return nil }) - //orderCard.StoreId + if m.OverdueFlag == 1 { // 押金清零 + eg.Go(func() error { + sql := fmt.Sprintf( + "UPDATE user SET deposit = 0, mark = 1 WHERE uid =%d;", + orderCard.Uid) + fmt.Println("sql:", sql) + err = begin.Exec(sql).Error + if err != nil { + logger.Errorf("err:", logger.Field("err", err)) + return err + } + return nil + }) + } + err = eg.Wait() if err != nil { logger.Errorf("err:", logger.Field("err", err))