Add: insert review

This commit is contained in:
2021-12-13 04:17:00 +08:00
parent e87b4823d9
commit 6b8bfedb9b
10 changed files with 157 additions and 5 deletions

View File

@@ -92,6 +92,8 @@ func NewAPI(config Config) (*API, error) {
apiMux.HandleFunc("/delete_tag_on_file", api.HandleDeleteTagOnFile)
// folder
apiMux.HandleFunc("/update_foldername", api.HandleUpdateFoldername)
// review
apiMux.HandleFunc("/insert_review", api.HandleInsertReview)
// below needs token
apiMux.HandleFunc("/walk", api.HandleWalk)
apiMux.HandleFunc("/reset", api.HandleReset)

View File

@@ -11,6 +11,7 @@ var (
ErrNotLoggedIn = errors.New("not logged in")
ErrNotAdmin = errors.New("not admin")
ErrEmpty = errors.New("Empty field detected, please fill in all fields")
ErrAnonymous = errors.New("Anonymous user detected, please login")
)
type Error struct {

42
pkg/api/handle_review.go Normal file
View File

@@ -0,0 +1,42 @@
package api
import (
"net/http"
"msw-open-music/pkg/database"
"encoding/json"
"time"
)
// review.FileId, review.Content
func (api *API) HandleInsertReview(w http.ResponseWriter, r *http.Request) {
review := &database.Review{}
err := json.NewDecoder(r.Body).Decode(review)
if err != nil {
api.HandleError(w, r, err)
return
}
// check not anonymous
err = api.CheckNotAnonymous(w, r)
if err != nil {
api.HandleError(w, r, err)
return
}
review.UserId, err = api.GetUserID(w, r)
if err != nil {
api.HandleError(w, r, err)
return
}
review.CreatedAt = time.Now().Unix()
err = api.Db.InsertReview(review)
if err != nil {
api.HandleError(w, r, err)
return
}
api.HandleOK(w, r)
}

View File

@@ -165,6 +165,25 @@ func (api *API) CheckAdmin(w http.ResponseWriter, r *http.Request) error {
return nil
}
func (api *API) CheckNotAnonymous(w http.ResponseWriter, r *http.Request) error {
session, _ := api.store.Get(r, api.defaultSessionName)
userId, ok := session.Values["userId"]
if !ok {
return ErrNotLoggedIn
}
user, err := api.Db.GetUserById(userId.(int64))
if err != nil {
return err
}
if user.Role == database.RoleAnonymous {
return ErrAnonymous
}
return nil
}
func (api *API) GetUserID(w http.ResponseWriter, r *http.Request) (int64, error) {
session, _ := api.store.Get(r, api.defaultSessionName)
userId, ok := session.Values["userId"]

View File

@@ -0,0 +1,10 @@
package database
func (database *Database) InsertReview(review *Review) error {
_, err := database.stmt.insertReview.Exec(
review.UserId,
review.FileId,
review.CreatedAt,
review.Content)
return err
}

View File

@@ -71,10 +71,12 @@ var initLikesTableQuery = `CREATE TABLE IF NOT EXISTS likes (
var initReviewsTableQuery = `CREATE TABLE IF NOT EXISTS reviews (
id INTEGER PRIMARY KEY,
user_id INTEGER NOT NULL,
time INTEGER NOT NULL,
modified_time INTEGER DEFAULT 0,
review TEXT NOT NULL,
FOREIGN KEY (user_id) REFERENCES users(id)
file_id INTEGER NOT NULL,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL DEFAULT 0,
content TEXT NOT NULL,
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (file_id) REFERENCES files(id)
);`
var initPlaybacksTableQuery = `CREATE TABLE IF NOT EXISTS playbacks (
@@ -202,6 +204,9 @@ var deleteTagOnFileQuery = `DELETE FROM file_has_tag WHERE tag_id = ? AND file_i
var updateFoldernameQuery = `UPDATE folders SET foldername = ? WHERE id = ?;`
var insertReviewQuery = `INSERT INTO reviews (user_id, file_id, created_at, content)
VALUES (?, ?, ?, ?);`
type Stmt struct {
initFilesTable *sql.Stmt
initFoldersTable *sql.Stmt
@@ -242,6 +247,7 @@ type Stmt struct {
getTagsOnFile *sql.Stmt
deleteTagOnFile *sql.Stmt
updateFoldername *sql.Stmt
insertReview *sql.Stmt
}
func NewPreparedStatement(sqlConn *sql.DB) (*Stmt, error) {
@@ -546,5 +552,11 @@ func NewPreparedStatement(sqlConn *sql.DB) (*Stmt, error) {
return nil, err
}
// init insertReview
stmt.insertReview, err = sqlConn.Prepare(insertReviewQuery)
if err != nil {
return nil, err
}
return stmt, err
}

View File

@@ -36,6 +36,17 @@ type Tag struct {
CreatedByUser *User `json:"created_by_user"`
}
type Review struct {
ID int64 `json:"id"`
FileId int64 `json:"file_id"`
File *File `json:"file"`
UserId int64 `json:"user_id"`
User *User `json:"user"`
CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
Content string `json:"content"`
}
var (
RoleAnonymous = int64(0)
RoleAdmin = int64(1)

View File

@@ -14,6 +14,7 @@ import Tags from "./component/Tags";
import EditTag from "./component/EditTag";
import AudioPlayer from "./component/AudioPlayer";
import UserStatus from "./component/UserStatus";
import ReviewPage from "./component/ReviewPage";
import { useState } from "react";
function App() {
@@ -90,6 +91,10 @@ function App() {
path="/files/:id/share"
element={<Share setPlayingFile={setPlayingFile} />}
/>
<Route
path="/files/:id/review"
element={<ReviewPage setPlayingFile={setPlayingFile} />}
/>
</Routes>
</main>
<footer>

View File

@@ -106,6 +106,13 @@ function FileInfo(props) {
>
Play
</button>
<button
onClick={() => {
navigate(`/files/${params.id}/review`);
}}
>
Review
</button>
<button
onClick={() => {
navigate(`/files/${params.id}/share`);

View File

@@ -0,0 +1,43 @@
import { useState } from "react";
import { useParams } from "react-router";
function ReviewPage() {
let params = useParams();
const [newReview, setNewReview] = useState("");
function submitReview() {
fetch("/api/v1/insert_review", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
content: newReview,
file_id: parseInt(params.id),
}),
})
.then((res) => res.json())
.then((data) => {
if (data.error) {
alert(data.error);
} else {
setNewReview("");
}
});
}
return (
<div className="page">
<h3>Review Page</h3>
<div>
<textarea
value={newReview}
onChange={(e) => setNewReview(e.target.value)}
/>
<button onClick={() => submitReview()}>Submit</button>
</div>
</div>
);
}
export default ReviewPage;