|
@@ -137,7 +137,7 @@
|
|
|
<text v-if="getPropertyValue(item, 'score') !== ''" class="score-text">{{ formatNumber(parseFloat(getPropertyValue(item, 'score'))) }}</text>
|
|
<text v-if="getPropertyValue(item, 'score') !== ''" class="score-text">{{ formatNumber(parseFloat(getPropertyValue(item, 'score'))) }}</text>
|
|
|
<!-- <text class="status-text">{{ getOrderStatusText(getPropertyValue(item, 'scoreStatus')) }}</text> -->
|
|
<!-- <text class="status-text">{{ getOrderStatusText(getPropertyValue(item, 'scoreStatus')) }}</text> -->
|
|
|
</view>
|
|
</view>
|
|
|
- </view>
|
|
|
|
|
|
|
+ </view>
|
|
|
<view class="info-row">
|
|
<view class="info-row">
|
|
|
<view class="info-label">
|
|
<view class="info-label">
|
|
|
<text class="text-gray">工作结束时间: {{ formatDate(getPropertyValue(item, 'realEndTime')) }}</text>
|
|
<text class="text-gray">工作结束时间: {{ formatDate(getPropertyValue(item, 'realEndTime')) }}</text>
|
|
@@ -188,7 +188,7 @@
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup lang="uts">
|
|
<script setup lang="uts">
|
|
|
- import { ref, computed, onMounted } from 'vue'
|
|
|
|
|
|
|
+ import { ref, computed, onMounted, onBeforeUnmount } from 'vue'
|
|
|
import { listOrderScores, getOrderScoreStatistics, listMobileOrderScores } from '@/api/score/index'
|
|
import { listOrderScores, getOrderScoreStatistics, listMobileOrderScores } from '@/api/score/index'
|
|
|
import { getDictDataByType } from '@/api/dict/index'
|
|
import { getDictDataByType } from '@/api/dict/index'
|
|
|
import type { SysDictData } from '@/types/dict'
|
|
import type { SysDictData } from '@/types/dict'
|
|
@@ -209,6 +209,12 @@
|
|
|
const totalRankingUsers = ref<number | null>(null)
|
|
const totalRankingUsers = ref<number | null>(null)
|
|
|
const customDate = ref<string>('')
|
|
const customDate = ref<string>('')
|
|
|
|
|
|
|
|
|
|
+ // 防止重复请求的标志位
|
|
|
|
|
+ const isSearching = ref<boolean>(false)
|
|
|
|
|
+
|
|
|
|
|
+ // 添加防抖定时器
|
|
|
|
|
+ let searchTimer: number | null = null
|
|
|
|
|
+
|
|
|
// 弹窗显示状态
|
|
// 弹窗显示状态
|
|
|
const showDatePickerPopup = ref<boolean>(false)
|
|
const showDatePickerPopup = ref<boolean>(false)
|
|
|
const showDatePicker = ref<boolean>(false)
|
|
const showDatePicker = ref<boolean>(false)
|
|
@@ -509,6 +515,11 @@
|
|
|
|
|
|
|
|
// 方法
|
|
// 方法
|
|
|
function loadData(isRefresh: boolean) {
|
|
function loadData(isRefresh: boolean) {
|
|
|
|
|
+ // 防止重复请求
|
|
|
|
|
+ if (loading.value && !isRefresh) {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
const shouldRefresh = isRefresh
|
|
const shouldRefresh = isRefresh
|
|
|
|
|
|
|
|
if (loading.value && !shouldRefresh) {
|
|
if (loading.value && !shouldRefresh) {
|
|
@@ -576,25 +587,91 @@
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function handleSearch() {
|
|
function handleSearch() {
|
|
|
- loadData(true)
|
|
|
|
|
|
|
+ // 添加防抖和防止重复请求
|
|
|
|
|
+ if (isSearching.value) {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const timer = searchTimer
|
|
|
|
|
+ if (timer != null) {
|
|
|
|
|
+ clearTimeout(timer)
|
|
|
|
|
+ searchTimer = null
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ searchTimer = setTimeout(() => {
|
|
|
|
|
+ isSearching.value = true
|
|
|
|
|
+ loadData(true)
|
|
|
|
|
+ // 延迟重置标志位,确保请求发送后才允许下一次搜索
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ isSearching.value = false
|
|
|
|
|
+ }, 100)
|
|
|
|
|
+ }, 300)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function clearSearch() {
|
|
function clearSearch() {
|
|
|
|
|
+ // 添加防抖和防止重复请求
|
|
|
|
|
+ if (isSearching.value) {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const timer = searchTimer
|
|
|
|
|
+ if (timer != null) {
|
|
|
|
|
+ clearTimeout(timer)
|
|
|
|
|
+ searchTimer = null
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
searchKeyword.value = ""
|
|
searchKeyword.value = ""
|
|
|
- loadData(true)
|
|
|
|
|
|
|
+ searchTimer = setTimeout(() => {
|
|
|
|
|
+ isSearching.value = true
|
|
|
|
|
+ loadData(true)
|
|
|
|
|
+ // 延迟重置标志位,确保请求发送后才允许下一次搜索
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ isSearching.value = false
|
|
|
|
|
+ }, 100)
|
|
|
|
|
+ }, 300)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function filterByStatus(status: string) {
|
|
function filterByStatus(status: string) {
|
|
|
|
|
+ // 添加防止重复请求
|
|
|
|
|
+ if (isSearching.value) {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const timer = searchTimer
|
|
|
|
|
+ if (timer != null) {
|
|
|
|
|
+ clearTimeout(timer)
|
|
|
|
|
+ searchTimer = null
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
statusFilter.value = status
|
|
statusFilter.value = status
|
|
|
- loadData(true)
|
|
|
|
|
- getStatistics()
|
|
|
|
|
|
|
+ searchTimer = setTimeout(() => {
|
|
|
|
|
+ isSearching.value = true
|
|
|
|
|
+ loadData(true)
|
|
|
|
|
+ getStatistics()
|
|
|
|
|
+ // 延迟重置标志位,确保请求发送后才允许下一次搜索
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ isSearching.value = false
|
|
|
|
|
+ }, 100)
|
|
|
|
|
+ }, 300)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- function changeMonth(month: string) {
|
|
|
|
|
|
|
+ function changeMonth(month: string) {
|
|
|
|
|
+ // 添加防止重复请求
|
|
|
|
|
+ if (isSearching.value) {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const timer = searchTimer
|
|
|
|
|
+ if (timer != null) {
|
|
|
|
|
+ clearTimeout(timer)
|
|
|
|
|
+ searchTimer = null
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
selectedMonth.value = month
|
|
selectedMonth.value = month
|
|
|
- //loadData(true)
|
|
|
|
|
- getStatistics()
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ searchTimer = setTimeout(() => {
|
|
|
|
|
+ getStatistics()
|
|
|
|
|
+ }, 300)
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
function loadMore() {
|
|
function loadMore() {
|
|
|
if (!hasMore.value || loading.value) return
|
|
if (!hasMore.value || loading.value) return
|
|
@@ -656,6 +733,15 @@
|
|
|
getStatistics()
|
|
getStatistics()
|
|
|
dictLoaded.value = true
|
|
dictLoaded.value = true
|
|
|
})
|
|
})
|
|
|
|
|
+
|
|
|
|
|
+ // 组件销毁时清除定时器
|
|
|
|
|
+ onBeforeUnmount(() => {
|
|
|
|
|
+ const timer = searchTimer
|
|
|
|
|
+ if (timer != null) {
|
|
|
|
|
+ clearTimeout(timer)
|
|
|
|
|
+ searchTimer = null
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style lang="scss">
|
|
<style lang="scss">
|