Files
chatai/src/components/settings.vue
2023-05-18 15:20:29 +08:00

138 lines
3.4 KiB
Vue

<template>
<section class="settings">
<el-form label-position="top" class="w100">
<el-form-item label="语言模型">
<el-row class="flexWrap">
<ai-model v-for="m in models" :model="m" small :class="{active:settings.model.id==m.id}"
@click="initModel(m)"/>
</el-row>
</el-form-item>
<el-form-item label="流式输出">
<el-switch v-model="settings.stream" :active-value="true" :inactive-value="false"/>
</el-form-item>
<el-form-item label="API KEY" v-if="isGPT">
<el-row class="w100">
<el-input v-model="settings.model.apiKey" clearable class="fill mar-r8"/>
<el-button type="text" @click="getModelAccount">应用</el-button>
</el-row>
</el-form-item>
<el-row v-loading="loadingAccount" element-loading-background="#272A37">
<el-form-item label="账号用户" class="fill">{{ account.username }}</el-form-item>
<el-form-item label="账户余额" class="fill">{{ [account.usage, account.total].join(" / ") }}</el-form-item>
<el-button type="text" @click="getModelAccount">刷新</el-button>
</el-row>
</el-form>
</section>
</template>
<script>
import AiModel from "../ui/AiModel";
import AiSelect from "../ui/AiSelect";
import * as models from "../utils/models";
export default {
name: "settings",
components: {AiModel, AiSelect},
props: {
modelValue: {default: () => ({})}
},
emits: ["update:modelValue"],
data() {
return {
settings: {},
loadingAccount: false
}
},
watch: {
modelValue: {
immediate: true,
handler(v) {
this.settings = v
this.getModelAccount()
}
}
},
computed: {
models: () => Object.values(models),
account: v => v.settings.account || {usage: 0, total: 0},
apiKey: v => v.settings.model.apiKey || "key无效或网络波动,请重新尝试",
isGPT: v => v.settings.model.name == "ChatGPT"
},
methods: {
initModel(model) {
const ins = new model()
const timer = setInterval(() => {
if (ins.apiKey) {
clearInterval(timer)
this.settings.model = ins
this.getModelAccount()
}
}, 500)
},
getModelAccount(c = 0) {
const ai = this.settings.model
if (ai.apiKey) {
this.loadingAccount = true
ai.getAccount().then(v => this.settings.account = v).finally(() => this.loadingAccount = false)
} else if (c < 5) setTimeout(() => this.getModelAccount(++c), 1000)
}
}
}
</script>
<style lang="scss" scoped>
.settings {
min-width: 375px;
margin-left: 16px;
:deep(.el-form) {
.el-form-item__label {
color: #bbb;
}
.el-form-item__content {
color: white;
}
.el-input__wrapper {
background-color: transparent;
& > input {
color: white;
}
}
.AiModel {
padding: 8px;
border: 1px solid transparent;
cursor: pointer;
user-select: none;
&.active {
border-color: #409EFF;
border-radius: 4px;
}
}
}
}
//移动端布局
@media screen and (max-width: 1150px) {
.settings {
margin-left: 0;
z-index: 202305181433;
position: fixed;
box-sizing: border-box;
padding: 0 16px 16px;
width: 100vw;
top: 80px;
left: 0;
height: calc(100vh - 80px);
overflow-y: auto;
overflow-x: hidden;
background-color: #272A37;
}
}
</style>