基于express和lowdb库的记账本实现

目录

首先要安装所需要的几个库

工具及知识介绍

index.js路由页面

list.js记账本列表页

Create.ejs表单页

success.js成功/失败跳转页面

db.json初始化db页面


首先要安装所需要的几个库

$ npm i -g express-generator
$ express
##安装express 到generator 文件夹
$ express -e generator 
$ npm i lowdb@1.0.0
$ npm i shortid

工具及知识介绍

  1. Express 框架的路由功能,使用 express.Router() 创建一个路由实例,然后使用 router.get() 和 router.post() 等方法来定义路由的处理函数。

  2. lowdb 库,这是一个轻量级的本地 JSON 数据库,使用 lowdb/adapters/FileSync 模块创建一个文件适配器,然后使用 low() 方法创建一个 lowdb 实例,最后通过该实例来读写 JSON 数据库。

  3. shortid 库,用于生成短 ID,方便对账单进行唯一标识。

  4. EJS 模板引擎,使用 res.render() 方法来渲染视图模板。

index.js路由页面

这个页面主要是用于处理记账本相关的功能,包括显示账单列表、添加记录、删除记录等功能

  • 使用 router.get('/account', ...) 定义 GET 请求的 /account 路由处理函数,用于获取所有的账单信息并渲染账单列表视图。
  • 这里将从一个名为 db 的数据库对象中获取一个名为 accounts 的数据集合。这个数据集合包含了所有的账单信息并将账单信息传递给这个视图模板
  • 使用 router.get('/account/create', ...) 定义 GET 请求的 /account/create 路由处理函数,用于渲染添加账单记录的视图。
  • 使用 router.post('/account', ...) 定义 POST 请求的 /account 路由处理函数,用于将新的账单记录写入 JSON 数据库并渲染添加成功的提示视图。
  • 这里生成一个唯一的 id,然后将请求体中的数据与这个 id 组合成一个新的账单对象。然后,它使用 db.get('accounts').unshift({...}).write() 方法将这个新的账单对象写入到数据库中。
  • 使用 router.get('/account/:id', ...) 定义带参数的 GET 请求的 /account/:id 路由处理函数,用于根据账单 ID 删除相应的账单记录并渲染删除成功的提示视图。
  • 这里用路由传参,将要删除掉的那一个的超链接地址后添加当前的id,这样跳转时,动态路由参数 :id从请求的参数中获取到 id,然后用 db.get('accounts').remove({id:id}).write() 方法从数据库中删除指定 id 的账单信息
var express = require('express');
var router = express.Router();
// 导入lowdb
const low = require('lowdb')
const FileSync = require('lowdb/adapters/FileSync')
const adapter = new FileSync(__dirname+'/../data/db.json')
const db = low(adapter)
// 导入shortid
const shortid = require('shortid')
/* GET home page. */
// 记账本列表
router.get('/account', function(req, res, next) {
  //获取所有的账单信息
  let accounts = db.get('accounts').value()
  console.log("accounts----->",accounts);
  res.render('list',{accounts:accounts})
});
// 添加记录
router.get('/account/create', function(req, res, next) {
  res.render('create')
});
router.post('/account', function(req, res, next) {
  console.log(req.body);
  let id = shortid.generate()
  // 写入文件
  db.get('accounts').unshift({id:id,...req.body}).write()
  // 成功提现
  res.render('success',{msg:'添加成功哦~~~',url:'/account'})
});
router.get('/account/:id',(req,res)=>{
  // 获取params的id参数
  let id = req.params.id
  // 删除
  db.get('accounts').remove({id:id}).write()
  res.render('success',{msg:'删除成功哦~~~',url:'/account'})
})
module.exports = router;

list.js记账本列表页

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
body {
    font-family: Arial, sans-serif;
    background-color: #f4f4f4;
    margin: 0;
    padding: 20px;
}

h1 {
    text-align: center;
    margin-bottom: 20px;
}

div {
    background-color: #fff;
    padding: 20px;
    border-radius: 8px;
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
    margin-bottom: 20px;
    position: relative;
}

div div {
    margin-bottom: 10px;
}

div div:last-child {
    margin-bottom: 0;
}

