| @@ -0,0 +1,47 @@ | |||
| package controllers | |||
| import ( | |||
| "encoding/json" | |||
| "github.com/casbin/casbase/object" | |||
| ) | |||
| func (c *ApiController) UpdateFile() { | |||
| storeId := c.Input().Get("store") | |||
| key := c.Input().Get("key") | |||
| var file object.File | |||
| err := json.Unmarshal(c.Ctx.Input.RequestBody, &file) | |||
| if err != nil { | |||
| panic(err) | |||
| } | |||
| c.Data["json"] = object.UpdateFile(storeId, key, &file) | |||
| c.ServeJSON() | |||
| } | |||
| func (c *ApiController) AddFile() { | |||
| storeId := c.Input().Get("store") | |||
| var file object.File | |||
| err := json.Unmarshal(c.Ctx.Input.RequestBody, &file) | |||
| if err != nil { | |||
| panic(err) | |||
| } | |||
| c.Data["json"] = object.AddFile(storeId, &file) | |||
| c.ServeJSON() | |||
| } | |||
| func (c *ApiController) DeleteFile() { | |||
| storeId := c.Input().Get("store") | |||
| var file object.File | |||
| err := json.Unmarshal(c.Ctx.Input.RequestBody, &file) | |||
| if err != nil { | |||
| panic(err) | |||
| } | |||
| c.Data["json"] = object.DeleteFile(storeId, &file) | |||
| c.ServeJSON() | |||
| } | |||
| @@ -0,0 +1,26 @@ | |||
| package object | |||
| import "github.com/casbin/casbase/storage" | |||
| func UpdateFile(storeId string, key string, file *File) bool { | |||
| return true | |||
| } | |||
| func AddFile(storeId string, file *File) bool { | |||
| affected, err := adapter.engine.Insert(file) | |||
| if err != nil { | |||
| panic(err) | |||
| } | |||
| return affected != 0 | |||
| } | |||
| func DeleteFile(storeId string, file *File) bool { | |||
| store := GetStore(storeId) | |||
| if store == nil { | |||
| return false | |||
| } | |||
| storage.DeleteObject(store.Bucket, file.Key) | |||
| return true | |||
| } | |||
| @@ -51,4 +51,8 @@ func initAPI() { | |||
| beego.Router("/api/update-store", &controllers.ApiController{}, "POST:UpdateStore") | |||
| beego.Router("/api/add-store", &controllers.ApiController{}, "POST:AddStore") | |||
| beego.Router("/api/delete-store", &controllers.ApiController{}, "POST:DeleteStore") | |||
| beego.Router("/api/update-file", &controllers.ApiController{}, "POST:UpdateFile") | |||
| beego.Router("/api/add-file", &controllers.ApiController{}, "POST:AddFile") | |||
| beego.Router("/api/delete-file", &controllers.ApiController{}, "POST:DeleteFile") | |||
| } | |||
| @@ -2,7 +2,7 @@ package storage | |||
| import "github.com/aliyun/aliyun-oss-go-sdk/oss" | |||
| func ListObjects(bucketName string) []oss.ObjectProperties { | |||
| func getBucket(bucketName string) *oss.Bucket { | |||
| client, err := oss.New(endpoint, clientId, clientSecret) | |||
| if err != nil { | |||
| panic(err) | |||
| @@ -13,6 +13,12 @@ func ListObjects(bucketName string) []oss.ObjectProperties { | |||
| panic(err) | |||
| } | |||
| return bucket | |||
| } | |||
| func ListObjects(bucketName string) []oss.ObjectProperties { | |||
| bucket := getBucket(bucketName) | |||
| res := []oss.ObjectProperties{} | |||
| marker := oss.Marker("") | |||
| i := 0 | |||
| @@ -37,3 +43,12 @@ func ListObjects(bucketName string) []oss.ObjectProperties { | |||
| return res | |||
| } | |||
| func DeleteObject(bucketName string, key string) { | |||
| bucket := getBucket(bucketName) | |||
| err := bucket.DeleteObject(key) | |||
| if err != nil { | |||
| panic(err) | |||
| } | |||
| } | |||
| @@ -1,9 +1,10 @@ | |||
| import React from "react"; | |||
| import {Button, Col, Empty, Row, Spin, Tooltip, Tree} from 'antd'; | |||
| import {CloudUploadOutlined, createFromIconfontCN, DeleteOutlined, EditOutlined, FolderAddOutlined, RadiusSettingOutlined} from "@ant-design/icons"; | |||
| import FileViewer from 'react-file-viewer'; | |||
| import * as Setting from "./Setting"; | |||
| import * as FileBackend from "./backend/FileBackend"; | |||
| import DocViewer, { DocViewerRenderers } from "react-doc-viewer"; | |||
| import FileViewer from 'react-file-viewer'; | |||
| import {Controlled as CodeMirror} from "react-codemirror2"; | |||
| import "codemirror/lib/codemirror.css"; | |||
| @@ -76,6 +77,18 @@ class FileTree extends React.Component { | |||
| } | |||
| } | |||
| deleteFile(file) { | |||
| FileBackend.deleteFile(`${this.props.store.owner}/${this.props.store.name}`, file) | |||
| .then((res) => { | |||
| Setting.showMessage("success", `File deleted successfully`); | |||
| window.location.reload(); | |||
| } | |||
| ) | |||
| .catch(error => { | |||
| Setting.showMessage("error", `File failed to delete: ${error}`); | |||
| }); | |||
| } | |||
| renderTree(store) { | |||
| const onDragEnter = (info) => { | |||
| // console.log(info); // expandedKeys 需要受控时设置 | |||
| @@ -204,13 +217,22 @@ class FileTree extends React.Component { | |||
| <Tooltip color={"rgb(255,255,255,0.8)"} placement="right" title={ | |||
| <div> | |||
| <Tooltip title={i18next.t("store:Rename")}> | |||
| <Button style={{marginRight: "5px"}} icon={<EditOutlined />} size="small" onClick={(e) => {Setting.showMessage("error", "Rename");e.stopPropagation()}} /> | |||
| <Button style={{marginRight: "5px"}} icon={<EditOutlined />} size="small" onClick={(e) => { | |||
| Setting.showMessage("error", "Rename"); | |||
| e.stopPropagation(); | |||
| }} /> | |||
| </Tooltip> | |||
| <Tooltip title={i18next.t("store:Move")}> | |||
| <Button style={{marginRight: "5px"}} icon={<RadiusSettingOutlined />} size="small" onClick={(e) => {Setting.showMessage("error", "Move");e.stopPropagation()}} /> | |||
| <Button style={{marginRight: "5px"}} icon={<RadiusSettingOutlined />} size="small" onClick={(e) => { | |||
| Setting.showMessage("error", "Move"); | |||
| e.stopPropagation(); | |||
| }} /> | |||
| </Tooltip> | |||
| <Tooltip title={i18next.t("store:Delete")}> | |||
| <Button icon={<DeleteOutlined />} size="small" onClick={(e) => {Setting.showMessage("error", "Delete");e.stopPropagation()}} /> | |||
| <Button icon={<DeleteOutlined />} size="small" onClick={(e) => { | |||
| this.deleteFile(file); | |||
| e.stopPropagation(); | |||
| }} /> | |||
| </Tooltip> | |||
| </div> | |||
| }> | |||
| @@ -0,0 +1,28 @@ | |||
| import * as Setting from "../Setting"; | |||
| export function updateFile(storeName, name, file) { | |||
| let newFile = Setting.deepCopy(file); | |||
| return fetch(`${Setting.ServerUrl}/api/update-file?store=${storeName}&name=${name}`, { | |||
| method: 'POST', | |||
| credentials: 'include', | |||
| body: JSON.stringify(newFile), | |||
| }).then(res => res.json()); | |||
| } | |||
| export function addFile(storeName, file) { | |||
| let newFile = Setting.deepCopy(file); | |||
| return fetch(`${Setting.ServerUrl}/api/add-file?store=${storeName}`, { | |||
| method: 'POST', | |||
| credentials: 'include', | |||
| body: JSON.stringify(newFile), | |||
| }).then(res => res.json()); | |||
| } | |||
| export function deleteFile(storeName, file) { | |||
| let newFile = Setting.deepCopy(file); | |||
| return fetch(`${Setting.ServerUrl}/api/delete-file?store=${storeName}`, { | |||
| method: 'POST', | |||
| credentials: 'include', | |||
| body: JSON.stringify(newFile), | |||
| }).then(res => res.json()); | |||
| } | |||