Add system settings management api

This commit is contained in:
2023-12-04 17:13:20 +08:00
parent 5c8775bf12
commit 902fcef9b2
18 changed files with 229 additions and 149 deletions

View File

@@ -1,32 +0,0 @@
package top.fatweb.api.controller.system
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.tags.Tag
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import top.fatweb.api.entity.common.ResponseResult
import top.fatweb.api.param.system.SettingParam
import top.fatweb.api.service.system.ISysSettingService
import top.fatweb.api.vo.system.SettingVo
/**
* System setting controller
*
* @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0
*/
@Tag(name = "系统设置", description = "系统设置相关接口")
@RequestMapping("/system/setting")
@RestController
class SettingController(
private val sysSettingService: ISysSettingService
) {
@Operation(summary = "获取")
fun get(): ResponseResult<SettingVo> = ResponseResult.success(data = sysSettingService.get())
@Operation(summary = "更新")
fun update(settingParam: SettingParam): ResponseResult<Nothing> {
sysSettingService.update(settingParam)
return ResponseResult.success()
}
}

View File

@@ -0,0 +1,33 @@
package top.fatweb.api.controller.system
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.tags.Tag
import org.springframework.web.bind.annotation.*
import top.fatweb.api.entity.common.ResponseResult
import top.fatweb.api.param.system.MailSettingsParam
import top.fatweb.api.service.system.ISettingsService
import top.fatweb.api.vo.system.SettingsVo
/**
* System settings controller
*
* @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0
*/
@Tag(name = "系统设置", description = "系统设置相关接口")
@RequestMapping("/system/settings")
@RestController
class SettingsController(
private val settingsService: ISettingsService
) {
@Operation(summary = "获取全部设置")
@GetMapping
fun get(): ResponseResult<SettingsVo> = ResponseResult.success(data = settingsService.get())
@Operation(summary = "更新邮件设置")
@PutMapping("/mail")
fun updateMail(@RequestBody mailSettingsParam: MailSettingsParam): ResponseResult<Nothing> {
settingsService.updateMail(mailSettingsParam)
return ResponseResult.success()
}
}

View File

@@ -1,32 +0,0 @@
package top.fatweb.api.converter.system
import top.fatweb.api.param.system.SettingParam
import top.fatweb.api.setting.MailSetting
import top.fatweb.api.setting.SystemSetting
import top.fatweb.api.vo.system.SettingVo
object SettingConverter {
fun mailSettingToMailSettingVo(mailSetting: MailSetting) = SettingVo.MailSettingVo(
host = mailSetting.host,
port = mailSetting.port,
username = mailSetting.username,
password = mailSetting.password,
from = mailSetting.from
)
fun systemSettingToSettingVo(sysSetting: SystemSetting) = SettingVo(
mail = sysSetting.mail?.let { mailSettingToMailSettingVo(it) }
)
fun mailSettingParamToMailSetting(mailSettingParam: SettingParam.MailSettingParam) = MailSetting(
host = mailSettingParam.host,
port = mailSettingParam.port,
username = mailSettingParam.username,
password = mailSettingParam.password,
from = mailSettingParam.from
)
fun settingParamToSystemSetting(settingParam: SettingParam) = SystemSetting(
mail = settingParam.mail?.let { mailSettingParamToMailSetting(it) }
)
}

View File

@@ -0,0 +1,19 @@
package top.fatweb.api.converter.system
import top.fatweb.api.settings.MailSettings
import top.fatweb.api.settings.SystemSettings
import top.fatweb.api.vo.system.SettingsVo
object SettingsConverter {
private fun mailSettingsToMailSettingsVo(mailSettings: MailSettings) = SettingsVo.MailSettingsVo(
host = mailSettings.host,
port = mailSettings.port,
username = mailSettings.username,
password = mailSettings.password,
from = mailSettings.from
)
fun systemSettingsToSettingsVo(systemSettings: SystemSettings) = SettingsVo(
mail = systemSettings.mail?.let { mailSettingsToMailSettingsVo(it) }
)
}

