diff --git a/cmd/douyin_sync_debug/main.go b/cmd/douyin_sync_debug/main.go index e62290b..9375991 100644 --- a/cmd/douyin_sync_debug/main.go +++ b/cmd/douyin_sync_debug/main.go @@ -64,7 +64,7 @@ func main() { env.Active() // 初始化 env flag(依赖已有的全局 -env/ACTIVE_ENV 配置) configs.Init() - cookie := "passport_csrf_token=0b67ab6212a41bd1903f03d4f9a887f9; passport_csrf_token_default=0b67ab6212a41bd1903f03d4f9a887f9; is_staff_user=false; s_v_web_id=verify_mkf83bbo_zfQ3q1Gp_5irf_4OOI_9y4N_C253269yUIJy; SHOP_ID=156231010; PIGEON_CID=4339134776748827; __security_mc_1_s_sdk_crypt_sdk=db47f387-4d0b-bf21; bd_ticket_guard_client_web_domain=2; bd_ticket_guard_client_data=eyJiZC10aWNrZXQtZ3VhcmQtdmVyc2lvbiI6MiwiYmQtdGlja2V0LWd1YXJkLWl0ZXJhdGlvbi12ZXJzaW9uIjoxLCJiZC10aWNrZXQtZ3VhcmQtcmVlLXB1YmxpYy1rZXkiOiJCTHVTREdkVFRHWUdNMVY3ZDZKS2M4V2FwWGJ1K3JVYmVqRThONTZoeTI4SUJXdmVxZjBLMS9GczE0dWx5RTVRd2d4cjdnaDd6SXdMZjlsWDkwOFZQQWs9IiwiYmQtdGlja2V0LWd1YXJkLXdlYi12ZXJzaW9uIjoyfQ%3D%3D; bd_ticket_guard_web_domain=3; gfkadpd=4272,23756; ecom_gray_shop_id=156231010; zsgw_business_data=%7B%22uuid%22%3A%226756720f-c380-4bda-ab81-3dd27ca08a2d%22%2C%22platform%22%3A%22pc%22%2C%22source%22%3A%22seo.baidu.069%22%7D; source=seo.baidu.069; Hm_lvt_b6520b076191ab4b36812da4c90f7a5e=1771350555,1772107597,1772794481,1773223394; HMACCOUNT=9C6B7571794A6624; csrf_session_id=8173f094b830570b2b64e98900924731; passport_mfa_token=CjcMUe8O6Zz52W9O1T3zlEkIxpWSHBCB4dHw9XBdiDU%2BIPU1pzwEXLpVjGth2W2nXGHC8OM6ffSmGkoKPAAAAAAAAAAAAABQK6uUDAbmPNiLgEkCaMWLdiWMpTEiK%2Fm1NGLpqOUmR4vBZtoNbJWrAhzjfim%2BBtfMlxCj6IsOGPax0WwgAiIBA8pTDDU%3D; Hm_lpvt_b6520b076191ab4b36812da4c90f7a5e=1773224382; ttwid=1%7CNnXcElGkMBE8UTpDOFYR5OfCUYkFjQaLyn1EagPBZgM%7C1773224307%7C18bc27eb78d0a5da332f8c3ec951f81229670377d82025fcb5e600e3766e367b; tt_scid=uSkT0B7AzW.AKqYpEsRrpTqtws.7fqp2P4-gBF1FyffuNMOl1AKuRvuymbUWzXRvcc00; odin_tt=6edadb78040b4604bed517fc3edef437495387c8a3bf60fa177788ff81dd88daaed661705eb0729801e665c086b098b263c3090fef72c26e872d2f3172f6e364; passport_auth_status=581a8676e64d918c69ee3930f4dacf8b%2C4bb14205ac4179b872cba76a97208a7e; passport_auth_status_ss=581a8676e64d918c69ee3930f4dacf8b%2C4bb14205ac4179b872cba76a97208a7e; bd_ticket_guard_server_data=eyJ0aWNrZXQiOiJoYXNoLk1SWGtrczRwYTZpWG91ODhuZENOT05idm9iSjI2SHlXOXRYN2JKNTdZMWM9IiwidHNfc2lnbiI6InRzLjIuMDg1MDhmMjljNWI2MjkzMjQ4ZTAwNGY0YjdiNjMwODI4ODk1YjFkZWQ1ZTRlYmFiZTc3NmYzZTUxYWJjZjZhNGM0ZmJlODdkMjMxOWNmMDUzMTg2MjRjZWRhMTQ5MTFjYTQwNmRlZGJlYmVkZGIyZTMwZmNlOGQ0ZmEwMjU3NWQiLCJjbGllbnRfY2VydCI6InB1Yi5CTHVTREdkVFRHWUdNMVY3ZDZKS2M4V2FwWGJ1K3JVYmVqRThONTZoeTI4SUJXdmVxZjBLMS9GczE0dWx5RTVRd2d4cjdnaDd6SXdMZjlsWDkwOFZQQWs9IiwibG9nX2lkIjoiMjAyNjAzMTExODE4NDBGQUVGNkZGMDBCMkUwQTJEQTU2QSIsImNyZWF0ZV90aW1lIjoxNzczMjI0MzIwfQ%3D%3D; uid_tt=e8ca5ad2e6032b72a0fd8c0843ff5e9b; uid_tt_ss=e8ca5ad2e6032b72a0fd8c0843ff5e9b; sid_tt=c1a29f1f0f71ea4ed9fbcde60bc2b390; sessionid=c1a29f1f0f71ea4ed9fbcde60bc2b390; sessionid_ss=c1a29f1f0f71ea4ed9fbcde60bc2b390; PHPSESSID=05ca4c3439dacd9ac5f1d86a78516abb; PHPSESSID_SS=05ca4c3439dacd9ac5f1d86a78516abb; ucas_c0=CkEKBTEuMC4wELaIgqLTr9DYaRjmJiD61rDnqc2DBCiwITCb1oDYuM3aB0CCg8XNBkiCt4HQBlC_vL6Ekt3t1GdYbhIUI1wJXqAsE71YWUNwS6OvJ9dOEVE; ucas_c0_ss=CkEKBTEuMC4wELaIgqLTr9DYaRjmJiD61rDnqc2DBCiwITCb1oDYuM3aB0CCg8XNBkiCt4HQBlC_vL6Ekt3t1GdYbhIUI1wJXqAsE71YWUNwS6OvJ9dOEVE; sid_guard=c1a29f1f0f71ea4ed9fbcde60bc2b390%7C1773224328%7C5184000%7CSun%2C+10-May-2026+10%3A18%3A48+GMT; sid_ucp_v1=1.0.0-KDA3MGQyMjJkNmQ1NDUxOGQ1MWRhYTFjMzBkZTZkMDBlMTNlYWJhYWUKGwib1oDYuM3aBxCIg8XNBhiwISAMOAZA9AdIBBoCaGwiIGMxYTI5ZjFmMGY3MWVhNGVkOWZiY2RlNjBiYzJiMzkw; ssid_ucp_v1=1.0.0-KDA3MGQyMjJkNmQ1NDUxOGQ1MWRhYTFjMzBkZTZkMDBlMTNlYWJhYWUKGwib1oDYuM3aBxCIg8XNBhiwISAMOAZA9AdIBBoCaGwiIGMxYTI5ZjFmMGY3MWVhNGVkOWZiY2RlNjBiYzJiMzkw; session_tlb_tag=sttt%7C17%7CwaKfHw9x6k7Z-83mC8KzkP________-tSxexYwusSRjOrIMuB3YiA6EaLnfr1fbbR8LfwAsAu74%3D; BUYIN_SASID=SID2_7615938059562205474; COMPASS_LUOPAN_DT=session_7615939876688511241" + cookie := "Hm_lvt_b6520b076191ab4b36812da4c90f7a5e=1773139856,1773407744,1773419459,1773858730; HMACCOUNT=F3B5BBA45AAD7006; passport_csrf_token=133a0751277aa016a5851e4cfc27c30c; passport_csrf_token_default=133a0751277aa016a5851e4cfc27c30c; Hm_lpvt_b6520b076191ab4b36812da4c90f7a5e=1773858732; s_v_web_id=verify_mmwdotm1_QYpHiLoc_99vO_49un_9xFU_0ZKfqsmF8gzh; ttwid=1%7Caa-Nm2neyE97yjVd8lXbX7cMYg2IRxLWDrrcDT-XwQI%7C1773858743%7C5ed45fcc397866e9ff1018ed6645a9d60db4ca1eb3b79c0d89935b9a3f2b4d1d; odin_tt=7df0869854126bc16f7be2322dc76227670fb02f8eae669788a93a9284185a793246e9d0e0efaac74aad9f64f1b3c014d060fd70f43361f11db669b394e6a2d5; passport_auth_status=414956d87dcb35d7ee019a02e518c832%2C; passport_auth_status_ss=414956d87dcb35d7ee019a02e518c832%2C; uid_tt=834c56a1b55881ba0850017833f57d5c; uid_tt_ss=834c56a1b55881ba0850017833f57d5c; sid_tt=190fa90c5c7cfcfe3eab172abe7f618d; sessionid=190fa90c5c7cfcfe3eab172abe7f618d; sessionid_ss=190fa90c5c7cfcfe3eab172abe7f618d; is_staff_user=false; PHPSESSID=4e8994de1e2d204fd3cc252063ea5cf8; PHPSESSID_SS=4e8994de1e2d204fd3cc252063ea5cf8; ucas_c0=CkEKBTEuMC4wEKaIh8qL9bvdaRjmJiD61rDnqc2DBCiwITCb1oDYuM3aB0DH3-vNBkjHk6jQBlC_vL6Ekt3t1GdYbhIUp6EWta511kbQ8CmoiX_vryfRgD0; ucas_c0_ss=CkEKBTEuMC4wEKaIh8qL9bvdaRjmJiD61rDnqc2DBCiwITCb1oDYuM3aB0DH3-vNBkjHk6jQBlC_vL6Ekt3t1GdYbhIUp6EWta511kbQ8CmoiX_vryfRgD0; zsgw_business_data=%7B%22uuid%22%3A%22bc287121-46d2-4609-a684-b9b59ecd9f97%22%2C%22platform%22%3A%22pc%22%2C%22source%22%3A%22seo.fxg.jinritemai.com%22%7D; source=seo.fxg.jinritemai.com; gfkadpd=4272,23756; csrf_session_id=1579f92b6914e7cbfbc81471e18918fc; ecom_gray_shop_id=156231010; COMPASS_LUOPAN_DT=session_7618656142230683913; sid_guard=190fa90c5c7cfcfe3eab172abe7f618d%7C1773858765%7C5183999%7CSun%2C+17-May-2026+18%3A32%3A44+GMT; session_tlb_tag=sttt%7C15%7CGQ-pDFx8_P4-qxcqvn9hjf_________dAEcZdrUq51A-FUS1s-6d6GSdYV7SE5IXVs9qSbNY5N0%3D; sid_ucp_v1=1.0.0-KGI4NTg4ZDQ0ZTRiM2JhYWU2NDZlNDc5YmUyMmI1YzM3OWY1OTQzOTcKGQib1oDYuM3aBxDN3-vNBhiwISAMOAZA9AcaAmhsIiAxOTBmYTkwYzVjN2NmY2ZlM2VhYjE3MmFiZTdmNjE4ZA; ssid_ucp_v1=1.0.0-KGI4NTg4ZDQ0ZTRiM2JhYWU2NDZlNDc5YmUyMmI1YzM3OWY1OTQzOTcKGQib1oDYuM3aBxDN3-vNBhiwISAMOAZA9AcaAmhsIiAxOTBmYTkwYzVjN2NmY2ZlM2VhYjE3MmFiZTdmNjE4ZA; BUYIN_SASID=SID2_7618660089398984998" if cookie == "" { fmt.Println("请通过环境变量 DOUYIN_COOKIE 提供抖店 Cookie") os.Exit(1) diff --git a/internal/api/user/shipping_fee_preorder_app.go b/internal/api/user/shipping_fee_preorder_app.go new file mode 100644 index 0000000..9a11f9c --- /dev/null +++ b/internal/api/user/shipping_fee_preorder_app.go @@ -0,0 +1,85 @@ +package app + +import ( + "fmt" + "net/http" + "time" + + "bindbox-game/internal/code" + "bindbox-game/internal/pkg/core" + "bindbox-game/internal/pkg/validation" + "bindbox-game/internal/repository/mysql/model" +) + +const ( + shippingFeeThreshold = 5 // 超过此件数收运费 + shippingFeeCents = 1000 // 运费金额(分),10 元 + shippingFeeSourceType = int32(5) // orders.source_type: 5 = 运费订单 +) + +type shippingFeePreorderRequest struct { + InventoryIDs []int64 `json:"inventory_ids"` +} + +type shippingFeePreorderResponse struct { + OrderNo string `json:"order_no"` +} + +// ShippingFeePreorder 创建运费订单 +// @Summary 创建运费订单 +// @Description 选中件数超过 5 件时,创建 10 元运费订单并返回 order_no;前端再调用 /pay/wechat/jsapi/preorder 发起支付 +// @Tags APP端.用户 +// @Accept json +// @Produce json +// @Security LoginVerifyToken +// @Param user_id path integer true "用户ID" +// @Param RequestBody body shippingFeePreorderRequest true "请求参数:资产ID列表" +// @Success 200 {object} shippingFeePreorderResponse +// @Failure 400 {object} code.Failure +// @Router /api/app/users/{user_id}/inventory/shipping-fee/preorder [post] +func (h *handler) ShippingFeePreorder() core.HandlerFunc { + return func(ctx core.Context) { + req := new(shippingFeePreorderRequest) + rsp := new(shippingFeePreorderResponse) + if err := ctx.ShouldBindJSON(req); err != nil { + ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err))) + return + } + if len(req.InventoryIDs) == 0 { + ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "inventory_ids 不能为空")) + return + } + if len(req.InventoryIDs) <= shippingFeeThreshold { + ctx.AbortWithError(core.Error(http.StatusBadRequest, 150001, fmt.Sprintf("件数不超过 %d 件,无需支付运费", shippingFeeThreshold))) + return + } + + userID := int64(ctx.SessionUserInfo().Id) + + // 生成运费订单号(SF + 时间戳 + 用户ID后6位,保证唯一) + now := time.Now() + orderNo := fmt.Sprintf("SF%s%06d", now.Format("20060102150405"), userID%1000000) + + // 创建运费订单(source_type=5 区分普通商品订单,status=1 待支付) + order := &model.Orders{ + UserID: userID, + OrderNo: orderNo, + SourceType: shippingFeeSourceType, + TotalAmount: shippingFeeCents, + DiscountAmount: 0, + PointsAmount: 0, + ActualAmount: shippingFeeCents, + Status: 1, + IsConsumed: 0, + } + if err := h.writeDB.Orders.WithContext(ctx.RequestContext()). + Omit(h.writeDB.Orders.PaidAt, h.writeDB.Orders.CancelledAt). + Create(order); err != nil { + ctx.AbortWithError(core.Error(http.StatusBadRequest, 150002, "创建运费订单失败: "+err.Error())) + return + } + + rsp.OrderNo = orderNo + ctx.Payload(rsp) + } +} diff --git a/internal/router/router.go b/internal/router/router.go index ee9345f..6a774f7 100755 --- a/internal/router/router.go +++ b/internal/router/router.go @@ -533,6 +533,7 @@ func NewHTTPMux(logger logger.CustomLogger, db mysql.Repo) (core.Mux, func(), er lotteryGroup.POST("/users/:user_id/points/redeem-item-card", userHandler.RedeemPointsToItemCard()) // 资产操作(发货/回收) + lotteryGroup.POST("/users/:user_id/inventory/shipping-fee/preorder", userHandler.ShippingFeePreorder()) lotteryGroup.POST("/users/:user_id/inventory/request-shipping", userHandler.RequestShippingBatch()) lotteryGroup.POST("/users/:user_id/inventory/cancel-shipping", userHandler.CancelShipping()) lotteryGroup.POST("/users/:user_id/inventory/redeem", userHandler.RedeemInventoryToPoints())