mirror of
https://github.com/LifeArchiveProject/WeChatDataAnalysis.git
synced 2026-02-19 14:20:51 +08:00
feat(sns): 朋友圈页支持联系人侧栏、导出与 Live Photo
- 左侧新增朋友圈联系人列表(按发圈数),支持搜索与“全部/单人”筛选 - 新增“导出全部/导出此人”,展示导出状态并支持下载 ZIP(SSE 优先,轮询兜底) - Live Photo/实况:悬停播放、静音切换与预览弹窗 - 媒体请求统一透传 use_cache;关闭缓存时追加时间戳避免浏览器缓存
This commit is contained in:
29
frontend/components/LivePhotoIcon.vue
Normal file
29
frontend/components/LivePhotoIcon.vue
Normal file
@@ -0,0 +1,29 @@
|
||||
<template>
|
||||
<svg
|
||||
:width="size"
|
||||
:height="size"
|
||||
viewBox="0 0 24 24"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<!-- Keep the SVG identical to WeFlow/src/components/LivePhotoIcon.tsx for visual consistency -->
|
||||
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
|
||||
<g stroke="currentColor" stroke-width="2">
|
||||
<circle fill="currentColor" stroke="none" cx="12" cy="12" r="2.5" />
|
||||
<circle cx="12" cy="12" r="5.5" />
|
||||
<circle cx="12" cy="12" r="9" stroke-dasharray="1 3.7" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps({
|
||||
size: {
|
||||
type: [Number, String],
|
||||
default: 24
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -236,6 +236,16 @@ export const useApi = () => {
|
||||
return await request(url)
|
||||
}
|
||||
|
||||
// 朋友圈联系人列表(按发圈数统计)
|
||||
const listSnsUsers = async (params = {}) => {
|
||||
const query = new URLSearchParams()
|
||||
if (params && params.account) query.set('account', params.account)
|
||||
if (params && params.keyword) query.set('keyword', String(params.keyword))
|
||||
if (params && params.limit != null) query.set('limit', String(params.limit))
|
||||
const url = '/sns/users' + (query.toString() ? `?${query.toString()}` : '')
|
||||
return await request(url)
|
||||
}
|
||||
|
||||
// 朋友圈图片本地缓存候选(用于错图时手动选择)
|
||||
const listSnsMediaCandidates = async (params = {}) => {
|
||||
const query = new URLSearchParams()
|
||||
@@ -356,6 +366,31 @@ export const useApi = () => {
|
||||
return await request(`/chat/exports/${encodeURIComponent(String(exportId))}`, { method: 'DELETE' })
|
||||
}
|
||||
|
||||
// 朋友圈导出(离线 HTML zip)
|
||||
const createSnsExport = async (data = {}) => {
|
||||
return await request('/sns/exports', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
account: data.account || null,
|
||||
scope: data.scope || 'selected',
|
||||
usernames: Array.isArray(data.usernames) ? data.usernames : [],
|
||||
use_cache: data.use_cache == null ? true : !!data.use_cache,
|
||||
output_dir: data.output_dir == null ? null : String(data.output_dir || '').trim(),
|
||||
file_name: data.file_name || null
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const getSnsExport = async (exportId) => {
|
||||
if (!exportId) throw new Error('Missing exportId')
|
||||
return await request(`/sns/exports/${encodeURIComponent(String(exportId))}`)
|
||||
}
|
||||
|
||||
const cancelSnsExport = async (exportId) => {
|
||||
if (!exportId) throw new Error('Missing exportId')
|
||||
return await request(`/sns/exports/${encodeURIComponent(String(exportId))}`, { method: 'DELETE' })
|
||||
}
|
||||
|
||||
// 联系人
|
||||
const listChatContacts = async (params = {}) => {
|
||||
const query = new URLSearchParams()
|
||||
@@ -454,6 +489,7 @@ export const useApi = () => {
|
||||
resolveNestedChatHistory,
|
||||
resolveAppMsg,
|
||||
listSnsTimeline,
|
||||
listSnsUsers,
|
||||
listSnsMediaCandidates,
|
||||
saveSnsMediaPicks,
|
||||
openChatMediaFolder,
|
||||
@@ -465,6 +501,9 @@ export const useApi = () => {
|
||||
getChatExport,
|
||||
listChatExports,
|
||||
cancelChatExport,
|
||||
createSnsExport,
|
||||
getSnsExport,
|
||||
cancelSnsExport,
|
||||
listChatContacts,
|
||||
exportChatContacts,
|
||||
getWrappedAnnual,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user