123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 |
- // Copyright 2019 getensh.com. All rights reserved.
- // Use of this source code is governed by getensh.com.
- package charge
- import (
- "context"
- "encoding/json"
- "fmt"
- "property-garden/errors"
- "property-garden/impl/v1/charge_utils"
- dbmodel "property-garden/model"
- "property-garden/pb"
- 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 checkChargeBillPayByHouseholdParam(req *pb_v1.ChargeBillPayByHouseholdRequest) 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, "缴费对象不能为空")
- case req.HouseholdUid == 0 && !req.Native:
- return status.Error(10003, "住户id不能为空")
- }
- return nil
- }
- func ThirdpartyPay(openId string, inputIp string, amount int64, orderId string, product string, mchid string, native bool) (string, string, string, error) {
- mreq := pb_v1.WxAppletPrepayRequest{
- Order: orderId,
- Product: product,
- OpenId: openId,
- Amount: amount,
- InputIp: inputIp,
- MchId: mchid,
- Native: native,
- }
- mreply, err := pb.Thirdparty.WxAppletPrepay(context.Background(), &mreq)
- if err != nil {
- return "", "", "", err
- }
- return mreply.PrepayId, mreply.Prepay, mreply.CodeUrl, nil
- }
- func householdChargeBillPayByBindIds(req *pb_v1.ChargeBillPayByHouseholdRequest, dbname string, mchId string) (reply *pb_v1.ChargeBillPayByHouseholdReply, err error) {
- reply = &pb_v1.ChargeBillPayByHouseholdReply{}
- 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 := ""
- productM := map[string]bool{}
- lateFeeBool := false
- orders := []string{}
- for i, v := range list {
- billIds = append(billIds, fmt.Sprintf("%v", v.ID))
- productM[charge_utils.ChargeTypeM[v.ChargeType]] = true
- 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 list[i].LateFee > 0 {
- lateFeeBool = true
- }
- 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, "无法支付,有订单正在支付中")
- }
- product := ""
- for k, _ := range productM {
- product = product + k + ";"
- }
- 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
- }
- //调用三方预支付
- thirdPrepayId, thirdPrepayInfo, codeUrl, err := ThirdpartyPay(req.OpenId, req.InputIp, req.ShouldPayAmount, orderId, product, mchId, req.Native)
- if err != nil {
- return nil, err
- }
- // 更新订单状态
- now := time.Now()
- values := map[string]interface{}{
- "comment": req.Comment,
- "pay_time": now.Unix(),
- "pay_mode": 1,
- "uid": req.HouseholdUid,
- "order_id": orderId,
- "pay_type": req.PayType,
- "status": charge_utils.PayStatusUnPay,
- }
- // 没有滞纳金批量更新
- if !lateFeeBool {
- bill.SetTable(dbname)
- err = bill.Update(db, where, values)
- if err != nil {
- return nil, errors.DataBaseError
- }
- } else {
- // 有滞纳金逐个更新
- for _, v := range list {
- values["late_fee"] = v.LateFee
- where = map[string]interface{}{
- "id": v.ID,
- }
- bill.SetTable(dbname)
- err = bill.Update(db, where, values)
- if err != nil {
- return nil, errors.DataBaseError
- }
- }
- }
- // 插入订单
- order := dbmodel.TChargeOrder{
- OrderId: orderId,
- Comment: req.Comment,
- Amount: req.ShouldPayAmount,
- PayAmount: req.PayAmount,
- PayType: req.PayType,
- CreatedAt: now,
- Uid: req.HouseholdUid,
- PackageId: 0,
- PrepayId: thirdPrepayId,
- TransactionId: "",
- Status: charge_utils.PayStatusUnPay,
- PayingDesc: "生活缴费",
- PayTime: now.Unix(),
- BillIds: strings.Join(billIds, ","),
- ObjName: objName,
- }
- order.SetTable(dbname)
- err = order.Insert(db)
- if err != nil {
- return nil, errors.DataBaseError
- }
- db.Commit()
- reply.OrderId = orderId
- reply.PrepayInfo = thirdPrepayInfo
- reply.CodeUrl = codeUrl
- return reply, nil
- }
- func householdChargeBillPayByBillIds(req *pb_v1.ChargeBillPayByHouseholdRequest, dbname string, mchId string) (reply *pb_v1.ChargeBillPayByHouseholdReply, err error) {
- reply = &pb_v1.ChargeBillPayByHouseholdReply{}
- 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{}
- productM := map[string]bool{}
- lateFeeBool := false
- orders := []string{}
- for i, v := range list {
- billIds = append(billIds, fmt.Sprintf("%v", v.ID))
- productM[charge_utils.ChargeTypeM[v.ChargeType]] = true
- chargeInfo := chargeInfoM[v.ChargeId]
- amount += v.Amount
- list[i].LateFee, _ = charge_utils.GetLateFee(v.Amount, v.ChargeEnd, &chargeInfo)
- amount += list[i].LateFee
- if list[i].LateFee > 0 {
- lateFeeBool = true
- }
- 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, "应缴金额与实缴金额不一致,需添加备注")
- }
- product := ""
- for k, _ := range productM {
- product = product + k + ";"
- }
- // 生成订单
- orderId, err := GenerateOrderId(req.GardenId, OrderTypeLife)
- if err != nil {
- return nil, err
- }
- //调用三方预支付
- thirdPrepayId, thirdPrepayInfo, codeUrl, err := ThirdpartyPay(req.OpenId, req.InputIp, req.ShouldPayAmount, orderId, product, mchId, req.Native)
- if err != nil {
- return nil, err
- }
- // 更新订单状态
- now := time.Now()
- values := map[string]interface{}{
- "comment": req.Comment,
- "pay_time": now.Unix(),
- "pay_mode": 1,
- "uid": req.HouseholdUid,
- "order_id": orderId,
- "pay_type": req.PayType,
- "status": charge_utils.PayStatusUnPay,
- }
- // 没有滞纳金批量更新
- if !lateFeeBool {
- bill.SetTable(dbname)
- err = bill.Update(db, where, values)
- if err != nil {
- return nil, errors.DataBaseError
- }
- } else {
- // 有滞纳金逐个更新
- for _, v := range list {
- values["late_fee"] = v.LateFee
- where = map[string]interface{}{
- "id": v.ID,
- }
- bill.SetTable(dbname)
- err = bill.Update(db, where, values)
- if err != nil {
- return nil, errors.DataBaseError
- }
- }
- }
- order := dbmodel.TChargeOrder{
- OrderId: orderId,
- Comment: req.Comment,
- Amount: req.ShouldPayAmount,
- PayAmount: req.PayAmount,
- PayType: req.PayType,
- CreatedAt: now,
- Uid: req.HouseholdUid,
- PackageId: 0,
- PrepayId: thirdPrepayId,
- TransactionId: "",
- Status: charge_utils.PayStatusUnPay,
- 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
- }
- db.Commit()
- reply.OrderId = orderId
- reply.PrepayInfo = thirdPrepayInfo
- reply.CodeUrl = codeUrl
- return reply, nil
- }
- func ChargeBillPayByHousehold(ctx context.Context, req *pb_v1.ChargeBillPayByHouseholdRequest) (reply *pb_v1.ChargeBillPayByHouseholdReply, err error) {
- reply = &pb_v1.ChargeBillPayByHouseholdReply{}
- // 捕获各个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 = checkChargeBillPayByHouseholdParam(req)
- if err != nil {
- return nil, err
- }
- mchId, err := charge_utils.CheckMchPayMode(req.GardenId)
- if err != nil {
- return nil, err
- }
- dbname := utils.GetGardenDbName(req.GardenId)
- if len(req.BillIds) > 0 {
- return householdChargeBillPayByBillIds(req, dbname, mchId)
- }
- return householdChargeBillPayByBindIds(req, dbname, mchId)
- }
|