This commit is contained in:
jack ning
2025-06-03 09:05:17 +08:00
parent aaa2f59d4a
commit 32e91c0fd2
3 changed files with 394 additions and 0 deletions

View File

@@ -0,0 +1,91 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2025-06-03 14:10:02
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2025-06-03 14:46:13
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
* Business Source License 1.1: https://github.com/Bytedesk/bytedesk/blob/main/LICENSE
* contact: 270580156@qq.com
* 联系270580156@qq.com
* Copyright (c) 2025 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.freeswitch.controller;
import com.bytedesk.freeswitch.service.CallService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
@Controller
@RequestMapping("/callcenter")
public class FreeswitchController {
@Autowired
private CallService callService;
// 添加用户信息到所有请求
@ModelAttribute
public void addAttributes(@AuthenticationPrincipal UserDetails userDetails, Model model) {
if (userDetails != null) {
model.addAttribute("currentUser", userDetails);
}
}
// 呼叫中心首页
// http://127.0.0.1:9003/callcenter/
@GetMapping({"", "/"})
public String index(Model model) {
// 获取呼叫中心统计数据
model.addAttribute("totalCalls", callService.countTotalCalls());
model.addAttribute("activeCalls", callService.countActiveCalls());
model.addAttribute("missedCalls", callService.countMissedCalls());
model.addAttribute("avgDuration", callService.getAverageCallDuration());
return "callcenter/index";
}
// 历史通话记录页面
@GetMapping("/history")
public String callHistory(Model model,
@RequestParam(required = false) String keyword,
@RequestParam(required = false) String status,
@PageableDefault(size = 10, sort = "createdAt", direction = Sort.Direction.DESC) Pageable pageable) {
model.addAttribute("calls", callService.getCallHistory(keyword, status, pageable));
model.addAttribute("keyword", keyword);
model.addAttribute("status", status);
return "callcenter/history";
}
// 我的通话记录
@GetMapping("/user/calls")
public String userCalls(@AuthenticationPrincipal UserDetails userDetails, Model model,
@PageableDefault(size = 10, sort = "createdAt", direction = Sort.Direction.DESC) Pageable pageable) {
String userId = userDetails.getUsername();
model.addAttribute("calls", callService.getUserCalls(userId, pageable));
return "callcenter/user-calls";
}
// 管理员页面 - 实时监控
@GetMapping("/admin/monitor")
public String monitorCalls(Model model) {
model.addAttribute("activeCalls", callService.getActiveCalls());
return "callcenter/admin/monitor";
}
// 管理员页面 - 座席状态
@GetMapping("/admin/agents")
public String agentStatus(Model model) {
model.addAttribute("agents", callService.getAgentStatus());
return "callcenter/admin/agents";
}
}

View File

