feat: 完成前端业务闭环与后端联调
This commit is contained in:
@@ -63,7 +63,7 @@
|
||||
v-if="hasMore"
|
||||
block
|
||||
type="secondary"
|
||||
:label="loadingMore ? '正在加载…' : '加载更多成员'"
|
||||
:label="loadingMore ? '正在加载…' : loadMoreError ? '加载失败,重新加载' : '加载更多成员'"
|
||||
@click="loadMore"
|
||||
/>
|
||||
</template>
|
||||
@@ -109,9 +109,10 @@ const members = ref([]);
|
||||
const total = ref(0);
|
||||
const pageNum = ref(1);
|
||||
const loadingMore = ref(false);
|
||||
const loadMoreError = ref(false);
|
||||
const memberDirectoryRequestController = createRequestController();
|
||||
let loadSequence = 0;
|
||||
const hasValidContext = computed(() => Boolean(genealogyId.value));
|
||||
const hasValidContext = computed(() => /^[1-9]\d*$/.test(genealogyId.value));
|
||||
const memberMeta = (member) =>
|
||||
`第 ${member.generation} 世 · ${member.generationName || "字辈待补"} · ${member.branch}`;
|
||||
const memberStatus = (member) => {
|
||||
@@ -124,22 +125,30 @@ const hasMore = computed(() => members.value.length < total.value);
|
||||
const loadMembers = async ({ append = false } = {}) => {
|
||||
if (!hasValidContext.value) return;
|
||||
const activeLoad = ++loadSequence;
|
||||
if (append) loadingMore.value = true;
|
||||
const requestedPage = append ? pageNum.value + 1 : 1;
|
||||
if (append) {
|
||||
loadingMore.value = true;
|
||||
loadMoreError.value = false;
|
||||
}
|
||||
else directoryState.value = "loading";
|
||||
try {
|
||||
const personPage = await lineageApi.getPersonPage(
|
||||
genealogyId.value,
|
||||
{ pageNum: pageNum.value, pageSize: 10, keyword: keyword.value },
|
||||
{ pageNum: requestedPage, pageSize: 10, keyword: keyword.value },
|
||||
{ requestController: memberDirectoryRequestController },
|
||||
);
|
||||
if (activeLoad !== loadSequence) return;
|
||||
members.value = append ? [...members.value, ...personPage.rows] : personPage.rows;
|
||||
pageNum.value = requestedPage;
|
||||
total.value = personPage.total;
|
||||
directoryState.value = members.value.length ? "list" : "empty";
|
||||
} catch (error) {
|
||||
if (activeLoad !== loadSequence || isRequestCancelled(error)) return;
|
||||
if (!append) members.value = [];
|
||||
directoryState.value = "error";
|
||||
if (append) loadMoreError.value = true;
|
||||
else {
|
||||
members.value = [];
|
||||
directoryState.value = "error";
|
||||
}
|
||||
} finally {
|
||||
if (activeLoad === loadSequence) loadingMore.value = false;
|
||||
}
|
||||
@@ -153,17 +162,16 @@ onLoad((query) => {
|
||||
void loadMembers();
|
||||
});
|
||||
const searchMembers = () => {
|
||||
pageNum.value = 1;
|
||||
loadMoreError.value = false;
|
||||
void loadMembers();
|
||||
};
|
||||
const loadMore = () => {
|
||||
if (loadingMore.value || !hasMore.value) return;
|
||||
pageNum.value += 1;
|
||||
void loadMembers({ append: true });
|
||||
};
|
||||
const retryDirectory = () => {
|
||||
if (!hasValidContext.value) return goBack();
|
||||
pageNum.value = 1;
|
||||
loadMoreError.value = false;
|
||||
return loadMembers();
|
||||
};
|
||||
const openMember = (item) =>
|
||||
@@ -199,16 +207,21 @@ onUnload(() => {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
gap: 20rpx;
|
||||
box-sizing: border-box;
|
||||
padding: 22rpx 32rpx 0;
|
||||
}
|
||||
.directory-context__name {
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
color: $ink;
|
||||
font-family: "STKaiti", "KaiTi", serif;
|
||||
font-size: clamp(17px, 32rpx, 22px);
|
||||
font-weight: 700;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
.directory-context__meta {
|
||||
flex: 0 0 auto;
|
||||
color: #62584c;
|
||||
font-size: clamp(15px, 24rpx, 18px);
|
||||
font-weight: 500;
|
||||
@@ -248,7 +261,7 @@ onUnload(() => {
|
||||
color: #776956;
|
||||
}
|
||||
.directory-content {
|
||||
padding: 22rpx 24rpx 50rpx;
|
||||
padding: 22rpx 24rpx calc(50rpx + env(safe-area-inset-bottom));
|
||||
}
|
||||
.directory-summary {
|
||||
display: flex;
|
||||
|
||||
Reference in New Issue
Block a user