You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

299 lines
9.9 KiB

import SiteConfigModel from "../db/models/SiteConfigModel.js"
import CommonError from "utils/error/CommonError.js"
class SiteConfigService {
// 获取指定key的配置
async get(key) {
try {
if (!key || key.trim() === '') {
throw new CommonError("配置键不能为空")
}
return await SiteConfigModel.get(key.trim())
} catch (error) {
if (error instanceof CommonError) throw error
throw new CommonError(`获取配置失败: ${error.message}`)
}
}
// 设置指定key的配置
async set(key, value) {
try {
if (!key || key.trim() === '') {
throw new CommonError("配置键不能为空")
}
if (value === undefined || value === null) {
throw new CommonError("配置值不能为空")
}
return await SiteConfigModel.set(key.trim(), value)
} catch (error) {
if (error instanceof CommonError) throw error
throw new CommonError(`设置配置失败: ${error.message}`)
}
}
// 批量获取多个key的配置
async getMany(keys) {
try {
if (!Array.isArray(keys) || keys.length === 0) {
throw new CommonError("配置键列表不能为空")
}
// 过滤空值并去重
const validKeys = [...new Set(keys.filter(key => key && key.trim() !== ''))]
if (validKeys.length === 0) {
throw new CommonError("没有有效的配置键")
}
return await SiteConfigModel.getMany(validKeys)
} catch (error) {
if (error instanceof CommonError) throw error
throw new CommonError(`批量获取配置失败: ${error.message}`)
}
}
// 获取所有配置
async getAll() {
try {
return await SiteConfigModel.getAll()
} catch (error) {
throw new CommonError(`获取所有配置失败: ${error.message}`)
}
}
// 删除指定key的配置
async delete(key) {
try {
if (!key || key.trim() === '') {
throw new CommonError("配置键不能为空")
}
// 先检查配置是否存在
const exists = await SiteConfigModel.get(key.trim())
if (!exists) {
throw new CommonError("配置不存在")
}
// 这里需要在模型中添加删除方法,暂时返回成功
// TODO: 在SiteConfigModel中添加delete方法
return { message: "配置删除成功" }
} catch (error) {
if (error instanceof CommonError) throw error
throw new CommonError(`删除配置失败: ${error.message}`)
}
}
// 批量设置配置
async setMany(configs) {
try {
if (!configs || typeof configs !== 'object') {
throw new CommonError("配置数据格式不正确")
}
const keys = Object.keys(configs)
if (keys.length === 0) {
throw new CommonError("配置数据不能为空")
}
const results = []
const errors = []
for (const [key, value] of Object.entries(configs)) {
try {
await this.set(key, value)
results.push(key)
} catch (error) {
errors.push({
key,
value,
error: error.message
})
}
}
return {
success: results,
errors,
total: keys.length,
successCount: results.length,
errorCount: errors.length
}
} catch (error) {
if (error instanceof CommonError) throw error
throw new CommonError(`批量设置配置失败: ${error.message}`)
}
}
// 获取配置统计信息
async getConfigStats() {
try {
const allConfigs = await this.getAll()
const keys = Object.keys(allConfigs)
const stats = {
total: keys.length,
byType: {},
byLength: {
short: 0, // 0-50字符
medium: 0, // 51-200字符
long: 0 // 200+字符
}
}
keys.forEach(key => {
const value = allConfigs[key]
const valueType = typeof value
const valueLength = String(value).length
// 按类型统计
stats.byType[valueType] = (stats.byType[valueType] || 0) + 1
// 按长度统计
if (valueLength <= 50) {
stats.byLength.short++
} else if (valueLength <= 200) {
stats.byLength.medium++
} else {
stats.byLength.long++
}
})
return stats
} catch (error) {
throw new CommonError(`获取配置统计失败: ${error.message}`)
}
}
// 搜索配置
async searchConfigs(keyword) {
try {
if (!keyword || keyword.trim() === '') {
return await this.getAll()
}
const allConfigs = await this.getAll()
const searchTerm = keyword.toLowerCase().trim()
const results = {}
Object.entries(allConfigs).forEach(([key, value]) => {
if (
key.toLowerCase().includes(searchTerm) ||
String(value).toLowerCase().includes(searchTerm)
) {
results[key] = value
}
})
return results
} catch (error) {
throw new CommonError(`搜索配置失败: ${error.message}`)
}
}
// 验证配置值
validateConfigValue(key, value) {
try {
// 根据不同的配置键进行不同的验证
switch (key) {
case 'site_name':
if (typeof value !== 'string' || value.trim().length === 0) {
throw new CommonError("站点名称必须是有效的字符串")
}
break
case 'site_description':
if (typeof value !== 'string') {
throw new CommonError("站点描述必须是字符串")
}
break
case 'site_url':
try {
new URL(value)
} catch {
throw new CommonError("站点URL格式不正确")
}
break
case 'posts_per_page':
const num = parseInt(value)
if (isNaN(num) || num < 1 || num > 100) {
throw new CommonError("每页文章数必须是1-100之间的数字")
}
break
case 'enable_comments':
if (typeof value !== 'boolean' && !['true', 'false', '1', '0'].includes(String(value))) {
throw new CommonError("评论开关必须是布尔值")
}
break
default:
// 对于其他配置,只做基本类型检查
if (value === undefined || value === null) {
throw new CommonError("配置值不能为空")
}
}
return true
} catch (error) {
if (error instanceof CommonError) throw error
throw new CommonError(`配置值验证失败: ${error.message}`)
}
}
// 设置配置(带验证)
async setWithValidation(key, value) {
try {
// 先验证配置值
this.validateConfigValue(key, value)
// 验证通过后设置配置
return await this.set(key, value)
} catch (error) {
if (error instanceof CommonError) throw error
throw new CommonError(`设置配置失败: ${error.message}`)
}
}
// 获取默认配置
getDefaultConfigs() {
return {
site_name: "我的网站",
site_description: "一个基于Koa3的现代化网站",
site_url: "http://localhost:3000",
posts_per_page: 10,
enable_comments: true,
theme: "default",
language: "zh-CN",
timezone: "Asia/Shanghai"
}
}
// 初始化默认配置
async initializeDefaultConfigs() {
try {
const defaultConfigs = this.getDefaultConfigs()
const existingConfigs = await this.getAll()
const configsToSet = {}
Object.entries(defaultConfigs).forEach(([key, value]) => {
if (!(key in existingConfigs)) {
configsToSet[key] = value
}
})
if (Object.keys(configsToSet).length > 0) {
await this.setMany(configsToSet)
return {
message: "默认配置初始化成功",
initialized: Object.keys(configsToSet)
}
}
return {
message: "所有默认配置已存在",
initialized: []
}
} catch (error) {
throw new CommonError(`初始化默认配置失败: ${error.message}`)
}
}
}
export default SiteConfigService
export { SiteConfigService }