diff --git a/api/core/app_server.go b/api/core/app_server.go
index d7bf5590..84c38cb4 100644
--- a/api/core/app_server.go
+++ b/api/core/app_server.go
@@ -155,7 +155,6 @@ func authorizeMiddleware(s *AppServer, client *redis.Client) gin.HandlerFunc {
c.Request.URL.Path == "/api/mj/notify" ||
c.Request.URL.Path == "/api/invite/hits" ||
c.Request.URL.Path == "/api/sd/jobs" ||
- c.Request.URL.Path == "/api/upload" ||
strings.HasPrefix(c.Request.URL.Path, "/api/test") ||
strings.HasPrefix(c.Request.URL.Path, "/api/function/") ||
strings.HasPrefix(c.Request.URL.Path, "/api/sms/") ||
diff --git a/api/handler/upload_handler.go b/api/handler/upload_handler.go
index 62f508a3..6a3da8a4 100644
--- a/api/handler/upload_handler.go
+++ b/api/handler/upload_handler.go
@@ -3,9 +3,13 @@ package handler
import (
"chatplus/core"
"chatplus/service/oss"
+ "chatplus/store/model"
+ "chatplus/store/vo"
+ "chatplus/utils"
"chatplus/utils/resp"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
+ "time"
)
type UploadHandler struct {
@@ -27,5 +31,40 @@ func (h *UploadHandler) Upload(c *gin.Context) {
return
}
+ userId := h.GetLoginUserId(c)
+ res := h.db.Create(&model.File{
+ UserId: userId,
+ Name: file.Name,
+ URL: file.URL,
+ Ext: file.Ext,
+ Size: file.Size,
+ CreatedAt: time.Time{},
+ })
+ if res.Error != nil || res.RowsAffected == 0 {
+ resp.ERROR(c, "error with update database: "+res.Error.Error())
+ return
+ }
+
resp.SUCCESS(c, file)
}
+
+func (h *UploadHandler) List(c *gin.Context) {
+ userId := h.GetLoginUserId(c)
+ var items []model.File
+ var files = make([]vo.File, 0)
+ h.db.Debug().Where("user_id = ?", userId).Find(&items)
+ if len(items) > 0 {
+ for _, v := range items {
+ var file vo.File
+ err := utils.CopyObject(v, &file)
+ if err != nil {
+ logger.Error(err)
+ continue
+ }
+ file.CreatedAt = v.CreatedAt.Unix()
+ files = append(files, file)
+ }
+ }
+
+ resp.SUCCESS(c, files)
+}
diff --git a/api/main.go b/api/main.go
index e4984dbc..514d3e19 100644
--- a/api/main.go
+++ b/api/main.go
@@ -214,6 +214,7 @@ func main() {
}),
fx.Invoke(func(s *core.AppServer, h *handler.UploadHandler) {
s.Engine.POST("/api/upload", h.Upload)
+ s.Engine.GET("/api/upload/list", h.List)
}),
fx.Invoke(func(s *core.AppServer, h *handler.SmsHandler) {
group := s.Engine.Group("/api/sms/")
diff --git a/api/service/oss/aliyun_oss.go b/api/service/oss/aliyun_oss.go
index 35ea314d..c9f4ea21 100644
--- a/api/service/oss/aliyun_oss.go
+++ b/api/service/oss/aliyun_oss.go
@@ -66,6 +66,7 @@ func (s AliYunOss) PutFile(ctx *gin.Context, name string) (File, error) {
}
return File{
+ Name: file.Filename,
URL: fmt.Sprintf("%s/%s", s.config.Domain, objectKey),
Ext: fileExt,
Size: file.Size,
diff --git a/api/service/oss/localstorage.go b/api/service/oss/localstorage.go
index 7536dab3..0ce5be2d 100644
--- a/api/service/oss/localstorage.go
+++ b/api/service/oss/localstorage.go
@@ -41,6 +41,7 @@ func (s LocalStorage) PutFile(ctx *gin.Context, name string) (File, error) {
ext := filepath.Ext(file.Filename)
return File{
+ Name: file.Filename,
URL: utils.GenUploadUrl(s.config.BasePath, s.config.BaseURL, path),
Ext: ext,
Size: file.Size,
diff --git a/api/service/oss/minio_oss.go b/api/service/oss/minio_oss.go
index d9e16e47..94b03a24 100644
--- a/api/service/oss/minio_oss.go
+++ b/api/service/oss/minio_oss.go
@@ -87,6 +87,7 @@ func (s MiniOss) PutFile(ctx *gin.Context, name string) (File, error) {
}
return File{
+ Name: file.Filename,
URL: fmt.Sprintf("%s/%s/%s", s.config.Domain, s.config.Bucket, info.Key),
Ext: fileExt,
Size: file.Size,
diff --git a/api/service/oss/qiniu_oss.go b/api/service/oss/qiniu_oss.go
index cf7789d1..3b989308 100644
--- a/api/service/oss/qiniu_oss.go
+++ b/api/service/oss/qiniu_oss.go
@@ -74,6 +74,7 @@ func (s QinNiuOss) PutFile(ctx *gin.Context, name string) (File, error) {
}
return File{
+ Name: file.Filename,
URL: fmt.Sprintf("%s/%s", s.config.Domain, ret.Key),
Ext: fileExt,
Size: file.Size,
diff --git a/api/service/oss/uploader.go b/api/service/oss/uploader.go
index 0861e09a..a8f7b50c 100644
--- a/api/service/oss/uploader.go
+++ b/api/service/oss/uploader.go
@@ -3,9 +3,10 @@ package oss
import "github.com/gin-gonic/gin"
type File struct {
- Size int64
- URL string
- Ext string
+ Name string `json:"name"`
+ Size int64 `json:"size"`
+ URL string `json:"url"`
+ Ext string `json:"ext"`
}
type Uploader interface {
PutFile(ctx *gin.Context, name string) (File, error)
diff --git a/api/store/model/file.go b/api/store/model/file.go
index 24ed0d06..dafd650e 100644
--- a/api/store/model/file.go
+++ b/api/store/model/file.go
@@ -5,6 +5,7 @@ import "time"
type File struct {
Id uint `gorm:"primarykey;column:id"`
UserId uint
+ Name string
URL string
Ext string
Size int64
diff --git a/api/store/vo/File.go b/api/store/vo/file.go
similarity index 87%
rename from api/store/vo/File.go
rename to api/store/vo/file.go
index 1127bd6b..2a0ebc6b 100644
--- a/api/store/vo/File.go
+++ b/api/store/vo/file.go
@@ -3,6 +3,7 @@ package vo
type File struct {
Id uint
UserId uint `json:"user_id"`
+ Name string `json:"name"`
URL string `json:"url"`
Ext string `json:"ext"`
Size int64 `json:"size"`
diff --git a/database/update-v3.2.5.sql b/database/update-v3.2.5.sql
index 5c80c025..7815dded 100644
--- a/database/update-v3.2.5.sql
+++ b/database/update-v3.2.5.sql
@@ -9,4 +9,5 @@ CREATE TABLE `chatgpt_plus`.`chatgpt_files` (
`created_at` DATETIME NOT NULL COMMENT '创建时间' ,
PRIMARY KEY (`id`)) ENGINE = InnoDB COMMENT = '用户文件表';
-ALTER TABLE `chatgpt_files` ADD `size` BIGINT(20) NOT NULL DEFAULT '0' COMMENT '文件大小' AFTER `ext`;
\ No newline at end of file
+ALTER TABLE `chatgpt_files` ADD `size` BIGINT(20) NOT NULL DEFAULT '0' COMMENT '文件大小' AFTER `ext`;
+ALTER TABLE `chatgpt_files` ADD `name` VARCHAR(100) NOT NULL COMMENT '文件名' AFTER `user_id`;
\ No newline at end of file
diff --git a/web/public/images/ext/doc.png b/web/public/images/ext/doc.png
new file mode 100644
index 00000000..9e2c3696
Binary files /dev/null and b/web/public/images/ext/doc.png differ
diff --git a/web/public/images/ext/file.png b/web/public/images/ext/file.png
new file mode 100644
index 00000000..45652525
Binary files /dev/null and b/web/public/images/ext/file.png differ
diff --git a/web/public/images/ext/md.png b/web/public/images/ext/md.png
new file mode 100644
index 00000000..c8d32228
Binary files /dev/null and b/web/public/images/ext/md.png differ
diff --git a/web/public/images/ext/pdf.png b/web/public/images/ext/pdf.png
new file mode 100644
index 00000000..4987837c
Binary files /dev/null and b/web/public/images/ext/pdf.png differ
diff --git a/web/public/images/ext/ppt.png b/web/public/images/ext/ppt.png
new file mode 100644
index 00000000..44019095
Binary files /dev/null and b/web/public/images/ext/ppt.png differ
diff --git a/web/public/images/ext/sql.png b/web/public/images/ext/sql.png
new file mode 100644
index 00000000..c2255c8c
Binary files /dev/null and b/web/public/images/ext/sql.png differ
diff --git a/web/public/images/ext/txt.png b/web/public/images/ext/txt.png
new file mode 100644
index 00000000..11744f48
Binary files /dev/null and b/web/public/images/ext/txt.png differ
diff --git a/web/public/images/ext/xls.png b/web/public/images/ext/xls.png
new file mode 100644
index 00000000..1897bdc3
Binary files /dev/null and b/web/public/images/ext/xls.png differ
diff --git a/web/src/assets/css/chat-plus.css b/web/src/assets/css/chat-plus.css
index 5e07cdd9..f7d03f65 100644
--- a/web/src/assets/css/chat-plus.css
+++ b/web/src/assets/css/chat-plus.css
@@ -213,6 +213,11 @@
width: 0;
height: 0;
}
+#app .common-layout .el-main .right-box #container .input-box .input-container .select-file {
+ position: absolute;
+ right: 48px;
+ top: 20px;
+}
#app .common-layout .el-main .right-box #container .input-box .input-container .send-btn {
position: absolute;
right: 12px;
diff --git a/web/src/assets/css/chat-plus.styl b/web/src/assets/css/chat-plus.styl
index fe6c2b84..3a628f31 100644
--- a/web/src/assets/css/chat-plus.styl
+++ b/web/src/assets/css/chat-plus.styl
@@ -279,6 +279,12 @@ $borderColor = #4676d0;
}
}
+ .select-file {
+ position absolute;
+ right 48px;
+ top 20px;
+ }
+
.send-btn {
position absolute;
right 12px;
diff --git a/web/src/assets/iconfont/iconfont.css b/web/src/assets/iconfont/iconfont.css
index a16a9c4e..3dece43a 100644
--- a/web/src/assets/iconfont/iconfont.css
+++ b/web/src/assets/iconfont/iconfont.css
@@ -1,8 +1,8 @@
@font-face {
font-family: "iconfont"; /* Project id 4125778 */
- src: url('iconfont.woff2?t=1703124384910') format('woff2'),
- url('iconfont.woff?t=1703124384910') format('woff'),
- url('iconfont.ttf?t=1703124384910') format('truetype');
+ src: url('iconfont.woff2?t=1705313263366') format('woff2'),
+ url('iconfont.woff?t=1705313263366') format('woff'),
+ url('iconfont.ttf?t=1705313263366') format('truetype');
}
.iconfont {
@@ -13,6 +13,38 @@
-moz-osx-font-smoothing: grayscale;
}
+.icon-xls:before {
+ content: "\e678";
+}
+
+.icon-file:before {
+ content: "\e62f";
+}
+
+.icon-doc:before {
+ content: "\e6c2";
+}
+
+.icon-pdf:before {
+ content: "\e6c3";
+}
+
+.icon-ppt:before {
+ content: "\e642";
+}
+
+.icon-txt:before {
+ content: "\e644";
+}
+
+.icon-sql:before {
+ content: "\e65b";
+}
+
+.icon-md:before {
+ content: "\e63a";
+}
+
.icon-loading:before {
content: "\e627";
}
diff --git a/web/src/assets/iconfont/iconfont.js b/web/src/assets/iconfont/iconfont.js
index 6521c8f0..36dd6b72 100644
--- a/web/src/assets/iconfont/iconfont.js
+++ b/web/src/assets/iconfont/iconfont.js
@@ -1 +1 @@
-window._iconfont_svg_string_4125778='',function(a){var l=(l=document.getElementsByTagName("script"))[l.length-1],c=l.getAttribute("data-injectcss"),l=l.getAttribute("data-disable-injectsvg");if(!l){var t,o,i,h,e,s=function(l,c){c.parentNode.insertBefore(l,c)};if(c&&!a.__iconfont__svg__cssinject__){a.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(l){console&&console.log(l)}}t=function(){var l,c=document.createElement("div");c.innerHTML=a._iconfont_svg_string_4125778,(c=c.getElementsByTagName("svg")[0])&&(c.setAttribute("aria-hidden","true"),c.style.position="absolute",c.style.width=0,c.style.height=0,c.style.overflow="hidden",c=c,(l=document.body).firstChild?s(c,l.firstChild):l.appendChild(c))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(t,0):(o=function(){document.removeEventListener("DOMContentLoaded",o,!1),t()},document.addEventListener("DOMContentLoaded",o,!1)):document.attachEvent&&(i=t,h=a.document,e=!1,z(),h.onreadystatechange=function(){"complete"==h.readyState&&(h.onreadystatechange=null,m())})}function m(){e||(e=!0,i())}function z(){try{h.documentElement.doScroll("left")}catch(l){return void setTimeout(z,50)}m()}}(window);
\ No newline at end of file
+window._iconfont_svg_string_4125778='',function(a){var l=(l=document.getElementsByTagName("script"))[l.length-1],c=l.getAttribute("data-injectcss"),l=l.getAttribute("data-disable-injectsvg");if(!l){var t,h,i,o,z,v=function(l,c){c.parentNode.insertBefore(l,c)};if(c&&!a.__iconfont__svg__cssinject__){a.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(l){console&&console.log(l)}}t=function(){var l,c=document.createElement("div");c.innerHTML=a._iconfont_svg_string_4125778,(c=c.getElementsByTagName("svg")[0])&&(c.setAttribute("aria-hidden","true"),c.style.position="absolute",c.style.width=0,c.style.height=0,c.style.overflow="hidden",c=c,(l=document.body).firstChild?v(c,l.firstChild):l.appendChild(c))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(t,0):(h=function(){document.removeEventListener("DOMContentLoaded",h,!1),t()},document.addEventListener("DOMContentLoaded",h,!1)):document.attachEvent&&(i=t,o=a.document,z=!1,e(),o.onreadystatechange=function(){"complete"==o.readyState&&(o.onreadystatechange=null,m())})}function m(){z||(z=!0,i())}function e(){try{o.documentElement.doScroll("left")}catch(l){return void setTimeout(e,50)}m()}}(window);
\ No newline at end of file
diff --git a/web/src/assets/iconfont/iconfont.json b/web/src/assets/iconfont/iconfont.json
index ea413f94..50942272 100644
--- a/web/src/assets/iconfont/iconfont.json
+++ b/web/src/assets/iconfont/iconfont.json
@@ -5,6 +5,62 @@
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
+ {
+ "icon_id": "12600976",
+ "name": "xls",
+ "font_class": "xls",
+ "unicode": "e678",
+ "unicode_decimal": 59000
+ },
+ {
+ "icon_id": "3750429",
+ "name": "file",
+ "font_class": "file",
+ "unicode": "e62f",
+ "unicode_decimal": 58927
+ },
+ {
+ "icon_id": "4318810",
+ "name": "doc",
+ "font_class": "doc",
+ "unicode": "e6c2",
+ "unicode_decimal": 59074
+ },
+ {
+ "icon_id": "4318811",
+ "name": "pdf",
+ "font_class": "pdf",
+ "unicode": "e6c3",
+ "unicode_decimal": 59075
+ },
+ {
+ "icon_id": "4628503",
+ "name": "ppt",
+ "font_class": "ppt",
+ "unicode": "e642",
+ "unicode_decimal": 58946
+ },
+ {
+ "icon_id": "6233095",
+ "name": "txt",
+ "font_class": "txt",
+ "unicode": "e644",
+ "unicode_decimal": 58948
+ },
+ {
+ "icon_id": "12600910",
+ "name": "sql",
+ "font_class": "sql",
+ "unicode": "e65b",
+ "unicode_decimal": 58971
+ },
+ {
+ "icon_id": "31260974",
+ "name": "md",
+ "font_class": "md",
+ "unicode": "e63a",
+ "unicode_decimal": 58938
+ },
{
"icon_id": "1278349",
"name": "loading",
diff --git a/web/src/assets/iconfont/iconfont.ttf b/web/src/assets/iconfont/iconfont.ttf
index 70c1c350..a00e66a7 100644
Binary files a/web/src/assets/iconfont/iconfont.ttf and b/web/src/assets/iconfont/iconfont.ttf differ
diff --git a/web/src/assets/iconfont/iconfont.woff b/web/src/assets/iconfont/iconfont.woff
index bba70a0d..0eb4791e 100644
Binary files a/web/src/assets/iconfont/iconfont.woff and b/web/src/assets/iconfont/iconfont.woff differ
diff --git a/web/src/assets/iconfont/iconfont.woff2 b/web/src/assets/iconfont/iconfont.woff2
index 5264eadc..1d906e0c 100644
Binary files a/web/src/assets/iconfont/iconfont.woff2 and b/web/src/assets/iconfont/iconfont.woff2 differ
diff --git a/web/src/components/FileSelect.vue b/web/src/components/FileSelect.vue
new file mode 100644
index 00000000..e25c7de5
--- /dev/null
+++ b/web/src/components/FileSelect.vue
@@ -0,0 +1,171 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/web/src/components/UserProfile.vue b/web/src/components/UserProfile.vue
index 105fd0b6..1d16ae84 100644
--- a/web/src/components/UserProfile.vue
+++ b/web/src/components/UserProfile.vue
@@ -7,6 +7,7 @@
:auto-upload="true"
:show-file-list="false"
:http-request="afterRead"
+ accept=".png,.jpg,.jpeg,.bmp"
>
diff --git a/web/src/views/ChatPlus.vue b/web/src/views/ChatPlus.vue
index 8611acc8..b45e9a32 100644
--- a/web/src/views/ChatPlus.vue
+++ b/web/src/views/ChatPlus.vue
@@ -187,6 +187,9 @@
:rows="2"
placeholder="按 Enter 键发送消息,使用 Ctrl + Enter 换行"
/>
+
+
+
@@ -290,6 +293,7 @@ import ConfigDialog from "@/components/ConfigDialog.vue";
import {checkSession} from "@/action/session";
import Welcome from "@/components/Welcome.vue";
import ChatMidJourney from "@/components/ChatMidJourney.vue";
+import FileSelect from "@/components/FileSelect.vue";
const title = ref('ChatGPT-智能助手');
const models = ref([])
@@ -875,6 +879,11 @@ const notShow = () => {
localStorage.setItem(showNoticeKey.value + loginUser.value.username, true)
showDemoNotice.value = false
}
+
+// 插入文件路径
+const insertURL = (url) => {
+ prompt.value += " " + url + " "
+}