活动批次查询确认
This commit is contained in:
parent
95dbc27dcc
commit
8ec8f2a980
|
|
@ -124,8 +124,10 @@ message CmbQueryProductReply {
|
|||
string detail = 18 [json_name = "detail"];
|
||||
|
||||
// 批次开始日期 格式yyyy-mm-dd hh:mm:ss.sss
|
||||
// 批次激活时间
|
||||
string saleStartTime = 19 [json_name = "saleStartTime"];
|
||||
// 批次结束时间,格式yyyy-mm-dd hh:mm:ss.sss
|
||||
// 批次激活时间
|
||||
string saleEndTime = 20 [json_name = "saleEndTime"];
|
||||
|
||||
// 错误码
|
||||
|
|
|
|||
|
|
@ -7,13 +7,15 @@ import (
|
|||
|
||||
// ProductBo 领域实体Bo结构,字段和模型字段保持一致
|
||||
type ProductBo struct {
|
||||
ID int32
|
||||
Name string
|
||||
ProductNo string
|
||||
BatchName string
|
||||
BatchNo string
|
||||
MchId string
|
||||
Channel vo.Channel
|
||||
CreateTime *time.Time
|
||||
UpdateTime *time.Time
|
||||
ID int32
|
||||
Name string
|
||||
ProductNo string
|
||||
BatchName string
|
||||
BatchNo string
|
||||
MchId string
|
||||
Channel vo.Channel
|
||||
AvailableType vo.AvailableType
|
||||
AvailableDays uint32
|
||||
CreateTime *time.Time
|
||||
UpdateTime *time.Time
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,22 +112,6 @@ func (v *VoucherBiz) CmbProductQuery(ctx context.Context, productNo string) (rep
|
|||
return err
|
||||
}
|
||||
|
||||
inputFormat := time.RFC3339
|
||||
|
||||
beginTime := ""
|
||||
if wechatResp.AvailableBeginTime != nil {
|
||||
// 解析开始时间
|
||||
availableBeginTime, _ := time.Parse(inputFormat, *wechatResp.AvailableBeginTime)
|
||||
beginTime = availableBeginTime.Format(time.DateTime)
|
||||
}
|
||||
|
||||
endTime := ""
|
||||
if wechatResp.AvailableEndTime != nil {
|
||||
// 解析结束时间
|
||||
availableEndTime, _ := time.Parse(inputFormat, *wechatResp.AvailableEndTime)
|
||||
endTime = availableEndTime.Format(time.DateTime)
|
||||
}
|
||||
|
||||
reps = &v1.CmbQueryProductReply{
|
||||
RespCode: vo.CmbResponseStatusSuccess.GetValue(),
|
||||
RespMsg: "成功",
|
||||
|
|
@ -137,28 +121,49 @@ func (v *VoucherBiz) CmbProductQuery(ctx context.Context, productNo string) (rep
|
|||
MinAmount: "",
|
||||
AvailableType: "",
|
||||
AvailableDays: "", // 动态有效期天数
|
||||
StartTime: beginTime,
|
||||
EndTime: endTime,
|
||||
StartTime: "",
|
||||
EndTime: "",
|
||||
AvailableStock: "",
|
||||
Detail: *wechatResp.Description,
|
||||
}
|
||||
|
||||
inputFormat := time.RFC3339
|
||||
|
||||
if wechatResp.AvailableBeginTime != nil {
|
||||
// 解析开始时间
|
||||
availableBeginTime, _ := time.Parse(inputFormat, *wechatResp.AvailableBeginTime)
|
||||
reps.StartTime = availableBeginTime.Format(time.DateTime)
|
||||
}
|
||||
|
||||
if wechatResp.AvailableEndTime != nil {
|
||||
// 解析结束时间
|
||||
availableEndTime, _ := time.Parse(inputFormat, *wechatResp.AvailableEndTime)
|
||||
reps.EndTime = availableEndTime.Format(time.DateTime)
|
||||
}
|
||||
|
||||
if wechatResp.StartTime != nil {
|
||||
s, _ := time.Parse(inputFormat, *wechatResp.StartTime)
|
||||
reps.SaleStartTime = s.Format(time.DateTime)
|
||||
}
|
||||
|
||||
if wechatResp.StopTime != nil {
|
||||
e, _ := time.Parse(inputFormat, *wechatResp.StopTime)
|
||||
reps.SaleEndTime = e.Format(time.DateTime)
|
||||
}
|
||||
|
||||
reps.Amount = fmt.Sprintf("%d", *wechatResp.StockUseRule.FixedNormalCoupon.CouponAmount)
|
||||
reps.MinAmount = fmt.Sprintf("%d", *wechatResp.StockUseRule.FixedNormalCoupon.TransactionMinimum)
|
||||
|
||||
availableStock := *wechatResp.StockUseRule.MaxCoupons - *wechatResp.DistributedCoupons
|
||||
reps.AvailableStock = fmt.Sprintf("%d", availableStock)
|
||||
|
||||
if wechatResp.StartTime != nil {
|
||||
s, _ := time.Parse(inputFormat, *wechatResp.StartTime)
|
||||
reps.SaleStartTime = s.Format(time.DateTime)
|
||||
}
|
||||
if wechatResp.StopTime != nil {
|
||||
e, _ := time.Parse(inputFormat, *wechatResp.StopTime)
|
||||
reps.SaleEndTime = e.Format(time.DateTime)
|
||||
availableType, err := product.AvailableType.GetCmbAvailableType()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
reps.AvailableType = vo.CmbAvailableTypeFixed.GetValue()
|
||||
reps.AvailableType = availableType.GetValue()
|
||||
reps.AvailableDays = fmt.Sprintf("%d", product.AvailableDays)
|
||||
|
||||
return nil
|
||||
})
|
||||
|
|
|
|||
|
|
@ -2,11 +2,10 @@ package biz
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/go-kratos/kratos/v2/log"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"gorm.io/gorm"
|
||||
err2 "voucher/api/err"
|
||||
"voucher/internal/biz/bo"
|
||||
"voucher/internal/biz/vo"
|
||||
"voucher/internal/pkg/lock"
|
||||
|
|
@ -34,8 +33,8 @@ func (v *VoucherBiz) order(ctx context.Context, req *bo.OrderCreateReqBo, produc
|
|||
// 真实发放
|
||||
voucherNo, err = v.WechatCpnRepo.Order(ctx, order)
|
||||
if err != nil {
|
||||
if err2 := v.fail(ctx, order, err.Error()); err2 != nil {
|
||||
return nil, err2
|
||||
if err3 := v.fail(ctx, order, err.Error()); err3 != nil {
|
||||
return nil, err3
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -118,7 +117,7 @@ func (v *VoucherBiz) registerNotifyTag(ctx context.Context, stockCreatorMchID, s
|
|||
}
|
||||
|
||||
wechatNotifyTag, err := v.WechatNotifyRegisterTagRepo.GetByStockIdAndMchId(ctx, stockCreatorMchID, stockID)
|
||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
if err != nil && !err2.IsDbNotFound(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
package vo
|
||||
|
||||
import "errors"
|
||||
|
||||
type AvailableType uint8
|
||||
|
||||
const (
|
||||
AvailableTypeFixed AvailableType = iota + 1
|
||||
AvailableTypeDynamic
|
||||
)
|
||||
|
||||
var AvailableTypeMap = map[AvailableType]string{
|
||||
AvailableTypeFixed: "固定有效期",
|
||||
AvailableTypeDynamic: "动态有效期",
|
||||
}
|
||||
|
||||
func (s AvailableType) GetText() string {
|
||||
if t, ok := AvailableTypeMap[s]; ok {
|
||||
return t
|
||||
}
|
||||
return "未知券领取类型"
|
||||
}
|
||||
|
||||
func (s AvailableType) GetValue() uint8 {
|
||||
return uint8(s)
|
||||
}
|
||||
|
||||
func (s AvailableType) IsFixed() bool {
|
||||
return s == AvailableTypeFixed
|
||||
}
|
||||
|
||||
func (s AvailableType) IsDynamic() bool {
|
||||
return s == AvailableTypeDynamic
|
||||
}
|
||||
|
||||
var AvailableCmbTypeMap = map[AvailableType]CmbAvailableType{
|
||||
AvailableTypeFixed: CmbAvailableTypeFixed,
|
||||
AvailableTypeDynamic: CmbAvailableTypeDynamic,
|
||||
}
|
||||
|
||||
func (s AvailableType) GetCmbAvailableType() (CmbAvailableType, error) {
|
||||
if t, ok := AvailableCmbTypeMap[s]; ok {
|
||||
return t, nil
|
||||
}
|
||||
return "", errors.New("未知券领取类型")
|
||||
}
|
||||
|
|
@ -16,8 +16,8 @@ func (s CmbFuncName) GetValue() string {
|
|||
type CmbStatus string
|
||||
|
||||
const (
|
||||
CmbStatusSuccess CmbStatus = "0"
|
||||
CmbStatusUse CmbStatus = "1"
|
||||
CmbStatusSuccess CmbStatus = "0" // 券可用
|
||||
CmbStatusUse CmbStatus = "1" // 券使用
|
||||
CmbStatusExpired CmbStatus = "2" // 券过期-待确认是否通知
|
||||
)
|
||||
|
||||
|
|
@ -29,8 +29,8 @@ func (s CmbStatus) GetValue() string {
|
|||
type CmbResponseStatus string
|
||||
|
||||
const (
|
||||
CmbResponseStatusSuccess CmbResponseStatus = "1000"
|
||||
CmbResponseStatusFail CmbResponseStatus = "1001"
|
||||
CmbResponseStatusSuccess CmbResponseStatus = "1000" // 响应成功
|
||||
CmbResponseStatusFail CmbResponseStatus = "1001" // 响应失败
|
||||
)
|
||||
|
||||
func (s CmbResponseStatus) GetValue() string {
|
||||
|
|
@ -41,8 +41,8 @@ func (s CmbResponseStatus) GetValue() string {
|
|||
type CmbAvailableType string
|
||||
|
||||
const (
|
||||
CmbAvailableTypeFixed CmbAvailableType = "0"
|
||||
CmbAvailableTypeDynamic CmbAvailableType = "1"
|
||||
CmbAvailableTypeFixed CmbAvailableType = "0" // 固定有效期
|
||||
CmbAvailableTypeDynamic CmbAvailableType = "1" // 动态有效期
|
||||
)
|
||||
|
||||
func (s CmbAvailableType) GetValue() string {
|
||||
|
|
|
|||
|
|
@ -12,15 +12,17 @@ const TableNameProduct = "product"
|
|||
|
||||
// Product mapped from table <product>
|
||||
type Product struct {
|
||||
ID int32 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"`
|
||||
Name string `gorm:"column:name;not null;comment:商品名称" json:"name"` // 商品名称
|
||||
ProductNo string `gorm:"column:product_no;not null;comment:商品编号" json:"product_no"` // 商品编号
|
||||
BatchName string `gorm:"column:batch_name;not null;comment:批次名称" json:"batch_name"` // 批次名称
|
||||
BatchNo string `gorm:"column:batch_no;not null;comment:立减金批次号" json:"batch_no"` // 立减金批次号
|
||||
MchId string `gorm:"column:mch_id;not null;comment:商户号,创建批次的商户号" json:"mch_id"` // 商户号,创建批次的商户号
|
||||
Channel uint8 `gorm:"column:channel;not null;comment:1:微信 2:支付宝" json:"channel"` // 1:微信 2:支付宝
|
||||
CreateTime *time.Time `gorm:"column:create_time;not null" json:"create_time"`
|
||||
UpdateTime *time.Time `gorm:"column:update_time" json:"update_time"`
|
||||
ID int32 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"`
|
||||
Name string `gorm:"column:name;not null;comment:商品名称" json:"name"` // 商品名称
|
||||
ProductNo string `gorm:"column:product_no;not null;comment:商品编号" json:"product_no"` // 商品编号
|
||||
BatchName string `gorm:"column:batch_name;not null;comment:批次名称" json:"batch_name"` // 批次名称
|
||||
BatchNo string `gorm:"column:batch_no;not null;comment:立减金批次号" json:"batch_no"` // 立减金批次号
|
||||
MchId string `gorm:"column:mch_id;not null;comment:商户号,创建批次的商户号" json:"mch_id"` // 商户号,创建批次的商户号
|
||||
Channel uint8 `gorm:"column:channel;not null;comment:1:微信 2:支付宝" json:"channel"` // 1:微信 2:支付宝
|
||||
AvailableType uint8 `gorm:"column:available_type;not null;comment:1:固定有效期 2:动态有效期" json:"available_type"`
|
||||
AvailableDays uint32 `gorm:"column:available_days;not null;comment:领取后多少天内" json:"available_days"`
|
||||
CreateTime *time.Time `gorm:"column:create_time;not null" json:"create_time"`
|
||||
UpdateTime *time.Time `gorm:"column:update_time" json:"update_time"`
|
||||
}
|
||||
|
||||
// TableName Product's table name
|
||||
|
|
|
|||
|
|
@ -257,3 +257,17 @@ func IsInSameNaturalMonth(startTime, endTime time.Time) bool {
|
|||
expectedEndTime.Minute() == endTime.Minute() &&
|
||||
expectedEndTime.Second() == endTime.Second()
|
||||
}
|
||||
|
||||
func DaysBetween(start, end time.Time) (int, error) {
|
||||
// 2. 统一到同一天的 0 点(避免时分秒干扰)
|
||||
startDay := start.Truncate(24 * time.Hour)
|
||||
endDay := end.Truncate(24 * time.Hour)
|
||||
|
||||
// 3. 计算天数(含结束日)
|
||||
days := int(endDay.Sub(startDay).Hours() / 24)
|
||||
if end.After(endDay) { // 结束时间非 0 点,加 1 天
|
||||
days++
|
||||
}
|
||||
|
||||
return days, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,3 +101,34 @@ func TestRFC3339(t *testing.T) {
|
|||
fmt.Printf("格式化后的开始时间: %s\n", formattedBeginTime)
|
||||
fmt.Printf("格式化后的结束时间: %s\n", formattedEndTime)
|
||||
}
|
||||
|
||||
func TestDaysBetween(t *testing.T) {
|
||||
// 输入的时间字符串
|
||||
availableBeginTimeStr := "2025-03-07T00:00:00+08:00"
|
||||
availableEndTimeStr := "2025-06-05T23:59:59+08:00"
|
||||
|
||||
// 定义输入时间字符串的格式
|
||||
inputFormat := time.RFC3339
|
||||
|
||||
// 解析开始时间
|
||||
availableBeginTime, err := time.Parse(inputFormat, availableBeginTimeStr)
|
||||
if err != nil {
|
||||
fmt.Printf("解析开始时间出错: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
// 解析结束时间
|
||||
availableEndTime, err := time.Parse(inputFormat, availableEndTimeStr)
|
||||
if err != nil {
|
||||
fmt.Printf("解析结束时间出错: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
days, err := DaysBetween(availableBeginTime, availableEndTime)
|
||||
if err != nil {
|
||||
fmt.Printf("解析结束时间出错: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
t.Log(days)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue