新增 修改提现审核状态

This commit is contained in:
wucongxing 2023-11-01 10:45:01 +08:00
parent dda86b626d
commit 5e5d25f1bd
8 changed files with 464 additions and 5 deletions

View File

@ -122,3 +122,84 @@ func (r *DoctorWithdrawal) GetDoctorWithdrawalOrderPage(c *gin.Context) {
result["data"] = res
responses.OkWithData(result, c)
}
// PutDoctorWithdrawalIncome 修改提现个人所得税
func (r *DoctorWithdrawal) PutDoctorWithdrawalIncome(c *gin.Context) {
doctorWithdrawalRequest := requests.DoctorWithdrawalRequest{}
req := doctorWithdrawalRequest.PutDoctorWithdrawalIncome
if err := c.ShouldBind(&req); err != nil {
responses.FailWithMessage(err.Error(), c)
return
}
// 参数验证
if err := global.Validate.Struct(req); err != nil {
responses.FailWithMessage(utils.Translate(err), c)
return
}
id := c.Param("withdrawal_id")
if id == "" {
responses.FailWithMessage("缺少参数", c)
return
}
// 将 id 转换为 int64 类型
withdrawalId, err := strconv.ParseInt(id, 10, 64)
if err != nil {
responses.Fail(c)
return
}
// 业务处理
doctorWithdrawaService := service.DoctorWithdrawaService{}
_, err = doctorWithdrawaService.PutDoctorWithdrawalIncome(req, withdrawalId)
if err != nil {
responses.FailWithMessage(err.Error(), c)
return
}
responses.Ok(c)
}
// PutDoctorWithdrawalExamine 修改提现审核状态
func (r *DoctorWithdrawal) PutDoctorWithdrawalExamine(c *gin.Context) {
doctorWithdrawalRequest := requests.DoctorWithdrawalRequest{}
req := doctorWithdrawalRequest.PutDoctorWithdrawalExamine
if err := c.ShouldBind(&req); err != nil {
responses.FailWithMessage(err.Error(), c)
return
}
// 参数验证
if err := global.Validate.Struct(req); err != nil {
responses.FailWithMessage(utils.Translate(err), c)
return
}
id := c.Param("withdrawal_id")
if id == "" {
responses.FailWithMessage("缺少参数", c)
return
}
// 将 id 转换为 int64 类型
withdrawalId, err := strconv.ParseInt(id, 10, 64)
if err != nil {
responses.Fail(c)
return
}
// 后台用户id
adminUserId := c.GetInt64("UserId")
// 业务处理
doctorWithdrawaService := service.DoctorWithdrawaService{}
_, err = doctorWithdrawaService.PutDoctorWithdrawalExamine(req, withdrawalId, adminUserId)
if err != nil {
responses.FailWithMessage(err.Error(), c)
return
}
responses.Ok(c)
}

90
api/dao/doctorAccount.go Normal file
View File

