Files
jiu/backend/internal/handler/public.go
T
wangjia 30a8e791a3 feat: 扫码商品详情页重设计 + 宣传主页 + nginx 路由完善
- public_product_screen: 1:1 复刻设计稿,新增商品介绍、批次防伪(自定义圆形印章)、完整商品参数表、门店营业时间、页脚链接
- app_theme: 完整品牌色系(brand/gray/accent/semantic)
- shop model: 新增 business_hours 字段,public 接口同步返回
- nginx: 新增 /product/ → Flutter app 扫码入口,修复 /docs /download html 后缀兼容
- web/: 新增宣传主页、功能页、文档页、扫码 HTML 及设计资源
- app_shell: 界面优化

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 18:58:04 +08:00

103 lines
2.4 KiB
Go

package handler
import (
"net/http"
"os"
"time"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
"github.com/wangjia/jiu/backend/internal/model"
)
type PublicHandler struct {
db *gorm.DB
}
func NewPublicHandler(db *gorm.DB) *PublicHandler {
return &PublicHandler{db: db}
}
// GetProduct GET /api/v1/public/products/:public_id (no auth)
func (h *PublicHandler) GetProduct(c *gin.Context) {
publicID := c.Param("public_id")
var product model.Product
if err := h.db.Where("public_id = ? AND deleted_at IS NULL", publicID).
Preload("Images").
First(&product).Error; err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "not found"})
return
}
// Fetch shop public info
var shop model.Shop
shopData := gin.H{}
if err := h.db.Where("id = ?", product.ShopID).First(&shop).Error; err == nil {
shopData = gin.H{
"name": shop.Name,
"code": shop.Code,
"address": shop.Address,
"phone": shop.Phone,
"business_hours": shop.BusinessHours,
}
}
// Fetch latest inventory batch for this product
var inv model.Inventory
batchData := gin.H(nil)
if err := h.db.Where("product_id = ? AND quantity > 0 AND deleted_at IS NULL", product.ID).
Order("created_at DESC").
First(&inv).Error; err == nil {
var pdStr *string
if inv.ProductionDate != nil {
s := inv.ProductionDate.Time.Format("2006-01-02")
pdStr = &s
}
batchData = gin.H{
"production_date": pdStr,
"batch_no": inv.BatchNo,
"in_stock_date": inv.CreatedAt.Format("2006-01-02"),
}
}
c.JSON(http.StatusOK, gin.H{
"data": gin.H{
"id": product.ID,
"name": product.Name,
"series": product.Series,
"spec": product.Spec,
"brand": product.Brand,
"unit": product.Unit,
"description": product.Description,
"images": product.Images,
"shop": shopData,
"batch": batchData,
},
})
}
// GetRelease GET /api/v1/public/release (no auth)
func (h *PublicHandler) GetRelease(c *gin.Context) {
version := os.Getenv("APP_VERSION")
if version == "" {
version = "1.0.0"
}
buildDate := os.Getenv("BUILD_DATE")
if buildDate == "" {
buildDate = time.Now().Format("2006-01-02")
}
c.JSON(http.StatusOK, gin.H{
"version": version,
"build_date": buildDate,
"download_urls": gin.H{
"macos": os.Getenv("DOWNLOAD_URL_MACOS"),
"windows": os.Getenv("DOWNLOAD_URL_WINDOWS"),
"web": "https://jiu.51yanmei.com/app",
},
"changelog": []gin.H{},
})
}