// Copyright 2019 getensh.com. All rights reserved. // Use of this source code is governed by getensh.com. package charge import ( "context" "encoding/json" "fmt" gid "git.getensh.com/common/gopkgs/id" "property-garden/errors" "property-garden/impl/v1/charge_utils" dbmodel "property-garden/model" pb_v1 "property-garden/pb/v1" "property-garden/utils" "strings" "time" "git.getensh.com/common/gopkgs/database" "git.getensh.com/common/gopkgs/logger" "go.uber.org/zap" "google.golang.org/grpc/status" ) func checkChargeBillPayParam(req *pb_v1.ChargeBillPayRequest) error { switch { case req.GardenId == 0: return status.Error(10003, "小区不能为空") case req.PayType == 0: return status.Error(10003, "缴费方式不能为空") case req.ShouldPayAmount == 0: return status.Error(10003, "应缴金额不能为空") case req.PayAmount == 0: return status.Error(10003, "实缴金额不能为空") case len(req.BillIds) == 0 && len(req.BindIds) == 0: return status.Error(10003, "缴费对象不能为空") } return nil } func chargeBillPayByBindIds(req *pb_v1.ChargeBillPayRequest, dbname string) (reply *pb_v1.ChargeBillPayReply, err error) { reply = &pb_v1.ChargeBillPayReply{} bill := dbmodel.NewChargeBill(dbname) where := map[string]interface{}{ "charge_bind_id in": req.BindIds, } chargeInfoM, err := charge_utils.GetAllChargeInfos(dbname) if err != nil { return nil, err } db := database.DB().Begin() defer func() { if err != nil { db.Rollback() } }() list, err := bill.List(db, where, nil, -1, -1, "") if err != nil { return nil, errors.DataBaseError } amount := int64(0) billIds := []string{} billIdsInt := []int64{} objName := "" orders := []string{} for i, v := range list { objName = v.ObjName chargeInfo := chargeInfoM[v.ChargeId] billIdsInt = append(billIdsInt, v.ID) amount += v.Amount list[i].LateFee, _ = charge_utils.GetLateFee(v.Amount, v.ChargeEnd, &chargeInfo) amount += list[i].LateFee if v.OrderId != "" { orders = append(orders, v.OrderId) } } isPaying := false isPaying, err = charge_utils.IsOrderPaying(orders, dbname, db) if err != nil { return nil, err } if isPaying { return nil, status.Error(10003, "无法支付,有订单正在支付中") } if amount != req.ShouldPayAmount { return nil, status.Error(10003, "应缴错误") } if req.ShouldPayAmount != req.PayAmount && req.Comment == "" { //return nil, status.Error(10003, "应缴金额与实缴金额不一致,需添加备注") } //生成订单 orderId, err := GenerateOrderId(req.GardenId, OrderTypeLife) if err != nil { return nil, err } now := time.Now() for i, _ := range list { list[i].ID = 0 list[i].Comment = req.Comment list[i].PayTime = now.Unix() list[i].PayMode = 1 list[i].OrderId = orderId list[i].PayType = req.PayType list[i].Status = charge_utils.PayStatusPayed } bill.SetTablePayed(dbname) err = bill.InsertMulti(db, &list) if err != nil { return nil, errors.DataBaseError } for _, v := range list { billIds = append(billIds, fmt.Sprintf("%v", v.ID)) } order := dbmodel.TChargeOrder{ OrderId: orderId, Comment: req.Comment, Amount: req.ShouldPayAmount, PayAmount: req.PayAmount, PayType: req.PayType, CreatedAt: now, Uid: 0, PackageId: 0, PrepayId: "", TransactionId: "", Status: charge_utils.PayStatusPayed, PayingDesc: "生活缴费", PayTime: now.Unix(), BillIds: strings.Join(billIds, ","), ObjName: objName, } order.SetTable(dbname) err = order.Insert(db) if err != nil { return nil, errors.DataBaseError } bill.SetTable(dbname) where = map[string]interface{}{ "id in": billIdsInt, } err = bill.Delete(db, where) if err != nil { return nil, errors.DataBaseError } if err = charge_utils.CompanyDealIncrease(req.GardenId, order.PayAmount, order.PayTime); err != nil { return nil, err } db.Commit() reply.OrderId = orderId return reply, nil } func chargeBillPayByBillIds(req *pb_v1.ChargeBillPayRequest, dbname string) (reply *pb_v1.ChargeBillPayReply, err error) { reply = &pb_v1.ChargeBillPayReply{} chargeInfoM, err := charge_utils.GetAllChargeInfos(dbname) if err != nil { return nil, err } bill := dbmodel.NewChargeBill(dbname) where := map[string]interface{}{ "id in": req.BillIds, } db := database.DB().Begin() defer func() { if err != nil { db.Rollback() } }() list, err := bill.List(db, where, nil, -1, -1, "") if err != nil { return nil, errors.DataBaseError } if len(list) == 0 { return nil, status.Error(10003, "没有账单") } amount := int64(0) billIds := []string{} orders := []string{} for i, v := range list { chargeInfo := chargeInfoM[v.ChargeId] amount += v.Amount list[i].LateFee, _ = charge_utils.GetLateFee(v.Amount, v.ChargeEnd, &chargeInfo) amount += list[i].LateFee if v.OrderId != "" { orders = append(orders, v.OrderId) } } isPaying := false isPaying, err = charge_utils.IsOrderPaying(orders, dbname, db) if err != nil { return nil, err } if isPaying { return nil, status.Error(10003, "无法支付,有订单正在支付中") } if amount != req.ShouldPayAmount { return nil, status.Error(10003, "应缴错误") } if req.ShouldPayAmount != req.PayAmount && req.Comment == "" { //return nil, status.Error(10003, "应缴金额与实缴金额不一致,需添加备注") } // 生成订单 orderId, err := GenerateOrderId(req.GardenId, OrderTypeLife) if err != nil { return nil, err } now := time.Now() for i, _ := range list { list[i].ID = 0 list[i].Comment = req.Comment list[i].PayTime = now.Unix() list[i].PayMode = 1 list[i].OrderId = orderId list[i].PayType = req.PayType list[i].Status = charge_utils.PayStatusPayed } bill.SetTablePayed(dbname) err = bill.InsertMulti(db, &list) if err != nil { return nil, errors.DataBaseError } for _, v := range list { billIds = append(billIds, fmt.Sprintf("%v", v.ID)) } order := dbmodel.TChargeOrder{ OrderId: orderId, Comment: req.Comment, Amount: req.ShouldPayAmount, PayAmount: req.PayAmount, PayType: req.PayType, CreatedAt: now, Uid: 0, PackageId: 0, PrepayId: "", TransactionId: "", Status: charge_utils.PayStatusPayed, PayingDesc: "生活缴费", PayTime: now.Unix(), BillIds: strings.Join(billIds, ","), ObjName: list[0].ObjName, } order.SetTable(dbname) err = order.Insert(db) if err != nil { return nil, errors.DataBaseError } bill.SetTable(dbname) where = map[string]interface{}{ "id in": req.BillIds, } err = bill.Delete(db, where) if err != nil { return nil, errors.DataBaseError } if err = charge_utils.CompanyDealIncrease(req.GardenId, order.PayAmount, order.PayTime); err != nil { return nil, err } db.Commit() reply.OrderId = orderId return reply, nil } const ( OrderTypeLife = 5 ) func GenerateOrderId(gardenId int64, orderType int) (string, error) { str := fmt.Sprintf("%d%07d-", orderType, gardenId) tmp, err := gid.GetUniqueID() if err != nil { return "", status.Error(10003, "订单号生成失败:"+err.Error()) } str += fmt.Sprintf("%d", tmp) return str, nil } func ChargeBillPay(ctx context.Context, req *pb_v1.ChargeBillPayRequest) (reply *pb_v1.ChargeBillPayReply, err error) { reply = &pb_v1.ChargeBillPayReply{} // 捕获各个task中的异常并返回给调用者 defer func() { if r := recover(); r != nil { err = fmt.Errorf("%+v", r) e := &status.Status{} if er := json.Unmarshal([]byte(err.Error()), e); er != nil { logger.Error("err", zap.String("system_err", err.Error()), zap.Stack("stacktrace")) } } }() // 参数检查 err = checkChargeBillPayParam(req) if err != nil { return nil, err } dbname := utils.GetGardenDbName(req.GardenId) if len(req.BillIds) > 0 { return chargeBillPayByBillIds(req, dbname) } return chargeBillPayByBindIds(req, dbname) }