124 lines
3.3 KiB
TypeScript
124 lines
3.3 KiB
TypeScript
import { makeAutoObservable, runInAction } from "mobx";
|
|
import { createContext } from "react";
|
|
import { createBill, getBills, getClass } from "../api/bills";
|
|
import { BillType, IBill } from "../model";
|
|
import * as R from "ramda"
|
|
|
|
/**
|
|
* 仅存储一个月的数据
|
|
*/
|
|
export class Bill {
|
|
private _bills: IBill[] = [];
|
|
// _cls2label: IClass = {consume: new Map<string, string[]>(), income: []}
|
|
private _cls2label: { consume: Record<string, string[]>, income: [] } = { consume: {}, income: [] }
|
|
|
|
constructor() {
|
|
makeAutoObservable(this)
|
|
this.fetchClass().then()
|
|
}
|
|
|
|
get bills() {
|
|
return this._bills
|
|
}
|
|
|
|
get cls2label() {
|
|
return this._cls2label
|
|
}
|
|
|
|
groupByDate(type?: BillType) {
|
|
const classFun = R.filter((bill: IBill) => R.of(bill.type).length === 0 || bill.type === type)
|
|
const functions = R.compose(
|
|
R.groupBy((bill: IBill) => bill.date),
|
|
classFun,
|
|
)
|
|
return functions(this._bills)
|
|
}
|
|
|
|
groupByClass(type?: BillType, date?: string) {
|
|
const classFun = R.filter((bill: IBill) => R.of(bill.type).length === 0 || bill.type === type && (date ? bill.date === date : true))
|
|
const functions = R.compose(
|
|
R.groupBy((bill: IBill) => bill.cls),
|
|
classFun,
|
|
)
|
|
return functions(this._bills)
|
|
}
|
|
|
|
get listDailyMoney() {
|
|
return this.groupByDate
|
|
}
|
|
|
|
get totalMoney() {
|
|
const functions = R.compose(
|
|
Number,
|
|
(s: number) => s.toFixed(2),
|
|
R.sum,
|
|
R.map((bill: IBill) => bill.money)
|
|
)
|
|
return functions(this._bills)
|
|
}
|
|
|
|
get consumeMoney() {
|
|
const functions = R.compose(
|
|
Number,
|
|
(s: number) => s.toFixed(2),
|
|
R.sum,
|
|
R.map((bill: IBill) => bill.money),
|
|
R.filter((bill: IBill) => bill.type === BillType.consume),
|
|
)
|
|
return functions(this._bills)
|
|
}
|
|
|
|
get incomeMoney() {
|
|
const functions = R.compose(
|
|
Number,
|
|
(s: number) => s.toFixed(2),
|
|
R.sum,
|
|
R.map((bill: IBill) => bill.money),
|
|
R.filter((bill: IBill) => bill.type === BillType.income),
|
|
)
|
|
return functions(this._bills)
|
|
}
|
|
|
|
getTotalMoney(type?: BillType) {
|
|
switch (type) {
|
|
case BillType.income:
|
|
return this.incomeMoney
|
|
case BillType.consume:
|
|
return this.consumeMoney
|
|
default:
|
|
return this.totalMoney
|
|
}
|
|
}
|
|
|
|
get meanMoneyByDate() {
|
|
const days = Reflect.ownKeys(this.groupByDate).length
|
|
if (days === 0) return 0
|
|
return this.totalMoney / days
|
|
}
|
|
|
|
|
|
async add(bill: IBill) {
|
|
const { id } = await createBill(bill)
|
|
bill.id = id
|
|
runInAction(() => {
|
|
this._bills.push(bill);
|
|
})
|
|
}
|
|
|
|
async fetch(year: number, month: number) {
|
|
const data = await getBills(year, month)
|
|
runInAction(() => {
|
|
this._bills = data
|
|
})
|
|
}
|
|
|
|
async fetchClass() {
|
|
const cls2label = await getClass()
|
|
runInAction(() => {
|
|
this._cls2label = cls2label
|
|
})
|
|
}
|
|
}
|
|
|
|
export const BillContext = createContext<Bill>(new Bill());
|