feat: income and expenditure

This commit is contained in:
KUN1007 2023-10-16 21:39:12 +08:00
parent 95ef65126d
commit 09c8f4a850
7 changed files with 131 additions and 145 deletions

View file

@ -8,9 +8,9 @@ export async function getIncomeApi(
requestData: Balance.BalanceIncomeRequestData requestData: Balance.BalanceIncomeRequestData
): Promise<Balance.BalanceIncomeResponseData> { ): Promise<Balance.BalanceIncomeResponseData> {
const queryParams = objectToQueryParams(requestData) const queryParams = objectToQueryParams(requestData)
const response = await fetchGet<Balance.BalanceIncomeResponseData>( const url = `/balance/income?${queryParams}`
`/balance/income?${queryParams}`
) const response = await fetchGet<Balance.BalanceIncomeResponseData>(url)
return response return response
} }
@ -19,8 +19,15 @@ export async function getExpenditureApi(
requestData: Balance.BalanceExpenditureRequestData requestData: Balance.BalanceExpenditureRequestData
): Promise<Balance.BalanceExpenditureResponseData> { ): Promise<Balance.BalanceExpenditureResponseData> {
const queryParams = objectToQueryParams(requestData) const queryParams = objectToQueryParams(requestData)
const response = await fetchGet<Balance.BalanceExpenditureResponseData>( const url = `/balance/expenditure?${queryParams}`
`/balance/expenditure?${queryParams}`
) const response = await fetchGet<Balance.BalanceExpenditureResponseData>(url)
return response
}
// 收支总额
export async function getPLStatementApi(): Promise<Balance.BalancePLStatementResponseData> {
const url = `/balance/statement`
const response = await fetchGet<Balance.BalancePLStatementResponseData>(url)
return response return response
} }

View file

@ -17,18 +17,35 @@ export interface BalanceExpenditureRequestData {
sortOrder: SortOrder sortOrder: SortOrder
} }
// income 响应数据 // 单条收入返回数据
export type BalanceIncomeResponseData = KUNGalgameResponseData<{ export interface BalanceIncome {
iid: number iid: number
reason: string reason: string
time: number time: number
amount: number amount: number
}> }
// expenditure 响应数据 // 单条支出返回数据
export type BalanceExpenditureResponseData = KUNGalgameResponseData<{ export interface BalanceExpenditure {
eid: number eid: number
reason: string reason: string
time: number time: number
amount: number amount: number
}> }
// 收支总额返回数据
export interface PLStatement {
totalIncome: number
totalExpenditure: number
profitLoss: number
}
// income 响应数据
export type BalanceIncomeResponseData = KUNGalgameResponseData<BalanceIncome[]>
// expenditure 响应数据
export type BalanceExpenditureResponseData = KUNGalgameResponseData<
BalanceExpenditure[]
>
export type BalancePLStatementResponseData = KUNGalgameResponseData<PLStatement>

View file

@ -6,9 +6,10 @@ import type {
BalanceExpenditureRequestData, BalanceExpenditureRequestData,
BalanceIncomeResponseData, BalanceIncomeResponseData,
BalanceExpenditureResponseData, BalanceExpenditureResponseData,
BalancePLStatementResponseData,
} from '@/api' } from '@/api'
import { getIncomeApi, getExpenditureApi } from '@/api' import { getIncomeApi, getExpenditureApi, getPLStatementApi } from '@/api'
interface BalanceStore { interface BalanceStore {
income: BalanceIncomeRequestData income: BalanceIncomeRequestData
@ -58,5 +59,10 @@ export const useKUNGalgameBalanceStore = defineStore({
} }
return await getExpenditureApi(requestData) return await getExpenditureApi(requestData)
}, },
// 获取收支总额
async getPLStatement(): Promise<BalancePLStatementResponseData> {
return await getPLStatementApi()
},
}, },
}) })

View file

