Browse Source

Merge branch 'master' into dev-xjf

pull/97/head
肖晋飞 3 weeks ago
parent
commit
774f624f4d
  1. 13
      src/api/alert/model/model/models.ts
  2. 6
      src/api/alert/model/models.ts
  3. 134
      src/views/model/list/ModelCard.vue

13
src/api/alert/model/model/models.ts

@ -7,6 +7,14 @@ export interface ModelCardItem {
createTime: string
}
export interface PageResult<T> {
total: number
current: number
size: number
records: T[]
pages: number
}
interface MovingWindows {
windowLength: number
samplingInterval: number
@ -32,3 +40,8 @@ export interface ModelQueryParams {
visible?: number | null
trash?: number | null
}
export interface ModelCardQueryParams extends ModelQueryParams {
pageNo?: number
pageSize?: number
}

6
src/api/alert/model/models.ts

@ -1,4 +1,4 @@
import type { ModelCardItem, ModelInfo, ModelQueryParams } from './model/models'
import type { ModelCardItem, ModelCardQueryParams, ModelInfo, PageResult } from './model/models'
import { defHttp } from '@/utils/http/axios'
enum Api {
@ -17,8 +17,8 @@ enum Api {
VERSION_LIST = '/alert/model/version/',
VERSION_NEW = '/alert/model/version/new/',
}
export function modelCardListApi(params?: ModelQueryParams) {
return defHttp.get<ModelCardItem[]>({ url: Api.MODEL_CARD_LIST, params })
export function modelCardListApi(params?: ModelCardQueryParams) {
return defHttp.get<PageResult<ModelCardItem>>({ url: Api.MODEL_CARD_LIST, params })
}
export const modelInfoApi = (idOrPath: any) => defHttp.get<any>({ url: `${Api.MODEL_INFO}/${idOrPath}` })

134
src/views/model/list/ModelCard.vue

@ -1,11 +1,11 @@
<script lang="ts" setup>
import { Card, Dropdown, Menu, Popconfirm } from 'ant-design-vue'
import type { PropType } from 'vue'
import { ref, watch } from 'vue'
import { onBeforeUnmount, onMounted, ref, watch } from 'vue'
import type { ModelItem } from './data'
import Icon from '@/components/Icon/index'
import { modelCardListApi, modelDeleteApi } from '@/api/alert/model/models'
import type { ModelQueryParams } from '@/api/alert/model/model/models'
import type { ModelCardQueryParams } from '@/api/alert/model/model/models'
import { useGo } from '@/hooks/web/usePage'
import { useMessage } from '@/hooks/web/useMessage'
@ -34,12 +34,19 @@ function changeModel(id, version?) {
}
const modelCardList = ref<Array<ModelItem>>([])
const lastQuery = ref<ModelQueryParams | null>(null)
const rootRef = ref<HTMLElement | null>(null)
const loadMoreTriggerRef = ref<HTMLElement | null>(null)
const lastQuery = ref<ModelCardQueryParams | null>(null)
const pageNo = ref(1)
const pageSize = 25
const listLoading = ref(false)
const noMore = ref(false)
let loadMoreObserver: IntersectionObserver | null = null
const colors = ['#8dc63f', '#dbb09e']
const statusStr = ['未下装', '已下装']
const statusIcons = ['ant-design:unlock-outlined', 'ant-design:lock-outlined']
function buildQuery(value: any): ModelQueryParams {
function buildQuery(value: any): ModelCardQueryParams {
return {
unitId: value?.unit,
typeId: value?.type,
@ -48,14 +55,7 @@ function buildQuery(value: any): ModelQueryParams {
}
}
async function loadModelList(value: any) {
const queryParams = buildQuery(value)
lastQuery.value = queryParams
const modelList = await modelCardListApi(queryParams)
if (!modelList) {
modelCardList.value = []
return
}
function normalizeCards(modelList: any[] = []): ModelItem[] {
const cardList: ModelItem[] = []
for (const modelCard of modelList) {
const statusIndex = Number(modelCard.status) || 0
@ -78,7 +78,40 @@ async function loadModelList(value: any) {
}
cardList.push(card)
}
modelCardList.value = cardList
return cardList
}
async function fetchModelList(queryParams: ModelCardQueryParams, append: boolean) {
if (listLoading.value)
return
listLoading.value = true
try {
const pageResult = await modelCardListApi({
...queryParams,
pageNo: pageNo.value,
pageSize,
})
if (!pageResult) {
modelCardList.value = []
noMore.value = true
return
}
const records = pageResult.records || []
const cardList = normalizeCards(records)
modelCardList.value = append ? modelCardList.value.concat(cardList) : cardList
noMore.value = pageResult.pages ? pageResult.current >= pageResult.pages : records.length < pageSize
}
finally {
listLoading.value = false
}
}
async function loadModelList(value: any) {
pageNo.value = 1
noMore.value = false
const queryParams = buildQuery(value)
lastQuery.value = queryParams
await fetchModelList(queryParams, false)
}
watch(
@ -103,16 +136,64 @@ function goCreateModel() {
query.push(`unitId=${encodeURIComponent(String(props.unitId))}`)
go(`/model/create${query.length ? `?${query.join('&')}` : ''}`)
}
async function loadMore() {
if (listLoading.value || noMore.value || !lastQuery.value)
return
pageNo.value += 1
await fetchModelList(lastQuery.value, true)
}
function getScrollParent(el: HTMLElement | null) {
let current = el?.parentElement || null
while (current) {
const style = window.getComputedStyle(current)
if (/(auto|scroll)/.test(style.overflowY))
return current
current = current.parentElement
}
return null
}
function initLoadMoreObserver() {
if (loadMoreObserver) {
loadMoreObserver.disconnect()
loadMoreObserver = null
}
const target = loadMoreTriggerRef.value
if (!target)
return
const root = getScrollParent(rootRef.value)
loadMoreObserver = new IntersectionObserver(
(entries) => {
if (entries.some(entry => entry.isIntersecting))
loadMore()
},
{ root, rootMargin: '160px 0px' },
)
loadMoreObserver.observe(target)
}
onMounted(() => {
initLoadMoreObserver()
})
onBeforeUnmount(() => {
if (loadMoreObserver) {
loadMoreObserver.disconnect()
loadMoreObserver = null
}
})
</script>
<template>
<div class="enter-y">
<div ref="rootRef" class="enter-y">
<div class="card-grid">
<template v-for="item in modelCardList" :key="item.title">
<Dropdown :trigger="['contextmenu']">
<Card
size="small"
:loading="loading"
:loading="loading || (listLoading && !modelCardList.length)"
:hoverable="true"
class="model-card"
:style="{ borderLeft: `6px solid ${item.statusColor}` }"
@ -168,6 +249,14 @@ function goCreateModel() {
<Icon icon="ic:sharp-add" :size="80" color="#a7a9a7" />
</Card>
</div>
<div ref="loadMoreTriggerRef" class="load-more-trigger" />
<div v-if="modelCardList.length" class="load-status">
<span v-if="listLoading">加载中...</span>
<span v-else-if="noMore">没有更多了</span>
</div>
<div v-else-if="!listLoading" class="load-status empty">
暂无数据
</div>
</div>
</template>
@ -315,4 +404,19 @@ function goCreateModel() {
background-color: #eef2ff;
border-color: #4c7af0;
}
.load-status {
padding: 12px 0 4px;
font-size: 12px;
color: #9ca3af;
text-align: center;
}
.load-status.empty {
padding-top: 24px;
}
.load-more-trigger {
height: 1px;
}
</style>

Loading…
Cancel
Save