fix(widget): 完善自动回复与新会话进线提醒
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
import { Button, Form, message } from 'antd'
|
||||
import { PlusOutlined } from '@ant-design/icons'
|
||||
import {
|
||||
@@ -24,11 +24,19 @@ import TagsSection from './settings/TagsSection'
|
||||
import TagModal from './settings/TagModal'
|
||||
|
||||
const Settings = () => {
|
||||
const { user } = useAuth()
|
||||
const isAdmin = usePermission('settings.basic')
|
||||
const { user, permissions } = useAuth()
|
||||
const canViewStaff = usePermission('settings.staff')
|
||||
const canEditAssignment = usePermission('settings.assign_rule')
|
||||
|
||||
const [activeTab, setActiveTab] = useState('basic')
|
||||
const visibleTabGroups = useMemo(
|
||||
() => tabGroups
|
||||
.map(group => ({ ...group, items: group.items.filter(item => permissions.has(item.permission)) }))
|
||||
.filter(group => group.items.length > 0),
|
||||
[permissions],
|
||||
)
|
||||
const visibleTabItems = useMemo(() => visibleTabGroups.flatMap(group => group.items), [visibleTabGroups])
|
||||
|
||||
const [activeTab, setActiveTab] = useState(() => visibleTabItems[0]?.key || '')
|
||||
const [basicForm] = Form.useForm()
|
||||
const [autoReplyForm] = Form.useForm()
|
||||
const [workForm] = Form.useForm()
|
||||
@@ -60,7 +68,7 @@ const Settings = () => {
|
||||
const [savingTag, setSavingTag] = useState(false)
|
||||
const [tagForm] = Form.useForm()
|
||||
|
||||
const currentTab = tabItems.find(t => t.key === activeTab) || tabItems[0]
|
||||
const currentTab = visibleTabItems.find(t => t.key === activeTab) || visibleTabItems[0] || tabItems[0]
|
||||
|
||||
const loadCustomerTags = async () => {
|
||||
setLoadingTags(true)
|
||||
@@ -146,6 +154,12 @@ const Settings = () => {
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (visibleTabItems.length > 0 && !visibleTabItems.some(item => item.key === activeTab)) {
|
||||
setActiveTab(visibleTabItems[0].key)
|
||||
}
|
||||
}, [activeTab, visibleTabItems])
|
||||
|
||||
useEffect(() => {
|
||||
if (activeTab === 'channels') loadChannels()
|
||||
if (['basic', 'autoreply', 'worktime', 'notify', 'assignment'].includes(activeTab)) loadSettings()
|
||||
@@ -284,7 +298,7 @@ const Settings = () => {
|
||||
</Button>
|
||||
) : null
|
||||
|
||||
const currentGroup = tabGroups.find(g => g.items.some(i => i.key === activeTab))
|
||||
const currentGroup = visibleTabGroups.find(g => g.items.some(i => i.key === activeTab))
|
||||
|
||||
return (
|
||||
<div className="h-full flex min-h-0 overflow-hidden bg-slate-50/60">
|
||||
@@ -298,7 +312,7 @@ const Settings = () => {
|
||||
<div className="text-[10px] text-slate-400 truncate leading-tight mt-0.5 font-medium">企业配置与业务规则</div>
|
||||
</div>
|
||||
<nav className="flex-1 overflow-y-auto p-3 space-y-4">
|
||||
{tabGroups.map(group => (
|
||||
{visibleTabGroups.map(group => (
|
||||
<div key={group.groupName} className="space-y-1">
|
||||
<div className="text-[10px] font-bold text-slate-400 uppercase tracking-wider px-2.5 mb-1 select-none">
|
||||
{group.groupName}
|
||||
@@ -345,7 +359,7 @@ const Settings = () => {
|
||||
<p className="text-xs text-slate-500 m-0 leading-tight truncate">{currentTab.desc}</p>
|
||||
</div>
|
||||
{panelHeaderAction}
|
||||
{activeTab === 'staff' && isAdmin && (
|
||||
{activeTab === 'staff' && canViewStaff && (
|
||||
<Button
|
||||
type="primary"
|
||||
size="small"
|
||||
@@ -386,7 +400,7 @@ const Settings = () => {
|
||||
<AssignmentSection
|
||||
assignForm={assignForm}
|
||||
loading={loadingSettings && !settings}
|
||||
isAdmin={isAdmin}
|
||||
isAdmin={canEditAssignment}
|
||||
saving={saving}
|
||||
onSave={savePartial}
|
||||
/>
|
||||
@@ -397,7 +411,7 @@ const Settings = () => {
|
||||
canViewStaff={canViewStaff}
|
||||
loadingStaff={loadingStaff}
|
||||
staffList={staffList}
|
||||
isAdmin={isAdmin}
|
||||
isAdmin={canViewStaff}
|
||||
seatUsed={seatUsed}
|
||||
seatLimit={seatLimit}
|
||||
currentUserId={user?.user_id}
|
||||
@@ -467,7 +481,7 @@ const Settings = () => {
|
||||
setStaffModalOpen={setStaffModalOpen}
|
||||
editingStaff={editingStaff}
|
||||
savingStaff={savingStaff}
|
||||
isAdmin={isAdmin}
|
||||
isAdmin={canViewStaff}
|
||||
staffForm={staffForm}
|
||||
onFinish={handleSaveStaff}
|
||||
/>
|
||||
|
||||
@@ -9,6 +9,7 @@ export interface TabItem {
|
||||
key: string
|
||||
label: string
|
||||
desc: string
|
||||
permission: string
|
||||
icon: ReactNode
|
||||
}
|
||||
|
||||
@@ -21,24 +22,24 @@ export const tabGroups: TabGroup[] = [
|
||||
{
|
||||
groupName: '企业与渠道',
|
||||
items: [
|
||||
{ key: 'basic', label: '基本设置', desc: '租户展示名称、默认昵称与时区', icon: <SettingOutlined /> },
|
||||
{ key: 'channels', label: '渠道管理', desc: '配置客户服务接入渠道与嵌入代码', icon: <ApiOutlined /> },
|
||||
{ key: 'staff', label: '坐席账号', desc: '管理客服/主管账号与坐席配额', icon: <UserSwitchOutlined /> },
|
||||
{ key: 'basic', label: '基本设置', desc: '租户展示名称、默认昵称与时区', permission: 'settings.basic', icon: <SettingOutlined /> },
|
||||
{ key: 'channels', label: '渠道管理', desc: '配置客户服务接入渠道与嵌入代码', permission: 'settings.channel', icon: <ApiOutlined /> },
|
||||
{ key: 'staff', label: '坐席账号', desc: '管理客服/主管账号与坐席配额', permission: 'settings.staff', icon: <UserSwitchOutlined /> },
|
||||
],
|
||||
},
|
||||
{
|
||||
groupName: '规则与路由',
|
||||
items: [
|
||||
{ key: 'assignment', label: '客服分配规则', desc: '自动分配策略与并发上限', icon: <TeamOutlined /> },
|
||||
{ key: 'tags', label: '客户标签', desc: '维护标签库,坐席为客户打标时选择', icon: <TagsOutlined /> },
|
||||
{ key: 'worktime', label: '工作时间', desc: '在线服务时段与非工作时间提示', icon: <ClockCircleOutlined /> },
|
||||
{ key: 'assignment', label: '客服分配规则', desc: '自动分配策略与并发上限', permission: 'settings.assign_rule', icon: <TeamOutlined /> },
|
||||
{ key: 'tags', label: '客户标签', desc: '维护标签库,坐席为客户打标时选择', permission: 'settings.customer_tag', icon: <TagsOutlined /> },
|
||||
{ key: 'worktime', label: '工作时间', desc: '在线服务时段与非工作时间提示', permission: 'settings.worktime', icon: <ClockCircleOutlined /> },
|
||||
],
|
||||
},
|
||||
{
|
||||
groupName: '自动化与通知',
|
||||
items: [
|
||||
{ key: 'autoreply', label: '自动回复', desc: '多段欢迎语(含图片)与离线留言提示', icon: <MessageOutlined /> },
|
||||
{ key: 'notify', label: '通知设置', desc: '声音、朗读、新会话与留言提醒', icon: <BellOutlined /> },
|
||||
{ key: 'autoreply', label: '自动回复', desc: '多段欢迎语(含图片)与离线留言提示', permission: 'settings.auto_reply', icon: <MessageOutlined /> },
|
||||
{ key: 'notify', label: '通知设置', desc: '声音、朗读、新会话与留言提醒', permission: 'settings.notification', icon: <BellOutlined /> },
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user