@ -1,8 +1,43 @@
<script setup lang="ts"> <script setup lang="ts">
import { onMounted, reactive, ref } from 'vue'
import Form from './components/Form.vue' import Form from './components/Form.vue'
import KUNGalgameFooter from '@/components/KUNGalgameFooter.vue' import KUNGalgameFooter from '@/components/KUNGalgameFooter.vue'
//
import { calculateTotalAmount } from './log' import { useKUNGalgameBalanceStore } from '@/store/modules/balance'
import type { BalanceIncome, BalanceExpenditure, PLStatement } from '@/api'
const incomeData = ref<BalanceIncome[]>([])
const expenditureData = ref<BalanceExpenditure[]>([])
const statement: PLStatement = reactive({
totalIncome: 0,
totalExpenditure: 0,
profitLoss: 0,
})
const getIncomeData = async () => {
const response = await useKUNGalgameBalanceStore().getIncome()
return response.data
}
const getExpenditureData = async () => {
const response = await useKUNGalgameBalanceStore().getExpenditure()
return response.data
}
const getPLStatementData = async () => {
const response = await useKUNGalgameBalanceStore().getPLStatement()
return response.data
}
onMounted(async () => {
incomeData.value = await getIncomeData()
expenditureData.value = await getExpenditureData()
const PLData = await getPLStatementData()
statement.totalIncome = PLData.totalIncome
statement.totalExpenditure = PLData.totalExpenditure
statement.profitLoss = PLData.profitLoss
})
</script> </script>
<template> <template>
@ -14,21 +49,29 @@ import { calculateTotalAmount } from './log'
<!-- 内容区 --> <!-- 内容区 -->
<div class="content"> <div class="content">
<!-- 是收入表的话就渲染为蓝色 --> <!-- 是收入表的话就渲染为蓝色 -->
<Form :isIncome="true" /> <Form
<Form /> :isIncome="true"
:income-data="incomeData"
:statement="statement"
/>
<Form
:isIncome="false"
:expenditure-data="expenditureData"
:statement="statement"
/>
</div> </div>
<!-- 经济状态 --> <!-- 经济状态 -->
<div class="sum"> <div class="sum">
<!-- 亏损和盈余的样式不一样 --> <!-- 亏损和盈余的样式不一样 -->
<div <div
class="amount-status-deficit" class="amount-status-deficit"
:class="calculateTotalAmount() >= 0 ? 'amount-status-surplus' : ''" :class="statement.profitLoss >= 0 ? 'amount-status-surplus' : ''"
> >
<div> <div>
<!-- i18n --> <!-- i18n -->
{{ $tm('balance.status') }}: {{ $tm('balance.status') }}:
<span>{{ <span>{{
calculateTotalAmount() >= 0 statement.profitLoss >= 0
? $tm('balance.surplusStatus') ? $tm('balance.surplusStatus')
: $tm('balance.deficitStatus') : $tm('balance.deficitStatus')
}}</span> }}</span>
@ -36,10 +79,10 @@ import { calculateTotalAmount } from './log'
<div> <div>
<!-- i18n --> <!-- i18n -->
{{ {{
calculateTotalAmount() >= 0 statement.profitLoss >= 0
? $tm('balance.surplusAmount') ? $tm('balance.surplusAmount')
: $tm('balance.deficitAmount') : $tm('balance.deficitAmount')
}}: {{ calculateTotalAmount() }} CNY }}: {{ statement.profitLoss }} CNY
</div> </div>
</div> </div>
</div> </div>

View file

@ -1,28 +1,41 @@
<script setup lang="ts"> <script setup lang="ts">
import { toRefs } from 'vue'
import Log from './Log.vue' import Log from './Log.vue'
// //
import { calculateTotalIncome, calculateTotalExpenditure } from '../log' import type { BalanceIncome, BalanceExpenditure, PLStatement } from '@/api'
const props = defineProps(['isIncome']) const props = defineProps<{
const title = props.isIncome ? 'income' : 'expenditure' isIncome: boolean
const total = props.isIncome ? 'totalIncome' : 'totalExpenditure' incomeData?: BalanceIncome[]
expenditureData?: BalanceExpenditure[]
statement: PLStatement
}>()
const { isIncome, incomeData, expenditureData, statement } = toRefs(props)
</script> </script>
<template> <template>
<!-- 收入 --> <!-- 收入 -->
<div class="form" :class="$props.isIncome ? '' : 'expenditure-form'"> <div class="form" :class="$props.isIncome ? '' : 'expenditure-form'">
<!-- 标题 --> <!-- 标题 -->
<div class="title">{{ $tm(`balance['${title}']`) }}</div> <div v-if="isIncome" class="title">{{ $tm(`balance.income`) }}</div>
<div v-if="!isIncome" class="title">{{ $tm(`balance.expenditure`) }}</div>
<!-- 收入记录的容器 --> <!-- 收入记录的容器 -->
<div class="container"> <div class="container">
<Log :isIncome="$props.isIncome" /> <!-- 单条支出记录 -->
<Log :is-income="isIncome" :data="incomeData" />
<Log :is-income="isIncome" :data="expenditureData" />
</div> </div>
<!-- 总收入 --> <!-- 总收入 -->
<div class="sum"> <div v-if="isIncome" class="sum">
{{ $tm(`balance['${total}']`) }}: {{ $tm(`balance.totalIncome`) }}:
{{ {{ statement.totalIncome }}
$props.isIncome ? calculateTotalIncome() : calculateTotalExpenditure() CNY
}} </div>
<div v-if="!isIncome" class="sum">
{{ $tm(`balance.totalExpenditure`) }}:
{{ statement.totalExpenditure }}
CNY CNY
</div> </div>
</div> </div>

