post.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import { defineStore } from "pinia"
  2. import { reactive, ref } from "vue"
  3. import type { PostItem, PostDetail, Pagination } from "../type"
  4. import { getPostController } from "../api/post-controller"
  5. import type { ResponsePostVo, ResponsePageVoListPostVo, PostVo } from "../api/models"
  6. function mapPostVo(v: PostVo): PostItem {
  7. const now = new Date()
  8. const pub = v.publishTime ? new Date(v.publishTime) : new Date(0)
  9. const isToday =
  10. pub.getFullYear() === now.getFullYear() &&
  11. pub.getMonth() === now.getMonth() &&
  12. pub.getDate() === now.getDate()
  13. const tags: string[] = []
  14. if (v.expertIsRealname) tags.push('已认证')
  15. return {
  16. id: v.id ?? '',
  17. title: v.title ?? '',
  18. expertName: v.expertName ?? '',
  19. expertAvatar: v.expertAvatar ?? '',
  20. expertLevel: v.expertLevel ?? 'gold',
  21. expertIsRealname: v.expertIsRealname ?? false,
  22. tags,
  23. price: v.price ?? 0,
  24. publishTime: v.publishTime ?? '',
  25. viewCount: v.viewCount ?? 0,
  26. isPublic: v.isPublic ?? false,
  27. hitStatus: v.hitStatus ?? 'pending',
  28. isTodayNew: isToday,
  29. expireTime: v.expireTime ?? '',
  30. }
  31. }
  32. export const usePostStore = defineStore('post', () => {
  33. const posts = ref<PostItem[]>([])
  34. const currentDetail = ref<PostDetail | null>(null)
  35. const currentStatus = ref('all')
  36. const searchKeyword = ref('')
  37. const pagination = reactive<Pagination>({ page: 1, pageSize: 10, total: 0 })
  38. const loading = ref(false)
  39. async function fetchPosts(status?: string, keyword?: string): Promise<void> {
  40. if (status !== undefined) currentStatus.value = status
  41. if (keyword !== undefined) searchKeyword.value = keyword
  42. loading.value = true
  43. try {
  44. const res: ResponsePageVoListPostVo = await getPostController().listPosts({
  45. status: currentStatus.value,
  46. keyword: searchKeyword.value,
  47. pageNum: pagination.page,
  48. pageSize: pagination.pageSize,
  49. })
  50. if (res.code === 200 && res.data) {
  51. posts.value = (res.data.data ?? []).map(mapPostVo)
  52. pagination.total = res.data.total ?? 0
  53. }
  54. } catch {
  55. posts.value = []
  56. } finally {
  57. loading.value = false
  58. }
  59. }
  60. async function fetchPostDetail(id: string): Promise<void> {
  61. loading.value = true
  62. try {
  63. const res: ResponsePostVo = await getPostController().getPostDetail(Number(id))
  64. if (res.code === 200 && res.data) {
  65. const v = res.data
  66. currentDetail.value = {
  67. id: v.id ?? '',
  68. title: v.title ?? '',
  69. contentIntro: v.contentIntro ?? '',
  70. contentPaid: v.contentPaid ?? '',
  71. price: v.price ?? 0,
  72. isPaid: v.isPaid ?? false,
  73. isPublic: v.isPublic ?? false,
  74. hitStatus: v.hitStatus ?? 'pending',
  75. publishTime: v.publishTime ?? '',
  76. expireTime: v.expireTime ?? '',
  77. expert: {
  78. name: v.expertName ?? '',
  79. avatar: v.expertAvatar ?? '',
  80. level: v.expertLevel ?? 'gold',
  81. isRealname: v.expertIsRealname ?? false,
  82. tags: v.expertIsRealname ? ['已认证'] : [],
  83. },
  84. previousPosts: [],
  85. }
  86. } else {
  87. currentDetail.value = null
  88. }
  89. } catch {
  90. currentDetail.value = null
  91. } finally {
  92. loading.value = false
  93. }
  94. }
  95. function loadMore(): void {
  96. pagination.page++
  97. fetchPosts()
  98. }
  99. return { posts, currentDetail, currentStatus, searchKeyword, pagination, loading, fetchPosts, fetchPostDetail, loadMore }
  100. })