feat(ui): 左侧菜单改分组式(微信管理/WhatsApp管理+下拉子菜单,对齐云客布局)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
浅念
2026-08-15 12:09:55 +08:00
parent 02f95af279
commit 9b21584e9a
5 changed files with 130 additions and 43 deletions
+7 -4
View File
@@ -1,6 +1,6 @@
<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import { useRouter } from 'vue-router'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage, type TabPaneName } from 'element-plus'
import { Download } from '@element-plus/icons-vue'
import { getCalls } from '@/api'
@@ -16,10 +16,15 @@ import { buildCallSections, readField } from '@/utils/callFields'
import { exportListToCsv } from '@/utils/csvExport'
import VoiceClipModal from '@/components/VoiceClipModal.vue'
const route = useRoute()
const router = useRouter()
// Calls aren't tied to a messaging channel — `channel` on a call is the call
// type (phone_call / voice_call / wa_voice_call). We keep a LOCAL filter so it
// doesn't fight the shared top-bar wechat/whatsapp store used by customers/groups.
const callType = ref<CallChannel>('voice_call')
const callType = ref<CallChannel>(
route.query.channel === 'whatsapp' ? 'wa_voice_call' : 'voice_call',
)
// 微信语音 tab scope filter: 对齐云客 微信好友/微信群 二分(isRoom 0=好友, 1=群)。
// 仅在 voice_call tab 生效;client-side 过滤当前页。
@@ -43,8 +48,6 @@ const voiceClipUserId = ref('')
const voiceClipChannel = ref<'wechat' | 'whatsapp'>('wechat')
const voiceClipStaffName = ref<string | null>(null)
const router = useRouter()
// All-fields drawer state.
const drawerOpen = ref(false)
const drawerCall = ref<PhoneCall | null>(null)
+5 -1
View File
@@ -47,7 +47,11 @@ const org = useOrgStore()
// activeTab 跟随全局 channelStore(StaffList viewCustomers 先 setChannel 再 push /customers)。
// channel 总是具体值('wechat' | 'whatsapp'),不会是 'all' —— CustomerList 强制按 tab 选 channel,
// loadTab 永不传 'all'(getCustomers 的 'all'→undefined 分支不会被触发)。
const activeTab = ref<TabKey>(channelStore.channel === 'whatsapp' ? 'whatsapp' : 'wechat')
const activeTab = ref<TabKey>(
route.query.channel === 'whatsapp' || (!route.query.channel && channelStore.channel === 'whatsapp')
? 'whatsapp'
: 'wechat',
)
const tabState = reactive<Record<TabKey, TabState>>({
wechat: freshTabState(),
whatsapp: freshTabState(),
+5 -1
View File
@@ -45,7 +45,11 @@ const channelStore = useChannelStore()
// activeTab 跟随全局 channelStore(StaffList viewGroups 先 setChannel 再 push /groups)。
// channel 总是具体值('wechat' | 'whatsapp'),不会是 'all'。
const activeTab = ref<TabKey>(channelStore.channel === 'whatsapp' ? 'whatsapp' : 'wechat')
const activeTab = ref<TabKey>(
route.query.channel === 'whatsapp' || (!route.query.channel && channelStore.channel === 'whatsapp')
? 'whatsapp'
: 'wechat',
)
const tabState = reactive<Record<TabKey, TabState>>({
wechat: freshTabState(),
whatsapp: freshTabState(),
+8 -5
View File
@@ -1,6 +1,6 @@
<script setup lang="ts">
import { computed, onMounted, reactive, ref } from 'vue'
import { useRouter } from 'vue-router'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { Download } from '@element-plus/icons-vue'
import { getAccounts, getCustomers, getStaffChatStats } from '@/api'
@@ -53,15 +53,18 @@ function freshTabState(): TabState {
}
}
const activeTab = ref<TabKey>('wechat')
const route = useRoute()
const router = useRouter()
const channelStore = useChannelStore()
const activeTab = ref<TabKey>(
(route.query.channel === 'whatsapp' ? 'whatsapp' : 'wechat') as TabKey,
)
const tabState = reactive<Record<TabKey, TabState>>({
wechat: freshTabState(),
whatsapp: freshTabState(),
})
const router = useRouter()
const channelStore = useChannelStore()
// All-fields drawer state (shared across tabs).
const drawerOpen = ref(false)
const drawerAccount = ref<Account | null>(null)