feat🔫: bill表格
This commit is contained in:
parent
6b54a5dc9d
commit
d7659d83b9
|
@ -17,6 +17,7 @@
|
|||
.content {
|
||||
flex: 1 1;
|
||||
padding: 10px;
|
||||
overflow: auto;
|
||||
}
|
||||
.footer {
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
export const useBill = () => {
|
||||
// const [bills, setBills] = useState<IBill[]>([])
|
||||
// const [_bills, setBills] = useState<IBill[]>([])
|
||||
//
|
||||
// useEffect(() => {
|
||||
// getBills().then(setBills).catch(console.dir)
|
||||
// }, [])
|
||||
// return {
|
||||
// bills,
|
||||
// _bills,
|
||||
// }
|
||||
}
|
|
@ -1,2 +1,14 @@
|
|||
.record {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: start;
|
||||
}
|
||||
|
||||
.new {
|
||||
}
|
||||
|
||||
.table {
|
||||
flex: 1 1;
|
||||
overflow: auto;
|
||||
}
|
|
@ -6,15 +6,21 @@ import {
|
|||
message,
|
||||
Radio,
|
||||
Select,
|
||||
Space
|
||||
Space, Table
|
||||
} from "antd";
|
||||
import {
|
||||
ArrowDownOutlined,
|
||||
CloudUploadOutlined, DeleteOutlined,
|
||||
} from "@ant-design/icons";
|
||||
import {useContext, useEffect, useRef, useState} from "react";
|
||||
import {BillType, EmptyBill} from "../../model";
|
||||
import {BillType, EmptyBill, IBill} from "../../model";
|
||||
import moment from "moment/moment";
|
||||
import {BillContext} from "../../store";
|
||||
import {observer} from "mobx-react-lite";
|
||||
import styles from "./Record.module.scss"
|
||||
import {BaseSelectRef} from "rc-select/lib/BaseSelect";
|
||||
import {createBill} from "../../api/bills";
|
||||
|
||||
|
||||
function Record() {
|
||||
|
||||
|
@ -35,12 +41,56 @@ function Record() {
|
|||
}, [clsRef])
|
||||
|
||||
|
||||
// table
|
||||
const columns = [
|
||||
{
|
||||
title: "日期",
|
||||
dataIndex: "date",
|
||||
key: "date",
|
||||
},
|
||||
{
|
||||
title: "类别",
|
||||
dataIndex: "cls",
|
||||
key: "cls",
|
||||
},
|
||||
{
|
||||
title: "标签",
|
||||
dataIndex: "label",
|
||||
key: "label",
|
||||
},
|
||||
{
|
||||
title: "金额",
|
||||
dataIndex: "money",
|
||||
key: "money",
|
||||
},
|
||||
{
|
||||
title: "备注",
|
||||
dataIndex: "options",
|
||||
key: "options",
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: 'action',
|
||||
render: (_: any, record: any) => (
|
||||
<Space>
|
||||
<Button
|
||||
type="primary"
|
||||
danger
|
||||
icon={<DeleteOutlined/>}
|
||||
onClick={() => setDataSource(datasource.filter(bill => bill !== record))}
|
||||
/>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
]
|
||||
const [datasource, setDataSource] = useState<IBill[]>([])
|
||||
|
||||
const typeOpt = [
|
||||
{label: '支出', value: BillType.consume},
|
||||
{label: '收入', value: BillType.income},
|
||||
];
|
||||
|
||||
|
||||
// 提交到表格
|
||||
const submit = async () => {
|
||||
const bill = EmptyBill()
|
||||
bill.type = billType
|
||||
|
@ -63,12 +113,32 @@ function Record() {
|
|||
}
|
||||
|
||||
if (checkBill()) {
|
||||
await billStore.add(bill)
|
||||
Reflect.set(bill, "key", crypto.randomUUID())
|
||||
setDataSource([bill, ...datasource])
|
||||
reset()
|
||||
} else {
|
||||
message.error("请输入完整")
|
||||
}
|
||||
}
|
||||
|
||||
// 上传云端
|
||||
const [uploadLoading, setUploadLoading] = useState(false)
|
||||
const upload = async () => {
|
||||
setUploadLoading(true)
|
||||
const failures = []
|
||||
for (let bill of datasource) {
|
||||
try {
|
||||
const {id} = await createBill(bill)
|
||||
if (!id) failures.push(bill)
|
||||
} catch (e) {
|
||||
failures.push(bill)
|
||||
}
|
||||
}
|
||||
setDataSource(failures)
|
||||
setUploadLoading(false)
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<div className={styles.record}>
|
||||
<div className={styles.new}>
|
||||
|
@ -81,6 +151,7 @@ function Record() {
|
|||
onChange={e => setBillType(e.target.value)}
|
||||
/>
|
||||
<DatePicker
|
||||
allowClear={false}
|
||||
value={moment(date, 'YYYY-MM-DD')}
|
||||
onChange={(_, dateStr) => setDate(dateStr)}
|
||||
/>
|
||||
|
@ -117,6 +188,7 @@ function Record() {
|
|||
cls2label.consume[cls]
|
||||
.map(la => <Select.Option key={la} value={la}>{la}</Select.Option>)
|
||||
}
|
||||
<Select.Option key={"other"} value={"其他"}>{"其他"}</Select.Option>)
|
||||
</Select>
|
||||
<InputNumber
|
||||
style={{width: 120}}
|
||||
|
@ -135,14 +207,27 @@ function Record() {
|
|||
/>
|
||||
<Button
|
||||
type="primary"
|
||||
icon={<ArrowDownOutlined/>}
|
||||
onKeyUp={e => e.key === "Tab"
|
||||
&& clsRef.current!.focus()
|
||||
}
|
||||
onClick={submit}
|
||||
>提交</Button>
|
||||
>
|
||||
提交
|
||||
</Button>
|
||||
</Space>
|
||||
</div>
|
||||
<div className={styles.table}></div>
|
||||
<div className={styles.table}>
|
||||
<Table dataSource={datasource} columns={columns}></Table>
|
||||
<Button
|
||||
icon={<CloudUploadOutlined/>}
|
||||
type="primary"
|
||||
loading={uploadLoading}
|
||||
onClick={upload}
|
||||
>
|
||||
全部上传
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -8,25 +8,28 @@ import * as R from "ramda"
|
|||
* 仅存储一个月的数据
|
||||
*/
|
||||
export class Bill {
|
||||
bills: IBill[] = [];
|
||||
private _bills: IBill[] = [];
|
||||
// _cls2label: IClass = {consume: new Map<string, string[]>(), income: []}
|
||||
_cls2label: { consume: Record<string, string[]>, income: [] } = {consume: {}, 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
|
||||
}
|
||||
|
||||
get listAllByDate() {
|
||||
return R.groupBy((bill: IBill) => bill.date)(this.bills)
|
||||
return R.groupBy((bill: IBill) => bill.date)(this._bills)
|
||||
}
|
||||
|
||||
get listAllByClass() {
|
||||
return R.groupBy((bill: IBill) => bill.cls)(this.bills)
|
||||
return R.groupBy((bill: IBill) => bill.cls)(this._bills)
|
||||
}
|
||||
|
||||
get listDailyMoney() {
|
||||
|
@ -40,7 +43,7 @@ export class Bill {
|
|||
R.sum,
|
||||
R.map((bill: IBill) => bill.money)
|
||||
)
|
||||
return functions(this.bills)
|
||||
return functions(this._bills)
|
||||
}
|
||||
|
||||
get meanMoneyByDate() {
|
||||
|
@ -54,14 +57,14 @@ export class Bill {
|
|||
const {id} = await createBill(bill)
|
||||
bill.id = id
|
||||
runInAction(() => {
|
||||
this.bills.push(bill);
|
||||
this._bills.push(bill);
|
||||
})
|
||||
}
|
||||
|
||||
async fetch(year: number, month: number) {
|
||||
const data = await getBills(year, month)
|
||||
runInAction(() => {
|
||||
this.bills = data
|
||||
this._bills = data
|
||||
})
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user