Browse Source

Merge branch 'master' of https://gitee.com/godoos/godoos

master
godo 5 months ago
parent
commit
882f2e3eb2
  1. 6
      frontend/src/assets/chat.scss
  2. 3
      frontend/src/components/localchat/AiChatMain.vue
  3. 251
      frontend/src/components/setting/SetSystem.vue
  4. 28
      frontend/src/components/setting/setStyle.css

6
frontend/src/assets/chat.scss

@ -108,11 +108,9 @@
@media screen and (max-width: 768px) { @media screen and (max-width: 768px) {
.chat-bot{ .chat-bot{
.input-area{ .input-area{
padding: 0;
.file-btn{ .file-btn{
margin-left: vw(-20); margin-left: vw(-10);
}
.websearch-btn{
margin-left: vw(-5);
} }
} }
} }

3
frontend/src/components/localchat/AiChatMain.vue

@ -7,6 +7,7 @@ import { ElScrollbar } from "element-plus";
import { getSystemConfig } from "@/system/config"; import { getSystemConfig } from "@/system/config";
import { Vue3Lottie } from "vue3-lottie"; import { Vue3Lottie } from "vue3-lottie";
import { file } from "jszip"; import { file } from "jszip";
import { isMobileDevice } from "@/util/device";
const chatStore = useAiChatStore(); const chatStore = useAiChatStore();
const modelStore = useModelStore(); const modelStore = useModelStore();
const isPadding = ref(false); // const isPadding = ref(false); //
@ -242,7 +243,7 @@ const uploadImage = async (event: any) => {
</el-col> </el-col>
<el-col :span="17"> <el-col :span="17">
<el-input v-model="userMessage" :placeholder="t('aichat.askme')" size="large" clearable <el-input v-model="userMessage" :placeholder="t('aichat.askme')" size="large" clearable
@keydown="handleKeydown" autofocus class="ai-input-area" /> @keydown="handleKeydown" :autofocus="isMobileDevice() ? false : true" class="ai-input-area" />
</el-col> </el-col>
<el-col :span="2"> <el-col :span="2">
<el-button v-if="!isPadding" @click="sendMessage" icon="Promotion" type="info" size="large" circle /> <el-button v-if="!isPadding" @click="sendMessage" icon="Promotion" type="info" size="large" circle />

251
frontend/src/components/setting/SetSystem.vue

@ -2,87 +2,54 @@
<div class="container"> <div class="container">
<div class="nav"> <div class="nav">
<ul> <ul>
<li <li v-for="(item, index) in items" :key="index" @click="selectItem(index)"
v-for="(item, index) in items" :class="{ active: index === activeIndex }">
:key="index"
@click="selectItem(index)"
:class="{ active: index === activeIndex }"
>
{{ item }} {{ item }}
</li> </li>
</ul> </ul>
</div> </div>
<div class="setting"> <div class="setting">
<div v-if="1 === activeIndex"> <div v-if="1 === activeIndex">
<div <div class="setting-item" style="margin-top: 60px">
class="setting-item"
style="margin-top: 60px"
>
<label>存储方式</label> <label>存储方式</label>
<el-select v-model="config.storeType"> <el-select v-model="config.storeType">
<el-option <el-option v-for="(item, key) in storeList" :key="key" :label="item.title"
v-for="(item, key) in storeList" :value="item.value" />
:key="key"
:label="item.title"
:value="item.value"
/>
</el-select> </el-select>
</div> </div>
<template v-if="config.storeType === 'local'"> <template v-if="config.storeType === 'local'">
<div class="setting-item"> <div class="setting-item">
<label>存储地址</label> <label>存储地址</label>
<el-input <el-input v-model="config.storePath" @click="selectFile()"
v-model="config.storePath" placeholder="可为空,为空则取系统默认存储地址:/用户目录/.godoos/os" />
@click="selectFile()"
placeholder="可为空,为空则取系统默认存储地址:/用户目录/.godoos/os"
/>
</div> </div>
<div class="setting-item"> <div class="setting-item">
<label>自定义端口</label> <label>自定义端口</label>
<el-input <el-input v-model="config.netPort" placeholder="可为空,为空则取系统默认56780" />
v-model="config.netPort"
placeholder="可为空,为空则取系统默认56780"
/>
</div> </div>
<div class="setting-item"> <div class="setting-item">
<label>自定义路径</label> <label>自定义路径</label>
<el-input <el-input v-model="config.netPath" placeholder="自定义web访问路径,英文,不要加斜杠,可为空" />
v-model="config.netPath"
placeholder="自定义web访问路径,英文,不要加斜杠,可为空"
/>
</div> </div>
</template> </template>
<template v-if="config.storeType === 'net'"> <template v-if="config.storeType === 'net'">
<div class="setting-item"> <div class="setting-item">
<label>服务器地址</label> <label>服务器地址</label>
<el-input <el-input v-model="config.storenet.url" placeholder="可访问的地址,例如http://192.168.1.6:56780 不要加斜杠" />
v-model="config.storenet.url"
placeholder="可访问的地址,例如http://192.168.1.6:56780 不要加斜杠"
/>
</div> </div>
<div class="setting-item"> <div class="setting-item">
<label>允许跨域</label> <label>允许跨域</label>
<el-switch <el-switch v-model="config.storenet.isCors" active-text="允许" inactive-text="不允许" style="
v-model="config.storenet.isCors"
active-text="允许"
inactive-text="不允许"
style="
--el-switch-on-color: #13ce66; --el-switch-on-color: #13ce66;
--el-switch-off-color: #ff4949; --el-switch-off-color: #ff4949;
" " active-value="1" inactive-value="" />
active-value="1"
inactive-value=""
/>
</div> </div>
</template> </template>
<template v-if="config.storeType === 'webdav'"> <template v-if="config.storeType === 'webdav'">
<div class="setting-item"> <div class="setting-item">
<label>服务器地址</label> <label>服务器地址</label>
<el-input <el-input v-model="config.webdavClient.url" placeholder="https://godoos.com/webdav 不要加斜杠" />
v-model="config.webdavClient.url"
placeholder="https://godoos.com/webdav 不要加斜杠"
/>
</div> </div>
<div class="setting-item"> <div class="setting-item">
<label>登陆用户名</label> <label>登陆用户名</label>
@ -90,46 +57,30 @@
</div> </div>
<div class="setting-item"> <div class="setting-item">
<label>登陆密码</label> <label>登陆密码</label>
<el-input <el-input v-model="config.webdavClient.password" type="password" />
v-model="config.webdavClient.password"
type="password"
/>
</div> </div>
</template> </template>
<div class="setting-item"> <div class="setting-item">
<label></label> <label></label>
<el-button <el-button @click="submitOsInfo" type="primary">
@click="submitOsInfo"
type="primary"
>
{{ t("confirm") }} {{ t("confirm") }}
</el-button> </el-button>
</div> </div>
</div> </div>
<div v-if="2 === activeIndex"> <div v-if="2 === activeIndex">
<div <div class="setting-item" style="margin-top: 60px">
class="setting-item"
style="margin-top: 60px"
>
<label>编辑器类型</label> <label>编辑器类型</label>
<el-select v-model="config.editorType"> <el-select v-model="config.editorType">
<el-option <el-option v-for="(item, key) in editorType" :key="key" :label="item.title"
v-for="(item, key) in editorType" :value="item.value" />
:key="key"
:label="item.title"
:value="item.value"
/>
</el-select> </el-select>
</div> </div>
<template v-if="config.editorType === 'onlyoffice'"> <template v-if="config.editorType === 'onlyoffice'">
<div class="setting-item"> <div class="setting-item">
<label>地址</label> <label>地址</label>
<el-input <el-input v-model="config.onlyoffice.url" placeholder="https://godoos.com/onlyoffice 不要加斜杠" />
v-model="config.onlyoffice.url"
placeholder="https://godoos.com/onlyoffice 不要加斜杠"
/>
</div> </div>
<!-- <div class="setting-item"> <!-- <div class="setting-item">
<label>私钥</label> <label>私钥</label>
@ -138,10 +89,7 @@
</template> </template>
<div class="setting-item"> <div class="setting-item">
<label></label> <label></label>
<el-button <el-button @click="submitEditInfo" type="primary">
@click="submitEditInfo"
type="primary"
>
{{ t("confirm") }} {{ t("confirm") }}
</el-button> </el-button>
</div> </div>
@ -152,10 +100,7 @@
</div> </div>
<div class="setting-item"> <div class="setting-item">
<label></label> <label></label>
<el-button <el-button @click="exportBackup" type="primary">
@click="exportBackup"
type="primary"
>
导出 导出
</el-button> </el-button>
</div> </div>
@ -164,73 +109,42 @@
</div> </div>
<div class="setting-item"> <div class="setting-item">
<label></label> <label></label>
<el-button <el-button @click="selectZipfile" type="primary">
@click="selectZipfile"
type="primary"
>
导入 导入
</el-button> </el-button>
<input <input type="file" accept=".zip" style="display: none" ref="zipFileInput" />
type="file"
accept=".zip"
style="display: none"
ref="zipFileInput"
/>
</div> </div>
</div> </div>
<div v-if="0 === activeIndex"> <div v-if="0 === activeIndex">
<div <div class="setting-item" style="margin-top: 60px">
class="setting-item"
style="margin-top: 60px"
>
<label>用户角色</label> <label>用户角色</label>
<el-select v-model="config.userType"> <el-select v-model="config.userType">
<el-option <el-option v-for="(item, key) in userTypes" :key="key" :label="item.title"
v-for="(item, key) in userTypes" :value="item.value" />
:key="key"
:label="item.title"
:value="item.value"
/>
</el-select> </el-select>
</div> </div>
<template v-if="config.userType === 'member'"> <template v-if="config.userType === 'member'">
<div class="setting-item"> <div class="setting-item">
<label>服务器地址</label> <label>服务器地址</label>
<el-input <el-input v-model="config.userInfo.url" placeholder="网址或域名,例子:https://godoos.com 不要加斜杠" />
v-model="config.userInfo.url"
placeholder="网址或域名,例子:https://godoos.com 不要加斜杠"
/>
</div> </div>
<div class="setting-item"> <div class="setting-item">
<label>用户名</label> <label>用户名</label>
<el-input <el-input v-model="config.userInfo.username" placeholder="登录用户名" />
v-model="config.userInfo.username"
placeholder="登录用户名"
/>
</div> </div>
<div class="setting-item"> <div class="setting-item">
<label>密码</label> <label>密码</label>
<el-input <el-input v-model="config.userInfo.password" type="password" placeholder="登录密码" />
v-model="config.userInfo.password"
type="password"
placeholder="登录密码"
/>
</div> </div>
</template> </template>
<div class="setting-item"> <div class="setting-item">
<label></label> <label></label>
<el-button <el-button @click="saveUserInfo" type="primary">
@click="saveUserInfo"
type="primary"
>
{{ t("confirm") }} {{ t("confirm") }}
</el-button> </el-button>
</div> </div>
</div> </div>
<div <div v-if="4 === activeIndex" class="setting-area">
v-if="4 === activeIndex"
class="setting-area"
>
<SetFilePwd v-if="config.userType === 'person'"></SetFilePwd> <SetFilePwd v-if="config.userType === 'person'"></SetFilePwd>
</div> </div>
</div> </div>
@ -238,20 +152,20 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { Dialog, join, System, t } from "@/system"; import { Dialog, join, System, t } from "@/system";
import { getSystemConfig, setSystemConfig } from "@/system/config"; import { getSystemConfig, setSystemConfig } from "@/system/config";
import { GetClientId } from "@/util/clientid.ts"; import { GetClientId } from "@/util/clientid.ts";
import { OpenDirDialog, RestartApp } from "@/util/goutil"; import { OpenDirDialog, RestartApp } from "@/util/goutil";
import { notifyError, notifySuccess } from "@/util/msg"; import { notifyError, notifySuccess } from "@/util/msg";
import FileSaver from "file-saver"; import FileSaver from "file-saver";
import JSZip from "jszip"; import JSZip from "jszip";
import { inject, ref } from "vue"; import { inject, ref } from "vue";
const config = ref(getSystemConfig()); const config = ref(getSystemConfig());
const sys = inject<System>("system")!; const sys = inject<System>("system")!;
let zipFile: File | undefined = undefined; let zipFile: File | undefined = undefined;
const zipFileInput = ref(); const zipFileInput = ref();
const fileName: any = ref(""); const fileName: any = ref("");
const storeList = [ const storeList = [
// { // {
// title: "", // title: "",
// value: "browser", // value: "browser",
@ -268,16 +182,19 @@
// title: "webdav", // title: "webdav",
// value: "webdav", // value: "webdav",
// }, // },
]; ];
const items = [ const items = [
"用户角色", "用户角色",
"存储配置", "存储配置",
"编辑器类型", "编辑器类型",
"备份还原", "备份还原",
"文件密码箱", "文件密码箱",
]; ];
const editorType = [ if (config.value.userType !== "person") {
items.pop()
}
const editorType = [
{ {
title: "系统默认", title: "系统默认",
value: "local", value: "local",
@ -286,9 +203,9 @@
title: "OnlyOffice", title: "OnlyOffice",
value: "onlyoffice", value: "onlyoffice",
}, },
]; ];
const urlRegex = /^(https?:\/\/)/; const urlRegex = /^(https?:\/\/)/;
const userTypes = [ const userTypes = [
{ {
title: "独立用户", title: "独立用户",
value: "person", value: "person",
@ -297,19 +214,19 @@
title: "企业用户", title: "企业用户",
value: "member", value: "member",
}, },
]; ];
const activeIndex = ref(0); const activeIndex = ref(0);
const selectItem = (index: number) => { const selectItem = (index: number) => {
activeIndex.value = index; activeIndex.value = index;
}; };
function selectFile() { function selectFile() {
OpenDirDialog().then((res: string) => { OpenDirDialog().then((res: string) => {
config.value.storePath = res; config.value.storePath = res;
}); });
} }
function submitOsInfo() { function submitOsInfo() {
const saveData = toRaw(config.value); const saveData = toRaw(config.value);
if (saveData.storeType === "local") { if (saveData.storeType === "local") {
const postData = parseData(saveData); const postData = parseData(saveData);
@ -415,8 +332,8 @@
// } // }
// }); // });
// } // }
} }
function submitEditInfo() { function submitEditInfo() {
const saveData = toRaw(config.value); const saveData = toRaw(config.value);
setSystemConfig(saveData); setSystemConfig(saveData);
Dialog.showMessageBox({ Dialog.showMessageBox({
@ -424,8 +341,8 @@
type: "success", type: "success",
}); });
return; return;
} }
function parseData(saveData: any) { function parseData(saveData: any) {
let postData = []; let postData = [];
if (saveData.storePath !== "") { if (saveData.storePath !== "") {
postData.push({ name: "osPath", value: saveData.storePath }); postData.push({ name: "osPath", value: saveData.storePath });
@ -449,8 +366,8 @@
}); });
} }
return postData; return postData;
} }
async function saveUserInfo() { async function saveUserInfo() {
const saveData = toRaw(config.value); const saveData = toRaw(config.value);
console.log(saveData); console.log(saveData);
if (saveData.userType == "person") { if (saveData.userType == "person") {
@ -516,8 +433,8 @@
notifyError("登录失败"); notifyError("登录失败");
} }
return; return;
} }
async function exportBackup() { async function exportBackup() {
const { setProgress } = Dialog.showProcessDialog({ const { setProgress } = Dialog.showProcessDialog({
message: `正在打包`, message: `正在打包`,
}); });
@ -539,8 +456,8 @@
setProgress(100); setProgress(100);
}); });
} }
} }
async function dfsPackage(path: string, zip: JSZip, setProgress: any) { async function dfsPackage(path: string, zip: JSZip, setProgress: any) {
const dir = await sys.fs.readdir(path); const dir = await sys.fs.readdir(path);
for (let i = 0; i < dir.length; i++) { for (let i = 0; i < dir.length; i++) {
@ -561,8 +478,8 @@
} }
} }
} }
} }
function selectZipfile() { function selectZipfile() {
zipFileInput.value.click(); zipFileInput.value.click();
zipFileInput.value.onchange = (e: any) => { zipFileInput.value.onchange = (e: any) => {
const tar: any = e.target as HTMLInputElement; const tar: any = e.target as HTMLInputElement;
@ -575,8 +492,8 @@
fileName.value = ""; fileName.value = "";
} }
}; };
} }
async function importBackup(path = "") { async function importBackup(path = "") {
if (!zipFile) { if (!zipFile) {
return; return;
} }
@ -618,22 +535,22 @@
}); });
}, 100); }, 100);
} }
} }
</script> </script>
<style scoped> <style scoped>
@import "./setStyle.css"; @import "./setStyle.css";
.ctrl { .ctrl {
width: 100px; width: 100px;
} }
.setting-item { .setting-item {
display: flex; display: flex;
align-items: center; align-items: center;
} }
.setting-area { .setting-area {
width: 100%; width: 100%;
height: 90%; height: 90%;
} }
</style> </style>

28
frontend/src/components/setting/setStyle.css

@ -74,8 +74,34 @@
text-align: right; text-align: right;
} }
@media screen and (max-width: 768px) { @media screen and (max-width: 768px) {
.container {
flex-direction: column;
}
.nav { .nav {
width: 25%; background-color: #f9f9f9;
width: 100%;
}
.nav ul {
display: flex;
justify-content: space-evenly;
}
.nav li {
flex: 1;
padding: 10px 0;
text-align: center;
}
.nav li.active {
background-color: #fff;
}
.nav li.active:hover {
background-color: #fff;
}
.nav li.active::after {
background-color: #80bbe9;
}
.setting {
margin-top: 20px;
box-sizing: border-box;
} }
.setting-item:first-child { .setting-item:first-child {
margin-top: 0px !important; margin-top: 0px !important;

Loading…
Cancel
Save