feat: 🚀 首页可以根据日期查询

This commit is contained in:
Bunny 2024-11-28 20:17:23 +08:00
parent b858b35bc9
commit 478dee4363
11 changed files with 151 additions and 47 deletions

View File

@ -2,7 +2,7 @@
export default {
// 超过最大值换行
printWidth: 160,
printWidth: 150,
// 缩进字节数
tabWidth: 1,
// 使用制表符而不是空格缩进行

View File

@ -3,6 +3,12 @@ import type { BaseResult, ResultTable } from '@/api/service/types';
/** 债务还款计划表---获取债务还款计划表列表 */
export const fetchGetUserDebtRepaymentPlanList = (data: any) => {
data = {
installmentAmount: data.installmentAmount,
dueDate: data.dueDate,
paidAmount: data.paidAmount,
paymentStatus: data.paymentStatus,
};
return http.request<BaseResult<ResultTable>>('get', `debtRepaymentPlan/noManage/getUserDebtRepaymentPlanList/${data.currentPage}/${data.pageSize}`, {
params: data,
});
@ -10,11 +16,26 @@ export const fetchGetUserDebtRepaymentPlanList = (data: any) => {
/** 债务还款计划表---添加债务还款计划表 */
export const fetchAddUserDebtRepaymentPlan = (data: any) => {
data = {
installmentNumber: data.installmentNumber,
installmentAmount: data.installmentAmount,
dueDate: data.dueDate,
paidAmount: data.paidAmount,
paymentStatus: data.paymentStatus,
};
return http.request<BaseResult<object>>('post', 'debtRepaymentPlan/noManage/addUserDebtRepaymentPlan', { data });
};
/** 债务还款计划表---更新债务还款计划表 */
export const fetchUpdateUserDebtRepaymentPlan = (data: any) => {
data = {
id: data.id,
installmentNumber: data.installmentNumber,
installmentAmount: data.installmentAmount,
dueDate: data.dueDate,
paidAmount: data.paidAmount,
paymentStatus: data.paymentStatus,
};
return http.request<BaseResult<object>>('put', 'debtRepaymentPlan/noManage/updateUserDebtRepaymentPlan', { data });
};

View File

@ -12,6 +12,7 @@ export const fetchUploadFile = (data: any) => {
};
/** 账单信息---首页内容展示 */
export const fetchHomeDatalist = () => {
return http.request<BaseResult<object>>('get', 'noManage/homeDatalist', {});
export const fetchHomeDatalist = (data: any) => {
data = { startDate: data.startDate, endDate: data.endDate };
return http.request<BaseResult<object>>('get', 'noManage/homeDatalist', { params: data });
};

View File

@ -69,6 +69,7 @@ export const useDebtRepaymentPlanUserStore = defineStore('debtRepaymentPlanUserS
/** 修改债务还款计划表 */
async updateDebtRepaymentPlan(data: any) {
data.paidAmount = Number(data.paidAmount) + Number(data.addAmount);
const result = await fetchUpdateUserDebtRepaymentPlan(data);
return storeMessage(result);
},

View File

@ -17,6 +17,8 @@ const props = withDefaults(defineProps<FormProps>(), {
dueDate: undefined,
//
paidAmount: undefined,
//
addAmount: 0,
//
paymentStatus: undefined,
}),
@ -30,6 +32,18 @@ const userDataList = ref();
const loading = ref(false);
const adminUserStore = useAdminUserStore();
/** 已还金额自定义验证*/
const paidAmountValidator = (rule, value, callback) => {
const paidAmount = Number(form.value.paidAmount);
const addAmount = Number(form.value.addAmount);
//
if (paidAmount + addAmount > form.value.installmentNumber) {
callback(new Error(`不能大于债务金额`));
}
callback();
};
defineExpose({ formRef });
</script>
@ -46,8 +60,25 @@ defineExpose({ formRef });
</el-form-item>
<!-- 已还金额 -->
<el-form-item :label="$t('paidAmount')" prop="paidAmount">
<el-input v-model="form.paidAmount" :min="0.01" :placeholder="$t('input') + $t('paidAmount')" :step="0.01" autocomplete="off" type="number" />
<el-form-item
:label="$t('paidAmount')"
:rules="[
{ required: true, message: `${$t('input')}${$t('paidAmount')}`, trigger: 'blur' },
{ validator: paidAmountValidator, trigger: 'blur' },
]"
prop="paidAmount"
>
<el-input
v-model="form.paidAmount"
:min="0.01"
:placeholder="$t('input') + $t('paidAmount')"
:step="0.01"
autocomplete="off"
class="w-[120px]"
type="number"
/>
<el-input v-model="form.addAmount" :min="0" :placeholder="$t('input')" :step="0.01" autocomplete="off" class="w-[120px]" type="number" />
</el-form-item>
<!-- 还款截止日期 -->

View File

@ -10,6 +10,7 @@ import { useDebtRepaymentPlanUserStore } from '@/store/financialUser/debtRepayme
export const formRef = ref();
// 删除ids
export const deleteIds = ref([]);
export const updatePaidAmount = ref(0);
const debtRepaymentPlanUserStore = useDebtRepaymentPlanUserStore();
/** 搜索初始化债务还款计划表 */
@ -30,6 +31,7 @@ export function onAdd() {
installmentAmount: undefined,
dueDate: undefined,
paidAmount: undefined,
addAmount: 0,
paymentStatus: undefined,
},
},
@ -62,6 +64,7 @@ export function onUpdate(row: any) {
installmentAmount: row.installmentAmount,
dueDate: row.dueDate,
paidAmount: row.paidAmount,
addAmount: 0,
paymentStatus: row.paymentStatus,
},
},
@ -74,6 +77,7 @@ export function onUpdate(row: any) {
formRef.value.formRef.validate(async (valid: any) => {
if (!valid) return;
// 原始金额加上后面要还款的金额
const result = await debtRepaymentPlanUserStore.updateDebtRepaymentPlan({ ...form, id: row.id });
if (!result) return;
done();

View File

@ -8,6 +8,8 @@ export interface FormItemProps {
dueDate: any;
// 已还金额
paidAmount: any;
// 需要继续添加的金额
addAmount: any;
// 还款状态
paymentStatus: string;
}

View File

@ -1,5 +1,5 @@
<script lang="ts" setup>
import { computed, type PropType, ref } from 'vue';
import { computed, onMounted, type PropType, ref, watch } from 'vue';
import { useDark, useECharts } from '@pureadmin/utils';
const props = defineProps({
@ -22,38 +22,47 @@ const { setOptions } = useECharts(chartRef, {
theme,
renderer: 'svg',
});
setOptions({
container: '.line-card',
xAxis: {
type: 'category',
show: false,
data: props.data,
},
grid: {
top: '15px',
bottom: 0,
left: 0,
right: 0,
},
yAxis: {
show: false,
type: 'value',
},
series: [
{
const init = () => {
setOptions({
container: '.line-card',
xAxis: {
type: 'category',
show: false,
data: props.data,
type: 'line',
symbol: 'none',
smooth: true,
color: props.color,
lineStyle: {
shadowOffsetY: 3,
shadowBlur: 7,
shadowColor: props.color,
},
},
],
grid: {
top: '15px',
bottom: 0,
left: 0,
right: 0,
},
yAxis: {
show: false,
type: 'value',
},
series: [
{
data: props.data,
type: 'line',
symbol: 'none',
smooth: true,
color: props.color,
lineStyle: {
shadowOffsetY: 3,
shadowBlur: 7,
shadowColor: props.color,
},
},
],
});
};
onMounted(() => {
watch(
() => props,
() => init(),
{ deep: true },
);
});
</script>

View File

@ -6,6 +6,7 @@ import { ElTag, ElText } from 'element-plus';
import { onMounted, reactive, ref, watch } from 'vue';
import { fetchGetUserBillList } from '@/api/v1/financial/user/billUser';
import Empty from './empty.svg?component';
import dayjs from 'dayjs';
const props = defineProps({
financialType: { type: Number as PropType<any>, default: undefined },
@ -94,8 +95,11 @@ const loading = ref(false);
async function onSearch() {
loading.value = true;
form.startDate = dayjs(form.startDate).format('YYYY-MM-DD');
form.endDate = dayjs(form.endDate).format('YYYY-MM-DD');
const result = await fetchGetUserBillList({ ...form, ...form.pagination });
dataList.value = result.data.list;
dataList.value = result.data?.list;
form.pagination.currentPage = result.data.pageNo;
form.pagination.pageSize = result.data.pageSize;
form.pagination.total = result.data.total;

View File

@ -7,11 +7,17 @@ import { ReNormalCountTo } from '@/components/CountTo';
import { useRenderFlicker } from '@/components/Flicker';
import ChartBar from '@/views/welcome/components/chart-bar.vue';
import ChartLine from '@/views/welcome/components/chart-line.vue';
import { chartData, expendData, expendPercent, homeRanks, incomeData, onSearch, xAxis } from '@/views/welcome/utils/hooks';
import { chartData, expendData, expendPercent, form, homeRanks, incomeData, onSearch, xAxis } from '@/views/welcome/utils/hooks';
import ChartRound from '@/views/welcome/components/chart-round.vue';
import { $t } from '@/plugins/i18n';
import { currentMouth, currentYear } from '@/enums/dateEnums';
const { isDark } = useDark();
//
const shortcuts = [
{ text: $t('thisMonth'), value: currentMouth },
{ text: $t('thisYear'), value: currentYear },
];
onMounted(() => {
onSearch();
@ -83,6 +89,18 @@ onMounted(() => {
<el-card class="bar-card" shadow="never">
<div class="flex justify-between">
<span class="text-md font-medium">{{ $t('analysisOverview') }}</span>
<span>
<el-date-picker
v-model="form.dateRange"
:end-placeholder="$t('endDate')"
:shortcuts="shortcuts"
:start-placeholder="$t('startDate')"
class="!w-[230px]"
clearable
type="daterange"
value-format="YYYY-MM-DD"
@change="onSearch"
/></span>
</div>
<div class="flex justify-between items-start mt-3">
<ChartBar :expend-data="expendData" :income-data="incomeData" :x-axis="xAxis" />
@ -90,12 +108,13 @@ onMounted(() => {
</el-card>
</re-col>
<!-- 收入支出排行榜 -->
<re-col v-motion :enter="{ opacity: 1, y: 0, transition: { delay: 640 } }" :initial="{ opacity: 0, y: 100 }" :value="6" :xs="24" class="mb-[18px]">
<el-card shadow="never">
<div class="flex justify-between">
<span class="text-md font-medium">{{ $t('incomeAndExpenditureRanking') }}</span>
</div>
<el-scrollbar class="mt-3" max-height="504">
<el-scrollbar class="mt-3" height="512" max-height="512">
<el-timeline>
<el-timeline-item
v-for="(item, index) in homeRanks"
@ -116,12 +135,13 @@ onMounted(() => {
</el-card>
</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">
<div class="flex justify-between">
<span class="text-md font-medium">{{ $t('dataStatistics') }}</span>
</div>
<WelcomeTable class="mt-3" />
<WelcomeTable :end-date="form.endDate" :start-date="form.startDate" class="mt-3" />
</el-card>
</re-col>
</el-row>

View File

@ -1,7 +1,7 @@
import { ref } from 'vue';
import { days } from '@/enums/dateEnums';
import { reactive, ref } from 'vue';
import { currentMouth, days } from '@/enums/dateEnums';
import { fetchHomeDatalist } from '@/api/v1/system/system';
import { default as dayjs } from 'dayjs';
import dayjs from 'dayjs';
import { $t } from '@/plugins/i18n';
// 支出百分比
@ -16,9 +16,19 @@ export const xAxis = ref([]);
export const incomeData = ref([]);
// 分析概览支出
export const expendData = ref([]);
// 查询日期表单
export const form = reactive({
startDate: undefined,
endDate: undefined,
dateRange: currentMouth,
});
/** 初始化数据 */
export const onSearch = async () => {
const result = await fetchHomeDatalist();
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;
}
@ -26,11 +36,12 @@ export const onSearch = async () => {
// 顶部数据
const homeCard = result.data?.homeCard;
const income = homeCard?.income?.amount;
const expend = homeCard?.expend?.amount;
const income = homeCard?.income?.amount ? homeCard?.income?.amount : 0;
const expend = homeCard?.expend?.amount ? homeCard?.expend?.amount : 0;
/* 支出百分比 */
expendPercent.value = Number((expend / (income + expend)).toFixed(2)) * 100;
const expendPercentValue = Number((expend / (income + expend)).toFixed(2)) * 100;
expendPercent.value = expendPercentValue ? expendPercentValue : 0;
// 收入和支出分析概览
xAxis.value = result.data.homeOverview