feat: add uuid
This commit is contained in:
+30
-16
@@ -5,6 +5,7 @@ package admin
|
||||
import (
|
||||
"archive/zip"
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"database/sql"
|
||||
"embed"
|
||||
"fmt"
|
||||
@@ -15,6 +16,7 @@ import (
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-chi/chi/v5/middleware"
|
||||
@@ -99,16 +101,16 @@ func (h *Handler) shop(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
data := map[string]any{
|
||||
"Nav": "shop",
|
||||
"Coins": h.rows(ctx, `SELECT id,title,coins,vip_days,price_toman,bonus_pct,sort,enabled FROM coin_packages ORDER BY sort`,
|
||||
"id", "title", "coins", "vip_days", "price_toman", "bonus_pct", "sort", "enabled"),
|
||||
"Tickets": h.rows(ctx, `SELECT id,title,tickets,price_toman,sort,enabled FROM ticket_packages ORDER BY sort`,
|
||||
"id", "title", "tickets", "price_toman", "sort", "enabled"),
|
||||
"Coins": h.rows(ctx, `SELECT id,title,coins,vip_days,price_toman,bonus_pct,sku,sort,enabled FROM coin_packages ORDER BY sort`,
|
||||
"id", "title", "coins", "vip_days", "price_toman", "bonus_pct", "sku", "sort", "enabled"),
|
||||
"Tickets": h.rows(ctx, `SELECT id,title,tickets,price_toman,sku,sort,enabled FROM ticket_packages ORDER BY sort`,
|
||||
"id", "title", "tickets", "price_toman", "sku", "sort", "enabled"),
|
||||
"Cards": h.rows(ctx, `SELECT id,title,price_coins,sort,enabled FROM card_skins ORDER BY sort`,
|
||||
"id", "title", "price_coins", "sort", "enabled"),
|
||||
"Boosters": h.rows(ctx, `SELECT id,title,multiplier,hours,price_toman,sort,enabled FROM boosters ORDER BY sort`,
|
||||
"id", "title", "multiplier", "hours", "price_toman", "sort", "enabled"),
|
||||
"VIP": h.rows(ctx, `SELECT id,title,months,price_toman,sort,enabled FROM vip_packages ORDER BY sort`,
|
||||
"id", "title", "months", "price_toman", "sort", "enabled"),
|
||||
"Boosters": h.rows(ctx, `SELECT id,title,multiplier,hours,price_toman,sku,sort,enabled FROM boosters ORDER BY sort`,
|
||||
"id", "title", "multiplier", "hours", "price_toman", "sku", "sort", "enabled"),
|
||||
"VIP": h.rows(ctx, `SELECT id,title,months,price_toman,sku,sort,enabled FROM vip_packages ORDER BY sort`,
|
||||
"id", "title", "months", "price_toman", "sku", "sort", "enabled"),
|
||||
"Tiers": h.rows(ctx, `SELECT id,title,hands,entry,prize,xp,trophy,rank_reward,sort,enabled FROM table_tiers ORDER BY sort`,
|
||||
"id", "title", "hands", "entry", "prize", "xp", "trophy", "rank_reward", "sort", "enabled"),
|
||||
"Saved": r.URL.Query().Get("saved") == "1",
|
||||
@@ -181,25 +183,26 @@ func (h *Handler) addItem(w http.ResponseWriter, r *http.Request) {
|
||||
if r.FormValue("enabled") == "on" {
|
||||
en = 1
|
||||
}
|
||||
sku := newUUID() // شناسهی محصولِ فروشگاه (uuid) خودکار تولید میشود
|
||||
|
||||
var q string
|
||||
var args []any
|
||||
switch kind {
|
||||
case "coin":
|
||||
q = `INSERT INTO coin_packages (id,title,coins,vip_days,price_toman,bonus_pct,sort,enabled) VALUES (?,?,?,?,?,?,?,?)`
|
||||
args = []any{id, r.FormValue("title"), f("coins"), f("vip_days"), f("price_toman"), f("bonus_pct"), f("sort"), en}
|
||||
q = `INSERT INTO coin_packages (id,title,coins,vip_days,price_toman,bonus_pct,sku,sort,enabled) VALUES (?,?,?,?,?,?,?,?,?)`
|
||||
args = []any{id, r.FormValue("title"), f("coins"), f("vip_days"), f("price_toman"), f("bonus_pct"), sku, f("sort"), en}
|
||||
case "ticket":
|
||||
q = `INSERT INTO ticket_packages (id,title,tickets,price_toman,sort,enabled) VALUES (?,?,?,?,?,?)`
|
||||
args = []any{id, r.FormValue("title"), f("tickets"), f("price_toman"), f("sort"), en}
|
||||
q = `INSERT INTO ticket_packages (id,title,tickets,price_toman,sku,sort,enabled) VALUES (?,?,?,?,?,?,?)`
|
||||
args = []any{id, r.FormValue("title"), f("tickets"), f("price_toman"), sku, f("sort"), en}
|
||||
case "card":
|
||||
q = `INSERT INTO card_skins (id,title,price_coins,sort,enabled) VALUES (?,?,?,?,?)`
|
||||
args = []any{id, r.FormValue("title"), f("price_coins"), f("sort"), en}
|
||||
case "booster":
|
||||
q = `INSERT INTO boosters (id,title,multiplier,hours,price_toman,sort,enabled) VALUES (?,?,?,?,?,?)`
|
||||
args = []any{id, r.FormValue("title"), f("multiplier"), f("hours"), f("price_toman"), f("sort"), en}
|
||||
q = `INSERT INTO boosters (id,title,multiplier,hours,price_toman,sku,sort,enabled) VALUES (?,?,?,?,?,?,?)`
|
||||
args = []any{id, r.FormValue("title"), f("multiplier"), f("hours"), f("price_toman"), sku, f("sort"), en}
|
||||
case "vip":
|
||||
q = `INSERT INTO vip_packages (id,title,months,price_toman,sort,enabled) VALUES (?,?,?,?,?,?)`
|
||||
args = []any{id, r.FormValue("title"), f("months"), f("price_toman"), f("sort"), en}
|
||||
q = `INSERT INTO vip_packages (id,title,months,price_toman,sku,sort,enabled) VALUES (?,?,?,?,?,?,?)`
|
||||
args = []any{id, r.FormValue("title"), f("months"), f("price_toman"), sku, f("sort"), en}
|
||||
case "tier":
|
||||
q = `INSERT INTO table_tiers (id,title,hands,entry,prize,xp,trophy,rank_reward,sort,enabled) VALUES (?,?,?,?,?,?,?,?,?,?)`
|
||||
args = []any{id, r.FormValue("title"), f("hands"), f("entry"), f("prize"), f("xp"), f("trophy"), f("rank_reward"), f("sort"), en}
|
||||
@@ -643,6 +646,17 @@ func (h *Handler) chatMessageDelete(w http.ResponseWriter, r *http.Request) {
|
||||
http.Redirect(w, r, "/admin/chat?saved=1", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
// newUUID یک UUIDv4 برای شناسهی محصولِ فروشگاه (SKU) تولید میکند.
|
||||
func newUUID() string {
|
||||
var b [16]byte
|
||||
if _, err := rand.Read(b[:]); err != nil {
|
||||
return fmt.Sprintf("sku-%d", time.Now().UnixNano())
|
||||
}
|
||||
b[6] = (b[6] & 0x0f) | 0x40 // نسخه ۴
|
||||
b[8] = (b[8] & 0x3f) | 0x80 // variant
|
||||
return fmt.Sprintf("%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:16])
|
||||
}
|
||||
|
||||
func (h *Handler) rows(ctx context.Context, query string, cols ...string) []map[string]any {
|
||||
rs, err := h.db.QueryContext(ctx, query)
|
||||
if err != nil {
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
<h2>بستههای سکه</h2>
|
||||
<table>
|
||||
<tr><th>شناسه</th><th>عنوان</th><th>سکه</th><th>VIP (روز)</th><th>قیمت (تومان)</th><th>بونوس٪</th><th>ترتیب</th><th>فعال</th><th colspan="2"></th></tr>
|
||||
<tr><th>شناسه</th><th>عنوان</th><th>سکه</th><th>VIP (روز)</th><th>قیمت (تومان)</th><th>بونوس٪</th><th>SKU (مایکت/کافه)</th><th>ترتیب</th><th>فعال</th><th colspan="2"></th></tr>
|
||||
{{range .Coins}}
|
||||
<tr><form method="post" action="/admin/shop/coin">
|
||||
<td>{{.id}}<input type="hidden" name="id" value="{{.id}}"></td>
|
||||
@@ -19,6 +19,7 @@
|
||||
<td><input name="vip_days" value="{{.vip_days}}"></td>
|
||||
<td><input name="price_toman" value="{{.price_toman}}"></td>
|
||||
<td><input name="bonus_pct" value="{{.bonus_pct}}"></td>
|
||||
<td><code style="font-size:11px">{{.sku}}</code></td>
|
||||
<td><input name="sort" value="{{.sort}}"></td>
|
||||
<td><input type="checkbox" name="enabled" {{if .enabled}}checked{{end}}></td>
|
||||
<td><button>ذخیره</button></td>
|
||||
@@ -32,6 +33,7 @@
|
||||
<td><input name="vip_days" value="0"></td>
|
||||
<td><input name="price_toman" value="0"></td>
|
||||
<td><input name="bonus_pct" value="0"></td>
|
||||
<td style="color:#9aa;font-size:11px">خودکار</td>
|
||||
<td><input name="sort" value="0"></td>
|
||||
<td><input type="checkbox" name="enabled" checked></td>
|
||||
<td colspan="2"><button>افزودن</button></td>
|
||||
@@ -40,13 +42,14 @@
|
||||
|
||||
<h2>بستههای بلیط</h2>
|
||||
<table>
|
||||
<tr><th>شناسه</th><th>عنوان</th><th>بلیط</th><th>قیمت (تومان)</th><th>ترتیب</th><th>فعال</th><th colspan="2"></th></tr>
|
||||
<tr><th>شناسه</th><th>عنوان</th><th>بلیط</th><th>قیمت (تومان)</th><th>SKU (مایکت/کافه)</th><th>ترتیب</th><th>فعال</th><th colspan="2"></th></tr>
|
||||
{{range .Tickets}}
|
||||
<tr><form method="post" action="/admin/shop/ticket">
|
||||
<td>{{.id}}<input type="hidden" name="id" value="{{.id}}"></td>
|
||||
<td><input type="text" name="title" value="{{.title}}"></td>
|
||||
<td><input name="tickets" value="{{.tickets}}"></td>
|
||||
<td><input name="price_toman" value="{{.price_toman}}"></td>
|
||||
<td><code style="font-size:11px">{{.sku}}</code></td>
|
||||
<td><input name="sort" value="{{.sort}}"></td>
|
||||
<td><input type="checkbox" name="enabled" {{if .enabled}}checked{{end}}></td>
|
||||
<td><button>ذخیره</button></td>
|
||||
@@ -58,6 +61,7 @@
|
||||
<td><input name="title" placeholder="عنوان"></td>
|
||||
<td><input name="tickets" value="0"></td>
|
||||
<td><input name="price_toman" value="0"></td>
|
||||
<td style="color:#9aa;font-size:11px">خودکار</td>
|
||||
<td><input name="sort" value="0"></td>
|
||||
<td><input type="checkbox" name="enabled" checked></td>
|
||||
<td colspan="2"><button>افزودن</button></td>
|
||||
@@ -98,7 +102,7 @@
|
||||
|
||||
<h2>بوسترها</h2>
|
||||
<table>
|
||||
<tr><th>شناسه</th><th>عنوان</th><th>ضریب</th><th>ساعت</th><th>قیمت (تومان)</th><th>ترتیب</th><th>فعال</th><th colspan="2"></th></tr>
|
||||
<tr><th>شناسه</th><th>عنوان</th><th>ضریب</th><th>ساعت</th><th>قیمت (تومان)</th><th>SKU (مایکت/کافه)</th><th>ترتیب</th><th>فعال</th><th colspan="2"></th></tr>
|
||||
{{range .Boosters}}
|
||||
<tr><form method="post" action="/admin/shop/booster">
|
||||
<td>{{.id}}<input type="hidden" name="id" value="{{.id}}"></td>
|
||||
@@ -106,6 +110,7 @@
|
||||
<td><input name="multiplier" value="{{.multiplier}}"></td>
|
||||
<td><input name="hours" value="{{.hours}}"></td>
|
||||
<td><input name="price_toman" value="{{.price_toman}}"></td>
|
||||
<td><code style="font-size:11px">{{.sku}}</code></td>
|
||||
<td><input name="sort" value="{{.sort}}"></td>
|
||||
<td><input type="checkbox" name="enabled" {{if .enabled}}checked{{end}}></td>
|
||||
<td><button>ذخیره</button></td>
|
||||
@@ -118,6 +123,7 @@
|
||||
<td><input name="multiplier" value="2"></td>
|
||||
<td><input name="hours" value="24"></td>
|
||||
<td><input name="price_toman" value="0"></td>
|
||||
<td style="color:#9aa;font-size:11px">خودکار</td>
|
||||
<td><input name="sort" value="0"></td>
|
||||
<td><input type="checkbox" name="enabled" checked></td>
|
||||
<td colspan="2"><button>افزودن</button></td>
|
||||
@@ -126,13 +132,14 @@
|
||||
|
||||
<h2>اشتراکهای VIP</h2>
|
||||
<table>
|
||||
<tr><th>شناسه</th><th>عنوان</th><th>ماه</th><th>قیمت (تومان)</th><th>ترتیب</th><th>فعال</th><th colspan="2"></th></tr>
|
||||
<tr><th>شناسه</th><th>عنوان</th><th>ماه</th><th>قیمت (تومان)</th><th>SKU (مایکت/کافه)</th><th>ترتیب</th><th>فعال</th><th colspan="2"></th></tr>
|
||||
{{range .VIP}}
|
||||
<tr><form method="post" action="/admin/shop/vip">
|
||||
<td>{{.id}}<input type="hidden" name="id" value="{{.id}}"></td>
|
||||
<td><input type="text" name="title" value="{{.title}}"></td>
|
||||
<td><input name="months" value="{{.months}}"></td>
|
||||
<td><input name="price_toman" value="{{.price_toman}}"></td>
|
||||
<td><code style="font-size:11px">{{.sku}}</code></td>
|
||||
<td><input name="sort" value="{{.sort}}"></td>
|
||||
<td><input type="checkbox" name="enabled" {{if .enabled}}checked{{end}}></td>
|
||||
<td><button>ذخیره</button></td>
|
||||
@@ -144,6 +151,7 @@
|
||||
<td><input name="title" placeholder="عنوان"></td>
|
||||
<td><input name="months" value="1"></td>
|
||||
<td><input name="price_toman" value="0"></td>
|
||||
<td style="color:#9aa;font-size:11px">خودکار</td>
|
||||
<td><input name="sort" value="0"></td>
|
||||
<td><input type="checkbox" name="enabled" checked></td>
|
||||
<td colspan="2"><button>افزودن</button></td>
|
||||
|
||||
Reference in New Issue
Block a user