@@ -0,0 +1,215 @@
<#import "layout/base.ftl" as base>
<@base.base title="ByteDesk 呼叫中心">
<!-- 顶部介绍区域 -->
<div class="row text-center mb-5">
<div class="col">
<h1 class="display-4 mb-3">FreeSWITCH 呼叫中心系统</h1>
<p class="lead">专业智能的企业级通信解决方案,提供高质量的语音呼叫服务</p>
</div>
</div>
<!-- 顶部统计信息 -->
<div class="row mb-4">
<div class="col-md-3">
<div class="card text-center feature-box h-100">
<div class="card-body">
<div class="feature-icon">📞</div>
<h5 class="card-title">总通话量</h5>
<p class="card-text display-6">${totalCalls!'0'}</p>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card text-center feature-box h-100">
<div class="card-body">
<div class="feature-icon">🔄</div>
<h5 class="card-title">当前活动通话</h5>
<p class="card-text display-6">${activeCalls!'0'}</p>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card text-center feature-box h-100">
<div class="card-body">
<div class="feature-icon">❌</div>
<h5 class="card-title">未接来电</h5>
<p class="card-text display-6">${missedCalls!'0'}</p>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card text-center feature-box h-100">
<div class="card-body">
<div class="feature-icon">⏱️</div>
<h5 class="card-title">平均通话时长</h5>
<p class="card-text display-6">${avgDuration!'0'}分钟</p>
</div>
</div>
</div>
</div>
<!-- 功能介绍 -->
<div class="row mb-5">
<div class="col-12">
<div class="card shadow-sm border-0">
<div class="card-body p-4">
<h2 class="card-title mb-4">ByteDesk 呼叫中心解决方案</h2>
<p class="lead">我们基于FreeSWITCH打造的呼叫中心系统为企业提供高效、稳定、灵活的通信服务</p>
<div class="row mt-5">
<div class="col-md-4 mb-4">
<div class="d-flex">
<div class="flex-shrink-0">
<div class="feature-icon">☎️</div>
</div>
<div class="flex-grow-1 ms-3">
<h5>语音通话</h5>
<p>高质量、低延迟的语音通话服务,支持多方通话和会议</p>
</div>
</div>
</div>
<div class="col-md-4 mb-4">
<div class="d-flex">
<div class="flex-shrink-0">
<div class="feature-icon">🔄</div>
</div>
<div class="flex-grow-1 ms-3">
<h5>智能路由</h5>
<p>基于技能、状态的智能呼叫分配,提高客服效率</p>
</div>
</div>
</div>
<div class="col-md-4 mb-4">
<div class="d-flex">
<div class="flex-shrink-0">
<div class="feature-icon">📊</div>
</div>
<div class="flex-grow-1 ms-3">
<h5>实时监控</h5>
<p>实时监控座席状态和通话质量,确保服务水平</p>
</div>
</div>
</div>
<div class="col-md-4 mb-4">
<div class="d-flex">
<div class="flex-shrink-0">
<div class="feature-icon">📱</div>
</div>
<div class="flex-grow-1 ms-3">
<h5>多通道接入</h5>
<p>支持SIP、WebRTC、手机、固话等多种接入方式</p>
</div>
</div>
</div>
<div class="col-md-4 mb-4">
<div class="d-flex">
<div class="flex-shrink-0">
<div class="feature-icon">🔌</div>
</div>
<div class="flex-grow-1 ms-3">
<h5>系统集成</h5>
<p>与CRM、客服系统等无缝集成提供统一服务体验</p>
</div>
</div>
</div>
<div class="col-md-4 mb-4">
<div class="d-flex">
<div class="flex-shrink-0">
<div class="feature-icon">🤖</div>
</div>
<div class="flex-grow-1 ms-3">
<h5>智能语音助手</h5>
<p>基于AI的语音识别和交互提供智能服务体验</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 技术架构介绍 -->
<div class="row mb-5">
<div class="col-12">
<div class="card shadow-sm border-0">
<div class="card-body p-4">
<h3 class="card-title mb-4">系统架构</h3>
<div class="row align-items-center">
<div class="col-md-6">
<h5 class="mb-3">FreeSWITCH 核心优势</h5>
<ul class="list-group list-group-flush">
<li class="list-group-item bg-transparent">高性能处理引擎,支持上千并发通话</li>
<li class="list-group-item bg-transparent">多协议支持SIP、WebRTC、PSTN等</li>
<li class="list-group-item bg-transparent">丰富的媒体处理能力,支持转码、录音、回声消除等</li>
<li class="list-group-item bg-transparent">灵活的路由策略,支持复杂呼叫场景</li>
<li class="list-group-item bg-transparent">开源稳定,易于扩展和定制</li>
</ul>
</div>
<div class="col-md-6">
<h5 class="mb-3">系统层级结构</h5>
<div class="bg-light p-3 rounded">
<pre class="mb-0"><code>
└── 呼叫中心系统
├── 接入层
│ ├── SIP接入
│ ├── WebRTC接入
│ └── PSTN接入
├── 核心层
│ ├── FreeSWITCH引擎
│ ├── 呼叫控制
│ └── 媒体处理
└── 应用层
├── 座席管理
├── 队列管理
├── 统计报表
└── 系统监控
</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 客户案例或使用场景 -->
<div class="row mb-5">
<div class="col-12">
<div class="card shadow-sm border-0">
<div class="card-body p-4">
<h3 class="card-title mb-4">应用场景</h3>
<div class="row">
<div class="col-md-4 mb-4">
<div class="card h-100">
<div class="card-body">
<h5 class="card-title">客服中心</h5>
<p class="card-text">为企业提供专业的呼入式客服中心解决方案,高效处理客户咨询与服务请求。</p>
</div>
</div>
</div>
<div class="col-md-4 mb-4">
<div class="card h-100">
<div class="card-body">
<h5 class="card-title">销售外呼</h5>
<p class="card-text">支持团队高效率销售外呼,提高接通率和转化率,实现销售目标。</p>
</div>
</div>
</div>
<div class="col-md-4 mb-4">
<div class="card h-100">
<div class="card-body">
<h5 class="card-title">远程办公</h5>
<p class="card-text">为远程办公团队提供统一通信平台,保持团队协作和客户服务无缝衔接。</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</@base.base>

View File

@@ -0,0 +1,88 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>${title!'ByteDesk 呼叫中心'}</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.2/font/bootstrap-icons.css" rel="stylesheet">
<link href="/css/callcenter/style.css" rel="stylesheet">
</head>
<body>
<!-- 导航栏 -->
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
<div class="container">
<a class="navbar-brand" href="/callcenter">ByteDesk 呼叫中心</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav me-auto">
<li class="nav-item">
<a class="nav-link" href="/callcenter">首页</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/callcenter/history">通话记录</a>
</li>
<#if currentUser??>
<li class="nav-item">
<a class="nav-link" href="/callcenter/user/calls">我的通话</a>
</li>
<#if currentUser.hasRole('ADMIN')>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" data-bs-toggle="dropdown">
管理
</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="/callcenter/admin/monitor">实时监控</a></li>
<li><a class="dropdown-item" href="/callcenter/admin/agents">座席状态</a></li>
</ul>
</li>
</#if>
</#if>
</ul>
<ul class="navbar-nav">
<#if currentUser??>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" data-bs-toggle="dropdown">
${currentUser.displayName!'用户'}
</a>
<ul class="dropdown-menu dropdown-menu-end">
<li><a class="dropdown-item" href="/profile">个人资料</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="/logout">退出登录</a></li>
</ul>
</li>
<#else>
<li class="nav-item">
<a class="nav-link" href="/login">登录</a>
</li>
</#if>
</ul>
</div>
</div>
</nav>
<main class="container my-4">
<#nested>
</main>
<!-- 页脚 -->
<footer class="bg-light py-4 mt-5">
<div class="container">
<div class="row">
<div class="col-md-6">
<h5>ByteDesk 呼叫中心</h5>
<p>专业智能的呼叫中心解决方案</p>
</div>
<div class="col-md-6 text-end">
<p>&copy; 2025 ByteDesk. All rights reserved.</p>
</div>
</div>
</div>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script src="/js/callcenter/main.js"></script>
</body>
</html>