eggjs 怎么实现获取账单列表接口并且实现列表数据分页查询功能?
Posted 凯小默
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了eggjs 怎么实现获取账单列表接口并且实现列表数据分页查询功能?相关的知识,希望对你有一定的参考价值。
说明
该分页列表查询接口我自己分成三步写的,跟小册上的实现方式不太样,我是通过 mysql 的 limit 分页去实现的。
主要分成三个大的部分逻辑:
- 通过查询一个月里的账单所处的是哪一天,全都查出来,形成一个天数列表
- 通过天数列表,去查里面每一天的账单数据
- 最后统计这个月的所有账单
列表原型要求
可以查看原型,看前端账单需要怎样展示:账单是以时间天数作为一条数据,需要显示每天的账单信息,还有当月总支出,当月总收入,全部类型,月份选择。
分析接口需要字段
入参字段有:查询时需要
curPage, // 当前页数 (默认为1)
pageSize, // 一页多少条(默认为5)
typeId, // 类型 'all'就是全部类型
billDate, // 账单日期
需要返回的字段有:
data:
totalExpense, // 当月支出
totalIncome, // 当月收入
dataList: [
day, // 日期
bills: // bill 数据表中的每一项账单
, ...] // 列表数据
pageObj:
curPage, // 当前页数
pageSize, // 一页多少条
totalPage, // 总分页数
totalRow, // 总条数
实现获取账单列表接口
1、在控制层添加一个 list 方法
打开 /controller/bill.js
,新增一个 list 方法,里面的大体逻辑
- 获取查询参数
- 拿到 token 获取用户信息 user_id
- 通过 user_id 获取列表分页数据
- 组装数据:需要通过日获取一天的账单列表数据
- 获取当月总支出、当月总收入、总条数
const moment = require('moment'); // javascript 日期处理类库
class BillController extends Controller
async list()
const ctx, app = this;
try
/**
* curPage, // 当前页数 (默认为1)
* pageSize, // 一页多少条(默认为5)
* typeId, // 类型 'all'就是全部类型
* billDate, // YYYY-MM 账单日期
* */
// 1、获取查询参数
const curPage = 1, pageSize = 5, typeId = 'all', billDate = ctx.query;
console.log('1、获取查询参数',curPage,pageSize,typeId,billDate);
// 2、拿到 token 获取用户信息 user_id
const token = ctx.request.header.authorization;
const decode = await app.jwt.verify(token, app.config.jwt.secret);
if (!decode) return;
let user_id = decode.id;
console.log('2、拿到 token 获取用户信息 user_id',user_id);
// 3、通过 user_id 获取列表分页数据
const dayResult = await ctx.service.bill.list(user_id, typeId, billDate, curPage, pageSize);
const dayList = JSON.parse(JSON.stringify(dayResult));
console.log('3、通过 user_id 获取当前用户的账单列表',dayResult,dayList);
// 4、组装数据:需要通过日获取一天的账单列表数据
let dataList = [];
for(var i = 0; i < dayList.length; i++)
const day = moment(dayList[i].day).format("YYYY-MM-DD");
const month = moment(dayList[i].day).format("YYYY-MM");
if(month === billDate)
const listResult = await ctx.service.bill.listByDay(user_id, typeId, billDate, day);
const billsList = JSON.parse(JSON.stringify(listResult));
console.log(day,listResult,billsList);
dataList.push(
day: day,
bills: billsList
);
console.log('4、然后将 list 过滤出月份和类型所对应的账单列表',dataList);
// 5、获取当月总支出、当月总收入、总条数
// 获取一个月的有账单的所有天数列表 typeId 写死为all
const allDayResult = await ctx.service.bill.allList(user_id, 'all', billDate);
const allDayList = JSON.parse(JSON.stringify(allDayResult));
// 当月总支出:支付类型:1:支出,2:收入
let totalExpense = allDayList.reduce((curr, next) =>
if (next.pay_type === 1)
curr += Number(next.amount);
return curr;
return curr;
, 0).toFixed(2);
// 当月总收入:支付类型:1:支出,2:收入
let totalIncome = allDayList.reduce((curr, next) =>
if (next.pay_type === 2)
curr += Number(next.amount);
return curr;
return curr;
, 0).toFixed(2);
// 总条数 需要根据 typeId 去过滤
const allDayTypeIdResult = await ctx.service.bill.allList(user_id, typeId, billDate);
const allDayTypeIdList = JSON.parse(JSON.stringify(allDayTypeIdResult));
let obj = ; // 用年月日作为 key(YYYY-MM-DD)
// 天数去重
let newAllDayTypeIdList = allDayTypeIdList.reduce((item, next) =>
let nextDate = moment(next.date).format("YYYY-MM-DD");
obj[nextDate] ? '' : obj[nextDate] = true && item.push(next);
return item;
, []);
let totalRow = newAllDayTypeIdList.length;
console.log('5、获取一个月的有账单的天数列表', obj, newAllDayTypeIdList);
console.log('总条数', totalRow, '当月总支出:',totalExpense, '当月总收入:',totalIncome);
ctx.body =
status: 200,
desc: '请求成功',
data:
totalExpense, // 当月总支出
totalIncome, // 当月总收入
dataList: dataList, // 列表数据
pageObj:
curPage, // 当前页数
pageSize, // 一页多少条
totalPage: Math.ceil(totalRow / pageSize), // 总分页数
totalRow, // 总条数
catch (error)
console.log(error);
ctx.body =
status: 500,
desc: '系统错误',
data: null
2、在服务层添加几个方法获取sql数据
这里需要会一点 sql 语句,分页的参考资料在文章后面。
获取一个月的列表分页数据:主要就是通过日期去去重找到哪些天有账单的日期列表数据,然后通过降序分页处理。
async list(user_id, type_id, month, curPage, pageSize)
const app = this;
try
// 去重找到日的数据列表降序分页
let type_id_str = type_id === "all" || type_id === "" ? "" : " and type_id = " + type_id;
let date_str = " and DATE_FORMAT(b.date,'%Y-%m') = '" + month + "'";
let sql = "select distinct STR_TO_DATE(b.date,'%Y-%m-%d') day from `kaimo-cost`.bill b where user_id = "+ user_id+ type_id_str + date_str + " order by day desc limit "+(curPage-1)*pageSize+", "+pageSize;
const result = await app.mysql.query(sql);
return result;
catch (error)
console.log(error);
return null;
获取某一天的账单列表数据:主要加入一些查询条件
async listByDay(user_id, type_id, month, day)
const app = this;
try
const QUERY_STR = 'id, pay_type, amount, date, type_id, type_name, remark';
let type_id_str = type_id === "all" || type_id === "" ? "" : " and type_id = " + type_id;
let date_str = " and STR_TO_DATE(b.date,'%Y-%m-%d') = '" + day + "'" + " and DATE_FORMAT(b.date,'%Y-%m') = '" + month + "'";
let sql = "select " + QUERY_STR + " from `kaimo-cost`.bill b where user_id = " + user_id + date_str + type_id_str;
console.log('通过日获取列表数据', sql);
const result = await app.mysql.query(sql);
return result;
catch (error)
console.log(error);
return null;
获取某个月的所有账单数据
async allList(user_id, type_id, month)
const app = this;
try
let type_id_str = type_id === "all" || type_id === "" ? "" : " and type_id = " + type_id;
let sql = "select * from `kaimo-cost`.bill b where user_id = "+ user_id + " and DATE_FORMAT(b.date,'%Y-%m') = '" + month + "'" + type_id_str;
console.log('获取月的所有账单数据', sql);
const result = await app.mysql.query(sql);
return result;
catch (error)
console.log(error);
return null;
3、配置路由
// 获取账单列表
router.get('/api/bill/list', verify_token, controller.bill.list);
测试获取账单列表接口
1、在 apifox 里新建接口
如下图所示:
2、伪造列表数据
我们可以将下面的 sql 在 DBeaver 执行,插入这些数据。
INSERT INTO `kaimo-cost`.bill
(id, pay_type, amount, `date`, type_id, type_name, user_id, remark)
VALUES(1, 1, '33.00', '2022-01-01 22:00:00', 2, '1', 5, '测试');
INSERT INTO `kaimo-cost`.bill
(id, pay_type, amount, `date`, type_id, type_name, user_id, remark)
VALUES(2, 1, '3', '2022-01-01 19:00:00', 2, '1', 5, '测试');
INSERT INTO `kaimo-cost`.bill
(id, pay_type, amount, `date`, type_id, type_name, user_id, remark)
VALUES(3, 1, '13', '2022-01-02 22:00:00', 2, '1', 5, '测试');
INSERT INTO `kaimo-cost`.bill
(id, pay_type, amount, `date`, type_id, type_name, user_id, remark)
VALUES(4, 2, '56', '2022-01-03 18:00:00', 2, '1', 5, '测试');
INSERT INTO `kaimo-cost`.bill
(id, pay_type, amount, `date`, type_id, type_name, user_id, remark)
VALUES(5, 2, '42', '2022-01-05 12:07:00', 1, '1', 5, '测试');
INSERT INTO `kaimo-cost`.bill
(id, pay_type, amount, `date`, type_id, type_name, user_id, remark)
VALUES(6, 2, '11', '2022-01-06 22:00:00', 2, '1', 5, '测试');
INSERT INTO `kaimo-cost`.bill
(id, pay_type, amount, `date`, type_id, type_name, user_id, remark)
VALUES(7, 1, '3', '2022-01-07 22:00:00', 5, '1', 5, '测试');
INSERT INTO `kaimo-cost`.bill
(id, pay_type, amount, `date`, type_id, type_name, user_id, remark)
VALUES(8, 1, '33', '2022-02-01 22:00:00', 14, '1', 5, '测试');
INSERT INTO `kaimo-cost`.bill
(id, pay_type, amount, `date`, type_id, type_name, user_id, remark)
VALUES(9, 1, '3', '2022-02-02 22:00:00', 14, '1', 5, '测试');
INSERT INTO `kaimo-cost`.bill
(id, pay_type, amount, `date`, type_id, type_name, user_id, remark)
VALUES(10, 2, '2', '2022-02-03 22:00:00', 2, '1', 5, '测试');
INSERT INTO `kaimo-cost`.bill
(id, pay_type, amount, `date`, type_id, type_name, user_id, remark)
VALUES(11, 2, '46.9', '2022-02-04 22:00:00', 2, '1', 5, '测试');
INSERT INTO `kaimo-cost`.bill
(id, pay_type, amount, `date`, type_id, type_name, user_id, remark)
VALUES(12, 2, '27', '2022-02-05 20:00:00', 1, '1', 5, '测试');
INSERT INTO `kaimo-cost`.bill
(id, pay_type, amount, `date`, type_id, type_name, user_id, remark)
VALUES(13, 2, '4', '2022-02-05 22:00:00', 1, '1', 5, '测试');
INSERT INTO `kaimo-cost`.bill
(id, pay_type, amount, `date`, type_id, type_name, user_id, remark)
VALUES(14, 2, '7', '2022-02-07 22:00:00', 4, '1', 5, '测试');
INSERT INTO `kaimo-cost`.bill
(id, pay_type, amount, `date`, type_id, type_name, user_id, remark)
VALUES(15, 1, '11', '2022-02-08 22:00:00', 4, '1', 5, '测试');
INSERT INTO `kaimo-cost`.bill
(id, pay_type, amount, `date以上是关于eggjs 怎么实现获取账单列表接口并且实现列表数据分页查询功能?的主要内容,如果未能解决你的问题,请参考以下文章