fixbug: 🐛 日期相关bug

This commit is contained in:
Bunny 2024-11-25 00:43:10 +08:00
parent 7bdc6ed08d
commit 2a75ff30e0
18 changed files with 120 additions and 82 deletions

View File

@ -1,6 +1,10 @@
import dayjs from 'dayjs';
export const currentWeek = [dayjs().startOf('week').add(1, 'day'), dayjs().endOf('week').add(1, 'day')];
export const currentMouth = [dayjs().startOf('month'), dayjs().endOf('month').add(1, 'day')];
export const currentWeek = () => {
const dayjs1 = [dayjs().day(1), dayjs().day(7)];
const dayjs2 = [dayjs().day(-6), dayjs().day(0)];
return dayjs().day() != 0 ? dayjs1 : dayjs2;
};
export const currentMouth = [dayjs().startOf('month'), dayjs().endOf('month')];
export const currentYear = [dayjs().startOf('year'), dayjs().endOf('year')];
export const days = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];

View File

@ -17,6 +17,8 @@ export const useBillStore = defineStore('billStore', {
userId: undefined,
// 类型1 - 收入,-1 - 支出
type: undefined,
// 金额
amount: undefined,
// 描述
description: undefined,
// 交易日志

View File

@ -3,7 +3,7 @@ import { fetchAddUserBill, fetchDeleteUserBill, fetchGetUserBillList, fetchUpdat
import { pageSizes } from '@/enums/baseConstant';
import { storeMessage } from '@/utils/message';
import { storePagination } from '@/store/useStorePagination';
import { getDefaultDateRange } from '@/utils/date';
import { getCurrentMouthDate } from '@/utils/date';
/**
* Store
@ -19,6 +19,8 @@ export const useBillUserStore = defineStore('billUserStore', {
form: {
// 类型1 - 收入,-1 - 支出
type: undefined,
// 金额
amount: undefined,
// 描述
description: undefined,
// 开始交易日期
@ -26,7 +28,7 @@ export const useBillUserStore = defineStore('billUserStore', {
// 结束交易日期
endDate: undefined,
// 交易日期
date: getDefaultDateRange(),
date: getCurrentMouthDate(),
},
// 分页查询结果
pagination: {

View File

@ -8,7 +8,7 @@ import {
fetchGetUserBudgetCategoryList,
fetchUpdateUserBudgetCategory,
} from '@/api/v1/financial/user/budgetCategoryUser';
import { getDefaultDateRange } from '@/utils/date';
import { getCurrentMouthDate } from '@/utils/date';
/**
* Store
@ -31,7 +31,7 @@ export const userBudgetCategoryUserStore = defineStore('budgetCategoryUserStore'
// 预算金额
amount: undefined,
// 预算周期
period: getDefaultDateRange(2, 30),
period: getCurrentMouthDate(),
// 开始预算时间
startPeriod: undefined,
// 结束预算时间

View File

@ -8,7 +8,7 @@ import {
fetchGetUserSavingGoalList,
fetchUpdateUserSavingGoal,
} from '@/api/v1/financial/user/savingGoalUser';
import { getDefaultDateRange } from '@/utils/date';
import { getCurrentMouthDate } from '@/utils/date';
/**
* Store
@ -24,7 +24,7 @@ export const useSavingGoalUserStore = defineStore('savingGoalUserStore', {
statusType: undefined, // 完成状态
savingGoalName: undefined, // 储值目标名称
amount: undefined, // 目标金额
duration: getDefaultDateRange(2, 30), // 目标时长
duration: getCurrentMouthDate(), // 目标时长
startDuration: undefined, // 开始目标时长
endDuration: undefined, // 结束目标时长
},

View File

@ -1,4 +1,5 @@
import dayjs from 'dayjs';
import { currentMouth } from '@/enums/dateEnums';
/** 设置默认时间 */
export const getDefaultDateRange = (start = 1, end = 7) => {
@ -15,6 +16,14 @@ export const getDefaultDateRange = (start = 1, end = 7) => {
return [dayjs(startDate).format('YYYY-MM-DD'), dayjs(endDate).format('YYYY-MM-DD')];
};
/** 获取当前月的日期*/
export const getCurrentMouthDate = () => {
const start = currentMouth[0];
const end = currentMouth[1];
return [start.format('YYYY-MM-DD'), end.format('YYYY-MM-DD')];
};
/** 格式化日期 */
export const dateformat = (date: any) => {
return dayjs(date).format('YYYY-MM-DD HH:mm:ss');

View File

@ -71,7 +71,7 @@ defineExpose({ formRef });
<!-- 类别id -->
<el-form-item :label="$t('category')" prop="categoryId">
<el-select v-model="form.categoryId" :placeholder="$t('select') + $t('category')" clearable filterable>
<el-select v-model="form.categoryId" :placeholder="$t('select') + $t('category')" clearable filterable @click="categoryUserStore.getCategoryUserAllList()">
<el-option v-for="item in categoryUserStore.allCategoryList" :key="item.id" :label="item.categoryName" :navigationBar="false" :value="item.id">
<el-text v-if="item.isBuiltin" effect="plain" size="large" type="info">{{ item.categoryName }}</el-text>
<el-text v-else effect="plain" size="large" type="success">{{ item.categoryName }}</el-text>

View File

@ -13,7 +13,7 @@ import { useBillUserStore } from '@/store/financialUser/billUser';
import { useRenderIcon } from '@/components/CommonIcon/src/hooks';
import { FormInstance } from 'element-plus';
import { incomeOrExpend } from '@/enums/baseConstant';
import { getDefaultDateRange } from '@/utils/date';
import { getCurrentMouthDate } from '@/utils/date';
const tableRef = ref();
const formRef = ref();
@ -40,7 +40,7 @@ const onSelectionChange = (rows: Array<any>) => {
const resetForm = async (formEl: FormInstance | undefined) => {
if (!formEl) return;
formEl.resetFields();
billStore.form.date = getDefaultDateRange();
billStore.form.date = getCurrentMouthDate();
billStore.form.startDate = undefined;
billStore.form.endDate = undefined;
await onSearch();
@ -61,6 +61,11 @@ onMounted(() => {
</el-select>
</el-form-item>
<!-- 金额 -->
<el-form-item :label="$t('amount')" prop="amount">
<el-input v-model="billStore.form.amount" :min="0" :placeholder="$t('input') + $t('amount')" :step="0.01" autocomplete="off" type="number" />
</el-form-item>
<!-- 描述 -->
<el-form-item :label="$t('description')" prop="description">
<el-input v-model="billStore.form.description" :placeholder="`${$t('input')}${$t('description')}`" class="!w-[180px]" clearable />

View File

@ -43,8 +43,9 @@ export function onAdd() {
label: $t('cancel'),
text: true,
bg: true,
btnClick: ({ dialog: { options, index } }) => {
btnClick: async ({ dialog: { options, index } }) => {
closeDialog(options, index);
await onSearch();
},
},
{

View File

@ -39,7 +39,7 @@ const onSearch = async () => {
//
analyseData.value = [];
analyseXAxis.value = [];
result.data.list.forEach(item => {
result.data.chartList.forEach(item => {
const transactionDate = item.transactionDate;
const date = `${dayjs(transactionDate).format('MM-DD')} ${days[dayjs(transactionDate).day()]}`;
analyseData.value.push(item.amount);

View File

@ -40,7 +40,7 @@ const onSearch = async () => {
//
analyseData.value = [];
analyseXAxis.value = [];
result.data.list.forEach(item => {
result.data.chartList.forEach(item => {
const transactionDate = item.transactionDate;
const date = `${dayjs(transactionDate).format('MM-DD')} ${days[dayjs(transactionDate).day()]}`;
analyseData.value.push(item.amount);

View File

@ -16,7 +16,7 @@ import { useAdminUserStore } from '@/store/system/adminUser';
import { budget } from '@/enums/bill/budget';
import { handleTree } from '@pureadmin/utils';
import { userBudgetCategoryUserStore } from '@/store/financialUser/budgetCategoryUser';
import { getDefaultDateRange } from '@/utils/date';
import { getCurrentMouthDate } from '@/utils/date';
const tableRef = ref();
const formRef = ref();
@ -49,7 +49,7 @@ const onSelectionChange = (rows: Array<any>) => {
const resetForm = async (formEl: FormInstance | undefined) => {
if (!formEl) return;
formEl.resetFields();
budgetCategoryStore.form.period = getDefaultDateRange(2, 30);
budgetCategoryStore.form.period = getCurrentMouthDate();
budgetCategoryStore.form.startPeriod = undefined;
budgetCategoryStore.form.endPeriod = undefined;
await onSearch();

View File

@ -16,7 +16,7 @@ import { budget } from '@/enums/bill/budget';
import { selectUserinfo } from '@/components/Table/Userinfo/columns';
import { savingGoal } from '@/enums/bill/savingGoal';
import { useSavingGoalUserStore } from '@/store/financialUser/savingGoalUser';
import { getDefaultDateRange } from '@/utils/date';
import { getCurrentMouthDate } from '@/utils/date';
const tableRef = ref();
const formRef = ref();
@ -48,7 +48,7 @@ const onSelectionChange = (rows: Array<any>) => {
const resetForm = async (formEl: FormInstance | undefined) => {
if (!formEl) return;
formEl.resetFields();
savingGoalUserStore.form.duration = getDefaultDateRange(2, 30);
savingGoalUserStore.form.duration = getCurrentMouthDate();
savingGoalUserStore.form.startDuration = undefined;
savingGoalUserStore.form.endDuration = undefined;
await onSearch();

View File

@ -97,6 +97,11 @@ onMounted(() => {
</el-select>
</el-form-item>
<!-- 金额 -->
<el-form-item :label="$t('amount')" prop="amount">
<el-input v-model="billStore.form.amount" :min="0" :placeholder="$t('input') + $t('amount')" :step="0.01" autocomplete="off" type="number" />
</el-form-item>
<!-- 描述 -->
<el-form-item :label="$t('description')" prop="description">
<el-input v-model="billStore.form.description" :placeholder="`${$t('input')}${$t('description')}`" class="!w-[180px]" clearable />

View File

@ -1,6 +1,7 @@
<script lang="ts" setup>
import { useDark, useECharts } from '@pureadmin/utils';
import { computed, nextTick, type PropType, ref, watch } from 'vue';
import { $t } from '@/plugins/i18n';
const props = defineProps({
incomeData: {
@ -44,7 +45,7 @@ watch(
right: 0,
},
legend: {
data: ['收入金额', '支出金额'],
data: [$t('income'), $t('expend')],
textStyle: {
color: '#606266',
fontSize: '0.875rem',
@ -76,7 +77,7 @@ watch(
],
series: [
{
name: '收入金额',
name: $t('income'),
type: 'line',
barWidth: 15,
itemStyle: {
@ -86,7 +87,7 @@ watch(
data: props.incomeData,
},
{
name: '支出金额',
name: $t('expend'),
type: 'bar',
barWidth: 15,
itemStyle: {

View File

@ -8,7 +8,8 @@ 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 ChartRound from '@/views/welcome/components/ChartRound.vue';
import ChartRound from '@/views/welcome/components/chart-round.vue';
import { $t } from '@/plugins/i18n';
const { isDark } = useDark();
@ -64,9 +65,9 @@ onMounted(() => {
>
<el-card class="line-card" shadow="never">
<div class="flex justify-between">
<span class="text-md font-medium"> 支出百分比 </span>
<span class="text-md font-medium"> {{ $t('percentageOfExpenditure') }} </span>
<div :style="{ backgroundColor: isDark ? 'transparent' : '#fff5f4' }" class="w-8 h-8 flex justify-center items-center rounded-md">
<IconifyIconOnline color="#F56C6C" icon="item.icon" width="18" />
<IconifyIconOnline color="#F56C6C" icon="tabler:percentage-66" width="18" />
</div>
</div>
<div class="flex justify-between items-start mt-3">
@ -81,7 +82,7 @@ onMounted(() => {
<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">分析概览</span>
<span class="text-md font-medium">{{ $t('analysisOverview') }}</span>
</div>
<div class="flex justify-between items-start mt-3">
<ChartBar :expend-data="expendData" :income-data="incomeData" :x-axis="xAxis" />
@ -92,7 +93,7 @@ onMounted(() => {
<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">收入支出排行榜</span>
<span class="text-md font-medium">{{ $t('incomeAndExpenditureRanking') }}</span>
</div>
<el-scrollbar class="mt-3" max-height="504">
<el-timeline>
@ -105,8 +106,8 @@ onMounted(() => {
placement="top"
>
<p class="text-text_color_regular text-sm">
<el-text v-show="item.type === -1" type="danger">{{ '支出' }}</el-text>
<el-text v-show="item.type === 1" type="success">{{ '收入' }}</el-text>
<el-text v-show="item.type === -1" type="danger">{{ $t('expend') }}</el-text>
<el-text v-show="item.type === 1" type="success">{{ $t('income') }}</el-text>
{{ `${item.name} ${item.amount}` }}
</p>
</el-timeline-item>
@ -118,7 +119,7 @@ onMounted(() => {
<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">数据统计</span>
<span class="text-md font-medium">{{ $t('dataStatistics') }}</span>
</div>
<WelcomeTable class="mt-3" />
</el-card>

View File

@ -2,6 +2,7 @@ import { ref } from 'vue';
import { days } from '@/enums/dateEnums';
import { fetchHomeDatalist } from '@/api/v1/system/system';
import { default as dayjs } from 'dayjs';
import { $t } from '@/plugins/i18n';
// 支出百分比
export const expendPercent = ref(0);
@ -27,63 +28,10 @@ export const onSearch = async () => {
const homeCard = result.data?.homeCard;
const income = homeCard?.income?.amount;
const expend = homeCard?.expend?.amount;
const incomeCharts = homeCard?.income?.charts;
const expendCharts = homeCard?.expend?.charts;
console.log(expend);
/* 收入金额 */
let data = {
icon: 'icon-park-outline:income',
bgColor: '#effaff',
color: '#67C23A',
duration: 2200,
name: '本月总收入',
value: income,
percent: <p class='font-medium text-green-500'>{`+ ${income}`}</p>,
data: incomeCharts,
};
chartData.value.push(data);
/* 支出金额 */
data = {
icon: 'icon-park-outline:expenses',
bgColor: '#fff5f4',
color: '#F56C6C',
duration: 2200,
name: '本月总支出',
value: expend,
percent: <p class='font-medium text-red-500'>{`- ${expend}`}</p>,
data: expendCharts,
};
chartData.value.push(data);
/* 盈利金额 */
const profit = incomeCharts.map((value, index) => {
const number = value - expendCharts[index];
return isNaN(number) ? 0 : number;
});
const profitValue = (income - expend).toFixed(2);
data = {
icon: 'hugeicons:profit',
bgColor: '#fff5f4',
color: '#409EFF',
duration: 2200,
name: '盈利金额',
value: Number(profitValue),
percent: <p class='font-medium text-blue-500'>{`${profitValue}`}</p>,
data: profit,
};
chartData.value.push(data);
/* 支出百分比 */
expendPercent.value = Number((expend / (income + expend)).toFixed(2)) * 100;
// 收入和支出排行榜
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 };
});
// 收入和支出分析概览
xAxis.value = result.data.homeOverview
.filter(item => item.type === 1)
@ -93,4 +41,64 @@ 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);
};
/**
*
* @param income
* @param expend
*/
function homeCardFun(income, expend) {
/* 收入金额 */
let data = {
icon: 'icon-park-outline:income',
bgColor: '#effaff',
color: '#67C23A',
duration: 2200,
name: $t('totalIncomeOfTheMonth'),
value: income,
percent: <p class='font-medium text-green-500'>{`+ ${income}`}</p>,
data: incomeData.value,
};
chartData.value.push(data);
/* 支出金额 */
data = {
icon: 'icon-park-outline:expenses',
bgColor: '#fff5f4',
color: '#F56C6C',
duration: 2200,
name: $t('totalExpendituresOfTheMonth'),
value: expend,
percent: <p class='font-medium text-red-500'>{`- ${expend}`}</p>,
data: expendData.value,
};
chartData.value.push(data);
/* 盈利金额 */
const profit = incomeData.value.map((value, index) => {
const number = value - expendData.value[index];
return isNaN(number) ? 0 : number;
});
const profitValue = (income - expend).toFixed(2);
data = {
icon: 'hugeicons:profit',
bgColor: '#fff5f4',
color: '#409EFF',
duration: 2200,
name: $t('amountOfProfit'),
value: Number(profitValue),
percent: <p class='font-medium text-blue-500'>{`${profitValue}`}</p>,
data: profit,
};
chartData.value.push(data);
}