Browse Source

Support uploading file

HEAD
Yang Luo 3 years ago
parent
commit
c3f9ecb5da
5 changed files with 69 additions and 19 deletions
  1. +15
    -2
      controllers/file.go
  2. +20
    -5
      object/file.go
  3. +1
    -3
      storage/aliyun.go
  4. +28
    -7
      web/src/FileTree.js
  5. +5
    -2
      web/src/backend/FileBackend.js

+ 15
- 2
controllers/file.go View File

@@ -2,6 +2,7 @@ package controllers


import ( import (
"encoding/json" "encoding/json"
"mime/multipart"


"github.com/casbin/casbase/object" "github.com/casbin/casbase/object"
) )
@@ -23,9 +24,21 @@ func (c *ApiController) UpdateFile() {
func (c *ApiController) AddFile() { func (c *ApiController) AddFile() {
storeId := c.Input().Get("store") storeId := c.Input().Get("store")
key := c.Input().Get("key") key := c.Input().Get("key")
newFolder := c.Input().Get("newFolder")
isLeaf := c.Input().Get("isLeaf") == "1"
filename := c.Input().Get("filename")
var file multipart.File

if isLeaf {
var err error
file, _, err = c.GetFile("file")
if err != nil {
c.ResponseError(err.Error())
return
}
defer file.Close()
}


c.Data["json"] = object.AddFile(storeId, key, newFolder)
c.Data["json"] = object.AddFile(storeId, key, isLeaf, filename, file)
c.ServeJSON() c.ServeJSON()
} }




+ 20
- 5
object/file.go View File

@@ -1,7 +1,10 @@
package object package object


import ( import (
"bytes"
"fmt" "fmt"
"io"
"mime/multipart"


"github.com/casbin/casbase/storage" "github.com/casbin/casbase/storage"
) )
@@ -10,14 +13,27 @@ func UpdateFile(storeId string, key string, file *File) bool {
return true return true
} }


func AddFile(storeId string, key string, newFolder string) bool {
func AddFile(storeId string, key string, isLeaf bool, filename string, file multipart.File) bool {
store := GetStore(storeId) store := GetStore(storeId)
if store == nil { if store == nil {
return false return false
} }


objectKey := fmt.Sprintf("%s/%s/_hidden.ini", key, newFolder)
storage.PutObject(store.Bucket, objectKey)
var objectKey string
var fileBuffer *bytes.Buffer
if isLeaf {
objectKey = fmt.Sprintf("%s/%s", key, filename)
fileBuffer = bytes.NewBuffer(nil)
if _, err := io.Copy(fileBuffer, file); err != nil {
panic(err)
}

} else {
objectKey = fmt.Sprintf("%s/%s/_hidden.ini", key, filename)
fileBuffer = bytes.NewBuffer(nil)
}

storage.PutObject(store.Bucket, objectKey, fileBuffer)
return true return true
} }


@@ -29,12 +45,11 @@ func DeleteFile(storeId string, key string, isLeaf bool) bool {


if isLeaf { if isLeaf {
storage.DeleteObject(store.Bucket, key) storage.DeleteObject(store.Bucket, key)
return true
} else { } else {
objects := storage.ListObjects(store.Bucket, key) objects := storage.ListObjects(store.Bucket, key)
for _, object := range objects { for _, object := range objects {
storage.DeleteObject(store.Bucket, object.Key) storage.DeleteObject(store.Bucket, object.Key)
} }
return true
} }
return true
} }

+ 1
- 3
storage/aliyun.go View File

@@ -48,11 +48,9 @@ func ListObjects(bucketName string, prefix string) []oss.ObjectProperties {
return res return res
} }


