fix: sync config cannot be overwritten #508

This commit is contained in:
Jacky 2024-08-19 17:43:18 +08:00
parent c700a29e17
commit bc92c0f344
No known key found for this signature in database
GPG key ID: 215C21B10DF38B4D
2 changed files with 117 additions and 195 deletions

View file

@ -1,141 +1,141 @@
package config package config
import ( import (
"github.com/0xJacky/Nginx-UI/api" "github.com/0xJacky/Nginx-UI/api"
"github.com/0xJacky/Nginx-UI/internal/config" "github.com/0xJacky/Nginx-UI/internal/config"
"github.com/0xJacky/Nginx-UI/internal/helper" "github.com/0xJacky/Nginx-UI/internal/helper"
"github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/0xJacky/Nginx-UI/internal/nginx"
"github.com/0xJacky/Nginx-UI/model" "github.com/0xJacky/Nginx-UI/model"
"github.com/0xJacky/Nginx-UI/query" "github.com/0xJacky/Nginx-UI/query"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/sashabaranov/go-openai" "github.com/sashabaranov/go-openai"
"net/http" "net/http"
"os" "os"
"time" "time"
) )
type EditConfigJson struct { type EditConfigJson struct {
Content string `json:"content" binding:"required"` Content string `json:"content" binding:"required"`
} }
func EditConfig(c *gin.Context) { func EditConfig(c *gin.Context) {
name := c.Param("name") name := c.Param("name")
var json struct { var json struct {
Name string `json:"name" binding:"required"` Name string `json:"name" binding:"required"`
Filepath string `json:"filepath" binding:"required"` Filepath string `json:"filepath" binding:"required"`
NewFilepath string `json:"new_filepath" binding:"required"` NewFilepath string `json:"new_filepath" binding:"required"`
Content string `json:"content"` Content string `json:"content"`
Overwrite bool `json:"overwrite"` SyncOverwrite bool `json:"sync_overwrite"`
SyncNodeIds []int `json:"sync_node_ids"` SyncNodeIds []int `json:"sync_node_ids"`
} }
if !api.BindAndValid(c, &json) { if !api.BindAndValid(c, &json) {
return return
} }
path := json.Filepath path := json.Filepath
if !helper.IsUnderDirectory(path, nginx.GetConfPath()) { if !helper.IsUnderDirectory(path, nginx.GetConfPath()) {
c.JSON(http.StatusForbidden, gin.H{ c.JSON(http.StatusForbidden, gin.H{
"message": "filepath is not under the nginx conf path", "message": "filepath is not under the nginx conf path",
}) })
return return
} }
if !helper.IsUnderDirectory(json.NewFilepath, nginx.GetConfPath()) { if !helper.IsUnderDirectory(json.NewFilepath, nginx.GetConfPath()) {
c.JSON(http.StatusForbidden, gin.H{ c.JSON(http.StatusForbidden, gin.H{
"message": "new filepath is not under the nginx conf path", "message": "new filepath is not under the nginx conf path",
}) })
return return
} }
if !helper.FileExists(path) { if !helper.FileExists(path) {
c.JSON(http.StatusNotFound, gin.H{ c.JSON(http.StatusNotFound, gin.H{
"message": "file not found", "message": "file not found",
}) })
return return
} }
content := json.Content content := json.Content
origContent, err := os.ReadFile(path) origContent, err := os.ReadFile(path)
if err != nil { if err != nil {
api.ErrHandler(c, err) api.ErrHandler(c, err)
return return
} }
if content != "" && content != string(origContent) { if content != "" && content != string(origContent) {
err = os.WriteFile(path, []byte(content), 0644) err = os.WriteFile(path, []byte(content), 0644)
if err != nil { if err != nil {
api.ErrHandler(c, err) api.ErrHandler(c, err)
return return
} }
} }
q := query.Config q := query.Config
cfg, err := q.Where(q.Filepath.Eq(json.Filepath)).FirstOrCreate() cfg, err := q.Where(q.Filepath.Eq(json.Filepath)).FirstOrCreate()
if err != nil { if err != nil {
api.ErrHandler(c, err) api.ErrHandler(c, err)
return return
} }
_, err = q.Where(q.Filepath.Eq(json.Filepath)).Updates(&model.Config{ _, err = q.Where(q.Filepath.Eq(json.Filepath)).Updates(&model.Config{
Name: json.Name, Name: json.Name,
Filepath: json.NewFilepath, Filepath: json.NewFilepath,
SyncNodeIds: json.SyncNodeIds, SyncNodeIds: json.SyncNodeIds,
SyncOverwrite: json.Overwrite, SyncOverwrite: json.SyncOverwrite,
}) })
if err != nil { if err != nil {
api.ErrHandler(c, err) api.ErrHandler(c, err)
return return
} }
g := query.ChatGPTLog g := query.ChatGPTLog
// handle rename // handle rename
if path != json.NewFilepath { if path != json.NewFilepath {
if helper.FileExists(json.NewFilepath) { if helper.FileExists(json.NewFilepath) {
c.JSON(http.StatusNotAcceptable, gin.H{ c.JSON(http.StatusNotAcceptable, gin.H{
"message": "File exists", "message": "File exists",
}) })
return return
} }
err := os.Rename(json.Filepath, json.NewFilepath) err := os.Rename(json.Filepath, json.NewFilepath)
if err != nil { if err != nil {
api.ErrHandler(c, err) api.ErrHandler(c, err)
return return
} }
// update ChatGPT record // update ChatGPT record
_, _ = g.Where(g.Name.Eq(json.NewFilepath)).Delete() _, _ = g.Where(g.Name.Eq(json.NewFilepath)).Delete()
_, _ = g.Where(g.Name.Eq(path)).Update(g.Name, json.NewFilepath) _, _ = g.Where(g.Name.Eq(path)).Update(g.Name, json.NewFilepath)
} }
err = config.SyncToRemoteServer(cfg, json.NewFilepath) err = config.SyncToRemoteServer(cfg, json.NewFilepath)
if err != nil { if err != nil {
api.ErrHandler(c, err) api.ErrHandler(c, err)
return return
} }
output := nginx.Reload() output := nginx.Reload()
if nginx.GetLogLevel(output) >= nginx.Warn { if nginx.GetLogLevel(output) >= nginx.Warn {
c.JSON(http.StatusInternalServerError, gin.H{ c.JSON(http.StatusInternalServerError, gin.H{
"message": output, "message": output,
}) })
return return
} }
chatgpt, err := g.Where(g.Name.Eq(json.NewFilepath)).FirstOrCreate() chatgpt, err := g.Where(g.Name.Eq(json.NewFilepath)).FirstOrCreate()
if err != nil { if err != nil {
api.ErrHandler(c, err) api.ErrHandler(c, err)
return return
} }
if chatgpt.Content == nil { if chatgpt.Content == nil {
chatgpt.Content = make([]openai.ChatCompletionMessage, 0) chatgpt.Content = make([]openai.ChatCompletionMessage, 0)
} }
c.JSON(http.StatusOK, config.Config{ c.JSON(http.StatusOK, config.Config{
Name: name, Name: name,
Content: content, Content: content,
ChatGPTMessages: chatgpt.Content, ChatGPTMessages: chatgpt.Content,
FilePath: json.NewFilepath, FilePath: json.NewFilepath,
ModifiedAt: time.Now(), ModifiedAt: time.Now(),
}) })
} }

