mirror of
https://github.com/yangjian102621/geekai.git
synced 2025-09-18 01:06:39 +08:00
support upload file from clipboard
This commit is contained in:
parent
246b023624
commit
37368fe13f
@ -1,4 +1,13 @@
|
|||||||
# 更新日志
|
# 更新日志
|
||||||
|
## v4.1.1
|
||||||
|
* Bug修复:修复 GPT 模型 function call 调用后没有输出的问题
|
||||||
|
* 功能新增:允许获取 License 授权用户可以自定义版权信息
|
||||||
|
* 功能新增:聊天对话框支持粘贴剪切板内容来上传截图和文件
|
||||||
|
* 功能优化:增加 session 和系统配置缓存,确保每个页面只进行一次 session 和 get system config 请求
|
||||||
|
* 功能优化:在应用列表页面,无需先添加模型到用户工作区,可以直接使用
|
||||||
|
* 功能新增:MJ 绘图失败的任务不会自动删除,而是会在列表页显示失败详细错误信息
|
||||||
|
* 功能新增:增加 Suno 文生音乐页面功能
|
||||||
|
|
||||||
## v4.1.0
|
## v4.1.0
|
||||||
* bug修复:修复移动端修改聊天标题不生效的问题
|
* bug修复:修复移动端修改聊天标题不生效的问题
|
||||||
* Bug修复:修复用户注册不显示用户名的问题
|
* Bug修复:修复用户注册不显示用户名的问题
|
||||||
|
@ -139,7 +139,7 @@ func authorizeMiddleware(s *AppServer, client *redis.Client) gin.HandlerFunc {
|
|||||||
|
|
||||||
if tokenString == "" {
|
if tokenString == "" {
|
||||||
if needLogin(c) {
|
if needLogin(c) {
|
||||||
resp.ERROR(c, "You should put Authorization in request headers")
|
resp.NotAuth(c, "You should put Authorization in request headers")
|
||||||
c.Abort()
|
c.Abort()
|
||||||
return
|
return
|
||||||
} else { // 直接放行
|
} else { // 直接放行
|
||||||
|
BIN
web/public/images/ext/mp3.png
Normal file
BIN
web/public/images/ext/mp3.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 812 B |
BIN
web/public/images/ext/mp4.png
Normal file
BIN
web/public/images/ext/mp4.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 743 B |
@ -241,8 +241,8 @@ watch(() => props.show, (newValue) => {
|
|||||||
|
|
||||||
const login = ref(true)
|
const login = ref(true)
|
||||||
const data = ref({
|
const data = ref({
|
||||||
username: "",
|
username: process.env.VUE_APP_USER,
|
||||||
password: "",
|
password: process.env.VUE_APP_PASS,
|
||||||
repass: "",
|
repass: "",
|
||||||
code: "",
|
code: "",
|
||||||
invite_code: ""
|
invite_code: ""
|
||||||
|
@ -37,7 +37,11 @@ export function GetFileIcon(ext) {
|
|||||||
".pptx": "ppt.png",
|
".pptx": "ppt.png",
|
||||||
".md": "md.png",
|
".md": "md.png",
|
||||||
".pdf": "pdf.png",
|
".pdf": "pdf.png",
|
||||||
".sql": "sql.png"
|
".sql": "sql.png",
|
||||||
|
".mp3": "mp3.png",
|
||||||
|
".wav": "mp3.png",
|
||||||
|
".mp4": "mp4.png",
|
||||||
|
".avi": "mp4.png",
|
||||||
}
|
}
|
||||||
if (files[ext]) {
|
if (files[ext]) {
|
||||||
return '/images/ext/' + files[ext]
|
return '/images/ext/' + files[ext]
|
||||||
|
@ -34,6 +34,8 @@ axios.interceptors.response.use(
|
|||||||
} else {
|
} else {
|
||||||
removeUserToken()
|
removeUserToken()
|
||||||
}
|
}
|
||||||
|
console.log(error.response.data)
|
||||||
|
error.response.data.message = "请先登录"
|
||||||
return Promise.reject(error.response.data)
|
return Promise.reject(error.response.data)
|
||||||
}
|
}
|
||||||
if (error.response.status === 400) {
|
if (error.response.status === 400) {
|
||||||
|
@ -219,6 +219,7 @@ import {useSharedStore} from "@/store/sharedata";
|
|||||||
import FileSelect from "@/components/FileSelect.vue";
|
import FileSelect from "@/components/FileSelect.vue";
|
||||||
import FileList from "@/components/FileList.vue";
|
import FileList from "@/components/FileList.vue";
|
||||||
import ChatSetting from "@/components/ChatSetting.vue";
|
import ChatSetting from "@/components/ChatSetting.vue";
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
const title = ref('ChatGPT-智能助手');
|
const title = ref('ChatGPT-智能助手');
|
||||||
const models = ref([])
|
const models = ref([])
|
||||||
@ -342,16 +343,6 @@ const initData = () => {
|
|||||||
})
|
})
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
// 加载会话
|
|
||||||
httpGet("/api/chat/list").then((res) => {
|
|
||||||
if (res.data) {
|
|
||||||
chatList.value = res.data;
|
|
||||||
allChats.value = res.data;
|
|
||||||
}
|
|
||||||
}).catch(() => {
|
|
||||||
ElMessage.error("加载会话列表失败!")
|
|
||||||
})
|
|
||||||
|
|
||||||
// 加载模型
|
// 加载模型
|
||||||
httpGet('/api/model/list',{id:roleId.value}).then(res => {
|
httpGet('/api/model/list',{id:roleId.value}).then(res => {
|
||||||
models.value = res.data
|
models.value = res.data
|
||||||
@ -368,6 +359,37 @@ const initData = () => {
|
|||||||
ElMessage.error('获取聊天角色失败: ' + e.messages)
|
ElMessage.error('获取聊天角色失败: ' + e.messages)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
inputRef.value.addEventListener('paste', (event) => {
|
||||||
|
const items = (event.clipboardData || window.clipboardData).items;
|
||||||
|
let fileFound = false;
|
||||||
|
loading.value = true
|
||||||
|
|
||||||
|
for (let item of items) {
|
||||||
|
if (item.kind === 'file') {
|
||||||
|
const file = item.getAsFile();
|
||||||
|
fileFound = true;
|
||||||
|
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('file', file);
|
||||||
|
// 执行上传操作
|
||||||
|
httpPost('/api/upload', formData).then((res) => {
|
||||||
|
files.value.push(res.data)
|
||||||
|
ElMessage.success({message: "上传成功", duration: 500})
|
||||||
|
loading.value = false
|
||||||
|
}).catch((e) => {
|
||||||
|
ElMessage.error('文件上传失败:' + e.message)
|
||||||
|
loading.value = false
|
||||||
|
})
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fileFound) {
|
||||||
|
document.getElementById('status').innerText = 'No file found in paste data.';
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const getRoleById = function (rid) {
|
const getRoleById = function (rid) {
|
||||||
@ -739,7 +761,7 @@ const onInput = (e) => {
|
|||||||
const autofillPrompt = (text) => {
|
const autofillPrompt = (text) => {
|
||||||
prompt.value = text
|
prompt.value = text
|
||||||
inputRef.value.focus()
|
inputRef.value.focus()
|
||||||
// sendMessage()
|
sendMessage()
|
||||||
}
|
}
|
||||||
// 发送消息
|
// 发送消息
|
||||||
const sendMessage = function () {
|
const sendMessage = function () {
|
||||||
|
@ -492,7 +492,13 @@
|
|||||||
<div class="image-slot">
|
<div class="image-slot">
|
||||||
<div class="err-msg-container">
|
<div class="err-msg-container">
|
||||||
<div class="title">任务失败</div>
|
<div class="title">任务失败</div>
|
||||||
<div class="text">{{ slotProp.item['err_msg'] }}</div>
|
<div class="text">
|
||||||
|
<el-popover title="错误详情" trigger="hover" :width="250" :content="slotProp.item['err_msg']" placement="top">
|
||||||
|
<template #reference>
|
||||||
|
{{ slotProp.item['err_msg'] }}
|
||||||
|
</template>
|
||||||
|
</el-popover>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<el-button type="danger" @click="removeImage(slotProp.item)">删除</el-button>
|
<el-button type="danger" @click="removeImage(slotProp.item)">删除</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user