update:统一使用PageData返回分页

This commit is contained in:
hrz
2025-04-05 17:16:06 +08:00
parent 671c992f3a
commit e337dd920d
13 changed files with 108 additions and 123 deletions
+14 -4
View File
@@ -21,7 +21,17 @@ conda install conda-forge::ffmpeg
建议:如果 `EdgeTTS` 经常失败,请先检查是否使用了代理(梯子)。如果使用了,请尝试关闭代理后再试; 建议:如果 `EdgeTTS` 经常失败,请先检查是否使用了代理(梯子)。如果使用了,请尝试关闭代理后再试;
如果用的是火山引擎的豆包 TTS,经常失败时建议使用付费版本,因为测试版本仅支持 2 个并发。 如果用的是火山引擎的豆包 TTS,经常失败时建议使用付费版本,因为测试版本仅支持 2 个并发。
### 4、如何提高小智对话响应速度? ⚡ ### 4、使用Wifi能连接自建服务器,但是4G模式却接不上 🔐
原因:虾哥的固件,4G模式需要使用安全连接。
解决方法:目前有两种方法可以解决。任选一种:
1、改代码。参考这个视频解决 https://www.bilibili.com/video/BV18MfTYoE85
2、使用nginx配置ssl证书。参考教程 https://icnt94i5ctj4.feishu.cn/docx/GnYOdMNJOoRCljx1ctecsj9cnRe
### 5、如何提高小智对话响应速度? ⚡
本项目默认配置为低成本方案,建议初学者先使用默认免费模型,解决"跑得动"的问题,再优化"跑得快"。 本项目默认配置为低成本方案,建议初学者先使用默认免费模型,解决"跑得动"的问题,再优化"跑得快"。
如需提升响应速度,可尝试更换各组件。以下为各组件的响应速度测试数据(仅供参考,不构成承诺): 如需提升响应速度,可尝试更换各组件。以下为各组件的响应速度测试数据(仅供参考,不构成承诺):
@@ -78,7 +88,7 @@ TTS 性能排行:
- LLM`AliLLM` - LLM`AliLLM`
- TTS`DoubaoTTS` - TTS`DoubaoTTS`
### 5、我说话很慢,停顿时小智老是抢话 🗣️ ### 6、我说话很慢,停顿时小智老是抢话 🗣️
建议:在配置文件中找到如下部分,将 `min_silence_duration_ms` 的值调大(例如改为 `1000`): 建议:在配置文件中找到如下部分,将 `min_silence_duration_ms` 的值调大(例如改为 `1000`):
@@ -90,7 +100,7 @@ VAD:
min_silence_duration_ms: 700 # 如果说话停顿较长,可将此值调大 min_silence_duration_ms: 700 # 如果说话停顿较长,可将此值调大
``` ```
### 6、我想通过小智控制电灯、空调、远程开关机等操作 💡 ### 7、我想通过小智控制电灯、空调、远程开关机等操作 💡
本项目,支持以工具调用的方式控制HomeAssistant设备 本项目,支持以工具调用的方式控制HomeAssistant设备
@@ -128,7 +138,7 @@ Intent:
- hass_play_music - hass_play_music
``` ```
### 7、更多问题,可联系我们反馈 💬 ### 8、更多问题,可联系我们反馈 💬
我们的联系方式放在[百度网盘中,点击前往](https://pan.baidu.com/s/1x6USjvP1nTRsZ45XlJu65Q),提取码是`223y`。 我们的联系方式放在[百度网盘中,点击前往](https://pan.baidu.com/s/1x6USjvP1nTRsZ45XlJu65Q),提取码是`223y`。
+1 -1
View File
@@ -1,4 +1,4 @@
本文档是开发类文档,如需部署小智服务端,[点击这里查看部署教程](.././FAQ.md#%E4%BD%BF%E7%94%A8%E6%96%B9%E5%BC%8F-) 本文档是开发类文档,如需部署小智服务端,[点击这里查看部署教程](../../../docs/Deployment.md)
# 项目介绍 # 项目介绍
manager-api 该项目基于SpringBoot框架开发。 manager-api 该项目基于SpringBoot框架开发。
@@ -1,38 +0,0 @@
package xiaozhi.common.page;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* 扩展的分页对象
* @author zjy
* @since 2025-4-2
*/
@Data
@Schema(description = "分页数据")
public class ExtendPageData<T> implements Serializable {
@Schema(description = "总记录数")
private int totalCount;
@Schema(description = "页数")
private int totalPage;
@Schema(description = "列表数据")
private List<T> list;
/**
* 分页
*
* @param list 列表数据
* @param total 总记录数
* @param page 页数
*/
public ExtendPageData(List<T> list, long total, long page) {
this.list = list;
this.totalCount = (int) total;
this.totalPage = (int) page;
}
}
@@ -4,19 +4,17 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.transaction.annotation.Transactional;
import xiaozhi.common.page.PageData; import xiaozhi.common.page.PageData;
import xiaozhi.common.service.impl.BaseServiceImpl; import xiaozhi.common.service.impl.BaseServiceImpl;
import xiaozhi.modules.agent.dao.AgentDao; import xiaozhi.modules.agent.dao.AgentDao;
import xiaozhi.modules.agent.entity.AgentEntity; import xiaozhi.modules.agent.entity.AgentEntity;
import xiaozhi.modules.agent.service.AgentService; import xiaozhi.modules.agent.service.AgentService;
import xiaozhi.modules.device.entity.DeviceEntity;
@Service @Service
public class AgentServiceImpl extends BaseServiceImpl<AgentDao, AgentEntity> implements AgentService { public class AgentServiceImpl extends BaseServiceImpl<AgentDao, AgentEntity> implements AgentService {
@@ -2,7 +2,7 @@ package xiaozhi.modules.device.service;
import java.util.List; import java.util.List;
import xiaozhi.common.page.ExtendPageData; import xiaozhi.common.page.PageData;
import xiaozhi.modules.device.dto.DeviceBindDTO; import xiaozhi.modules.device.dto.DeviceBindDTO;
import xiaozhi.modules.device.dto.DevicePageUserDTO; import xiaozhi.modules.device.dto.DevicePageUserDTO;
import xiaozhi.modules.device.dto.DeviceReportReqDTO; import xiaozhi.modules.device.dto.DeviceReportReqDTO;
@@ -45,12 +45,14 @@ public interface DeviceService {
/** /**
* 删除此用户的所有设备 * 删除此用户的所有设备
*
* @param userId 用户id * @param userId 用户id
*/ */
void deleteByUserId(Long userId); void deleteByUserId(Long userId);
/** /**
* 获取指定用户的设备数量 * 获取指定用户的设备数量
*
* @param userId 用户id * @param userId 用户id
* @return 设备数量 * @return 设备数量
*/ */
@@ -62,5 +64,5 @@ public interface DeviceService {
* @param dto 分页查找参数 * @param dto 分页查找参数
* @return 用户列表分页数据 * @return 用户列表分页数据
*/ */
ExtendPageData<UserShowDeviceListVO> page(DevicePageUserDTO dto); PageData<UserShowDeviceListVO> page(DevicePageUserDTO dto);
} }
@@ -8,7 +8,6 @@ import java.util.Map;
import java.util.TimeZone; import java.util.TimeZone;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
@@ -17,11 +16,12 @@ import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.RandomUtil;
import xiaozhi.common.constant.Constant; import xiaozhi.common.constant.Constant;
import xiaozhi.common.exception.RenException; import xiaozhi.common.exception.RenException;
import xiaozhi.common.page.ExtendPageData; import xiaozhi.common.page.PageData;
import xiaozhi.common.service.impl.BaseServiceImpl; import xiaozhi.common.service.impl.BaseServiceImpl;
import xiaozhi.common.user.UserDetail; import xiaozhi.common.user.UserDetail;
import xiaozhi.common.utils.ConvertUtils; import xiaozhi.common.utils.ConvertUtils;
@@ -46,13 +46,12 @@ public class DeviceServiceImpl extends BaseServiceImpl<DeviceDao, DeviceEntity>
private final String frontedUrl; private final String frontedUrl;
private final RedisTemplate<String, Object> redisTemplate; private final RedisTemplate<String, Object> redisTemplate;
// 添加构造函数来初始化 deviceMapper // 添加构造函数来初始化 deviceMapper
public DeviceServiceImpl(DeviceDao deviceDao, SysUserUtilService sysUserUtilService, public DeviceServiceImpl(DeviceDao deviceDao, SysUserUtilService sysUserUtilService,
@Value("${app.fronted-url:http://localhost:8001}") String frontedUrl, @Value("${app.fronted-url:http://localhost:8001}") String frontedUrl,
RedisTemplate<String, Object> redisTemplate) { RedisTemplate<String, Object> redisTemplate) {
this.deviceDao = deviceDao; this.deviceDao = deviceDao;
this.sysUserUtilService = sysUserUtilService; this.sysUserUtilService = sysUserUtilService;
this.frontedUrl = frontedUrl; this.frontedUrl = frontedUrl;
@@ -223,7 +222,7 @@ public class DeviceServiceImpl extends BaseServiceImpl<DeviceDao, DeviceEntity>
} }
@Override @Override
public ExtendPageData<UserShowDeviceListVO> page(DevicePageUserDTO dto) { public PageData<UserShowDeviceListVO> page(DevicePageUserDTO dto) {
Map<String, Object> params = new HashMap<String, Object>(); Map<String, Object> params = new HashMap<String, Object>();
params.put(Constant.PAGE, dto.getPage()); params.put(Constant.PAGE, dto.getPage());
params.put(Constant.LIMIT, dto.getLimit()); params.put(Constant.LIMIT, dto.getLimit());
@@ -243,9 +242,8 @@ public class DeviceServiceImpl extends BaseServiceImpl<DeviceDao, DeviceEntity>
vo.setDeviceType(device.getBoard()); vo.setDeviceType(device.getBoard());
return vo; return vo;
}).toList(); }).toList();
//计算页数 // 计算页数
long num = page.getTotal() / Long.parseLong(dto.getPage()); return new PageData<>(list, page.getTotal());
return new ExtendPageData<>(list, page.getTotal(), num);
} }
private DeviceReportRespDTO.ServerTime buildServerTime() { private DeviceReportRespDTO.ServerTime buildServerTime() {
@@ -5,8 +5,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@@ -37,8 +35,6 @@ public class ModelConfigServiceImpl extends BaseServiceImpl<ModelConfigDao, Mode
private final ModelProviderService modelProviderService; private final ModelProviderService modelProviderService;
private final TimbreService timbreService; private final TimbreService timbreService;
private static final Logger logger = LoggerFactory.getLogger(ModelConfigServiceImpl.class);
@Override @Override
public List<String> getModelCodeList(String modelType, String modelName) { public List<String> getModelCodeList(String modelType, String modelName) {
return modelConfigDao.getModelCodeList(modelType, modelName); return modelConfigDao.getModelCodeList(modelType, modelName);
@@ -17,7 +17,6 @@ import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import xiaozhi.common.constant.Constant; import xiaozhi.common.constant.Constant;
import xiaozhi.common.page.ExtendPageData;
import xiaozhi.common.page.PageData; import xiaozhi.common.page.PageData;
import xiaozhi.common.utils.Result; import xiaozhi.common.utils.Result;
import xiaozhi.common.validator.ValidatorUtils; import xiaozhi.common.validator.ValidatorUtils;
@@ -51,7 +50,7 @@ public class AdminController {
@Parameter(name = Constant.PAGE, description = "当前页码,从1开始", required = true), @Parameter(name = Constant.PAGE, description = "当前页码,从1开始", required = true),
@Parameter(name = Constant.LIMIT, description = "每页显示记录数", required = true), @Parameter(name = Constant.LIMIT, description = "每页显示记录数", required = true),
}) })
public Result<ExtendPageData<AdminPageUserVO>> pageUser( public Result<PageData<AdminPageUserVO>> pageUser(
@Parameter(hidden = true) @RequestParam Map<String, Object> params) { @Parameter(hidden = true) @RequestParam Map<String, Object> params) {
AdminPageUserDTO dto = new AdminPageUserDTO(); AdminPageUserDTO dto = new AdminPageUserDTO();
dto.setMobile((String) params.get("mobile")); dto.setMobile((String) params.get("mobile"));
@@ -59,8 +58,8 @@ public class AdminController {
dto.setPage((String) params.get(Constant.PAGE)); dto.setPage((String) params.get(Constant.PAGE));
ValidatorUtils.validateEntity(dto); ValidatorUtils.validateEntity(dto);
ValidatorUtils.validateEntity(dto); ValidatorUtils.validateEntity(dto);
ExtendPageData<AdminPageUserVO> page = sysUserService.page(dto); PageData<AdminPageUserVO> page = sysUserService.page(dto);
return new Result<ExtendPageData<AdminPageUserVO>>().ok(page); return new Result<PageData<AdminPageUserVO>>().ok(page);
} }
@PutMapping("/users/{id}") @PutMapping("/users/{id}")
@@ -88,14 +87,14 @@ public class AdminController {
@Parameter(name = Constant.PAGE, description = "当前页码,从1开始", required = true), @Parameter(name = Constant.PAGE, description = "当前页码,从1开始", required = true),
@Parameter(name = Constant.LIMIT, description = "每页显示记录数", required = true), @Parameter(name = Constant.LIMIT, description = "每页显示记录数", required = true),
}) })
public Result<ExtendPageData<UserShowDeviceListVO>> pageDevice( public Result<PageData<UserShowDeviceListVO>> pageDevice(
@Parameter(hidden = true) @RequestParam Map<String, Object> params) { @Parameter(hidden = true) @RequestParam Map<String, Object> params) {
DevicePageUserDTO dto = new DevicePageUserDTO(); DevicePageUserDTO dto = new DevicePageUserDTO();
dto.setKeywords((String) params.get("keywords")); dto.setKeywords((String) params.get("keywords"));
dto.setLimit((String) params.get(Constant.LIMIT)); dto.setLimit((String) params.get(Constant.LIMIT));
dto.setPage((String) params.get(Constant.PAGE)); dto.setPage((String) params.get(Constant.PAGE));
ValidatorUtils.validateEntity(dto); ValidatorUtils.validateEntity(dto);
ExtendPageData<UserShowDeviceListVO> page = deviceService.page(dto); PageData<UserShowDeviceListVO> page = deviceService.page(dto);
return new Result<ExtendPageData<UserShowDeviceListVO>>().ok(page); return new Result<PageData<UserShowDeviceListVO>>().ok(page);
} }
} }
@@ -1,6 +1,6 @@
package xiaozhi.modules.sys.service; package xiaozhi.modules.sys.service;
import xiaozhi.common.page.ExtendPageData; import xiaozhi.common.page.PageData;
import xiaozhi.common.service.BaseService; import xiaozhi.common.service.BaseService;
import xiaozhi.modules.sys.dto.AdminPageUserDTO; import xiaozhi.modules.sys.dto.AdminPageUserDTO;
import xiaozhi.modules.sys.dto.PasswordDTO; import xiaozhi.modules.sys.dto.PasswordDTO;
@@ -21,6 +21,7 @@ public interface SysUserService extends BaseService<SysUserEntity> {
/** /**
* 删除指定用户,且有关联的数据设备和智能体 * 删除指定用户,且有关联的数据设备和智能体
*
* @param ids * @param ids
*/ */
void deleteById(Long ids); void deleteById(Long ids);
@@ -55,5 +56,5 @@ public interface SysUserService extends BaseService<SysUserEntity> {
* @param dto 分页查找参数 * @param dto 分页查找参数
* @return 用户列表分页数据 * @return 用户列表分页数据
*/ */
ExtendPageData<AdminPageUserVO> page(AdminPageUserDTO dto); PageData<AdminPageUserVO> page(AdminPageUserDTO dto);
} }
@@ -18,7 +18,7 @@ import lombok.AllArgsConstructor;
import xiaozhi.common.constant.Constant; import xiaozhi.common.constant.Constant;
import xiaozhi.common.exception.ErrorCode; import xiaozhi.common.exception.ErrorCode;
import xiaozhi.common.exception.RenException; import xiaozhi.common.exception.RenException;
import xiaozhi.common.page.ExtendPageData; import xiaozhi.common.page.PageData;
import xiaozhi.common.service.impl.BaseServiceImpl; import xiaozhi.common.service.impl.BaseServiceImpl;
import xiaozhi.common.utils.ConvertUtils; import xiaozhi.common.utils.ConvertUtils;
import xiaozhi.modules.agent.service.AgentService; import xiaozhi.modules.agent.service.AgentService;
@@ -99,7 +99,6 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserDao, SysUserEntit
deviceService.deleteByUserId(id); deviceService.deleteByUserId(id);
// 删除智能体 // 删除智能体
agentService.deleteById(id); agentService.deleteById(id);
// TODO 除了要删除用户还要删除用户关联的对话
} }
@Override @Override
@@ -151,16 +150,14 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserDao, SysUserEntit
} }
@Override @Override
public ExtendPageData<AdminPageUserVO> page(AdminPageUserDTO dto) { public PageData<AdminPageUserVO> page(AdminPageUserDTO dto) {
Map<String, Object> params = new HashMap<String, Object>(); Map<String, Object> params = new HashMap<String, Object>();
params.put(Constant.PAGE, dto.getPage()); params.put(Constant.PAGE, dto.getPage());
params.put(Constant.LIMIT, dto.getLimit()); params.put(Constant.LIMIT, dto.getLimit());
IPage<SysUserEntity> page = baseDao.selectPage( IPage<SysUserEntity> page = baseDao.selectPage(
getPage(params, "id", true), getPage(params, "id", true),
// 定义查询条件 new QueryWrapper<SysUserEntity>().eq(StringUtils.isNotBlank(dto.getMobile()), "username",
new QueryWrapper<SysUserEntity>() dto.getMobile()));
// 必须按照手机号码查找
.eq(StringUtils.isNotBlank(dto.getMobile()), "username", dto.getMobile()));
// 循环处理page获取回来的数据,返回需要的字段 // 循环处理page获取回来的数据,返回需要的字段
List<AdminPageUserVO> list = page.getRecords().stream().map(user -> { List<AdminPageUserVO> list = page.getRecords().stream().map(user -> {
AdminPageUserVO adminPageUserVO = new AdminPageUserVO(); AdminPageUserVO adminPageUserVO = new AdminPageUserVO();
@@ -168,12 +165,10 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserDao, SysUserEntit
adminPageUserVO.setMobile(user.getUsername()); adminPageUserVO.setMobile(user.getUsername());
String deviceCount = deviceService.selectCountByUserId(user.getId()).toString(); String deviceCount = deviceService.selectCountByUserId(user.getId()).toString();
adminPageUserVO.setDeviceCount(deviceCount); adminPageUserVO.setDeviceCount(deviceCount);
adminPageUserVO.setStatus(user.getStatus().toString()); adminPageUserVO.setStatus(user.getStatus());
return adminPageUserVO; return adminPageUserVO;
}).toList(); }).toList();
//计算页数 return new PageData<>(list, page.getTotal());
long num = page.getTotal() / Long.parseLong(dto.getPage());
return new ExtendPageData<>(list, page.getTotal(),num);
} }
private boolean isStrongPassword(String password) { private boolean isStrongPassword(String password) {
@@ -23,7 +23,4 @@ public class AdminPageUserVO {
@Schema(description = "用户id") @Schema(description = "用户id")
private String userid; private String userid;
@Schema(description = "用户状态")
private String status;
} }
+1 -1
View File
@@ -1,4 +1,4 @@
本文档是开发类文档,如需部署小智服务端,[点击这里查看部署教程](.././FAQ.md#%E4%BD%BF%E7%94%A8%E6%96%B9%E5%BC%8F-) 本文档是开发类文档,如需部署小智服务端,[点击这里查看部署教程](../../../docs/Deployment.md)
# xiaozhi # xiaozhi
+64 -37
View File
@@ -10,7 +10,10 @@ import requests
def get_project_dir(): def get_project_dir():
"""获取项目根目录""" """获取项目根目录"""
return os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + '/' return (
os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+ "/"
)
def get_local_ip(): def get_local_ip():
@@ -24,6 +27,7 @@ def get_local_ip():
except Exception as e: except Exception as e:
return "127.0.0.1" return "127.0.0.1"
def is_private_ip(ip_addr): def is_private_ip(ip_addr):
""" """
Check if an IP address is a private IP address (compatible with IPv4 and IPv6). Check if an IP address is a private IP address (compatible with IPv4 and IPv6).
@@ -33,48 +37,48 @@ def is_private_ip(ip_addr):
""" """
try: try:
# Validate IPv4 or IPv6 address format # Validate IPv4 or IPv6 address format
if not re.match(r"^(\d{1,3}\.){3}\d{1,3}$|^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$", ip_addr): if not re.match(
r"^(\d{1,3}\.){3}\d{1,3}$|^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$", ip_addr
):
return False # Invalid IP address format return False # Invalid IP address format
# IPv4 private address ranges # IPv4 private address ranges
if '.' in ip_addr: # IPv4 address if "." in ip_addr: # IPv4 address
ip_parts = list(map(int, ip_addr.split('.'))) ip_parts = list(map(int, ip_addr.split(".")))
if ip_parts[0] == 10: if ip_parts[0] == 10:
return True # 10.0.0.0/8 range return True # 10.0.0.0/8 range
elif ip_parts[0] == 172 and 16 <= ip_parts[1] <= 31: elif ip_parts[0] == 172 and 16 <= ip_parts[1] <= 31:
return True # 172.16.0.0/12 range return True # 172.16.0.0/12 range
elif ip_parts[0] == 192 and ip_parts[1] == 168: elif ip_parts[0] == 192 and ip_parts[1] == 168:
return True # 192.168.0.0/16 range return True # 192.168.0.0/16 range
elif ip_addr == '127.0.0.1': elif ip_addr == "127.0.0.1":
return True # Loopback address return True # Loopback address
elif ip_parts[0] == 169 and ip_parts[1] == 254: elif ip_parts[0] == 169 and ip_parts[1] == 254:
return True # Link-local address 169.254.0.0/16 return True # Link-local address 169.254.0.0/16
else: else:
return False # Not a private IPv4 address return False # Not a private IPv4 address
else: # IPv6 address else: # IPv6 address
ip_addr = ip_addr.lower() ip_addr = ip_addr.lower()
if ip_addr.startswith('fc00:') or ip_addr.startswith('fd00:'): if ip_addr.startswith("fc00:") or ip_addr.startswith("fd00:"):
return True # Unique Local Addresses (FC00::/7) return True # Unique Local Addresses (FC00::/7)
elif ip_addr == '::1': elif ip_addr == "::1":
return True # Loopback address return True # Loopback address
elif ip_addr.startswith('fe80:'): elif ip_addr.startswith("fe80:"):
return True # Link-local unicast addresses (FE80::/10) return True # Link-local unicast addresses (FE80::/10)
else: else:
return False # Not a private IPv6 address return False # Not a private IPv6 address
except (ValueError, IndexError): except (ValueError, IndexError):
return False # IP address format error or insufficient segments return False # IP address format error or insufficient segments
def get_ip_info(ip_addr): def get_ip_info(ip_addr):
try: try:
if is_private_ip(ip_addr):
ip_addr = ""
url = f"https://whois.pconline.com.cn/ipJson.jsp?json=true&ip={ip_addr}" url = f"https://whois.pconline.com.cn/ipJson.jsp?json=true&ip={ip_addr}"
resp = requests.get(url).json() resp = requests.get(url).json()
ip_info = {"city": resp.get("city")}
ip_info = {
"city": resp.get("city"),
"region": resp.get("region"),
"addr": resp.get("addr")
}
return ip_info return ip_info
except Exception as e: except Exception as e:
logging.error(f"Error getting client ip info: {e}") logging.error(f"Error getting client ip info: {e}")
@@ -89,7 +93,7 @@ def read_config(config_path):
def write_json_file(file_path, data): def write_json_file(file_path, data):
"""将数据写入 JSON 文件""" """将数据写入 JSON 文件"""
with open(file_path, 'w', encoding='utf-8') as file: with open(file_path, "w", encoding="utf-8") as file:
json.dump(data, file, ensure_ascii=False, indent=4) json.dump(data, file, ensure_ascii=False, indent=4)
@@ -97,21 +101,28 @@ def is_punctuation_or_emoji(char):
"""检查字符是否为空格、指定标点或表情符号""" """检查字符是否为空格、指定标点或表情符号"""
# 定义需要去除的中英文标点(包括全角/半角) # 定义需要去除的中英文标点(包括全角/半角)
punctuation_set = { punctuation_set = {
'', ',', # 中文逗号 + 英文逗号 "",
'', '.', # 中文号 + 英文 ",", # 中文号 + 英文
'', '!', # 中文感叹号 + 英文感叹号 "",
'-', '', # 英文连字符 + 中文全角横线 ".", # 中文句号 + 英文句号
'' # 中文顿号 "",
"!", # 中文感叹号 + 英文感叹号
"-",
"", # 英文连字符 + 中文全角横线
"", # 中文顿号
} }
if char.isspace() or char in punctuation_set: if char.isspace() or char in punctuation_set:
return True return True
# 检查表情符号(保留原有逻辑) # 检查表情符号(保留原有逻辑)
code_point = ord(char) code_point = ord(char)
emoji_ranges = [ emoji_ranges = [
(0x1F600, 0x1F64F), (0x1F300, 0x1F5FF), (0x1F600, 0x1F64F),
(0x1F680, 0x1F6FF), (0x1F900, 0x1F9FF), (0x1F300, 0x1F5FF),
(0x1FA70, 0x1FAFF), (0x2600, 0x26FF), (0x1F680, 0x1F6FF),
(0x2700, 0x27BF) (0x1F900, 0x1F9FF),
(0x1FA70, 0x1FAFF),
(0x2600, 0x26FF),
(0x2700, 0x27BF),
] ]
return any(start <= code_point <= end for start, end in emoji_ranges) return any(start <= code_point <= end for start, end in emoji_ranges)
@@ -127,27 +138,42 @@ def get_string_no_punctuation_or_emoji(s):
end = len(chars) - 1 end = len(chars) - 1
while end >= start and is_punctuation_or_emoji(chars[end]): while end >= start and is_punctuation_or_emoji(chars[end]):
end -= 1 end -= 1
return ''.join(chars[start:end + 1]) return "".join(chars[start : end + 1])
def remove_punctuation_and_length(text): def remove_punctuation_and_length(text):
# 全角符号和半角符号的Unicode范围 # 全角符号和半角符号的Unicode范围
full_width_punctuations = '!"#$%&'()*+,-。/:;<=>?@[\]^_`{|}~' full_width_punctuations = (
"!"#$%&'()*+,-。/:;<=>?@[\]^_`{|}~"
)
half_width_punctuations = r'!"#$%&\'()*+,-./:;<=>?@[\]^_`{|}~' half_width_punctuations = r'!"#$%&\'()*+,-./:;<=>?@[\]^_`{|}~'
space = ' ' # 半角空格 space = " " # 半角空格
full_width_space = ' ' # 全角空格 full_width_space = " " # 全角空格
# 去除全角和半角符号以及空格 # 去除全角和半角符号以及空格
result = ''.join([char for char in text if result = "".join(
char not in full_width_punctuations and char not in half_width_punctuations and char not in space and char not in full_width_space]) [
char
for char in text
if char not in full_width_punctuations
and char not in half_width_punctuations
and char not in space
and char not in full_width_space
]
)
if result == "Yeah": if result == "Yeah":
return 0, "" return 0, ""
return len(result), result return len(result), result
def check_model_key(modelType, modelKey): def check_model_key(modelType, modelKey):
if "" in modelKey: if "" in modelKey:
logging.error("你还没配置" + modelType + "的密钥,请在配置文件中配置密钥,否则无法正常工作") logging.error(
"你还没配置"
+ modelType
+ "的密钥,请在配置文件中配置密钥,否则无法正常工作"
)
return False return False
return True return True
@@ -157,15 +183,15 @@ def check_ffmpeg_installed():
try: try:
# 执行ffmpeg -version命令,并捕获输出 # 执行ffmpeg -version命令,并捕获输出
result = subprocess.run( result = subprocess.run(
['ffmpeg', '-version'], ["ffmpeg", "-version"],
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, stderr=subprocess.PIPE,
text=True, text=True,
check=True # 如果返回码非零则抛出异常 check=True, # 如果返回码非零则抛出异常
) )
# 检查输出中是否包含版本信息(可选) # 检查输出中是否包含版本信息(可选)
output = result.stdout + result.stderr output = result.stdout + result.stderr
if 'ffmpeg version' in output.lower(): if "ffmpeg version" in output.lower():
ffmpeg_installed = True ffmpeg_installed = True
return False return False
except (subprocess.CalledProcessError, FileNotFoundError): except (subprocess.CalledProcessError, FileNotFoundError):
@@ -178,9 +204,10 @@ def check_ffmpeg_installed():
error_msg += "2、查阅安装文档,如何在conda环境中安装ffmpeg\n" error_msg += "2、查阅安装文档,如何在conda环境中安装ffmpeg\n"
raise ValueError(error_msg) raise ValueError(error_msg)
def extract_json_from_string(input_string): def extract_json_from_string(input_string):
"""提取字符串中的 JSON 部分""" """提取字符串中的 JSON 部分"""
pattern = r'(\{.*\})' pattern = r"(\{.*\})"
match = re.search(pattern, input_string) match = re.search(pattern, input_string)
if match: if match:
return match.group(1) # 返回提取的 JSON 字符串 return match.group(1) # 返回提取的 JSON 字符串