那些开始在金融部门工作的人可能会遇到这个术语“双重进入”,这是管理交易和财务记录的基本概念。在这篇文章中,我想详细说明该概念的使用方式,以及其对维持财务交易的完整性的重要性
>解释一个示例的双重输入是什么。因此,请考虑您将$ 1,000的pix转让以支付帐户;此转移过程实际上执行了两个操作:
金融部门的重要性
>双重入口系统在金融领域至关重要,原因有多种:
确保所有财务交易都是准确记录的,从而减少了帐户中的错误和差异
package main
import (
"fmt"
"time"
)
type account struct {
id string
balance float64
}
type transaction struct {
id string
fromid string
toid string
amount float64
timestamp time.time
}
func (a *account) debit(amount float64) error {
if a.balance < amount {
return fmt.errorf("saldo insuficiente")
}
a.balance -= amount
return nil
}
func (a *account) credit(amount float64) {
a.balance += amount
}
func transfer(from, to *account, amount float64) error {
// primeira entrada: débito da conta origem
if err := from.debit(amount); err != nil {
return err
}
// segunda entrada: crédito na conta destino
to.credit(amount)
return nil
}
func main() {
// criando contas de exemplo
accounta := &account{
id: "conta_a",
balance: 1000.0,
}
accountb := &account{
id: "conta_b",
balance: 500.0,
}
fmt.printf("antes da transferência:\nconta a: r$%.2f\nconta b: r$%.2f\n\n",
accounta.balance, accountb.balance)
// realizando uma transferência
err := transfer(accounta, accountb, 300.0)
if err != nil {
fmt.printf("erro na transferência: %v\n", err)
return
}
fmt.printf("após a transferência:\nconta a: r$%.2f\nconta b: r$%.2f\n",
accounta.balance, accountb.balance)
}
>一个帐户结构,代表具有id和余额
的帐户交易结构以记录交易的详细信息
>实现双重输入概念的传输函数,以确保执行两个操作
>
执行后,此代码演示了从帐户a到帐户b的300.00 $ $转移,显示了操作前后的余额。如果在过程中存在任何错误(例如余额不足),则交易未完成
so被称为操作
type account struct {
id string
balance float64 // note o 'b' minúsculo tornando o campo privado
}
// método getter para acessar o saldo
func (a *account) getbalance() float64 {
return a.balance
}
// métodos de débito e crédito agora trabalham com o campo privado
func (a *account) debit(amount float64) error {
if a.balance < amount {
return fmt.errorf("saldo insuficiente")
}
a.balance -= amount
return nil
}
func (a *account) credit(amount float64) {
a.balance += amount
}
生产代码
作为实现双重入口系统的工具的一个实际示例,我们有伊萨兹(midaz),这是莱利安(lerian)维护的分类帐开源,他使用此技术来确保金融交易的完整性。 与基本上所有封闭的巴西金融系统不同,func (uc *UseCase) CreateOperation(ctx context.Context,
accounts []*account.Account,
transactionID string,
dsl *goldModel.Transaction,
validate goldModel.Responses,
result chan []*operation.Operation,
err chan error) {
// Declara uma lista para armazenar as operações criadas
var operations []*operation.Operation
// Cria uma lista `fromTo` contendo as contas de origem e destino envolvidas na transação
var fromTo []goldModel.FromTo
fromTo = append(fromTo, dsl.Send.Source.From...) // Adiciona contas de origem
fromTo = append(fromTo, dsl.Send.Distribute.To...) // Adiciona contas de destino
// Percorre todas as contas envolvidas na transação
for _, acc := range accounts {
// Verifica se a conta está na lista `fromTo`
for i := range fromTo {
// Verifica se a conta atual está envolvida na transação, seja pelo ID ou pelo alias.
if fromTo[i].Account == acc.Id || fromTo[i].Account == acc.Alias {
// Define o saldo atual da conta
balance := operation.Balance{
Available: &acc.Balance.Available,
OnHold: &acc.Balance.OnHold,
Scale: &acc.Balance.Scale,
}
// Valida a operação e calcula os valores da transação
amt, bat, er := goldModel.ValidateFromToOperation(fromTo[i], validate, acc)
if er != nil {
logger.Errorf("Error creating operation: %v", er)
}
// Converte os valores da transação para float64 e a escala de casas decimais
v := float64(amt.Value)
s := float64(amt.Scale)
amount := operation.Amount{
Amount: &v,
Scale: &s,
}
// Define o saldo da conta após a operação
ba := float64(bat.Available)
boh := float64(bat.OnHold)
bs := float64(bat.Scale)
balanceAfter := operation.Balance{
Available: &ba,
OnHold: &boh,
Scale: &bs,
}
// Determina se a operação será um débito ou crédito
var typeOperation string
if fromTo[i].IsFrom {
typeOperation = constant.DEBIT
} else {
typeOperation = constant.CREDIT
}
// Cria uma nova operação com os dados processados
save := &operation.Operation{
ID: pkg.GenerateUUIDv7().String(),
TransactionID: transactionID,
Type: typeOperation,
AssetCode: dsl.Send.Asset,
Amount: amount,
Balance: balance,
BalanceAfter: balanceAfter,
AccountID: acc.Id,
AccountAlias: acc.Alias,
...
}
// Salva a operação no banco de dados
op, er := uc.OperationRepo.Create(ctx, save)
if er != nil {
logger.Errorf("Error creating operation: %v", er)
}
// Adiciona a operação criada à lista de operações
operations = append(operations, op)
break // Sai do loop para evitar múltiplas inclusões da mesma conta
}
}
}
// Envia a lista de operações criadas pelo canal `result`
result <- operations
}
以上就是双重入口:是什么,何时使用以及如何做的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号