浅念
ab5a918a3b
fix(calls+scraper): 语音群scope服务端过滤+对话发现缺口补全+抓取韧性三连修
...
- /api/calls 加 scope=friend|group(@chatroom后缀判群,与isRoom实测等价120=120),CallList去掉「全部」tab改服务端查
- 对话发现:全部customer pair ∪ 语音pair(weChatId,talker),未扫过的排最前——修复纯语音关系客户聊天记录永远空(35%语音客户pair从未扫过)
- voice-calls改浏览器直发(isRoom=0/1双趟+WA callSource=4,拦截方式已两次失效)
- 断连恢复重试30×2min(云客约3h一次断连,已实战扛过多次)
- WA messages upsert改整列表直调(_upsert_all逐条传dict被迭代成key字符串→TypeError)
- 405测试绿含scope新增3个
Co-Authored-By: Claude <noreply@anthropic.com >
2026-08-19 16:48:22 +08:00
浅念
2cdbdf7283
fix(ui): 微信群scope换列(群信息)+WA语音加操作列(播放/长语音)
...
Co-Authored-By: Claude <noreply@anthropic.com >
2026-08-15 16:01:56 +08:00
浅念
aa90d9d8f2
feat(ui): 列表页移除tab结构(每渠道独立页面,由侧栏菜单驱动)
...
Co-Authored-By: Claude <noreply@anthropic.com >
2026-08-15 13:41:49 +08:00
浅念
9b21584e9a
feat(ui): 左侧菜单改分组式(微信管理/WhatsApp管理+下拉子菜单,对齐云客布局)
...
Co-Authored-By: Claude <noreply@anthropic.com >
2026-08-15 12:09:55 +08:00
浅念
02f95af279
fix(ui): 所有列表页默认分页改为10条(原20条)
...
Co-Authored-By: Claude <noreply@anthropic.com >
2026-08-15 11:32:33 +08:00
浅念
edd6a27371
feat(ui): 所有列表页加CSV导出按钮(全量拉取+中文BOM兼容Excel)
...
Co-Authored-By: Claude <noreply@anthropic.com >
2026-08-15 10:31:21 +08:00
浅念
20cf2c51f0
feat(staff): 员工详情独立页(StaffDetail.vue,替代 drawer 降级,对齐云客 userDetailNew)
...
Co-Authored-By: Claude <noreply@anthropic.com >
2026-08-11 17:05:01 +08:00
浅念
17ee5a1a6c
feat(calls): 微信语音 好友/群 scope 筛选(对齐云客,client-side isRoom 过滤)
...
Co-Authored-By: Claude <noreply@anthropic.com >
2026-08-11 15:25:42 +08:00
浅念
8b19c299bb
feat(calls): WA语音 单元格可点(客户→WA chat,员工→drawer)+ chatChannel helper
...
Co-Authored-By: Claude <noreply@anthropic.com >
2026-08-11 11:59:56 +08:00
浅念
f1b5861b35
feat(calls): VoiceClipModal 只读长语音列表+播放,接入 CallList(微信+WA语音)
...
Co-Authored-By: Claude <noreply@anthropic.com >
2026-08-10 18:37:29 +08:00
浅念
5bf5e25bad
feat(calls): CallList 微信语音 客户/员工/姓名 单元格可点(复用聊天导航,对齐云客)
...
Co-Authored-By: Claude <noreply@anthropic.com >
2026-08-08 16:19:21 +08:00
浅念
05cc1dfcc4
feat(calls): 前端录音播放本地优先(/api/media/{hash}) + OSS 回退 + drawer
...
Co-Authored-By: Claude <noreply@anthropic.com >
2026-08-07 16:55:49 +08:00
浅念
7a5bb9927e
feat(calls): callStatusLabel channel-aware + callTypeLabel WA + 补 WA/微信语音字段 label
...
call_status 极性随 channel 不同(phone 0未接/2接通;voice/WA 1接通/2未接通),
仅值 2 按 channel 分支。
Co-Authored-By: Claude <noreply@anthropic.com >
2026-08-07 11:54:38 +08:00
浅念
28d8448f62
feat(calls): 电话 tab 保留通用 8 列(按 channel 分离列集)
...
Co-Authored-By: Claude <noreply@anthropic.com >
2026-08-07 11:09:47 +08:00
浅念
f8705cb741
feat(calls): WA 语音 tab 对齐云客列(状态/客户/员工/通话时间和录音)
...
Co-Authored-By: Claude <noreply@anthropic.com >
2026-08-07 11:03:22 +08:00
浅念
f4dc115129
feat(calls): 微信语音 tab 对齐云客列(通话信息/客户/员工微信/员工信息/录音/时长)
...
Co-Authored-By: Claude <noreply@anthropic.com >
2026-08-07 10:57:17 +08:00
浅念
ca3a2a2d3d
feat(calls): CallList 改 el-tabs(微信语音/WA 语音/电话)+ CallChannel 加 wa_voice_call
...
Co-Authored-By: Claude <noreply@anthropic.com >
2026-08-07 10:50:38 +08:00
浅念
0d466c4e4a
feat: full-field display for group/call/sms (raw_json + drawers)
...
Mirrors the Customer/Message/Staff/Accounts pattern: backend exposes the
verbatim upstream record on the response schema; the frontend list shows
source-matching columns and a row-click opens an all-fields el-drawer with
Chinese-labeled camelCase keys (unknown keys roll up under 其他).
Backend (yunke-server/app/api/schemas.py)
- GroupOut / PhoneCallOut / SmsOut: add raw_json: dict[str, Any] | None
(Pydantic v2 from_attributes picks up the existing ORM column).
- Tests: extend tests/test_api_{groups,calls,sms}.py with a per-schema
raw_json round-trip assertion (phone_call + voice_call payload shapes
both covered for calls).
Frontend (yunkes)
- src/utils/{groupFields,callFields,smsFields}.ts: 中文 label map +
grouped sections + readField (structured-column preference) +
toDisplayField (image / time / audio / bool / status / direction).
- src/api/types.ts: add raw_json to Group / PhoneCall / Sms.
- src/views/GroupList.vue: richer columns (群名/群ID/成员数/群主/归属微信/
消息数/最近聊天/渠道) + all-fields drawer (chatRoomId/chatRoomName,
memberCount/memberIds, headImageUrl, wechatId/wechatNickName,
userName/userPhone/userId, messageCount/ownMessageCount,
lossMembers/addMembers, lastChatTime/updateTime).
- src/views/CallList.vue: keeps existing columns + adds all-fields drawer
(id/startCallTime, callDuration/callSeconds/ringTime, callStatus/
incomingCall, userId/userIdName/departmentId, callNumber/simPhone/
simNumber/imei, recordFile/isUpload/downloadCount/aiAsr/qcStatus/
planCustomerName/version + voice-call extras ossFileName/duration/
startTime/endTime/remark). Drawer plays recording inline via audio
render kind; existing play-record dialog retained.
- src/views/SmsList.vue: keeps existing columns + adds all-fields drawer
(id/customerPhone, sms/smsSub, sender, direction, userId/
senderDepartment, receiveName, createTime, simPhone/simNumber, source)
with a full-body preview block at the top.
Co-Authored-By: Claude <noreply@anthropic.com >
2026-08-05 10:12:49 +08:00
浅念
b822e87d4d
feat: remaining frontend views (groups/calls/sms/sync) + messageout media fields
...
Backend (Part A):
- MessageOut: add file_th_url, file_hd_url, duration, transcription_text, md5
(room_id + sender_head_url already existed) so the chat timeline can render
image thumbnails, voice duration/transcription, and avatars from a single
response.
- PhoneCallOut: add record_file so the Calls view can offer recording playback.
- SmsOut: add content (full body) so the SMS detail dialog shows the whole text.
- Tests: red->green for each new field (media fields default None + populated,
record_file round-trip, content round-trip). Suite 267 -> 271.
Frontend (Part B):
- api/index.ts: wrappers getGroups/getGroupMembers/getCalls/getSms/getSyncStatus
+ Group/GroupMember/PhoneCall/Sms/SyncState/SyncRun/SyncStatus types in
types.ts (mirror the *Out pydantic schemas).
- views/GroupList.vue (/groups): table + channel filter + pagination; row click
opens the group timeline.
- views/CallList.vue (/calls): table + call-type filter (phone_call/voice_call/
all); "播放录音" action opens an el-dialog with <audio controls>.
- views/SmsList.vue (/sms): table; row click opens a detail dialog with the full
content.
- views/SyncStatus.vue (/sync): two tables (states + recent_runs) with a manual
refresh; run status color-coded.
- ChatTimeline.vue: reused for both 1:1 DM (talkerId) and group (roomId) by
branching the query; group title + per-member sender already handled by
MessageBubble.
- router: add /groups /calls /sms /sync + /group/:channel/:ownerId/:roomId.
- layouts/MainLayout.vue: replace the single 客户列表 button with an el-menu
(客户 / 群 / 通话 / 短信 / 同步); org tree kept on the left.
Co-Authored-By: Claude <noreply@anthropic.com >
2026-08-01 16:38:47 +08:00