@ -0,0 +1,90 @@
package dao
import (
"gorm.io/gorm"
"hospital-admin-api/api/model"
"hospital-admin-api/global"
)
type DoctorAccountDao struct {
}
// GetDoctorAccountById 获取医生账户数据-账户id
func (r *DoctorAccountDao) GetDoctorAccountById(accountId int64) (m *model.DoctorAccount, err error) {
err = global.Db.First(&m, accountId).Error
if err != nil {
return nil, err
}
return m, nil
}
// GetDoctorAccountByDoctorId 获取医生账户数据-医生id
func (r *DoctorAccountDao) GetDoctorAccountByDoctorId(doctorId int64) (m *model.DoctorAccount, err error) {
err = global.Db.Where("doctor_id = ?", doctorId).First(&m).Error
if err != nil {
return nil, err
}
return m, nil
}
// DeleteDoctorAccount 删除医生账户
func (r *DoctorAccountDao) DeleteDoctorAccount(tx *gorm.DB, maps interface{}) error {
err := tx.Where(maps).Delete(&model.DoctorAccount{}).Error
if err != nil {
return err
}
return nil
}
// EditDoctorAccount 修改医生账户
func (r *DoctorAccountDao) EditDoctorAccount(tx *gorm.DB, maps interface{}, data interface{}) error {
err := tx.Model(&model.DoctorAccount{}).Where(maps).Updates(data).Error
if err != nil {
return err
}
return nil
}
// EditDoctorAccountById 修改医生账户-医生账户id
func (r *DoctorAccountDao) EditDoctorAccountById(tx *gorm.DB, accountId int64, data interface{}) error {
err := tx.Model(&model.DoctorAccount{}).Where("account_id = ?", accountId).Updates(data).Error
if err != nil {
return err
}
return nil
}
// GetDoctorAccountList 获取医生账户列表
func (r *DoctorAccountDao) GetDoctorAccountList(maps interface{}) (m []*model.DoctorAccount, err error) {
err = global.Db.Where(maps).Find(&m).Error
if err != nil {
return nil, err
}
return m, nil
}
// AddDoctorAccount 新增医生账户
func (r *DoctorAccountDao) AddDoctorAccount(tx *gorm.DB, model *model.DoctorAccount) (*model.DoctorAccount, error) {
if err := tx.Create(model).Error; err != nil {
return nil, err
}
return model, nil
}
// Dec 自减
func (r *DoctorAccountDao) Dec(tx *gorm.DB, maps interface{}, numeral float64, field string) error {
err := tx.Model(&model.DoctorAccount{}).Where(maps).Update(field, gorm.Expr(field+" - ?", numeral)).Error
if err != nil {
return err
}
return nil
}
// Inc 自增
func (r *DoctorAccountDao) Inc(tx *gorm.DB, maps interface{}, numeral float64, field string) error {
err := tx.Model(&model.DoctorAccount{}).Where(maps).Update(field, gorm.Expr(field+" + ?", numeral)).Error
if err != nil {
return err
}
return nil
}

View File

