mirror of
https://github.com/0xJacky/nginx-ui.git
synced 2025-05-11 02:15:48 +02:00
wip: ChatGPT assistant
This commit is contained in:
parent
ba87f02a53
commit
4cd77f28eb
27 changed files with 3197 additions and 529 deletions
|
@ -14,3 +14,9 @@ NginxConfigDir =
|
|||
[nginx_log]
|
||||
AccessLogPath = /var/log/nginx/access.log
|
||||
ErrorLogPath = /var/log/nginx/error.log
|
||||
|
||||
[openai]
|
||||
Model =
|
||||
BaseUrl =
|
||||
Proxy =
|
||||
Token =
|
||||
|
|
3
frontend/components.d.ts
vendored
3
frontend/components.d.ts
vendored
|
@ -16,6 +16,7 @@ declare module '@vue/runtime-core' {
|
|||
ACol: typeof import('ant-design-vue/es')['Col']
|
||||
ACollapse: typeof import('ant-design-vue/es')['Collapse']
|
||||
ACollapsePanel: typeof import('ant-design-vue/es')['CollapsePanel']
|
||||
AComment: typeof import('ant-design-vue/es')['Comment']
|
||||
AConfigProvider: typeof import('ant-design-vue/es')['ConfigProvider']
|
||||
ADivider: typeof import('ant-design-vue/es')['Divider']
|
||||
ADrawer: typeof import('ant-design-vue/es')['Drawer']
|
||||
|
@ -55,9 +56,11 @@ declare module '@vue/runtime-core' {
|
|||
ATabs: typeof import('ant-design-vue/es')['Tabs']
|
||||
ATag: typeof import('ant-design-vue/es')['Tag']
|
||||
ATextarea: typeof import('ant-design-vue/es')['Textarea']
|
||||
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
|
||||
BreadcrumbBreadcrumb: typeof import('./src/components/Breadcrumb/Breadcrumb.vue')['default']
|
||||
ChartAreaChart: typeof import('./src/components/Chart/AreaChart.vue')['default']
|
||||
ChartRadialBarChart: typeof import('./src/components/Chart/RadialBarChart.vue')['default']
|
||||
ChatGPTChatGPT: typeof import('./src/components/ChatGPT/ChatGPT.vue')['default']
|
||||
CodeEditorCodeEditor: typeof import('./src/components/CodeEditor/CodeEditor.vue')['default']
|
||||
FooterToolbarFooterToolBar: typeof import('./src/components/FooterToolbar/FooterToolBar.vue')['default']
|
||||
LogoLogo: typeof import('./src/components/Logo/Logo.vue')['default']
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
"apexcharts": "^3.36.3",
|
||||
"axios": "^1.2.2",
|
||||
"dayjs": "^1.11.7",
|
||||
"highlight.js": "^11.7.0",
|
||||
"marked": "^4.2.5",
|
||||
"nprogress": "^0.2.0",
|
||||
"pinia": "^2.0.28",
|
||||
|
|
9
frontend/src/api/openai.ts
Normal file
9
frontend/src/api/openai.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
import http from '@/lib/http'
|
||||
|
||||
const openai = {
|
||||
store_record(data: any) {
|
||||
return http.post('/chat_gpt_record', data)
|
||||
}
|
||||
}
|
||||
|
||||
export default openai
|
219
frontend/src/components/ChatGPT/ChatGPT.vue
Normal file
219
frontend/src/components/ChatGPT/ChatGPT.vue
Normal file
|
@ -0,0 +1,219 @@
|
|||
<script setup lang="ts">
|
||||
import {computed, ref, watch} from 'vue'
|
||||
import {useGettext} from 'vue3-gettext'
|
||||
import {useUserStore} from '@/pinia'
|
||||
import {storeToRefs} from 'pinia'
|
||||
import {urlJoin} from '@/lib/helper'
|
||||
import {marked} from 'marked'
|
||||
import hljs from 'highlight.js'
|
||||
import 'highlight.js/styles/vs2015.css'
|
||||
import {SendOutlined} from '@ant-design/icons-vue'
|
||||
import Template from '@/views/template/Template.vue'
|
||||
import openai from '@/api/openai'
|
||||
|
||||
const {$gettext} = useGettext()
|
||||
|
||||
const props = defineProps(['content', 'path', 'history_messages'])
|
||||
|
||||
watch(computed(() => props.history_messages), () => {
|
||||
messages.value = props.history_messages
|
||||
})
|
||||
|
||||
const {current} = useGettext()
|
||||
|
||||
const messages: any = ref([])
|
||||
|
||||
const loading = ref(false)
|
||||
const ask_buffer = ref('')
|
||||
|
||||
async function send() {
|
||||
if (messages.value.length === 0) {
|
||||
messages.value.push({
|
||||
role: 'user',
|
||||
content: props.content + '\n\nCurrent Language Code: ' + current
|
||||
})
|
||||
} else {
|
||||
messages.value.push({
|
||||
role: 'user',
|
||||
content: ask_buffer.value
|
||||
})
|
||||
ask_buffer.value = ''
|
||||
}
|
||||
loading.value = true
|
||||
const t = ref({
|
||||
role: 'assistant',
|
||||
content: ''
|
||||
})
|
||||
const user = useUserStore()
|
||||
|
||||
const {token} = storeToRefs(user)
|
||||
|
||||
console.log('fetching...')
|
||||
|
||||
let res = await fetch(urlJoin(window.location.pathname, '/api/chat_gpt'), {
|
||||
method: 'POST',
|
||||
headers: {'Accept': 'text/event-stream', Authorization: token.value},
|
||||
body: JSON.stringify({messages: messages.value})
|
||||
})
|
||||
|
||||
messages.value.push(t.value)
|
||||
// read body as stream
|
||||
console.log('reading...')
|
||||
let reader = res.body!.getReader()
|
||||
|
||||
// read stream
|
||||
console.log('reading stream...')
|
||||
|
||||
let buffer = ''
|
||||
|
||||
while (true) {
|
||||
let {done, value} = await reader.read()
|
||||
if (done) {
|
||||
console.log('done')
|
||||
loading.value = false
|
||||
store_record()
|
||||
break
|
||||
}
|
||||
|
||||
apply(value)
|
||||
}
|
||||
|
||||
function apply(input: any) {
|
||||
const decoder = new TextDecoder('utf-8')
|
||||
const raw = decoder.decode(input)
|
||||
|
||||
const regex = /{"content":"(.+?)"}/g
|
||||
const matches = raw.match(regex)
|
||||
|
||||
matches?.forEach(v => {
|
||||
const content = JSON.parse(v).content
|
||||
for (let c of content) {
|
||||
buffer += c
|
||||
if (isCodeBlockComplete(buffer)) {
|
||||
t.value.content = buffer
|
||||
} else {
|
||||
t.value.content = buffer + '\n```'
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function isCodeBlockComplete(text: string) {
|
||||
const codeBlockRegex = /```/g
|
||||
const matches = text.match(codeBlockRegex)
|
||||
if (matches) {
|
||||
return matches.length % 2 === 0
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const renderer = new marked.Renderer()
|
||||
renderer.code = (code, lang: string) => {
|
||||
const language = hljs.getLanguage(lang) ? lang : 'nginx'
|
||||
const highlightedCode = hljs.highlight(code, {language}).value
|
||||
return `<pre><code class="hljs ${language}">${highlightedCode}</code></pre>`
|
||||
}
|
||||
|
||||
marked.setOptions({
|
||||
renderer: renderer,
|
||||
langPrefix: 'hljs language-', // highlight.js css expects a top-level 'hljs' class.
|
||||
pedantic: false,
|
||||
gfm: true,
|
||||
breaks: false,
|
||||
sanitize: false,
|
||||
smartypants: true,
|
||||
xhtml: false
|
||||
})
|
||||
|
||||
function store_record() {
|
||||
openai.store_record({
|
||||
file_name: props.path,
|
||||
messages: messages.value
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-card title="ChatGPT">
|
||||
<div class="chatgpt-container">
|
||||
<template v-if="messages?.length>0">
|
||||
<a-list
|
||||
class="chatgpt-log"
|
||||
item-layout="horizontal"
|
||||
:data-source="messages"
|
||||
>
|
||||
<template #renderItem="{ item }">
|
||||
<a-list-item>
|
||||
<a-comment :author="item.role" :avatar="item.avatar">
|
||||
<template #content>
|
||||
<div class="content" v-html="marked.parse(item.content)"></div>
|
||||
</template>
|
||||
</a-comment>
|
||||
</a-list-item>
|
||||
</template>
|
||||
</a-list>
|
||||
<div class="input-msg">
|
||||
<a-textarea auto-size v-model:value="ask_buffer"/>
|
||||
<div class="sned-btn">
|
||||
<a-button size="small" type="text" :loading="loading" @click="send">
|
||||
<send-outlined/>
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a-button @click="send">{{ $gettext('Chat with ChatGPT') }}</a-button>
|
||||
</template>
|
||||
</div>
|
||||
</a-card>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.chatgpt-container {
|
||||
margin: 0 auto;
|
||||
max-width: 800px;
|
||||
|
||||
.chatgpt-log {
|
||||
.content {
|
||||
width: 100%;
|
||||
|
||||
:deep(.hljs) {
|
||||
border-radius: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ant-comment-content) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:deep(.ant-comment) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:deep(.ant-comment-content-detail) {
|
||||
width: 100%;
|
||||
|
||||
p {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ant-list-item:first-child) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.input-msg {
|
||||
position: relative;
|
||||
|
||||
.sned-btn {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -10,6 +10,7 @@ import domain from '@/api/domain'
|
|||
import ngx from '@/api/ngx'
|
||||
import {message} from 'ant-design-vue'
|
||||
import config from '@/api/config'
|
||||
import ChatGPT from '@/components/ChatGPT/ChatGPT.vue'
|
||||
|
||||
|
||||
const {$gettext, interpolate} = useGettext()
|
||||
|
@ -52,6 +53,7 @@ const advance_mode = computed({
|
|||
advance_mode_ref.value = v
|
||||
}
|
||||
})
|
||||
const history_chatgpt_record = ref([])
|
||||
|
||||
function handle_response(r: any) {
|
||||
|
||||
|
@ -64,6 +66,7 @@ function handle_response(r: any) {
|
|||
configText.value = r.config
|
||||
enabled.value = r.enabled
|
||||
auto_cert.value = r.auto_cert
|
||||
history_chatgpt_record.value = r.chatgpt_messages
|
||||
Object.assign(ngx_config, r.tokenized)
|
||||
Object.assign(cert_info_map, r.cert_info)
|
||||
}
|
||||
|
@ -73,6 +76,8 @@ function init() {
|
|||
domain.get(name.value).then((r: any) => {
|
||||
handle_response(r)
|
||||
}).catch(handle_parse_error)
|
||||
} else {
|
||||
history_chatgpt_record.value = []
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -159,65 +164,71 @@ function on_change_enabled(checked: boolean) {
|
|||
}
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<a-card :bordered="false">
|
||||
<template #title>
|
||||
<span style="margin-right: 10px">{{ interpolate($gettext('Edit %{n}'), {n: name}) }}</span>
|
||||
<a-tag color="blue" v-if="enabled">
|
||||
{{ $gettext('Enabled') }}
|
||||
</a-tag>
|
||||
<a-tag color="orange" v-else>
|
||||
{{ $gettext('Disabled') }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template #extra>
|
||||
<div class="mode-switch">
|
||||
<div class="switch">
|
||||
<a-switch size="small" :disabled="parse_error_status"
|
||||
v-model:checked="advance_mode" @change="on_mode_change"/>
|
||||
<a-row :gutter="16">
|
||||
<a-col :xs="24" :sm="18" :md="16">
|
||||
<a-card :bordered="false">
|
||||
<template #title>
|
||||
<span style="margin-right: 10px">{{ interpolate($gettext('Edit %{n}'), {n: name}) }}</span>
|
||||
<a-tag color="blue" v-if="enabled">
|
||||
{{ $gettext('Enabled') }}
|
||||
</a-tag>
|
||||
<a-tag color="orange" v-else>
|
||||
{{ $gettext('Disabled') }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template #extra>
|
||||
<div class="mode-switch">
|
||||
<div class="switch">
|
||||
<a-switch size="small" :disabled="parse_error_status"
|
||||
v-model:checked="advance_mode" @change="on_mode_change"/>
|
||||
</div>
|
||||
<template v-if="advance_mode">
|
||||
<div>{{ $gettext('Advance Mode') }}</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div>{{ $gettext('Basic Mode') }}</div>
|
||||
</template>
|
||||
</div>
|
||||
<template v-if="advance_mode">
|
||||
<div>{{ $gettext('Advance Mode') }}</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div>{{ $gettext('Basic Mode') }}</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<transition name="slide-fade">
|
||||
<div v-if="advance_mode" key="advance">
|
||||
<div class="parse-error-alert-wrapper" v-if="parse_error_status">
|
||||
<a-alert :message="$gettext('Nginx Configuration Parse Error')"
|
||||
:description="parse_error_message"
|
||||
type="error"
|
||||
show-icon
|
||||
<transition name="slide-fade">
|
||||
<div v-if="advance_mode" key="advance">
|
||||
<div class="parse-error-alert-wrapper" v-if="parse_error_status">
|
||||
<a-alert :message="$gettext('Nginx Configuration Parse Error')"
|
||||
:description="parse_error_message"
|
||||
type="error"
|
||||
show-icon
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<code-editor v-model:content="configText"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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
|
||||
ref="ngx_config_editor"
|
||||
:ngx_config="ngx_config"
|
||||
:cert_info="cert_info_map"
|
||||
v-model:auto_cert="auto_cert"
|
||||
:enabled="enabled"
|
||||
@callback="save()"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<code-editor v-model:content="configText"/>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</a-card>
|
||||
</a-col>
|
||||
|
||||
<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
|
||||
ref="ngx_config_editor"
|
||||
:ngx_config="ngx_config"
|
||||
:cert_info="cert_info_map"
|
||||
v-model:auto_cert="auto_cert"
|
||||
:enabled="enabled"
|
||||
@callback="save()"
|
||||
/>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
</a-card>
|
||||
<a-col class="col-right" :xs="24" :sm="6" :md="8">
|
||||
<chat-g-p-t class="chatgpt" :content="configText" :path="ngx_config.file_name"
|
||||
:history_messages="history_chatgpt_record"/>
|
||||
</a-col>
|
||||
|
||||
<footer-tool-bar>
|
||||
<a-space>
|
||||
|
@ -229,7 +240,7 @@ function on_change_enabled(checked: boolean) {
|
|||
</a-button>
|
||||
</a-space>
|
||||
</footer-tool-bar>
|
||||
</div>
|
||||
</a-row>
|
||||
</template>
|
||||
|
||||
<style lang="less">
|
||||
|
@ -237,6 +248,15 @@ function on_change_enabled(checked: boolean) {
|
|||
</style>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.col-right {
|
||||
position: relative;
|
||||
|
||||
.chatgpt {
|
||||
position: sticky;
|
||||
top: 78px;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-card {
|
||||
margin: 10px 0;
|
||||
box-shadow: unset;
|
||||
|
|
|
@ -1912,6 +1912,11 @@ he@1.2.0, he@^1.2.0:
|
|||
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
|
||||
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
|
||||
|
||||
highlight.js@^11.7.0:
|
||||
version "11.7.0"
|
||||
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.7.0.tgz#3ff0165bc843f8c9bce1fd89e2fda9143d24b11e"
|
||||
integrity sha512-1rRqesRFhMO/PRF+G86evnyJkCgaZFOI+Z6kdj15TA18funfoqJXvgPCLSf0SWq3SRfg1j3HlDs8o4s3EGq1oQ==
|
||||
|
||||
html-minifier-terser@^6.1.0:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#bfc818934cc07918f6b3669f5774ecdfd48f32ab"
|
||||
|
|
37
go.mod
37
go.mod
|
@ -11,7 +11,7 @@ require (
|
|||
github.com/go-co-op/gocron v1.18.0
|
||||
github.com/go-playground/locales v0.14.1
|
||||
github.com/go-playground/universal-translator v0.18.1
|
||||
github.com/go-playground/validator/v10 v10.11.2
|
||||
github.com/go-playground/validator/v10 v10.12.0
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/gorilla/websocket v1.5.0
|
||||
|
@ -19,54 +19,61 @@ require (
|
|||
github.com/jpillora/overseer v1.1.6
|
||||
github.com/lib/pq v1.10.7
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/sashabaranov/go-openai v1.5.3
|
||||
github.com/shirou/gopsutil/v3 v3.23.1
|
||||
github.com/spf13/cast v1.5.0
|
||||
github.com/tufanbarisyildirim/gonginx v0.0.0-20230104065106-9ae864d29eed
|
||||
github.com/unknwon/com v1.0.1
|
||||
golang.org/x/crypto v0.6.0
|
||||
golang.org/x/crypto v0.7.0
|
||||
gopkg.in/ini.v1 v1.67.0
|
||||
gorm.io/driver/sqlite v1.4.4
|
||||
gorm.io/gorm v1.24.5
|
||||
gorm.io/gen v0.3.21
|
||||
gorm.io/gorm v1.24.6
|
||||
gorm.io/plugin/dbresolver v1.4.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/StackExchange/wmi v1.2.1 // indirect
|
||||
github.com/bytedance/sonic v1.8.2 // indirect
|
||||
github.com/bytedance/sonic v1.8.5 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.2.0 // indirect
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-jose/go-jose/v3 v3.0.0 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/goccy/go-json v0.10.0 // indirect
|
||||
github.com/go-sql-driver/mysql v1.7.0 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/jpillora/s3 v1.1.4 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
||||
github.com/leodido/go-urn v1.2.1 // indirect
|
||||
github.com/leodido/go-urn v1.2.2 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20230110061619-bbe2e5e100de // indirect
|
||||
github.com/mattn/go-isatty v0.0.17 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.16 // indirect
|
||||
github.com/miekg/dns v1.1.50 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.7 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect
|
||||
github.com/robfig/cron/v3 v3.0.1 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.11 // indirect
|
||||
github.com/tklauser/numcpus v0.6.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.10 // indirect
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
golang.org/x/arch v0.2.0 // indirect
|
||||
golang.org/x/mod v0.8.0 // indirect
|
||||
golang.org/x/net v0.7.0 // indirect
|
||||
golang.org/x/arch v0.3.0 // indirect
|
||||
golang.org/x/mod v0.9.0 // indirect
|
||||
golang.org/x/net v0.8.0 // indirect
|
||||
golang.org/x/sync v0.1.0 // indirect
|
||||
golang.org/x/sys v0.5.0 // indirect
|
||||
golang.org/x/text v0.7.0 // indirect
|
||||
golang.org/x/tools v0.6.0 // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
golang.org/x/sys v0.6.0 // indirect
|
||||
golang.org/x/text v0.8.0 // indirect
|
||||
golang.org/x/tools v0.7.0 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
gopkg.in/fsnotify.v1 v1.4.7 // indirect
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
gorm.io/datatypes v1.1.1 // indirect
|
||||
gorm.io/driver/mysql v1.4.7 // indirect
|
||||
gorm.io/hints v1.1.1 // indirect
|
||||
)
|
||||
|
|
100
go.sum
100
go.sum
|
@ -2,8 +2,8 @@ github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrU
|
|||
github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA=
|
||||
github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8=
|
||||
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
||||
github.com/bytedance/sonic v1.8.2 h1:Eq1oE3xWIBE3tj2ZtJFK1rDAx7+uA4bRytozVhXMHKY=
|
||||
github.com/bytedance/sonic v1.8.2/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
|
||||
github.com/bytedance/sonic v1.8.5 h1:kjX0/vo5acEQ/sinD/18SkA/lDDUk23F0RcaHvI7omc=
|
||||
github.com/bytedance/sonic v1.8.5/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
|
||||
github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4=
|
||||
github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
|
||||
|
@ -44,12 +44,17 @@ github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+
|
|||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
|
||||
github.com/go-playground/validator/v10 v10.11.2 h1:q3SHpufmypg+erIExEKUmsgmhDTyhcJ38oeKGACXohU=
|
||||
github.com/go-playground/validator/v10 v10.11.2/go.mod h1:NieE624vt4SCTJtD87arVLvdmjPAeV8BQlHtMnw9D7s=
|
||||
github.com/goccy/go-json v0.10.0 h1:mXKd9Qw4NuzShiRlOXKews24ufknHO7gx30lsDyokKA=
|
||||
github.com/goccy/go-json v0.10.0/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/go-playground/validator/v10 v10.12.0 h1:E4gtWgxWxp8YSxExrQFv5BpCahla0PVF2oTTEYaWQGI=
|
||||
github.com/go-playground/validator/v10 v10.12.0/go.mod h1:hCAPuzYvKdP33pxWa+2+6AIKXEKqjIUyqsNCtbsSJrA=
|
||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
|
||||
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
|
||||
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
|
@ -67,6 +72,14 @@ github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWm
|
|||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
|
||||
github.com/jackc/pgconn v1.13.0 h1:3L1XMNV2Zvca/8BYhzcRFS70Lr0WlDg16Di6SFGAbys=
|
||||
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
|
||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||
github.com/jackc/pgproto3/v2 v2.3.1 h1:nwj7qwf0S+Q7ISFfBndqeLwSwxs+4DPsbRFjECT1Y4Y=
|
||||
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg=
|
||||
github.com/jackc/pgtype v1.12.0 h1:Dlq8Qvcch7kiehm8wPGIW0W3KsCCHJnRacKW0UM8n5w=
|
||||
github.com/jackc/pgx/v4 v4.17.2 h1:0Ut0rpeKwvIVbMQ1KbMBU4h6wxehBI535LK6Flheh8E=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
|
@ -87,8 +100,8 @@ github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8t
|
|||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||
github.com/leodido/go-urn v1.2.2 h1:7z68G0FCGvDk646jz1AelTYNYWrTNm0bEcFAo147wt4=
|
||||
github.com/leodido/go-urn v1.2.2/go.mod h1:kUaIbLZWttglzwNuG0pgsh5vuV6u2YcGBYz1hIPjtOQ=
|
||||
github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
|
||||
github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||
|
@ -100,6 +113,7 @@ github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/
|
|||
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/microsoft/go-mssqldb v0.17.0 h1:Fto83dMZPnYv1Zwx5vHHxpNraeEaUlQ/hhHLgZiaenE=
|
||||
github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
|
||||
github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
|
@ -108,8 +122,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ
|
|||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU=
|
||||
github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek=
|
||||
github.com/pelletier/go-toml/v2 v2.0.7 h1:muncTPStnKRos5dpVKULv2FVd4bMOhNePj9CjgDb8Us=
|
||||
github.com/pelletier/go-toml/v2 v2.0.7/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
|
@ -119,7 +133,10 @@ github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b h1:0LFwY6Q3g
|
|||
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
|
||||
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
|
||||
github.com/rwtodd/Go.Sed v0.0.0-20210816025313-55464686f9ef/go.mod h1:8AEUvGVi2uQ5b24BIhcr0GCcpd/RNAFWaN2CJFrWIIQ=
|
||||
github.com/sashabaranov/go-openai v1.5.3 h1:o6n6dj0h9u+5mE1m+D8eT0zYhh7229o8ymDd2zDwAXU=
|
||||
github.com/sashabaranov/go-openai v1.5.3/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
|
||||
github.com/shirou/gopsutil/v3 v3.23.1 h1:a9KKO+kGLKEvcPIs4W62v0nu3sciVDOOOPUD0Hz7z/4=
|
||||
github.com/shirou/gopsutil/v3 v3.23.1/go.mod h1:NN6mnm5/0k8jw4cBfCnJtr5L7ErOTg18tMNpgFkn0hA=
|
||||
github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
|
@ -141,8 +158,9 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
|||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM=
|
||||
github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI=
|
||||
github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms=
|
||||
|
@ -153,8 +171,8 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS
|
|||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||
github.com/ugorji/go/codec v1.2.10 h1:eimT6Lsr+2lzmSZxPhLFoOWFmQqwk0fllJJ5hEbTXtQ=
|
||||
github.com/ugorji/go/codec v1.2.10/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
github.com/unknwon/com v1.0.1 h1:3d1LTxD+Lnf3soQiD4Cp/0BRB+Rsa/+RTvz8GMMzIXs=
|
||||
github.com/unknwon/com v1.0.1/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
|
@ -162,25 +180,25 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1
|
|||
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
|
||||
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/arch v0.2.0 h1:W1sUEHXiJTfjaFJ5SLo0N6lZn+0eO5gWD1MFeTGqQEY=
|
||||
golang.org/x/arch v0.2.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
|
||||
golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
|
||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=
|
||||
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -202,30 +220,30 @@ golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
|
||||
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
|
@ -237,11 +255,27 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/datatypes v1.1.1 h1:XAjO7NNfUKVUvnS3+BkqMrPXxCAcxDlpOYbjnizxNCw=
|
||||
gorm.io/datatypes v1.1.1/go.mod h1:u8GEgFjJ+GpsGfgHmBUcQqHm/937t3sj/SO9dvbndTg=
|
||||
gorm.io/driver/mysql v1.4.3/go.mod h1:sSIebwZAVPiT+27jK9HIwvsqOGKx3YMPmrA3mBJR10c=
|
||||
gorm.io/driver/mysql v1.4.7 h1:rY46lkCspzGHn7+IYsNpSfEv9tA+SU4SkkB+GFX125Y=
|
||||
gorm.io/driver/mysql v1.4.7/go.mod h1:SxzItlnT1cb6e1e4ZRpgJN2VYtcqJgqnHxWr4wsP8oc=
|
||||
gorm.io/driver/postgres v1.4.5 h1:mTeXTTtHAgnS9PgmhN2YeUbazYpLhUI1doLnw42XUZc=
|
||||
gorm.io/driver/sqlite v1.4.2/go.mod h1:0Aq3iPO+v9ZKbcdiz8gLWRw5VOPcBOPUQJFLq5e2ecI=
|
||||
gorm.io/driver/sqlite v1.4.4 h1:gIufGoR0dQzjkyqDyYSCvsYR6fba1Gw5YKDqKeChxFc=
|
||||
gorm.io/driver/sqlite v1.4.4/go.mod h1:0Aq3iPO+v9ZKbcdiz8gLWRw5VOPcBOPUQJFLq5e2ecI=
|
||||
gorm.io/driver/sqlserver v1.4.1 h1:t4r4r6Jam5E6ejqP7N82qAJIJAht27EGT41HyPfXRw0=
|
||||
gorm.io/gen v0.3.21 h1:t8329wT4tW1ZZWOm7vn4LV6OIrz8a5zCg+p78ezt+rA=
|
||||
gorm.io/gen v0.3.21/go.mod h1:aWgvoKdG9f8Des4TegSa0N5a+gwhGsFo0JJMaLwokvk=
|
||||
gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
|
||||
gorm.io/gorm v1.24.0/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
||||
gorm.io/gorm v1.24.5 h1:g6OPREKqqlWq4kh/3MCQbZKImeB9e6Xgc4zD+JgNZGE=
|
||||
gorm.io/gorm v1.24.5/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
||||
gorm.io/gorm v1.24.3/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
||||
gorm.io/gorm v1.24.6 h1:wy98aq9oFEetsc4CAbKD2SoBCdMzsbSIvSUUFJuHi5s=
|
||||
gorm.io/gorm v1.24.6/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||
gorm.io/hints v1.1.1 h1:NPampLxQujY+277452rt4yqtg6JmzNZ1jA2olk0eFXw=
|
||||
gorm.io/hints v1.1.1/go.mod h1:zdwzfFqvBWGbpuKiAhLFOSGSpeD3/VsRgkXR9Y7Z3cs=
|
||||
gorm.io/plugin/dbresolver v1.4.1 h1:Ug4LcoPhrvqq71UhxtF346f+skTYoCa/nEsdjvHwEzk=
|
||||
gorm.io/plugin/dbresolver v1.4.1/go.mod h1:CTbCtMWhsjXSiJqiW2R8POvJ2cq18RVOl4WGyT5nhNc=
|
||||
gotest.tools/v3 v3.2.0 h1:I0DwBVMGAx26dttAj1BtJLAkVGncrkkUXfJLC4Flt/I=
|
||||
gotest.tools/v3 v3.2.0/go.mod h1:Mcr9QNxkg0uMvy/YElmo4SpXgJKWgQvYrT7Kw5RzJ1A=
|
||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||
|
|
4
main.go
4
main.go
|
@ -7,6 +7,7 @@ import (
|
|||
"github.com/0xJacky/Nginx-UI/server/model"
|
||||
"github.com/0xJacky/Nginx-UI/server/pkg/cert"
|
||||
"github.com/0xJacky/Nginx-UI/server/pkg/nginx"
|
||||
"github.com/0xJacky/Nginx-UI/server/query"
|
||||
"github.com/0xJacky/Nginx-UI/server/router"
|
||||
"github.com/0xJacky/Nginx-UI/server/service"
|
||||
"github.com/0xJacky/Nginx-UI/server/settings"
|
||||
|
@ -50,7 +51,8 @@ func prog(state overseer.State) {
|
|||
|
||||
log.Printf("Nginx config dir path: %s", nginx.GetConfPath())
|
||||
if "" != settings.ServerSettings.JwtSecret {
|
||||
model.Init()
|
||||
db := model.Init()
|
||||
query.Init(db)
|
||||
}
|
||||
|
||||
s := gocron.NewScheduler(time.UTC)
|
||||
|
|
|
@ -3,6 +3,7 @@ package api
|
|||
import (
|
||||
"github.com/0xJacky/Nginx-UI/server/pkg/config_list"
|
||||
"github.com/0xJacky/Nginx-UI/server/pkg/nginx"
|
||||
"github.com/0xJacky/Nginx-UI/server/query"
|
||||
"github.com/gin-gonic/gin"
|
||||
"log"
|
||||
"net/http"
|
||||
|
@ -84,8 +85,17 @@ func GetConfig(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
g := query.ChatGPTLog
|
||||
chatgpt, err := g.Where(g.Name.Eq(path)).FirstOrCreate()
|
||||
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"config": string(content),
|
||||
"config": string(content),
|
||||
"chatgpt_messages": chatgpt.Content,
|
||||
})
|
||||
|
||||
}
|
||||
|
|
|
@ -1,440 +1,450 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"github.com/0xJacky/Nginx-UI/server/model"
|
||||
"github.com/0xJacky/Nginx-UI/server/pkg/cert"
|
||||
"github.com/0xJacky/Nginx-UI/server/pkg/config_list"
|
||||
"github.com/0xJacky/Nginx-UI/server/pkg/helper"
|
||||
"github.com/0xJacky/Nginx-UI/server/pkg/nginx"
|
||||
"github.com/gin-gonic/gin"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
"github.com/0xJacky/Nginx-UI/server/model"
|
||||
"github.com/0xJacky/Nginx-UI/server/pkg/cert"
|
||||
"github.com/0xJacky/Nginx-UI/server/pkg/config_list"
|
||||
"github.com/0xJacky/Nginx-UI/server/pkg/helper"
|
||||
"github.com/0xJacky/Nginx-UI/server/pkg/nginx"
|
||||
"github.com/0xJacky/Nginx-UI/server/query"
|
||||
"github.com/gin-gonic/gin"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func GetDomains(c *gin.Context) {
|
||||
name := c.Query("name")
|
||||
orderBy := c.Query("order_by")
|
||||
sort := c.DefaultQuery("sort", "desc")
|
||||
name := c.Query("name")
|
||||
orderBy := c.Query("order_by")
|
||||
sort := c.DefaultQuery("sort", "desc")
|
||||
|
||||
mySort := map[string]string{
|
||||
"enabled": "bool",
|
||||
"name": "string",
|
||||
"modify": "time",
|
||||
}
|
||||
mySort := map[string]string{
|
||||
"enabled": "bool",
|
||||
"name": "string",
|
||||
"modify": "time",
|
||||
}
|
||||
|
||||
configFiles, err := os.ReadDir(nginx.GetConfPath("sites-available"))
|
||||
configFiles, err := os.ReadDir(nginx.GetConfPath("sites-available"))
|
||||
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
enabledConfig, err := os.ReadDir(nginx.GetConfPath("sites-enabled"))
|
||||
enabledConfig, err := os.ReadDir(nginx.GetConfPath("sites-enabled"))
|
||||
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
enabledConfigMap := make(map[string]bool)
|
||||
for i := range enabledConfig {
|
||||
enabledConfigMap[enabledConfig[i].Name()] = true
|
||||
}
|
||||
enabledConfigMap := make(map[string]bool)
|
||||
for i := range enabledConfig {
|
||||
enabledConfigMap[enabledConfig[i].Name()] = true
|
||||
}
|
||||
|
||||
var configs []gin.H
|
||||
var configs []gin.H
|
||||
|
||||
for i := range configFiles {
|
||||
file := configFiles[i]
|
||||
fileInfo, _ := file.Info()
|
||||
if !file.IsDir() {
|
||||
if name != "" && !strings.Contains(file.Name(), name) {
|
||||
continue
|
||||
}
|
||||
configs = append(configs, gin.H{
|
||||
"name": file.Name(),
|
||||
"size": fileInfo.Size(),
|
||||
"modify": fileInfo.ModTime(),
|
||||
"enabled": enabledConfigMap[file.Name()],
|
||||
})
|
||||
}
|
||||
}
|
||||
for i := range configFiles {
|
||||
file := configFiles[i]
|
||||
fileInfo, _ := file.Info()
|
||||
if !file.IsDir() {
|
||||
if name != "" && !strings.Contains(file.Name(), name) {
|
||||
continue
|
||||
}
|
||||
configs = append(configs, gin.H{
|
||||
"name": file.Name(),
|
||||
"size": fileInfo.Size(),
|
||||
"modify": fileInfo.ModTime(),
|
||||
"enabled": enabledConfigMap[file.Name()],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
configs = config_list.Sort(orderBy, sort, mySort[orderBy], configs)
|
||||
configs = config_list.Sort(orderBy, sort, mySort[orderBy], configs)
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"data": configs,
|
||||
})
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"data": configs,
|
||||
})
|
||||
}
|
||||
|
||||
type CertificateInfo struct {
|
||||
SubjectName string `json:"subject_name"`
|
||||
IssuerName string `json:"issuer_name"`
|
||||
NotAfter time.Time `json:"not_after"`
|
||||
NotBefore time.Time `json:"not_before"`
|
||||
SubjectName string `json:"subject_name"`
|
||||
IssuerName string `json:"issuer_name"`
|
||||
NotAfter time.Time `json:"not_after"`
|
||||
NotBefore time.Time `json:"not_before"`
|
||||
}
|
||||
|
||||
func GetDomain(c *gin.Context) {
|
||||
rewriteName, ok := c.Get("rewriteConfigFileName")
|
||||
rewriteName, ok := c.Get("rewriteConfigFileName")
|
||||
|
||||
name := c.Param("name")
|
||||
name := c.Param("name")
|
||||
|
||||
// for modify filename
|
||||
if ok {
|
||||
name = rewriteName.(string)
|
||||
}
|
||||
// for modify filename
|
||||
if ok {
|
||||
name = rewriteName.(string)
|
||||
}
|
||||
|
||||
path := nginx.GetConfPath("sites-available", name)
|
||||
path := nginx.GetConfPath("sites-available", name)
|
||||
|
||||
enabled := true
|
||||
if _, err := os.Stat(nginx.GetConfPath("sites-enabled", name)); os.IsNotExist(err) {
|
||||
enabled = false
|
||||
}
|
||||
enabled := true
|
||||
if _, err := os.Stat(nginx.GetConfPath("sites-enabled", name)); os.IsNotExist(err) {
|
||||
enabled = false
|
||||
}
|
||||
|
||||
c.Set("maybe_error", "nginx_config_syntax_error")
|
||||
config, err := nginx.ParseNgxConfig(path)
|
||||
c.Set("maybe_error", "nginx_config_syntax_error")
|
||||
config, err := nginx.ParseNgxConfig(path)
|
||||
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.Set("maybe_error", "")
|
||||
c.Set("maybe_error", "")
|
||||
|
||||
certInfoMap := make(map[int]CertificateInfo)
|
||||
for serverIdx, server := range config.Servers {
|
||||
for _, directive := range server.Directives {
|
||||
if directive.Directive == "ssl_certificate" {
|
||||
certInfoMap := make(map[int]CertificateInfo)
|
||||
for serverIdx, server := range config.Servers {
|
||||
for _, directive := range server.Directives {
|
||||
if directive.Directive == "ssl_certificate" {
|
||||
|
||||
pubKey, err := cert.GetCertInfo(directive.Params)
|
||||
pubKey, err := cert.GetCertInfo(directive.Params)
|
||||
|
||||
if err != nil {
|
||||
log.Println("Failed to get certificate information", err)
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
log.Println("Failed to get certificate information", err)
|
||||
break
|
||||
}
|
||||
|
||||
certInfoMap[serverIdx] = CertificateInfo{
|
||||
SubjectName: pubKey.Subject.CommonName,
|
||||
IssuerName: pubKey.Issuer.CommonName,
|
||||
NotAfter: pubKey.NotAfter,
|
||||
NotBefore: pubKey.NotBefore,
|
||||
}
|
||||
certInfoMap[serverIdx] = CertificateInfo{
|
||||
SubjectName: pubKey.Subject.CommonName,
|
||||
IssuerName: pubKey.Issuer.CommonName,
|
||||
NotAfter: pubKey.NotAfter,
|
||||
NotBefore: pubKey.NotBefore,
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
certModel, _ := model.FirstCert(name)
|
||||
certModel, _ := model.FirstCert(name)
|
||||
|
||||
c.Set("maybe_error", "nginx_config_syntax_error")
|
||||
g := query.ChatGPTLog
|
||||
chatgpt, err := g.Where(g.Name.Eq(path)).FirstOrCreate()
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"enabled": enabled,
|
||||
"name": name,
|
||||
"config": config.FmtCode(),
|
||||
"tokenized": config,
|
||||
"auto_cert": certModel.AutoCert == model.AutoCertEnabled,
|
||||
"cert_info": certInfoMap,
|
||||
})
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.Set("maybe_error", "nginx_config_syntax_error")
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"enabled": enabled,
|
||||
"name": name,
|
||||
"config": config.FmtCode(),
|
||||
"tokenized": config,
|
||||
"auto_cert": certModel.AutoCert == model.AutoCertEnabled,
|
||||
"cert_info": certInfoMap,
|
||||
"chatgpt_messages": chatgpt.Content,
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func SaveDomain(c *gin.Context) {
|
||||
name := c.Param("name")
|
||||
name := c.Param("name")
|
||||
|
||||
if name == "" {
|
||||
c.JSON(http.StatusNotAcceptable, gin.H{
|
||||
"message": "param name is empty",
|
||||
})
|
||||
return
|
||||
}
|
||||
if name == "" {
|
||||
c.JSON(http.StatusNotAcceptable, gin.H{
|
||||
"message": "param name is empty",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
var json struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
Content string `json:"content" binding:"required"`
|
||||
Overwrite bool `json:"overwrite"`
|
||||
}
|
||||
var json struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
Content string `json:"content" binding:"required"`
|
||||
Overwrite bool `json:"overwrite"`
|
||||
}
|
||||
|
||||
if !BindAndValid(c, &json) {
|
||||
return
|
||||
}
|
||||
if !BindAndValid(c, &json) {
|
||||
return
|
||||
}
|
||||
|
||||
path := nginx.GetConfPath("sites-available", name)
|
||||
path := nginx.GetConfPath("sites-available", name)
|
||||
|
||||
if !json.Overwrite && helper.FileExists(path) {
|
||||
c.JSON(http.StatusNotAcceptable, gin.H{
|
||||
"message": "File exists",
|
||||
})
|
||||
return
|
||||
}
|
||||
if !json.Overwrite && helper.FileExists(path) {
|
||||
c.JSON(http.StatusNotAcceptable, gin.H{
|
||||
"message": "File exists",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
err := os.WriteFile(path, []byte(json.Content), 0644)
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
enabledConfigFilePath := nginx.GetConfPath("sites-enabled", name)
|
||||
// rename the config file if needed
|
||||
if name != json.Name {
|
||||
newPath := nginx.GetConfPath("sites-available", json.Name)
|
||||
// check if dst file exists, do not rename
|
||||
if helper.FileExists(newPath) {
|
||||
c.JSON(http.StatusNotAcceptable, gin.H{
|
||||
"message": "File exists",
|
||||
})
|
||||
return
|
||||
}
|
||||
// recreate soft link
|
||||
if helper.FileExists(enabledConfigFilePath) {
|
||||
_ = os.Remove(enabledConfigFilePath)
|
||||
enabledConfigFilePath = nginx.GetConfPath("sites-enabled", json.Name)
|
||||
err = os.Symlink(newPath, enabledConfigFilePath)
|
||||
err := os.WriteFile(path, []byte(json.Content), 0644)
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
enabledConfigFilePath := nginx.GetConfPath("sites-enabled", name)
|
||||
// rename the config file if needed
|
||||
if name != json.Name {
|
||||
newPath := nginx.GetConfPath("sites-available", json.Name)
|
||||
// check if dst file exists, do not rename
|
||||
if helper.FileExists(newPath) {
|
||||
c.JSON(http.StatusNotAcceptable, gin.H{
|
||||
"message": "File exists",
|
||||
})
|
||||
return
|
||||
}
|
||||
// recreate soft link
|
||||
if helper.FileExists(enabledConfigFilePath) {
|
||||
_ = os.Remove(enabledConfigFilePath)
|
||||
enabledConfigFilePath = nginx.GetConfPath("sites-enabled", json.Name)
|
||||
err = os.Symlink(newPath, enabledConfigFilePath)
|
||||
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
err = os.Rename(path, newPath)
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
err = os.Rename(path, newPath)
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
name = json.Name
|
||||
c.Set("rewriteConfigFileName", name)
|
||||
}
|
||||
name = json.Name
|
||||
c.Set("rewriteConfigFileName", name)
|
||||
}
|
||||
|
||||
enabledConfigFilePath = nginx.GetConfPath("sites-enabled", name)
|
||||
if helper.FileExists(enabledConfigFilePath) {
|
||||
// Test nginx configuration
|
||||
output := nginx.TestConf()
|
||||
if nginx.GetLogLevel(output) >= nginx.Warn {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"message": output,
|
||||
"error": "nginx_config_syntax_error",
|
||||
})
|
||||
return
|
||||
}
|
||||
enabledConfigFilePath = nginx.GetConfPath("sites-enabled", name)
|
||||
if helper.FileExists(enabledConfigFilePath) {
|
||||
// Test nginx configuration
|
||||
output := nginx.TestConf()
|
||||
if nginx.GetLogLevel(output) >= nginx.Warn {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"message": output,
|
||||
"error": "nginx_config_syntax_error",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
output = nginx.Reload()
|
||||
output = nginx.Reload()
|
||||
|
||||
if nginx.GetLogLevel(output) >= nginx.Warn {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"message": output,
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
if nginx.GetLogLevel(output) >= nginx.Warn {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"message": output,
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
GetDomain(c)
|
||||
GetDomain(c)
|
||||
}
|
||||
|
||||
func EnableDomain(c *gin.Context) {
|
||||
configFilePath := nginx.GetConfPath("sites-available", c.Param("name"))
|
||||
enabledConfigFilePath := nginx.GetConfPath("sites-enabled", c.Param("name"))
|
||||
configFilePath := nginx.GetConfPath("sites-available", c.Param("name"))
|
||||
enabledConfigFilePath := nginx.GetConfPath("sites-enabled", c.Param("name"))
|
||||
|
||||
_, err := os.Stat(configFilePath)
|
||||
_, err := os.Stat(configFilePath)
|
||||
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
if _, err = os.Stat(enabledConfigFilePath); os.IsNotExist(err) {
|
||||
err = os.Symlink(configFilePath, enabledConfigFilePath)
|
||||
if _, err = os.Stat(enabledConfigFilePath); os.IsNotExist(err) {
|
||||
err = os.Symlink(configFilePath, enabledConfigFilePath)
|
||||
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Test nginx config, if not pass then disable the site.
|
||||
output := nginx.TestConf()
|
||||
// Test nginx config, if not pass then disable the site.
|
||||
output := nginx.TestConf()
|
||||
|
||||
if nginx.GetLogLevel(output) >= nginx.Warn {
|
||||
_ = os.Remove(enabledConfigFilePath)
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"message": output,
|
||||
})
|
||||
return
|
||||
}
|
||||
if nginx.GetLogLevel(output) >= nginx.Warn {
|
||||
_ = os.Remove(enabledConfigFilePath)
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"message": output,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
output = nginx.Reload()
|
||||
output = nginx.Reload()
|
||||
|
||||
if nginx.GetLogLevel(output) >= nginx.Warn {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"message": output,
|
||||
})
|
||||
return
|
||||
}
|
||||
if nginx.GetLogLevel(output) >= nginx.Warn {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"message": output,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "ok",
|
||||
})
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "ok",
|
||||
})
|
||||
}
|
||||
|
||||
func DisableDomain(c *gin.Context) {
|
||||
enabledConfigFilePath := nginx.GetConfPath("sites-enabled", c.Param("name"))
|
||||
enabledConfigFilePath := nginx.GetConfPath("sites-enabled", c.Param("name"))
|
||||
|
||||
_, err := os.Stat(enabledConfigFilePath)
|
||||
_, err := os.Stat(enabledConfigFilePath)
|
||||
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
err = os.Remove(enabledConfigFilePath)
|
||||
err = os.Remove(enabledConfigFilePath)
|
||||
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
// delete auto cert record
|
||||
certModel := model.Cert{Filename: c.Param("name")}
|
||||
err = certModel.Remove()
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
// delete auto cert record
|
||||
certModel := model.Cert{Filename: c.Param("name")}
|
||||
err = certModel.Remove()
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
output := nginx.Reload()
|
||||
output := nginx.Reload()
|
||||
|
||||
if nginx.GetLogLevel(output) >= nginx.Warn {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"message": output,
|
||||
})
|
||||
return
|
||||
}
|
||||
if nginx.GetLogLevel(output) >= nginx.Warn {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"message": output,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "ok",
|
||||
})
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "ok",
|
||||
})
|
||||
}
|
||||
|
||||
func DeleteDomain(c *gin.Context) {
|
||||
var err error
|
||||
name := c.Param("name")
|
||||
availablePath := nginx.GetConfPath("sites-available", name)
|
||||
enabledPath := nginx.GetConfPath("sites-enabled", name)
|
||||
var err error
|
||||
name := c.Param("name")
|
||||
availablePath := nginx.GetConfPath("sites-available", name)
|
||||
enabledPath := nginx.GetConfPath("sites-enabled", name)
|
||||
|
||||
if _, err = os.Stat(availablePath); os.IsNotExist(err) {
|
||||
c.JSON(http.StatusNotFound, gin.H{
|
||||
"message": "site not found",
|
||||
})
|
||||
return
|
||||
}
|
||||
if _, err = os.Stat(availablePath); os.IsNotExist(err) {
|
||||
c.JSON(http.StatusNotFound, gin.H{
|
||||
"message": "site not found",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if _, err = os.Stat(enabledPath); err == nil {
|
||||
c.JSON(http.StatusNotAcceptable, gin.H{
|
||||
"message": "site is enabled",
|
||||
})
|
||||
return
|
||||
}
|
||||
if _, err = os.Stat(enabledPath); err == nil {
|
||||
c.JSON(http.StatusNotAcceptable, gin.H{
|
||||
"message": "site is enabled",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
certModel := model.Cert{Filename: name}
|
||||
_ = certModel.Remove()
|
||||
certModel := model.Cert{Filename: name}
|
||||
_ = certModel.Remove()
|
||||
|
||||
err = os.Remove(availablePath)
|
||||
err = os.Remove(availablePath)
|
||||
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "ok",
|
||||
})
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "ok",
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func AddDomainToAutoCert(c *gin.Context) {
|
||||
name := c.Param("name")
|
||||
name := c.Param("name")
|
||||
|
||||
var json struct {
|
||||
Domains []string `json:"domains"`
|
||||
}
|
||||
var json struct {
|
||||
Domains []string `json:"domains"`
|
||||
}
|
||||
|
||||
if !BindAndValid(c, &json) {
|
||||
return
|
||||
}
|
||||
if !BindAndValid(c, &json) {
|
||||
return
|
||||
}
|
||||
|
||||
certModel, err := model.FirstOrCreateCert(name)
|
||||
certModel, err := model.FirstOrCreateCert(name)
|
||||
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
err = certModel.Updates(&model.Cert{
|
||||
Name: name,
|
||||
Domains: json.Domains,
|
||||
AutoCert: model.AutoCertEnabled,
|
||||
})
|
||||
err = certModel.Updates(&model.Cert{
|
||||
Name: name,
|
||||
Domains: json.Domains,
|
||||
AutoCert: model.AutoCertEnabled,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, certModel)
|
||||
c.JSON(http.StatusOK, certModel)
|
||||
}
|
||||
|
||||
func RemoveDomainFromAutoCert(c *gin.Context) {
|
||||
name := c.Param("name")
|
||||
certModel, err := model.FirstCert(name)
|
||||
name := c.Param("name")
|
||||
certModel, err := model.FirstCert(name)
|
||||
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
err = certModel.Updates(&model.Cert{
|
||||
AutoCert: model.AutoCertDisabled,
|
||||
})
|
||||
err = certModel.Updates(&model.Cert{
|
||||
AutoCert: model.AutoCertDisabled,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, nil)
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, nil)
|
||||
}
|
||||
|
||||
func DuplicateSite(c *gin.Context) {
|
||||
name := c.Param("name")
|
||||
name := c.Param("name")
|
||||
|
||||
var json struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
}
|
||||
var json struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
}
|
||||
|
||||
if !BindAndValid(c, &json) {
|
||||
return
|
||||
}
|
||||
if !BindAndValid(c, &json) {
|
||||
return
|
||||
}
|
||||
|
||||
src := nginx.GetConfPath("sites-available", name)
|
||||
dst := nginx.GetConfPath("sites-available", json.Name)
|
||||
src := nginx.GetConfPath("sites-available", name)
|
||||
dst := nginx.GetConfPath("sites-available", json.Name)
|
||||
|
||||
if helper.FileExists(dst) {
|
||||
c.JSON(http.StatusNotAcceptable, gin.H{
|
||||
"message": "File exists",
|
||||
})
|
||||
return
|
||||
}
|
||||
if helper.FileExists(dst) {
|
||||
c.JSON(http.StatusNotAcceptable, gin.H{
|
||||
"message": "File exists",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
_, err := helper.CopyFile(src, dst)
|
||||
_, err := helper.CopyFile(src, dst)
|
||||
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"dst": dst,
|
||||
})
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"dst": dst,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package api
|
|||
|
||||
import (
|
||||
"github.com/0xJacky/Nginx-UI/server/model"
|
||||
"github.com/0xJacky/Nginx-UI/server/query"
|
||||
"github.com/0xJacky/Nginx-UI/server/settings"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
|
@ -54,7 +55,8 @@ func InstallNginxUI(c *gin.Context) {
|
|||
}
|
||||
|
||||
// Init model
|
||||
model.Init()
|
||||
db := model.Init()
|
||||
query.Init(db)
|
||||
|
||||
curd := model.NewCurd(&model.Auth{})
|
||||
pwd, _ := bcrypt.GenerateFromPassword([]byte(json.Password), bcrypt.DefaultCost)
|
||||
|
@ -70,5 +72,4 @@ func InstallNginxUI(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "ok",
|
||||
})
|
||||
|
||||
}
|
||||
|
|
160
server/api/openai.go
Normal file
160
server/api/openai.go
Normal file
|
@ -0,0 +1,160 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/0xJacky/Nginx-UI/server/model"
|
||||
"github.com/0xJacky/Nginx-UI/server/query"
|
||||
"github.com/0xJacky/Nginx-UI/server/settings"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sashabaranov/go-openai"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
)
|
||||
|
||||
const ChatGPTInitPrompt = "You are a assistant who can help users write and optimise the configurations of Nginx, the first user message contains the content of the configuration file which is currently opened by the user and the current language code(CLC). You suppose to use the language corresponding to the CLC to give the first reply. Later the language environment depends on the user message. The first reply should involve the key information of the file and ask user what can you help them."
|
||||
|
||||
func MakeChatCompletionRequest(c *gin.Context) {
|
||||
var json struct {
|
||||
Messages []openai.ChatCompletionMessage `json:"messages"`
|
||||
}
|
||||
|
||||
if !BindAndValid(c, &json) {
|
||||
return
|
||||
}
|
||||
|
||||
messages := []openai.ChatCompletionMessage{
|
||||
{
|
||||
Role: openai.ChatMessageRoleSystem,
|
||||
Content: ChatGPTInitPrompt,
|
||||
},
|
||||
}
|
||||
messages = append(messages, json.Messages...)
|
||||
// sse server
|
||||
c.Writer.Header().Set("Content-Type", "text/event-stream")
|
||||
c.Writer.Header().Set("Cache-Control", "no-cache")
|
||||
c.Writer.Header().Set("Connection", "keep-alive")
|
||||
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
log.Println(settings.OpenAISettings.Token)
|
||||
|
||||
config := openai.DefaultConfig(settings.OpenAISettings.Token)
|
||||
|
||||
if settings.OpenAISettings.Proxy != "" {
|
||||
proxyUrl, err := url.Parse(settings.OpenAISettings.Proxy)
|
||||
if err != nil {
|
||||
c.Stream(func(w io.Writer) bool {
|
||||
c.SSEvent("message", gin.H{
|
||||
"type": "error",
|
||||
"content": err.Error(),
|
||||
})
|
||||
return false
|
||||
})
|
||||
return
|
||||
}
|
||||
transport := &http.Transport{
|
||||
Proxy: http.ProxyURL(proxyUrl),
|
||||
}
|
||||
config.HTTPClient = &http.Client{
|
||||
Transport: transport,
|
||||
}
|
||||
}
|
||||
|
||||
if settings.OpenAISettings.BaseUrl != "" {
|
||||
config.BaseURL = settings.OpenAISettings.BaseUrl
|
||||
}
|
||||
|
||||
openaiClient := openai.NewClientWithConfig(config)
|
||||
ctx := context.Background()
|
||||
|
||||
req := openai.ChatCompletionRequest{
|
||||
Model: openai.GPT3Dot5Turbo0301,
|
||||
Messages: messages,
|
||||
Stream: true,
|
||||
}
|
||||
stream, err := openaiClient.CreateChatCompletionStream(ctx, req)
|
||||
if err != nil {
|
||||
fmt.Printf("CompletionStream error: %v\n", err)
|
||||
c.Stream(func(w io.Writer) bool {
|
||||
c.SSEvent("message", gin.H{
|
||||
"type": "error",
|
||||
"content": err.Error(),
|
||||
})
|
||||
return false
|
||||
})
|
||||
return
|
||||
}
|
||||
defer stream.Close()
|
||||
msgChan := make(chan string)
|
||||
go func() {
|
||||
for {
|
||||
response, err := stream.Recv()
|
||||
if errors.Is(err, io.EOF) {
|
||||
close(msgChan)
|
||||
fmt.Println()
|
||||
return
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("Stream error: %v\n", err)
|
||||
close(msgChan)
|
||||
return
|
||||
}
|
||||
|
||||
// Send SSE to client
|
||||
message := fmt.Sprintf("%s", response.Choices[0].Delta.Content)
|
||||
fmt.Printf("%s", response.Choices[0].Delta.Content)
|
||||
_ = os.Stdout.Sync()
|
||||
|
||||
msgChan <- message
|
||||
}
|
||||
}()
|
||||
|
||||
c.Stream(func(w io.Writer) bool {
|
||||
if m, ok := <-msgChan; ok {
|
||||
c.SSEvent("message", gin.H{
|
||||
"type": "message",
|
||||
"content": m,
|
||||
})
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
}
|
||||
|
||||
func StoreChatGPTRecord(c *gin.Context) {
|
||||
var json struct {
|
||||
FileName string `json:"file_name"`
|
||||
Messages []openai.ChatCompletionMessage `json:"messages"`
|
||||
}
|
||||
|
||||
if !BindAndValid(c, &json) {
|
||||
return
|
||||
}
|
||||
|
||||
name := json.FileName
|
||||
g := query.ChatGPTLog
|
||||
_, err := g.Where(g.Name.Eq(name)).FirstOrCreate()
|
||||
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
_, err = g.Where(g.Name.Eq(name)).Updates(&model.ChatGPTLog{
|
||||
Name: name,
|
||||
Content: json.Messages,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "ok",
|
||||
})
|
||||
}
|
67
server/cmd/generate/generate.go
Normal file
67
server/cmd/generate/generate.go
Normal file
|
@ -0,0 +1,67 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"github.com/0xJacky/Nginx-UI/server/model"
|
||||
"github.com/0xJacky/Nginx-UI/server/settings"
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gen"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
"log"
|
||||
"path"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// specify the output directory (default: "./query")
|
||||
// ### if you want to query without context constrain, set mode gen.WithoutContext ###
|
||||
g := gen.NewGenerator(gen.Config{
|
||||
OutPath: "../../query",
|
||||
Mode: gen.WithoutContext | gen.WithDefaultQuery,
|
||||
//if you want the nullable field generation property to be pointer type, set FieldNullable true
|
||||
FieldNullable: true,
|
||||
//if you want to assign field which has default value in `Create` API, set FieldCoverable true, reference: https://gorm.io/docs/create.html#Default-Values
|
||||
FieldCoverable: true,
|
||||
// if you want to generate field with unsigned integer type, set FieldSignable true
|
||||
/* FieldSignable: true,*/
|
||||
//if you want to generate index tags from database, set FieldWithIndexTag true
|
||||
/* FieldWithIndexTag: true,*/
|
||||
//if you want to generate type tags from database, set FieldWithTypeTag true
|
||||
/* FieldWithTypeTag: true,*/
|
||||
//if you need unit tests for query code, set WithUnitTest true
|
||||
/* WithUnitTest: true, */
|
||||
})
|
||||
|
||||
// reuse the database connection in Project or create a connection here
|
||||
// if you want to use GenerateModel/GenerateModelAs, UseDB is necessary or it will panic
|
||||
var confPath string
|
||||
flag.StringVar(&confPath, "config", "app.ini", "Specify the configuration file")
|
||||
flag.Parse()
|
||||
|
||||
settings.Init(confPath)
|
||||
dbPath := path.Join(path.Dir(settings.ConfPath), fmt.Sprintf("%s.db", settings.ServerSettings.Database))
|
||||
|
||||
var err error
|
||||
db, err := gorm.Open(sqlite.Open(dbPath), &gorm.Config{
|
||||
Logger: logger.Default.LogMode(logger.Info),
|
||||
PrepareStmt: true,
|
||||
DisableForeignKeyConstraintWhenMigrating: true,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
g.UseDB(db)
|
||||
|
||||
// apply basic crud api on structs or table models which is specified by table name with function
|
||||
// GenerateModel/GenerateModelAs. And generator will generate table models' code when calling Excute.
|
||||
g.ApplyBasic(model.GenerateAllModel()...)
|
||||
|
||||
// apply diy interfaces on structs or table models
|
||||
g.ApplyInterface(func(method model.Method) {}, model.GenerateAllModel()...)
|
||||
|
||||
// execute the action of code generation
|
||||
g.Execute()
|
||||
}
|
34
server/model/chatgpt_log.go
Normal file
34
server/model/chatgpt_log.go
Normal file
|
@ -0,0 +1,34 @@
|
|||
package model
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sashabaranov/go-openai"
|
||||
)
|
||||
|
||||
type JSON []openai.ChatCompletionMessage
|
||||
|
||||
// Scan scan value into Jsonb, implements sql.Scanner interface
|
||||
func (j *JSON) Scan(value interface{}) error {
|
||||
bytes, ok := value.([]byte)
|
||||
if !ok {
|
||||
return errors.New(fmt.Sprint("Failed to unmarshal JSONB value:", value))
|
||||
}
|
||||
|
||||
var result []openai.ChatCompletionMessage
|
||||
err := json.Unmarshal(bytes, &result)
|
||||
*j = result
|
||||
return err
|
||||
}
|
||||
|
||||
// Value return json value, implement driver.Valuer interface
|
||||
func (j *JSON) Value() (driver.Value, error) {
|
||||
return json.Marshal(*j)
|
||||
}
|
||||
|
||||
type ChatGPTLog struct {
|
||||
Name string `json:"name"`
|
||||
Content JSON `json:"content" gorm:"serializer:json"`
|
||||
}
|
|
@ -6,6 +6,7 @@ import (
|
|||
"github.com/gin-gonic/gin"
|
||||
"github.com/spf13/cast"
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gen"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
"log"
|
||||
|
@ -22,28 +23,37 @@ type Model struct {
|
|||
DeletedAt *time.Time `gorm:"index" json:"deleted_at"`
|
||||
}
|
||||
|
||||
func Init() {
|
||||
func GenerateAllModel() []any {
|
||||
return []any{
|
||||
ConfigBackup{},
|
||||
Auth{},
|
||||
AuthToken{},
|
||||
Cert{},
|
||||
ChatGPTLog{},
|
||||
}
|
||||
}
|
||||
|
||||
func Init() *gorm.DB {
|
||||
dbPath := path.Join(path.Dir(settings.ConfPath), fmt.Sprintf("%s.db", settings.ServerSettings.Database))
|
||||
|
||||
var err error
|
||||
db, err = gorm.Open(sqlite.Open(dbPath), &gorm.Config{
|
||||
Logger: logger.Default.LogMode(logger.Info),
|
||||
PrepareStmt: true,
|
||||
Logger: logger.Default.LogMode(logger.Info),
|
||||
PrepareStmt: true,
|
||||
DisableForeignKeyConstraintWhenMigrating: true,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
// Migrate the schema
|
||||
AutoMigrate(&ConfigBackup{})
|
||||
AutoMigrate(&Auth{})
|
||||
AutoMigrate(&AuthToken{})
|
||||
AutoMigrate(&Cert{})
|
||||
}
|
||||
|
||||
func AutoMigrate(model interface{}) {
|
||||
err := db.AutoMigrate(model)
|
||||
// Migrate the schema
|
||||
err = db.AutoMigrate(GenerateAllModel()...)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
return db
|
||||
}
|
||||
|
||||
func orderAndPaginate(c *gin.Context) func(db *gorm.DB) *gorm.DB {
|
||||
|
@ -114,3 +124,10 @@ func GetListWithPagination(models interface{},
|
|||
|
||||
return
|
||||
}
|
||||
|
||||
type Method interface {
|
||||
// FirstByID Where("id=@id")
|
||||
FirstByID(id int) (*gen.T, error)
|
||||
// DeleteByID update @@table set deleted_at=NOW() where id=@id
|
||||
DeleteByID(id int) error
|
||||
}
|
||||
|
|
354
server/query/auth_tokens.gen.go
Normal file
354
server/query/auth_tokens.gen.go
Normal file
|
@ -0,0 +1,354 @@
|
|||
// 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 newAuthToken(db *gorm.DB, opts ...gen.DOOption) authToken {
|
||||
_authToken := authToken{}
|
||||
|
||||
_authToken.authTokenDo.UseDB(db, opts...)
|
||||
_authToken.authTokenDo.UseModel(&model.AuthToken{})
|
||||
|
||||
tableName := _authToken.authTokenDo.TableName()
|
||||
_authToken.ALL = field.NewAsterisk(tableName)
|
||||
_authToken.Token = field.NewString(tableName, "token")
|
||||
|
||||
_authToken.fillFieldMap()
|
||||
|
||||
return _authToken
|
||||
}
|
||||
|
||||
type authToken struct {
|
||||
authTokenDo
|
||||
|
||||
ALL field.Asterisk
|
||||
Token field.String
|
||||
|
||||
fieldMap map[string]field.Expr
|
||||
}
|
||||
|
||||
func (a authToken) Table(newTableName string) *authToken {
|
||||
a.authTokenDo.UseTable(newTableName)
|
||||
return a.updateTableName(newTableName)
|
||||
}
|
||||
|
||||
func (a authToken) As(alias string) *authToken {
|
||||
a.authTokenDo.DO = *(a.authTokenDo.As(alias).(*gen.DO))
|
||||
return a.updateTableName(alias)
|
||||
}
|
||||
|
||||
func (a *authToken) updateTableName(table string) *authToken {
|
||||
a.ALL = field.NewAsterisk(table)
|
||||
a.Token = field.NewString(table, "token")
|
||||
|
||||
a.fillFieldMap()
|
||||
|
||||
return a
|
||||
}
|
||||
|
||||
func (a *authToken) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||
_f, ok := a.fieldMap[fieldName]
|
||||
if !ok || _f == nil {
|
||||
return nil, false
|
||||
}
|
||||
_oe, ok := _f.(field.OrderExpr)
|
||||
return _oe, ok
|
||||
}
|
||||
|
||||
func (a *authToken) fillFieldMap() {
|
||||
a.fieldMap = make(map[string]field.Expr, 1)
|
||||
a.fieldMap["token"] = a.Token
|
||||
}
|
||||
|
||||
func (a authToken) clone(db *gorm.DB) authToken {
|
||||
a.authTokenDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||
return a
|
||||
}
|
||||
|
||||
func (a authToken) replaceDB(db *gorm.DB) authToken {
|
||||
a.authTokenDo.ReplaceDB(db)
|
||||
return a
|
||||
}
|
||||
|
||||
type authTokenDo struct{ gen.DO }
|
||||
|
||||
// FirstByID Where("id=@id")
|
||||
func (a authTokenDo) FirstByID(id int) (result *model.AuthToken, err error) {
|
||||
var params []interface{}
|
||||
|
||||
var generateSQL strings.Builder
|
||||
params = append(params, id)
|
||||
generateSQL.WriteString("id=? ")
|
||||
|
||||
var executeSQL *gorm.DB
|
||||
executeSQL = a.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 (a authTokenDo) DeleteByID(id int) (err error) {
|
||||
var params []interface{}
|
||||
|
||||
var generateSQL strings.Builder
|
||||
params = append(params, id)
|
||||
generateSQL.WriteString("update auth_tokens set deleted_at=NOW() where id=? ")
|
||||
|
||||
var executeSQL *gorm.DB
|
||||
executeSQL = a.UnderlyingDB().Exec(generateSQL.String(), params...) // ignore_security_alert
|
||||
err = executeSQL.Error
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (a authTokenDo) Debug() *authTokenDo {
|
||||
return a.withDO(a.DO.Debug())
|
||||
}
|
||||
|
||||
func (a authTokenDo) WithContext(ctx context.Context) *authTokenDo {
|
||||
return a.withDO(a.DO.WithContext(ctx))
|
||||
}
|
||||
|
||||
func (a authTokenDo) ReadDB() *authTokenDo {
|
||||
return a.Clauses(dbresolver.Read)
|
||||
}
|
||||
|
||||
func (a authTokenDo) WriteDB() *authTokenDo {
|
||||
return a.Clauses(dbresolver.Write)
|
||||
}
|
||||
|
||||
func (a authTokenDo) Session(config *gorm.Session) *authTokenDo {
|
||||
return a.withDO(a.DO.Session(config))
|
||||
}
|
||||
|
||||
func (a authTokenDo) Clauses(conds ...clause.Expression) *authTokenDo {
|
||||
return a.withDO(a.DO.Clauses(conds...))
|
||||
}
|
||||
|
||||
func (a authTokenDo) Returning(value interface{}, columns ...string) *authTokenDo {
|
||||
return a.withDO(a.DO.Returning(value, columns...))
|
||||
}
|
||||
|
||||
func (a authTokenDo) Not(conds ...gen.Condition) *authTokenDo {
|
||||
return a.withDO(a.DO.Not(conds...))
|
||||
}
|
||||
|
||||
func (a authTokenDo) Or(conds ...gen.Condition) *authTokenDo {
|
||||
return a.withDO(a.DO.Or(conds...))
|
||||
}
|
||||
|
||||
func (a authTokenDo) Select(conds ...field.Expr) *authTokenDo {
|
||||
return a.withDO(a.DO.Select(conds...))
|
||||
}
|
||||
|
||||
func (a authTokenDo) Where(conds ...gen.Condition) *authTokenDo {
|
||||
return a.withDO(a.DO.Where(conds...))
|
||||
}
|
||||
|
||||
func (a authTokenDo) Exists(subquery interface{ UnderlyingDB() *gorm.DB }) *authTokenDo {
|
||||
return a.Where(field.CompareSubQuery(field.ExistsOp, nil, subquery.UnderlyingDB()))
|
||||
}
|
||||
|
||||
func (a authTokenDo) Order(conds ...field.Expr) *authTokenDo {
|
||||
return a.withDO(a.DO.Order(conds...))
|
||||
}
|
||||
|
||||
func (a authTokenDo) Distinct(cols ...field.Expr) *authTokenDo {
|
||||
return a.withDO(a.DO.Distinct(cols...))
|
||||
}
|
||||
|
||||
func (a authTokenDo) Omit(cols ...field.Expr) *authTokenDo {
|
||||
return a.withDO(a.DO.Omit(cols...))
|
||||
}
|
||||
|
||||
func (a authTokenDo) Join(table schema.Tabler, on ...field.Expr) *authTokenDo {
|
||||
return a.withDO(a.DO.Join(table, on...))
|
||||
}
|
||||
|
||||
func (a authTokenDo) LeftJoin(table schema.Tabler, on ...field.Expr) *authTokenDo {
|
||||
return a.withDO(a.DO.LeftJoin(table, on...))
|
||||
}
|
||||
|
||||
func (a authTokenDo) RightJoin(table schema.Tabler, on ...field.Expr) *authTokenDo {
|
||||
return a.withDO(a.DO.RightJoin(table, on...))
|
||||
}
|
||||
|
||||
func (a authTokenDo) Group(cols ...field.Expr) *authTokenDo {
|
||||
return a.withDO(a.DO.Group(cols...))
|
||||
}
|
||||
|
||||
func (a authTokenDo) Having(conds ...gen.Condition) *authTokenDo {
|
||||
return a.withDO(a.DO.Having(conds...))
|
||||
}
|
||||
|
||||
func (a authTokenDo) Limit(limit int) *authTokenDo {
|
||||
return a.withDO(a.DO.Limit(limit))
|
||||
}
|
||||
|
||||
func (a authTokenDo) Offset(offset int) *authTokenDo {
|
||||
return a.withDO(a.DO.Offset(offset))
|
||||
}
|
||||
|
||||
func (a authTokenDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *authTokenDo {
|
||||
return a.withDO(a.DO.Scopes(funcs...))
|
||||
}
|
||||
|
||||
func (a authTokenDo) Unscoped() *authTokenDo {
|
||||
return a.withDO(a.DO.Unscoped())
|
||||
}
|
||||
|
||||
func (a authTokenDo) Create(values ...*model.AuthToken) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return a.DO.Create(values)
|
||||
}
|
||||
|
||||
func (a authTokenDo) CreateInBatches(values []*model.AuthToken, batchSize int) error {
|
||||
return a.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 (a authTokenDo) Save(values ...*model.AuthToken) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return a.DO.Save(values)
|
||||
}
|
||||
|
||||
func (a authTokenDo) First() (*model.AuthToken, error) {
|
||||
if result, err := a.DO.First(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AuthToken), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a authTokenDo) Take() (*model.AuthToken, error) {
|
||||
if result, err := a.DO.Take(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AuthToken), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a authTokenDo) Last() (*model.AuthToken, error) {
|
||||
if result, err := a.DO.Last(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AuthToken), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a authTokenDo) Find() ([]*model.AuthToken, error) {
|
||||
result, err := a.DO.Find()
|
||||
return result.([]*model.AuthToken), err
|
||||
}
|
||||
|
||||
func (a authTokenDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.AuthToken, err error) {
|
||||
buf := make([]*model.AuthToken, 0, batchSize)
|
||||
err = a.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 (a authTokenDo) FindInBatches(result *[]*model.AuthToken, batchSize int, fc func(tx gen.Dao, batch int) error) error {
|
||||
return a.DO.FindInBatches(result, batchSize, fc)
|
||||
}
|
||||
|
||||
func (a authTokenDo) Attrs(attrs ...field.AssignExpr) *authTokenDo {
|
||||
return a.withDO(a.DO.Attrs(attrs...))
|
||||
}
|
||||
|
||||
func (a authTokenDo) Assign(attrs ...field.AssignExpr) *authTokenDo {
|
||||
return a.withDO(a.DO.Assign(attrs...))
|
||||
}
|
||||
|
||||
func (a authTokenDo) Joins(fields ...field.RelationField) *authTokenDo {
|
||||
for _, _f := range fields {
|
||||
a = *a.withDO(a.DO.Joins(_f))
|
||||
}
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a authTokenDo) Preload(fields ...field.RelationField) *authTokenDo {
|
||||
for _, _f := range fields {
|
||||
a = *a.withDO(a.DO.Preload(_f))
|
||||
}
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a authTokenDo) FirstOrInit() (*model.AuthToken, error) {
|
||||
if result, err := a.DO.FirstOrInit(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AuthToken), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a authTokenDo) FirstOrCreate() (*model.AuthToken, error) {
|
||||
if result, err := a.DO.FirstOrCreate(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AuthToken), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a authTokenDo) FindByPage(offset int, limit int) (result []*model.AuthToken, count int64, err error) {
|
||||
result, err = a.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 = a.Offset(-1).Limit(-1).Count()
|
||||
return
|
||||
}
|
||||
|
||||
func (a authTokenDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
|
||||
count, err = a.Count()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = a.Offset(offset).Limit(limit).Scan(result)
|
||||
return
|
||||
}
|
||||
|
||||
func (a authTokenDo) Scan(result interface{}) (err error) {
|
||||
return a.DO.Scan(result)
|
||||
}
|
||||
|
||||
func (a authTokenDo) Delete(models ...*model.AuthToken) (result gen.ResultInfo, err error) {
|
||||
return a.DO.Delete(models)
|
||||
}
|
||||
|
||||
func (a *authTokenDo) withDO(do gen.Dao) *authTokenDo {
|
||||
a.DO = *do.(*gen.DO)
|
||||
return a
|
||||
}
|
374
server/query/auths.gen.go
Normal file
374
server/query/auths.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 newAuth(db *gorm.DB, opts ...gen.DOOption) auth {
|
||||
_auth := auth{}
|
||||
|
||||
_auth.authDo.UseDB(db, opts...)
|
||||
_auth.authDo.UseModel(&model.Auth{})
|
||||
|
||||
tableName := _auth.authDo.TableName()
|
||||
_auth.ALL = field.NewAsterisk(tableName)
|
||||
_auth.ID = field.NewUint(tableName, "id")
|
||||
_auth.CreatedAt = field.NewTime(tableName, "created_at")
|
||||
_auth.UpdatedAt = field.NewTime(tableName, "updated_at")
|
||||
_auth.DeletedAt = field.NewTime(tableName, "deleted_at")
|
||||
_auth.Name = field.NewString(tableName, "name")
|
||||
_auth.Password = field.NewString(tableName, "password")
|
||||
|
||||
_auth.fillFieldMap()
|
||||
|
||||
return _auth
|
||||
}
|
||||
|
||||
type auth struct {
|
||||
authDo
|
||||
|
||||
ALL field.Asterisk
|
||||
ID field.Uint
|
||||
CreatedAt field.Time
|
||||
UpdatedAt field.Time
|
||||
DeletedAt field.Time
|
||||
Name field.String
|
||||
Password field.String
|
||||
|
||||
fieldMap map[string]field.Expr
|
||||
}
|
||||
|
||||
func (a auth) Table(newTableName string) *auth {
|
||||
a.authDo.UseTable(newTableName)
|
||||
return a.updateTableName(newTableName)
|
||||
}
|
||||
|
||||
func (a auth) As(alias string) *auth {
|
||||
a.authDo.DO = *(a.authDo.As(alias).(*gen.DO))
|
||||
return a.updateTableName(alias)
|
||||
}
|
||||
|
||||
func (a *auth) updateTableName(table string) *auth {
|
||||
a.ALL = field.NewAsterisk(table)
|
||||
a.ID = field.NewUint(table, "id")
|
||||
a.CreatedAt = field.NewTime(table, "created_at")
|
||||
a.UpdatedAt = field.NewTime(table, "updated_at")
|
||||
a.DeletedAt = field.NewTime(table, "deleted_at")
|
||||
a.Name = field.NewString(table, "name")
|
||||
a.Password = field.NewString(table, "password")
|
||||
|
||||
a.fillFieldMap()
|
||||
|
||||
return a
|
||||
}
|
||||
|
||||
func (a *auth) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||
_f, ok := a.fieldMap[fieldName]
|
||||
if !ok || _f == nil {
|
||||
return nil, false
|
||||
}
|
||||
_oe, ok := _f.(field.OrderExpr)
|
||||
return _oe, ok
|
||||
}
|
||||
|
||||
func (a *auth) fillFieldMap() {
|
||||
a.fieldMap = make(map[string]field.Expr, 6)
|
||||
a.fieldMap["id"] = a.ID
|
||||
a.fieldMap["created_at"] = a.CreatedAt
|
||||
a.fieldMap["updated_at"] = a.UpdatedAt
|
||||
a.fieldMap["deleted_at"] = a.DeletedAt
|
||||
a.fieldMap["name"] = a.Name
|
||||
a.fieldMap["password"] = a.Password
|
||||
}
|
||||
|
||||
func (a auth) clone(db *gorm.DB) auth {
|
||||
a.authDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||
return a
|
||||
}
|
||||
|
||||
func (a auth) replaceDB(db *gorm.DB) auth {
|
||||
a.authDo.ReplaceDB(db)
|
||||
return a
|
||||
}
|
||||
|
||||
type authDo struct{ gen.DO }
|
||||
|
||||
// FirstByID Where("id=@id")
|
||||
func (a authDo) FirstByID(id int) (result *model.Auth, err error) {
|
||||
var params []interface{}
|
||||
|
||||
var generateSQL strings.Builder
|
||||
params = append(params, id)
|
||||
generateSQL.WriteString("id=? ")
|
||||
|
||||
var executeSQL *gorm.DB
|
||||
executeSQL = a.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 (a authDo) DeleteByID(id int) (err error) {
|
||||
var params []interface{}
|
||||
|
||||
var generateSQL strings.Builder
|
||||
params = append(params, id)
|
||||
generateSQL.WriteString("update auths set deleted_at=NOW() where id=? ")
|
||||
|
||||
var executeSQL *gorm.DB
|
||||
executeSQL = a.UnderlyingDB().Exec(generateSQL.String(), params...) // ignore_security_alert
|
||||
err = executeSQL.Error
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (a authDo) Debug() *authDo {
|
||||
return a.withDO(a.DO.Debug())
|
||||
}
|
||||
|
||||
func (a authDo) WithContext(ctx context.Context) *authDo {
|
||||
return a.withDO(a.DO.WithContext(ctx))
|
||||
}
|
||||
|
||||
func (a authDo) ReadDB() *authDo {
|
||||
return a.Clauses(dbresolver.Read)
|
||||
}
|
||||
|
||||
func (a authDo) WriteDB() *authDo {
|
||||
return a.Clauses(dbresolver.Write)
|
||||
}
|
||||
|
||||
func (a authDo) Session(config *gorm.Session) *authDo {
|
||||
return a.withDO(a.DO.Session(config))
|
||||
}
|
||||
|
||||
func (a authDo) Clauses(conds ...clause.Expression) *authDo {
|
||||
return a.withDO(a.DO.Clauses(conds...))
|
||||
}
|
||||
|
||||
func (a authDo) Returning(value interface{}, columns ...string) *authDo {
|
||||
return a.withDO(a.DO.Returning(value, columns...))
|
||||
}
|
||||
|
||||
func (a authDo) Not(conds ...gen.Condition) *authDo {
|
||||
return a.withDO(a.DO.Not(conds...))
|
||||
}
|
||||
|
||||
func (a authDo) Or(conds ...gen.Condition) *authDo {
|
||||
return a.withDO(a.DO.Or(conds...))
|
||||
}
|
||||
|
||||
func (a authDo) Select(conds ...field.Expr) *authDo {
|
||||
return a.withDO(a.DO.Select(conds...))
|
||||
}
|
||||
|
||||
func (a authDo) Where(conds ...gen.Condition) *authDo {
|
||||
return a.withDO(a.DO.Where(conds...))
|
||||
}
|
||||
|
||||
func (a authDo) Exists(subquery interface{ UnderlyingDB() *gorm.DB }) *authDo {
|
||||
return a.Where(field.CompareSubQuery(field.ExistsOp, nil, subquery.UnderlyingDB()))
|
||||
}
|
||||
|
||||
func (a authDo) Order(conds ...field.Expr) *authDo {
|
||||
return a.withDO(a.DO.Order(conds...))
|
||||
}
|
||||
|
||||
func (a authDo) Distinct(cols ...field.Expr) *authDo {
|
||||
return a.withDO(a.DO.Distinct(cols...))
|
||||
}
|
||||
|
||||
func (a authDo) Omit(cols ...field.Expr) *authDo {
|
||||
return a.withDO(a.DO.Omit(cols...))
|
||||
}
|
||||
|
||||
func (a authDo) Join(table schema.Tabler, on ...field.Expr) *authDo {
|
||||
return a.withDO(a.DO.Join(table, on...))
|
||||
}
|
||||
|
||||
func (a authDo) LeftJoin(table schema.Tabler, on ...field.Expr) *authDo {
|
||||
return a.withDO(a.DO.LeftJoin(table, on...))
|
||||
}
|
||||
|
||||
func (a authDo) RightJoin(table schema.Tabler, on ...field.Expr) *authDo {
|
||||
return a.withDO(a.DO.RightJoin(table, on...))
|
||||
}
|
||||
|
||||
func (a authDo) Group(cols ...field.Expr) *authDo {
|
||||
return a.withDO(a.DO.Group(cols...))
|
||||
}
|
||||
|
||||
func (a authDo) Having(conds ...gen.Condition) *authDo {
|
||||
return a.withDO(a.DO.Having(conds...))
|
||||
}
|
||||
|
||||
func (a authDo) Limit(limit int) *authDo {
|
||||
return a.withDO(a.DO.Limit(limit))
|
||||
}
|
||||
|
||||
func (a authDo) Offset(offset int) *authDo {
|
||||
return a.withDO(a.DO.Offset(offset))
|
||||
}
|
||||
|
||||
func (a authDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *authDo {
|
||||
return a.withDO(a.DO.Scopes(funcs...))
|
||||
}
|
||||
|
||||
func (a authDo) Unscoped() *authDo {
|
||||
return a.withDO(a.DO.Unscoped())
|
||||
}
|
||||
|
||||
func (a authDo) Create(values ...*model.Auth) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return a.DO.Create(values)
|
||||
}
|
||||
|
||||
func (a authDo) CreateInBatches(values []*model.Auth, batchSize int) error {
|
||||
return a.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 (a authDo) Save(values ...*model.Auth) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return a.DO.Save(values)
|
||||
}
|
||||
|
||||
func (a authDo) First() (*model.Auth, error) {
|
||||
if result, err := a.DO.First(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.Auth), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a authDo) Take() (*model.Auth, error) {
|
||||
if result, err := a.DO.Take(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.Auth), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a authDo) Last() (*model.Auth, error) {
|
||||
if result, err := a.DO.Last(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.Auth), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a authDo) Find() ([]*model.Auth, error) {
|
||||
result, err := a.DO.Find()
|
||||
return result.([]*model.Auth), err
|
||||
}
|
||||
|
||||
func (a authDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.Auth, err error) {
|
||||
buf := make([]*model.Auth, 0, batchSize)
|
||||
err = a.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 (a authDo) FindInBatches(result *[]*model.Auth, batchSize int, fc func(tx gen.Dao, batch int) error) error {
|
||||
return a.DO.FindInBatches(result, batchSize, fc)
|
||||
}
|
||||
|
||||
func (a authDo) Attrs(attrs ...field.AssignExpr) *authDo {
|
||||
return a.withDO(a.DO.Attrs(attrs...))
|
||||
}
|
||||
|
||||
func (a authDo) Assign(attrs ...field.AssignExpr) *authDo {
|
||||
return a.withDO(a.DO.Assign(attrs...))
|
||||
}
|
||||
|
||||
func (a authDo) Joins(fields ...field.RelationField) *authDo {
|
||||
for _, _f := range fields {
|
||||
a = *a.withDO(a.DO.Joins(_f))
|
||||
}
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a authDo) Preload(fields ...field.RelationField) *authDo {
|
||||
for _, _f := range fields {
|
||||
a = *a.withDO(a.DO.Preload(_f))
|
||||
}
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a authDo) FirstOrInit() (*model.Auth, error) {
|
||||
if result, err := a.DO.FirstOrInit(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.Auth), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a authDo) FirstOrCreate() (*model.Auth, error) {
|
||||
if result, err := a.DO.FirstOrCreate(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.Auth), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a authDo) FindByPage(offset int, limit int) (result []*model.Auth, count int64, err error) {
|
||||
result, err = a.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 = a.Offset(-1).Limit(-1).Count()
|
||||
return
|
||||
}
|
||||
|
||||
func (a authDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
|
||||
count, err = a.Count()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = a.Offset(offset).Limit(limit).Scan(result)
|
||||
return
|
||||
}
|
||||
|
||||
func (a authDo) Scan(result interface{}) (err error) {
|
||||
return a.DO.Scan(result)
|
||||
}
|
||||
|
||||
func (a authDo) Delete(models ...*model.Auth) (result gen.ResultInfo, err error) {
|
||||
return a.DO.Delete(models)
|
||||
}
|
||||
|
||||
func (a *authDo) withDO(do gen.Dao) *authDo {
|
||||
a.DO = *do.(*gen.DO)
|
||||
return a
|
||||
}
|
394
server/query/certs.gen.go
Normal file
394
server/query/certs.gen.go
Normal file
|
@ -0,0 +1,394 @@
|
|||
// 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 newCert(db *gorm.DB, opts ...gen.DOOption) cert {
|
||||
_cert := cert{}
|
||||
|
||||
_cert.certDo.UseDB(db, opts...)
|
||||
_cert.certDo.UseModel(&model.Cert{})
|
||||
|
||||
tableName := _cert.certDo.TableName()
|
||||
_cert.ALL = field.NewAsterisk(tableName)
|
||||
_cert.ID = field.NewUint(tableName, "id")
|
||||
_cert.CreatedAt = field.NewTime(tableName, "created_at")
|
||||
_cert.UpdatedAt = field.NewTime(tableName, "updated_at")
|
||||
_cert.DeletedAt = field.NewTime(tableName, "deleted_at")
|
||||
_cert.Name = field.NewString(tableName, "name")
|
||||
_cert.Domains = field.NewField(tableName, "domains")
|
||||
_cert.Filename = field.NewString(tableName, "filename")
|
||||
_cert.SSLCertificatePath = field.NewString(tableName, "ssl_certificate_path")
|
||||
_cert.SSLCertificateKeyPath = field.NewString(tableName, "ssl_certificate_key_path")
|
||||
_cert.AutoCert = field.NewInt(tableName, "auto_cert")
|
||||
_cert.Log = field.NewString(tableName, "log")
|
||||
|
||||
_cert.fillFieldMap()
|
||||
|
||||
return _cert
|
||||
}
|
||||
|
||||
type cert struct {
|
||||
certDo
|
||||
|
||||
ALL field.Asterisk
|
||||
ID field.Uint
|
||||
CreatedAt field.Time
|
||||
UpdatedAt field.Time
|
||||
DeletedAt field.Time
|
||||
Name field.String
|
||||
Domains field.Field
|
||||
Filename field.String
|
||||
SSLCertificatePath field.String
|
||||
SSLCertificateKeyPath field.String
|
||||
AutoCert field.Int
|
||||
Log field.String
|
||||
|
||||
fieldMap map[string]field.Expr
|
||||
}
|
||||
|
||||
func (c cert) Table(newTableName string) *cert {
|
||||
c.certDo.UseTable(newTableName)
|
||||
return c.updateTableName(newTableName)
|
||||
}
|
||||
|
||||
func (c cert) As(alias string) *cert {
|
||||
c.certDo.DO = *(c.certDo.As(alias).(*gen.DO))
|
||||
return c.updateTableName(alias)
|
||||
}
|
||||
|
||||
func (c *cert) updateTableName(table string) *cert {
|
||||
c.ALL = field.NewAsterisk(table)
|
||||
c.ID = field.NewUint(table, "id")
|
||||
c.CreatedAt = field.NewTime(table, "created_at")
|
||||
c.UpdatedAt = field.NewTime(table, "updated_at")
|
||||
c.DeletedAt = field.NewTime(table, "deleted_at")
|
||||
c.Name = field.NewString(table, "name")
|
||||
c.Domains = field.NewField(table, "domains")
|
||||
c.Filename = field.NewString(table, "filename")
|
||||
c.SSLCertificatePath = field.NewString(table, "ssl_certificate_path")
|
||||
c.SSLCertificateKeyPath = field.NewString(table, "ssl_certificate_key_path")
|
||||
c.AutoCert = field.NewInt(table, "auto_cert")
|
||||
c.Log = field.NewString(table, "log")
|
||||
|
||||
c.fillFieldMap()
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *cert) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||
_f, ok := c.fieldMap[fieldName]
|
||||
if !ok || _f == nil {
|
||||
return nil, false
|
||||
}
|
||||
_oe, ok := _f.(field.OrderExpr)
|
||||
return _oe, ok
|
||||
}
|
||||
|
||||
func (c *cert) fillFieldMap() {
|
||||
c.fieldMap = make(map[string]field.Expr, 11)
|
||||
c.fieldMap["id"] = c.ID
|
||||
c.fieldMap["created_at"] = c.CreatedAt
|
||||
c.fieldMap["updated_at"] = c.UpdatedAt
|
||||
c.fieldMap["deleted_at"] = c.DeletedAt
|
||||
c.fieldMap["name"] = c.Name
|
||||
c.fieldMap["domains"] = c.Domains
|
||||
c.fieldMap["filename"] = c.Filename
|
||||
c.fieldMap["ssl_certificate_path"] = c.SSLCertificatePath
|
||||
c.fieldMap["ssl_certificate_key_path"] = c.SSLCertificateKeyPath
|
||||
c.fieldMap["auto_cert"] = c.AutoCert
|
||||
c.fieldMap["log"] = c.Log
|
||||
}
|
||||
|
||||
func (c cert) clone(db *gorm.DB) cert {
|
||||
c.certDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||
return c
|
||||
}
|
||||
|
||||
func (c cert) replaceDB(db *gorm.DB) cert {
|
||||
c.certDo.ReplaceDB(db)
|
||||
return c
|
||||
}
|
||||
|
||||
type certDo struct{ gen.DO }
|
||||
|
||||
// FirstByID Where("id=@id")
|
||||
func (c certDo) FirstByID(id int) (result *model.Cert, err error) {
|
||||
var params []interface{}
|
||||
|
||||
var generateSQL strings.Builder
|
||||
params = append(params, id)
|
||||
generateSQL.WriteString("id=? ")
|
||||
|
||||
var executeSQL *gorm.DB
|
||||
executeSQL = c.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 (c certDo) DeleteByID(id int) (err error) {
|
||||
var params []interface{}
|
||||
|
||||
var generateSQL strings.Builder
|
||||
params = append(params, id)
|
||||
generateSQL.WriteString("update certs set deleted_at=NOW() where id=? ")
|
||||
|
||||
var executeSQL *gorm.DB
|
||||
executeSQL = c.UnderlyingDB().Exec(generateSQL.String(), params...) // ignore_security_alert
|
||||
err = executeSQL.Error
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (c certDo) Debug() *certDo {
|
||||
return c.withDO(c.DO.Debug())
|
||||
}
|
||||
|
||||
func (c certDo) WithContext(ctx context.Context) *certDo {
|
||||
return c.withDO(c.DO.WithContext(ctx))
|
||||
}
|
||||
|
||||
func (c certDo) ReadDB() *certDo {
|
||||
return c.Clauses(dbresolver.Read)
|
||||
}
|
||||
|
||||
func (c certDo) WriteDB() *certDo {
|
||||
return c.Clauses(dbresolver.Write)
|
||||
}
|
||||
|
||||
func (c certDo) Session(config *gorm.Session) *certDo {
|
||||
return c.withDO(c.DO.Session(config))
|
||||
}
|
||||
|
||||
func (c certDo) Clauses(conds ...clause.Expression) *certDo {
|
||||
return c.withDO(c.DO.Clauses(conds...))
|
||||
}
|
||||
|
||||
func (c certDo) Returning(value interface{}, columns ...string) *certDo {
|
||||
return c.withDO(c.DO.Returning(value, columns...))
|
||||
}
|
||||
|
||||
func (c certDo) Not(conds ...gen.Condition) *certDo {
|
||||
return c.withDO(c.DO.Not(conds...))
|
||||
}
|
||||
|
||||
func (c certDo) Or(conds ...gen.Condition) *certDo {
|
||||
return c.withDO(c.DO.Or(conds...))
|
||||
}
|
||||
|
||||
func (c certDo) Select(conds ...field.Expr) *certDo {
|
||||
return c.withDO(c.DO.Select(conds...))
|
||||
}
|
||||
|
||||
func (c certDo) Where(conds ...gen.Condition) *certDo {
|
||||
return c.withDO(c.DO.Where(conds...))
|
||||
}
|
||||
|
||||
func (c certDo) Exists(subquery interface{ UnderlyingDB() *gorm.DB }) *certDo {
|
||||
return c.Where(field.CompareSubQuery(field.ExistsOp, nil, subquery.UnderlyingDB()))
|
||||
}
|
||||
|
||||
func (c certDo) Order(conds ...field.Expr) *certDo {
|
||||
return c.withDO(c.DO.Order(conds...))
|
||||
}
|
||||
|
||||
func (c certDo) Distinct(cols ...field.Expr) *certDo {
|
||||
return c.withDO(c.DO.Distinct(cols...))
|
||||
}
|
||||
|
||||
func (c certDo) Omit(cols ...field.Expr) *certDo {
|
||||
return c.withDO(c.DO.Omit(cols...))
|
||||
}
|
||||
|
||||
func (c certDo) Join(table schema.Tabler, on ...field.Expr) *certDo {
|
||||
return c.withDO(c.DO.Join(table, on...))
|
||||
}
|
||||
|
||||
func (c certDo) LeftJoin(table schema.Tabler, on ...field.Expr) *certDo {
|
||||
return c.withDO(c.DO.LeftJoin(table, on...))
|
||||
}
|
||||
|
||||
func (c certDo) RightJoin(table schema.Tabler, on ...field.Expr) *certDo {
|
||||
return c.withDO(c.DO.RightJoin(table, on...))
|
||||
}
|
||||
|
||||
func (c certDo) Group(cols ...field.Expr) *certDo {
|
||||
return c.withDO(c.DO.Group(cols...))
|
||||
}
|
||||
|
||||
func (c certDo) Having(conds ...gen.Condition) *certDo {
|
||||
return c.withDO(c.DO.Having(conds...))
|
||||
}
|
||||
|
||||
func (c certDo) Limit(limit int) *certDo {
|
||||
return c.withDO(c.DO.Limit(limit))
|
||||
}
|
||||
|
||||
func (c certDo) Offset(offset int) *certDo {
|
||||
return c.withDO(c.DO.Offset(offset))
|
||||
}
|
||||
|
||||
func (c certDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *certDo {
|
||||
return c.withDO(c.DO.Scopes(funcs...))
|
||||
}
|
||||
|
||||
func (c certDo) Unscoped() *certDo {
|
||||
return c.withDO(c.DO.Unscoped())
|
||||
}
|
||||
|
||||
func (c certDo) Create(values ...*model.Cert) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return c.DO.Create(values)
|
||||
}
|
||||
|
||||
func (c certDo) CreateInBatches(values []*model.Cert, batchSize int) error {
|
||||
return c.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 (c certDo) Save(values ...*model.Cert) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return c.DO.Save(values)
|
||||
}
|
||||
|
||||
func (c certDo) First() (*model.Cert, error) {
|
||||
if result, err := c.DO.First(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.Cert), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c certDo) Take() (*model.Cert, error) {
|
||||
if result, err := c.DO.Take(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.Cert), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c certDo) Last() (*model.Cert, error) {
|
||||
if result, err := c.DO.Last(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.Cert), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c certDo) Find() ([]*model.Cert, error) {
|
||||
result, err := c.DO.Find()
|
||||
return result.([]*model.Cert), err
|
||||
}
|
||||
|
||||
func (c certDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.Cert, err error) {
|
||||
buf := make([]*model.Cert, 0, batchSize)
|
||||
err = c.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 (c certDo) FindInBatches(result *[]*model.Cert, batchSize int, fc func(tx gen.Dao, batch int) error) error {
|
||||
return c.DO.FindInBatches(result, batchSize, fc)
|
||||
}
|
||||
|
||||
func (c certDo) Attrs(attrs ...field.AssignExpr) *certDo {
|
||||
return c.withDO(c.DO.Attrs(attrs...))
|
||||
}
|
||||
|
||||
func (c certDo) Assign(attrs ...field.AssignExpr) *certDo {
|
||||
return c.withDO(c.DO.Assign(attrs...))
|
||||
}
|
||||
|
||||
func (c certDo) Joins(fields ...field.RelationField) *certDo {
|
||||
for _, _f := range fields {
|
||||
c = *c.withDO(c.DO.Joins(_f))
|
||||
}
|
||||
return &c
|
||||
}
|
||||
|
||||
func (c certDo) Preload(fields ...field.RelationField) *certDo {
|
||||
for _, _f := range fields {
|
||||
c = *c.withDO(c.DO.Preload(_f))
|
||||
}
|
||||
return &c
|
||||
}
|
||||
|
||||
func (c certDo) FirstOrInit() (*model.Cert, error) {
|
||||
if result, err := c.DO.FirstOrInit(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.Cert), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c certDo) FirstOrCreate() (*model.Cert, error) {
|
||||
if result, err := c.DO.FirstOrCreate(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.Cert), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c certDo) FindByPage(offset int, limit int) (result []*model.Cert, count int64, err error) {
|
||||
result, err = c.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 = c.Offset(-1).Limit(-1).Count()
|
||||
return
|
||||
}
|
||||
|
||||
func (c certDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
|
||||
count, err = c.Count()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = c.Offset(offset).Limit(limit).Scan(result)
|
||||
return
|
||||
}
|
||||
|
||||
func (c certDo) Scan(result interface{}) (err error) {
|
||||
return c.DO.Scan(result)
|
||||
}
|
||||
|
||||
func (c certDo) Delete(models ...*model.Cert) (result gen.ResultInfo, err error) {
|
||||
return c.DO.Delete(models)
|
||||
}
|
||||
|
||||
func (c *certDo) withDO(do gen.Dao) *certDo {
|
||||
c.DO = *do.(*gen.DO)
|
||||
return c
|
||||
}
|
358
server/query/chat_gpt_logs.gen.go
Normal file
358
server/query/chat_gpt_logs.gen.go
Normal file
|
@ -0,0 +1,358 @@
|
|||
// 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 newChatGPTLog(db *gorm.DB, opts ...gen.DOOption) chatGPTLog {
|
||||
_chatGPTLog := chatGPTLog{}
|
||||
|
||||
_chatGPTLog.chatGPTLogDo.UseDB(db, opts...)
|
||||
_chatGPTLog.chatGPTLogDo.UseModel(&model.ChatGPTLog{})
|
||||
|
||||
tableName := _chatGPTLog.chatGPTLogDo.TableName()
|
||||
_chatGPTLog.ALL = field.NewAsterisk(tableName)
|
||||
_chatGPTLog.Name = field.NewString(tableName, "name")
|
||||
_chatGPTLog.Content = field.NewField(tableName, "content")
|
||||
|
||||
_chatGPTLog.fillFieldMap()
|
||||
|
||||
return _chatGPTLog
|
||||
}
|
||||
|
||||
type chatGPTLog struct {
|
||||
chatGPTLogDo
|
||||
|
||||
ALL field.Asterisk
|
||||
Name field.String
|
||||
Content field.Field
|
||||
|
||||
fieldMap map[string]field.Expr
|
||||
}
|
||||
|
||||
func (c chatGPTLog) Table(newTableName string) *chatGPTLog {
|
||||
c.chatGPTLogDo.UseTable(newTableName)
|
||||
return c.updateTableName(newTableName)
|
||||
}
|
||||
|
||||
func (c chatGPTLog) As(alias string) *chatGPTLog {
|
||||
c.chatGPTLogDo.DO = *(c.chatGPTLogDo.As(alias).(*gen.DO))
|
||||
return c.updateTableName(alias)
|
||||
}
|
||||
|
||||
func (c *chatGPTLog) updateTableName(table string) *chatGPTLog {
|
||||
c.ALL = field.NewAsterisk(table)
|
||||
c.Name = field.NewString(table, "name")
|
||||
c.Content = field.NewField(table, "content")
|
||||
|
||||
c.fillFieldMap()
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *chatGPTLog) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||
_f, ok := c.fieldMap[fieldName]
|
||||
if !ok || _f == nil {
|
||||
return nil, false
|
||||
}
|
||||
_oe, ok := _f.(field.OrderExpr)
|
||||
return _oe, ok
|
||||
}
|
||||
|
||||
func (c *chatGPTLog) fillFieldMap() {
|
||||
c.fieldMap = make(map[string]field.Expr, 2)
|
||||
c.fieldMap["name"] = c.Name
|
||||
c.fieldMap["content"] = c.Content
|
||||
}
|
||||
|
||||
func (c chatGPTLog) clone(db *gorm.DB) chatGPTLog {
|
||||
c.chatGPTLogDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||
return c
|
||||
}
|
||||
|
||||
func (c chatGPTLog) replaceDB(db *gorm.DB) chatGPTLog {
|
||||
c.chatGPTLogDo.ReplaceDB(db)
|
||||
return c
|
||||
}
|
||||
|
||||
type chatGPTLogDo struct{ gen.DO }
|
||||
|
||||
// FirstByID Where("id=@id")
|
||||
func (c chatGPTLogDo) FirstByID(id int) (result *model.ChatGPTLog, err error) {
|
||||
var params []interface{}
|
||||
|
||||
var generateSQL strings.Builder
|
||||
params = append(params, id)
|
||||
generateSQL.WriteString("id=? ")
|
||||
|
||||
var executeSQL *gorm.DB
|
||||
executeSQL = c.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 (c chatGPTLogDo) DeleteByID(id int) (err error) {
|
||||
var params []interface{}
|
||||
|
||||
var generateSQL strings.Builder
|
||||
params = append(params, id)
|
||||
generateSQL.WriteString("update chat_gpt_logs set deleted_at=NOW() where id=? ")
|
||||
|
||||
var executeSQL *gorm.DB
|
||||
executeSQL = c.UnderlyingDB().Exec(generateSQL.String(), params...) // ignore_security_alert
|
||||
err = executeSQL.Error
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) Debug() *chatGPTLogDo {
|
||||
return c.withDO(c.DO.Debug())
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) WithContext(ctx context.Context) *chatGPTLogDo {
|
||||
return c.withDO(c.DO.WithContext(ctx))
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) ReadDB() *chatGPTLogDo {
|
||||
return c.Clauses(dbresolver.Read)
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) WriteDB() *chatGPTLogDo {
|
||||
return c.Clauses(dbresolver.Write)
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) Session(config *gorm.Session) *chatGPTLogDo {
|
||||
return c.withDO(c.DO.Session(config))
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) Clauses(conds ...clause.Expression) *chatGPTLogDo {
|
||||
return c.withDO(c.DO.Clauses(conds...))
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) Returning(value interface{}, columns ...string) *chatGPTLogDo {
|
||||
return c.withDO(c.DO.Returning(value, columns...))
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) Not(conds ...gen.Condition) *chatGPTLogDo {
|
||||
return c.withDO(c.DO.Not(conds...))
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) Or(conds ...gen.Condition) *chatGPTLogDo {
|
||||
return c.withDO(c.DO.Or(conds...))
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) Select(conds ...field.Expr) *chatGPTLogDo {
|
||||
return c.withDO(c.DO.Select(conds...))
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) Where(conds ...gen.Condition) *chatGPTLogDo {
|
||||
return c.withDO(c.DO.Where(conds...))
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) Exists(subquery interface{ UnderlyingDB() *gorm.DB }) *chatGPTLogDo {
|
||||
return c.Where(field.CompareSubQuery(field.ExistsOp, nil, subquery.UnderlyingDB()))
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) Order(conds ...field.Expr) *chatGPTLogDo {
|
||||
return c.withDO(c.DO.Order(conds...))
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) Distinct(cols ...field.Expr) *chatGPTLogDo {
|
||||
return c.withDO(c.DO.Distinct(cols...))
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) Omit(cols ...field.Expr) *chatGPTLogDo {
|
||||
return c.withDO(c.DO.Omit(cols...))
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) Join(table schema.Tabler, on ...field.Expr) *chatGPTLogDo {
|
||||
return c.withDO(c.DO.Join(table, on...))
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) LeftJoin(table schema.Tabler, on ...field.Expr) *chatGPTLogDo {
|
||||
return c.withDO(c.DO.LeftJoin(table, on...))
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) RightJoin(table schema.Tabler, on ...field.Expr) *chatGPTLogDo {
|
||||
return c.withDO(c.DO.RightJoin(table, on...))
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) Group(cols ...field.Expr) *chatGPTLogDo {
|
||||
return c.withDO(c.DO.Group(cols...))
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) Having(conds ...gen.Condition) *chatGPTLogDo {
|
||||
return c.withDO(c.DO.Having(conds...))
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) Limit(limit int) *chatGPTLogDo {
|
||||
return c.withDO(c.DO.Limit(limit))
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) Offset(offset int) *chatGPTLogDo {
|
||||
return c.withDO(c.DO.Offset(offset))
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *chatGPTLogDo {
|
||||
return c.withDO(c.DO.Scopes(funcs...))
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) Unscoped() *chatGPTLogDo {
|
||||
return c.withDO(c.DO.Unscoped())
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) Create(values ...*model.ChatGPTLog) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return c.DO.Create(values)
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) CreateInBatches(values []*model.ChatGPTLog, batchSize int) error {
|
||||
return c.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 (c chatGPTLogDo) Save(values ...*model.ChatGPTLog) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return c.DO.Save(values)
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) First() (*model.ChatGPTLog, error) {
|
||||
if result, err := c.DO.First(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.ChatGPTLog), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) Take() (*model.ChatGPTLog, error) {
|
||||
if result, err := c.DO.Take(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.ChatGPTLog), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) Last() (*model.ChatGPTLog, error) {
|
||||
if result, err := c.DO.Last(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.ChatGPTLog), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) Find() ([]*model.ChatGPTLog, error) {
|
||||
result, err := c.DO.Find()
|
||||
return result.([]*model.ChatGPTLog), err
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.ChatGPTLog, err error) {
|
||||
buf := make([]*model.ChatGPTLog, 0, batchSize)
|
||||
err = c.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 (c chatGPTLogDo) FindInBatches(result *[]*model.ChatGPTLog, batchSize int, fc func(tx gen.Dao, batch int) error) error {
|
||||
return c.DO.FindInBatches(result, batchSize, fc)
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) Attrs(attrs ...field.AssignExpr) *chatGPTLogDo {
|
||||
return c.withDO(c.DO.Attrs(attrs...))
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) Assign(attrs ...field.AssignExpr) *chatGPTLogDo {
|
||||
return c.withDO(c.DO.Assign(attrs...))
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) Joins(fields ...field.RelationField) *chatGPTLogDo {
|
||||
for _, _f := range fields {
|
||||
c = *c.withDO(c.DO.Joins(_f))
|
||||
}
|
||||
return &c
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) Preload(fields ...field.RelationField) *chatGPTLogDo {
|
||||
for _, _f := range fields {
|
||||
c = *c.withDO(c.DO.Preload(_f))
|
||||
}
|
||||
return &c
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) FirstOrInit() (*model.ChatGPTLog, error) {
|
||||
if result, err := c.DO.FirstOrInit(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.ChatGPTLog), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) FirstOrCreate() (*model.ChatGPTLog, error) {
|
||||
if result, err := c.DO.FirstOrCreate(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.ChatGPTLog), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) FindByPage(offset int, limit int) (result []*model.ChatGPTLog, count int64, err error) {
|
||||
result, err = c.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 = c.Offset(-1).Limit(-1).Count()
|
||||
return
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
|
||||
count, err = c.Count()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = c.Offset(offset).Limit(limit).Scan(result)
|
||||
return
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) Scan(result interface{}) (err error) {
|
||||
return c.DO.Scan(result)
|
||||
}
|
||||
|
||||
func (c chatGPTLogDo) Delete(models ...*model.ChatGPTLog) (result gen.ResultInfo, err error) {
|
||||
return c.DO.Delete(models)
|
||||
}
|
||||
|
||||
func (c *chatGPTLogDo) withDO(do gen.Dao) *chatGPTLogDo {
|
||||
c.DO = *do.(*gen.DO)
|
||||
return c
|
||||
}
|
378
server/query/config_backups.gen.go
Normal file
378
server/query/config_backups.gen.go
Normal file
|
@ -0,0 +1,378 @@
|
|||
// 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 newConfigBackup(db *gorm.DB, opts ...gen.DOOption) configBackup {
|
||||
_configBackup := configBackup{}
|
||||
|
||||
_configBackup.configBackupDo.UseDB(db, opts...)
|
||||
_configBackup.configBackupDo.UseModel(&model.ConfigBackup{})
|
||||
|
||||
tableName := _configBackup.configBackupDo.TableName()
|
||||
_configBackup.ALL = field.NewAsterisk(tableName)
|
||||
_configBackup.ID = field.NewUint(tableName, "id")
|
||||
_configBackup.CreatedAt = field.NewTime(tableName, "created_at")
|
||||
_configBackup.UpdatedAt = field.NewTime(tableName, "updated_at")
|
||||
_configBackup.DeletedAt = field.NewTime(tableName, "deleted_at")
|
||||
_configBackup.Name = field.NewString(tableName, "name")
|
||||
_configBackup.FilePath = field.NewString(tableName, "file_path")
|
||||
_configBackup.Content = field.NewString(tableName, "content")
|
||||
|
||||
_configBackup.fillFieldMap()
|
||||
|
||||
return _configBackup
|
||||
}
|
||||
|
||||
type configBackup struct {
|
||||
configBackupDo
|
||||
|
||||
ALL field.Asterisk
|
||||
ID field.Uint
|
||||
CreatedAt field.Time
|
||||
UpdatedAt field.Time
|
||||
DeletedAt field.Time
|
||||
Name field.String
|
||||
FilePath field.String
|
||||
Content field.String
|
||||
|
||||
fieldMap map[string]field.Expr
|
||||
}
|
||||
|
||||
func (c configBackup) Table(newTableName string) *configBackup {
|
||||
c.configBackupDo.UseTable(newTableName)
|
||||
return c.updateTableName(newTableName)
|
||||
}
|
||||
|
||||
func (c configBackup) As(alias string) *configBackup {
|
||||
c.configBackupDo.DO = *(c.configBackupDo.As(alias).(*gen.DO))
|
||||
return c.updateTableName(alias)
|
||||
}
|
||||
|
||||
func (c *configBackup) updateTableName(table string) *configBackup {
|
||||
c.ALL = field.NewAsterisk(table)
|
||||
c.ID = field.NewUint(table, "id")
|
||||
c.CreatedAt = field.NewTime(table, "created_at")
|
||||
c.UpdatedAt = field.NewTime(table, "updated_at")
|
||||
c.DeletedAt = field.NewTime(table, "deleted_at")
|
||||
c.Name = field.NewString(table, "name")
|
||||
c.FilePath = field.NewString(table, "file_path")
|
||||
c.Content = field.NewString(table, "content")
|
||||
|
||||
c.fillFieldMap()
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *configBackup) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||
_f, ok := c.fieldMap[fieldName]
|
||||
if !ok || _f == nil {
|
||||
return nil, false
|
||||
}
|
||||
_oe, ok := _f.(field.OrderExpr)
|
||||
return _oe, ok
|
||||
}
|
||||
|
||||
func (c *configBackup) fillFieldMap() {
|
||||
c.fieldMap = make(map[string]field.Expr, 7)
|
||||
c.fieldMap["id"] = c.ID
|
||||
c.fieldMap["created_at"] = c.CreatedAt
|
||||
c.fieldMap["updated_at"] = c.UpdatedAt
|
||||
c.fieldMap["deleted_at"] = c.DeletedAt
|
||||
c.fieldMap["name"] = c.Name
|
||||
c.fieldMap["file_path"] = c.FilePath
|
||||
c.fieldMap["content"] = c.Content
|
||||
}
|
||||
|
||||
func (c configBackup) clone(db *gorm.DB) configBackup {
|
||||
c.configBackupDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||
return c
|
||||
}
|
||||
|
||||
func (c configBackup) replaceDB(db *gorm.DB) configBackup {
|
||||
c.configBackupDo.ReplaceDB(db)
|
||||
return c
|
||||
}
|
||||
|
||||
type configBackupDo struct{ gen.DO }
|
||||
|
||||
// FirstByID Where("id=@id")
|
||||
func (c configBackupDo) FirstByID(id int) (result *model.ConfigBackup, err error) {
|
||||
var params []interface{}
|
||||
|
||||
var generateSQL strings.Builder
|
||||
params = append(params, id)
|
||||
generateSQL.WriteString("id=? ")
|
||||
|
||||
var executeSQL *gorm.DB
|
||||
executeSQL = c.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 (c configBackupDo) DeleteByID(id int) (err error) {
|
||||
var params []interface{}
|
||||
|
||||
var generateSQL strings.Builder
|
||||
params = append(params, id)
|
||||
generateSQL.WriteString("update config_backups set deleted_at=NOW() where id=? ")
|
||||
|
||||
var executeSQL *gorm.DB
|
||||
executeSQL = c.UnderlyingDB().Exec(generateSQL.String(), params...) // ignore_security_alert
|
||||
err = executeSQL.Error
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (c configBackupDo) Debug() *configBackupDo {
|
||||
return c.withDO(c.DO.Debug())
|
||||
}
|
||||
|
||||
func (c configBackupDo) WithContext(ctx context.Context) *configBackupDo {
|
||||
return c.withDO(c.DO.WithContext(ctx))
|
||||
}
|
||||
|
||||
func (c configBackupDo) ReadDB() *configBackupDo {
|
||||
return c.Clauses(dbresolver.Read)
|
||||
}
|
||||
|
||||
func (c configBackupDo) WriteDB() *configBackupDo {
|
||||
return c.Clauses(dbresolver.Write)
|
||||
}
|
||||
|
||||
func (c configBackupDo) Session(config *gorm.Session) *configBackupDo {
|
||||
return c.withDO(c.DO.Session(config))
|
||||
}
|
||||
|
||||
func (c configBackupDo) Clauses(conds ...clause.Expression) *configBackupDo {
|
||||
return c.withDO(c.DO.Clauses(conds...))
|
||||
}
|
||||
|
||||
func (c configBackupDo) Returning(value interface{}, columns ...string) *configBackupDo {
|
||||
return c.withDO(c.DO.Returning(value, columns...))
|
||||
}
|
||||
|
||||
func (c configBackupDo) Not(conds ...gen.Condition) *configBackupDo {
|
||||
return c.withDO(c.DO.Not(conds...))
|
||||
}
|
||||
|
||||
func (c configBackupDo) Or(conds ...gen.Condition) *configBackupDo {
|
||||
return c.withDO(c.DO.Or(conds...))
|
||||
}
|
||||
|
||||
func (c configBackupDo) Select(conds ...field.Expr) *configBackupDo {
|
||||
return c.withDO(c.DO.Select(conds...))
|
||||
}
|
||||
|
||||
func (c configBackupDo) Where(conds ...gen.Condition) *configBackupDo {
|
||||
return c.withDO(c.DO.Where(conds...))
|
||||
}
|
||||
|
||||
func (c configBackupDo) Exists(subquery interface{ UnderlyingDB() *gorm.DB }) *configBackupDo {
|
||||
return c.Where(field.CompareSubQuery(field.ExistsOp, nil, subquery.UnderlyingDB()))
|
||||
}
|
||||
|
||||
func (c configBackupDo) Order(conds ...field.Expr) *configBackupDo {
|
||||
return c.withDO(c.DO.Order(conds...))
|
||||
}
|
||||
|
||||
func (c configBackupDo) Distinct(cols ...field.Expr) *configBackupDo {
|
||||
return c.withDO(c.DO.Distinct(cols...))
|
||||
}
|
||||
|
||||
func (c configBackupDo) Omit(cols ...field.Expr) *configBackupDo {
|
||||
return c.withDO(c.DO.Omit(cols...))
|
||||
}
|
||||
|
||||
func (c configBackupDo) Join(table schema.Tabler, on ...field.Expr) *configBackupDo {
|
||||
return c.withDO(c.DO.Join(table, on...))
|
||||
}
|
||||
|
||||
func (c configBackupDo) LeftJoin(table schema.Tabler, on ...field.Expr) *configBackupDo {
|
||||
return c.withDO(c.DO.LeftJoin(table, on...))
|
||||
}
|
||||
|
||||
func (c configBackupDo) RightJoin(table schema.Tabler, on ...field.Expr) *configBackupDo {
|
||||
return c.withDO(c.DO.RightJoin(table, on...))
|
||||
}
|
||||
|
||||
func (c configBackupDo) Group(cols ...field.Expr) *configBackupDo {
|
||||
return c.withDO(c.DO.Group(cols...))
|
||||
}
|
||||
|
||||
func (c configBackupDo) Having(conds ...gen.Condition) *configBackupDo {
|
||||
return c.withDO(c.DO.Having(conds...))
|
||||
}
|
||||
|
||||
func (c configBackupDo) Limit(limit int) *configBackupDo {
|
||||
return c.withDO(c.DO.Limit(limit))
|
||||
}
|
||||
|
||||
func (c configBackupDo) Offset(offset int) *configBackupDo {
|
||||
return c.withDO(c.DO.Offset(offset))
|
||||
}
|
||||
|
||||
func (c configBackupDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *configBackupDo {
|
||||
return c.withDO(c.DO.Scopes(funcs...))
|
||||
}
|
||||
|
||||
func (c configBackupDo) Unscoped() *configBackupDo {
|
||||
return c.withDO(c.DO.Unscoped())
|
||||
}
|
||||
|
||||
func (c configBackupDo) Create(values ...*model.ConfigBackup) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return c.DO.Create(values)
|
||||
}
|
||||
|
||||
func (c configBackupDo) CreateInBatches(values []*model.ConfigBackup, batchSize int) error {
|
||||
return c.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 (c configBackupDo) Save(values ...*model.ConfigBackup) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return c.DO.Save(values)
|
||||
}
|
||||
|
||||
func (c configBackupDo) First() (*model.ConfigBackup, error) {
|
||||
if result, err := c.DO.First(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.ConfigBackup), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c configBackupDo) Take() (*model.ConfigBackup, error) {
|
||||
if result, err := c.DO.Take(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.ConfigBackup), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c configBackupDo) Last() (*model.ConfigBackup, error) {
|
||||
if result, err := c.DO.Last(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.ConfigBackup), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c configBackupDo) Find() ([]*model.ConfigBackup, error) {
|
||||
result, err := c.DO.Find()
|
||||
return result.([]*model.ConfigBackup), err
|
||||
}
|
||||
|
||||
func (c configBackupDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.ConfigBackup, err error) {
|
||||
buf := make([]*model.ConfigBackup, 0, batchSize)
|
||||
err = c.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 (c configBackupDo) FindInBatches(result *[]*model.ConfigBackup, batchSize int, fc func(tx gen.Dao, batch int) error) error {
|
||||
return c.DO.FindInBatches(result, batchSize, fc)
|
||||
}
|
||||
|
||||
func (c configBackupDo) Attrs(attrs ...field.AssignExpr) *configBackupDo {
|
||||
return c.withDO(c.DO.Attrs(attrs...))
|
||||
}
|
||||
|
||||
func (c configBackupDo) Assign(attrs ...field.AssignExpr) *configBackupDo {
|
||||
return c.withDO(c.DO.Assign(attrs...))
|
||||
}
|
||||
|
||||
func (c configBackupDo) Joins(fields ...field.RelationField) *configBackupDo {
|
||||
for _, _f := range fields {
|
||||
c = *c.withDO(c.DO.Joins(_f))
|
||||
}
|
||||
return &c
|
||||
}
|
||||
|
||||
func (c configBackupDo) Preload(fields ...field.RelationField) *configBackupDo {
|
||||
for _, _f := range fields {
|
||||
c = *c.withDO(c.DO.Preload(_f))
|
||||
}
|
||||
return &c
|
||||
}
|
||||
|
||||
func (c configBackupDo) FirstOrInit() (*model.ConfigBackup, error) {
|
||||
if result, err := c.DO.FirstOrInit(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.ConfigBackup), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c configBackupDo) FirstOrCreate() (*model.ConfigBackup, error) {
|
||||
if result, err := c.DO.FirstOrCreate(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.ConfigBackup), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c configBackupDo) FindByPage(offset int, limit int) (result []*model.ConfigBackup, count int64, err error) {
|
||||
result, err = c.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 = c.Offset(-1).Limit(-1).Count()
|
||||
return
|
||||
}
|
||||
|
||||
func (c configBackupDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
|
||||
count, err = c.Count()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = c.Offset(offset).Limit(limit).Scan(result)
|
||||
return
|
||||
}
|
||||
|
||||
func (c configBackupDo) Scan(result interface{}) (err error) {
|
||||
return c.DO.Scan(result)
|
||||
}
|
||||
|
||||
func (c configBackupDo) Delete(models ...*model.ConfigBackup) (result gen.ResultInfo, err error) {
|
||||
return c.DO.Delete(models)
|
||||
}
|
||||
|
||||
func (c *configBackupDo) withDO(do gen.Dao) *configBackupDo {
|
||||
c.DO = *do.(*gen.DO)
|
||||
return c
|
||||
}
|
131
server/query/gen.go
Normal file
131
server/query/gen.go
Normal file
|
@ -0,0 +1,131 @@
|
|||
// 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"
|
||||
"database/sql"
|
||||
|
||||
"gorm.io/gorm"
|
||||
|
||||
"gorm.io/gen"
|
||||
|
||||
"gorm.io/plugin/dbresolver"
|
||||
)
|
||||
|
||||
var (
|
||||
Q = new(Query)
|
||||
Auth *auth
|
||||
AuthToken *authToken
|
||||
Cert *cert
|
||||
ChatGPTLog *chatGPTLog
|
||||
ConfigBackup *configBackup
|
||||
)
|
||||
|
||||
func SetDefault(db *gorm.DB, opts ...gen.DOOption) {
|
||||
*Q = *Use(db, opts...)
|
||||
Auth = &Q.Auth
|
||||
AuthToken = &Q.AuthToken
|
||||
Cert = &Q.Cert
|
||||
ChatGPTLog = &Q.ChatGPTLog
|
||||
ConfigBackup = &Q.ConfigBackup
|
||||
}
|
||||
|
||||
func Use(db *gorm.DB, opts ...gen.DOOption) *Query {
|
||||
return &Query{
|
||||
db: db,
|
||||
Auth: newAuth(db, opts...),
|
||||
AuthToken: newAuthToken(db, opts...),
|
||||
Cert: newCert(db, opts...),
|
||||
ChatGPTLog: newChatGPTLog(db, opts...),
|
||||
ConfigBackup: newConfigBackup(db, opts...),
|
||||
}
|
||||
}
|
||||
|
||||
type Query struct {
|
||||
db *gorm.DB
|
||||
|
||||
Auth auth
|
||||
AuthToken authToken
|
||||
Cert cert
|
||||
ChatGPTLog chatGPTLog
|
||||
ConfigBackup configBackup
|
||||
}
|
||||
|
||||
func (q *Query) Available() bool { return q.db != nil }
|
||||
|
||||
func (q *Query) clone(db *gorm.DB) *Query {
|
||||
return &Query{
|
||||
db: db,
|
||||
Auth: q.Auth.clone(db),
|
||||
AuthToken: q.AuthToken.clone(db),
|
||||
Cert: q.Cert.clone(db),
|
||||
ChatGPTLog: q.ChatGPTLog.clone(db),
|
||||
ConfigBackup: q.ConfigBackup.clone(db),
|
||||
}
|
||||
}
|
||||
|
||||
func (q *Query) ReadDB() *Query {
|
||||
return q.ReplaceDB(q.db.Clauses(dbresolver.Read))
|
||||
}
|
||||
|
||||
func (q *Query) WriteDB() *Query {
|
||||
return q.ReplaceDB(q.db.Clauses(dbresolver.Write))
|
||||
}
|
||||
|
||||
func (q *Query) ReplaceDB(db *gorm.DB) *Query {
|
||||
return &Query{
|
||||
db: db,
|
||||
Auth: q.Auth.replaceDB(db),
|
||||
AuthToken: q.AuthToken.replaceDB(db),
|
||||
Cert: q.Cert.replaceDB(db),
|
||||
ChatGPTLog: q.ChatGPTLog.replaceDB(db),
|
||||
ConfigBackup: q.ConfigBackup.replaceDB(db),
|
||||
}
|
||||
}
|
||||
|
||||
type queryCtx struct {
|
||||
Auth *authDo
|
||||
AuthToken *authTokenDo
|
||||
Cert *certDo
|
||||
ChatGPTLog *chatGPTLogDo
|
||||
ConfigBackup *configBackupDo
|
||||
}
|
||||
|
||||
func (q *Query) WithContext(ctx context.Context) *queryCtx {
|
||||
return &queryCtx{
|
||||
Auth: q.Auth.WithContext(ctx),
|
||||
AuthToken: q.AuthToken.WithContext(ctx),
|
||||
Cert: q.Cert.WithContext(ctx),
|
||||
ChatGPTLog: q.ChatGPTLog.WithContext(ctx),
|
||||
ConfigBackup: q.ConfigBackup.WithContext(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
func (q *Query) Transaction(fc func(tx *Query) error, opts ...*sql.TxOptions) error {
|
||||
return q.db.Transaction(func(tx *gorm.DB) error { return fc(q.clone(tx)) }, opts...)
|
||||
}
|
||||
|
||||
func (q *Query) Begin(opts ...*sql.TxOptions) *QueryTx {
|
||||
return &QueryTx{q.clone(q.db.Begin(opts...))}
|
||||
}
|
||||
|
||||
type QueryTx struct{ *Query }
|
||||
|
||||
func (q *QueryTx) Commit() error {
|
||||
return q.db.Commit().Error
|
||||
}
|
||||
|
||||
func (q *QueryTx) Rollback() error {
|
||||
return q.db.Rollback().Error
|
||||
}
|
||||
|
||||
func (q *QueryTx) SavePoint(name string) error {
|
||||
return q.db.SavePoint(name).Error
|
||||
}
|
||||
|
||||
func (q *QueryTx) RollbackTo(name string) error {
|
||||
return q.db.RollbackTo(name).Error
|
||||
}
|
9
server/query/query.go
Normal file
9
server/query/query.go
Normal file
|
@ -0,0 +1,9 @@
|
|||
package query
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func Init(db *gorm.DB) {
|
||||
SetDefault(db)
|
||||
}
|
|
@ -1,113 +1,117 @@
|
|||
package router
|
||||
|
||||
import (
|
||||
"github.com/0xJacky/Nginx-UI/server/api"
|
||||
"github.com/gin-contrib/static"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
"github.com/0xJacky/Nginx-UI/server/api"
|
||||
"github.com/gin-contrib/static"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func InitRouter() *gin.Engine {
|
||||
r := gin.New()
|
||||
r.Use(gin.Logger())
|
||||
r := gin.New()
|
||||
r.Use(gin.Logger())
|
||||
|
||||
r.Use(recovery())
|
||||
r.Use(recovery())
|
||||
|
||||
r.Use(cacheJs())
|
||||
r.Use(cacheJs())
|
||||
|
||||
r.Use(static.Serve("/", mustFS("")))
|
||||
r.Use(static.Serve("/", mustFS("")))
|
||||
|
||||
r.NoRoute(func(c *gin.Context) {
|
||||
c.Redirect(http.StatusMovedPermanently, "/")
|
||||
})
|
||||
r.NoRoute(func(c *gin.Context) {
|
||||
c.Redirect(http.StatusMovedPermanently, "/")
|
||||
})
|
||||
|
||||
root := r.Group("/api")
|
||||
{
|
||||
root.GET("install", api.InstallLockCheck)
|
||||
root.POST("install", api.InstallNginxUI)
|
||||
root := r.Group("/api")
|
||||
{
|
||||
root.GET("install", api.InstallLockCheck)
|
||||
root.POST("install", api.InstallNginxUI)
|
||||
|
||||
root.POST("/login", api.Login)
|
||||
root.DELETE("/logout", api.Logout)
|
||||
root.POST("/login", api.Login)
|
||||
root.DELETE("/logout", api.Logout)
|
||||
|
||||
g := root.Group("/", authRequired())
|
||||
{
|
||||
g.GET("analytic", api.Analytic)
|
||||
g.GET("analytic/init", api.GetAnalyticInit)
|
||||
g := root.Group("/", authRequired())
|
||||
{
|
||||
g.GET("analytic", api.Analytic)
|
||||
g.GET("analytic/init", api.GetAnalyticInit)
|
||||
|
||||
g.GET("users", api.GetUsers)
|
||||
g.GET("user/:id", api.GetUser)
|
||||
g.POST("user", api.AddUser)
|
||||
g.POST("user/:id", api.EditUser)
|
||||
g.DELETE("user/:id", api.DeleteUser)
|
||||
g.GET("users", api.GetUsers)
|
||||
g.GET("user/:id", api.GetUser)
|
||||
g.POST("user", api.AddUser)
|
||||
g.POST("user/:id", api.EditUser)
|
||||
g.DELETE("user/:id", api.DeleteUser)
|
||||
|
||||
g.GET("domains", api.GetDomains)
|
||||
g.GET("domain/:name", api.GetDomain)
|
||||
g.GET("domains", api.GetDomains)
|
||||
g.GET("domain/:name", api.GetDomain)
|
||||
|
||||
// Modify site configuration directly
|
||||
g.POST("domain/:name", api.SaveDomain)
|
||||
// Modify site configuration directly
|
||||
g.POST("domain/:name", api.SaveDomain)
|
||||
|
||||
// Transform NgxConf to nginx configuration
|
||||
g.POST("ngx/build_config", api.BuildNginxConfig)
|
||||
// Tokenized nginx configuration to NgxConf
|
||||
g.POST("ngx/tokenize_config", api.TokenizeNginxConfig)
|
||||
// Format nginx configuration code
|
||||
g.POST("ngx/format_code", api.FormatNginxConfig)
|
||||
// nginx reload
|
||||
g.POST("nginx/reload", api.ReloadNginx)
|
||||
// nginx restart
|
||||
g.POST("nginx/restart", api.RestartNginx)
|
||||
// nginx test
|
||||
g.POST("nginx/test", api.TestNginx)
|
||||
// nginx status
|
||||
g.GET("nginx/status", api.NginxStatus)
|
||||
// Transform NgxConf to nginx configuration
|
||||
g.POST("ngx/build_config", api.BuildNginxConfig)
|
||||
// Tokenized nginx configuration to NgxConf
|
||||
g.POST("ngx/tokenize_config", api.TokenizeNginxConfig)
|
||||
// Format nginx configuration code
|
||||
g.POST("ngx/format_code", api.FormatNginxConfig)
|
||||
// nginx reload
|
||||
g.POST("nginx/reload", api.ReloadNginx)
|
||||
// nginx restart
|
||||
g.POST("nginx/restart", api.RestartNginx)
|
||||
// nginx test
|
||||
g.POST("nginx/test", api.TestNginx)
|
||||
// nginx status
|
||||
g.GET("nginx/status", api.NginxStatus)
|
||||
|
||||
g.POST("domain/:name/enable", api.EnableDomain)
|
||||
g.POST("domain/:name/disable", api.DisableDomain)
|
||||
g.DELETE("domain/:name", api.DeleteDomain)
|
||||
// duplicate site
|
||||
g.POST("domain/:name/duplicate", api.DuplicateSite)
|
||||
g.GET("domain/:name/cert", api.IssueCert)
|
||||
g.POST("domain/:name/enable", api.EnableDomain)
|
||||
g.POST("domain/:name/disable", api.DisableDomain)
|
||||
g.DELETE("domain/:name", api.DeleteDomain)
|
||||
// duplicate site
|
||||
g.POST("domain/:name/duplicate", api.DuplicateSite)
|
||||
g.GET("domain/:name/cert", api.IssueCert)
|
||||
|
||||
g.GET("configs", api.GetConfigs)
|
||||
g.GET("config/*name", api.GetConfig)
|
||||
g.POST("config", api.AddConfig)
|
||||
g.POST("config/*name", api.EditConfig)
|
||||
g.GET("configs", api.GetConfigs)
|
||||
g.GET("config/*name", api.GetConfig)
|
||||
g.POST("config", api.AddConfig)
|
||||
g.POST("config/*name", api.EditConfig)
|
||||
|
||||
//g.GET("backups", api.GetFileBackupList)
|
||||
//g.GET("backup/:id", api.GetFileBackup)
|
||||
//g.GET("backups", api.GetFileBackupList)
|
||||
//g.GET("backup/:id", api.GetFileBackup)
|
||||
|
||||
g.GET("template", api.GetTemplate)
|
||||
g.GET("template/configs", api.GetTemplateConfList)
|
||||
g.GET("template/blocks", api.GetTemplateBlockList)
|
||||
g.GET("template/block/:name", api.GetTemplateBlock)
|
||||
g.GET("template", api.GetTemplate)
|
||||
g.GET("template/configs", api.GetTemplateConfList)
|
||||
g.GET("template/blocks", api.GetTemplateBlockList)
|
||||
g.GET("template/block/:name", api.GetTemplateBlock)
|
||||
|
||||
g.GET("certs", api.GetCertList)
|
||||
g.GET("cert/:id", api.GetCert)
|
||||
g.POST("cert", api.AddCert)
|
||||
g.POST("cert/:id", api.ModifyCert)
|
||||
g.DELETE("cert/:id", api.RemoveCert)
|
||||
// Add domain to auto-renew cert list
|
||||
g.POST("auto_cert/:name", api.AddDomainToAutoCert)
|
||||
// Delete domain from auto-renew cert list
|
||||
g.DELETE("auto_cert/:name", api.RemoveDomainFromAutoCert)
|
||||
g.GET("certs", api.GetCertList)
|
||||
g.GET("cert/:id", api.GetCert)
|
||||
g.POST("cert", api.AddCert)
|
||||
g.POST("cert/:id", api.ModifyCert)
|
||||
g.DELETE("cert/:id", api.RemoveCert)
|
||||
// Add domain to auto-renew cert list
|
||||
g.POST("auto_cert/:name", api.AddDomainToAutoCert)
|
||||
// Delete domain from auto-renew cert list
|
||||
g.DELETE("auto_cert/:name", api.RemoveDomainFromAutoCert)
|
||||
|
||||
// pty
|
||||
g.GET("pty", api.Pty)
|
||||
// pty
|
||||
g.GET("pty", api.Pty)
|
||||
|
||||
// Nginx log
|
||||
g.GET("nginx_log", api.NginxLog)
|
||||
g.POST("nginx_log", api.GetNginxLogPage)
|
||||
// Nginx log
|
||||
g.GET("nginx_log", api.NginxLog)
|
||||
g.POST("nginx_log", api.GetNginxLogPage)
|
||||
|
||||
// Settings
|
||||
g.GET("settings", api.GetSettings)
|
||||
g.POST("settings", api.SaveSettings)
|
||||
// Settings
|
||||
g.GET("settings", api.GetSettings)
|
||||
g.POST("settings", api.SaveSettings)
|
||||
|
||||
// Upgrade
|
||||
g.GET("upgrade/release", api.GetRelease)
|
||||
g.GET("upgrade/current", api.GetCurrentVersion)
|
||||
g.GET("upgrade/perform", api.PerformCoreUpgrade)
|
||||
}
|
||||
}
|
||||
// Upgrade
|
||||
g.GET("upgrade/release", api.GetRelease)
|
||||
g.GET("upgrade/current", api.GetCurrentVersion)
|
||||
g.GET("upgrade/perform", api.PerformCoreUpgrade)
|
||||
|
||||
return r
|
||||
// ChatGPT
|
||||
g.POST("/chat_gpt", api.MakeChatCompletionRequest)
|
||||
g.POST("/chat_gpt_record", api.StoreChatGPTRecord)
|
||||
}
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
|
|
@ -36,6 +36,13 @@ type NginxLog struct {
|
|||
ErrorLogPath string `json:"error_log_path"`
|
||||
}
|
||||
|
||||
type OpenAI struct {
|
||||
BaseUrl string `json:"base_url"`
|
||||
Token string `json:"token"`
|
||||
Proxy string `json:"proxy"`
|
||||
Model string `json:"model"`
|
||||
}
|
||||
|
||||
var ServerSettings = &Server{
|
||||
HttpPort: "9000",
|
||||
RunMode: "debug",
|
||||
|
@ -53,11 +60,14 @@ var NginxLogSettings = &NginxLog{
|
|||
ErrorLogPath: "",
|
||||
}
|
||||
|
||||
var OpenAISettings = &OpenAI{}
|
||||
|
||||
var ConfPath string
|
||||
|
||||
var sections = map[string]interface{}{
|
||||
"server": ServerSettings,
|
||||
"nginx_log": NginxLogSettings,
|
||||
"openai": OpenAISettings,
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
51
server/test/chatgpt_test.go
Normal file
51
server/test/chatgpt_test.go
Normal file
|
@ -0,0 +1,51 @@
|
|||
package test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/0xJacky/Nginx-UI/server/settings"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sashabaranov/go-openai"
|
||||
"io"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestChatGPT(t *testing.T) {
|
||||
settings.Init("../../app.ini")
|
||||
c := openai.NewClient(settings.OpenAISettings.Token)
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
req := openai.ChatCompletionRequest{
|
||||
Model: openai.GPT3Dot5Turbo0301,
|
||||
Messages: []openai.ChatCompletionMessage{
|
||||
{
|
||||
Role: openai.ChatMessageRoleUser,
|
||||
Content: "帮我写一个 nginx 配置文件的示例",
|
||||
},
|
||||
},
|
||||
Stream: true,
|
||||
}
|
||||
stream, err := c.CreateChatCompletionStream(ctx, req)
|
||||
if err != nil {
|
||||
fmt.Printf("CompletionStream error: %v\n", err)
|
||||
return
|
||||
}
|
||||
defer stream.Close()
|
||||
|
||||
for {
|
||||
response, err := stream.Recv()
|
||||
if errors.Is(err, io.EOF) {
|
||||
return
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("Stream error: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("%v", response.Choices[0].Delta.Content)
|
||||
_ = os.Stdout.Sync()
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue