267 lines
7.9 KiB
JavaScript
267 lines
7.9 KiB
JavaScript
/**
|
|
* Soul创业派对 - 我的动态(含待审/通过/驳回,驳回可跳转编辑)
|
|
*/
|
|
const app = getApp()
|
|
|
|
const PAGE_SIZE = 10
|
|
const THUMB_MAX = 3
|
|
|
|
function relativeTime(iso) {
|
|
if (!iso) return ''
|
|
const d = new Date(iso)
|
|
const t = d.getTime()
|
|
if (Number.isNaN(t)) return ''
|
|
const sec = Math.max(0, Math.floor((Date.now() - t) / 1000))
|
|
if (sec < 60) return '刚刚'
|
|
if (sec < 3600) return `${Math.floor(sec / 60)}分钟前`
|
|
if (sec < 86400) return `${Math.floor(sec / 3600)}小时前`
|
|
if (sec < 86400 * 7) return `${Math.floor(sec / 86400)}天前`
|
|
const m = `${d.getMonth() + 1}`.padStart(2, '0')
|
|
const day = `${d.getDate()}`.padStart(2, '0')
|
|
return `${m}-${day}`
|
|
}
|
|
|
|
function auditLabel(st) {
|
|
const s = String(st || '').toLowerCase()
|
|
if (s === 'pending') return '审核中'
|
|
if (s === 'rejected') return '已驳回'
|
|
return '已发布'
|
|
}
|
|
|
|
function parseImagesField(images) {
|
|
if (images == null) return []
|
|
if (typeof images === 'string') {
|
|
const s = images.trim()
|
|
if (!s) return []
|
|
try {
|
|
const p = JSON.parse(s)
|
|
return Array.isArray(p) ? p : []
|
|
} catch (_) {
|
|
return []
|
|
}
|
|
}
|
|
return Array.isArray(images) ? images : []
|
|
}
|
|
|
|
function normalizeArticleImageSrc(raw) {
|
|
const u = String(raw || '').trim()
|
|
if (!u || u === 'undefined' || u === 'null') return ''
|
|
if (/^https?:\/\//i.test(u)) return u
|
|
if (u.startsWith('//')) return `https:${u}`
|
|
if (u.startsWith('wxfile://') || u.startsWith('cloud://')) return u
|
|
const base = String((app.globalData && app.globalData.baseUrl) || '').replace(/\/$/, '')
|
|
if (u.startsWith('/') && base) return `${base}${u}`
|
|
return u
|
|
}
|
|
|
|
function buildThumbSlots(imagesField) {
|
|
const rawList = parseImagesField(imagesField)
|
|
const n = Math.min(rawList.length, THUMB_MAX)
|
|
const thumbSlots = []
|
|
for (let i = 0; i < n; i++) {
|
|
const srcNorm = normalizeArticleImageSrc(String(rawList[i] || '').trim())
|
|
const ok =
|
|
!!srcNorm &&
|
|
(/^https?:\/\//i.test(srcNorm) ||
|
|
srcNorm.startsWith('wxfile://') ||
|
|
srcNorm.startsWith('cloud://'))
|
|
thumbSlots.push({ slotIdx: i, src: ok ? srcNorm : '', loadFailed: false })
|
|
}
|
|
return {
|
|
showThumbRow: rawList.length > 0,
|
|
thumbSlots,
|
|
thumbMoreCount: rawList.length > THUMB_MAX ? rawList.length - THUMB_MAX : 0,
|
|
}
|
|
}
|
|
|
|
function mapRows(rows) {
|
|
return (rows || []).map((r) => {
|
|
const st = String(r.auditStatus || 'approved').toLowerCase()
|
|
const thumb = buildThumbSlots(r.images)
|
|
return Object.assign({}, r, {
|
|
auditStatus: st === 'pending' || st === 'rejected' ? st : 'approved',
|
|
auditLabel: auditLabel(st),
|
|
timeText: relativeTime(r.createdAt),
|
|
preview: String(r.preview || '').trim(),
|
|
rejectReason: String(r.rejectReason || '').trim(),
|
|
showThumbRow: thumb.showThumbRow,
|
|
thumbSlots: thumb.thumbSlots,
|
|
thumbMoreCount: thumb.thumbMoreCount,
|
|
})
|
|
})
|
|
}
|
|
|
|
Page({
|
|
data: {
|
|
statusBarHeight: 44,
|
|
auditMode: false,
|
|
list: [],
|
|
page: 1,
|
|
total: 0,
|
|
hasMore: true,
|
|
loading: true,
|
|
loadingMore: false,
|
|
},
|
|
|
|
onLoad() {
|
|
this.setData({
|
|
statusBarHeight: app.globalData.statusBarHeight || 44,
|
|
auditMode: !!app.globalData.auditMode,
|
|
})
|
|
try {
|
|
app.getAuditMode && app.getAuditMode().catch(() => {})
|
|
} catch (_) {}
|
|
this.reload()
|
|
},
|
|
|
|
onShow() {
|
|
this.setData({ auditMode: !!app.globalData.auditMode })
|
|
},
|
|
|
|
goCompose() {
|
|
if (app.globalData.auditMode) {
|
|
wx.showToast({ title: '当前为体验版,暂无法访问', icon: 'none' })
|
|
return
|
|
}
|
|
wx.navigateTo({ url: '/pages/super-article-editor/super-article-editor' })
|
|
},
|
|
|
|
onReachBottom() {
|
|
this.loadMore()
|
|
},
|
|
|
|
goBack() {
|
|
wx.navigateBack({ fail: () => wx.switchTab({ url: '/pages/my/my' }) })
|
|
},
|
|
|
|
noop() {},
|
|
|
|
openDetail(e) {
|
|
const id = e.currentTarget?.dataset?.id
|
|
if (!id) return
|
|
wx.navigateTo({ url: `/pages/read/read?superArticleId=${encodeURIComponent(String(id))}` })
|
|
},
|
|
|
|
openEdit(e) {
|
|
const id = e.currentTarget?.dataset?.id
|
|
if (!id) return
|
|
wx.navigateTo({ url: `/pages/super-article-editor/super-article-editor?id=${encodeURIComponent(String(id))}` })
|
|
},
|
|
|
|
tapDeleteArticle(e) {
|
|
const id = e.currentTarget?.dataset?.id
|
|
if (!id || this._articleDeleting) return
|
|
const userId = app.globalData.userInfo?.id
|
|
if (!userId) {
|
|
wx.showToast({ title: '请先登录', icon: 'none' })
|
|
return
|
|
}
|
|
wx.showModal({
|
|
title: '删除动态',
|
|
content: '删除后不可恢复,确定删除?',
|
|
confirmText: '删除',
|
|
confirmColor: '#dc2626',
|
|
success: async (r) => {
|
|
if (!r.confirm) return
|
|
this._articleDeleting = true
|
|
wx.showLoading({ title: '删除中…', mask: true })
|
|
try {
|
|
await app.request({
|
|
url: `/api/miniprogram/super/articles/${encodeURIComponent(String(id))}?userId=${encodeURIComponent(String(userId))}`,
|
|
method: 'DELETE',
|
|
})
|
|
wx.hideLoading()
|
|
this._articleDeleting = false
|
|
const list = this.data.list.filter((x) => String(x.id) !== String(id))
|
|
const total = Math.max(0, (Number(this.data.total) || 0) - 1)
|
|
this.setData({
|
|
list,
|
|
total,
|
|
hasMore: list.length < total,
|
|
})
|
|
wx.showToast({ title: '已删除', icon: 'success' })
|
|
} catch (_) {
|
|
wx.hideLoading()
|
|
this._articleDeleting = false
|
|
/* app.request 已 toast */
|
|
}
|
|
},
|
|
})
|
|
},
|
|
|
|
onThumbError(e) {
|
|
const rowIdx = Number(e.currentTarget.dataset.rowidx)
|
|
const slotIdx = Number(e.currentTarget.dataset.slotidx)
|
|
if (Number.isNaN(rowIdx) || Number.isNaN(slotIdx)) return
|
|
this.setData({ [`list[${rowIdx}].thumbSlots[${slotIdx}].loadFailed`]: true })
|
|
},
|
|
|
|
previewRowImages(e) {
|
|
const rowIdx = Number(e.currentTarget.dataset.rowidx)
|
|
if (Number.isNaN(rowIdx)) return
|
|
const row = this.data.list[rowIdx]
|
|
if (!row) return
|
|
const urls = parseImagesField(row.images)
|
|
.map((u) => normalizeArticleImageSrc(String(u || '').trim()))
|
|
.filter((u) => /^https?:\/\//i.test(u))
|
|
if (!urls.length) return
|
|
const current = String(e.currentTarget.dataset.current || '').trim() || urls[0]
|
|
wx.previewImage({ urls, current })
|
|
},
|
|
|
|
async reload() {
|
|
const userId = app.globalData.userInfo?.id
|
|
if (!userId || !app.globalData.isLoggedIn) {
|
|
wx.showToast({ title: '请先登录', icon: 'none' })
|
|
setTimeout(() => wx.navigateBack(), 400)
|
|
return
|
|
}
|
|
this.setData({ loading: true, page: 1, list: [], hasMore: true })
|
|
try {
|
|
const res = await app.request({
|
|
url: `/api/miniprogram/super/articles/mine?userId=${encodeURIComponent(String(userId))}&page=1&pageSize=${PAGE_SIZE}`,
|
|
silent: true,
|
|
})
|
|
const raw = Array.isArray(res?.list) ? res.list : []
|
|
const list = mapRows(raw)
|
|
const total = Number(res?.total) || 0
|
|
this.setData({
|
|
list,
|
|
total,
|
|
hasMore: list.length < total,
|
|
loading: false,
|
|
page: 1,
|
|
})
|
|
} catch (_) {
|
|
this.setData({ loading: false, list: [] })
|
|
}
|
|
},
|
|
|
|
async loadMore() {
|
|
if (this.data.loading || this.data.loadingMore || !this.data.hasMore) return
|
|
const userId = app.globalData.userInfo?.id
|
|
if (!userId) return
|
|
const nextPage = this.data.page + 1
|
|
this.setData({ loadingMore: true })
|
|
try {
|
|
const res = await app.request({
|
|
url: `/api/miniprogram/super/articles/mine?userId=${encodeURIComponent(String(userId))}&page=${nextPage}&pageSize=${PAGE_SIZE}`,
|
|
silent: true,
|
|
})
|
|
const raw = Array.isArray(res?.list) ? res.list : []
|
|
const chunk = mapRows(raw)
|
|
const merged = this.data.list.concat(chunk)
|
|
const total = Number(res?.total) || this.data.total
|
|
this.setData({
|
|
list: merged,
|
|
page: nextPage,
|
|
total,
|
|
hasMore: merged.length < total,
|
|
loadingMore: false,
|
|
})
|
|
} catch (_) {
|
|
this.setData({ loadingMore: false })
|
|
}
|
|
},
|
|
})
|