From da7397ce7e8cc4788e71738876c6d7236d74b90b Mon Sep 17 00:00:00 2001 From: Jafeng <2998840497@qq.com> Date: Fri, 23 Jan 2026 17:59:24 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=AE=8C=E5=96=84=E8=BD=AC=E7=A7=BB?= =?UTF-8?q?=E3=80=81=E5=85=B1=E4=BA=AB=E3=80=81=E5=88=86=E7=BB=84=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/case/archive-detail.vue | 172 +++++++++++++++++---- pages/case/batch-share.vue | 212 +++++++++++++++++++------ pages/case/batch-transfer.vue | 214 ++++++++++++++++++++------ pages/case/case.vue | 132 +++++++++++++--- pages/case/group-manage.vue | 280 ++++++++++++++++++++++++++++++---- utils/api.js | 7 + 6 files changed, 840 insertions(+), 177 deletions(-) diff --git a/pages/case/archive-detail.vue b/pages/case/archive-detail.vue index 241ec5f..5625446 100644 --- a/pages/case/archive-detail.vue +++ b/pages/case/archive-detail.vue @@ -76,8 +76,8 @@ - - + + {{ tag }} @@ -184,13 +184,13 @@ - + - {{ g }} + {{ g.groupName }} @@ -259,8 +259,7 @@ const archive = ref({ createdByDoctor: true, hasBindWechat: false, notes: '', - groups: [], - groupOptions: ['高血压', '糖尿病', '高血脂'] + groupIds: [] }); const accountStore = useAccountStore(); @@ -295,6 +294,7 @@ function normalizeArchiveFromApi(raw) { createTime: r.createTime || '', creator: r.creator || '', notes: r.notes || r.remark || '', + groupIds: Array.isArray(r.groupIds) ? r.groupIds : [], }; return next; } @@ -321,6 +321,7 @@ async function fetchArchive() { } archive.value = { ...archive.value, ...normalizeArchiveFromApi(res.data) }; saveToStorage(); + await fetchTeamGroups(true); } catch (e) { toast('获取档案失败'); } finally { @@ -328,6 +329,56 @@ async function fetchArchive() { } } +const teamGroups = ref([]); +const groupNameMap = computed(() => { + const map = new Map(); + (Array.isArray(teamGroups.value) ? teamGroups.value : []).forEach((g) => { + if (g && g._id && g.groupName) map.set(String(g._id), String(g.groupName)); + }); + return map; +}); + +const archiveGroupNames = computed(() => { + const ids = Array.isArray(archive.value.groupIds) ? archive.value.groupIds : []; + const map = groupNameMap.value; + return ids.map((id) => map.get(String(id))).filter(Boolean); +}); + +function sortGroupList(list) { + const { orderList, corpList, restList } = (Array.isArray(list) ? list : []).reduce( + (p, c) => { + if (typeof c?.sortOrder === 'number') p.orderList.push(c); + else if (c?.parentGroupId) p.corpList.push(c); + else p.restList.push(c); + return p; + }, + { orderList: [], corpList: [], restList: [] } + ); + orderList.sort((a, b) => a.sortOrder - b.sortOrder); + return [...orderList, ...corpList, ...restList]; +} + +async function fetchTeamGroups(silent = false) { + const corpId = getCorpId(); + const team = uni.getStorageSync(CURRENT_TEAM_STORAGE_KEY) || {}; + const teamId = team?.teamId ? String(team.teamId) : ''; + if (!corpId || !teamId) return; + try { + const projection = { _id: 1, groupName: 1, parentGroupId: 1, sortOrder: 1 }; + const res = await api('getGroups', { corpId, teamId, page: 1, pageSize: 1000, projection, countGroupMember: false }); + if (!res?.success) { + if (!silent) toast(res?.message || '获取分组失败'); + teamGroups.value = []; + return; + } + const list = Array.isArray(res.data) ? res.data : Array.isArray(res.data?.data) ? res.data.data : []; + teamGroups.value = sortGroupList(list); + } catch (e) { + if (!silent) toast('获取分组失败'); + teamGroups.value = []; + } +} + async function updateArchive(patch) { const id = String(archiveId.value || ''); if (!id) return false; @@ -375,8 +426,7 @@ onLoad((options) => { archive.value = { ...archive.value, ...cached, - groups: Array.isArray(cached.groups) ? cached.groups : archive.value.groups, - groupOptions: Array.isArray(cached.groupOptions) ? cached.groupOptions : archive.value.groupOptions + groupIds: Array.isArray(cached.groupIds) ? cached.groupIds : archive.value.groupIds }; } @@ -416,8 +466,7 @@ onShow(() => { archive.value = { ...archive.value, ...cached, - groups: Array.isArray(cached.groups) ? cached.groups : archive.value.groups, - groupOptions: Array.isArray(cached.groupOptions) ? cached.groupOptions : archive.value.groupOptions, + groupIds: Array.isArray(cached.groupIds) ? cached.groupIds : archive.value.groupIds, }; } setTimeout(measureTabsTop, 30); @@ -528,19 +577,18 @@ const saveNotes = () => { const groupPopup = ref(null); const addGroupPopup = ref(null); -const groupOptions = computed(() => (Array.isArray(archive.value.groupOptions) ? archive.value.groupOptions : [])); - const selectedGroupMap = ref({}); const syncSelectedMapFromArchive = () => { - const current = Array.isArray(archive.value.groups) ? archive.value.groups : []; - selectedGroupMap.value = current.reduce((acc, name) => { - acc[name] = true; + const current = Array.isArray(archive.value.groupIds) ? archive.value.groupIds.map(String) : []; + selectedGroupMap.value = current.reduce((acc, id) => { + acc[String(id)] = true; return acc; }, {}); }; -const openGroups = () => { +const openGroups = async () => { + await fetchTeamGroups(false); syncSelectedMapFromArchive(); groupPopup.value?.open(); }; @@ -549,14 +597,54 @@ const closeGroups = () => { groupPopup.value?.close(); }; -const toggleGroup = (name) => { - selectedGroupMap.value[name] = !selectedGroupMap.value[name]; +const toggleGroup = (groupId) => { + const key = String(groupId || ''); + if (!key) return; + selectedGroupMap.value[key] = !selectedGroupMap.value[key]; }; -const saveGroups = () => { - archive.value.groups = Object.keys(selectedGroupMap.value).filter(k => selectedGroupMap.value[k]); - saveToStorage(); - closeGroups(); +async function applyGroupChange(nextIds) { + const memberId = String(archiveId.value || ''); + if (!memberId) return false; + const prevIds = Array.isArray(archive.value.groupIds) ? archive.value.groupIds.map(String) : []; + const next = Array.isArray(nextIds) ? nextIds.map(String).filter(Boolean) : []; + + const toAdd = next.filter((id) => !prevIds.includes(id)); + const toRemove = prevIds.filter((id) => !next.includes(id)); + + if (toAdd.length === 0 && toRemove.length === 0) return true; + + loading('保存中...'); + try { + for (const id of toAdd) { + const res = await api('addGroupIdForMember', { memberId, toGroupId: id }); + if (!res?.success) { + toast(res?.message || '分组保存失败'); + return false; + } + } + for (const id of toRemove) { + const res = await api('addGroupIdForMember', { memberId, fromGroupId: id }); + if (!res?.success) { + toast(res?.message || '分组保存失败'); + return false; + } + } + uni.setStorageSync(NEED_RELOAD_STORAGE_KEY, 1); + await fetchArchive(); + return true; + } catch (e) { + toast('分组保存失败'); + return false; + } finally { + hideLoading(); + } +} + +const saveGroups = async () => { + const nextIds = Object.keys(selectedGroupMap.value).filter((k) => selectedGroupMap.value[k]); + const ok = await applyGroupChange(nextIds); + if (ok) closeGroups(); }; // 添加新分组 @@ -571,22 +659,46 @@ const closeAddGroup = () => { addGroupPopup.value?.close(); }; -const saveAddGroup = () => { +const saveAddGroup = async () => { const name = String(newGroupName.value || '').trim(); if (!name) { uni.showToast({ title: '请输入分组名称', icon: 'none' }); return; } - const exists = groupOptions.value.some(g => String(g).trim() === name); + const exists = (Array.isArray(teamGroups.value) ? teamGroups.value : []).some((g) => String(g?.groupName || '').trim() === name); if (exists) { uni.showToast({ title: '该分组已存在', icon: 'none' }); return; } - archive.value.groupOptions = [...groupOptions.value, name]; - selectedGroupMap.value[name] = true; - saveToStorage(); - closeAddGroup(); + const corpId = getCorpId(); + const team = uni.getStorageSync(CURRENT_TEAM_STORAGE_KEY) || {}; + const teamId = team?.teamId ? String(team.teamId) : ''; + const creator = getUserId(); + if (!corpId || !teamId || !creator) { + toast('缺少用户/团队信息'); + return; + } + + loading('保存中...'); + try { + const params = { groupName: name, teamId, groupType: 'team', creator }; + const res = await api('createGroup', { corpId, teamId, params }); + if (!res?.success) { + toast(res?.message || '新增分组失败'); + return; + } + await fetchTeamGroups(true); + // 自动选中新建分组(后续在“保存”时调用 addGroupIdForMember) + const newId = res.data ? String(res.data) : ''; + if (newId) selectedGroupMap.value[newId] = true; + uni.setStorageSync('ykt_case_groups_need_reload', 1); + closeAddGroup(); + } catch (e) { + toast('新增分组失败'); + } finally { + hideLoading(); + } }; diff --git a/pages/case/batch-share.vue b/pages/case/batch-share.vue index 93ff426..0c04dda 100644 --- a/pages/case/batch-share.vue +++ b/pages/case/batch-share.vue @@ -3,8 +3,8 @@ 选择共享团队 - {{ team ? team.name : "请选择团队" }} - + {{ team ? team.name : '请选择团队' }} + 共享客户:表示客户档案共享多个团队可见,多个团队可同时为该客户服务。 @@ -12,8 +12,8 @@ @@ -26,39 +26,129 @@ + diff --git a/pages/case/batch-transfer.vue b/pages/case/batch-transfer.vue index 998fb42..e6784ae 100644 --- a/pages/case/batch-transfer.vue +++ b/pages/case/batch-transfer.vue @@ -3,15 +3,15 @@ 选择新负责团队 - {{ team ? team.name : "请选择选择团队" }} - + {{ team ? team.name : '请选择团队' }} + @@ -26,40 +26,129 @@ + diff --git a/pages/case/case.vue b/pages/case/case.vue index 5732319..2ca2d57 100644 --- a/pages/case/case.vue +++ b/pages/case/case.vue @@ -31,13 +31,13 @@ - {{ tab }} + {{ tab.label }} @@ -83,7 +83,7 @@ -