浅念
|
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 |
|
浅念
|
ff7e9cb1d9
|
feat: backend read api for all entities (messages/groups/calls/sms/org/sync)
Adds the read-only API surface the upcoming Vue frontend needs to browse all
mirrored entities. Follows the existing customer-router pattern: Annotated
deps, Page[T] envelope, select+where+order_by, count() for total.
Endpoints (all GET):
* /api/departments -> list[DepartmentOut] (path-ordered, plain list)
* /api/staff -> Page[StaffOut] (department_id, is_on_job filters)
* /api/accounts -> Page[AccountOut] (channel filter; unified
wechat+whatsapp projection built in memory)
* /api/messages -> Page[MessageOut] (channel/owner/talker/room/
[start,end] filters; ordered timestamp asc)
* /api/groups -> Page[GroupOut] (channel/owner filters)
* /api/groups/{id}/members -> list[GroupMemberOut] (404 on unknown room)
* /api/calls -> Page[PhoneCallOut] (channel/user/time window;
ordered start_call_time desc)
* /api/sms -> Page[SmsOut] (user/time window; create_time desc)
* /api/sync/status -> {states, recent_runs} monitor payload
Schemas (Pydantic v2, from_attributes=True): MessageOut, GroupOut,
GroupMemberOut, PhoneCallOut, SmsOut, DepartmentOut, StaffOut, AccountOut
(unified across two tables), SyncStateOut, SyncRunOut, SyncStatusOut.
Only human-relevant fields per entity are exposed.
Tests: per-router TDD via httpx ASGITransport against an in-memory SQLite
override of get_session. A shared make_client factory in conftest.py builds
the seeded client, deduping the ~40-line fixture across the six new files.
41 new tests cover shape + every documented filter + pagination + ordering
(nulls-last verified on all desc/asc time columns).
Suite: 226 -> 267 passing. ruff check clean.
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-08-01 16:15:40 +08:00 |
|