package models import ( "errors" "fmt" "github.com/gin-gonic/gin" orm "go-admin/common/global" "go-admin/logger" "go-admin/tools" "gorm.io/gorm" "math/rand" "time" ) const ( ErpRepairOrderUnAudit = 1 // 待审核 ErpRepairOrderWaitRepair = 2 // 待送修 ErpRepairOrderBingRepaired = 3 // 维修中 ErpRepairOrderFinished = 4 // 已完成 ) type RepairRecord struct { Model SerialNumber string `json:"serial_number"` // 订单编号 Uid uint32 `json:"uid"` // 用户ID Tel string `json:"tel"` // 手机号 MemberLevel uint32 `json:"member_level"` // 会员等级:1-普通用户,6-尊享会员 StoreId uint32 `json:"store_id"` // 门店ID StoreName string `json:"store_name" gorm:"-"` // 门店名称 HandlerId uint32 `json:"handler_id"` // 经手人ID HandlerName string `json:"handler_name"` // 经手人名称 State uint8 `json:"state"` // 状态(1-待审核,2-待送修,3-维修中,4-已完成) MakerId uint32 `json:"maker_id"` // 制单人ID MakerName string `json:"maker_name"` // 制单人名称 MakerTime *time.Time `json:"maker_time"` // 制单时间 AuditorId uint32 `json:"auditor_id"` // 审核人ID AuditorName string `json:"auditor_name"` // 审核人名称 AuditTime *time.Time `json:"audit_time"` // 审核时间 SendTime *time.Time `json:"send_time"` // 送修时间 SendRemark string `json:"send_remark"` // 送修备注 ExpressNo string `json:"express_no"` // 快递单号 RepairUnitId uint32 `json:"repair_unit_id"` // 维修单位ID(供应商) RepairUnitName string `json:"repair_unit_name" gorm:"-"` // 维修单位名称(供应商) RepairFee float64 `json:"repair_fee"` // 维修费用 CompletedTime *time.Time `json:"completed_time"` // 完成时间 CompleteRemark string `json:"complete_remark"` // 完成备注 Commodities []RepairRecordCommodity `json:"commodities" gorm:"-"` // 维修商品信息 } type RepairRecordCommodity struct { Model RepairRecordId uint32 `json:"repair_record_id"` // 维修记录ID CommodityId uint32 `json:"commodity_id"` // 商品ID CommodityName string `json:"commodity_name" gorm:"-"` // 商品名称 OldIMEI string `json:"old_imei"` // 旧机器编码 NewIMEI string `json:"new_imei"` // 新机器编码 Count uint32 `json:"count"` // 数量 FaultImage string `json:"fault_image"` // 故障图片 FaultDesc string `json:"fault_desc"` // 故障描述 } type RepairCreateReq struct { Uid uint32 `json:"uid"` Tel string `json:"tel"` StoreId uint32 `json:"store_id" binding:"required"` HandlerId uint32 `json:"handler_id" binding:"required"` // 经手人id HandlerName string `json:"handler_name"` // 经手人名称 Commodities []RepairRecordCommodity `json:"commodities"` } type RepairEditReq struct { SerialNumber string `json:"serial_number" binding:"required"` // 订单编号 Uid uint32 `json:"uid"` // 用户ID Tel string `json:"tel"` // 手机号 MemberLevel uint32 `json:"member_level"` // 会员等级:普通用户、尊享会员 StoreId uint32 `json:"store_id" binding:"required"` // 门店ID HandlerId uint32 `json:"handler_id" binding:"required"` // 经手人ID HandlerName string `json:"handler_name"` // 经手人名称 State uint8 `json:"state"` // 状态(1-待审核,2-已审核,3-维修中,4-已完成) MakerId uint32 `json:"maker_id" binding:"required"` // 制单人ID MakerName string `json:"maker_name"` // 制单人名称 MakerTime *time.Time `json:"maker_time"` // 制单时间 AuditorId uint32 `json:"auditor_id"` // 审核人ID AuditorName string `json:"auditor_name"` // 审核人名称 AuditTime *time.Time `json:"audit_time"` // 审核时间 SendTime *time.Time `json:"send_time"` // 送修时间 SendRemark string `json:"send_remark"` // 送修备注 ExpressNo string `json:"express_no"` // 快递单号 RepairUnitId uint32 `json:"repair_unit_id"` // 维修单位ID RepairFee float64 `json:"repair_fee"` // 维修费用 CompletedTime *time.Time `json:"completed_time"` // 完成时间 CompleteRemark string `json:"complete_remark"` // 完成备注 Commodities []RepairRecordCommodity `json:"commodities"` } // ErpRepairDeleteReq 删除维修订单入参 type ErpRepairDeleteReq struct { SerialNumber string `json:"serial_number" binding:"required"` // 单据编号 } // ErpRepairOrderListReq 查询维修订单列表入参 type ErpRepairOrderListReq struct { SerialNumber string `json:"serial_number"` // 单据编号 Uid uint32 `json:"uid"` // 用户ID Tel string `json:"tel"` // 手机号 MemberLevel uint32 `json:"member_level"` // 会员等级:普通用户、尊享会员 StoreId []uint32 `json:"store_id"` // 门店id HandlerId uint32 `json:"handler_id"` // 经手人id State []uint32 `json:"state"` // 状态:1-待审核,2-已审核,3-维修中,4-已完成 MakeTimeStart string `json:"make_time_start"` // 制单开始时间 MakeTimeEnd string `json:"make_time_end"` // 制单结束时间 AuditTimeStart string `json:"audit_time_start"` // 审核开始时间 AuditTimeEnd string `json:"audit_time_end"` // 审核结束时间 SendTimeStart string `json:"send_time_start"` // 送修开始时间 SendTimeEnd string `json:"send_time_end"` // 送修结束时间 CompleteTimeStart string `json:"complete_time_start"` // 维修完成开始时间 CompleteTimeEnd string `json:"complete_time_end"` // 维修完成结束时间 PageIndex int `json:"pageIndex"` // 页码 PageSize int `json:"pageSize"` // 页面条数 } // ErpRepairOrderListResp 查询维修订单列表出参 type ErpRepairOrderListResp struct { List []RepairRecord `json:"list"` Total int `json:"total"` // 总条数 PageIndex int `json:"pageIndex"` // 页码 PageSize int `json:"pageSize"` // 页面条数 } // ErpRepairDetailReq 查询维修订单详情入参 type ErpRepairDetailReq struct { SerialNumber string `json:"serial_number" binding:"required"` // 单据编号 } // ErpRepairAuditReq 审核维修订单入参 type ErpRepairAuditReq struct { SerialNumber string `json:"serial_number" binding:"required"` // 单据编号 State int `json:"state" binding:"required"` // 审核操作: 1-审核 2-取消审核 } // ErpRepairSendReq 维修订单送修入参 type ErpRepairSendReq struct { SerialNumber string `json:"serial_number" binding:"required"` // 单据编号 RepairUnitId uint32 `json:"repair_unit_id" binding:"required"` // 维修单位ID(供应商) ExpressNo string `json:"express_no"` // 快递单号 SendRemark string `json:"send_remark"` // 送修备注 } // ErpRepairCompleteReq 维修订单完成入参 type ErpRepairCompleteReq struct { SerialNumber string `json:"serial_number" binding:"required"` // 单据编号 RepairFee float64 `json:"repair_fee"` // 维修费用 CompleteRemark string `json:"complete_remark"` // 完成备注 } // NewRepairBillSn 生成维修订单号 func NewRepairBillSn() string { nowTime := time.Now() rand.Seed(nowTime.UnixNano()) max := 1 for { if max > 5 { logger.Error("create sn err") return "" } random := rand.Int31n(9999) + 1000 sn := fmt.Sprintf("wx%s%d", nowTime.Format("060102"), random) exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM repair_record WHERE serial_number='%s'", sn)) if err != nil { logger.Error("exist sn err") } if !exist { return sn } max++ } } // CreateRepairOrder 创建维修订单 func CreateRepairOrder(req *RepairCreateReq, sysUser *SysUser) (*RepairRecord, error) { // 开始事务 tx := orm.Eloquent.Begin() defer func() { if r := recover(); r != nil { tx.Rollback() return } }() userMemberLevel := 1 // 判断是否为尊享会员 if IsValidPrivilegeMember(req.Uid) { userMemberLevel = 6 } nowTime := time.Now() // 写入主表 repair := RepairRecord{ SerialNumber: NewRepairBillSn(), Uid: req.Uid, Tel: req.Tel, MemberLevel: uint32(userMemberLevel), StoreId: req.StoreId, HandlerId: req.HandlerId, HandlerName: req.HandlerName, MakerId: uint32(sysUser.UserId), MakerName: sysUser.NickName, MakerTime: &nowTime, State: ErpRepairOrderUnAudit, // 初始状态:待审核 } if err := tx.Create(&repair).Error; err != nil { tx.Rollback() logger.Error("Create RepairRecord err:", logger.Field("err", err)) return nil, err } // 写入子表 for _, com := range req.Commodities { item := RepairRecordCommodity{ RepairRecordId: repair.ID, CommodityId: com.CommodityId, CommodityName: com.CommodityName, OldIMEI: com.OldIMEI, NewIMEI: com.NewIMEI, Count: com.Count, FaultImage: com.FaultImage, FaultDesc: com.FaultDesc, } if err := tx.Create(&item).Error; err != nil { tx.Rollback() logger.Error("Create RepairCommodity err:", logger.Field("err", err)) return nil, err } } if err := tx.Commit().Error; err != nil { tx.Rollback() logger.Error("commit err:", logger.Field("err", err)) return nil, err } repair.Commodities = req.Commodities return &repair, nil } // EditRepairOrder 编辑维修订单 func EditRepairOrder(req *RepairEditReq, sysUser *SysUser) (*RepairRecord, error) { // 查询订单信息 var repairOrder RepairRecord err := orm.Eloquent.Table("repair_record").Where("serial_number=?", req.SerialNumber).Find(&repairOrder).Error if err != nil { logger.Error("repair order err:", logger.Field("err", err)) return nil, err } if repairOrder.State != ErpRepairOrderUnAudit { // 只有待审核的订单才能编辑 return nil, errors.New("订单不是待审核状态") } begin := orm.Eloquent.Begin() // 1-更新维修订单信息 repairOrder.Uid = req.Uid repairOrder.Tel = req.Tel repairOrder.MemberLevel = req.MemberLevel repairOrder.StoreId = req.StoreId repairOrder.HandlerId = req.HandlerId repairOrder.HandlerName = req.HandlerName repairOrder.MakerId = uint32(sysUser.UserId) repairOrder.MakerName = sysUser.NickName err = begin.Model(&RepairRecord{}).Where("serial_number=?", req.SerialNumber). Omit("created_at").Save(repairOrder).Error if err != nil { begin.Rollback() logger.Error("update erp_order err:", logger.Field("err", err)) return nil, err } // 2-更新维修订单商品表 err = updateRepairCommodityData(begin, repairOrder.ID, req) if err != nil { begin.Rollback() logger.Error("update erp_purchase_commodity err:", logger.Field("err", err)) return nil, err } err = begin.Commit().Error if err != nil { begin.Rollback() logger.Error("commit err:", logger.Field("err", err)) return nil, err } return &repairOrder, nil } // updateRepairCommodityData 更新维修订单商品信息 func updateRepairCommodityData(gdb *gorm.DB, orderId uint32, req *RepairEditReq) error { // 查询现有的零售订单信息 var commodities []RepairRecordCommodity err := orm.Eloquent.Table("repair_record_commodity").Where("repair_record_id = ?", orderId).Find(&commodities).Error if err != nil { logger.Error("query repair_record_commodity err:", logger.Field("err", err)) return err } // 1-删除所有的商品信息 if len(commodities) != 0 { err = gdb.Delete(&commodities).Error if err != nil { logger.Error("更新商品订单信息-删除 error") return errors.New("操作失败:" + err.Error()) } } for i, _ := range req.Commodities { req.Commodities[i].ID = 0 if req.Commodities[i].RepairRecordId == 0 { //发现前端有时会没传,后端打补丁 req.Commodities[i].RepairRecordId = orderId } } // 2-更新商品订单信息-新增 if len(req.Commodities) != 0 { err = gdb.Create(&req.Commodities).Error if err != nil { logger.Error("更新商品订单信息-新增 error") return errors.New("操作失败:" + err.Error()) } } return nil } // List 查询采购订单列表 func (m *ErpRepairOrderListReq) List(c *gin.Context) (*ErpRepairOrderListResp, error) { resp := &ErpRepairOrderListResp{ PageIndex: m.PageIndex, PageSize: m.PageSize, } page := m.PageIndex - 1 if page < 0 { page = 0 } if m.PageSize == 0 { m.PageSize = 10 } qs := orm.Eloquent.Table("repair_record") if m.SerialNumber != "" { qs = qs.Where("serial_number = ?", m.SerialNumber) } else if m.Uid != 0 { qs = qs.Where("uid = ?", m.Uid) } else if m.Tel != "" { qs = qs.Where("tel = ?", m.Tel) } else { if len(m.StoreId) != 0 { qs = qs.Where("store_id in ?", m.StoreId) } // 非管理员才判断所属门店 if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") { sysUser, err := GetSysUserByCtx(c) if err != nil { return nil, errors.New("操作失败:" + err.Error()) } // 返回sysUser未过期的门店id列表 storeList := GetValidStoreIDs(sysUser.StoreData) if len(storeList) > 0 { if len(storeList) == 1 { qs = qs.Where("store_id = ?", storeList[0]) } else { qs = qs.Where("store_id IN (?)", storeList) } } else { return nil, errors.New("用户未绑定门店") } } if m.MemberLevel != 0 { qs = qs.Where("member_level = ?", m.MemberLevel) } if len(m.State) > 0 { qs = qs.Where("state IN (?)", m.State) } if m.HandlerId != 0 { qs = qs.Where("handler_id=?", m.HandlerId) } if m.AuditTimeStart != "" { parse, err := time.Parse(QueryTimeFormat, m.AuditTimeStart) if err != nil { logger.Errorf("erpRepairOrderList err:", err) return nil, err } qs = qs.Where("audit_time > ?", parse) } if m.AuditTimeEnd != "" { parse, err := time.Parse(QueryTimeFormat, m.AuditTimeEnd) if err != nil { logger.Errorf("erpRepairOrderList err:", err) return nil, err } //parse = parse.AddDate(0, 0, 1) qs = qs.Where("audit_time < ?", parse) } if m.MakeTimeStart != "" { parse, err := time.Parse(QueryTimeFormat, m.MakeTimeStart) if err != nil { logger.Errorf("err:", err) } qs = qs.Where("maker_time > ?", parse) } if m.MakeTimeEnd != "" { parse, err := time.Parse(QueryTimeFormat, m.MakeTimeEnd) if err != nil { logger.Errorf("err:", err) } qs = qs.Where("maker_time < ?", parse) } if m.SendTimeStart != "" { parse, err := time.Parse(QueryTimeFormat, m.SendTimeStart) if err != nil { logger.Errorf("err:", err) } qs = qs.Where("send_time > ?", parse) } if m.SendTimeEnd != "" { parse, err := time.Parse(QueryTimeFormat, m.SendTimeEnd) if err != nil { logger.Errorf("err:", err) } qs = qs.Where("send_time < ?", parse) } if m.CompleteTimeStart != "" { parse, err := time.Parse(QueryTimeFormat, m.CompleteTimeStart) if err != nil { logger.Errorf("err:", err) } qs = qs.Where("complete_time > ?", parse) } if m.CompleteTimeEnd != "" { parse, err := time.Parse(QueryTimeFormat, m.CompleteTimeEnd) if err != nil { logger.Errorf("err:", err) } qs = qs.Where("complete_time < ?", parse) } } var count int64 err := qs.Count(&count).Error if err != nil { logger.Error("count err:", logger.Field("err", err)) return resp, err } resp.Total = int(count) var orders []RepairRecord err = qs.Order("id DESC").Offset(page * m.PageSize).Limit(m.PageSize).Find(&orders).Error if err != nil && err != RecordNotFound { logger.Error("erp commodity list err:", logger.Field("err", err)) return resp, err } // 校验时间,如果为01-01-01 08:05,则赋值为空 for i, v := range orders { if v.MakerTime != nil && v.MakerTime.IsZero() { orders[i].MakerTime = nil } if v.AuditTime != nil && v.AuditTime.IsZero() { orders[i].AuditTime = nil } if v.SendTime != nil && v.SendTime.IsZero() { orders[i].SendTime = nil } if v.CompletedTime != nil && v.CompletedTime.IsZero() { orders[i].CompletedTime = nil } } resp.List = orders return resp, nil } // SendToRepair 维修订单送修 func SendToRepair(req *ErpRepairSendReq, c *gin.Context) error { // 查询订单信息 var repairRecord RepairRecord err := orm.Eloquent.Table("repair_record").Where("serial_number = ?", req.SerialNumber). Find(&repairRecord).Error if err != nil { logger.Error("order err:", logger.Field("err", err)) return err } sysUser, err := GetSysUserByCtx(c) if err != nil { logger.Error("sys user err:", logger.Field("err", err)) return err } // 校验入参门店是否包含在用户所有门店中,是否过期 if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") { if !CheckUserStore(repairRecord.StoreId, sysUser) { return errors.New("操作失败:您没有该门店权限") } } if repairRecord.ID == 0 { return errors.New("未查询到订单信息") } if repairRecord.State != ErpRepairOrderWaitRepair { return errors.New("订单不是待送修状态") } nowTime := time.Now() repairRecord.RepairUnitId = req.RepairUnitId repairRecord.ExpressNo = req.ExpressNo repairRecord.SendRemark = req.SendRemark repairRecord.State = ErpRepairOrderBingRepaired repairRecord.SendTime = &nowTime err = orm.Eloquent.Model(&RepairRecord{}).Where("id = ?", repairRecord.ID). Updates(repairRecord).Error if err != nil { return err } return nil } // CompleteRepairOrder 维修订单完成 func CompleteRepairOrder(req *ErpRepairCompleteReq, c *gin.Context) error { // 查询订单信息 var repairRecord RepairRecord err := orm.Eloquent.Table("repair_record").Where("serial_number = ?", req.SerialNumber). Find(&repairRecord).Error if err != nil { logger.Error("order err:", logger.Field("err", err)) return err } sysUser, err := GetSysUserByCtx(c) if err != nil { logger.Error("sys user err:", logger.Field("err", err)) return err } // 校验入参门店是否包含在用户所有门店中,是否过期 if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") { if !CheckUserStore(repairRecord.StoreId, sysUser) { return errors.New("操作失败:您没有该门店权限") } } if repairRecord.ID == 0 { return errors.New("未查询到订单信息") } if repairRecord.State != ErpRepairOrderBingRepaired { return errors.New("订单不是待送修状态") } nowTime := time.Now() repairRecord.RepairFee = req.RepairFee repairRecord.CompleteRemark = req.CompleteRemark repairRecord.State = ErpRepairOrderFinished repairRecord.CompletedTime = &nowTime err = orm.Eloquent.Model(&RepairRecord{}).Where("id = ?", repairRecord.ID). Updates(repairRecord).Error if err != nil { return err } return nil }