78
app/auto-imports.d.ts vendored
View file

@ -165,81 +165,3 @@ declare module 'vue' {
readonly watchSyncEffect: UnwrapRef<typeof import('vue')['watchSyncEffect']> readonly watchSyncEffect: UnwrapRef<typeof import('vue')['watchSyncEffect']>
} }
} }
declare module '@vue/runtime-core' {
interface GlobalComponents {}
interface ComponentCustomProperties {
readonly $gettext: UnwrapRef<typeof import('@/gettext')['$gettext']>
readonly $ngettext: UnwrapRef<typeof import('@/gettext')['$ngettext']>
readonly $npgettext: UnwrapRef<typeof import('@/gettext')['$npgettext']>
readonly $pgettext: UnwrapRef<typeof import('@/gettext')['$pgettext']>
readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']>
readonly acceptHMRUpdate: UnwrapRef<typeof import('pinia')['acceptHMRUpdate']>
readonly computed: UnwrapRef<typeof import('vue')['computed']>
readonly createApp: UnwrapRef<typeof import('vue')['createApp']>
readonly createPinia: UnwrapRef<typeof import('pinia')['createPinia']>
readonly customRef: UnwrapRef<typeof import('vue')['customRef']>
readonly defineAsyncComponent: UnwrapRef<typeof import('vue')['defineAsyncComponent']>
readonly defineComponent: UnwrapRef<typeof import('vue')['defineComponent']>
readonly defineStore: UnwrapRef<typeof import('pinia')['defineStore']>
readonly effectScope: UnwrapRef<typeof import('vue')['effectScope']>
readonly getActivePinia: UnwrapRef<typeof import('pinia')['getActivePinia']>
readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']>
readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']>
readonly h: UnwrapRef<typeof import('vue')['h']>
readonly inject: UnwrapRef<typeof import('vue')['inject']>
readonly isProxy: UnwrapRef<typeof import('vue')['isProxy']>
readonly isReactive: UnwrapRef<typeof import('vue')['isReactive']>
readonly isReadonly: UnwrapRef<typeof import('vue')['isReadonly']>
readonly isRef: UnwrapRef<typeof import('vue')['isRef']>
readonly mapActions: UnwrapRef<typeof import('pinia')['mapActions']>
readonly mapGetters: UnwrapRef<typeof import('pinia')['mapGetters']>
readonly mapState: UnwrapRef<typeof import('pinia')['mapState']>
readonly mapStores: UnwrapRef<typeof import('pinia')['mapStores']>
readonly mapWritableState: UnwrapRef<typeof import('pinia')['mapWritableState']>
readonly markRaw: UnwrapRef<typeof import('vue')['markRaw']>
readonly nextTick: UnwrapRef<typeof import('vue')['nextTick']>
readonly onActivated: UnwrapRef<typeof import('vue')['onActivated']>
readonly onBeforeMount: UnwrapRef<typeof import('vue')['onBeforeMount']>
readonly onBeforeRouteLeave: UnwrapRef<typeof import('vue-router')['onBeforeRouteLeave']>
readonly onBeforeRouteUpdate: UnwrapRef<typeof import('vue-router')['onBeforeRouteUpdate']>
readonly onBeforeUnmount: UnwrapRef<typeof import('vue')['onBeforeUnmount']>
readonly onBeforeUpdate: UnwrapRef<typeof import('vue')['onBeforeUpdate']>
readonly onDeactivated: UnwrapRef<typeof import('vue')['onDeactivated']>
readonly onErrorCaptured: UnwrapRef<typeof import('vue')['onErrorCaptured']>
readonly onMounted: UnwrapRef<typeof import('vue')['onMounted']>
readonly onRenderTracked: UnwrapRef<typeof import('vue')['onRenderTracked']>
readonly onRenderTriggered: UnwrapRef<typeof import('vue')['onRenderTriggered']>
readonly onScopeDispose: UnwrapRef<typeof import('vue')['onScopeDispose']>
readonly onServerPrefetch: UnwrapRef<typeof import('vue')['onServerPrefetch']>
readonly onUnmounted: UnwrapRef<typeof import('vue')['onUnmounted']>
readonly onUpdated: UnwrapRef<typeof import('vue')['onUpdated']>
readonly provide: UnwrapRef<typeof import('vue')['provide']>
readonly reactive: UnwrapRef<typeof import('vue')['reactive']>
readonly readonly: UnwrapRef<typeof import('vue')['readonly']>
readonly ref: UnwrapRef<typeof import('vue')['ref']>
readonly resolveComponent: UnwrapRef<typeof import('vue')['resolveComponent']>
readonly setActivePinia: UnwrapRef<typeof import('pinia')['setActivePinia']>
readonly setMapStoreSuffix: UnwrapRef<typeof import('pinia')['setMapStoreSuffix']>
readonly shallowReactive: UnwrapRef<typeof import('vue')['shallowReactive']>
readonly shallowReadonly: UnwrapRef<typeof import('vue')['shallowReadonly']>
readonly shallowRef: UnwrapRef<typeof import('vue')['shallowRef']>
readonly storeToRefs: UnwrapRef<typeof import('pinia')['storeToRefs']>
readonly toRaw: UnwrapRef<typeof import('vue')['toRaw']>
readonly toRef: UnwrapRef<typeof import('vue')['toRef']>
readonly toRefs: UnwrapRef<typeof import('vue')['toRefs']>
readonly toValue: UnwrapRef<typeof import('vue')['toValue']>
readonly triggerRef: UnwrapRef<typeof import('vue')['triggerRef']>
readonly unref: UnwrapRef<typeof import('vue')['unref']>
readonly useAttrs: UnwrapRef<typeof import('vue')['useAttrs']>
readonly useCssModule: UnwrapRef<typeof import('vue')['useCssModule']>
readonly useCssVars: UnwrapRef<typeof import('vue')['useCssVars']>
readonly useLink: UnwrapRef<typeof import('vue-router')['useLink']>
readonly useRoute: UnwrapRef<typeof import('vue-router')['useRoute']>
readonly useRouter: UnwrapRef<typeof import('vue-router')['useRouter']>
readonly useSlots: UnwrapRef<typeof import('vue')['useSlots']>
readonly watch: UnwrapRef<typeof import('vue')['watch']>
readonly watchEffect: UnwrapRef<typeof import('vue')['watchEffect']>
readonly watchPostEffect: UnwrapRef<typeof import('vue')['watchPostEffect']>
readonly watchSyncEffect: UnwrapRef<typeof import('vue')['watchSyncEffect']>
}
}