提交文件api还需要完善

This commit is contained in:
2025-06-30 18:42:39 +08:00
parent 18c2cb9d4a
commit a6e4d6e219
5 changed files with 191 additions and 110 deletions
+37 -6
View File
@@ -11,20 +11,51 @@ import (
"saas/models" "saas/models"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/mitchellh/mapstructure"
) )
func V1_file_api(r *gin.RouterGroup) { func V1_file_api(r *gin.RouterGroup) {
r.GET("/", func(ctx *gin.Context) { r.GET("/", func(ctx *gin.Context) {
ctx.JSON(http.StatusOK, map[string]interface{}{ Return_json(ctx, "json_error", nil)
"error": "you need use Post",
})
}) })
r.POST("/upload", func(ctx *gin.Context) {
//文件api是一定要登录的,直接用中间件判断登录状态
// r.Use(func(ctx *gin.Context) {
// Use_is_login(ctx)
// })
r.Use(func(ctx *gin.Context) {
fmt.Println("file_api")
cookie := ctx.PostForm("cookie")
var cookie_t models.Cookie
if err := mapstructure.Decode(cookie, &cookie_t); err == nil {
if cookie_t.Value != "" {
cookie_vel := cookie_t.Value
fmt.Println(cookie_vel)
}
}
//fmt.Println(cookie)
file, err := ctx.FormFile("file") file, err := ctx.FormFile("file")
if err == nil { if err == nil {
dst := path.Join("./data/upload", file.Filename) fmt.Println(file)
ctx.SaveUploadedFile(file, dst) } else {
fmt.Println(err)
} }
})
r.POST("/upload", func(ctx *gin.Context) {
//先判断有没有登录
//获取中间件处理的结果
_, is_login := ctx.Get("user_info")
if is_login {
Return_json(ctx, "api_ok", nil)
} else {
Return_json(ctx, "user_no_sign", nil)
}
}) })
//接收头像的接口, //接收头像的接口,
+3 -4
View File
@@ -1,7 +1,6 @@
package routers package routers
import ( import (
"fmt"
"saas/models" "saas/models"
"strings" "strings"
"time" "time"
@@ -157,9 +156,9 @@ func V1_user_api(r *gin.RouterGroup) {
//先判断是否已经登录 //先判断是否已经登录
//获取中间件处理的结果 //获取中间件处理的结果
user_info, is_login := ctx.Get("user_info") _, is_login := ctx.Get("user_info")
fmt.Println(is_login) //fmt.Println(is_login)
fmt.Println(user_info) //fmt.Println(user_info)
if is_login == true { if is_login == true {
//fmt.Println("loged") //fmt.Println("loged")
cookie_any, _ := ctx.Get("cookie") //这个cookie在中间件已经判断为有效的,否则is_login不可能为true,所以直接在数据库删除应该是安全的 cookie_any, _ := ctx.Get("cookie") //这个cookie在中间件已经判断为有效的,否则is_login不可能为true,所以直接在数据库删除应该是安全的
+6 -2
View File
@@ -1,7 +1,6 @@
package routers package routers
import ( import (
"fmt"
"saas/models" "saas/models"
"time" "time"
@@ -28,6 +27,7 @@ func Fitst_use(ctx *gin.Context) {
} }
} }
var data_t map[string]interface{} var data_t map[string]interface{}
if err = mapstructure.Decode(jsonData["data"], &data_t); err == nil { if err = mapstructure.Decode(jsonData["data"], &data_t); err == nil {
ctx.Set("data", &data_t) ctx.Set("data", &data_t)
@@ -80,7 +80,7 @@ func Fitst_use(ctx *gin.Context) {
models.DB.Create(&user_info) // 传入指针 models.DB.Create(&user_info) // 传入指针
} }
//写入当前登录的用户信息 传递给下一个组件 //写入当前登录的用户信息 传递给下一个组件
fmt.Println(user_info) //fmt.Println(user_info)
ctx.Set("user_info", &user_info) ctx.Set("user_info", &user_info)
ctx.Set("user", &user) ctx.Set("user", &user)
} else { } else {
@@ -116,3 +116,7 @@ func Fitst_use(ctx *gin.Context) {
} }
} }
func Use_is_login(ctx *gin.Context) {
}
+53 -10
View File
@@ -27,9 +27,51 @@ function load_json(key) {
} }
} }
function post_file(path, file, file_name, callback) {
var head_path = "/api/v1/file";
// 创建FormData对象
const formData = new FormData();
formData.append("file", file, file_name); // 'file' 是后端接收文件的字段名
//获取保存的cookie
var cookie = load_json("cookie");
//console.log(cookie);
formData.append("cookie", JSON.stringify(cookie)); //插入cookie
var re_data = {};
// 发送请求
axios
.post(head_path + path, formData, {
headers: {
"Content-Type": "multipart/form-data", // 这里实际上可以省略,因为FormData会被正确识别
},
})
.then((response) => {
//console.log(response)
re_data["statusCode"] = response.status;
//载入服务器返回的数据
if (response.data) {
re_data["data"] = response.data;
}
//自动保存服务器发送的cookie
if (response.cookie) {
if (response.cookie.Value == "") {
dele("cookie");
} else {
save_json("cookie", response.cookie);
}
}
callback(re_data);
})
.catch((error) => {
re_data["statusCode"] = -1;
re_data["error"] = error;
callback(re_data);
});
}
function post_json(path, json, callback) { function post_json(path, json, callback) {
var host = "";
var port = 0;
var head_path = "/api/v1"; var head_path = "/api/v1";
//把cookie插入json //把cookie插入json
var data = {}; var data = {};
@@ -52,20 +94,21 @@ function post_json(path, json, callback) {
//载入服务器返回的数据 //载入服务器返回的数据
if (response.data) { if (response.data) {
re_data["data"] = response.data; re_data["data"] = response.data;
} //自动保存服务器发送的cookie
//自动保存服务器发送的cookie if (response.data.cookie) {
if (response.cookie) { if (response.data.cookie.Value == "") {
if (response.cookie.Value == "") { dele("cookie");
dele("cookie"); } else {
} else { save_json("cookie", response.data.cookie);
save_json("cookie", response.cookie); }
} }
} }
callback(re_data); callback(re_data);
}) })
.catch((error) => { .catch((error) => {
re_data["statusCode"] = -1; re_data["statusCode"] = -1;
re_data["error"]=error; re_data["error"] = error;
callback(re_data); callback(re_data);
}); });
} }
+88 -84
View File
@@ -83,12 +83,14 @@
<div class="row g-3"> <div class="row g-3">
<div class="col-md"> <div class="col-md">
<div class="form-label">名字</div> <div class="form-label">名字</div>
<input id="username" type="text" class="form-control" value="{{.user_info.Username}}" maxlength="30"> <input id="username" type="text" class="form-control" value="{{.user_info.Username}}"
maxlength="30">
</div> </div>
<div class="col-md"> <div class="col-md">
<div class="form-label">备注</div> <div class="form-label">备注</div>
<input id="first_name" type="text" class="form-control" value="{{.user_info.FirstName}}" maxlength="50"> <input id="first_name" type="text" class="form-control" value="{{.user_info.FirstName}}"
maxlength="50">
</div> </div>
</div> </div>
@@ -230,9 +232,12 @@
/* 头像裁剪器样式*/ /* 头像裁剪器样式*/
.container { .container {
width: 95%; /* 改为百分比宽度 */ width: 95%;
margin: 20px auto; /* 增加上下边距 */ /* 改为百分比宽度 */
max-width: 1200px; /* 保留最大宽度 */ margin: 20px auto;
/* 增加上下边距 */
max-width: 1200px;
/* 保留最大宽度 */
background: white; background: white;
padding: 30px; padding: 30px;
border-radius: 12px; border-radius: 12px;
@@ -243,58 +248,76 @@
display: flex; display: flex;
gap: 30px; gap: 30px;
margin-top: 20px; margin-top: 20px;
flex-wrap: wrap; /* 添加换行支持 */ flex-wrap: wrap;
/* 添加换行支持 */
} }
/* 裁剪区域 */ /* 裁剪区域 */
.crop-section { .crop-section {
flex: 1 1 60%; /* 弹性布局基础宽度 */ flex: 1 1 60%;
min-width: 300px; /* 降低最小宽度 */ /* 弹性布局基础宽度 */
height: auto; /* 移除固定高度 */ min-width: 300px;
min-height: 400px; /* 设置最小度 */ /* 降低最小度 */
height: auto;
/* 移除固定高度 */
min-height: 400px;
/* 设置最小高度 */
} }
#image-wrapper { #image-wrapper {
width: 100%; width: 100%;
height: 60vh; /* 改用视窗单位 */ height: 60vh;
max-height: 600px; /* 设置最大高度 */ /* 改用视窗单位 */
max-height: 600px;
/* 设置最大高度 */
background: #f8f9fa; background: #f8f9fa;
border: 2px dashed #ddd; border: 2px dashed #ddd;
border-radius: 8px; border-radius: 8px;
overflow: hidden; overflow: hidden;
} }
/* 预览区域自适应 */ /* 预览区域自适应 */
.preview-section { .preview-section {
flex: 1 1 35%; /* 弹性布局基础宽度 */ flex: 1 1 35%;
min-width: 250px; /* 设置合理最小宽度 */ /* 弹性布局基础宽度 */
min-width: 250px;
/* 设置合理最小宽度 */
} }
/* 移动端适配 */
@media (max-width: 768px) { /* 移动端适配 */
@media (max-width: 768px) {
.container { .container {
padding: 15px; /* 减少内边距 */ padding: 15px;
/* 减少内边距 */
} }
.flex-wrapper { .flex-wrapper {
flex-direction: column; /* 垂直排列 */ flex-direction: column;
/* 垂直排列 */
} }
.crop-section, .crop-section,
.preview-section { .preview-section {
width: 100% !important; /* 强制全宽 */ width: 100% !important;
min-width: unset; /* 移除最小宽度 */ /* 强制全宽 */
min-width: unset;
/* 移除最小宽度 */
} }
#image-wrapper { #image-wrapper {
height: 50vh; /* 调整移动端高度 */ height: 50vh;
/* 调整移动端高度 */
} }
.preview-box { .preview-box {
width: 120px; /* 缩小预览区域 */ width: 120px;
/* 缩小预览区域 */
height: 120px; height: 120px;
} }
.controls { .controls {
flex-direction: column; /* 垂直排列按钮 */ flex-direction: column;
/* 垂直排列按钮 */
margin-top: 10px; margin-top: 10px;
} }
} }
@@ -519,7 +542,7 @@
const progressBar = document.querySelector('.progress-bar'); const progressBar = document.querySelector('.progress-bar');
const progressContainer = document.querySelector('.progress-container'); const progressContainer = document.querySelector('.progress-container');
try {
if (!cropper) { if (!cropper) {
showMessage('⚠️ 请先选择并裁剪图片', 'error'); showMessage('⚠️ 请先选择并裁剪图片', 'error');
return; return;
@@ -536,42 +559,23 @@
canvas.toBlob(resolve, 'image/jpeg', 0.9) canvas.toBlob(resolve, 'image/jpeg', 0.9)
); );
const formData = new FormData(); post_file("/upload", blob, `avatar_${Date.now()}.jpg`, (c) => {
formData.append('file', blob, `avatar_${Date.now()}.jpg`); if (c.statusCode == 200) {
formData.append('meta', JSON.stringify({ if (c.data.err_code == 0) {
width: canvas.width, //save_json("cookie", c.data.return.cookie)
height: canvas.height, banner_alert('success', "更换成功", 950)
scale: currentScale.toFixed(2) } else {
})); banner_alert('warning', "服务错误", 3000)
}
const response = await fetch('/api/v1/file/avatar', { } else {
method: 'POST', banner_alert('danger', "网络连接错误:" + c.statusCode, 3000)
body: formData,
headers: {
'X-Requested-With': 'XMLHttpRequest'
} }
}); })
if (!response.ok) throw new Error(`服务器错误: ${response.status}`);
const result = await response.json();
if (result.err_code == 0) {
showMessage(`✅ 上传成功!`, 'success');
set_user_avatar(result.data.path);
console.log(get_user_avatar());
avatar_toolt.hide();
} else {
showMessage(`❌ 上传失败: ${result.err_msg}`, 'error');
}
} catch (error) {
console.error('上传错误:', error);
showMessage(`❌ 上传失败: ${error.message}`, 'error');
} finally {
progressBar.style.width = '0%';
progressContainer.style.display = 'none';
}
}); });
// 消息提示 // 消息提示
@@ -594,37 +598,37 @@
//initCropper('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII='); //initCropper('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=');
//更新用户资料 //更新用户资料
function updata_user_info(){ function updata_user_info() {
const url = '/api/v1/user/updata_info'; const url = '/api/v1/user/updata_info';
const sumt_data = { const sumt_data = {
avatar:get_user_avatar(), avatar: get_user_avatar(),
username:document.getElementById("username").value, username: document.getElementById("username").value,
first_name:document.getElementById("first_name").value, first_name: document.getElementById("first_name").value,
birthday:document.getElementById("birthday-picker").value, birthday: document.getElementById("birthday-picker").value,
}; };
try { try {
const response = axios.post(url, sumt_data, { const response = axios.post(url, sumt_data, {
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}
}).then(response => {
//console.log(response)
if(response.data.err_code==0){
location.reload()
}else{
console.log(response.data)
}
});
} catch (error) {
if (error.response) {
// 服务器返回了错误状态码(如 4xx, 5xx)
console.error('服务器错误:', error.response.data);
} else {
console.error('请求未完成:', error.message);
} }
}).then(response => {
//console.log(response)
if (response.data.err_code == 0) {
location.reload()
} else {
console.log(response.data)
}
});
} catch (error) {
if (error.response) {
// 服务器返回了错误状态码(如 4xx, 5xx)
console.error('服务器错误:', error.response.data);
} else {
console.error('请求未完成:', error.message);
} }
}
} }
</script> </script>