mirror of
https://gitee.com/270580156/weiyu.git
synced 2026-05-19 05:37:53 +00:00
update plugins/freeswitch: add 36 mod 4 del 1 files
This commit is contained in:
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* @Author: jackning 270580156@qq.com
|
||||
* @Date: 2025-06-09 10:00:00
|
||||
* @LastEditors: jackning 270580156@qq.com
|
||||
* @LastEditTime: 2025-06-09 10:00:00
|
||||
* @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
|
||||
*
|
||||
* Copyright (c) 2025 by bytedesk.com, All Rights Reserved.
|
||||
*/
|
||||
package com.bytedesk.freeswitch.model;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import com.bytedesk.core.base.BaseEntity;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.EntityListeners;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
/**
|
||||
* FreeSwitch通话详单记录实体
|
||||
* 对应数据库表:freeswitch_cdr
|
||||
*/
|
||||
@Entity
|
||||
@Data
|
||||
@SuperBuilder
|
||||
@Accessors(chain = true)
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@EntityListeners({FreeSwitchCdrEntityListener.class})
|
||||
@Table(name = "freeswitch_cdr")
|
||||
public class FreeSwitchCdrEntity extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 通话唯一标识符
|
||||
*/
|
||||
@Column(name = "uuid", nullable = false, unique = true, length = 36)
|
||||
private String uuid;
|
||||
|
||||
/**
|
||||
* 主叫名称
|
||||
*/
|
||||
@Column(name = "caller_id_name", length = 100)
|
||||
private String callerIdName;
|
||||
|
||||
/**
|
||||
* 主叫号码
|
||||
*/
|
||||
@Column(name = "caller_id_number", nullable = false, length = 50)
|
||||
private String callerIdNumber;
|
||||
|
||||
/**
|
||||
* 被叫号码
|
||||
*/
|
||||
@Column(name = "destination_number", nullable = false, length = 50)
|
||||
private String destinationNumber;
|
||||
|
||||
/**
|
||||
* 上下文
|
||||
*/
|
||||
@Column(name = "context", length = 50)
|
||||
private String context;
|
||||
|
||||
/**
|
||||
* 通话开始时间
|
||||
*/
|
||||
@Column(name = "start_stamp")
|
||||
private LocalDateTime startStamp;
|
||||
|
||||
/**
|
||||
* 通话接通时间
|
||||
*/
|
||||
@Column(name = "answer_stamp")
|
||||
private LocalDateTime answerStamp;
|
||||
|
||||
/**
|
||||
* 通话结束时间
|
||||
*/
|
||||
@Column(name = "end_stamp")
|
||||
private LocalDateTime endStamp;
|
||||
|
||||
/**
|
||||
* 通话总时长(秒)
|
||||
*/
|
||||
@Column(name = "duration")
|
||||
private Integer duration;
|
||||
|
||||
/**
|
||||
* 计费时长(秒)
|
||||
*/
|
||||
@Column(name = "billsec")
|
||||
private Integer billsec;
|
||||
|
||||
/**
|
||||
* 挂断原因
|
||||
*/
|
||||
@Column(name = "hangup_cause", length = 50)
|
||||
private String hangupCause;
|
||||
|
||||
/**
|
||||
* 账户代码
|
||||
*/
|
||||
@Column(name = "accountcode", length = 50)
|
||||
private String accountcode;
|
||||
|
||||
/**
|
||||
* 读取编解码器
|
||||
*/
|
||||
@Column(name = "read_codec", length = 20)
|
||||
private String readCodec;
|
||||
|
||||
/**
|
||||
* 写入编解码器
|
||||
*/
|
||||
@Column(name = "write_codec", length = 20)
|
||||
private String writeCodec;
|
||||
|
||||
/**
|
||||
* SIP挂断处理
|
||||
*/
|
||||
@Column(name = "sip_hangup_disposition", length = 50)
|
||||
private String sipHangupDisposition;
|
||||
|
||||
/**
|
||||
* 录音文件路径
|
||||
*/
|
||||
@Column(name = "record_file", length = 500)
|
||||
private String recordFile;
|
||||
|
||||
/**
|
||||
* 通话方向(inbound/outbound)
|
||||
*/
|
||||
@Column(name = "direction", length = 20)
|
||||
private String direction;
|
||||
|
||||
/**
|
||||
* JSON格式的扩展信息
|
||||
*/
|
||||
@Column(name = "json", columnDefinition = "TEXT")
|
||||
private String json;
|
||||
|
||||
/**
|
||||
* 获取通话状态描述
|
||||
*/
|
||||
public String getCallStatusDescription() {
|
||||
if (answerStamp != null) {
|
||||
return "已接通";
|
||||
} else if (hangupCause != null) {
|
||||
return "未接通 - " + hangupCause;
|
||||
} else {
|
||||
return "未知状态";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否为成功通话
|
||||
*/
|
||||
public boolean isSuccessfulCall() {
|
||||
return answerStamp != null && billsec != null && billsec > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取格式化的通话时长
|
||||
*/
|
||||
public String getFormattedDuration() {
|
||||
if (duration == null) return "00:00:00";
|
||||
|
||||
int hours = duration / 3600;
|
||||
int minutes = (duration % 3600) / 60;
|
||||
int seconds = duration % 60;
|
||||
|
||||
return String.format("%02d:%02d:%02d", hours, minutes, seconds);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* @Author: jackning 270580156@qq.com
|
||||
* @Date: 2025-06-09 10:00:00
|
||||
* @LastEditors: jackning 270580156@qq.com
|
||||
* @LastEditTime: 2025-06-09 10:00:00
|
||||
* @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
|
||||
*
|
||||
* Copyright (c) 2025 by bytedesk.com, All Rights Reserved.
|
||||
*/
|
||||
package com.bytedesk.freeswitch.model;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import jakarta.persistence.PostPersist;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* FreeSwitch CDR实体监听器
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class FreeSwitchCdrEntityListener {
|
||||
|
||||
@PostPersist
|
||||
public void postPersist(FreeSwitchCdrEntity entity) {
|
||||
log.info("FreeSwitch CDR记录创建: uuid={}, caller={}, destination={}, duration={}",
|
||||
entity.getUuid(), entity.getCallerIdNumber(),
|
||||
entity.getDestinationNumber(), entity.getDuration());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* @Author: jackning 270580156@qq.com
|
||||
* @Date: 2025-06-09 10:00:00
|
||||
* @LastEditors: jackning 270580156@qq.com
|
||||
* @LastEditTime: 2025-06-09 10:00:00
|
||||
* @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
|
||||
*
|
||||
* Copyright (c) 2025 by bytedesk.com, All Rights Reserved.
|
||||
*/
|
||||
package com.bytedesk.freeswitch.model;
|
||||
|
||||
import com.bytedesk.core.base.BaseEntity;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.EntityListeners;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
/**
|
||||
* FreeSwitch会议室实体
|
||||
* 对应数据库表:freeswitch_conferences
|
||||
*/
|
||||
@Entity
|
||||
@Data
|
||||
@SuperBuilder
|
||||
@Accessors(chain = true)
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@EntityListeners({FreeSwitchConferenceEntityListener.class})
|
||||
@Table(name = "freeswitch_conferences")
|
||||
public class FreeSwitchConferenceEntity extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 会议室名称
|
||||
*/
|
||||
@Column(name = "conference_name", nullable = false, unique = true, length = 100)
|
||||
private String conferenceName;
|
||||
|
||||
/**
|
||||
* 会议室描述
|
||||
*/
|
||||
@Column(name = "description", length = 255)
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 会议室密码
|
||||
*/
|
||||
@Column(name = "password", length = 50)
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 最大参与者数量
|
||||
*/
|
||||
@Column(name = "max_members")
|
||||
private Integer maxMembers;
|
||||
|
||||
/**
|
||||
* 是否启用
|
||||
*/
|
||||
@Column(name = "enabled", nullable = false)
|
||||
private Boolean enabled = true;
|
||||
|
||||
/**
|
||||
* 是否录音
|
||||
*/
|
||||
@Column(name = "record_enabled", nullable = false)
|
||||
private Boolean recordEnabled = false;
|
||||
|
||||
/**
|
||||
* 录音文件路径
|
||||
*/
|
||||
@Column(name = "record_path", length = 500)
|
||||
private String recordPath;
|
||||
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
@Column(name = "creator", length = 100)
|
||||
private String creator;
|
||||
|
||||
/**
|
||||
* 会议室配置参数(JSON格式)
|
||||
*/
|
||||
@Column(name = "config_json", columnDefinition = "TEXT")
|
||||
private String configJson;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@Column(name = "remarks", length = 500)
|
||||
private String remarks;
|
||||
|
||||
/**
|
||||
* 检查会议室是否有密码保护
|
||||
*/
|
||||
public boolean isPasswordProtected() {
|
||||
return password != null && !password.trim().isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查会议室是否已满
|
||||
*/
|
||||
public boolean isFull(int currentMembers) {
|
||||
return maxMembers != null && currentMembers >= maxMembers;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* @Author: jackning 270580156@qq.com
|
||||
* @Date: 2025-06-09 10:00:00
|
||||
* @LastEditors: jackning 270580156@qq.com
|
||||
* @LastEditTime: 2025-06-09 10:00:00
|
||||
* @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
|
||||
*
|
||||
* Copyright (c) 2025 by bytedesk.com, All Rights Reserved.
|
||||
*/
|
||||
package com.bytedesk.freeswitch.model;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import jakarta.persistence.PostPersist;
|
||||
import jakarta.persistence.PostUpdate;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* FreeSwitch会议室实体监听器
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class FreeSwitchConferenceEntityListener {
|
||||
|
||||
@PostPersist
|
||||
public void postPersist(FreeSwitchConferenceEntity entity) {
|
||||
log.info("FreeSwitch会议室创建: name={}, maxMembers={}",
|
||||
entity.getConferenceName(), entity.getMaxMembers());
|
||||
}
|
||||
|
||||
@PostUpdate
|
||||
public void postUpdate(FreeSwitchConferenceEntity entity) {
|
||||
log.info("FreeSwitch会议室更新: name={}, enabled={}",
|
||||
entity.getConferenceName(), entity.getEnabled());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* @Author: jackning 270580156@qq.com
|
||||
* @Date: 2025-06-09 10:00:00
|
||||
* @LastEditors: jackning 270580156@qq.com
|
||||
* @LastEditTime: 2025-06-09 10:00:00
|
||||
* @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
|
||||
*
|
||||
* Copyright (c) 2025 by bytedesk.com, All Rights Reserved.
|
||||
*/
|
||||
package com.bytedesk.freeswitch.model;
|
||||
|
||||
import com.bytedesk.core.base.BaseEntity;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.EntityListeners;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
/**
|
||||
* FreeSwitch网关实体
|
||||
* 对应数据库表:freeswitch_gateways
|
||||
*/
|
||||
@Entity
|
||||
@Data
|
||||
@SuperBuilder
|
||||
@Accessors(chain = true)
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@EntityListeners({FreeSwitchGatewayEntityListener.class})
|
||||
@Table(name = "freeswitch_gateways")
|
||||
public class FreeSwitchGatewayEntity extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 网关名称
|
||||
*/
|
||||
@Column(name = "gateway_name", nullable = false, unique = true, length = 100)
|
||||
private String gatewayName;
|
||||
|
||||
/**
|
||||
* 网关描述
|
||||
*/
|
||||
@Column(name = "description", length = 255)
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* SIP服务器地址
|
||||
*/
|
||||
@Column(name = "proxy", nullable = false, length = 255)
|
||||
private String proxy;
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
@Column(name = "username", nullable = false, length = 100)
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
@Column(name = "password", nullable = false, length = 255)
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 从号码
|
||||
*/
|
||||
@Column(name = "from_user", length = 100)
|
||||
private String fromUser;
|
||||
|
||||
/**
|
||||
* 从域名
|
||||
*/
|
||||
@Column(name = "from_domain", length = 100)
|
||||
private String fromDomain;
|
||||
|
||||
/**
|
||||
* 注册
|
||||
*/
|
||||
@Column(name = "register", nullable = false)
|
||||
private Boolean register = true;
|
||||
|
||||
/**
|
||||
* 注册传输协议
|
||||
*/
|
||||
@Column(name = "register_transport", length = 20)
|
||||
private String registerTransport = "udp";
|
||||
|
||||
/**
|
||||
* 网关状态
|
||||
*/
|
||||
@Column(name = "status", length = 20)
|
||||
private String status = "DOWN";
|
||||
|
||||
/**
|
||||
* 是否启用
|
||||
*/
|
||||
@Column(name = "enabled", nullable = false)
|
||||
private Boolean enabled = true;
|
||||
|
||||
/**
|
||||
* 扩展配置(JSON格式)
|
||||
*/
|
||||
@Column(name = "config_json", columnDefinition = "TEXT")
|
||||
private String configJson;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@Column(name = "remarks", length = 500)
|
||||
private String remarks;
|
||||
|
||||
/**
|
||||
* 检查网关是否在线
|
||||
*/
|
||||
public boolean isOnline() {
|
||||
return "UP".equalsIgnoreCase(status) && enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取完整的代理地址
|
||||
*/
|
||||
public String getFullProxy() {
|
||||
if (proxy.contains("sip:")) {
|
||||
return proxy;
|
||||
}
|
||||
return "sip:" + proxy;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* @Author: jackning 270580156@qq.com
|
||||
* @Date: 2025-06-09 10:00:00
|
||||
* @LastEditors: jackning 270580156@qq.com
|
||||
* @LastEditTime: 2025-06-09 10:00:00
|
||||
* @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
|
||||
*
|
||||
* Copyright (c) 2025 by bytedesk.com, All Rights Reserved.
|
||||
*/
|
||||
package com.bytedesk.freeswitch.model;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import jakarta.persistence.PostPersist;
|
||||
import jakarta.persistence.PostUpdate;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* FreeSwitch网关实体监听器
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class FreeSwitchGatewayEntityListener {
|
||||
|
||||
@PostPersist
|
||||
public void postPersist(FreeSwitchGatewayEntity entity) {
|
||||
log.info("FreeSwitch网关创建: name={}, proxy={}",
|
||||
entity.getGatewayName(), entity.getProxy());
|
||||
}
|
||||
|
||||
@PostUpdate
|
||||
public void postUpdate(FreeSwitchGatewayEntity entity) {
|
||||
log.info("FreeSwitch网关更新: name={}, status={}, enabled={}",
|
||||
entity.getGatewayName(), entity.getStatus(), entity.getEnabled());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* @Author: jackning 270580156@qq.com
|
||||
* @Date: 2025-06-09 10:00:00
|
||||
* @LastEditors: jackning 270580156@qq.com
|
||||
* @LastEditTime: 2025-06-09 10:00:00
|
||||
* @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
|
||||
*
|
||||
* Copyright (c) 2025 by bytedesk.com, All Rights Reserved.
|
||||
*/
|
||||
package com.bytedesk.freeswitch.model;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import com.bytedesk.core.base.BaseEntity;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.EntityListeners;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
/**
|
||||
* FreeSwitch用户实体
|
||||
* 对应数据库表:freeswitch_users
|
||||
*/
|
||||
@Entity
|
||||
@Data
|
||||
@SuperBuilder
|
||||
@Accessors(chain = true)
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@EntityListeners({FreeSwitchUserEntityListener.class})
|
||||
@Table(name = "freeswitch_users")
|
||||
public class FreeSwitchUserEntity extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 用户名(SIP用户名)
|
||||
*/
|
||||
@Column(name = "username", nullable = false, unique = true, length = 50)
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* SIP域名
|
||||
*/
|
||||
@Column(name = "domain", nullable = false, length = 100)
|
||||
private String domain;
|
||||
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
@Column(name = "password", nullable = false, length = 255)
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 显示名称
|
||||
*/
|
||||
@Column(name = "display_name", length = 100)
|
||||
private String displayName;
|
||||
|
||||
/**
|
||||
* 邮箱
|
||||
*/
|
||||
@Column(name = "email", length = 100)
|
||||
private String email;
|
||||
|
||||
/**
|
||||
* 账户代码
|
||||
*/
|
||||
@Column(name = "accountcode", length = 50)
|
||||
private String accountcode;
|
||||
|
||||
/**
|
||||
* 是否启用
|
||||
*/
|
||||
@Column(name = "enabled", nullable = false)
|
||||
private Boolean enabled = true;
|
||||
|
||||
/**
|
||||
* 最后注册时间
|
||||
*/
|
||||
@Column(name = "last_register")
|
||||
private LocalDateTime lastRegister;
|
||||
|
||||
/**
|
||||
* 注册IP地址
|
||||
*/
|
||||
@Column(name = "register_ip", length = 45)
|
||||
private String registerIp;
|
||||
|
||||
/**
|
||||
* 用户代理
|
||||
*/
|
||||
@Column(name = "user_agent", length = 255)
|
||||
private String userAgent;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@Column(name = "remarks", length = 500)
|
||||
private String remarks;
|
||||
|
||||
/**
|
||||
* 获取完整的SIP地址
|
||||
*/
|
||||
public String getSipAddress() {
|
||||
return username + "@" + domain;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查用户是否在线
|
||||
*/
|
||||
public boolean isOnline() {
|
||||
return enabled && lastRegister != null &&
|
||||
lastRegister.isAfter(LocalDateTime.now().minusMinutes(5));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* @Author: jackning 270580156@qq.com
|
||||
* @Date: 2025-06-09 10:00:00
|
||||
* @LastEditors: jackning 270580156@qq.com
|
||||
* @LastEditTime: 2025-06-09 10:00:00
|
||||
* @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
|
||||
*
|
||||
* Copyright (c) 2025 by bytedesk.com, All Rights Reserved.
|
||||
*/
|
||||
package com.bytedesk.freeswitch.model;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import jakarta.persistence.PostPersist;
|
||||
import jakarta.persistence.PostUpdate;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* FreeSwitch用户实体监听器
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class FreeSwitchUserEntityListener {
|
||||
|
||||
@PostPersist
|
||||
public void postPersist(FreeSwitchUserEntity entity) {
|
||||
log.info("FreeSwitch用户创建: username={}, domain={}",
|
||||
entity.getUsername(), entity.getDomain());
|
||||
}
|
||||
|
||||
@PostUpdate
|
||||
public void postUpdate(FreeSwitchUserEntity entity) {
|
||||
log.info("FreeSwitch用户更新: username={}, enabled={}",
|
||||
entity.getUsername(), entity.getEnabled());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* @Author: jackning 270580156@qq.com
|
||||
* @Date: 2025-06-09 10:00:00
|
||||
* @LastEditors: jackning 270580156@qq.com
|
||||
* @LastEditTime: 2025-06-09 10:00:00
|
||||
* @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
|
||||
*
|
||||
* Copyright (c) 2025 by bytedesk.com, All Rights Reserved.
|
||||
*/
|
||||
package com.bytedesk.freeswitch.repository;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.bytedesk.freeswitch.model.FreeSwitchCdrEntity;
|
||||
|
||||
/**
|
||||
* FreeSwitch CDR仓库接口
|
||||
*/
|
||||
@Repository
|
||||
public interface FreeSwitchCdrRepository extends JpaRepository<FreeSwitchCdrEntity, Long>,
|
||||
JpaSpecificationExecutor<FreeSwitchCdrEntity> {
|
||||
|
||||
/**
|
||||
* 根据UUID查找CDR记录
|
||||
*/
|
||||
Optional<FreeSwitchCdrEntity> findByUuid(String uuid);
|
||||
|
||||
/**
|
||||
* 根据主叫号码查找CDR记录
|
||||
*/
|
||||
List<FreeSwitchCdrEntity> findByCallerIdNumber(String callerIdNumber);
|
||||
|
||||
/**
|
||||
* 根据被叫号码查找CDR记录
|
||||
*/
|
||||
List<FreeSwitchCdrEntity> findByDestinationNumber(String destinationNumber);
|
||||
|
||||
/**
|
||||
* 根据账户代码查找CDR记录
|
||||
*/
|
||||
List<FreeSwitchCdrEntity> findByAccountcode(String accountcode);
|
||||
|
||||
/**
|
||||
* 根据通话方向查找CDR记录
|
||||
*/
|
||||
List<FreeSwitchCdrEntity> findByDirection(String direction);
|
||||
|
||||
/**
|
||||
* 根据挂断原因查找CDR记录
|
||||
*/
|
||||
List<FreeSwitchCdrEntity> findByHangupCause(String hangupCause);
|
||||
|
||||
/**
|
||||
* 查找指定时间范围内的CDR记录
|
||||
*/
|
||||
List<FreeSwitchCdrEntity> findByStartStampBetween(LocalDateTime startTime, LocalDateTime endTime);
|
||||
|
||||
/**
|
||||
* 查找成功接通的通话记录
|
||||
*/
|
||||
List<FreeSwitchCdrEntity> findByAnswerStampIsNotNull();
|
||||
|
||||
/**
|
||||
* 查找有录音文件的通话记录
|
||||
*/
|
||||
List<FreeSwitchCdrEntity> findByRecordFileIsNotNull();
|
||||
|
||||
/**
|
||||
* 根据主叫或被叫号码查找CDR记录
|
||||
*/
|
||||
@Query("SELECT c FROM FreeSwitchCdrEntity c WHERE c.callerIdNumber = :number OR c.destinationNumber = :number")
|
||||
List<FreeSwitchCdrEntity> findByCallerOrDestination(@Param("number") String number);
|
||||
|
||||
/**
|
||||
* 查找指定号码的通话历史(分页)
|
||||
*/
|
||||
@Query("SELECT c FROM FreeSwitchCdrEntity c WHERE c.callerIdNumber = :number OR c.destinationNumber = :number ORDER BY c.startStamp DESC")
|
||||
Page<FreeSwitchCdrEntity> findCallHistory(@Param("number") String number, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 统计指定时间范围内的通话数量
|
||||
*/
|
||||
@Query("SELECT COUNT(c) FROM FreeSwitchCdrEntity c WHERE c.startStamp BETWEEN :startTime AND :endTime")
|
||||
long countCallsInTimeRange(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);
|
||||
|
||||
/**
|
||||
* 统计指定时间范围内成功接通的通话数量
|
||||
*/
|
||||
@Query("SELECT COUNT(c) FROM FreeSwitchCdrEntity c WHERE c.startStamp BETWEEN :startTime AND :endTime AND c.answerStamp IS NOT NULL")
|
||||
long countAnsweredCallsInTimeRange(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);
|
||||
|
||||
/**
|
||||
* 计算指定时间范围内的总通话时长
|
||||
*/
|
||||
@Query("SELECT COALESCE(SUM(c.billsec), 0) FROM FreeSwitchCdrEntity c WHERE c.startStamp BETWEEN :startTime AND :endTime AND c.answerStamp IS NOT NULL")
|
||||
long sumBillSecInTimeRange(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);
|
||||
|
||||
/**
|
||||
* 查找最近的通话记录
|
||||
*/
|
||||
@Query("SELECT c FROM FreeSwitchCdrEntity c ORDER BY c.startStamp DESC")
|
||||
Page<FreeSwitchCdrEntity> findRecentCalls(Pageable pageable);
|
||||
|
||||
/**
|
||||
* 根据主叫号码统计通话次数
|
||||
*/
|
||||
@Query("SELECT COUNT(c) FROM FreeSwitchCdrEntity c WHERE c.callerIdNumber = :callerNumber")
|
||||
long countByCallerNumber(@Param("callerNumber") String callerNumber);
|
||||
|
||||
/**
|
||||
* 根据被叫号码统计通话次数
|
||||
*/
|
||||
@Query("SELECT COUNT(c) FROM FreeSwitchCdrEntity c WHERE c.destinationNumber = :destinationNumber")
|
||||
long countByDestinationNumber(@Param("destinationNumber") String destinationNumber);
|
||||
|
||||
/**
|
||||
* 检查UUID是否存在
|
||||
*/
|
||||
boolean existsByUuid(String uuid);
|
||||
|
||||
/**
|
||||
* 删除指定日期之前的CDR记录
|
||||
*/
|
||||
void deleteByStartStampBefore(LocalDateTime cutoffDate);
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* @Author: jackning 270580156@qq.com
|
||||
* @Date: 2025-06-09 10:00:00
|
||||
* @LastEditors: jackning 270580156@qq.com
|
||||
* @LastEditTime: 2025-06-09 10:00:00
|
||||
* @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
|
||||
*
|
||||
* Copyright (c) 2025 by bytedesk.com, All Rights Reserved.
|
||||
*/
|
||||
package com.bytedesk.freeswitch.repository;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.bytedesk.freeswitch.model.FreeSwitchUserEntity;
|
||||
|
||||
/**
|
||||
* FreeSwitch用户仓库接口
|
||||
*/
|
||||
@Repository
|
||||
public interface FreeSwitchUserRepository extends JpaRepository<FreeSwitchUserEntity, Long>,
|
||||
JpaSpecificationExecutor<FreeSwitchUserEntity> {
|
||||
|
||||
/**
|
||||
* 根据用户名查找用户
|
||||
*/
|
||||
Optional<FreeSwitchUserEntity> findByUsername(String username);
|
||||
|
||||
/**
|
||||
* 根据用户名和域名查找用户
|
||||
*/
|
||||
Optional<FreeSwitchUserEntity> findByUsernameAndDomain(String username, String domain);
|
||||
|
||||
/**
|
||||
* 根据邮箱查找用户
|
||||
*/
|
||||
Optional<FreeSwitchUserEntity> findByEmail(String email);
|
||||
|
||||
/**
|
||||
* 查找启用的用户
|
||||
*/
|
||||
List<FreeSwitchUserEntity> findByEnabledTrue();
|
||||
|
||||
/**
|
||||
* 根据域名查找用户
|
||||
*/
|
||||
List<FreeSwitchUserEntity> findByDomain(String domain);
|
||||
|
||||
/**
|
||||
* 根据账户代码查找用户
|
||||
*/
|
||||
List<FreeSwitchUserEntity> findByAccountcode(String accountcode);
|
||||
|
||||
/**
|
||||
* 检查用户名是否存在
|
||||
*/
|
||||
boolean existsByUsername(String username);
|
||||
|
||||
/**
|
||||
* 检查用户名和域名组合是否存在
|
||||
*/
|
||||
boolean existsByUsernameAndDomain(String username, String domain);
|
||||
|
||||
/**
|
||||
* 查找在线用户(最近5分钟内有注册记录)
|
||||
*/
|
||||
@Query("SELECT u FROM FreeSwitchUserEntity u WHERE u.enabled = true AND u.lastRegister > :cutoffTime")
|
||||
List<FreeSwitchUserEntity> findOnlineUsers(@Param("cutoffTime") LocalDateTime cutoffTime);
|
||||
|
||||
/**
|
||||
* 根据用户名模糊搜索
|
||||
*/
|
||||
Page<FreeSwitchUserEntity> findByUsernameContainingIgnoreCase(String username, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 根据显示名称模糊搜索
|
||||
*/
|
||||
Page<FreeSwitchUserEntity> findByDisplayNameContainingIgnoreCase(String displayName, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 统计启用的用户数量
|
||||
*/
|
||||
long countByEnabledTrue();
|
||||
|
||||
/**
|
||||
* 统计在线用户数量
|
||||
*/
|
||||
@Query("SELECT COUNT(u) FROM FreeSwitchUserEntity u WHERE u.enabled = true AND u.lastRegister > :cutoffTime")
|
||||
long countOnlineUsers(@Param("cutoffTime") LocalDateTime cutoffTime);
|
||||
|
||||
/**
|
||||
* 更新用户最后注册时间和IP
|
||||
*/
|
||||
@Query("UPDATE FreeSwitchUserEntity u SET u.lastRegister = :registerTime, u.registerIp = :registerIp WHERE u.username = :username AND u.domain = :domain")
|
||||
int updateLastRegister(@Param("username") String username,
|
||||
@Param("domain") String domain,
|
||||
@Param("registerTime") LocalDateTime registerTime,
|
||||
@Param("registerIp") String registerIp);
|
||||
}
|
||||
Reference in New Issue
Block a user