mirror of
https://github.com/0xJacky/nginx-ui.git
synced 2025-05-11 02:15:48 +02:00
wip: entrance of ChatGPT
This commit is contained in:
parent
af1be98575
commit
8c1cdda305
8 changed files with 407 additions and 227 deletions
|
@ -46,6 +46,7 @@
|
|||
"unplugin-vue-components": "^0.22.12",
|
||||
"vite": "^4.1.4",
|
||||
"vite-plugin-html": "^3.2.0",
|
||||
"vite-svg-loader": "^4.0.0",
|
||||
"vue-tsc": "^1.0.24"
|
||||
}
|
||||
}
|
||||
|
|
1
frontend/src/assets/svg/ChatGPT_logo.svg
Normal file
1
frontend/src/assets/svg/ChatGPT_logo.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2406 2406"><path d="M1 578.4C1 259.5 259.5 1 578.4 1h1249.1c319 0 577.5 258.5 577.5 577.4V2406H578.4C259.5 2406 1 2147.5 1 1828.6V578.4z" fill="#74aa9c"/><path d="M1107.3 299.1c-198 0-373.9 127.3-435.2 315.3C544.8 640.6 434.9 720.2 370.5 833c-99.3 171.4-76.6 386.9 56.4 533.8-41.1 123.1-27 257.7 38.6 369.2 98.7 172 297.3 260.2 491.6 219.2 86.1 97 209.8 152.3 339.6 151.8 198 0 373.9-127.3 435.3-315.3 127.5-26.3 237.2-105.9 301-218.5 99.9-171.4 77.2-386.9-55.8-533.9v-.6c41.1-123.1 27-257.8-38.6-369.8-98.7-171.4-297.3-259.6-491-218.6-86.6-96.8-210.5-151.8-340.3-151.2zm0 117.5-.6.6c79.7 0 156.3 27.5 217.6 78.4-2.5 1.2-7.4 4.3-11 6.1L952.8 709.3c-18.4 10.4-29.4 30-29.4 51.4V1248l-155.1-89.4V755.8c-.1-187.1 151.6-338.9 339-339.2zm434.2 141.9c121.6-.2 234 64.5 294.7 169.8 39.2 68.6 53.9 148.8 40.4 226.5-2.5-1.8-7.3-4.3-10.4-6.1l-360.4-208.2c-18.4-10.4-41-10.4-59.4 0L1024 984.2V805.4L1372.7 604c51.3-29.7 109.5-45.4 168.8-45.5zM650 743.5v427.9c0 21.4 11 40.4 29.4 51.4l421.7 243-155.7 90L597.2 1355c-162-93.8-217.4-300.9-123.8-462.8C513.1 823.6 575.5 771 650 743.5zm807.9 106 348.8 200.8c162.5 93.7 217.6 300.6 123.8 462.8l.6.6c-39.8 68.6-102.4 121.2-176.5 148.2v-428c0-21.4-11-41-29.4-51.4l-422.3-243.7 155-89.3zM1201.7 997l177.8 102.8v205.1l-177.8 102.8-177.8-102.8v-205.1L1201.7 997zm279.5 161.6 155.1 89.4v402.2c0 187.3-152 339.2-339 339.2v-.6c-79.1 0-156.3-27.6-217-78.4 2.5-1.2 8-4.3 11-6.1l360.4-207.5c18.4-10.4 30-30 29.4-51.4l.1-486.8zM1380 1421.9v178.8l-348.8 200.8c-162.5 93.1-369.6 38-463.4-123.7h.6c-39.8-68-54-148.8-40.5-226.5 2.5 1.8 7.4 4.3 10.4 6.1l360.4 208.2c18.4 10.4 41 10.4 59.4 0l421.9-243.7z" fill="white"/></svg>
|
After Width: | Height: | Size: 1.7 KiB |
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import {computed, ref, watch} from 'vue'
|
||||
import {computed, onMounted, ref, watch} from 'vue'
|
||||
import {useGettext} from 'vue3-gettext'
|
||||
import {useUserStore} from '@/pinia'
|
||||
import {storeToRefs} from 'pinia'
|
||||
|
@ -10,12 +10,20 @@ 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'
|
||||
import ChatGPT_logo from '@/assets/svg/ChatGPT_logo.svg'
|
||||
import Icon from '@ant-design/icons-vue'
|
||||
|
||||
const {$gettext} = useGettext()
|
||||
|
||||
const props = defineProps(['content', 'path', 'history_messages'])
|
||||
const emit = defineEmits(['update:history_messages'])
|
||||
const history_messages = computed(() => props.history_messages)
|
||||
|
||||
watch(computed(() => props.history_messages), () => {
|
||||
onMounted(() => {
|
||||
messages.value = props.history_messages
|
||||
})
|
||||
|
||||
watch(history_messages, () => {
|
||||
messages.value = props.history_messages
|
||||
})
|
||||
|
||||
|
@ -99,6 +107,9 @@ async function request() {
|
|||
}
|
||||
|
||||
async function send() {
|
||||
if (!messages.value) {
|
||||
messages.value = []
|
||||
}
|
||||
if (messages.value.length === 0) {
|
||||
messages.value.push({
|
||||
role: 'user',
|
||||
|
@ -145,6 +156,7 @@ function clear_record() {
|
|||
messages: []
|
||||
})
|
||||
messages.value = []
|
||||
emit('update:history_messages', [])
|
||||
}
|
||||
|
||||
async function regenerate(index: number) {
|
||||
|
@ -154,73 +166,88 @@ async function regenerate(index: number) {
|
|||
}
|
||||
|
||||
const editing_idx = ref(-1)
|
||||
|
||||
const button_shape = computed(() => loading.value ? 'square' : 'circle')
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-card title="ChatGPT">
|
||||
<a-card class="chatgpt" title="ChatGPT" v-if="messages?.length>1">
|
||||
<div class="chatgpt-container">
|
||||
<template v-if="messages?.length>0">
|
||||
<a-list
|
||||
class="chatgpt-log"
|
||||
item-layout="horizontal"
|
||||
:data-source="messages"
|
||||
>
|
||||
<template #renderItem="{ item, index }">
|
||||
<a-list-item>
|
||||
<a-comment :author="item.role" :avatar="item.avatar">
|
||||
<template #content>
|
||||
<div class="content" v-if="item.role==='assistant'||editing_idx!=index"
|
||||
v-html="marked.parse(item.content)"></div>
|
||||
<a-input style="padding: 0" v-else v-model:value="item.content"
|
||||
:bordered="false"/>
|
||||
</template>
|
||||
<template #actions>
|
||||
<a-list
|
||||
class="chatgpt-log"
|
||||
item-layout="horizontal"
|
||||
:data-source="messages"
|
||||
>
|
||||
<template #renderItem="{ item, index }">
|
||||
<a-list-item>
|
||||
<a-comment :author="item.role" :avatar="item.avatar">
|
||||
<template #content>
|
||||
<div class="content" v-if="item.role==='assistant'||editing_idx!=index"
|
||||
v-html="marked.parse(item.content)"></div>
|
||||
<a-input style="padding: 0" v-else v-model:value="item.content"
|
||||
:bordered="false"/>
|
||||
</template>
|
||||
<template #actions>
|
||||
<span v-if="item.role==='user'&&editing_idx!==index" @click="editing_idx=index">
|
||||
{{ $gettext('Modify') }}
|
||||
</span>
|
||||
<template v-else-if="editing_idx==index">
|
||||
<span @click="regenerate(index+1)">{{ $gettext('Save') }}</span>
|
||||
<span @click="editing_idx=-1">{{ $gettext('Cancel') }}</span>
|
||||
</template>
|
||||
<span v-else-if="!loading" @click="regenerate(index)" :disabled="loading">
|
||||
<template v-else-if="editing_idx==index">
|
||||
<span @click="regenerate(index+1)">{{ $gettext('Save') }}</span>
|
||||
<span @click="editing_idx=-1">{{ $gettext('Cancel') }}</span>
|
||||
</template>
|
||||
<span v-else-if="!loading" @click="regenerate(index)" :disabled="loading">
|
||||
{{ $gettext('Reload') }}
|
||||
</span>
|
||||
</template>
|
||||
</a-comment>
|
||||
</a-list-item>
|
||||
</template>
|
||||
</a-list>
|
||||
<div class="input-msg">
|
||||
<div class="control-btn">
|
||||
<a-space v-show="!loading">
|
||||
<a-popconfirm
|
||||
:cancelText="$gettext('No')"
|
||||
:okText="$gettext('OK')"
|
||||
:title="$gettext('Are you sure you want to clear the record of chat?')"
|
||||
@confirm="clear_record">
|
||||
<a-button type="text">{{ $gettext('Clear') }}</a-button>
|
||||
</a-popconfirm>
|
||||
<a-button type="text" @click="regenerate(messages?.length-1)">
|
||||
{{ $gettext('Regenerate response') }}
|
||||
</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
<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/>
|
||||
</template>
|
||||
</a-comment>
|
||||
</a-list-item>
|
||||
</template>
|
||||
</a-list>
|
||||
<div class="input-msg">
|
||||
<div class="control-btn">
|
||||
<a-space v-show="!loading">
|
||||
<a-popconfirm
|
||||
:cancelText="$gettext('No')"
|
||||
:okText="$gettext('OK')"
|
||||
:title="$gettext('Are you sure you want to clear the record of chat?')"
|
||||
@confirm="clear_record">
|
||||
<a-button type="text">{{ $gettext('Clear') }}</a-button>
|
||||
</a-popconfirm>
|
||||
<a-button type="text" @click="regenerate(messages?.length-1)">
|
||||
{{ $gettext('Regenerate response') }}
|
||||
</a-button>
|
||||
</div>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a-button @click="send">{{ $gettext('Chat with ChatGPT') }}</a-button>
|
||||
</template>
|
||||
<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>
|
||||
</div>
|
||||
</a-card>
|
||||
<template v-else>
|
||||
<div class="chat-start">
|
||||
<a-button size="large" shape="circle" @click="send" :loading="loading">
|
||||
<Icon v-if="!loading" :component="ChatGPT_logo"/>
|
||||
</a-button>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.chatgpt {
|
||||
position: sticky;
|
||||
top: 78px;
|
||||
}
|
||||
|
||||
.chat-start {
|
||||
position: fixed !important;
|
||||
right: 36px;
|
||||
bottom: 78px;
|
||||
}
|
||||
|
||||
.chatgpt-container {
|
||||
margin: 0 auto;
|
||||
max-width: 800px;
|
||||
|
|
|
@ -162,10 +162,13 @@ function on_change_enabled(checked: boolean) {
|
|||
disable()
|
||||
}
|
||||
}
|
||||
|
||||
const editor_md = computed(() => history_chatgpt_record?.value?.length > 1 ? 16 : 24)
|
||||
const chat_md = computed(() => history_chatgpt_record?.value?.length > 1 ? 8 : 24)
|
||||
</script>
|
||||
<template>
|
||||
<a-row :gutter="16">
|
||||
<a-col :xs="24" :sm="24" :md="16">
|
||||
<a-col :xs="24" :sm="24" :md="editor_md">
|
||||
<a-card :bordered="false">
|
||||
<template #title>
|
||||
<span style="margin-right: 10px">{{ interpolate($gettext('Edit %{n}'), {n: name}) }}</span>
|
||||
|
@ -225,9 +228,9 @@ function on_change_enabled(checked: boolean) {
|
|||
</a-card>
|
||||
</a-col>
|
||||
|
||||
<a-col class="col-right" :xs="24" :sm="24" :md="8">
|
||||
<chat-g-p-t class="chatgpt" :content="configText" :path="ngx_config.file_name"
|
||||
:history_messages="history_chatgpt_record"/>
|
||||
<a-col class="col-right" :xs="24" :sm="24" :md="chat_md">
|
||||
<chat-g-p-t :content="configText" :path="ngx_config.file_name"
|
||||
v-model:history_messages="history_chatgpt_record"/>
|
||||
</a-col>
|
||||
|
||||
<footer-tool-bar>
|
||||
|
@ -250,11 +253,6 @@ function on_change_enabled(checked: boolean) {
|
|||
<style lang="less" scoped>
|
||||
.col-right {
|
||||
position: relative;
|
||||
|
||||
.chatgpt {
|
||||
position: sticky;
|
||||
top: 78px;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-card {
|
||||
|
|
|
@ -6,6 +6,7 @@ import {AntDesignVueResolver} from 'unplugin-vue-components/resolvers'
|
|||
import {fileURLToPath, URL} from 'url'
|
||||
import vueJsx from '@vitejs/plugin-vue-jsx'
|
||||
import vitePluginBuildId from 'vite-plugin-build-id'
|
||||
import svgLoader from 'vite-svg-loader'
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
|
@ -25,7 +26,7 @@ export default defineConfig({
|
|||
'.less'
|
||||
]
|
||||
},
|
||||
plugins: [vue(), vueJsx(), vitePluginBuildId(),
|
||||
plugins: [vue(), vueJsx(), vitePluginBuildId(), svgLoader(),
|
||||
Components({
|
||||
resolvers: [AntDesignVueResolver({importStyle: false})],
|
||||
directoryAsNamespace: true
|
||||
|
|
|
@ -864,6 +864,16 @@
|
|||
estree-walker "^2.0.2"
|
||||
source-map "^0.6.1"
|
||||
|
||||
"@vue/compiler-core@3.2.47":
|
||||
version "3.2.47"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.2.47.tgz#3e07c684d74897ac9aa5922c520741f3029267f8"
|
||||
integrity sha512-p4D7FDnQb7+YJmO2iPEv0SQNeNzcbHdGByJDsT4lynf63AFkOTFN07HsiRSvjGo0QrxR/o3d0hUyNCUnBU2Tig==
|
||||
dependencies:
|
||||
"@babel/parser" "^7.16.4"
|
||||
"@vue/shared" "3.2.47"
|
||||
estree-walker "^2.0.2"
|
||||
source-map "^0.6.1"
|
||||
|
||||
"@vue/compiler-dom@3.2.37":
|
||||
version "3.2.37"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.2.37.tgz#10d2427a789e7c707c872da9d678c82a0c6582b5"
|
||||
|
@ -880,6 +890,14 @@
|
|||
"@vue/compiler-core" "3.2.45"
|
||||
"@vue/shared" "3.2.45"
|
||||
|
||||
"@vue/compiler-dom@3.2.47":
|
||||
version "3.2.47"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.2.47.tgz#a0b06caf7ef7056939e563dcaa9cbde30794f305"
|
||||
integrity sha512-dBBnEHEPoftUiS03a4ggEig74J2YBZ2UIeyfpcRM2tavgMWo4bsEfgCGsu+uJIL/vax9S+JztH8NmQerUo7shQ==
|
||||
dependencies:
|
||||
"@vue/compiler-core" "3.2.47"
|
||||
"@vue/shared" "3.2.47"
|
||||
|
||||
"@vue/compiler-sfc@3.2.37":
|
||||
version "3.2.37"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.37.tgz#3103af3da2f40286edcd85ea495dcb35bc7f5ff4"
|
||||
|
@ -912,6 +930,22 @@
|
|||
postcss "^8.1.10"
|
||||
source-map "^0.6.1"
|
||||
|
||||
"@vue/compiler-sfc@^3.2.20":
|
||||
version "3.2.47"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.47.tgz#1bdc36f6cdc1643f72e2c397eb1a398f5004ad3d"
|
||||
integrity sha512-rog05W+2IFfxjMcFw10tM9+f7i/+FFpZJJ5XHX72NP9eC2uRD+42M3pYcQqDXVYoj74kHMSEdQ/WmCjt8JFksQ==
|
||||
dependencies:
|
||||
"@babel/parser" "^7.16.4"
|
||||
"@vue/compiler-core" "3.2.47"
|
||||
"@vue/compiler-dom" "3.2.47"
|
||||
"@vue/compiler-ssr" "3.2.47"
|
||||
"@vue/reactivity-transform" "3.2.47"
|
||||
"@vue/shared" "3.2.47"
|
||||
estree-walker "^2.0.2"
|
||||
magic-string "^0.25.7"
|
||||
postcss "^8.1.10"
|
||||
source-map "^0.6.1"
|
||||
|
||||
"@vue/compiler-ssr@3.2.37":
|
||||
version "3.2.37"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.2.37.tgz#4899d19f3a5fafd61524a9d1aee8eb0505313cff"
|
||||
|
@ -928,6 +962,14 @@
|
|||
"@vue/compiler-dom" "3.2.45"
|
||||
"@vue/shared" "3.2.45"
|
||||
|
||||
"@vue/compiler-ssr@3.2.47":
|
||||
version "3.2.47"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.2.47.tgz#35872c01a273aac4d6070ab9d8da918ab13057ee"
|
||||
integrity sha512-wVXC+gszhulcMD8wpxMsqSOpvDZ6xKXSVWkf50Guf/S+28hTAXPDYRTbLQ3EDkOP5Xz/+SY37YiwDquKbJOgZw==
|
||||
dependencies:
|
||||
"@vue/compiler-dom" "3.2.47"
|
||||
"@vue/shared" "3.2.47"
|
||||
|
||||
"@vue/devtools-api@^6.1.4":
|
||||
version "6.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.2.1.tgz#6f2948ff002ec46df01420dfeff91de16c5b4092"
|
||||
|
@ -960,6 +1002,17 @@
|
|||
estree-walker "^2.0.2"
|
||||
magic-string "^0.25.7"
|
||||
|
||||
"@vue/reactivity-transform@3.2.47":
|
||||
version "3.2.47"
|
||||
resolved "https://registry.yarnpkg.com/@vue/reactivity-transform/-/reactivity-transform-3.2.47.tgz#e45df4d06370f8abf29081a16afd25cffba6d84e"
|
||||
integrity sha512-m8lGXw8rdnPVVIdIFhf0LeQ/ixyHkH5plYuS83yop5n7ggVJU+z5v0zecwEnX7fa7HNLBhh2qngJJkxpwEEmYA==
|
||||
dependencies:
|
||||
"@babel/parser" "^7.16.4"
|
||||
"@vue/compiler-core" "3.2.47"
|
||||
"@vue/shared" "3.2.47"
|
||||
estree-walker "^2.0.2"
|
||||
magic-string "^0.25.7"
|
||||
|
||||
"@vue/reactivity@3.2.37":
|
||||
version "3.2.37"
|
||||
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.2.37.tgz#5bc3847ac58828e2b78526e08219e0a1089f8848"
|
||||
|
@ -1034,6 +1087,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.45.tgz#a3fffa7489eafff38d984e23d0236e230c818bc2"
|
||||
integrity sha512-Ewzq5Yhimg7pSztDV+RH1UDKBzmtqieXQlpTVm2AwraoRL/Rks96mvd8Vgi7Lj+h+TH8dv7mXD3FRZR3TUvbSg==
|
||||
|
||||
"@vue/shared@3.2.47":
|
||||
version "3.2.47"
|
||||
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.47.tgz#e597ef75086c6e896ff5478a6bfc0a7aa4bbd14c"
|
||||
integrity sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ==
|
||||
|
||||
"@zougt/some-loader-utils@^1.4.3":
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/@zougt/some-loader-utils/-/some-loader-utils-1.4.3.tgz#41cf762b291ab9697f8c008bdeebaf80eaee4714"
|
||||
|
@ -1462,6 +1520,17 @@ css-select@^4.1.3, css-select@^4.2.1:
|
|||
domutils "^2.8.0"
|
||||
nth-check "^2.0.1"
|
||||
|
||||
css-select@^5.1.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6"
|
||||
integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==
|
||||
dependencies:
|
||||
boolbase "^1.0.0"
|
||||
css-what "^6.1.0"
|
||||
domhandler "^5.0.2"
|
||||
domutils "^3.0.1"
|
||||
nth-check "^2.0.1"
|
||||
|
||||
css-selector-parser@^1.3:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/css-selector-parser/-/css-selector-parser-1.4.1.tgz#03f9cb8a81c3e5ab2c51684557d5aaf6d2569759"
|
||||
|
@ -1475,7 +1544,23 @@ css-tree@^1.1.2, css-tree@^1.1.3:
|
|||
mdn-data "2.0.14"
|
||||
source-map "^0.6.1"
|
||||
|
||||
css-what@^6.0.1:
|
||||
css-tree@^2.2.1:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.3.1.tgz#10264ce1e5442e8572fc82fbe490644ff54b5c20"
|
||||
integrity sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==
|
||||
dependencies:
|
||||
mdn-data "2.0.30"
|
||||
source-map-js "^1.0.1"
|
||||
|
||||
css-tree@~2.2.0:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.2.1.tgz#36115d382d60afd271e377f9c5f67d02bd48c032"
|
||||
integrity sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==
|
||||
dependencies:
|
||||
mdn-data "2.0.28"
|
||||
source-map-js "^1.0.1"
|
||||
|
||||
css-what@^6.0.1, css-what@^6.1.0:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4"
|
||||
integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==
|
||||
|
@ -1551,6 +1636,13 @@ csso@^4.2.0:
|
|||
dependencies:
|
||||
css-tree "^1.1.2"
|
||||
|
||||
csso@^5.0.5:
|
||||
version "5.0.5"
|
||||
resolved "https://registry.yarnpkg.com/csso/-/csso-5.0.5.tgz#f9b7fe6cc6ac0b7d90781bb16d5e9874303e2ca6"
|
||||
integrity sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==
|
||||
dependencies:
|
||||
css-tree "~2.2.0"
|
||||
|
||||
csstype@^2.6.8:
|
||||
version "2.6.20"
|
||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.20.tgz#9229c65ea0b260cf4d3d997cb06288e36a8d6dda"
|
||||
|
@ -1609,7 +1701,16 @@ dom-serializer@^1.0.1:
|
|||
domhandler "^4.2.0"
|
||||
entities "^2.0.0"
|
||||
|
||||
domelementtype@^2.0.1, domelementtype@^2.2.0:
|
||||
dom-serializer@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53"
|
||||
integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==
|
||||
dependencies:
|
||||
domelementtype "^2.3.0"
|
||||
domhandler "^5.0.2"
|
||||
entities "^4.2.0"
|
||||
|
||||
domelementtype@^2.0.1, domelementtype@^2.2.0, domelementtype@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d"
|
||||
integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==
|
||||
|
@ -1621,6 +1722,13 @@ domhandler@^4.2.0, domhandler@^4.3.1:
|
|||
dependencies:
|
||||
domelementtype "^2.2.0"
|
||||
|
||||
domhandler@^5.0.1, domhandler@^5.0.2:
|
||||
version "5.0.3"
|
||||
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31"
|
||||
integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==
|
||||
dependencies:
|
||||
domelementtype "^2.3.0"
|
||||
|
||||
domutils@^2.8.0:
|
||||
version "2.8.0"
|
||||
resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135"
|
||||
|
@ -1630,6 +1738,15 @@ domutils@^2.8.0:
|
|||
domelementtype "^2.2.0"
|
||||
domhandler "^4.2.0"
|
||||
|
||||
domutils@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.0.1.tgz#696b3875238338cb186b6c0612bd4901c89a4f1c"
|
||||
integrity sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==
|
||||
dependencies:
|
||||
dom-serializer "^2.0.0"
|
||||
domelementtype "^2.3.0"
|
||||
domhandler "^5.0.1"
|
||||
|
||||
dot-case@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751"
|
||||
|
@ -1670,6 +1787,11 @@ entities@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
|
||||
integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==
|
||||
|
||||
entities@^4.2.0:
|
||||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/entities/-/entities-4.4.0.tgz#97bdaba170339446495e653cfd2db78962900174"
|
||||
integrity sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==
|
||||
|
||||
errno@^0.1.1:
|
||||
version "0.1.8"
|
||||
resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f"
|
||||
|
@ -2168,6 +2290,16 @@ mdn-data@2.0.14:
|
|||
resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50"
|
||||
integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==
|
||||
|
||||
mdn-data@2.0.28:
|
||||
version "2.0.28"
|
||||
resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.28.tgz#5ec48e7bef120654539069e1ae4ddc81ca490eba"
|
||||
integrity sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==
|
||||
|
||||
mdn-data@2.0.30:
|
||||
version "2.0.30"
|
||||
resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.30.tgz#ce4df6f80af6cfbe218ecd5c552ba13c4dfa08cc"
|
||||
integrity sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==
|
||||
|
||||
merge2@^1.3.0:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
|
||||
|
@ -2791,7 +2923,7 @@ sortablejs@1.14.0:
|
|||
resolved "https://registry.yarnpkg.com/sortablejs/-/sortablejs-1.14.0.tgz#6d2e17ccbdb25f464734df621d4f35d4ab35b3d8"
|
||||
integrity sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w==
|
||||
|
||||
source-map-js@^1.0.2:
|
||||
source-map-js@^1.0.1, source-map-js@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
|
||||
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
|
||||
|
@ -2924,6 +3056,18 @@ svgo@^2.7.0:
|
|||
picocolors "^1.0.0"
|
||||
stable "^0.1.8"
|
||||
|
||||
svgo@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/svgo/-/svgo-3.0.2.tgz#5e99eeea42c68ee0dc46aa16da093838c262fe0a"
|
||||
integrity sha512-Z706C1U2pb1+JGP48fbazf3KxHrWOsLme6Rv7imFBn5EnuanDW1GPaA/P1/dvObE670JDePC3mnj0k0B7P0jjQ==
|
||||
dependencies:
|
||||
"@trysound/sax" "0.2.0"
|
||||
commander "^7.2.0"
|
||||
css-select "^5.1.0"
|
||||
css-tree "^2.2.1"
|
||||
csso "^5.0.5"
|
||||
picocolors "^1.0.0"
|
||||
|
||||
terser@^5.10.0:
|
||||
version "5.14.2"
|
||||
resolved "https://registry.yarnpkg.com/terser/-/terser-5.14.2.tgz#9ac9f22b06994d736174f4091aa368db896f1c10"
|
||||
|
@ -3051,6 +3195,14 @@ vite-plugin-html@^3.2.0:
|
|||
node-html-parser "^5.3.3"
|
||||
pathe "^0.2.0"
|
||||
|
||||
vite-svg-loader@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/vite-svg-loader/-/vite-svg-loader-4.0.0.tgz#1cec4337dba3c23ab13bcabb111896e251b047ac"
|
||||
integrity sha512-0MMf1yzzSYlV4MGePsLVAOqXsbF5IVxbn4EEzqRnWxTQl8BJg/cfwIzfQNmNQxZp5XXwd4kyRKF1LytuHZTnqA==
|
||||
dependencies:
|
||||
"@vue/compiler-sfc" "^3.2.20"
|
||||
svgo "^3.0.2"
|
||||
|
||||
vite@^4.0.4:
|
||||
version "4.0.4"
|
||||
resolved "https://registry.npmmirror.com/vite/-/vite-4.0.4.tgz#4612ce0b47bbb233a887a54a4ae0c6e240a0da31"
|
||||
|
|
|
@ -1,160 +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"
|
||||
"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"`
|
||||
}
|
||||
var json struct {
|
||||
Messages []openai.ChatCompletionMessage `json:"messages"`
|
||||
}
|
||||
|
||||
if !BindAndValid(c, &json) {
|
||||
return
|
||||
}
|
||||
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)
|
||||
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)
|
||||
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.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
|
||||
}
|
||||
if settings.OpenAISettings.BaseUrl != "" {
|
||||
config.BaseURL = settings.OpenAISettings.BaseUrl
|
||||
}
|
||||
|
||||
openaiClient := openai.NewClientWithConfig(config)
|
||||
ctx := context.Background()
|
||||
openaiClient := openai.NewClientWithConfig(config)
|
||||
ctx := context.Background()
|
||||
|
||||
req := openai.ChatCompletionRequest{
|
||||
Model: settings.OpenAISettings.Model,
|
||||
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
|
||||
}
|
||||
req := openai.ChatCompletionRequest{
|
||||
Model: settings.OpenAISettings.Model,
|
||||
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
|
||||
}
|
||||
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()
|
||||
// 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
|
||||
}
|
||||
}()
|
||||
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
|
||||
})
|
||||
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"`
|
||||
}
|
||||
var json struct {
|
||||
FileName string `json:"file_name"`
|
||||
Messages []openai.ChatCompletionMessage `json:"messages"`
|
||||
}
|
||||
|
||||
if !BindAndValid(c, &json) {
|
||||
return
|
||||
}
|
||||
if !BindAndValid(c, &json) {
|
||||
return
|
||||
}
|
||||
|
||||
name := json.FileName
|
||||
g := query.ChatGPTLog
|
||||
_, err := g.Where(g.Name.Eq(name)).FirstOrCreate()
|
||||
name := json.FileName
|
||||
g := query.ChatGPTLog
|
||||
_, err := g.Where(g.Name.Eq(name)).FirstOrCreate()
|
||||
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
_, err = g.Where(g.Name.Eq(name)).Updates(&model.ChatGPTLog{
|
||||
Name: name,
|
||||
Content: json.Messages,
|
||||
})
|
||||
_, err = g.Where(g.Name.Eq(name)).Updates(&model.ChatGPTLog{
|
||||
Name: name,
|
||||
Content: json.Messages,
|
||||
})
|
||||
|
||||
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",
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,45 +1,45 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"github.com/0xJacky/Nginx-UI/server/settings"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
"github.com/0xJacky/Nginx-UI/server/settings"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func GetSettings(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"server": settings.ServerSettings,
|
||||
"nginx_log": settings.NginxLogSettings,
|
||||
"openai": settings.OpenAISettings,
|
||||
})
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"server": settings.ServerSettings,
|
||||
"nginx_log": settings.NginxLogSettings,
|
||||
"openai": settings.OpenAISettings,
|
||||
})
|
||||
}
|
||||
|
||||
func SaveSettings(c *gin.Context) {
|
||||
var json struct {
|
||||
Server settings.Server `json:"server"`
|
||||
NginxLog settings.NginxLog `json:"nginx_log"`
|
||||
Openai settings.OpenAI `json:"openai"`
|
||||
}
|
||||
var json struct {
|
||||
Server settings.Server `json:"server"`
|
||||
NginxLog settings.NginxLog `json:"nginx_log"`
|
||||
Openai settings.OpenAI `json:"openai"`
|
||||
}
|
||||
|
||||
if !BindAndValid(c, &json) {
|
||||
return
|
||||
}
|
||||
if !BindAndValid(c, &json) {
|
||||
return
|
||||
}
|
||||
|
||||
settings.Conf.Section("server").Key("Email").SetValue(json.Server.Email)
|
||||
settings.Conf.Section("server").Key("HTTPChallengePort").SetValue(json.Server.HTTPChallengePort)
|
||||
settings.Conf.Section("nginx_log").Key("AccessLogPath").SetValue(json.NginxLog.AccessLogPath)
|
||||
settings.Conf.Section("nginx_log").Key("ErrorLogPath").SetValue(json.NginxLog.ErrorLogPath)
|
||||
settings.Conf.Section("server").Key("Email").SetValue(json.Server.Email)
|
||||
settings.Conf.Section("server").Key("HTTPChallengePort").SetValue(json.Server.HTTPChallengePort)
|
||||
settings.Conf.Section("nginx_log").Key("AccessLogPath").SetValue(json.NginxLog.AccessLogPath)
|
||||
settings.Conf.Section("nginx_log").Key("ErrorLogPath").SetValue(json.NginxLog.ErrorLogPath)
|
||||
|
||||
settings.Conf.Section("openai").Key("Model").SetValue(json.Openai.Model)
|
||||
settings.Conf.Section("openai").Key("BaseUrl").SetValue(json.Openai.BaseUrl)
|
||||
settings.Conf.Section("openai").Key("Proxy").SetValue(json.Openai.Proxy)
|
||||
settings.Conf.Section("openai").Key("Token").SetValue(json.Openai.Token)
|
||||
settings.Conf.Section("openai").Key("Model").SetValue(json.Openai.Model)
|
||||
settings.Conf.Section("openai").Key("BaseUrl").SetValue(json.Openai.BaseUrl)
|
||||
settings.Conf.Section("openai").Key("Proxy").SetValue(json.Openai.Proxy)
|
||||
settings.Conf.Section("openai").Key("Token").SetValue(json.Openai.Token)
|
||||
|
||||
err := settings.Save()
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
err := settings.Save()
|
||||
if err != nil {
|
||||
ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
GetSettings(c)
|
||||
GetSettings(c)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue