mh_goadmin_server/app/admin/models/repair.go

583 lines
20 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}