View file

@ -1,42 +1,26 @@
<script setup lang="ts"> <script setup lang="ts">
import { FSLog } from '../log' import { computed } from 'vue'
defineProps<{ import dayjs from 'dayjs'
isIncome?: boolean
import type { BalanceIncome, BalanceExpenditure } from '@/api'
const props = defineProps<{
isIncome: boolean
data?: BalanceIncome[] | BalanceExpenditure[]
}>() }>()
const data = computed(() => props.data)
</script> </script>
<template> <template>
<!-- 单条收入记录 --> <!-- 单条收入记录 -->
<div v-for="kun in FSLog" :key="kun.index" v-if="$props.isIncome"> <div v-for="(kun, index) in data" :key="index">
<div <div class="log" :class="props.isIncome ? '' : 'expenditure-log'">
class="log"
v-if="kun.income"
:class="$props.isIncome ? '' : 'expenditure-log'"
>
<!-- 收入来源 --> <!-- 收入来源 -->
<div class="reason">{{ kun.reason }}</div> <div class="reason" v-html="kun.reason"></div>
<!-- 收入时间和金额 --> <!-- 收入时间和金额 -->
<div class="result"> <div class="result">
<!-- 收入时间 --> <!-- 收入时间 -->
<span class="date">{{ kun.date }}</span> <span class="date">{{ dayjs(kun.time).format('YYYY/MM/DD') }}</span>
<!-- 收入金额 -->
<span class="amount">{{ kun.amount }}</span>
</div>
</div>
</div>
<!-- 单条支出记录 -->
<div v-for="kun in FSLog" :key="kun.index" v-if="!$props.isIncome">
<div
class="log"
v-if="!kun.income"
:class="$props.isIncome ? '' : 'expenditure-log'"
>
<!-- 收入来源 -->
<div class="reason">{{ kun.reason }}</div>
<!-- 收入时间和金额 -->
<div class="result">
<!-- 收入时间 -->
<span class="date">{{ kun.date }}</span>
<!-- 收入金额 --> <!-- 收入金额 -->
<span class="amount">{{ kun.amount }}</span> <span class="amount">{{ kun.amount }}</span>
</div> </div>

View file

@ -1,84 +0,0 @@
// 注意,这只是一个临时的数据文件,后来会被替换为后端接口
interface FS {
index: number
// 是否为收入
income: boolean
reason: string
date: string
amount: number
}
export const FSLog: FS[] = [
{
index: 1,
income: false,
reason:
'啊这可海星啊这可海星啊这可海星啊这可海星啊这可海星啊这可海星啊这可海星',
date: '2019/10/07',
amount: 1007,
},
{
index: 2,
income: true,
reason: '啊这可海星',
date: '2019/10/07',
amount: 107,
},
{
index: 3,
income: false,
reason: '啊这可海星',
date: '2019/10/07',
amount: 1007,
},
{
index: 4,
income: false,
reason: '啊这可海星',
date: '2019/10/07',
amount: 1007,
},
{
index: 5,
income: false,
reason: '啊这可海星',
date: '2019/10/07',
amount: 1007,
},
{
index: 6,
income: true,
reason: '啊这可海星',
date: '2019/10/07',
amount: 10007,
},
{
index: 7,
income: false,
reason: '啊这可海星',
date: '2019/10/07',
amount: 1007,
},
]
// 计算盈亏
export const calculateTotalAmount = (): number => {
return FSLog.reduce((total, item) => {
if (item.income) {
return total + item.amount
} else {
return total - item.amount
}
}, 0)
}
// 计算总收入
export const calculateTotalIncome = (): number => {
const filteredData = FSLog.filter((item) => item.income)
return filteredData.reduce((total, item) => total + item.amount, 0)
}
// 计算总支出
export const calculateTotalExpenditure = (): number =>
calculateTotalAmount() - calculateTotalIncome()