@ -11,7 +11,7 @@ type DoctorWithdrawalOrderDao struct {
}
// GetDoctorWithdrawalOrderById 获取医生提现关联订单数据-id
func (r *DoctorWithdrawalOrderDao) GetDoctorWithdrawalOrderById(withdrawalBankId int64) (m *model.DoctorWithdrawalBank, err error) {
func (r *DoctorWithdrawalOrderDao) GetDoctorWithdrawalOrderById(withdrawalBankId int64) (m *model.DoctorWithdrawalOrder, err error) {
err = global.Db.First(&m, withdrawalBankId).Error
if err != nil {
return nil, err
@ -20,8 +20,8 @@ func (r *DoctorWithdrawalOrderDao) GetDoctorWithdrawalOrderById(withdrawalBankId
}
// GetDoctorWithdrawalOrderByWithdrawalId 获取医生提现关联订单数据-提现id
func (r *DoctorWithdrawalOrderDao) GetDoctorWithdrawalOrderByWithdrawalId(withdrawalId int64) (m *model.DoctorWithdrawalBank, err error) {
err = global.Db.Where("withdrawal_id = ?", withdrawalId).First(&m).Error
func (r *DoctorWithdrawalOrderDao) GetDoctorWithdrawalOrderByWithdrawalId(withdrawalId int64) (m []*model.DoctorWithdrawalOrder, err error) {
err = global.Db.Where("withdrawal_id = ?", withdrawalId).Find(&m).Error
if err != nil {
return nil, err
}

View File

@ -0,0 +1,37 @@
package model
import (
"gorm.io/gorm"
"hospital-admin-api/global"
"time"
)
// DoctorAccount 医生账户总表-已结束订单
type DoctorAccount struct {
AccountId int64 `gorm:"column:account_id;type:bigint(19);primary_key;comment:账户id" json:"account_id"`
DoctorId int64 `gorm:"column:doctor_id;type:bigint(19);comment:医生id" json:"doctor_id"`
TotalAmount float64 `gorm:"column:total_amount;type:decimal(18,8) unsigned;comment:总金额(已结束订单的总金额)" json:"total_amount"`
BalanceAccount float64 `gorm:"column:balance_account;type:decimal(18,8) unsigned;default:0.00000000;comment:账户余额" json:"balance_account"`
AppliedWithdrawalAmount float64 `gorm:"column:applied_withdrawal_amount;type:decimal(18,8) unsigned;default:0.00000000;comment:提现金额" json:"applied_withdrawal_amount"`
ActualWithdrawalAmount float64 `gorm:"column:actual_withdrawal_amount;type:decimal(18,8) unsigned;default:0.00000000;comment:实际提现金额" json:"actual_withdrawal_amount"`
IncomeTax float64 `gorm:"column:income_tax;type:decimal(18,8) unsigned;default:0.00000000;comment:所得税金额" json:"income_tax"`
Model
}
func (m *DoctorAccount) TableName() string {
return "gdxz_doctor_account"
}
func (m *DoctorAccount) BeforeCreate(tx *gorm.DB) error {
if m.AccountId == 0 {
m.AccountId = global.Snowflake.Generate().Int64()
}
m.CreatedAt = LocalTime(time.Now())
tx.Statement.SetColumn("CreatedAt", m.CreatedAt)
m.UpdatedAt = LocalTime(time.Now())
tx.Statement.SetColumn("UpdatedAt", m.UpdatedAt)
return nil
}

View File

@ -3,6 +3,8 @@ package requests
type DoctorWithdrawalRequest struct {
GetDoctorWithdrawalPage // 获取医生提现列表-分页
GetDoctorWithdrawalOrderPage // 提现详情-关联订单列表-分页
PutDoctorWithdrawalIncome // 修改提现个人所得税
PutDoctorWithdrawalExamine // 修改提现审核状态
}
// GetDoctorWithdrawalPage 获取医生提现列表-分页
@ -22,3 +24,14 @@ type GetDoctorWithdrawalOrderPage struct {
Page int `json:"page" form:"page" label:"页码"`
PageSize int `json:"page_size" form:"page_size" label:"每页个数"`
}
// PutDoctorWithdrawalIncome 修改提现个人所得税
type PutDoctorWithdrawalIncome struct {
IncomeTax float64 `json:"income_tax" form:"income_tax" validate:"required" label:"个人所得税金额"`
}
// PutDoctorWithdrawalExamine 修改提现审核状态
type PutDoctorWithdrawalExamine struct {
ExamineStatus int `json:"examine_status" form:"examine_status" validate:"required,oneof=2 3" label:"审核状态"` // 1:审核中 2:审核通过 3:审核未通过)
ExamineFailReason string `json:"examine_fail_reason" form:"examine_fail_reason" label:"审核失败原因"`
}

View File

@ -521,10 +521,10 @@ func privateRouter(r *gin.Engine, api controller.Api) {
withdrawalGroup.GET("/order/:withdrawal_id", api.DoctorWithdrawal.GetDoctorWithdrawalOrderPage)
// 修改提现个人所得税
withdrawalGroup.PUT("/income/:withdrawal_id", api.OrderPrescription.GetOrderPrescriptionPage)
withdrawalGroup.PUT("/income/:withdrawal_id", api.DoctorWithdrawal.PutDoctorWithdrawalIncome)
// 修改提现审核状态
withdrawalGroup.PUT("/examine/:withdrawal_id", api.OrderPrescription.GetOrderPrescriptionPage)
withdrawalGroup.PUT("/examine/:withdrawal_id", api.DoctorWithdrawal.PutDoctorWithdrawalExamine)
// 修改打款审核状态
withdrawalGroup.PUT("/payment/:withdrawal_id", api.OrderPrescription.GetOrderPrescriptionPage)

View File

@ -4,6 +4,11 @@ import (
"errors"
"hospital-admin-api/api/dao"
"hospital-admin-api/api/dto"
"hospital-admin-api/api/requests"
"hospital-admin-api/global"
"hospital-admin-api/utils"
"math"
"time"
)
type DoctorWithdrawaService struct {
@ -68,3 +73,201 @@ func (r *DoctorWithdrawaService) GetDoctorWithdrawal(withdrawalId int64) (g *dto
return g, nil
}
// PutDoctorWithdrawalIncome 修改提现个人所得税
func (r *DoctorWithdrawaService) 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()
}
}()
// 计算实际提现金额
actualWithdrawalAmount := math.Floor((doctorWithdrawal.AppliedWithdrawalAmount-req.IncomeTax)*0.75*100) / 100
// 提现申请修改数据-提现金额固定不动,修改个人所得税,实际提现金额跟随变动
doctorWithdrawalData := make(map[string]interface{})
doctorWithdrawalData["income_tax"] = req.IncomeTax // 提现所得税金额
doctorWithdrawalData["actual_withdrawal_amount"] = actualWithdrawalAmount // 实际提现金额
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 *DoctorWithdrawaService) 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())
}
// 返还医生账户金额
if req.ExamineStatus == 3 {
// 获取医生账户数据
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 := math.Floor((amountTotal-incomeTax)*0.75*100) / 100
incomeTax = math.Floor(incomeTax*100) / 100
// 账户余额-增加
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, withdrawalAmount, "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, incomeTax, "income_tax")
if err != nil {
tx.Rollback()
return false, err
}
}
tx.Commit()
return true, nil
}
// 获取提现关联订单医生分成总金额
func (r *DoctorWithdrawaService) getDoctorWithdrawalOrderAmountTotal(withdrawalId int64) (float64, error) {
// 获取医生提现-关联订单数据
doctorWithdrawalOrderDao := dao.DoctorWithdrawalOrderDao{}
doctorWithdrawalOrders, err := doctorWithdrawalOrderDao.GetDoctorWithdrawalOrderByWithdrawalId(withdrawalId)
if err != nil {
return 0, errors.New("关联订单数据错误")
}
// 总金额
var amountTotal float64
for _, v := range doctorWithdrawalOrders {
// 获取订单数据
orderInquiryDao := dao.OrderInquiryDao{}
orderInquiry, err := orderInquiryDao.GetOrderInquiryById(v.OrderInquiryId)
if err != nil {
return 0, errors.New("订单数据错误")
}
if orderInquiry.InquiryStatus != 6 {
return 0, errors.New("存在未结束订单,数据错误")
}
if orderInquiry.IsWithdrawal != 0 {
return 0, errors.New("存在已被提现订单,数据错误")
}
if orderInquiry.InquiryPayStatus != 2 {
return 0, errors.New("存在支付状态错误订单,数据错误")
}
amountTotal = amountTotal + orderInquiry.AmountTotal
}
// 医生分成金额
if amountTotal > 0 {
amountTotal = math.Floor(amountTotal*0.75*100) / 100
}
return amountTotal, nil
}

35
utils/compute.go Normal file
View File

@ -0,0 +1,35 @@
package utils
// 一些计算
// ComputeIndividualIncomeTax 计算个人所得税
func ComputeIndividualIncomeTax(income float64) float64 {
if income <= 800 {
return 0
}
if income <= 4000 {
income = income - 800
}
// 实际纳税金额
income = income * 0.8
// 税率、速算扣除数
var taxRate, quickDeduction float64
if income <= 20000 {
taxRate = 0.2
quickDeduction = 0
} else if income <= 50000 {
taxRate = 0.3
quickDeduction = 2000
} else {
taxRate = 0.4
quickDeduction = 7000
}
incomeTax := income*taxRate - quickDeduction
return incomeTax
}