431 lines
13 KiB
Go
431 lines
13 KiB
Go
package service
|
||
|
||
import (
|
||
"errors"
|
||
"github.com/shopspring/decimal"
|
||
"hospital-admin-api/api/dao"
|
||
"hospital-admin-api/api/dto"
|
||
"hospital-admin-api/api/requests"
|
||
"hospital-admin-api/global"
|
||
"hospital-admin-api/utils"
|
||
"time"
|
||
)
|
||
|
||
type DoctorWithdrawalService struct {
|
||
}
|
||
|
||
// GetDoctorWithdrawal 提现详情
|
||
func (r *DoctorWithdrawalService) GetDoctorWithdrawal(withdrawalId int64) (g *dto.DoctorWithdrawalDto, err error) {
|
||
doctorWithdrawalDao := dao.DoctorWithdrawalDao{}
|
||
doctorWithdrawal, err := doctorWithdrawalDao.GetDoctorWithdrawalById(withdrawalId)
|
||
if doctorWithdrawal == nil {
|
||
return nil, errors.New("数据错误")
|
||
}
|
||
|
||
// 获取医生数据
|
||
userDoctorDao := dao.UserDoctorDao{}
|
||
userDoctor, err := userDoctorDao.GetUserDoctorById(doctorWithdrawal.DoctorId)
|
||
if err != nil || userDoctor == nil {
|
||
return nil, errors.New("医生数据错误")
|
||
}
|
||
|
||
// 获取医生用户数据
|
||
userDao := dao.UserDao{}
|
||
user, err := userDao.GetUserById(userDoctor.UserId)
|
||
if err != nil || user == nil {
|
||
return nil, errors.New("医生数据错误")
|
||
}
|
||
|
||
// 获取医生详情数据
|
||
userDoctorInfoDao := dao.UserDoctorInfoDao{}
|
||
userDoctorInfo, err := userDoctorInfoDao.GetUserDoctorInfoByUserId(userDoctor.UserId)
|
||
if err != nil || userDoctorInfo == nil {
|
||
return nil, errors.New("医生详情数据错误")
|
||
}
|
||
|
||
// 获取提现关联银行数据
|
||
doctorWithdrawalBankDao := dao.DoctorWithdrawalBankDao{}
|
||
doctorWithdrawalBank, err := doctorWithdrawalBankDao.GetDoctorWithdrawalBankByWithdrawalId(doctorWithdrawal.WithdrawalId)
|
||
if err != nil || doctorWithdrawalBank == nil {
|
||
return nil, errors.New("银行卡数据错误")
|
||
}
|
||
|
||
// 获取基础银行数据
|
||
basicBankDao := dao.BasicBankDao{}
|
||
basicBank, err := basicBankDao.GetBasicBankById(doctorWithdrawalBank.BankId)
|
||
if err != nil || basicBank == nil {
|
||
return nil, errors.New("银行数据错误")
|
||
}
|
||
|
||
// 处理返回值
|
||
g = dto.GetDoctorWithdrawalDto(doctorWithdrawal)
|
||
|
||
// 加载医生名称
|
||
g.LoadDoctorName(userDoctor)
|
||
|
||
// 加载医生证件号码(掩码)
|
||
g.LoadDoctorCardNumMask(userDoctorInfo)
|
||
|
||
// 加载审核人员名称
|
||
g.LoadExamineByName(doctorWithdrawal.ExamineBy)
|
||
|
||
// 加载打款人员名称
|
||
g.LoadPaymentByName(doctorWithdrawal.ExamineBy)
|
||
|
||
// 加载提现关联银行数据
|
||
g.LoadDoctorWithdrawalBank(doctorWithdrawalBank)
|
||
|
||
// 加载基础银行数据
|
||
g.LoadBasicBank(basicBank)
|
||
|
||
// 加载医生user_id
|
||
g.LoadDoctorUserId(user)
|
||
|
||
return g, nil
|
||
}
|
||
|
||
// PutDoctorWithdrawalIncome 修改提现个人所得税
|
||
func (r *DoctorWithdrawalService) PutDoctorWithdrawalIncome(req requests.PutDoctorWithdrawalIncome, withdrawalId int64) (bool, error) {
|
||
doctorWithdrawalDao := dao.DoctorWithdrawalDao{}
|
||
doctorWithdrawal, _ := doctorWithdrawalDao.GetDoctorWithdrawalById(withdrawalId)
|
||
if doctorWithdrawal == nil {
|
||
return false, errors.New("数据错误")
|
||
}
|
||
|
||
// 判断审核状态
|
||
if doctorWithdrawal.ExamineStatus == 2 {
|
||
return false, errors.New("提现申请已审核通过,请勿再次操作")
|
||
}
|
||
|
||
if doctorWithdrawal.ExamineStatus == 3 {
|
||
return false, errors.New("提现申请已被驳回,请勿再次操作")
|
||
}
|
||
|
||
if doctorWithdrawal.PaymentStatus == 1 {
|
||
return false, errors.New("已打款,请勿再次操作")
|
||
}
|
||
|
||
if req.IncomeTax >= doctorWithdrawal.AppliedWithdrawalAmount {
|
||
return false, errors.New("个人所得税金额不可超出申请提现金额")
|
||
}
|
||
|
||
// 开始事务
|
||
tx := global.Db.Begin()
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
tx.Rollback()
|
||
}
|
||
}()
|
||
|
||
// 计算实际提现金额
|
||
var appliedWithdrawalAmount = decimal.NewFromFloat(doctorWithdrawal.AppliedWithdrawalAmount)
|
||
var incomeTax = decimal.NewFromFloat(req.IncomeTax)
|
||
|
||
// (计算提现金额-个人所得税金额) * 100 取小数点后3位,
|
||
actualWithdrawalAmount := appliedWithdrawalAmount.Sub(incomeTax).Mul(decimal.NewFromFloat(100)).Floor().Div(decimal.NewFromFloat(100))
|
||
// 转为float64
|
||
result, _ := actualWithdrawalAmount.Float64()
|
||
|
||
// 提现申请修改数据-提现金额固定不动,修改个人所得税,实际提现金额跟随变动
|
||
doctorWithdrawalData := make(map[string]interface{})
|
||
doctorWithdrawalData["actual_withdrawal_amount"] = result // 实际提现金额
|
||
doctorWithdrawalData["income_tax"] = req.IncomeTax // 提现所得税金额
|
||
err := doctorWithdrawalDao.EditDoctorWithdrawalById(tx, doctorWithdrawal.WithdrawalId, doctorWithdrawalData)
|
||
if err != nil {
|
||
tx.Rollback()
|
||
return false, errors.New(err.Error())
|
||
}
|
||
|
||
tx.Commit()
|
||
return true, nil
|
||
}
|
||
|
||
// PutDoctorWithdrawalExamine 修改提现审核状态
|
||
func (r *DoctorWithdrawalService) PutDoctorWithdrawalExamine(req requests.PutDoctorWithdrawalExamine, withdrawalId, adminUserId int64) (bool, error) {
|
||
doctorWithdrawalDao := dao.DoctorWithdrawalDao{}
|
||
doctorWithdrawal, _ := doctorWithdrawalDao.GetDoctorWithdrawalById(withdrawalId)
|
||
if doctorWithdrawal == nil {
|
||
return false, errors.New("数据错误")
|
||
}
|
||
|
||
// 判断审核状态
|
||
if doctorWithdrawal.ExamineStatus == 2 {
|
||
return false, errors.New("提现申请已审核通过,无法操作")
|
||
}
|
||
|
||
if doctorWithdrawal.ExamineStatus == 3 {
|
||
return false, errors.New("提现申请已被驳回,请勿再次操作")
|
||
}
|
||
|
||
if doctorWithdrawal.PaymentStatus == 1 {
|
||
return false, errors.New("已打款,请勿再次操作")
|
||
}
|
||
|
||
if req.ExamineStatus == 3 {
|
||
if req.ExamineFailReason == "" {
|
||
return false, errors.New("请填写拒绝原因")
|
||
}
|
||
}
|
||
|
||
// 开始事务
|
||
tx := global.Db.Begin()
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
tx.Rollback()
|
||
}
|
||
}()
|
||
|
||
// 提现申请修改数据
|
||
doctorWithdrawalData := make(map[string]interface{})
|
||
doctorWithdrawalData["examine_status"] = req.ExamineStatus
|
||
if req.ExamineFailReason != "" {
|
||
doctorWithdrawalData["examine_fail_reason"] = req.ExamineFailReason
|
||
}
|
||
doctorWithdrawalData["examine_time"] = time.Now().Format("2006-01-02 15:04:05")
|
||
doctorWithdrawalData["examine_by"] = adminUserId
|
||
err := doctorWithdrawalDao.EditDoctorWithdrawalById(tx, doctorWithdrawal.WithdrawalId, doctorWithdrawalData)
|
||
if err != nil {
|
||
tx.Rollback()
|
||
return false, errors.New(err.Error())
|
||
}
|
||
|
||
// 获取医生账户数据
|
||
doctorAccountDao := dao.DoctorAccountDao{}
|
||
doctorAccount, err := doctorAccountDao.GetDoctorAccountByDoctorId(doctorWithdrawal.DoctorId)
|
||
if err != nil {
|
||
tx.Rollback()
|
||
return false, errors.New("医生账户数据错误")
|
||
}
|
||
|
||
// 获取医生分成总金额
|
||
amountTotal, err := r.getDoctorWithdrawalOrderAmountTotal(withdrawalId)
|
||
if err != nil {
|
||
tx.Rollback()
|
||
return false, err
|
||
}
|
||
|
||
// 重新计算医生个人所得税
|
||
incomeTax := utils.ComputeIndividualIncomeTax(amountTotal)
|
||
|
||
// 重新计算实际提现金额
|
||
withdrawalAmount := amountTotal - incomeTax
|
||
|
||
// 返还医生账户金额-审核不通过
|
||
if req.ExamineStatus == 3 {
|
||
// 账户余额-增加
|
||
maps := make(map[string]interface{})
|
||
maps["account_id"] = doctorAccount.AccountId
|
||
err = doctorAccountDao.Inc(tx, maps, amountTotal, "balance_account")
|
||
if err != nil {
|
||
tx.Rollback()
|
||
return false, err
|
||
}
|
||
|
||
// 提现金额-减少
|
||
maps = make(map[string]interface{})
|
||
maps["account_id"] = doctorAccount.AccountId
|
||
err = doctorAccountDao.Dec(tx, maps, amountTotal, "applied_withdrawal_amount")
|
||
if err != nil {
|
||
tx.Rollback()
|
||
return false, err
|
||
}
|
||
|
||
// 实际提现金额-减少
|
||
maps = make(map[string]interface{})
|
||
maps["account_id"] = doctorAccount.AccountId
|
||
err = doctorAccountDao.Dec(tx, maps, withdrawalAmount, "actual_withdrawal_amount")
|
||
if err != nil {
|
||
tx.Rollback()
|
||
return false, err
|
||
}
|
||
|
||
// 提现所得税金额-减少
|
||
maps = make(map[string]interface{})
|
||
maps["account_id"] = doctorAccount.AccountId
|
||
err = doctorAccountDao.Dec(tx, maps, incomeTax, "income_tax")
|
||
if err != nil {
|
||
tx.Rollback()
|
||
return false, err
|
||
}
|
||
|
||
// 获取医生提现-关联订单数据
|
||
doctorWithdrawalOrderDao := dao.DoctorWithdrawalOrderDao{}
|
||
doctorWithdrawalOrders, err := doctorWithdrawalOrderDao.GetDoctorWithdrawalOrderByWithdrawalId(withdrawalId)
|
||
if err != nil {
|
||
tx.Rollback()
|
||
return false, errors.New("关联订单数据错误")
|
||
}
|
||
|
||
// 修改问诊订单提现状态
|
||
orderDao := dao.OrderDao{}
|
||
orderInquiryDao := dao.OrderInquiryDao{}
|
||
for _, v := range doctorWithdrawalOrders {
|
||
// 获取订单数据
|
||
order, err := orderDao.GetOrderPreloadById(v.OrderId)
|
||
if order == nil {
|
||
tx.Rollback()
|
||
return false, errors.New("关联订单数据错误")
|
||
}
|
||
|
||
// 修改订单数据
|
||
orderData := make(map[string]interface{})
|
||
orderData["is_withdrawal"] = 0
|
||
orderData["withdrawal_time"] = nil
|
||
|
||
err = orderDao.EditOrderById(tx, v.OrderId, orderData)
|
||
if err != nil {
|
||
tx.Rollback()
|
||
return false, errors.New("回滚关联订单数据失败")
|
||
}
|
||
|
||
if order.OrderType == 1 {
|
||
orderInquiryData := make(map[string]interface{})
|
||
orderInquiryData["is_withdrawal"] = 0
|
||
orderInquiryData["withdrawal_time"] = nil
|
||
err = orderInquiryDao.EditOrderInquiryById(tx, order.OrderInquiry.OrderInquiryId, orderInquiryData)
|
||
if err != nil {
|
||
tx.Rollback()
|
||
return false, errors.New("操作关联订单数据失败")
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
tx.Commit()
|
||
return true, nil
|
||
}
|
||
|
||
// PutDoctorWithdrawalPayment 确认打款
|
||
func (r *DoctorWithdrawalService) PutDoctorWithdrawalPayment(withdrawalId, adminUserId int64) (bool, error) {
|
||
doctorWithdrawalDao := dao.DoctorWithdrawalDao{}
|
||
doctorWithdrawal, _ := doctorWithdrawalDao.GetDoctorWithdrawalById(withdrawalId)
|
||
if doctorWithdrawal == nil {
|
||
return false, errors.New("数据错误")
|
||
}
|
||
|
||
// 判断审核状态
|
||
if doctorWithdrawal.ExamineStatus != 2 {
|
||
return false, errors.New("请先确认打款金额并审核")
|
||
}
|
||
|
||
if doctorWithdrawal.PaymentStatus == 1 {
|
||
return false, errors.New("已打款,请勿再次操作")
|
||
}
|
||
|
||
// 开始事务
|
||
tx := global.Db.Begin()
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
tx.Rollback()
|
||
}
|
||
}()
|
||
|
||
// 提现申请修改数据
|
||
doctorWithdrawalData := make(map[string]interface{})
|
||
doctorWithdrawalData["payment_status"] = 1
|
||
doctorWithdrawalData["payment_time"] = time.Now().Format("2006-01-02 15:04:05")
|
||
doctorWithdrawalData["payment_by"] = adminUserId
|
||
err := doctorWithdrawalDao.EditDoctorWithdrawalById(tx, doctorWithdrawal.WithdrawalId, doctorWithdrawalData)
|
||
if err != nil {
|
||
tx.Rollback()
|
||
return false, errors.New(err.Error())
|
||
}
|
||
|
||
// 获取医生提现-关联订单数据
|
||
doctorWithdrawalOrderDao := dao.DoctorWithdrawalOrderDao{}
|
||
doctorWithdrawalOrders, err := doctorWithdrawalOrderDao.GetDoctorWithdrawalOrderByWithdrawalId(withdrawalId)
|
||
if err != nil {
|
||
tx.Rollback()
|
||
return false, errors.New("关联订单数据错误")
|
||
}
|
||
|
||
// 修改问诊订单提现状态
|
||
orderDao := dao.OrderDao{}
|
||
orderInquiryDao := dao.OrderInquiryDao{}
|
||
for _, v := range doctorWithdrawalOrders {
|
||
// 获取订单数据
|
||
order, err := orderDao.GetOrderPreloadById(v.OrderId)
|
||
if order == nil {
|
||
tx.Rollback()
|
||
return false, errors.New("关联订单数据错误")
|
||
}
|
||
|
||
// 修改订单数据
|
||
orderData := make(map[string]interface{})
|
||
orderData["is_withdrawal"] = 1
|
||
orderData["withdrawal_time"] = time.Now().Format("2006-01-02 15:04:05")
|
||
|
||
err = orderDao.EditOrderById(tx, v.OrderId, orderData)
|
||
if err != nil {
|
||
tx.Rollback()
|
||
return false, errors.New("关联订单数据错误")
|
||
}
|
||
|
||
if order.OrderType == 1 {
|
||
orderInquiryData := make(map[string]interface{})
|
||
orderInquiryData["is_withdrawal"] = 1
|
||
orderInquiryData["withdrawal_time"] = time.Now().Format("2006-01-02 15:04:05")
|
||
err = orderInquiryDao.EditOrderInquiryById(tx, order.OrderInquiry.OrderInquiryId, orderInquiryData)
|
||
if err != nil {
|
||
tx.Rollback()
|
||
return false, errors.New("操作关联订单数据失败")
|
||
}
|
||
}
|
||
}
|
||
|
||
tx.Commit()
|
||
return true, nil
|
||
}
|
||
|
||
// 获取提现关联订单医生分成总金额
|
||
func (r *DoctorWithdrawalService) getDoctorWithdrawalOrderAmountTotal(withdrawalId int64) (float64, error) {
|
||
// 获取医生提现-关联订单数据
|
||
doctorWithdrawalOrderDao := dao.DoctorWithdrawalOrderDao{}
|
||
doctorWithdrawalOrders, err := doctorWithdrawalOrderDao.GetDoctorWithdrawalOrderByWithdrawalId(withdrawalId)
|
||
if err != nil {
|
||
return 0, errors.New("关联订单数据错误")
|
||
}
|
||
|
||
orderDao := dao.OrderDao{}
|
||
|
||
// 总金额
|
||
var amountTotal = decimal.NewFromFloat(0)
|
||
for _, v := range doctorWithdrawalOrders {
|
||
// 获取订单数据
|
||
order, err := orderDao.GetOrderPreloadById(v.OrderId)
|
||
if err != nil {
|
||
return 0, errors.New("订单数据错误")
|
||
}
|
||
|
||
if order.OrderInquiry != nil {
|
||
if order.OrderInquiry.InquiryStatus != 6 {
|
||
return 0, errors.New("存在未结束订单,数据错误")
|
||
}
|
||
|
||
}
|
||
|
||
if order.IsWithdrawal == 1 {
|
||
return 0, errors.New("存在已被提现订单,数据错误")
|
||
}
|
||
|
||
if order.PayStatus != 2 {
|
||
return 0, errors.New("存在支付状态错误订单,数据错误")
|
||
}
|
||
|
||
var orderAmountTotal = decimal.NewFromFloat(order.AmountTotal)
|
||
|
||
amountTotal = amountTotal.Add(orderAmountTotal)
|
||
}
|
||
|
||
// 分成比例
|
||
var prop = decimal.NewFromFloat(0.75)
|
||
|
||
// 计算分成
|
||
amountTotal = amountTotal.Mul(prop)
|
||
|
||
// 转为float64
|
||
result, _ := amountTotal.Float64()
|
||
|
||
return result, nil
|
||
}
|