大量的代码格式化
Some checks failed
Docker Build & Deploy / Build Docker Image (push) Failing after 1m10s
Docker Build & Deploy / Deploy to Production (push) Has been skipped
Docker Build & Deploy / Cleanup Dangling Images (push) Successful in 1s
Docker Build & Deploy / WeChat Notification (push) Successful in 1s

This commit is contained in:
孙诚
2026-01-16 11:15:44 +08:00
parent 9069e3dbcf
commit 319f8f7d7b
54 changed files with 2973 additions and 2200 deletions

View File

@@ -1,123 +1,124 @@
<template>
<PopupContainer
v-model="visible"
title="交易详情"
height="75%"
:closeable="false"
>
<PopupContainer v-model="visible" title="交易详情" height="75%" :closeable="false">
<template #header-actions>
<van-button size="small" type="primary" plain @click="handleOffsetClick">抵账</van-button>
<van-button size="small" type="primary" plain @click="handleOffsetClick"> 抵账 </van-button>
</template>
<van-form style="margin-top: 12px;">
<van-cell-group inset>
<van-cell title="记录时间" :value="formatDate(transaction.createTime)" />
</van-cell-group>
<van-form style="margin-top: 12px">
<van-cell-group inset>
<van-cell title="记录时间" :value="formatDate(transaction.createTime)" />
</van-cell-group>
<van-cell-group inset title="交易明细">
<van-field
v-model="occurredAtLabel"
name="occurredAt"
label="交易时间"
readonly
is-link
placeholder="请选择交易时间"
:rules="[{ required: true, message: '请选择交易时间' }]"
@click="showDatePicker = true"
/>
<van-field
v-model="editForm.reason"
name="reason"
label="交易摘要"
placeholder="请输入交易摘要"
type="textarea"
rows="2"
autosize
maxlength="200"
show-word-limit
/>
<van-field
v-model="editForm.amount"
name="amount"
label="交易金额"
placeholder="请输入交易金额"
type="number"
:rules="[{ required: true, message: '请输入交易金额' }]"
/>
<van-field
v-model="editForm.balance"
name="balance"
label="交易后余额"
placeholder="请输入交易后余额"
type="number"
:rules="[{ required: true, message: '请输入交易后余额' }]"
/>
<van-cell-group inset title="交易明细">
<van-field
v-model="occurredAtLabel"
name="occurredAt"
label="交易时间"
readonly
is-link
placeholder="请选择交易时间"
:rules="[{ required: true, message: '请选择交易时间' }]"
@click="showDatePicker = true"
/>
<van-field
v-model="editForm.reason"
name="reason"
label="交易摘要"
placeholder="请输入交易摘要"
type="textarea"
rows="2"
autosize
maxlength="200"
show-word-limit
/>
<van-field
v-model="editForm.amount"
name="amount"
label="交易金额"
placeholder="请输入交易金额"
type="number"
:rules="[{ required: true, message: '请输入交易金额' }]"
/>
<van-field
v-model="editForm.balance"
name="balance"
label="交易后余额"
placeholder="请输入交易后余额"
type="number"
:rules="[{ required: true, message: '请输入交易后余额' }]"
/>
<van-field name="type" label="交易类型">
<template #input>
<van-radio-group v-model="editForm.type" direction="horizontal" @change="handleTypeChange">
<van-radio :name="0">支出</van-radio>
<van-radio :name="1">收入</van-radio>
<van-radio :name="2">不计</van-radio>
</van-radio-group>
</template>
</van-field>
<van-field name="type" label="交易类型">
<template #input>
<van-radio-group
v-model="editForm.type"
direction="horizontal"
@change="handleTypeChange"
>
<van-radio :name="0"> 支出 </van-radio>
<van-radio :name="1"> 收入 </van-radio>
<van-radio :name="2"> 不计 </van-radio>
</van-radio-group>
</template>
</van-field>
<van-field name="classify" label="交易分类">
<template #input>
<div style="flex: 1;">
<div
v-if="transaction && transaction.unconfirmedClassify && transaction.unconfirmedClassify !== editForm.classify"
class="suggestion-tip"
@click="applySuggestion"
>
<van-icon name="bulb-o" class="suggestion-icon" />
<span class="suggestion-text">
建议: {{ transaction.unconfirmedClassify }}
<span v-if="transaction.unconfirmedType !== null && transaction.unconfirmedType !== undefined && transaction.unconfirmedType !== editForm.type">
({{ getTypeName(transaction.unconfirmedType) }})
</span>
<van-field name="classify" label="交易分类">
<template #input>
<div style="flex: 1">
<div
v-if="
transaction &&
transaction.unconfirmedClassify &&
transaction.unconfirmedClassify !== editForm.classify
"
class="suggestion-tip"
@click="applySuggestion"
>
<van-icon name="bulb-o" class="suggestion-icon" />
<span class="suggestion-text">
建议: {{ transaction.unconfirmedClassify }}
<span
v-if="
transaction.unconfirmedType !== null &&
transaction.unconfirmedType !== undefined &&
transaction.unconfirmedType !== editForm.type
"
>
({{ getTypeName(transaction.unconfirmedType) }})
</span>
<div class="suggestion-apply">应用</div>
</div>
<span v-else-if="!editForm.classify" style="color: var(--van-gray-5);">请选择交易分类</span>
<span v-else>{{ editForm.classify }}</span>
</span>
<div class="suggestion-apply">应用</div>
</div>
</template>
</van-field>
<ClassifySelector
v-model="editForm.classify"
:type="editForm.type"
@change="handleClassifyChange"
/>
</van-cell-group>
<span v-else-if="!editForm.classify" style="color: var(--van-gray-5)"
>请选择交易分类</span
>
<span v-else>{{ editForm.classify }}</span>
</div>
</template>
</van-field>
<ClassifySelector
v-model="editForm.classify"
:type="editForm.type"
@change="handleClassifyChange"
/>
</van-cell-group>
</van-form>
<template #footer>
<van-button
round
block
type="primary"
:loading="submitting"
@click="onSubmit"
>
<van-button round block type="primary" :loading="submitting" @click="onSubmit">
保存修改
</van-button>
</template>
</PopupContainer>
<!-- 抵账候选列表弹窗 -->
<PopupContainer
v-model="showOffsetPopup"
title="选择抵账交易"
height="75%"
>
<PopupContainer v-model="showOffsetPopup" title="选择抵账交易" height="75%">
<van-list>
<van-cell
v-for="item in offsetCandidates"
:key="item.id"
:title="item.reason"
<van-cell
v-for="item in offsetCandidates"
:key="item.id"
:title="item.reason"
:label="formatDate(item.occurredAt)"
:value="item.amount"
is-link
@@ -154,7 +155,11 @@ import { showToast, showConfirmDialog } from 'vant'
import dayjs from 'dayjs'
import PopupContainer from '@/components/PopupContainer.vue'
import ClassifySelector from '@/components/ClassifySelector.vue'
import { updateTransaction, getCandidatesForOffset, offsetTransactions } from '@/api/transactionRecord'
import {
updateTransaction,
getCandidatesForOffset,
offsetTransactions
} from '@/api/transactionRecord'
const props = defineProps({
show: {
@@ -196,35 +201,41 @@ const occurredAtLabel = computed(() => {
})
// 监听props变化
watch(() => props.show, (newVal) => {
visible.value = newVal
})
watch(() => props.transaction, (newVal) => {
if (newVal) {
isSyncing.value = true
// 填充编辑表单
editForm.id = newVal.id
editForm.reason = newVal.reason || ''
editForm.amount = String(newVal.amount)
editForm.balance = String(newVal.balance)
editForm.type = newVal.type
editForm.classify = newVal.classify || ''
// 初始化日期时间
if (newVal.occurredAt) {
editForm.occurredAt = newVal.occurredAt
const dt = dayjs(newVal.occurredAt)
currentDate.value = dt.format('YYYY-MM-DD').split('-')
currentTime.value = dt.format('HH:mm').split(':')
}
// 在下一个 tick 结束同步状态,确保 van-radio-group 的 @change 已触发完毕
nextTick(() => {
isSyncing.value = false
})
watch(
() => props.show,
(newVal) => {
visible.value = newVal
}
})
)
watch(
() => props.transaction,
(newVal) => {
if (newVal) {
isSyncing.value = true
// 填充编辑表单
editForm.id = newVal.id
editForm.reason = newVal.reason || ''
editForm.amount = String(newVal.amount)
editForm.balance = String(newVal.balance)
editForm.type = newVal.type
editForm.classify = newVal.classify || ''
// 初始化日期时间
if (newVal.occurredAt) {
editForm.occurredAt = newVal.occurredAt
const dt = dayjs(newVal.occurredAt)
currentDate.value = dt.format('YYYY-MM-DD').split('-')
currentTime.value = dt.format('HH:mm').split(':')
}
// 在下一个 tick 结束同步状态,确保 van-radio-group 的 @change 已触发完毕
nextTick(() => {
isSyncing.value = false
})
}
}
)
watch(visible, (newVal) => {
emit('update:show', newVal)
@@ -258,7 +269,10 @@ const onConfirmTime = ({ selectedValues }) => {
const applySuggestion = () => {
if (props.transaction.unconfirmedClassify) {
editForm.classify = props.transaction.unconfirmedClassify
if (props.transaction.unconfirmedType !== null && props.transaction.unconfirmedType !== undefined) {
if (
props.transaction.unconfirmedType !== null &&
props.transaction.unconfirmedType !== undefined
) {
editForm.type = props.transaction.unconfirmedType
}
}
@@ -277,7 +291,7 @@ const getTypeName = (type) => {
const onSubmit = async () => {
try {
submitting.value = true
const data = {
id: editForm.id,
reason: editForm.reason,
@@ -287,7 +301,7 @@ const onSubmit = async () => {
classify: editForm.classify,
occurredAt: editForm.occurredAt
}
const response = await updateTransaction(data)
if (response.success) {
showToast('保存成功')
@@ -314,11 +328,13 @@ const handleClassifyChange = () => {
// 清空分类
const formatDate = (dateString) => {
if (!dateString) return ''
if (!dateString) {
return ''
}
const date = new Date(dateString)
return date.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
return date.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit'
@@ -347,7 +363,7 @@ const handleOffsetClick = async () => {
const handleCandidateSelect = (candidate) => {
showConfirmDialog({
title: '确认抵账',
message: `确认将当前交易与 "${candidate.reason}" (${candidate.amount}) 互相抵消吗?\n抵消后两笔交易将被删除`,
message: `确认将当前交易与 "${candidate.reason}" (${candidate.amount}) 互相抵消吗\n抵消后两笔交易将被删除`
})
.then(async () => {
try {
@@ -367,7 +383,7 @@ const handleCandidateSelect = (candidate) => {
})
.catch(() => {
// on cancel
});
})
}
</script>