fix: S2 缺陷修复 — emoji/类型/双重请求/动画/prefers-reduced-motion

This commit is contained in:
2026-06-08 16:53:27 +08:00
parent 618cd20ebf
commit 4e43a9049a
11 changed files with 47 additions and 26 deletions

View File

@@ -136,7 +136,7 @@ onMounted(async () => {
}
const pages = getCurrentPages()
const page = pages[pages.length - 1] as any
const page = pages[pages.length - 1] as { options?: Record<string, string> }
if (page?.options?.type && ['expense', 'income'].includes(page.options.type)) {
type.value = page.options.type
}

View File

@@ -86,6 +86,7 @@ import { onShow, onPullDownRefresh } from '@dcloudio/uni-app'
import { waitForReady } from '@/utils/app-ready'
import { statusBarHeight } from '@/utils/system'
import { getFeedbackList, updateFeedbackStatus } from '@/api/feedback'
import type { Feedback } from '@/api/feedback'
import { API_BASE } from '@/config'
import Icon from '@/components/Icon/Icon.vue'
@@ -102,7 +103,7 @@ const statusMap: Record<string, string> = {
ignored: '已忽略'
}
const list = ref<any[]>([])
const list = ref<Feedback[]>([])
const loading = ref(false)
const filterStatus = ref('')
const page = ref(1)
@@ -138,7 +139,7 @@ async function loadList(reset = false) {
}
loading.value = true
try {
const params: any = { page: page.value, pageSize }
const params: { page: number; pageSize: number; status?: string } = { page: page.value, pageSize }
if (filterStatus.value) params.status = filterStatus.value
const data = await getFeedbackList(params)
if (reset) {
@@ -160,7 +161,7 @@ function loadMore() {
loadList(false)
}
async function updateStatus(item: any, status: string) {
async function updateStatus(item: Feedback, status: string) {
try {
await updateFeedbackStatus(item.id, status)
item.status = status

View File

@@ -180,14 +180,12 @@ function loadMore() {
function selectDate(date: string) {
selectedDate.value = date
page.value = 1
loadLogs()
// loadLogs() 由 watch([filterLevel, selectedDate]) 统一触发,避免双重请求
}
function onDateChange(e: any) {
selectedDate.value = e.detail.value
page.value = 1
loadLogs()
// loadLogs() 由 watch 统一触发
}
function getBarWidth(count: number): number {

View File

@@ -96,7 +96,7 @@ async function loadUsers(reset = false) {
}
loading.value = true
try {
const params: any = { page: page.value, pageSize: 20 }
const params: { page: number; pageSize: number; keyword?: string } = { page: page.value, pageSize: 20 }
if (keyword.value.trim()) params.keyword = keyword.value.trim()
const data = await getUsers(params)
if (reset) {

View File

@@ -79,8 +79,9 @@
<text class="state-text">加载失败下拉刷新重试</text>
</view>
<view class="empty" v-if="txList.length === 0 && !loading && !loadError">
<text class="empty-text">暂无账单记录</text>
<view class="state-box" v-if="txList.length === 0 && !loading && !loadError">
<Icon name="edit" :size="48" color="#BFB3B3" />
<text class="state-text">暂无账单记录</text>
</view>
</view>
</template>
@@ -98,6 +99,7 @@ import Skeleton from '@/components/Skeleton/Skeleton.vue'
import FilterPanel from './filter-panel.vue'
import { statusBarHeight } from '@/utils/system'
import { formatAmount, formatDate } from '@/utils/format'
import type { Transaction, TransactionParams } from '@/api/transaction'
import type { FilterParams } from '@/api/filter'
const userStore = useUserStore()
@@ -106,7 +108,7 @@ const loading = ref(false)
const filterType = ref('all')
const page = ref(1)
const pageSize = 20
const txList = ref<any[]>([])
const txList = ref<Transaction[]>([])
const total = ref(0)
const loadError = ref(false)
let loadSeq = 0 // 请求序号,防止并发覆盖
@@ -162,7 +164,7 @@ async function loadTx(reset = false, silent = false) {
if (!silent) txList.value = []
}
const seq = ++loadSeq
const params: any = { page: page.value, pageSize, group_id: groupStore.currentGroupId }
const params: TransactionParams & { group_id?: number | null; category_ids?: string } = { page: page.value, pageSize, group_id: groupStore.currentGroupId }
if (filterType.value !== 'all') params.type = filterType.value
// 合并高级筛选参数
const af = advancedFilters.value
@@ -369,13 +371,6 @@ onPullDownRefresh(() => {
.loading-text { font-size: $font-md; color: $text-muted; }
.empty {
text-align: center;
padding: 120rpx 0;
}
.empty-text { font-size: $font-lg; color: $text-muted; }
.state-box {
@include state-box;
justify-content: center;

View File

@@ -81,6 +81,7 @@ import { useGroupStore } from '@/stores/group'
import { getOverview } from '@/api/stats'
import { waitForReady } from '@/utils/app-ready'
import { formatAmount, getCurrentMonth } from '@/utils/format'
import type { Budget } from '@/api/budget'
import { statusBarHeight } from '@/utils/system'
import BudgetBar from '@/components/BudgetBar/BudgetBar.vue'
import Numpad from '@/components/Numpad/Numpad.vue'
@@ -90,7 +91,7 @@ const budgetStore = useBudgetStore()
const groupStore = useGroupStore()
const currentMonth = getCurrentMonth()
const budget = ref<any>(null)
const budget = ref<Budget | null>(null)
const budgetAmount = ref(0)
const monthExpense = ref(0)
const loading = ref(true)

View File

@@ -146,6 +146,7 @@ import { useGroupStore } from '@/stores/group'
import { useNotificationStore } from '@/stores/notification'
import { waitForReady } from '@/utils/app-ready'
import { getOverview } from '@/api/stats'
import type { Transaction } from '@/api/transaction'
import { getNotificationImageUrl } from '@/api/notification'
import { formatAmount, formatAmountRaw } from '@/utils/format'
import { statusBarHeight, capsuleRight } from '@/utils/system'
@@ -165,7 +166,7 @@ const DEFAULT_BUDGET = 500000 // 5000元
const overview = computed(() => statsStore.overview)
const budget = computed(() => budgetStore.budget)
const recentTx = ref<any[]>([])
const recentTx = ref<Transaction[]>([])
const loading = ref(true)
const loadError = ref(false)
const todayExpense = ref(0)

View File

@@ -39,7 +39,7 @@
</view>
<view class="notif-content">
<view class="notif-title-row">
<text v-if="item.is_pinned" class="pin-badge">📌</text>
<text v-if="item.is_pinned" class="pin-badge">置顶</text>
<text class="notif-title">{{ item.title }}</text>
</view>
<text class="notif-body" v-if="item.content">{{ item.content }}</text>
@@ -355,7 +355,12 @@ onReachBottom(() => {
}
.pin-badge {
font-size: $font-md;
font-size: $font-xs;
color: $primary;
background: #FFE8E0;
padding: 2rpx 10rpx;
border-radius: $radius-xs;
font-weight: 500;
}
.notif-title {

View File

@@ -144,6 +144,7 @@ import { useGroupStore } from '@/stores/group'
import { useConfigStore } from '@/stores/config'
import { waitForReady } from '@/utils/app-ready'
import { getTransactions } from '@/api/transaction'
import type { Transaction } from '@/api/transaction'
import { formatAmount } from '@/utils/format'
import { statusBarHeight } from '@/utils/system'
import Icon from '@/components/Icon/Icon.vue'
@@ -326,7 +327,7 @@ async function exportData() {
uni.showLoading({ title: '导出中 0%' })
try {
// 分页获取全部数据(服务端 pageSize 上限 100
const allList: any[] = []
const allList: Transaction[] = []
let page = 1
let total = 0
do {

View File

@@ -548,6 +548,10 @@ function getBarWidth(amount: number) {
border-radius: 6rpx;
background: linear-gradient(90deg, $primary, #FFB89A);
transition: width 0.6s ease-out;
@media (prefers-reduced-motion: reduce) {
transition: none;
}
}
.trend-amount {