View File

@@ -0,0 +1,9 @@
package top.fatweb.api.param.system
data class MailSettingsParam (
val host: String?,
val port: Int?,
val username: String?,
val password: String?,
val from: String?
)

View File

@@ -1,13 +0,0 @@
package top.fatweb.api.param.system
data class SettingParam (
val mail: MailSettingParam?
) {
data class MailSettingParam (
val host: String,
val port: Int,
val username: String,
val password: String,
val from: String
)
}

View File

@@ -0,0 +1,10 @@
package top.fatweb.api.service.system
import top.fatweb.api.param.system.MailSettingsParam
import top.fatweb.api.vo.system.SettingsVo
interface ISettingsService {
fun get(): SettingsVo
fun updateMail(mailSettingsParam: MailSettingsParam)
}

View File

@@ -1,10 +0,0 @@
package top.fatweb.api.service.system
import top.fatweb.api.param.system.SettingParam
import top.fatweb.api.vo.system.SettingVo
interface ISysSettingService {
fun get(): SettingVo
fun update(settingParam: SettingParam)
}

View File

@@ -0,0 +1,24 @@
package top.fatweb.api.service.system.impl
import org.springframework.stereotype.Service
import top.fatweb.api.converter.system.SettingsConverter
import top.fatweb.api.param.system.MailSettingsParam
import top.fatweb.api.service.system.ISettingsService
import top.fatweb.api.settings.MailSettings
import top.fatweb.api.settings.SettingsOperator
import top.fatweb.api.vo.system.SettingsVo
@Service
class SettingsServiceImpl : ISettingsService {
override fun get(): SettingsVo = SettingsConverter.systemSettingsToSettingsVo(SettingsOperator.settings())
override fun updateMail(mailSettingsParam: MailSettingsParam) {
mailSettingsParam.apply {
SettingsOperator.setMailValue(MailSettings::host, host)
SettingsOperator.setMailValue(MailSettings::port, port)
SettingsOperator.setMailValue(MailSettings::username, username)
SettingsOperator.setMailValue(MailSettings::password, password)
SettingsOperator.setMailValue(MailSettings::from, from)
}
}
}

View File

@@ -1,17 +0,0 @@
package top.fatweb.api.service.system.impl
import org.springframework.stereotype.Service
import top.fatweb.api.param.system.SettingParam
import top.fatweb.api.service.system.ISysSettingService
import top.fatweb.api.vo.system.SettingVo
@Service
class SysSettingServiceImpl : ISysSettingService {
override fun get(): SettingVo {
TODO("Not yet implemented")
}
override fun update(settingParam: SettingParam) {
TODO("Not yet implemented")
}
}

View File

@@ -1,31 +0,0 @@
package top.fatweb.api.setting
import com.fasterxml.jackson.dataformat.yaml.YAMLMapper
import com.fasterxml.jackson.module.kotlin.readValue
import java.io.File
import java.io.IOException
object SettingOperator {
const val SETTING_FILE_NAME = "data/config/setting.yaml"
private val yamlMapper = YAMLMapper()
var systemSetting: SystemSetting? = null
fun init() {
}
fun getFromSettingFile(): SystemSetting {
val settingFile = File(SETTING_FILE_NAME)
if (!settingFile.isFile) {
if (!settingFile.parentFile.isDirectory) {
if (!settingFile.parentFile.mkdirs()) {
throw IOException("Can not make directory: ${settingFile.parentFile.absolutePath}")
}
}
settingFile.delete()
settingFile.createNewFile()
}
return yamlMapper.readValue<SystemSetting>(settingFile)
}
}

View File

@@ -1,5 +0,0 @@
package top.fatweb.api.setting
data class SystemSetting(
var mail: MailSetting? = null
)

View File

