feat: 🚀 添加存储已存储金额
This commit is contained in:
parent
ed4233ee23
commit
3cea26c1f3
|
@ -3,6 +3,18 @@ import type { BaseResult, ResultTable } from '@/api/service/types';
|
|||
|
||||
/** 用户储值---获取用户储值列表 */
|
||||
export const fetchGetSavingGoalList = (data: any) => {
|
||||
data = {
|
||||
userId: data.userId,
|
||||
statusType: data.statusType,
|
||||
savingGoalName: data.savingGoalName,
|
||||
amount: data.amount,
|
||||
amountDeposited: data.amountDeposited,
|
||||
duration: data.duration,
|
||||
startDuration: data.startDuration,
|
||||
endDuration: data.endDuration,
|
||||
pageSize: data.pageSize,
|
||||
currentPage: data.currentPage,
|
||||
};
|
||||
return http.request<BaseResult<ResultTable>>('get', `savingGoal/getSavingGoalList/${data.currentPage}/${data.pageSize}`, { params: data });
|
||||
};
|
||||
|
||||
|
|
|
@ -3,7 +3,20 @@ import type { BaseResult, ResultTable } from '@/api/service/types';
|
|||
|
||||
/** 用户储值---获取用户储值列表 */
|
||||
export const fetchGetUserSavingGoalList = (data: any) => {
|
||||
return http.request<BaseResult<ResultTable>>('get', `savingGoal/noManage/getUserSavingGoalList/${data.currentPage}/${data.pageSize}`, { params: data });
|
||||
data = {
|
||||
statusType: data.statusType,
|
||||
savingGoalName: data.savingGoalName,
|
||||
amount: data.amount,
|
||||
amountDeposited: data.amountDeposited,
|
||||
duration: data.duration,
|
||||
startDuration: data.startDuration,
|
||||
endDuration: data.endDuration,
|
||||
pageSize: data.pageSize,
|
||||
currentPage: data.currentPage,
|
||||
};
|
||||
return http.request<BaseResult<ResultTable>>('get', `savingGoal/noManage/getUserSavingGoalList/${data.currentPage}/${data.pageSize}`, {
|
||||
params: data,
|
||||
});
|
||||
};
|
||||
|
||||
/** 用户储值---添加用户储值 */
|
||||
|
|
|
@ -18,6 +18,7 @@ export const useSavingGoalStore = defineStore('savingGoalStore', {
|
|||
statusType: undefined, // 完成状态
|
||||
savingGoalName: undefined, // 储值目标名称
|
||||
amount: undefined, // 目标金额
|
||||
amountDeposited: undefined, // 已存入金额
|
||||
duration: undefined, // 目标时长
|
||||
startDuration: undefined, // 开始目标时长
|
||||
endDuration: undefined, // 结束目标时长
|
||||
|
@ -44,10 +45,6 @@ export const useSavingGoalStore = defineStore('savingGoalStore', {
|
|||
|
||||
// 整理请求参数
|
||||
const data = { ...this.pagination, ...this.form };
|
||||
delete data.pageSizes;
|
||||
delete data.total;
|
||||
delete data.background;
|
||||
delete data.duration;
|
||||
|
||||
// 获取用户储值列表
|
||||
const result = await fetchGetSavingGoalList(data);
|
||||
|
|
|
@ -24,6 +24,7 @@ export const useSavingGoalUserStore = defineStore('savingGoalUserStore', {
|
|||
statusType: undefined, // 完成状态
|
||||
savingGoalName: undefined, // 储值目标名称
|
||||
amount: undefined, // 目标金额
|
||||
amountDeposited: undefined, // 已存入金额
|
||||
duration: getCurrentMouthDate(), // 目标时长
|
||||
startDuration: undefined, // 开始目标时长
|
||||
endDuration: undefined, // 结束目标时长
|
||||
|
@ -50,10 +51,6 @@ export const useSavingGoalUserStore = defineStore('savingGoalUserStore', {
|
|||
|
||||
// 整理请求参数
|
||||
const data = { ...this.pagination, ...this.form };
|
||||
delete data.pageSizes;
|
||||
delete data.total;
|
||||
delete data.background;
|
||||
delete data.duration;
|
||||
|
||||
// 获取用户储值列表
|
||||
const result = await fetchGetUserSavingGoalList(data);
|
||||
|
@ -65,12 +62,14 @@ export const useSavingGoalUserStore = defineStore('savingGoalUserStore', {
|
|||
|
||||
/** 添加用户储值 */
|
||||
async addSavingGoal(data: any) {
|
||||
data.amountDeposited = Number(data.amountDeposited) + Number(data.addAmount);
|
||||
const result = await fetchAddUserSavingGoal(data);
|
||||
return storeMessage(result);
|
||||
},
|
||||
|
||||
/** 修改用户储值 */
|
||||
async updateSavingGoal(data: any) {
|
||||
data.amountDeposited = Number(data.amountDeposited) + Number(data.addAmount);
|
||||
const result = await fetchUpdateUserSavingGoal(data);
|
||||
return storeMessage(result);
|
||||
},
|
||||
|
|
|
@ -64,7 +64,15 @@ onMounted(() => {
|
|||
<el-form ref="formRef" :inline="true" :model="savingGoalUserStore.form" class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px] overflow-auto">
|
||||
<!-- 完成状态 -->
|
||||
<el-form-item :label="$t('statusType')" prop="statusType">
|
||||
<el-select v-model="savingGoalUserStore.form.statusType" :placeholder="$t('statusType')" class="!w-[180px]" clearable filterable remote remote-show-suffix>
|
||||
<el-select
|
||||
v-model="savingGoalUserStore.form.statusType"
|
||||
:placeholder="$t('statusType')"
|
||||
class="!w-[180px]"
|
||||
clearable
|
||||
filterable
|
||||
remote
|
||||
remote-show-suffix
|
||||
>
|
||||
<el-option v-for="item in savingGoal" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
@ -79,6 +87,16 @@ onMounted(() => {
|
|||
<el-input v-model="savingGoalUserStore.form.amount" :placeholder="`${$t('input')}${$t('amount')}`" class="!w-[180px]" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<!-- 目标金额 -->
|
||||
<el-form-item :label="$t('amountDeposited')" prop="amountDeposited">
|
||||
<el-input
|
||||
v-model="savingGoalUserStore.form.amountDeposited"
|
||||
:placeholder="`${$t('input')}${$t('amountDeposited')}`"
|
||||
class="!w-[180px]"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 目标时长 -->
|
||||
<el-form-item :label="$t('duration')" prop="duration">
|
||||
<el-date-picker
|
||||
|
@ -94,7 +112,9 @@ onMounted(() => {
|
|||
|
||||
<!-- 搜索和重置 -->
|
||||
<el-form-item>
|
||||
<el-button :icon="useRenderIcon('ri:search-line')" :loading="savingGoalUserStore.loading" type="primary" @click="onSearch"> {{ $t('search') }} </el-button>
|
||||
<el-button :icon="useRenderIcon('ri:search-line')" :loading="savingGoalUserStore.loading" type="primary" @click="onSearch">
|
||||
{{ $t('search') }}
|
||||
</el-button>
|
||||
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm(formRef)"> {{ $t('buttons.reset') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
@ -153,7 +173,9 @@ onMounted(() => {
|
|||
</template>
|
||||
|
||||
<template #operation="{ row }">
|
||||
<el-button :icon="useRenderIcon(EditPen)" :size="size" class="reset-margin" link type="primary" @click="onUpdate(row)"> {{ $t('modify') }} </el-button>
|
||||
<el-button :icon="useRenderIcon(EditPen)" :size="size" class="reset-margin" link type="primary" @click="onUpdate(row)">
|
||||
{{ $t('modify') }}
|
||||
</el-button>
|
||||
<el-popconfirm :title="`${$t('delete')}?`" @confirm="onDelete(row)">
|
||||
<template #reference>
|
||||
<el-button :icon="useRenderIcon(Delete)" :size="size" class="reset-margin" link type="primary">
|
||||
|
|
|
@ -17,6 +17,10 @@ const props = withDefaults(defineProps<FormProps>(), {
|
|||
savingGoalName: undefined,
|
||||
// 目标金额
|
||||
amount: undefined,
|
||||
// 已存入金额
|
||||
amountDeposited: undefined,
|
||||
// 需要继续添加的金额
|
||||
addAmount: 0,
|
||||
// 目标时长
|
||||
duration: undefined,
|
||||
}),
|
||||
|
@ -30,6 +34,18 @@ const userDataList = ref();
|
|||
const loading = ref(false);
|
||||
const adminUserStore = useAdminUserStore();
|
||||
|
||||
/** 已还金额自定义验证*/
|
||||
const paidAmountValidator = (rule, value, callback) => {
|
||||
const amountDeposited = Number(form.value.amountDeposited);
|
||||
const addAmount = Number(form.value.addAmount);
|
||||
|
||||
// 输入的金额大于债务金额
|
||||
if (amountDeposited + addAmount > form.value.amount) {
|
||||
callback(new Error(`不能大于总金额`));
|
||||
}
|
||||
callback();
|
||||
};
|
||||
|
||||
defineExpose({ formRef });
|
||||
</script>
|
||||
|
||||
|
@ -52,6 +68,28 @@ defineExpose({ formRef });
|
|||
<el-input v-model="form.amount" :min="0.01" :placeholder="$t('input') + $t('amount')" :step="0.01" autocomplete="off" type="number" />
|
||||
</el-form-item>
|
||||
|
||||
<!-- 已存入金额 -->
|
||||
<el-form-item
|
||||
:label="$t('amountDeposited')"
|
||||
:rules="[
|
||||
{ required: true, message: `${$t('input')}${$t('amountDeposited')}`, trigger: 'blur' },
|
||||
{ validator: paidAmountValidator, trigger: 'blur' },
|
||||
]"
|
||||
prop="amountDeposited"
|
||||
>
|
||||
<el-input
|
||||
v-model="form.amountDeposited"
|
||||
:min="0.01"
|
||||
:placeholder="$t('input') + $t('amountDeposited')"
|
||||
:step="0.01"
|
||||
autocomplete="off"
|
||||
class="w-[47%]"
|
||||
type="number"
|
||||
/>
|
||||
➕️
|
||||
<el-input v-model="form.addAmount" :min="0" :placeholder="$t('input')" :step="0.01" autocomplete="off" class="w-[48%]" type="number" />
|
||||
</el-form-item>
|
||||
|
||||
<!-- 目标时长 -->
|
||||
<el-form-item :label="$t('duration')" prop="duration">
|
||||
<el-date-picker
|
||||
|
|
|
@ -24,6 +24,19 @@ export const columns: TableColumnList = [
|
|||
);
|
||||
},
|
||||
},
|
||||
// 已存入金额
|
||||
{
|
||||
label: $t('amountDeposited'),
|
||||
prop: 'amountDeposited',
|
||||
width: 150,
|
||||
formatter({ amountDeposited }) {
|
||||
return (
|
||||
<ElText style={{ fontWeight: 800 }} type={'info'} size={'large'}>
|
||||
{amountDeposited}¥
|
||||
</ElText>
|
||||
);
|
||||
},
|
||||
},
|
||||
// 目标时长
|
||||
{
|
||||
label: $t('duration'),
|
||||
|
@ -50,6 +63,8 @@ export const rules = reactive<FormRules>({
|
|||
savingGoalName: [{ required: true, message: `${$t('input')}${$t('savingGoalName')}`, trigger: 'blur' }],
|
||||
// 目标金额
|
||||
amount: [{ required: true, message: `${$t('input')}${$t('amount')}`, trigger: 'blur' }],
|
||||
// 已存入金额
|
||||
amountDeposited: [{ required: true, message: `${$t('input')}${$t('amountDeposited')}`, trigger: 'blur' }],
|
||||
// 目标时长
|
||||
duration: [{ required: true, message: `${$t('input')}${$t('duration')}`, trigger: 'blur' }],
|
||||
});
|
||||
|
|
|
@ -29,6 +29,7 @@ export function onAdd() {
|
|||
statusType: undefined,
|
||||
savingGoalName: undefined,
|
||||
amount: undefined,
|
||||
amountDeposited: undefined,
|
||||
duration: undefined,
|
||||
},
|
||||
},
|
||||
|
@ -64,6 +65,7 @@ export function onUpdate(row: any) {
|
|||
statusType: row.statusType,
|
||||
savingGoalName: row.savingGoalName,
|
||||
amount: row.amount,
|
||||
amountDeposited: row.amountDeposited,
|
||||
duration: [row.startDuration, row.endDuration],
|
||||
},
|
||||
},
|
||||
|
|
|
@ -6,6 +6,10 @@ export interface FormItemProps {
|
|||
savingGoalName: string;
|
||||
// 目标金额
|
||||
amount: any;
|
||||
// 已存入金额
|
||||
amountDeposited: any;
|
||||
// 需要继续添加的金额
|
||||
addAmount: any;
|
||||
// 目标时长
|
||||
duration: string;
|
||||
// 开始目标时长
|
||||
|
|
|
@ -93,7 +93,15 @@ onMounted(() => {
|
|||
|
||||
<!-- 完成状态 -->
|
||||
<el-form-item :label="$t('statusType')" prop="statusType">
|
||||
<el-select v-model="savingGoalStore.form.statusType" :placeholder="$t('statusType')" class="!w-[180px]" clearable filterable remote remote-show-suffix>
|
||||
<el-select
|
||||
v-model="savingGoalStore.form.statusType"
|
||||
:placeholder="$t('statusType')"
|
||||
class="!w-[180px]"
|
||||
clearable
|
||||
filterable
|
||||
remote
|
||||
remote-show-suffix
|
||||
>
|
||||
<el-option v-for="item in savingGoal" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
@ -108,6 +116,11 @@ onMounted(() => {
|
|||
<el-input v-model="savingGoalStore.form.amount" :placeholder="`${$t('input')}${$t('amount')}`" class="!w-[180px]" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<!-- 已存入金额 -->
|
||||
<el-form-item :label="$t('amountDeposited')" prop="amountDeposited">
|
||||
<el-input v-model="savingGoalStore.form.amountDeposited" :placeholder="`${$t('input')}${$t('amountDeposited')}`" class="!w-[180px]" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<!-- 目标时长 -->
|
||||
<el-form-item :label="$t('duration')" prop="duration">
|
||||
<el-date-picker
|
||||
|
@ -123,7 +136,9 @@ onMounted(() => {
|
|||
|
||||
<!-- 搜索和重置 -->
|
||||
<el-form-item>
|
||||
<el-button :icon="useRenderIcon('ri:search-line')" :loading="savingGoalStore.loading" type="primary" @click="onSearch"> {{ $t('search') }} </el-button>
|
||||
<el-button :icon="useRenderIcon('ri:search-line')" :loading="savingGoalStore.loading" type="primary" @click="onSearch">
|
||||
{{ $t('search') }}
|
||||
</el-button>
|
||||
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm(formRef)"> {{ $t('buttons.reset') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
@ -182,7 +197,9 @@ onMounted(() => {
|
|||
</template>
|
||||
|
||||
<template #operation="{ row }">
|
||||
<el-button :icon="useRenderIcon(EditPen)" :size="size" class="reset-margin" link type="primary" @click="onUpdate(row)"> {{ $t('modify') }} </el-button>
|
||||
<el-button :icon="useRenderIcon(EditPen)" :size="size" class="reset-margin" link type="primary" @click="onUpdate(row)">
|
||||
{{ $t('modify') }}
|
||||
</el-button>
|
||||
<el-popconfirm :title="`${$t('delete')}?`" @confirm="onDelete(row)">
|
||||
<template #reference>
|
||||
<el-button :icon="useRenderIcon(Delete)" :size="size" class="reset-margin" link type="primary">
|
||||
|
|
|
@ -18,6 +18,8 @@ const props = withDefaults(defineProps<FormProps>(), {
|
|||
savingGoalName: undefined,
|
||||
// 目标金额
|
||||
amount: undefined,
|
||||
// 目标金额
|
||||
amountDeposited: undefined,
|
||||
// 目标时长
|
||||
duration: undefined,
|
||||
}),
|
||||
|
@ -85,6 +87,18 @@ defineExpose({ formRef });
|
|||
<el-input v-model="form.amount" :min="0.01" :placeholder="$t('input') + $t('amount')" :step="0.01" autocomplete="off" type="number" />
|
||||
</el-form-item>
|
||||
|
||||
<!-- 已存入金额 -->
|
||||
<el-form-item :label="$t('amountDeposited')" prop="amountDeposited">
|
||||
<el-input
|
||||
v-model="form.amountDeposited"
|
||||
:min="0.01"
|
||||
:placeholder="$t('input') + $t('amountDeposited')"
|
||||
:step="0.01"
|
||||
autocomplete="off"
|
||||
type="number"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 目标时长 -->
|
||||
<el-form-item :label="$t('duration')" prop="duration">
|
||||
<el-date-picker
|
||||
|
|
|
@ -24,6 +24,19 @@ export const columns: TableColumnList = [
|
|||
);
|
||||
},
|
||||
},
|
||||
// 已存入金额
|
||||
{
|
||||
label: $t('amountDeposited'),
|
||||
prop: 'amountDeposited',
|
||||
width: 150,
|
||||
formatter({ amountDeposited }) {
|
||||
return (
|
||||
<ElText style={{ fontWeight: 800 }} type={'info'} size={'large'}>
|
||||
{amountDeposited}¥
|
||||
</ElText>
|
||||
);
|
||||
},
|
||||
},
|
||||
// 目标时长
|
||||
{
|
||||
label: $t('duration'),
|
||||
|
@ -56,6 +69,8 @@ export const rules = reactive<FormRules>({
|
|||
savingGoalName: [{ required: true, message: `${$t('input')}${$t('savingGoalName')}`, trigger: 'blur' }],
|
||||
// 目标金额
|
||||
amount: [{ required: true, message: `${$t('input')}${$t('amount')}`, trigger: 'blur' }],
|
||||
// 已存入金额
|
||||
amountDeposited: [{ required: true, message: `${$t('input')}${$t('amountDeposited')}`, trigger: 'blur' }],
|
||||
// 目标时长
|
||||
duration: [{ required: true, message: `${$t('input')}${$t('duration')}`, trigger: 'blur' }],
|
||||
});
|
||||
|
|
|
@ -30,6 +30,7 @@ export function onAdd() {
|
|||
statusType: undefined,
|
||||
savingGoalName: undefined,
|
||||
amount: undefined,
|
||||
amountDeposited: undefined,
|
||||
duration: undefined,
|
||||
},
|
||||
},
|
||||
|
@ -66,6 +67,7 @@ export function onUpdate(row: any) {
|
|||
statusType: row.statusType,
|
||||
savingGoalName: row.savingGoalName,
|
||||
amount: row.amount,
|
||||
amountDeposited: row.amountDeposited,
|
||||
duration: [row.startDuration, row.endDuration],
|
||||
},
|
||||
},
|
||||
|
|
|
@ -8,6 +8,8 @@ export interface FormItemProps {
|
|||
savingGoalName: string;
|
||||
// 目标金额
|
||||
amount: any;
|
||||
// 已存入金额
|
||||
amountDeposited: any;
|
||||
// 目标时长
|
||||
duration: string;
|
||||
// 开始目标时长
|
||||
|
|
|
@ -79,7 +79,7 @@ const form = reactive({
|
|||
// 结束交易日期
|
||||
endDate: props.endDate,
|
||||
pagination: {
|
||||
pageSize: 10,
|
||||
pageSize: 15,
|
||||
currentPage: 1,
|
||||
layout: 'prev, pager, next',
|
||||
total: 1,
|
||||
|
|
|
@ -85,7 +85,14 @@ onMounted(() => {
|
|||
</el-card>
|
||||
</re-col>
|
||||
|
||||
<re-col v-motion :enter="{ opacity: 1, y: 0, transition: { delay: 400 } }" :initial="{ opacity: 0, y: 100 }" :value="18" :xs="24" class="mb-[18px]">
|
||||
<re-col
|
||||
v-motion
|
||||
:enter="{ opacity: 1, y: 0, transition: { delay: 400 } }"
|
||||
:initial="{ opacity: 0, y: 100 }"
|
||||
:value="18"
|
||||
:xs="24"
|
||||
class="mb-[18px]"
|
||||
>
|
||||
<el-card class="bar-card" shadow="never">
|
||||
<div class="flex justify-between">
|
||||
<span class="text-md font-medium">{{ $t('analysisOverview') }}</span>
|
||||
|
@ -136,8 +143,15 @@ onMounted(() => {
|
|||
</re-col>
|
||||
|
||||
<!-- 数据统计表格 -->
|
||||
<re-col v-motion :enter="{ opacity: 1, y: 0, transition: { delay: 560 } }" :initial="{ opacity: 0, y: 100 }" :value="24" :xs="24" class="mb-[18px]">
|
||||
<el-card class="h-[580px]" shadow="never">
|
||||
<re-col
|
||||
v-motion
|
||||
:enter="{ opacity: 1, y: 0, transition: { delay: 560 } }"
|
||||
:initial="{ opacity: 0, y: 100 }"
|
||||
:value="24"
|
||||
:xs="24"
|
||||
class="mb-[18px]"
|
||||
>
|
||||
<el-card class="h-[100%]" shadow="never">
|
||||
<div class="flex justify-between">
|
||||
<span class="text-md font-medium">{{ $t('dataStatistics') }}</span>
|
||||
</div>
|
||||
|
|
|
@ -25,25 +25,24 @@ export const form = reactive({
|
|||
|
||||
/** 初始化数据 */
|
||||
export const onSearch = async () => {
|
||||
// 初始化请求数据,设置开始时间和结束时间范围
|
||||
form.startDate = dayjs(form.dateRange[0]).format('YYYY-MM-DD');
|
||||
form.endDate = dayjs(form.dateRange[1]).format('YYYY-MM-DD');
|
||||
|
||||
// 请求后端数据并判断是否成功
|
||||
const result = await fetchHomeDatalist(form);
|
||||
if (result.code !== 200) {
|
||||
return;
|
||||
}
|
||||
chartData.value = [];
|
||||
if (result.code !== 200) return;
|
||||
|
||||
// 顶部数据
|
||||
chartData.value = [];
|
||||
const homeCard = result.data?.homeCard;
|
||||
const income = homeCard?.income?.amount ? homeCard?.income?.amount : 0;
|
||||
const expend = homeCard?.expend?.amount ? homeCard?.expend?.amount : 0;
|
||||
|
||||
/* 支出百分比 */
|
||||
// 支出百分比
|
||||
const expendPercentValue = Number((expend / (income + expend)).toFixed(2)) * 100;
|
||||
expendPercent.value = expendPercentValue ? expendPercentValue : 0;
|
||||
|
||||
// 收入和支出分析概览
|
||||
/* 收入和支出分析概览 */
|
||||
xAxis.value = result.data.homeOverview
|
||||
.filter(item => item.type === 1)
|
||||
.map(item => {
|
||||
|
@ -53,13 +52,14 @@ export const onSearch = async () => {
|
|||
incomeData.value = result.data.homeOverview.filter(item => item.type === 1).map(item => item.amount);
|
||||
expendData.value = result.data.homeOverview.filter(item => item.type === -1).map(item => item.amount);
|
||||
|
||||
// 收入和支出排行榜
|
||||
/* 收入和支出排行榜 */
|
||||
homeRanks.value = result.data.homeRanks.map(item => {
|
||||
const transactionDate = item.transactionDate;
|
||||
const date = `${dayjs(transactionDate).format('YYYY-MM-DD')} ${days[dayjs(transactionDate).day()]}`;
|
||||
return { date, amount: item.amount, name: item.categoryName, type: item.type };
|
||||
});
|
||||
|
||||
/* 顶部卡片数据 */
|
||||
homeCardFun(income, expend);
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue