完成70%
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
class="people-page"
|
||||
:class="{
|
||||
'people-state--ready': peopleState === 'ready',
|
||||
'people-state--loading': peopleState === 'loading',
|
||||
'people-state--empty': peopleState === 'empty',
|
||||
'people-state--error': peopleState === 'error',
|
||||
}"
|
||||
@@ -12,7 +13,12 @@
|
||||
<view class="people-page__header"><PageHeader title="人物录" /></view>
|
||||
|
||||
<view class="people-content">
|
||||
<template v-if="peopleState === 'ready'">
|
||||
<AppLoading
|
||||
v-if="peopleState === 'loading'"
|
||||
text="正在读取人物录"
|
||||
description="请稍候,正在读取当前家谱的人物资料。"
|
||||
/>
|
||||
<template v-else-if="peopleState === 'ready'">
|
||||
<view class="people-search">
|
||||
<input
|
||||
v-model="keywordInput"
|
||||
@@ -30,9 +36,9 @@
|
||||
>
|
||||
</view>
|
||||
|
||||
<view v-if="filteredPeople.length" class="people-list">
|
||||
<view v-if="people.length" class="people-list">
|
||||
<view
|
||||
v-for="person in filteredPeople"
|
||||
v-for="person in people"
|
||||
:key="person.id"
|
||||
class="person-card"
|
||||
@click="openPerson(person)"
|
||||
@@ -46,10 +52,12 @@
|
||||
</view>
|
||||
</view>
|
||||
<AppButton
|
||||
v-if="hasMore"
|
||||
class="people-primary-action"
|
||||
type="secondary"
|
||||
block
|
||||
label="填写人物预览"
|
||||
@click="createPersonPreview"
|
||||
:label="loadingMore ? '正在加载…' : '加载更多人物'"
|
||||
@click="loadMore"
|
||||
/>
|
||||
</view>
|
||||
|
||||
@@ -85,9 +93,10 @@
|
||||
}}</text>
|
||||
</view>
|
||||
<AppButton
|
||||
v-if="peopleState !== 'empty'"
|
||||
:type="peopleState === 'empty' ? 'primary' : 'secondary'"
|
||||
block
|
||||
:label="peopleState === 'error' ? '重新查看' : peopleState === 'invalid' ? '返回上一页' : '填写人物预览'"
|
||||
:label="peopleState === 'error' ? '重新查看' : '返回上一页'"
|
||||
@click="handleStateAction"
|
||||
/>
|
||||
</view>
|
||||
@@ -96,15 +105,13 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onLoad } from "@dcloudio/uni-app";
|
||||
import { onLoad, onUnload } from "@dcloudio/uni-app";
|
||||
import { computed, ref } from "vue";
|
||||
import AppButton from "@/components/AppButton.vue";
|
||||
import AppLoading from "@/components/AppLoading.vue";
|
||||
import ModulePageBackground from "@/components/ModulePageBackground.vue";
|
||||
import PageHeader from "@/components/PageHeader.vue";
|
||||
import {
|
||||
getGenealogyFixtureAccess,
|
||||
listTreeMemberPresentationFixtures,
|
||||
} from "@/data/mock.js";
|
||||
import { appApi, createRequestController, isRequestCancelled } from "@/utils/api.js";
|
||||
import { goBack, openPage } from "@/utils/navigation.js";
|
||||
|
||||
const genealogyId = ref("");
|
||||
@@ -112,17 +119,13 @@ const people = ref([]);
|
||||
const peopleState = ref("ready");
|
||||
const keywordInput = ref("");
|
||||
const keyword = ref("");
|
||||
const hasValidContext = computed(() => peopleState.value !== "invalid");
|
||||
|
||||
const filteredPeople = computed(() => {
|
||||
const value = keyword.value.trim().toLowerCase();
|
||||
if (!value) return people.value;
|
||||
return people.value.filter((person) =>
|
||||
`${person.name} ${person.relation} ${person.branch || ""} ${person.generationName || ""} 第${person.generation}世 ${person.generation}`
|
||||
.toLowerCase()
|
||||
.includes(value),
|
||||
);
|
||||
});
|
||||
const total = ref(0);
|
||||
const pageNum = ref(1);
|
||||
const loadingMore = ref(false);
|
||||
const peopleRequestController = createRequestController();
|
||||
let loadSequence = 0;
|
||||
const hasValidContext = computed(() => Boolean(genealogyId.value));
|
||||
const hasMore = computed(() => people.value.length < total.value);
|
||||
|
||||
const applySearch = () => {
|
||||
if (keyword.value) {
|
||||
@@ -130,14 +133,42 @@ const applySearch = () => {
|
||||
return;
|
||||
}
|
||||
keyword.value = keywordInput.value.trim();
|
||||
pageNum.value = 1;
|
||||
void loadPeople();
|
||||
};
|
||||
const clearSearch = () => {
|
||||
keywordInput.value = "";
|
||||
keyword.value = "";
|
||||
pageNum.value = 1;
|
||||
void loadPeople();
|
||||
};
|
||||
const restoreList = () => {
|
||||
people.value = listTreeMemberPresentationFixtures(genealogyId.value);
|
||||
peopleState.value = people.value.length ? "ready" : "empty";
|
||||
const loadPeople = async ({ append = false } = {}) => {
|
||||
if (!hasValidContext.value) return;
|
||||
const activeLoad = ++loadSequence;
|
||||
if (append) loadingMore.value = true;
|
||||
else peopleState.value = "loading";
|
||||
try {
|
||||
const result = await appApi.getPersonPage(
|
||||
genealogyId.value,
|
||||
{ pageNum: pageNum.value, pageSize: 10, keyword: keyword.value },
|
||||
{ requestController: peopleRequestController },
|
||||
);
|
||||
if (activeLoad !== loadSequence) return;
|
||||
people.value = append ? [...people.value, ...result.rows] : result.rows;
|
||||
total.value = result.total;
|
||||
peopleState.value = people.value.length ? "ready" : "empty";
|
||||
} catch (error) {
|
||||
if (activeLoad !== loadSequence || isRequestCancelled(error)) return;
|
||||
if (!append) people.value = [];
|
||||
peopleState.value = "error";
|
||||
} finally {
|
||||
if (activeLoad === loadSequence) loadingMore.value = false;
|
||||
}
|
||||
};
|
||||
const loadMore = () => {
|
||||
if (loadingMore.value || !hasMore.value) return;
|
||||
pageNum.value += 1;
|
||||
void loadPeople({ append: true });
|
||||
};
|
||||
const openPerson = (person) =>
|
||||
hasValidContext.value
|
||||
@@ -151,34 +182,27 @@ const openPerson = (person) =>
|
||||
"R01",
|
||||
)
|
||||
: Promise.resolve(false);
|
||||
const createPersonPreview = () =>
|
||||
hasValidContext.value
|
||||
? openPage(
|
||||
"R02",
|
||||
{ genealogyId: genealogyId.value, mode: "create" },
|
||||
"R01",
|
||||
)
|
||||
: Promise.resolve(false);
|
||||
const handleStateAction = () => {
|
||||
if (peopleState.value === "invalid") return goBack();
|
||||
if (peopleState.value === "error") return restoreList();
|
||||
return createPersonPreview();
|
||||
if (peopleState.value === "error") {
|
||||
pageNum.value = 1;
|
||||
return loadPeople();
|
||||
}
|
||||
return goBack();
|
||||
};
|
||||
|
||||
onLoad((query) => {
|
||||
genealogyId.value = String(query.genealogyId || "");
|
||||
const access = getGenealogyFixtureAccess(genealogyId.value);
|
||||
if (!["owner", "member"].includes(access.accessRole)) {
|
||||
if (!hasValidContext.value || query.state === "error") {
|
||||
people.value = [];
|
||||
peopleState.value = "invalid";
|
||||
return;
|
||||
}
|
||||
people.value = listTreeMemberPresentationFixtures(genealogyId.value);
|
||||
peopleState.value = ["empty", "error"].includes(query.state)
|
||||
? query.state
|
||||
: people.value.length
|
||||
? "ready"
|
||||
: "empty";
|
||||
void loadPeople();
|
||||
});
|
||||
onUnload(() => {
|
||||
loadSequence += 1;
|
||||
peopleRequestController.abort();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user