delete short url
This commit is contained in:
parent
c1f4731669
commit
ae060a2a37
@ -17,6 +17,7 @@ type Querier interface {
|
|||||||
GetUserByName(ctx context.Context, username string) (*User, error)
|
GetUserByName(ctx context.Context, username string) (*User, error)
|
||||||
ListUrlByUser(ctx context.Context, userID string) ([]*UserRelateUrl, error)
|
ListUrlByUser(ctx context.Context, userID string) ([]*UserRelateUrl, error)
|
||||||
ListUsers(ctx context.Context, arg *ListUsersParams) ([]*User, error)
|
ListUsers(ctx context.Context, arg *ListUsersParams) ([]*User, error)
|
||||||
|
UpdateStatus(ctx context.Context, arg *UpdateStatusParams) (*UserRelateUrl, error)
|
||||||
UpdateUser(ctx context.Context, arg *UpdateUserParams) (*User, error)
|
UpdateUser(ctx context.Context, arg *UpdateUserParams) (*User, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,12 @@ INSERT INTO user_relate_url (
|
|||||||
)
|
)
|
||||||
RETURNING *;
|
RETURNING *;
|
||||||
|
|
||||||
|
-- name: UpdateStatus :one
|
||||||
|
UPDATE user_relate_url
|
||||||
|
SET status = $2
|
||||||
|
WHERE short_url = $1
|
||||||
|
RETURNING *;
|
||||||
|
|
||||||
-- name: ListUrlByUser :many
|
-- name: ListUrlByUser :many
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM user_relate_url
|
FROM user_relate_url
|
||||||
|
|||||||
@ -83,3 +83,30 @@ func (q *Queries) ListUrlByUser(ctx context.Context, userID string) ([]*UserRela
|
|||||||
}
|
}
|
||||||
return items, nil
|
return items, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const updateStatus = `-- name: UpdateStatus :one
|
||||||
|
UPDATE user_relate_url
|
||||||
|
SET status = $2
|
||||||
|
WHERE short_url = $1
|
||||||
|
RETURNING id, user_id, short_url, origin_url, status, expire_at, created_at
|
||||||
|
`
|
||||||
|
|
||||||
|
type UpdateStatusParams struct {
|
||||||
|
ShortUrl string `json:"short_url"`
|
||||||
|
Status int32 `json:"status"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) UpdateStatus(ctx context.Context, arg *UpdateStatusParams) (*UserRelateUrl, error) {
|
||||||
|
row := q.db.QueryRowContext(ctx, updateStatus, arg.ShortUrl, arg.Status)
|
||||||
|
var i UserRelateUrl
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.UserID,
|
||||||
|
&i.ShortUrl,
|
||||||
|
&i.OriginUrl,
|
||||||
|
&i.Status,
|
||||||
|
&i.ExpireAt,
|
||||||
|
&i.CreatedAt,
|
||||||
|
)
|
||||||
|
return &i, err
|
||||||
|
}
|
||||||
|
|||||||
@ -15,14 +15,6 @@ func HomeView(templates fs.FS, store db.Store) http.HandlerFunc {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
renderLayout(w, r, templates, nil, "home.html.tmpl")
|
renderLayout(w, r, templates, nil, "home.html.tmpl")
|
||||||
}
|
}
|
||||||
|
|
||||||
scheme := "http://"
|
|
||||||
if r.TLS != nil {
|
|
||||||
scheme = "https://"
|
|
||||||
}
|
|
||||||
for _, item := range result {
|
|
||||||
item.ShortUrl = scheme + r.Host + "/" + item.ShortUrl
|
|
||||||
}
|
|
||||||
renderLayout(w, r, templates, result, "home.html.tmpl")
|
renderLayout(w, r, templates, result, "home.html.tmpl")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,6 +20,13 @@ func renderLayout(w http.ResponseWriter, r *http.Request, templates fs.FS, data
|
|||||||
"currentUser": func() *Authorize {
|
"currentUser": func() *Authorize {
|
||||||
return withUser(r.Context())
|
return withUser(r.Context())
|
||||||
},
|
},
|
||||||
|
"genShortUrl": func(url string) string {
|
||||||
|
scheme := "http://"
|
||||||
|
if r.TLS != nil {
|
||||||
|
scheme = "https://"
|
||||||
|
}
|
||||||
|
return scheme + r.Host + "/" + url
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
tpl := template.Must(t.Clone())
|
tpl := template.Must(t.Clone())
|
||||||
|
|||||||
35
handler/resp.go
Normal file
35
handler/resp.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type response struct {
|
||||||
|
Success bool `json:"success"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
Data any `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func respond(w http.ResponseWriter, message string, v any, statusCode int) {
|
||||||
|
rsp := response{
|
||||||
|
Success: true,
|
||||||
|
Message: message,
|
||||||
|
Data: v,
|
||||||
|
}
|
||||||
|
b, err := json.Marshal(rsp)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||||
|
w.WriteHeader(statusCode)
|
||||||
|
_, err = w.Write(b)
|
||||||
|
if err != nil && !errors.Is(err, context.Canceled) {
|
||||||
|
log.Printf("could not write http response: %v\n", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -59,6 +59,28 @@ func CreateShortUrl(templates fs.FS, store db.Store) http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func DeleteShortUrl(store db.Store) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
vars := mux.Vars(r)
|
||||||
|
shorUrl := vars["shortUrl"]
|
||||||
|
_, err := store.UpdateStatus(r.Context(), &db.UpdateStatusParams{
|
||||||
|
ShortUrl: shorUrl,
|
||||||
|
Status: -1,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
respond(w, "删除错误", nil, http.StatusOK)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = service.DeleteShortUrl(shorUrl)
|
||||||
|
if err != nil {
|
||||||
|
respond(w, "删除错误", nil, http.StatusOK)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
respond(w, "删除成功", nil, http.StatusOK)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func HandleShortUrlRedirect(w http.ResponseWriter, r *http.Request) {
|
func HandleShortUrlRedirect(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
shorUrl := vars["shortUrl"]
|
shorUrl := vars["shortUrl"]
|
||||||
|
|||||||
3
main.go
3
main.go
@ -99,13 +99,12 @@ func main() {
|
|||||||
|
|
||||||
subRouter := router.PathPrefix("/").Subrouter()
|
subRouter := router.PathPrefix("/").Subrouter()
|
||||||
subRouter.Use(handler.MyAuthorize)
|
subRouter.Use(handler.MyAuthorize)
|
||||||
|
|
||||||
subRouter.Handle("/", handler.HomeView(templates, store)).Methods(http.MethodGet)
|
subRouter.Handle("/", handler.HomeView(templates, store)).Methods(http.MethodGet)
|
||||||
|
|
||||||
subRouter.Handle("/create-short-url", hds.MethodHandler{
|
subRouter.Handle("/create-short-url", hds.MethodHandler{
|
||||||
http.MethodGet: http.Handler(handler.CreateShortUrlView(templates)),
|
http.MethodGet: http.Handler(handler.CreateShortUrlView(templates)),
|
||||||
http.MethodPost: http.Handler(handler.CreateShortUrl(templates, store)),
|
http.MethodPost: http.Handler(handler.CreateShortUrl(templates, store)),
|
||||||
})
|
})
|
||||||
|
subRouter.Handle("/delete-short-url/{shortUrl}", handler.DeleteShortUrl(store)).Methods(http.MethodPost)
|
||||||
|
|
||||||
router.HandleFunc("/{shortUrl}", handler.HandleShortUrlRedirect).Methods(http.MethodGet)
|
router.HandleFunc("/{shortUrl}", handler.HandleShortUrlRedirect).Methods(http.MethodGet)
|
||||||
|
|
||||||
|
|||||||
@ -52,3 +52,7 @@ func RetrieveInitialUrl(shortUrl string) (string, error) {
|
|||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func DeleteShortUrl(shortUrl string) error {
|
||||||
|
return storeService.redisClient.Set(ctx, shortUrl, "", time.Second).Err()
|
||||||
|
}
|
||||||
|
|||||||
@ -13,7 +13,7 @@
|
|||||||
{{range .}}
|
{{range .}}
|
||||||
<tr>
|
<tr>
|
||||||
<td width="600px">{{.OriginUrl}}</td>
|
<td width="600px">{{.OriginUrl}}</td>
|
||||||
<td width="320px"><a target="_blank" href="{{.ShortUrl}}">{{.ShortUrl}}</a></td>
|
<td width="320px"><a target="_blank" href="{{genShortUrl .ShortUrl}}">{{genShortUrl .ShortUrl}}</a></td>
|
||||||
<td width="80px">
|
<td width="80px">
|
||||||
{{if eq .Status 0}}
|
{{if eq .Status 0}}
|
||||||
<code>YES</code>
|
<code>YES</code>
|
||||||
@ -21,10 +21,15 @@
|
|||||||
<code>NO</code>
|
<code>NO</code>
|
||||||
{{end}}
|
{{end}}
|
||||||
</td>
|
</td>
|
||||||
<td width="80px">delete</td>
|
<td width="80px">
|
||||||
|
{{if eq .Status 0}}
|
||||||
|
<button data-short-url="{{.ShortUrl}}" class="btn btn-danger deleteShortUrl">删除</button>
|
||||||
|
{{end}}
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{{end}}
|
{{end}}
|
||||||
</table>
|
</table>
|
||||||
|
{{ csrfField }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -51,6 +56,28 @@
|
|||||||
{{end}}
|
{{end}}
|
||||||
{{define "js"}}
|
{{define "js"}}
|
||||||
<script>
|
<script>
|
||||||
|
$('.deleteShortUrl').click(function () {
|
||||||
|
let csrfToken = $('input[name="csrf_token"]').val()
|
||||||
|
let u = $(this).attr('data-short-url')
|
||||||
|
$.ajax({
|
||||||
|
url: '/delete-short-url/' + u,
|
||||||
|
type: 'POST',
|
||||||
|
cache: false,
|
||||||
|
processData: false,
|
||||||
|
contentType: false,
|
||||||
|
headers: {
|
||||||
|
"X-CSRF-Token": csrfToken
|
||||||
|
},
|
||||||
|
success: function (res) {
|
||||||
|
if (res.success) {
|
||||||
|
alert('删除成功');
|
||||||
|
window.location.reload();
|
||||||
|
} else {
|
||||||
|
alert('删除失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{template "footer" .}}
|
{{template "footer" .}}
|
||||||
Loading…
x
Reference in New Issue
Block a user