@@ -1,6 +1,9 @@
package top.fatweb.api.setting
package top.fatweb.api.settings
data class MailSetting(
import com.fasterxml.jackson.annotation.JsonInclude
@JsonInclude(JsonInclude.Include.NON_EMPTY)
data class MailSettings(
var host: String? = null,
var port: Int? = null,
var username: String? = null,

View File

@@ -0,0 +1,90 @@
package top.fatweb.api.settings
import com.fasterxml.jackson.databind.exc.MismatchedInputException
import com.fasterxml.jackson.dataformat.yaml.YAMLMapper
import com.fasterxml.jackson.module.kotlin.readValue
import top.fatweb.api.util.StrUtil
import java.io.File
import java.io.IOException
import kotlin.reflect.KMutableProperty1
object SettingsOperator {
private const val SETTINGS_FILE_NAME = "data/config/settings.yaml"
private val yamlMapper = YAMLMapper()
private val settingFile = File(SETTINGS_FILE_NAME)
private lateinit var systemSettings: SystemSettings
init {
getFromSettingsFile()
}
@Throws(IOException::class, MismatchedInputException::class)
private fun getFromSettingsFile() {
if (settingFile.isDirectory) {
throw IOException("'${settingFile.absoluteFile}' is a directory, cannot create settings file")
}
if (!settingFile.isFile) {
if (settingFile.parentFile.isFile) {
throw IOException("'${settingFile.parentFile.absoluteFile}' is a file, cannot create settings file")
}
if (!settingFile.parentFile.isDirectory) {
if (!settingFile.parentFile.mkdirs()) {
throw IOException("Cannot make directory: ${settingFile.parentFile.absolutePath}")
}
}
settingFile.delete()
settingFile.createNewFile()
}
if (settingFile.length() == 0L) {
systemSettings = SystemSettings()
saveSettingsToFile()
}
systemSettings = yamlMapper.readValue(settingFile)
}
private fun saveSettingsToFile() {
yamlMapper.writeValue(settingFile, systemSettings)
}
fun <V> setMailValue(field: KMutableProperty1<MailSettings, V?>, value: V?) {
systemSettings.mail?.let {
if (field == MailSettings::password) {
getMailValue(MailSettings::password)?.let { password ->
if (StrUtil.md5(password) == value) {
return
}
}
}
field.set(it, value)
} ?: {
MailSettings().also {
field.set(it, value)
systemSettings.mail = it
}
}
saveSettingsToFile()
}
fun <V> getMailValue(field: KMutableProperty1<MailSettings, V?>): V? = systemSettings.mail?.let(field)
fun settings() = systemSettings.copy(
mail = systemSettings.mail?.copy()
).apply {
mail?.apply {
password = password?.let {
StrUtil.md5(it)
}
}
}
fun overwrite(systemSettings: SystemSettings) {
this.systemSettings = systemSettings
saveSettingsToFile()
}
}

View File

@@ -0,0 +1,8 @@
package top.fatweb.api.settings
import com.fasterxml.jackson.annotation.JsonInclude
@JsonInclude(JsonInclude.Include.NON_EMPTY)
data class SystemSettings(
var mail: MailSettings? = null
)

View File

@@ -1,5 +1,6 @@
package top.fatweb.api.util
import java.security.MessageDigest
import java.util.regex.Pattern
/**
@@ -49,4 +50,17 @@ object StrUtil {
return password.toString()
}
fun md5(content: String): String {
val hash = MessageDigest.getInstance("MD5").digest(content.toByteArray())
val hex = StringBuilder(hash.size * 2)
for (b in hash) {
var str = Integer.toHexString(b.toInt())
if (b < 0x10) {
str = "0$str"
}
hex.append(str.substring(str.length -2))
}
return hex.toString()
}
}

View File

@@ -1,9 +1,9 @@
package top.fatweb.api.vo.system
data class SettingVo(
val mail: MailSettingVo?
data class SettingsVo(
val mail: MailSettingsVo?
) {
data class MailSettingVo(
data class MailSettingsVo(
val host: String?,
val port: Int?,
val username: String?,