Files
gaoYuJournal/miniprogram/components/journal-list/index.ts
2025-12-08 18:47:44 +08:00

232 lines
5.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// components/journal-list/index.ts
import config from "../../config/index";
import { JournalPage, JournalPageType } from "../../types/Journal";
import Time from "../../utils/Time";
import Toolkit from "../../utils/Toolkit";
export type JournalListItem = {
id: number;
date: string;
location?: string;
idea?: string;
thumbUrl?: string;
}
interface JournalListData {
list: JournalListItem[];
isFetching: boolean;
isFinished: boolean;
page: JournalPage;
searchValue: string;
}
// 组件实例类型扩展
interface ComponentInstance {
debouncedSearch?: ((keyword: string) => void) & { cancel(): void };
}
Component<JournalListData, {}, {}, ComponentInstance>({
options: {
styleIsolation: 'apply-shared'
},
properties: {
visible: {
type: Boolean,
value: false
},
type: {
type: String,
value: undefined // NORMAL 或 PORTFOLIO不传则获取所有类型
},
selectedId: {
type: Number,
value: undefined
},
searchable: {
type: Boolean,
value: false // 是否显示搜索框
},
mode: {
type: String,
value: 'select' // 'select' 选择模式 或 'navigate' 跳转模式
}
},
data: <JournalListData>{
list: [],
isFetching: false,
isFinished: false,
page: {
index: 0,
size: 16,
type: JournalPageType.PREVIEW
},
searchValue: ""
},
lifetimes: {
ready() {
// 创建防抖搜索函数
this.debouncedSearch = Toolkit.debounce(
(keyword: string) => {
this.resetAndSearch(keyword);
},
false, // 不立即执行,等待输入停止
400 // 400ms 延迟
);
// 组件加载时就获取数据
this.fetch();
},
detached() {
// 组件销毁时取消防抖
if (this.debouncedSearch) {
this.debouncedSearch.cancel();
}
}
},
observers: {
'visible': function(visible: boolean) {
// visible 从 false 变为 true 时,如果还没有数据则加载
if (visible && this.data.list.length === 0) {
this.fetch();
}
},
'type': function() {
this.resetPage();
}
},
methods: {
resetPage() {
const likeExample = this.data.searchValue ? {
idea: this.data.searchValue,
location: this.data.searchValue
} : undefined;
const equalsExample = this.properties.type ? {
type: this.properties.type
} : undefined;
this.setData({
page: {
index: 0,
size: 16,
type: JournalPageType.PREVIEW,
equalsExample,
likeExample
},
list: [],
isFinished: false
});
},
fetch() {
if (this.data.isFetching || this.data.isFinished) {
return;
}
this.setData({ isFetching: true });
wx.request({
url: `${config.url}/journal/list`,
method: "POST",
header: {
Key: wx.getStorageSync("key")
},
data: this.data.page,
success: (resp: any) => {
const list = resp.data.data.list;
if (!list || list.length === 0) {
this.setData({ isFinished: true });
return;
}
const result = list.map((journal: any) => {
// 获取第一张缩略图
const firstThumb = journal.items.find((item: any) => item.attachType === "THUMB");
return {
id: journal.id,
date: Time.toPassedDate(journal.createdAt),
idea: journal.idea,
location: journal.location,
thumbUrl: firstThumb ? `${config.url}/attachment/read/${firstThumb.mongoId}` : undefined
} as JournalListItem;
});
this.setData({
page: {
...this.data.page,
index: this.data.page.index + 1
},
list: this.data.list.concat(result),
isFinished: list.length < this.data.page.size
});
},
complete: () => {
this.setData({ isFetching: false });
}
});
},
onSearchChange(e: WechatMiniprogram.CustomEvent) {
const value = e.detail.value.trim();
this.setData({ searchValue: value });
// 如果是清空操作不使用防抖clear 事件会处理)
if (value === "" && this.debouncedSearch) {
this.debouncedSearch.cancel();
return;
}
// 使用防抖自动搜索
if (this.debouncedSearch) {
this.debouncedSearch(value);
}
},
onSearchSubmit(e: WechatMiniprogram.CustomEvent) {
const value = e.detail.value.trim();
// 立即搜索,取消防抖
if (this.debouncedSearch) {
this.debouncedSearch.cancel();
}
this.resetAndSearch(value);
},
onSearchClear() {
// 取消防抖,立即搜索
if (this.debouncedSearch) {
this.debouncedSearch.cancel();
}
this.resetAndSearch("");
},
resetAndSearch(keyword: string) {
const likeExample = keyword ? {
idea: keyword,
location: keyword
} : undefined;
const equalsExample = this.properties.type ? {
type: this.properties.type
} : undefined;
this.setData({
searchValue: keyword,
list: [],
page: {
index: 0,
size: 16,
type: JournalPageType.PREVIEW,
equalsExample,
likeExample
},
isFetching: false,
isFinished: false
}, () => {
// 无论是否有搜索词,都重新获取列表
this.fetch();
});
},
onSelectItem(e: WechatMiniprogram.BaseEvent) {
const { id } = e.currentTarget.dataset;
if (this.properties.mode === 'navigate') {
// 跳转模式:触发 navigate 事件
this.triggerEvent('navigate', { id });
} else {
// 选择模式:触发 select 事件
this.triggerEvent('select', { id });
}
},
onScrollToLower() {
this.fetch();
}
}
});