add feedback
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
@@ -11,6 +12,7 @@ import (
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type API struct {
|
||||
@@ -471,6 +473,42 @@ func (api *API) HandleAddFfmpegConfig(w http.ResponseWriter, r *http.Request) {
|
||||
api.HandleOK(w, r)
|
||||
}
|
||||
|
||||
type FeedbackRequest struct {
|
||||
Feedback string `json:"feedback"`
|
||||
}
|
||||
|
||||
func (api *API) HandleFeedback(w http.ResponseWriter, r *http.Request) {
|
||||
feedbackRequest := &FeedbackRequest{}
|
||||
err :=json.NewDecoder(r.Body).Decode(feedbackRequest)
|
||||
if err != nil {
|
||||
api.HandleError(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
// check empty feedback
|
||||
if feedbackRequest.Feedback == "" {
|
||||
api.HandleErrorString(w, r, `"feedback" can't be empty`)
|
||||
return
|
||||
}
|
||||
|
||||
log.Println("[api] Feedback", feedbackRequest.Feedback)
|
||||
|
||||
headerBuff := &bytes.Buffer{}
|
||||
err = r.Header.Write(headerBuff)
|
||||
if err != nil {
|
||||
api.HandleError(w, r, err)
|
||||
return
|
||||
}
|
||||
header := headerBuff.String()
|
||||
|
||||
err = api.Db.InsertFeedback(time.Now().Unix(), feedbackRequest.Feedback, header)
|
||||
if err != nil {
|
||||
api.HandleError(w, r, err)
|
||||
return
|
||||
}
|
||||
api.HandleOK(w, r)
|
||||
}
|
||||
|
||||
func NewAPIConfig() (APIConfig) {
|
||||
apiConfig := APIConfig{
|
||||
FfmpegConfigs: make(map[string]*FfmpegConfig),
|
||||
@@ -515,6 +553,7 @@ func NewAPI(apiConfig APIConfig) (*API, error) {
|
||||
apiMux.HandleFunc("/get_random_files", api.HandleGetRandomFiles)
|
||||
apiMux.HandleFunc("/get_file_stream", api.HandleGetFileStream)
|
||||
apiMux.HandleFunc("/get_ffmpeg_config_list", api.HandleGetFfmpegConfigs)
|
||||
apiMux.HandleFunc("/feedback", api.HandleFeedback)
|
||||
// below needs token
|
||||
apiMux.HandleFunc("/walk", api.HandleWalk)
|
||||
apiMux.HandleFunc("/reset", api.HandleReset)
|
||||
|
||||
@@ -21,6 +21,12 @@ var initFoldersTableQuery = `CREATE TABLE IF NOT EXISTS folders (
|
||||
folder TEXT NOT NULL,
|
||||
foldername TEXT NOT NULL
|
||||
);`
|
||||
var initFeedbacksTableQuery = `CREATE TABLE IF NOT EXISTS feedbacks (
|
||||
id INTEGER PRIMARY KEY,
|
||||
time INTEGER NOT NULL,
|
||||
feedback TEXT NOT NULL,
|
||||
header TEXT NOT NULL
|
||||
);`
|
||||
var insertFolderQuery = `INSERT INTO folders (folder, foldername) VALUES (?, ?);`
|
||||
var findFolderQuery = `SELECT id FROM folders WHERE folder = ? LIMIT 1;`
|
||||
var insertFileQuery = `INSERT INTO files (folder_id, filename, filesize) VALUES (?, ?, ?);`
|
||||
@@ -32,6 +38,7 @@ var getFileQuery = `SELECT files.id, files.folder_id, files.filename, folders.fo
|
||||
var searchFoldersQuery = `SELECT id, folder, foldername FROM folders WHERE foldername LIKE ? LIMIT ? OFFSET ?;`
|
||||
var getFilesInFolderQuery = `SELECT id, filename, filesize FROM files WHERE folder_id = ? LIMIT ? OFFSET ?;`
|
||||
var getRandomFilesQuery = `SELECT files.id, files.folder_id, files.filename, folders.foldername, files.filesize FROM files JOIN folders on files.folder_id = folders.id ORDER BY RANDOM() LIMIT ?;`
|
||||
var insertFeedbackQuery = `INSERT INTO feedbacks (time, feedback, header) VALUES (?, ?, ?);`
|
||||
|
||||
type Database struct {
|
||||
sqlConn *sql.DB
|
||||
@@ -41,6 +48,7 @@ type Database struct {
|
||||
type Stmt struct {
|
||||
initFilesTable *sql.Stmt
|
||||
initFoldersTable *sql.Stmt
|
||||
initFeedbacksTable *sql.Stmt
|
||||
insertFolder *sql.Stmt
|
||||
insertFile *sql.Stmt
|
||||
findFolder *sql.Stmt
|
||||
@@ -52,6 +60,7 @@ type Stmt struct {
|
||||
searchFolders *sql.Stmt
|
||||
getFilesInFolder *sql.Stmt
|
||||
getRandomFiles *sql.Stmt
|
||||
insertFeedback *sql.Stmt
|
||||
}
|
||||
|
||||
type File struct {
|
||||
@@ -70,6 +79,14 @@ type Folder struct {
|
||||
Foldername string `json:"foldername"`
|
||||
}
|
||||
|
||||
func (database *Database) InsertFeedback(time int64, feedback string, header string) (error) {
|
||||
_, err := database.stmt.insertFeedback.Exec(time, feedback, header)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (database *Database) GetRandomFiles(limit int64) ([]File, error) {
|
||||
rows, err := database.stmt.getRandomFiles.Query(limit)
|
||||
if err != nil {
|
||||
@@ -304,6 +321,12 @@ func NewPreparedStatement(sqlConn *sql.DB) (*Stmt, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// init feedbacks tables
|
||||
stmt.initFeedbacksTable, err = sqlConn.Prepare(initFeedbacksTableQuery)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// run init statement
|
||||
_, err = stmt.initFilesTable.Exec()
|
||||
if err != nil {
|
||||
@@ -313,6 +336,10 @@ func NewPreparedStatement(sqlConn *sql.DB) (*Stmt, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, err = stmt.initFeedbacksTable.Exec()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// init insert folder statement
|
||||
stmt.insertFolder, err = sqlConn.Prepare(insertFolderQuery)
|
||||
@@ -380,6 +407,12 @@ func NewPreparedStatement(sqlConn *sql.DB) (*Stmt, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// init insertFeedback
|
||||
stmt.insertFeedback, err = sqlConn.Prepare(insertFeedbackQuery)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return stmt, err
|
||||
}
|
||||
|
||||
|
||||
27
web/index.js
27
web/index.js
@@ -149,6 +149,12 @@ const component_manage= {
|
||||
emits: ['set_token'],
|
||||
data() {
|
||||
return {
|
||||
feedback: "",
|
||||
feedback_status: "Submit",
|
||||
feedback_placeholder: "feedback...",
|
||||
submit_disabled: false,
|
||||
is_err: false,
|
||||
err_msg: "",
|
||||
}
|
||||
},
|
||||
template: `
|
||||
@@ -156,10 +162,31 @@ const component_manage= {
|
||||
<h4>关于本站</h4>
|
||||
<p>本站是 MSW Project 的一个应用,希望以个人之力分享被隐藏在历史中的音乐。</p>
|
||||
<p>自己是V家厨,喜欢的p主包括 wonder-k, buzzG, *luna 等,但却因为种种原因淹没在主流音乐APP的曲库中。本站的初衷是为了让那些知名度低的 VOCALOID / ACG / 东方曲,能够被更多有缘人听到,同时有一个跨平台的工具,能够在低网速的条件下享受硬盘中的无损音乐。</p>
|
||||
<p>站内音乐来自公开网络,仅供个人使用,如有侵权请联系提交反馈</p>
|
||||
<input type="text" v-model="feedback" :disabled="submit_disabled" :placeholder="feedback_placeholder"/>
|
||||
<button @click="submit_feedback" :disabled="submit_disabled">{{ feedback_status }}</button>
|
||||
<label v-if="is_err">{{ err_msg }}</label>
|
||||
<component-token :token="token" @set_token="$emit('set_token', $event)"></component-token>
|
||||
<component-manage-database :token="token"></component-manage-database>
|
||||
</div>
|
||||
`,
|
||||
methods: {
|
||||
submit_feedback() {
|
||||
axios.post('/api/v1/feedback', {
|
||||
feedback: this.feedback,
|
||||
}).then((response) => {
|
||||
this.submit_disabled = true
|
||||
this.feedback = ""
|
||||
this.feedback_status = "Success"
|
||||
this.feedback_placeholder = "Thanks for your feedback!"
|
||||
this.is_err = false
|
||||
}).catch((err) => {
|
||||
console.log(err)
|
||||
this.is_err = true
|
||||
this.err_msg = err.response.data.status
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
const component_manage_database = {
|
||||
props: ['token'],
|
||||
|
||||
Reference in New Issue
Block a user