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
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 }
|