.divClass {
    transition: transform 0.3s ease;
}

.divClass:hover {
    transform: scale(1.05);
}

.xxx {
    position: absolute;
    top: 10px;
    right: 10px;
    background-color: #007bff;
    color: #fff;
    padding: 5px 10px;
    border-radius: 4px;
    cursor: pointer;
    transition: background-color 0.3s ease;
}

.xxx:hover {
    background-color: #0062cc;
}
.timeDiv:hover,
.titleDiv:hover,
.amountDiv:hover,
.noteDiv:hover {
    transform: scale(1.01);
    transition: transform 0.6s ease;
}

    </style>
</head>

<body>
    <h1>记账本列表</h1>
    <div>
        <% accounts.forEach(function(item) { %>
            <div class="<%= item.type==='-1'?'warn':'ok' %>">
                <div class="timeDiv">时间:<%= item.time %>
                </div>
                <div class="titleDiv">标题:<%= item.title %>
                </div>
                <div class="amountDiv"><span class="<%= item.type==='-1'?'zhichu':'shouru' %>">
                        <%= item.type==='-1' ?'支出':'收入' %>
                    </span>金额:<%= item.account %>
                </div>
                <div class="noteDiv">备注:<%= item.remarks %>
                </div>
                <a href="/account/<%= item.id %>"><div class="xxx">X</div></a>
            </div>
            <hr>
            <% }); %>
    </div>
</body>
</html>

Create.ejs表单页

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body {
    font-family: Arial, sans-serif;
    background-color: #f4f4f4;
    margin: 0;
    padding: 20px;
}

h1 {
    text-align: center;
    color: #333;
}

form {
    background-color: #fff;
    padding: 20px;
    border-radius: 8px;
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
    max-width: 500px;
    margin: 0 auto;
}

form div {
    margin-bottom: 10px;
}

form label {
    font-weight: bold;
}

form input[type="text"],
form select {
    width: 100%;
    padding: 10px;
    border: none;
    border-radius: 4px;
    margin-top: 5px;
    margin-bottom: 15px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

form button {
    background-color: #007bff;
    color: #fff;
    padding: 10px 20px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    transition: background-color 0.3s ease;
}

form button:hover {
    background-color: #0062cc;
}
    </style>
</head>

<body>
    <h1>添加记录</h1>
    <hr>
    <div>
        <form action="/account" method="post">
            事项: <input type="text" name="title"><br>
            发生时间: <input type="text" name="time"><br>
            <div>
                <label for="type">类型</label>
                <select name="type" id="">
                    <option value="-1">支出</option>
                    <option value="+1">收入</option>
                </select>
            </div>
            金额: <input type="text" name="account"><br>
            备注: <input type="text" name="remarks"><br>
            <button>添加</button>
        </form>
    </div>
</body>
</html>

success.js成功/失败跳转页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body {
    font-family: Arial, sans-serif;
    background-color: #f4f4f4;
    margin: 0;
    padding: 20px;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
}

div {
    text-align: center;
    background-color: #fff;
    padding: 20px;
    border-radius: 8px;
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
    max-width: 300px;
    transition: transform 0.3s ease;
}

h1 {
    color: #007bff;
    font-size: 48px;
    margin-bottom: 20px;
    animation: heartbeat 1.5s infinite;
}

p {
    margin-top: 20px;
}

a {
    display: inline-block;
    padding: 10px 20px;
    background-color: #007bff;
    color: #fff;
    text-decoration: none;
    border-radius: 4px;
    transition: background-color 0.3s ease;
}

a:hover {
    background-color: #0062cc;
}

@keyframes heartbeat {
    0% {
        transform: scale(1);
    }
    50% {
        transform: scale(1.05);
    }
    100% {
        transform: scale(1);
    }
}
    </style>
</head>
<body>
    <div>
        <h1>:)<%= msg %></h1>
        <p><a href="<%= url %>">点击跳转</a></p>
    </div>
</body>
</html>

db.json初始化db页面

{
  "accounts": [

  ]
}

启动用npmstart

如果没在package.json配置,修改为

"scripts": {
 "start": "nodemon ./bin/www"
},

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值