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
): Promise<Balance.BalanceIncomeResponseData> {
const queryParams = objectToQueryParams(requestData)
const response = await fetchGet<Balance.BalanceIncomeResponseData>(
`/balance/income?${queryParams}`
)
const url = `/balance/income?${queryParams}`
const response = await fetchGet<Balance.BalanceIncomeResponseData>(url)
return response
}
@ -19,8 +19,15 @@ export async function getExpenditureApi(
requestData: Balance.BalanceExpenditureRequestData
): Promise<Balance.BalanceExpenditureResponseData> {
const queryParams = objectToQueryParams(requestData)
const response = await fetchGet<Balance.BalanceExpenditureResponseData>(
`/balance/expenditure?${queryParams}`
)
const url = `/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
}

View file

@ -17,18 +17,35 @@ export interface BalanceExpenditureRequestData {
sortOrder: SortOrder
}
// income 响应数据
export type BalanceIncomeResponseData = KUNGalgameResponseData<{
// 单条收入返回数据
export interface BalanceIncome {
iid: number
reason: string
time: number
amount: number
}>
}
// expenditure 响应数据
export type BalanceExpenditureResponseData = KUNGalgameResponseData<{
// 单条支出返回数据
export interface BalanceExpenditure {
eid: number
reason: string
time: 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,
BalanceIncomeResponseData,
BalanceExpenditureResponseData,
BalancePLStatementResponseData,
} from '@/api'
import { getIncomeApi, getExpenditureApi } from '@/api'
import { getIncomeApi, getExpenditureApi, getPLStatementApi } from '@/api'
interface BalanceStore {
income: BalanceIncomeRequestData
@ -58,5 +59,10 @@ export const useKUNGalgameBalanceStore = defineStore({
}
return await getExpenditureApi(requestData)
},
// 获取收支总额
async getPLStatement(): Promise<BalancePLStatementResponseData> {
return await getPLStatementApi()
},
},
})

View file

@ -1,8 +1,43 @@
<script setup lang="ts">
import { onMounted, reactive, ref } from 'vue'
import Form from './components/Form.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>
<template>
@ -14,21 +49,29 @@ import { calculateTotalAmount } from './log'
<!-- 内容区 -->
<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 class="sum">
<!-- 亏损和盈余的样式不一样 -->
<div
class="amount-status-deficit"
:class="calculateTotalAmount() >= 0 ? 'amount-status-surplus' : ''"
:class="statement.profitLoss >= 0 ? 'amount-status-surplus' : ''"
>
<div>
<!-- i18n -->
{{ $tm('balance.status') }}:
<span>{{
calculateTotalAmount() >= 0
statement.profitLoss >= 0
? $tm('balance.surplusStatus')
: $tm('balance.deficitStatus')
}}</span>
@ -36,10 +79,10 @@ import { calculateTotalAmount } from './log'
<div>
<!-- i18n -->
{{
calculateTotalAmount() >= 0
statement.profitLoss >= 0
? $tm('balance.surplusAmount')
: $tm('balance.deficitAmount')
}}: {{ calculateTotalAmount() }} CNY
}}: {{ statement.profitLoss }} CNY
</div>
</div>
</div>

View file

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

View file

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