func PutObject(bucketName string, key string) {
func PutObject(bucketName string, key string, fileBuffer *bytes.Buffer) {
bucket := getBucket(bucketName) bucket := getBucket(bucketName)


fileBuffer := bytes.NewBuffer(nil)

err := bucket.PutObject(key, fileBuffer) err := bucket.PutObject(key, fileBuffer)
if err != nil { if err != nil {
panic(err) panic(err)


+ 28
- 7
web/src/FileTree.js View File

@@ -1,5 +1,5 @@
import React from "react"; import React from "react";
import {Button, Col, Empty, Input, Popconfirm, Row, Spin, Tooltip, Tree} from 'antd';
import {Button, Col, Empty, Input, Popconfirm, Row, Spin, Tooltip, Tree, Upload} from 'antd';
import {CloudUploadOutlined, createFromIconfontCN, DeleteOutlined, EditOutlined, FolderAddOutlined, RadiusSettingOutlined} from "@ant-design/icons"; import {CloudUploadOutlined, createFromIconfontCN, DeleteOutlined, EditOutlined, FolderAddOutlined, RadiusSettingOutlined} from "@ant-design/icons";
import * as Setting from "./Setting"; import * as Setting from "./Setting";
import * as FileBackend from "./backend/FileBackend"; import * as FileBackend from "./backend/FileBackend";
@@ -86,9 +86,24 @@ class FileTree extends React.Component {
}; };
} }


uploadFile(file, info) {
const storeId = `${this.props.store.owner}/${this.props.store.name}`;

// this.setState({uploading: true});
const filename = info.fileList[0].name;
FileBackend.addFile(storeId, file.key, true, filename, info.file)
.then(res => {
Setting.showMessage("success", `File uploaded successfully`);
window.location.reload();
})
.catch(error => {
Setting.showMessage("error", `File failed to upload: ${error}`);
});
};

addFile(file, newFolder) { addFile(file, newFolder) {
const storeId = `${this.props.store.owner}/${this.props.store.name}`; const storeId = `${this.props.store.owner}/${this.props.store.name}`;
FileBackend.addFile(storeId, file.key, newFolder)
FileBackend.addFile(storeId, file.key, false, newFolder, null)
.then((res) => { .then((res) => {
Setting.showMessage("success", `File added successfully`); Setting.showMessage("success", `File added successfully`);
window.location.reload(); window.location.reload();
@@ -303,10 +318,16 @@ class FileTree extends React.Component {
}} /> }} />
</Tooltip> </Tooltip>
<Tooltip title={i18next.t("store:Upload file")}> <Tooltip title={i18next.t("store:Upload file")}>
<Button style={{marginRight: "5px"}} icon={<CloudUploadOutlined />} size="small" onClick={(e) => {
Setting.showMessage("error", "Upload file");
e.stopPropagation();
}} />
<Upload maxCount={1} accept="*" showUploadList={false} beforeUpload={file => {return false;}} onChange={info => {
this.uploadFile(file, info);
}}
>
<Button style={{marginRight: "5px"}} icon={<CloudUploadOutlined />} size="small" />
</Upload>
{/*<Button style={{marginRight: "5px"}} icon={<CloudUploadOutlined />} size="small" onClick={(e) => {*/}
{/* Setting.showMessage("error", "Upload file");*/}
{/* e.stopPropagation();*/}
{/*}} />*/}
</Tooltip> </Tooltip>
<Tooltip title={i18next.t("store:Delete")}> <Tooltip title={i18next.t("store:Delete")}>
<span onClick={(e) => e.stopPropagation()}> <span onClick={(e) => e.stopPropagation()}>
@@ -404,7 +425,7 @@ class FileTree extends React.Component {
); );
} }


if (["txt", "html", "js", "css", "md"].includes(ext)) {
if (["txt", "htm", "html", "js", "css", "md"].includes(ext)) {
if (this.state.loading) { if (this.state.loading) {
return ( return (
<div className="App"> <div className="App">


+ 5
- 2
web/src/backend/FileBackend.js View File

@@ -9,10 +9,13 @@ export function updateFile(storeId, name, file) {
}).then(res => res.json()); }).then(res => res.json());
} }
export function addFile(storeId, key, newFolder) {
return fetch(`${Setting.ServerUrl}/api/add-file?store=${storeId}&key=${key}&newFolder=${newFolder}`, {
export function addFile(storeId, key, isLeaf, filename, file) {
let formData = new FormData();
formData.append("file", file);
return fetch(`${Setting.ServerUrl}/api/add-file?store=${storeId}&key=${key}&isLeaf=${isLeaf ? 1 : 0}&filename=${filename}`, {
method: 'POST', method: 'POST',
credentials: 'include', credentials: 'include',
body: formData,
}).then(res => res.json()); }).then(res => res.json());
} }


Loading…
Cancel
Save