mirror of
https://github.com/Kakune55/Pixel.git
synced 2025-05-06 18:29:25 +08:00
完成文件上传链接生成功能
This commit is contained in:
parent
42c764f825
commit
ee9aeb4820
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/data
|
138
Web/info.html
Normal file
138
Web/info.html
Normal file
@ -0,0 +1,138 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>文件详细</title>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Arial', sans-serif;
|
||||
background-color: #f5f5f5;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
header {
|
||||
background-color: #333;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
#container {
|
||||
width: 85%;
|
||||
max-width: 800px;
|
||||
background-color: #fff;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||
margin-top: 80px;
|
||||
/* 顶栏高度 + 20px 的间距 */
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#table-container {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
#table-container table {
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#table-container tr:hover {
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
|
||||
#table-container td:first-child {
|
||||
width: 20%;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
#table-container td:last-child {
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
#imgshow {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<header>
|
||||
<h2>Pixel</h2>
|
||||
<!-- 添加帮助和用户信息的按钮/链接等 -->
|
||||
</header>
|
||||
|
||||
<div id="container">
|
||||
<div id="thumbnail-container">
|
||||
<img id="imgshow" alt="缩略图">
|
||||
<hr>
|
||||
<div id="table-container">
|
||||
<table id="linktable">
|
||||
<tr>
|
||||
<td>URL</td>
|
||||
<td><span class="imgurl"></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MarkDown</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>HTML</td>
|
||||
<td><img src="<span class="imgurl"></span>" alt="img" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>HTML</td>
|
||||
<td>[img]<span class="imgurl"></span>[/img]
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function GetRequest() {
|
||||
var url = location.search; //获取url中"?"符后的字串
|
||||
var theRequest = new Object();
|
||||
if (url.indexOf("?") != -1) {
|
||||
var str = url.substr(1);
|
||||
strs = str.split("&");
|
||||
for (var i = 0; i < strs.length; i++) {
|
||||
theRequest[strs[i].split("=")[0]] = decodeURI(strs[i].split("=")[1]);
|
||||
}
|
||||
}
|
||||
return theRequest;
|
||||
}
|
||||
const Resq = GetRequest();
|
||||
linkid = Resq["id"]
|
||||
|
||||
imgurl = window.location.protocol + "//" + window.location.host + "/img?id=" + linkid
|
||||
document.getElementById("imgshow").src = imgurl
|
||||
var elements = document.getElementsByClassName("imgurl"); // 获取所有具有类名 "myClass" 的元素
|
||||
for (var i = 0; i < elements.length; i++) {
|
||||
elements[i].innerHTML = imgurl;
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,5 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
@ -36,7 +37,8 @@
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||
margin-top: 80px; /* 顶栏高度 + 20px 的间距 */
|
||||
margin-top: 80px;
|
||||
/* 顶栏高度 + 20px 的间距 */
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@ -54,7 +56,6 @@
|
||||
background-color: #4caf50;
|
||||
color: #fff;
|
||||
border: none;
|
||||
padding: 10px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.3s;
|
||||
@ -71,7 +72,6 @@
|
||||
background-color: #4caf50;
|
||||
color: #fff;
|
||||
border: none;
|
||||
padding: 10px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.3s;
|
||||
@ -99,7 +99,8 @@
|
||||
margin-top: 20px;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
display: none; /* 默认隐藏 */
|
||||
display: none;
|
||||
/* 默认隐藏 */
|
||||
}
|
||||
|
||||
#thumbnail {
|
||||
@ -108,6 +109,7 @@
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<header>
|
||||
@ -158,7 +160,8 @@
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState === XMLHttpRequest.DONE) {
|
||||
if (xhr.status === 200) {
|
||||
alert('文件上传成功!');
|
||||
gourl = "info?id=" + xhr.responseText
|
||||
window.location.href = gourl
|
||||
} else {
|
||||
alert('文件上传失败!');
|
||||
}
|
||||
@ -198,4 +201,5 @@
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@ -18,7 +18,8 @@ func Initdb() {
|
||||
createTableSQL := `
|
||||
CREATE TABLE IF NOT EXISTS mytable (
|
||||
link TEXT PRIMARY KEY,
|
||||
md5 TEXT NOT NULL
|
||||
md5 TEXT NOT NULL,
|
||||
ext TEXT NOT NULL
|
||||
);
|
||||
`
|
||||
|
||||
@ -28,7 +29,7 @@ func Initdb() {
|
||||
}
|
||||
}
|
||||
|
||||
func NewFile(linkID string, md5 string) {
|
||||
func NewFile(linkID string, md5 string, ext string) {
|
||||
db, err := sql.Open("sqlite3", "./data/database.db")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
@ -37,7 +38,7 @@ func NewFile(linkID string, md5 string) {
|
||||
|
||||
// SQL语句
|
||||
SQL := `
|
||||
INSERT INTO "main"."mytable" ("link", "md5") VALUES (?, ?)
|
||||
INSERT INTO "main"."mytable" ("link", "md5" ,"ext") VALUES (?, ? , ?)
|
||||
`
|
||||
|
||||
stmt, err := db.Prepare(SQL)
|
||||
@ -45,13 +46,13 @@ func NewFile(linkID string, md5 string) {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = stmt.Exec(linkID,md5) //插入记录
|
||||
_, err = stmt.Exec(linkID,md5,ext) //插入记录
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func GetFileInfo(linkID string) string {
|
||||
func GetFileName(linkID string) string {
|
||||
db, err := sql.Open("sqlite3", "./data/database.db")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
@ -71,7 +72,8 @@ func GetFileInfo(linkID string) string {
|
||||
// 扫描查询结果
|
||||
var md5 string
|
||||
var linkIDx string
|
||||
err = row.Scan(&linkIDx,&md5)
|
||||
var ext string
|
||||
err = row.Scan(&linkIDx,&md5,&ext)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return ""
|
||||
@ -80,5 +82,5 @@ func GetFileInfo(linkID string) string {
|
||||
}
|
||||
return ""
|
||||
}
|
||||
return md5
|
||||
return md5+ext
|
||||
}
|
66
main.go
66
main.go
@ -11,6 +11,7 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
@ -31,7 +32,6 @@ func init() {
|
||||
`
|
||||
fmt.Println(appinfo)
|
||||
|
||||
database.Initdb() //初始化数据库
|
||||
dirPath := "./data/img"
|
||||
|
||||
// 使用 os.Stat 检查目录是否存在
|
||||
@ -39,7 +39,7 @@ func init() {
|
||||
|
||||
if os.IsNotExist(err) {
|
||||
// 目录不存在,可以调用 os.Mkdir 创建
|
||||
err := os.Mkdir(dirPath, 0755)
|
||||
err := os.MkdirAll(dirPath, 0755)
|
||||
if err != nil {
|
||||
fmt.Println("无法创建目录:", err)
|
||||
return
|
||||
@ -52,18 +52,28 @@ func init() {
|
||||
// 发生其他错误
|
||||
fmt.Println("发生错误:", err)
|
||||
}
|
||||
|
||||
database.Initdb() //初始化数据库
|
||||
fmt.Println("数据库初始化完成")
|
||||
}
|
||||
|
||||
|
||||
func main() {
|
||||
|
||||
http.HandleFunc("/upload", upload) //设置访问的路由
|
||||
http.HandleFunc("/info", showimg)
|
||||
http.HandleFunc("/upload", upload)
|
||||
http.HandleFunc("/img/",downloadHandler)//设置访问的路由
|
||||
fmt.Println("Web服务器已启动")
|
||||
err := http.ListenAndServe(":9090", nil) //设置监听的端口
|
||||
if err != nil {
|
||||
log.Fatal("ListenAndServe: ", err)
|
||||
}
|
||||
}
|
||||
|
||||
func showimg(w http.ResponseWriter, r *http.Request) {
|
||||
t, _ := template.ParseFiles("Web/info.html")
|
||||
t.Execute(w, "Hello")
|
||||
}
|
||||
|
||||
|
||||
// 处理/upload 逻辑
|
||||
func upload(w http.ResponseWriter, r *http.Request) {
|
||||
@ -116,8 +126,9 @@ func upload(w http.ResponseWriter, r *http.Request) {
|
||||
io.Copy(f, file)
|
||||
|
||||
// 存入数据库
|
||||
database.NewFile(RandomString(10),md5sum)
|
||||
|
||||
var linkid = RandomString(10)
|
||||
database.NewFile(linkid,md5sum,ext)
|
||||
w.Write([]byte(linkid))
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,3 +142,46 @@ func RandomString(n int) string {
|
||||
}
|
||||
return string(bytes)
|
||||
}
|
||||
|
||||
func downloadHandler(w http.ResponseWriter, r *http.Request) {
|
||||
// 获取请求参数,例如文件名
|
||||
filename := r.FormValue("id")
|
||||
if filename == "" {
|
||||
http.Error(w, "未提供文件名", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// 拼接文件路径,确保路径安全性
|
||||
filePath := filepath.Join("./data/img", database.GetFileName(filename))
|
||||
|
||||
// 打开文件
|
||||
file, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
http.Error(w, "文件未找到", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// 获取文件信息
|
||||
fileInfo, err := file.Stat()
|
||||
if err != nil {
|
||||
http.Error(w, "无法获取文件信息", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// 设置响应头,告诉浏览器直接显示文件
|
||||
w.Header().Set("Content-Disposition", "inline; filename="+filename)
|
||||
w.Header().Set("Content-Type", "image/jpeg") // 适用于 JPEG 图片,根据实际文件类型设置
|
||||
|
||||
// 将文件内容拷贝到响应体中
|
||||
http.ServeContent(w, r, filename, fileInfo.ModTime(), file)
|
||||
}
|
||||
|
||||
// 辅助函数,获取文件大小
|
||||
func fileSize(file *os.File) int64 {
|
||||
stat, err := file.Stat()
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return stat.Size()
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user