You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MERN栈银行应用MongoDB用户余额更新失败问题求助

问题分析与解决方案

你的核心问题是在React前端代码中直接连接并操作MongoDB,这完全违背了MERN架构的分层原则——前端只能通过调用后端API来间接操作数据库,不能直接连接数据库。另外你的后端也没有提供处理存款的API接口,前端自然无法完成余额更新。

修复步骤

1. 后端添加存款API路由

在router.js中扩展现有路由,添加处理存款的逻辑:

const express = require('express')
const router = express.Router()
const schemas = require('../models/schemas')

router.post('/users/:a', async(req, res) => {
  const {name, email, password, balance, amount} = req.body
  const action = req.params.a
  
  switch(action) {
    case "send":
      const userData = {name: name, email: email, password: password, balance: balance}
      const newUser = new schemas.Users(userData)
      const saveUser = await newUser.save()
      if (saveUser) {
        res.send('User created')
      } else {
        res.send('Failed to create user. Please make sure all fields are filled and try again.')
      }
      break;
    // 新增存款处理逻辑
    case "deposit":
      try {
        // 找到用户并累加余额(注意转换amount为数字)
        const updatedUser = await schemas.Users.findOneAndUpdate(
          { email: email },
          { $inc: { balance: Number(amount) } }, // $inc用于累加,而非直接替换
          { new: true }
        )
        if (updatedUser) {
          res.send(`存款成功,当前余额:${updatedUser.balance}`)
        } else {
          res.send('未找到该用户')
        }
      } catch (err) {
        res.send('存款失败:' + err.message)
      }
      break;
    default:
      res.send('Invalid Request')
      break
  }
})

module.exports = router

2. 重构前端DepositPage代码

去掉前端的mongoose连接,改用axios调用后端API,和创建账户的逻辑保持一致:

import { useEffect, useState } from "react"
import { useNavigate, useLocation } from 'react-router-dom'
import React from "react";
import Card from "../../partials/Card";
import axios from "axios"; // 引入axios

function DepositPage() {
    const navigate = useNavigate();
    const location = useLocation();
    const [show, setShow]     = useState(true);
    const [status, setStatus] = useState('');  
  
    return (
      <Card
        bgcolor="dark"
        header="Deposit"
        status={status}
        body={show ? 
          <DepositForm setShow={setShow} setStatus={setStatus}/> :
          <DepositMsg setShow={setShow}/>}
      />
    )
  }
  
  function DepositMsg(props){
    return (<>
      <h5>User Successfully Deposited into Their Account</h5>
      <button type="submit" 
        className="btn btn-light" 
        onClick={() => props.setShow(true)}>
          Make Another Deposit
      </button>
    </>);
  } 
  
  function DepositForm(props){
    const [email, setEmail]   = useState('');
    const [amount, setAmount] = useState('');
    
    const handleDeposit = async () => {
      try {
        const response = await axios.post('http://localhost:4000/users/deposit', {
          email: email,
          amount: amount
        })
        props.setStatus(response.data);
        props.setShow(false);
      } catch (err) {
        props.setStatus('存款失败:' + err.response.data);
      }
    }
  
    return (<>
      Email<br/>
      <input type="input" 
        className="form-control" 
        placeholder="Enter email" 
        value={email} 
        onChange={e => setEmail(e.currentTarget.value)}/><br/>
        
      Amount<br/>
      <input type="number" 
        className="form-control" 
        placeholder="Enter amount" 
        value={amount} 
        onChange={e => setAmount(e.currentTarget.value)}/><br/>
  
      <button type="button" 
        className="btn btn-light" 
        onClick={handleDeposit}>
          Deposit
      </button>
    </>);
  }

 export default DepositPage

关键说明

  • 前端永远不要直接连接数据库,所有数据库操作必须通过后端API完成,这是安全和架构规范的基本要求。
  • 使用$inc而非$set来更新余额,因为存款是累加金额,不是直接替换现有余额。
  • 确保在API调用的异步逻辑完成后再更新前端状态(比如setShow(false)),避免请求未完成就显示成功提示。

内容的提问来源于stack exchange,提问作者Michael McKinnon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 05:25:54