mirror of
https://github.com/0xJacky/nginx-ui.git
synced 2025-05-12 02:45:49 +02:00
feat: forced use of advanced editor #73
This commit is contained in:
parent
8905575cdf
commit
defd81461e
10 changed files with 508 additions and 34 deletions
|
@ -25,6 +25,10 @@ class Domain extends Curd {
|
||||||
duplicate(name: string, data: any) {
|
duplicate(name: string, data: any) {
|
||||||
return http.post(this.baseUrl + '/' + name + '/duplicate', data)
|
return http.post(this.baseUrl + '/' + name + '/duplicate', data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
advance_mode(name: string, data: any) {
|
||||||
|
return http.post(this.baseUrl + '/' + name + '/advance', data)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const domain = new Domain('/domain')
|
const domain = new Domain('/domain')
|
||||||
|
|
|
@ -8,11 +8,10 @@ import {computed, provide, reactive, ref, watch} from 'vue'
|
||||||
import {useRoute, useRouter} from 'vue-router'
|
import {useRoute, useRouter} from 'vue-router'
|
||||||
import domain from '@/api/domain'
|
import domain from '@/api/domain'
|
||||||
import ngx from '@/api/ngx'
|
import ngx from '@/api/ngx'
|
||||||
import {message} from 'ant-design-vue'
|
import {message, Modal} from 'ant-design-vue'
|
||||||
import config from '@/api/config'
|
import config from '@/api/config'
|
||||||
import ChatGPT from '@/components/ChatGPT/ChatGPT.vue'
|
import ChatGPT from '@/components/ChatGPT/ChatGPT.vue'
|
||||||
|
|
||||||
|
|
||||||
const {$gettext, interpolate} = useGettext()
|
const {$gettext, interpolate} = useGettext()
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
@ -25,7 +24,7 @@ watch(route, () => {
|
||||||
|
|
||||||
const update = ref(0)
|
const update = ref(0)
|
||||||
|
|
||||||
const ngx_config = reactive({
|
const ngx_config: any = reactive({
|
||||||
name: '',
|
name: '',
|
||||||
upstreams: [],
|
upstreams: [],
|
||||||
servers: []
|
servers: []
|
||||||
|
@ -57,6 +56,10 @@ const history_chatgpt_record = ref([])
|
||||||
|
|
||||||
function handle_response(r: any) {
|
function handle_response(r: any) {
|
||||||
|
|
||||||
|
if (r.advanced) {
|
||||||
|
advance_mode.value = true
|
||||||
|
}
|
||||||
|
|
||||||
Object.keys(cert_info_map).forEach(v => {
|
Object.keys(cert_info_map).forEach(v => {
|
||||||
delete cert_info_map[v]
|
delete cert_info_map[v]
|
||||||
})
|
})
|
||||||
|
@ -95,14 +98,17 @@ function handle_parse_error(r: any) {
|
||||||
throw r
|
throw r
|
||||||
}
|
}
|
||||||
|
|
||||||
function on_mode_change(advance_mode: boolean) {
|
function on_mode_change(advanced: boolean) {
|
||||||
if (advance_mode) {
|
domain.advance_mode(name.value, {advanced}).then(() => {
|
||||||
build_config()
|
advance_mode.value = advanced
|
||||||
} else {
|
if (advanced) {
|
||||||
return ngx.tokenize_config(configText.value).then((r: any) => {
|
build_config()
|
||||||
Object.assign(ngx_config, r)
|
} else {
|
||||||
}).catch(handle_parse_error)
|
return ngx.tokenize_config(configText.value).then((r: any) => {
|
||||||
}
|
Object.assign(ngx_config, r)
|
||||||
|
}).catch(handle_parse_error)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function build_config() {
|
function build_config() {
|
||||||
|
@ -140,6 +146,7 @@ const save = async () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
function enable() {
|
function enable() {
|
||||||
|
enabled.value = true
|
||||||
domain.enable(name.value).then(() => {
|
domain.enable(name.value).then(() => {
|
||||||
message.success($gettext('Enabled successfully'))
|
message.success($gettext('Enabled successfully'))
|
||||||
enabled.value = true
|
enabled.value = true
|
||||||
|
@ -149,6 +156,7 @@ function enable() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function disable() {
|
function disable() {
|
||||||
|
enabled.value = false
|
||||||
domain.disable(name.value).then(() => {
|
domain.disable(name.value).then(() => {
|
||||||
message.success($gettext('Disabled successfully'))
|
message.success($gettext('Disabled successfully'))
|
||||||
enabled.value = false
|
enabled.value = false
|
||||||
|
@ -158,11 +166,18 @@ function disable() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function on_change_enabled(checked: boolean) {
|
function on_change_enabled(checked: boolean) {
|
||||||
if (checked) {
|
Modal.confirm({
|
||||||
enable()
|
title: checked ? $gettext('Do you want to enable this site?') : $gettext('Do you want to disable this site?'),
|
||||||
} else {
|
mask: false,
|
||||||
disable()
|
centered: true,
|
||||||
}
|
async onOk() {
|
||||||
|
if (checked) {
|
||||||
|
enable()
|
||||||
|
} else {
|
||||||
|
disable()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const editor_md = computed(() => history_chatgpt_record?.value?.length > 1 ? 16 : 24)
|
const editor_md = computed(() => history_chatgpt_record?.value?.length > 1 ? 16 : 24)
|
||||||
|
@ -187,7 +202,7 @@ provide('save_site_config', save)
|
||||||
<div class="mode-switch">
|
<div class="mode-switch">
|
||||||
<div class="switch">
|
<div class="switch">
|
||||||
<a-switch size="small" :disabled="parse_error_status"
|
<a-switch size="small" :disabled="parse_error_status"
|
||||||
v-model:checked="advance_mode" @change="on_mode_change"/>
|
:checked="advance_mode" @change="on_mode_change"/>
|
||||||
</div>
|
</div>
|
||||||
<template v-if="advance_mode">
|
<template v-if="advance_mode">
|
||||||
<div>{{ $gettext('Advance Mode') }}</div>
|
<div>{{ $gettext('Advance Mode') }}</div>
|
||||||
|
@ -198,6 +213,13 @@ provide('save_site_config', save)
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<a-form-item :label="$gettext('Enabled')">
|
||||||
|
<a-switch :checked="enabled" @change="on_change_enabled"/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item :label="$gettext('Name')">
|
||||||
|
<a-input v-model:value="filename"/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
<transition name="slide-fade">
|
<transition name="slide-fade">
|
||||||
<div v-if="advance_mode" key="advance">
|
<div v-if="advance_mode" key="advance">
|
||||||
<div class="parse-error-alert-wrapper" v-if="parse_error_status">
|
<div class="parse-error-alert-wrapper" v-if="parse_error_status">
|
||||||
|
@ -213,12 +235,6 @@ provide('save_site_config', save)
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="domain-edit-container" key="basic" v-else>
|
<div class="domain-edit-container" key="basic" v-else>
|
||||||
<a-form-item :label="$gettext('Enabled')">
|
|
||||||
<a-switch v-model:checked="enabled" @change="on_change_enabled"/>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item :label="$gettext('Name')">
|
|
||||||
<a-input v-model:value="filename"/>
|
|
||||||
</a-form-item>
|
|
||||||
<ngx-config-editor
|
<ngx-config-editor
|
||||||
ref="ngx_config_editor"
|
ref="ngx_config_editor"
|
||||||
:ngx_config="ngx_config"
|
:ngx_config="ngx_config"
|
||||||
|
|
|
@ -2,7 +2,7 @@ server {
|
||||||
listen 80;
|
listen 80;
|
||||||
listen [::]:80;
|
listen [::]:80;
|
||||||
server_name homework.jackyu.cn;
|
server_name homework.jackyu.cn;
|
||||||
# rewrite ^(.*)$ https://$host$1 permanent;
|
# rewrite ^(.*)$ https://$host$1 permanent;
|
||||||
return 307 https://$server_name$request_uri;
|
return 307 https://$server_name$request_uri;
|
||||||
location /.well-known/acme-challenge {
|
location /.well-known/acme-challenge {
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
|
@ -17,7 +17,7 @@ server {
|
||||||
server_name homework.jackyu.cn;
|
server_name homework.jackyu.cn;
|
||||||
ssl_certificate /etc/nginx/ssl/homework.jackyu.cn/fullchain.cer;
|
ssl_certificate /etc/nginx/ssl/homework.jackyu.cn/fullchain.cer;
|
||||||
ssl_certificate_key /etc/nginx/ssl/homework.jackyu.cn/private.key;
|
ssl_certificate_key /etc/nginx/ssl/homework.jackyu.cn/private.key;
|
||||||
# rewrite ^(.*)$ https://$host$1 permanent;
|
# rewrite ^(.*)$ https://$host$1 permanent;
|
||||||
return 307 https://$server_name$request_uri;
|
return 307 https://$server_name$request_uri;
|
||||||
location /.well-known/acme-challenge {
|
location /.well-known/acme-challenge {
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
|
|
|
@ -94,6 +94,39 @@ func GetDomain(c *gin.Context) {
|
||||||
enabled = false
|
enabled = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g := query.ChatGPTLog
|
||||||
|
chatgpt, err := g.Where(g.Name.Eq(path)).FirstOrCreate()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
ErrHandler(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
s := query.Site
|
||||||
|
site, err := s.Where(s.Path.Eq(path)).FirstOrInit()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
ErrHandler(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if site.Advanced {
|
||||||
|
origContent, err := os.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
ErrHandler(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, gin.H{
|
||||||
|
"advanced": site.Advanced,
|
||||||
|
"enabled": enabled,
|
||||||
|
"name": name,
|
||||||
|
"config": string(origContent),
|
||||||
|
"chatgpt_messages": chatgpt.Content,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
c.Set("maybe_error", "nginx_config_syntax_error")
|
c.Set("maybe_error", "nginx_config_syntax_error")
|
||||||
config, err := nginx.ParseNgxConfig(path)
|
config, err := nginx.ParseNgxConfig(path)
|
||||||
|
|
||||||
|
@ -130,17 +163,10 @@ func GetDomain(c *gin.Context) {
|
||||||
|
|
||||||
certModel, _ := model.FirstCert(name)
|
certModel, _ := model.FirstCert(name)
|
||||||
|
|
||||||
g := query.ChatGPTLog
|
|
||||||
chatgpt, err := g.Where(g.Name.Eq(path)).FirstOrCreate()
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
ErrHandler(c, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
c.Set("maybe_error", "nginx_config_syntax_error")
|
c.Set("maybe_error", "nginx_config_syntax_error")
|
||||||
|
|
||||||
c.JSON(http.StatusOK, gin.H{
|
c.JSON(http.StatusOK, gin.H{
|
||||||
|
"advanced": site.Advanced,
|
||||||
"enabled": enabled,
|
"enabled": enabled,
|
||||||
"name": name,
|
"name": name,
|
||||||
"config": config.FmtCode(),
|
"config": config.FmtCode(),
|
||||||
|
@ -190,6 +216,9 @@ func SaveDomain(c *gin.Context) {
|
||||||
// rename the config file if needed
|
// rename the config file if needed
|
||||||
if name != json.Name {
|
if name != json.Name {
|
||||||
newPath := nginx.GetConfPath("sites-available", json.Name)
|
newPath := nginx.GetConfPath("sites-available", json.Name)
|
||||||
|
s := query.Site
|
||||||
|
_, err = s.Where(s.Path.Eq(path)).Update(s.Path, newPath)
|
||||||
|
|
||||||
// check if dst file exists, do not rename
|
// check if dst file exists, do not rename
|
||||||
if helper.FileExists(newPath) {
|
if helper.FileExists(newPath) {
|
||||||
c.JSON(http.StatusNotAcceptable, gin.H{
|
c.JSON(http.StatusNotAcceptable, gin.H{
|
||||||
|
@ -448,3 +477,36 @@ func DuplicateSite(c *gin.Context) {
|
||||||
"dst": dst,
|
"dst": dst,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func DomainEditByAdvancedMode(c *gin.Context) {
|
||||||
|
var json struct {
|
||||||
|
Advanced bool `json:"advanced"`
|
||||||
|
}
|
||||||
|
|
||||||
|
if !BindAndValid(c, &json) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
name := c.Param("name")
|
||||||
|
path := nginx.GetConfPath("sites-available", name)
|
||||||
|
|
||||||
|
s := query.Site
|
||||||
|
|
||||||
|
_, err := s.Where(s.Path.Eq(path)).FirstOrCreate()
|
||||||
|
if err != nil {
|
||||||
|
ErrHandler(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = s.Where(s.Path.Eq(path)).Update(s.Advanced, json.Advanced)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
ErrHandler(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, gin.H{
|
||||||
|
"message": "ok",
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ func GenerateAllModel() []any {
|
||||||
AuthToken{},
|
AuthToken{},
|
||||||
Cert{},
|
Cert{},
|
||||||
ChatGPTLog{},
|
ChatGPTLog{},
|
||||||
|
Site{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
7
server/model/site.go
Normal file
7
server/model/site.go
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
package model
|
||||||
|
|
||||||
|
type Site struct {
|
||||||
|
Model
|
||||||
|
Path string `json:"path"`
|
||||||
|
Advanced bool `json:"advanced"`
|
||||||
|
}
|
|
@ -11,7 +11,7 @@ import (
|
||||||
func buildComments(orig string, indent int) (content string) {
|
func buildComments(orig string, indent int) (content string) {
|
||||||
scanner := bufio.NewScanner(strings.NewReader(orig))
|
scanner := bufio.NewScanner(strings.NewReader(orig))
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
content += strings.Repeat("\t", indent) + "# " + scanner.Text() + "\n"
|
content += strings.Repeat("\t", indent) + "# " + strings.TrimSpace(scanner.Text()) + "\n"
|
||||||
}
|
}
|
||||||
content = strings.TrimLeft(content, "\n")
|
content = strings.TrimLeft(content, "\n")
|
||||||
return
|
return
|
||||||
|
|
|
@ -22,6 +22,7 @@ var (
|
||||||
Cert *cert
|
Cert *cert
|
||||||
ChatGPTLog *chatGPTLog
|
ChatGPTLog *chatGPTLog
|
||||||
ConfigBackup *configBackup
|
ConfigBackup *configBackup
|
||||||
|
Site *site
|
||||||
)
|
)
|
||||||
|
|
||||||
func SetDefault(db *gorm.DB, opts ...gen.DOOption) {
|
func SetDefault(db *gorm.DB, opts ...gen.DOOption) {
|
||||||
|
@ -31,6 +32,7 @@ func SetDefault(db *gorm.DB, opts ...gen.DOOption) {
|
||||||
Cert = &Q.Cert
|
Cert = &Q.Cert
|
||||||
ChatGPTLog = &Q.ChatGPTLog
|
ChatGPTLog = &Q.ChatGPTLog
|
||||||
ConfigBackup = &Q.ConfigBackup
|
ConfigBackup = &Q.ConfigBackup
|
||||||
|
Site = &Q.Site
|
||||||
}
|
}
|
||||||
|
|
||||||
func Use(db *gorm.DB, opts ...gen.DOOption) *Query {
|
func Use(db *gorm.DB, opts ...gen.DOOption) *Query {
|
||||||
|
@ -41,6 +43,7 @@ func Use(db *gorm.DB, opts ...gen.DOOption) *Query {
|
||||||
Cert: newCert(db, opts...),
|
Cert: newCert(db, opts...),
|
||||||
ChatGPTLog: newChatGPTLog(db, opts...),
|
ChatGPTLog: newChatGPTLog(db, opts...),
|
||||||
ConfigBackup: newConfigBackup(db, opts...),
|
ConfigBackup: newConfigBackup(db, opts...),
|
||||||
|
Site: newSite(db, opts...),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,6 +55,7 @@ type Query struct {
|
||||||
Cert cert
|
Cert cert
|
||||||
ChatGPTLog chatGPTLog
|
ChatGPTLog chatGPTLog
|
||||||
ConfigBackup configBackup
|
ConfigBackup configBackup
|
||||||
|
Site site
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Query) Available() bool { return q.db != nil }
|
func (q *Query) Available() bool { return q.db != nil }
|
||||||
|
@ -64,6 +68,7 @@ func (q *Query) clone(db *gorm.DB) *Query {
|
||||||
Cert: q.Cert.clone(db),
|
Cert: q.Cert.clone(db),
|
||||||
ChatGPTLog: q.ChatGPTLog.clone(db),
|
ChatGPTLog: q.ChatGPTLog.clone(db),
|
||||||
ConfigBackup: q.ConfigBackup.clone(db),
|
ConfigBackup: q.ConfigBackup.clone(db),
|
||||||
|
Site: q.Site.clone(db),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,6 +88,7 @@ func (q *Query) ReplaceDB(db *gorm.DB) *Query {
|
||||||
Cert: q.Cert.replaceDB(db),
|
Cert: q.Cert.replaceDB(db),
|
||||||
ChatGPTLog: q.ChatGPTLog.replaceDB(db),
|
ChatGPTLog: q.ChatGPTLog.replaceDB(db),
|
||||||
ConfigBackup: q.ConfigBackup.replaceDB(db),
|
ConfigBackup: q.ConfigBackup.replaceDB(db),
|
||||||
|
Site: q.Site.replaceDB(db),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +98,7 @@ type queryCtx struct {
|
||||||
Cert *certDo
|
Cert *certDo
|
||||||
ChatGPTLog *chatGPTLogDo
|
ChatGPTLog *chatGPTLogDo
|
||||||
ConfigBackup *configBackupDo
|
ConfigBackup *configBackupDo
|
||||||
|
Site *siteDo
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Query) WithContext(ctx context.Context) *queryCtx {
|
func (q *Query) WithContext(ctx context.Context) *queryCtx {
|
||||||
|
@ -101,6 +108,7 @@ func (q *Query) WithContext(ctx context.Context) *queryCtx {
|
||||||
Cert: q.Cert.WithContext(ctx),
|
Cert: q.Cert.WithContext(ctx),
|
||||||
ChatGPTLog: q.ChatGPTLog.WithContext(ctx),
|
ChatGPTLog: q.ChatGPTLog.WithContext(ctx),
|
||||||
ConfigBackup: q.ConfigBackup.WithContext(ctx),
|
ConfigBackup: q.ConfigBackup.WithContext(ctx),
|
||||||
|
Site: q.Site.WithContext(ctx),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
374
server/query/sites.gen.go
Normal file
374
server/query/sites.gen.go
Normal file
|
@ -0,0 +1,374 @@
|
||||||
|
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||||
|
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||||
|
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package query
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"gorm.io/gorm/clause"
|
||||||
|
"gorm.io/gorm/schema"
|
||||||
|
|
||||||
|
"gorm.io/gen"
|
||||||
|
"gorm.io/gen/field"
|
||||||
|
|
||||||
|
"gorm.io/plugin/dbresolver"
|
||||||
|
|
||||||
|
"github.com/0xJacky/Nginx-UI/server/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newSite(db *gorm.DB, opts ...gen.DOOption) site {
|
||||||
|
_site := site{}
|
||||||
|
|
||||||
|
_site.siteDo.UseDB(db, opts...)
|
||||||
|
_site.siteDo.UseModel(&model.Site{})
|
||||||
|
|
||||||
|
tableName := _site.siteDo.TableName()
|
||||||
|
_site.ALL = field.NewAsterisk(tableName)
|
||||||
|
_site.ID = field.NewUint(tableName, "id")
|
||||||
|
_site.CreatedAt = field.NewTime(tableName, "created_at")
|
||||||
|
_site.UpdatedAt = field.NewTime(tableName, "updated_at")
|
||||||
|
_site.DeletedAt = field.NewTime(tableName, "deleted_at")
|
||||||
|
_site.Path = field.NewString(tableName, "path")
|
||||||
|
_site.Advanced = field.NewBool(tableName, "advanced")
|
||||||
|
|
||||||
|
_site.fillFieldMap()
|
||||||
|
|
||||||
|
return _site
|
||||||
|
}
|
||||||
|
|
||||||
|
type site struct {
|
||||||
|
siteDo
|
||||||
|
|
||||||
|
ALL field.Asterisk
|
||||||
|
ID field.Uint
|
||||||
|
CreatedAt field.Time
|
||||||
|
UpdatedAt field.Time
|
||||||
|
DeletedAt field.Time
|
||||||
|
Path field.String
|
||||||
|
Advanced field.Bool
|
||||||
|
|
||||||
|
fieldMap map[string]field.Expr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s site) Table(newTableName string) *site {
|
||||||
|
s.siteDo.UseTable(newTableName)
|
||||||
|
return s.updateTableName(newTableName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s site) As(alias string) *site {
|
||||||
|
s.siteDo.DO = *(s.siteDo.As(alias).(*gen.DO))
|
||||||
|
return s.updateTableName(alias)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *site) updateTableName(table string) *site {
|
||||||
|
s.ALL = field.NewAsterisk(table)
|
||||||
|
s.ID = field.NewUint(table, "id")
|
||||||
|
s.CreatedAt = field.NewTime(table, "created_at")
|
||||||
|
s.UpdatedAt = field.NewTime(table, "updated_at")
|
||||||
|
s.DeletedAt = field.NewTime(table, "deleted_at")
|
||||||
|
s.Path = field.NewString(table, "path")
|
||||||
|
s.Advanced = field.NewBool(table, "advanced")
|
||||||
|
|
||||||
|
s.fillFieldMap()
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *site) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||||
|
_f, ok := s.fieldMap[fieldName]
|
||||||
|
if !ok || _f == nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
_oe, ok := _f.(field.OrderExpr)
|
||||||
|
return _oe, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *site) fillFieldMap() {
|
||||||
|
s.fieldMap = make(map[string]field.Expr, 6)
|
||||||
|
s.fieldMap["id"] = s.ID
|
||||||
|
s.fieldMap["created_at"] = s.CreatedAt
|
||||||
|
s.fieldMap["updated_at"] = s.UpdatedAt
|
||||||
|
s.fieldMap["deleted_at"] = s.DeletedAt
|
||||||
|
s.fieldMap["path"] = s.Path
|
||||||
|
s.fieldMap["advanced"] = s.Advanced
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s site) clone(db *gorm.DB) site {
|
||||||
|
s.siteDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s site) replaceDB(db *gorm.DB) site {
|
||||||
|
s.siteDo.ReplaceDB(db)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
type siteDo struct{ gen.DO }
|
||||||
|
|
||||||
|
// FirstByID Where("id=@id")
|
||||||
|
func (s siteDo) FirstByID(id int) (result *model.Site, err error) {
|
||||||
|
var params []interface{}
|
||||||
|
|
||||||
|
var generateSQL strings.Builder
|
||||||
|
params = append(params, id)
|
||||||
|
generateSQL.WriteString("id=? ")
|
||||||
|
|
||||||
|
var executeSQL *gorm.DB
|
||||||
|
executeSQL = s.UnderlyingDB().Where(generateSQL.String(), params...).Take(&result) // ignore_security_alert
|
||||||
|
err = executeSQL.Error
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteByID update @@table set deleted_at=NOW() where id=@id
|
||||||
|
func (s siteDo) DeleteByID(id int) (err error) {
|
||||||
|
var params []interface{}
|
||||||
|
|
||||||
|
var generateSQL strings.Builder
|
||||||
|
params = append(params, id)
|
||||||
|
generateSQL.WriteString("update sites set deleted_at=NOW() where id=? ")
|
||||||
|
|
||||||
|
var executeSQL *gorm.DB
|
||||||
|
executeSQL = s.UnderlyingDB().Exec(generateSQL.String(), params...) // ignore_security_alert
|
||||||
|
err = executeSQL.Error
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) Debug() *siteDo {
|
||||||
|
return s.withDO(s.DO.Debug())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) WithContext(ctx context.Context) *siteDo {
|
||||||
|
return s.withDO(s.DO.WithContext(ctx))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) ReadDB() *siteDo {
|
||||||
|
return s.Clauses(dbresolver.Read)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) WriteDB() *siteDo {
|
||||||
|
return s.Clauses(dbresolver.Write)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) Session(config *gorm.Session) *siteDo {
|
||||||
|
return s.withDO(s.DO.Session(config))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) Clauses(conds ...clause.Expression) *siteDo {
|
||||||
|
return s.withDO(s.DO.Clauses(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) Returning(value interface{}, columns ...string) *siteDo {
|
||||||
|
return s.withDO(s.DO.Returning(value, columns...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) Not(conds ...gen.Condition) *siteDo {
|
||||||
|
return s.withDO(s.DO.Not(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) Or(conds ...gen.Condition) *siteDo {
|
||||||
|
return s.withDO(s.DO.Or(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) Select(conds ...field.Expr) *siteDo {
|
||||||
|
return s.withDO(s.DO.Select(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) Where(conds ...gen.Condition) *siteDo {
|
||||||
|
return s.withDO(s.DO.Where(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) Exists(subquery interface{ UnderlyingDB() *gorm.DB }) *siteDo {
|
||||||
|
return s.Where(field.CompareSubQuery(field.ExistsOp, nil, subquery.UnderlyingDB()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) Order(conds ...field.Expr) *siteDo {
|
||||||
|
return s.withDO(s.DO.Order(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) Distinct(cols ...field.Expr) *siteDo {
|
||||||
|
return s.withDO(s.DO.Distinct(cols...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) Omit(cols ...field.Expr) *siteDo {
|
||||||
|
return s.withDO(s.DO.Omit(cols...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) Join(table schema.Tabler, on ...field.Expr) *siteDo {
|
||||||
|
return s.withDO(s.DO.Join(table, on...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) LeftJoin(table schema.Tabler, on ...field.Expr) *siteDo {
|
||||||
|
return s.withDO(s.DO.LeftJoin(table, on...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) RightJoin(table schema.Tabler, on ...field.Expr) *siteDo {
|
||||||
|
return s.withDO(s.DO.RightJoin(table, on...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) Group(cols ...field.Expr) *siteDo {
|
||||||
|
return s.withDO(s.DO.Group(cols...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) Having(conds ...gen.Condition) *siteDo {
|
||||||
|
return s.withDO(s.DO.Having(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) Limit(limit int) *siteDo {
|
||||||
|
return s.withDO(s.DO.Limit(limit))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) Offset(offset int) *siteDo {
|
||||||
|
return s.withDO(s.DO.Offset(offset))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *siteDo {
|
||||||
|
return s.withDO(s.DO.Scopes(funcs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) Unscoped() *siteDo {
|
||||||
|
return s.withDO(s.DO.Unscoped())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) Create(values ...*model.Site) error {
|
||||||
|
if len(values) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return s.DO.Create(values)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) CreateInBatches(values []*model.Site, batchSize int) error {
|
||||||
|
return s.DO.CreateInBatches(values, batchSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save : !!! underlying implementation is different with GORM
|
||||||
|
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
|
||||||
|
func (s siteDo) Save(values ...*model.Site) error {
|
||||||
|
if len(values) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return s.DO.Save(values)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) First() (*model.Site, error) {
|
||||||
|
if result, err := s.DO.First(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return result.(*model.Site), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) Take() (*model.Site, error) {
|
||||||
|
if result, err := s.DO.Take(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return result.(*model.Site), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) Last() (*model.Site, error) {
|
||||||
|
if result, err := s.DO.Last(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return result.(*model.Site), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) Find() ([]*model.Site, error) {
|
||||||
|
result, err := s.DO.Find()
|
||||||
|
return result.([]*model.Site), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.Site, err error) {
|
||||||
|
buf := make([]*model.Site, 0, batchSize)
|
||||||
|
err = s.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
|
||||||
|
defer func() { results = append(results, buf...) }()
|
||||||
|
return fc(tx, batch)
|
||||||
|
})
|
||||||
|
return results, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) FindInBatches(result *[]*model.Site, batchSize int, fc func(tx gen.Dao, batch int) error) error {
|
||||||
|
return s.DO.FindInBatches(result, batchSize, fc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) Attrs(attrs ...field.AssignExpr) *siteDo {
|
||||||
|
return s.withDO(s.DO.Attrs(attrs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) Assign(attrs ...field.AssignExpr) *siteDo {
|
||||||
|
return s.withDO(s.DO.Assign(attrs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) Joins(fields ...field.RelationField) *siteDo {
|
||||||
|
for _, _f := range fields {
|
||||||
|
s = *s.withDO(s.DO.Joins(_f))
|
||||||
|
}
|
||||||
|
return &s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) Preload(fields ...field.RelationField) *siteDo {
|
||||||
|
for _, _f := range fields {
|
||||||
|
s = *s.withDO(s.DO.Preload(_f))
|
||||||
|
}
|
||||||
|
return &s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) FirstOrInit() (*model.Site, error) {
|
||||||
|
if result, err := s.DO.FirstOrInit(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return result.(*model.Site), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) FirstOrCreate() (*model.Site, error) {
|
||||||
|
if result, err := s.DO.FirstOrCreate(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return result.(*model.Site), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) FindByPage(offset int, limit int) (result []*model.Site, count int64, err error) {
|
||||||
|
result, err = s.Offset(offset).Limit(limit).Find()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if size := len(result); 0 < limit && 0 < size && size < limit {
|
||||||
|
count = int64(size + offset)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
count, err = s.Offset(-1).Limit(-1).Count()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
|
||||||
|
count, err = s.Count()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.Offset(offset).Limit(limit).Scan(result)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) Scan(result interface{}) (err error) {
|
||||||
|
return s.DO.Scan(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s siteDo) Delete(models ...*model.Site) (result gen.ResultInfo, err error) {
|
||||||
|
return s.DO.Delete(models)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *siteDo) withDO(do gen.Dao) *siteDo {
|
||||||
|
s.DO = *do.(*gen.DO)
|
||||||
|
return s
|
||||||
|
}
|
|
@ -63,6 +63,8 @@ func InitRouter() *gin.Engine {
|
||||||
|
|
||||||
g.POST("domain/:name/enable", api.EnableDomain)
|
g.POST("domain/:name/enable", api.EnableDomain)
|
||||||
g.POST("domain/:name/disable", api.DisableDomain)
|
g.POST("domain/:name/disable", api.DisableDomain)
|
||||||
|
g.POST("domain/:name/advance", api.DomainEditByAdvancedMode)
|
||||||
|
|
||||||
g.DELETE("domain/:name", api.DeleteDomain)
|
g.DELETE("domain/:name", api.DeleteDomain)
|
||||||
// duplicate site
|
// duplicate site
|
||||||
g.POST("domain/:name/duplicate", api.DuplicateSite)
|
g.POST("domain/:name/duplicate", api.DuplicateSite)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue