package controller import ( . "app.yhyue.com/moapp/jybase/api" "app.yhyue.com/moapp/jybase/common" "app.yhyue.com/moapp/jybase/date" "context" "fmt" "github.com/gogf/gf/v2/database/gdb" "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/net/ghttp" "github.com/gogf/gf/v2/util/gconv" "github.com/pkg/errors" "jyOrderManager/internal/jyutil" "jyOrderManager/internal/logic/order" "jyOrderManager/internal/logic/product" "jyOrderManager/internal/model" "jyOrderManager/internal/service" "strings" "time" ) var checkOrderProduct = func(ctx context.Context, orderCode string, param model.OrderParams, oldOrderRes ...g.Map) (productArr []product.JyProduct, removeOrderDetailIds []int64, masterKey string, priceFinal, priceOriginal, commissionCheck int, err error) { var ( actProduct = map[string]map[string]product.JyProduct{} orderMap g.Map existsOrderDetailIds = map[int64]bool{} update = false ) if len(oldOrderRes) > 0 { orderMap, update = oldOrderRes[0], true } // 订单参数基础校验 if param.EmptyPhone != 1 && param.PersonPhone == "" { err = fmt.Errorf("订单参数异常") return } if update { //待审核和已完成订单禁止修改 var orderDetailRes gdb.Result orderDetailRes, err = g.DB().Query(ctx, "SELECT id FROM jy_order_detail WHERE order_code=? and status =1", param.OrderCode) if err != nil || orderDetailRes.IsEmpty() { err = gerror.Wrapf(err, "为查询到订单明细") return } var ( orderStatus = gconv.Int(orderMap["order_status"]) auditStatus = gconv.Int(orderMap["audit_status"]) ) if auditStatus > 0 || orderStatus == 1 { err = errors.New("当前订单状态禁止修改") return } for _, m := range orderDetailRes.List() { existsOrderDetailIds[gconv.Int64(m["id"])] = true } } var ( maxPrice int ) //大会员超级订阅同订单不能多次购买 hasVipCheckMap := map[string]bool{} for _, tParam := range param.ProductArr { orderDetailId := gconv.Int64(tParam["id"]) if update { existsOrderDetailIds[orderDetailId] = false } //参数注入 if param.EmptyPhone != 1 { tParam["phone"] = param.PersonPhone //开通手机号 } tParam["order_code"] = orderCode //订单号 tParam["reqSubject"] = param.BuySubject //购买主体 tParam["reqCompanyName"] = param.CompanyName //公司名称 var ( productCode = gconv.String(tParam["product_code"]) amount = gconv.Int(tParam["amount"]) originalPrice = gconv.Int(tParam["original_price"]) ) productClass, pErr := service.Product().GetProductClassByProductCode(productCode) if pErr != nil { err = fmt.Errorf("请勿重复选购会员商品") return } if productClass.Code == "dyh" || productClass.Code == "cjdy" { if hasVipCheckMap[productClass.Code] { err = fmt.Errorf("请勿重复选购会员商品") return } hasVipCheckMap[productClass.Code] = true } //计算销售费用 if productClass.TopClass == "外采赠品" { commissionCheck += originalPrice } pFunc, pErr := product.JyProFunc.GetProductInitFuncByCode(productCode) if pErr != nil { err = gerror.Wrapf(pErr, "获取商品异常") return } pObj, pErr := pFunc(tParam) if pErr != nil { err = gerror.Wrap(pErr, fmt.Sprintf("获取%s商品异常", productCode)) return } //获取价格最贵的商品作为主商品 if amount > maxPrice { maxPrice = amount masterKey = fmt.Sprintf("%s_%d", productCode, amount) } var ( actCode = gconv.String(tParam["activityCode"]) //活动code checkCode = common.If(common.If(actCode != "", 2, 1).(int) == 2 || param.EmptyPhone == 1, 2, 1).(int) //1全额校验 2不校验是否满足购买需求(活动和暂无手机号) ) if actCode != "" { //活动商品 if _, ok := actProduct[actCode]; ok { actProduct[actCode][productCode] = pObj } else { actProduct[actCode] = map[string]product.JyProduct{productCode: pObj} } } else { //单个商品价格 if originalPrice := gconv.Int(originalPrice); originalPrice > 0 { priceOriginal += originalPrice } if amount > 0 { priceFinal += amount } } if err = pObj.Check(ctx, checkCode); err != nil { return } productArr = append(productArr, pObj) } if len(productArr) == 0 { err = fmt.Errorf("订单商品为空") return } // 活动商品校验完整,防止缺少增加商品 if len(actProduct) > 0 { now := time.Now() for actCode, productList := range actProduct { act := service.Product().GetActivityByCode(actCode) //当前用户是否有权限 if !service.Product().PowerCheck(act.Code, jyutil.GetUserDeptIdFromCtx(ctx)) { err = fmt.Errorf("没有创建%s活动的权限", act.Name) return } if act == nil { err = fmt.Errorf("未知活动code %s", actCode) return } if now.After(act.EndTime) || now.Before(act.StartTime) { err = fmt.Errorf("活动%s不在有效期", actCode) return } if len(productList) != len(act.Products) { err = fmt.Errorf("活动产品不完整 %s", actCode) return } if act.Price > 0 { priceOriginal += act.Price } if param.ActPrice["actCode"] > 0 { priceFinal += param.ActPrice["actCode"] } } } for orderDetailId, ok := range existsOrderDetailIds { if ok { removeOrderDetailIds = append(removeOrderDetailIds, orderDetailId) } } return } // SaveOrderHandler 创建订单 func SaveOrderHandler(r *ghttp.Request) { rData, err := func() (interface{}, error) { var ( param model.OrderParams ctx = r.Context() uMsg = jyutil.GetUserMsgFromCtx(ctx) userName = uMsg.EntUserName entUserId = uMsg.EntUserId masterKey string priceFinal, priceOriginal, commissionCheck int productArr []product.JyProduct orderCode = fmt.Sprintf("%s%s", time.Now().Format("150405"), common.GetRandom(6)) ) err := gconv.Struct(r.GetBody(), ¶m) if err != nil { return nil, gerror.Wrapf(err, "数据校验异常") } //产品参数校验 productArr, _, masterKey, priceFinal, priceOriginal, commissionCheck, err = checkOrderProduct(ctx, orderCode, param) if err != nil { return nil, err } if priceFinal != param.ContractMoney || priceOriginal != param.OrderMoney { return nil, fmt.Errorf("价格核对异常") } if commissionCheck != param.ChannelCommission { return nil, fmt.Errorf("销售费用合算异常") } //数据库操作 if err := g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error { //todo 插入订单表 if _, err := g.DB().Ctx(ctx).Insert(ctx, "dataexport_order", g.Map{ "order_code": orderCode, "order_money": param.OrderMoney, "pay_money": param.ContractMoney, "pay_way": param.PayType, "product_type": getProductNameByMasterKey(masterKey), "order_status": 0, "user_phone": param.PersonPhone, "personPhone": param.ContactsPhone, "personName": param.ContactsName, "company_name": param.CompanyName, "is_backstage_order": 1, "commission": param.ChannelCommission, "order_channel": param.OrderChannel, "create_time": time.Now().Format("2006-01-02 15:04:05"), "create_person": userName, "last_update_person": userName, "salesperson_entUserId": entUserId, "signing_subject": param.PaybackCompany, "audit_status": common.If(param.Save == 1, 0, 1), "buy_subject": param.BuySubject, "payment_user": param.PaymentUser, "zero_type": param.ZeroOrderType, "remark": param.OrderRemark, "user_id": jyutil.GetCommonUserIdByPhone(ctx, param.PersonPhone, param.CompanyName, param.BuySubject), }); err != nil { return gerror.Wrap(err, "插入订单表异常") } //todo 订单详情表 for _, p := range productArr { //是否是主商品 if err := p.SaveUpdate(ctx, masterKey); err != nil { return gerror.Wrapf(err, "插入商品明细异常") } } //todo 销售业绩 if err := order.SaveOrUpdateSaleMoneyTmp(ctx, orderCode, userName, param.SaleMoney, param.ContractMoney-param.ChannelCommission); err != nil { return gerror.Wrapf(err, "销售业绩异常") } //todo 合同 if err := order.SaveOrUpdateContract(ctx, orderCode, param.CompanyName, param.ContractMoney, param.Contract); err != nil { return gerror.Wrapf(err, "合同异常") } //todo 回款计划 if err := order.SaveOrUpdateReturnPlant(ctx, orderCode, param.ContractMoney, param.ReturnPlant); err != nil { return gerror.Wrapf(err, "回款计划异常") } if param.Save == 2 { //todo 审核记录 if _, err = g.DB().Save(ctx, "audit_records", map[string]interface{}{ "operator": userName, "create_time": date.NowFormat(date.Date_Full_Layout), "operator_type": 1, "audit_status": 1, "order_code": orderCode, "audit_type": 2, }); err != nil { return gerror.Wrapf(err, "审核记录异常") } } return nil }); err != nil { return nil, gerror.Wrapf(err, "数据库操作异常") } return orderCode, nil }() if err != nil { g.Log().Errorf(r.Context(), "创建订单异常 %v", err) } r.Response.WriteJson(NewResult(rData, err)) } // UpdateOrderHandler 订单修改 func UpdateOrderHandler(r *ghttp.Request) { rData, err := func() (interface{}, error) { var ( param model.OrderParams ctx = r.Context() uMsg = jyutil.GetUserMsgFromCtx(ctx) userName = uMsg.EntUserName entUserId = uMsg.EntUserId masterKey string priceFinal, priceOriginal int ) err := gconv.Struct(r.GetBody(), ¶m) if err != nil { return nil, gerror.Wrapf(err, "数据校验异常") } if param.OrderCode == "" { return nil, gerror.New("缺少订单编号") } orderRes, err := g.DB().GetOne(ctx, "SELECT * FROM dataexport_order WHERE order_code=?", param.OrderCode) if err != nil || orderRes.IsEmpty() { err = gerror.Wrapf(err, "未知订单") return nil, err } //产品参数校验 productArr, removeIds, masterKey, priceFinal, priceOriginal, commissionCheck, err := checkOrderProduct(ctx, param.OrderCode, param, orderRes.Map()) if err != nil { return nil, err } if priceFinal != param.ContractMoney || priceOriginal != param.OrderMoney { return nil, fmt.Errorf("价格核对异常") } if commissionCheck != param.ChannelCommission { return nil, fmt.Errorf("销售费用合算异常") } //数据库操作 if err := g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error { var delDetailIds []string detailIds, _ := g.DB().Ctx(ctx).Query(ctx, "SELECT id FROM jy_order_detail WHERE order_code = ? and status =1", param.OrderCode) if !detailIds.IsEmpty() { //编辑订单存在删除老产品 for _, idMap := range detailIds.List() { var isExist bool for _, jyProduct := range param.ProductArr { if gconv.String(idMap["id"]) == gconv.String(jyProduct["id"]) { isExist = true break } } if !isExist { delDetailIds = append(delDetailIds, gconv.String(idMap["id"])) } } } upOrder := g.Map{ "order_money": param.OrderMoney, "pay_money": param.ContractMoney, "pay_way": param.PayType, "product_type": getProductNameByMasterKey(masterKey), "order_status": param.OrderStatus, "user_phone": param.PersonPhone, "company_name": param.CompanyName, "is_backstage_order": 1, "commission": param.ChannelCommission, "order_channel": param.OrderChannel, "create_person": userName, "last_update_person": userName, "salesperson_entUserId": entUserId, "signing_subject": param.PaybackCompany, "audit_status": common.If(param.Save == 1, 0, 1), "buy_subject": param.BuySubject, "payment_user": param.PaymentUser, "zero_type": param.ZeroOrderType, "remark": param.OrderRemark, "user_id": jyutil.GetCommonUserIdByPhone(ctx, param.PersonPhone, param.CompanyName, param.BuySubject), } //退回单子重新编辑提交后更改审核状态 if auditStatus := gconv.Int(orderRes.Map()["audit_status"]); auditStatus < 0 { upOrder["order_status"] = 0 upOrder["audit_status"] = SwitchAudit(auditStatus) } //编辑回退订单或未完成订单 if _, err = g.DB().Ctx(ctx).Update(ctx, "dataexport_order", upOrder, "order_code=? and order_status=0 ", param.OrderCode); err != nil { return gerror.Wrap(err, "修改订单表内容异常") } //todo 删除已经不存在的商品 for _, id := range removeIds { if _, err := g.DB().Update(ctx, "jy_order_detail", g.Map{ "status": 2, }, "id=? and order_code=?", id, param.OrderCode); err != nil { return gerror.Wrapf(err, "删除旧订单明细内容异常") } } //todo 订单详情表 for _, p := range productArr { if err := p.SaveUpdate(ctx, masterKey); err != nil { return gerror.Wrapf(err, "插入商品明细异常") } } //todo 销售业绩 p610.管理后台创建订单,订单状态为已完成(不包含从未完成改成已完成,未提交的状态),“销售人员”、“销售业绩”、“销售渠道”不支持编辑; if gconv.Int(orderRes["order_status"]) == 0 { err = order.SaveOrUpdateSaleMoneyTmp(ctx, param.OrderCode, userName, param.SaleMoney, param.ContractMoney-param.ChannelCommission) if err != nil { return err } } //todo 合同 if err := order.SaveOrUpdateContract(ctx, param.OrderCode, param.CompanyName, param.ContractMoney, param.Contract); err != nil { return gerror.Wrapf(err, "合同异常") } //todo 回款计划 if err := order.SaveOrUpdateReturnPlant(ctx, param.OrderCode, param.ContractMoney, param.ReturnPlant); err != nil { return gerror.Wrapf(err, "回款计划异常") } if len(delDetailIds) > 0 { //存在删除的订单 g.DB().Ctx(ctx).Update(ctx, "dataexport_order", map[string]interface{}{ "status": -1, }, fmt.Sprintf(" id in (%s)", strings.Join(delDetailIds, ","))) } return nil }); err != nil { return nil, gerror.Wrapf(err, "数据库操作异常") } return nil, err }() if err != nil { g.Log().Errorf(r.Context(), "订单修改异常 %v", err) } r.Response.WriteJson(NewResult(rData, err)) } // GetContractPdfHandler 电子pdf合同 func GetContractPdfHandler(r *ghttp.Request) { rData, err := func() (interface{}, error) { rj, err := r.GetJson() if err != nil { return nil, errors.Wrap(err, "请求参数格式异常") } var ( orderCode = rj.Get("orderCode").String() onlyQuery = rj.Get("onlyQuery").String() ctx = r.Context() uMsg = jyutil.GetUserMsgFromCtx(ctx) userName = uMsg.EntUserName ) pdfPath, err := order.GetContractPdf(ctx, orderCode, userName, onlyQuery != "") if err != nil { return nil, err } return pdfPath, nil }() if err != nil { g.Log().Errorf(r.Context(), "生成电子pdf合同出错 %v", err) } r.Response.WriteJson(NewResult(rData, err)) } func getProductNameByMasterKey(masterKey string) string { if arr := strings.Split(masterKey, "_"); len(arr) > 0 { var productCode = arr[0] mp, err := service.Product().GetProduct(productCode) if err != nil { return "" } mc, err := service.Product().GetProductClass(mp.ProductClassId) if err != nil { return "" } if mc.ClassName == "超级订阅" { return "VIP订阅" } return mc.ClassName } return "" } // 订单审核状态 const ( OrderUncommitted = 0 // 待提交 OrderPending = 1 // 待审核 OrderFirstPassed = 2 // 一审通过 OrderPassed = 3 // 审核通过 OrderSecondPassed = 4 // 审核通过 OrderFirstReturn = -2 // 一审退回 OrderSecondReturn = -3 // 二审退回 OrderThreeReturn = -4 // 二审退回 ) // SwitchAudit 订单审核轨迹状态流转 func SwitchAudit(auditStatus int) (saveAuditStatus int) { // 我的订单-编辑订单 只能编辑订单审核状态为已退回、待提交 不开通权限 switch auditStatus { case OrderUncommitted: saveAuditStatus = OrderPending // 待一审 case OrderFirstReturn: saveAuditStatus = OrderPending // 待一审 case OrderSecondReturn: saveAuditStatus = OrderFirstPassed // 一审通过 待二审 case OrderThreeReturn: //三审退回状态下,编辑订单后,审核状态是二审通过 saveAuditStatus = OrderSecondPassed // 一审通过 待二审 } return }