feat(commerce): 排盘保存需显式同意,默认本地计算不上传
- 前端免费排盘默认不保存,勾选同意后才调用保存接口 - 服务端要求 consentVersion,记录 consentAt,校验并限流公开保存接口 - 付费结算单独披露报告快照与订单信息将由服务端存储 - 管理端展示同意版本与时间,历史无同意证据记录保留并标注 Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
parent
ea6828b925
commit
132fef051b
@@ -1,6 +1,7 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
@@ -9,6 +10,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gouki/lunar-server/internal/config"
|
||||
@@ -21,21 +23,37 @@ var accessCodePattern = regexp.MustCompile(`^ZM-[A-Z2-7]{4}-[A-Z2-7]{4}-[A-Z2-7]
|
||||
|
||||
func SaveChartRecord(c *gin.Context) {
|
||||
var request struct {
|
||||
ReportID string `json:"reportId" binding:"required"`
|
||||
Name string `json:"name"`
|
||||
BirthDate string `json:"birthDate" binding:"required"`
|
||||
BirthTime string `json:"birthTime" binding:"required"`
|
||||
Gender string `json:"gender" binding:"required"`
|
||||
City string `json:"city" binding:"required"`
|
||||
Snapshot json.RawMessage `json:"snapshot" binding:"required"`
|
||||
ReportID string `json:"reportId" binding:"required"`
|
||||
Name string `json:"name"`
|
||||
BirthDate string `json:"birthDate" binding:"required"`
|
||||
BirthTime string `json:"birthTime" binding:"required"`
|
||||
Gender string `json:"gender" binding:"required"`
|
||||
City string `json:"city" binding:"required"`
|
||||
ConsentVersion string `json:"consentVersion" binding:"required"`
|
||||
Snapshot json.RawMessage `json:"snapshot" binding:"required"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&request); err != nil || !reportIDPattern.MatchString(request.ReportID) || len(request.Snapshot) < 2 || len(request.Snapshot) > 512*1024 || request.Snapshot[0] != '{' {
|
||||
c.Request.Body = http.MaxBytesReader(c.Writer, c.Request.Body, 600*1024)
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"code": 400, "msg": "排盘记录参数错误"})
|
||||
return
|
||||
}
|
||||
snapshot := bytes.TrimSpace(request.Snapshot)
|
||||
var snapshotObject map[string]json.RawMessage
|
||||
birthDate, dateErr := time.Parse("2006-01-02", request.BirthDate)
|
||||
_, timeErr := time.Parse("15:04", request.BirthTime)
|
||||
if !reportIDPattern.MatchString(request.ReportID) || len(snapshot) < 2 || len(snapshot) > 512*1024 ||
|
||||
json.Unmarshal(snapshot, &snapshotObject) != nil || snapshotObject == nil ||
|
||||
dateErr != nil || birthDate.Year() < 1901 || birthDate.Year() > 2100 || timeErr != nil ||
|
||||
(request.Gender != "male" && request.Gender != "female") || request.ConsentVersion != service.ChartRecordConsentVersion ||
|
||||
utf8.RuneCountInString(request.Name) > 64 || utf8.RuneCountInString(request.City) > 64 {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"code": 400, "msg": "排盘记录参数错误或未同意保存"})
|
||||
return
|
||||
}
|
||||
consentedAt := time.Now().UTC()
|
||||
record := &model.BaziChartRecord{
|
||||
ReportID: request.ReportID, Name: request.Name, BirthDate: request.BirthDate,
|
||||
BirthTime: request.BirthTime, Gender: request.Gender, City: request.City, Snapshot: string(request.Snapshot),
|
||||
BirthTime: request.BirthTime, Gender: request.Gender, City: request.City,
|
||||
ConsentVersion: request.ConsentVersion, ConsentAt: &consentedAt, Snapshot: string(snapshot),
|
||||
}
|
||||
if userID, exists := c.Get("userID"); exists {
|
||||
if value, ok := userID.(uint); ok {
|
||||
|
||||
Reference in New Issue
Block a user