Merge branch 'develop' of https://gitee.com/fusenpack/fusenapi into develop
This commit is contained in:
commit
06349aafa7
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -30,6 +30,7 @@
|
||||||
*.vsix
|
*.vsix
|
||||||
|
|
||||||
__debug_bin
|
__debug_bin
|
||||||
|
__debug_bin*
|
||||||
|
|
||||||
.idea
|
.idea
|
||||||
.vscode
|
.vscode
|
||||||
|
|
|
@ -121,3 +121,8 @@ const (
|
||||||
// 云仓完成
|
// 云仓完成
|
||||||
STATUS_FONT_COMPLETED_CLOUD Order = 8
|
STATUS_FONT_COMPLETED_CLOUD Order = 8
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 订单取消时间
|
||||||
|
const (
|
||||||
|
CANCLE_ORDER_EXPIRE int64 = 48 * 3600
|
||||||
|
)
|
||||||
|
|
|
@ -8,3 +8,6 @@ const DEFAULT_PAGE_SIZE = 20
|
||||||
|
|
||||||
// 最大每页显示数量
|
// 最大每页显示数量
|
||||||
const MAX_PAGE_SIZE = 300
|
const MAX_PAGE_SIZE = 300
|
||||||
|
|
||||||
|
// 最大分页
|
||||||
|
const MAX_PAGE = 100
|
||||||
|
|
|
@ -24,3 +24,7 @@ func (d *FsProductDesignModel) FindOne(ctx context.Context, id int64, userId int
|
||||||
err = d.db.WithContext(ctx).Model(&FsProductDesign{}).Where("`id` = ? and `user_id` = ? and `status` = ?", id, userId, 1).First(&resp).Error
|
err = d.db.WithContext(ctx).Model(&FsProductDesign{}).Where("`id` = ? and `user_id` = ? and `status` = ?", id, userId, 1).First(&resp).Error
|
||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *FsOrderDetailModel) TableName() string {
|
||||||
|
return m.name
|
||||||
|
}
|
||||||
|
|
|
@ -3,8 +3,11 @@ package gmodel
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fusenapi/constants"
|
"fusenapi/constants"
|
||||||
|
"reflect"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"fusenapi/utils/handler"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -51,3 +54,75 @@ func (o *FsOrderModel) FindLastSuccessOneOrder(ctx context.Context, userId int64
|
||||||
err = o.db.WithContext(ctx).Model(&FsOrder{}).Where("`user_id` = ? and `status` > ?", userId, statusGt).Order("id DESC").Take(&order).Error
|
err = o.db.WithContext(ctx).Model(&FsOrder{}).Where("`user_id` = ? and `status` > ?", userId, statusGt).Order("id DESC").Take(&order).Error
|
||||||
return order, err
|
return order, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 分页查询的订单
|
||||||
|
func (o *FsOrderModel) FindPageListByPage(ctx context.Context, rowBuilder *gorm.DB, page *int64, pageSize *int64, filterMap map[string]string, orderBy string) ([]*FsOrderRel, error) {
|
||||||
|
var resp []*FsOrderRel
|
||||||
|
// 过滤
|
||||||
|
if filterMap != nil {
|
||||||
|
rowBuilder = rowBuilder.Scopes(handler.FilterData(filterMap))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 排序
|
||||||
|
if orderBy != "" {
|
||||||
|
var fieldsMap = make(map[string]struct{})
|
||||||
|
s := reflect.TypeOf(&FsOrder{}).Elem() //通过反射获取type定义
|
||||||
|
for i := 0; i < s.NumField(); i++ {
|
||||||
|
fieldsMap[s.Field(i).Tag.Get("json")] = struct{}{}
|
||||||
|
}
|
||||||
|
rowBuilder = rowBuilder.Scopes(handler.OrderCheck(orderBy, fieldsMap))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页
|
||||||
|
rowBuilder = rowBuilder.Scopes(handler.Paginate(page, pageSize))
|
||||||
|
|
||||||
|
// 结果
|
||||||
|
result := rowBuilder.WithContext(ctx).Find(&resp)
|
||||||
|
if result.Error != nil {
|
||||||
|
return nil, result.Error
|
||||||
|
} else {
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type FsOrderRel struct {
|
||||||
|
FsOrder
|
||||||
|
FsOrderDetails []FsOrderDetails `gorm:"foreignKey:order_id;references:id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FsOrderDetails struct {
|
||||||
|
FsOrderDetail
|
||||||
|
FsOrderDetailTemplateInfo FsOrderDetailTemplate `gorm:"foreignKey:id;references:order_detail_template_id"`
|
||||||
|
FsProductInfo FsProduct `gorm:"foreignKey:id;references:product_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *FsOrderModel) RowSelectBuilder(selectData []string) *gorm.DB {
|
||||||
|
var rowBuilder = m.db.Table(m.name)
|
||||||
|
|
||||||
|
if selectData != nil {
|
||||||
|
rowBuilder = rowBuilder.Select(selectData)
|
||||||
|
} else {
|
||||||
|
rowBuilder = rowBuilder.Select("*")
|
||||||
|
}
|
||||||
|
return rowBuilder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *FsOrderModel) FindCount(ctx context.Context, countBuilder *gorm.DB, filterMap map[string]string) (int64, error) {
|
||||||
|
var count int64
|
||||||
|
|
||||||
|
// 过滤
|
||||||
|
if filterMap != nil {
|
||||||
|
countBuilder = countBuilder.Scopes(handler.FilterData(filterMap))
|
||||||
|
}
|
||||||
|
|
||||||
|
result := countBuilder.WithContext(ctx).Limit(1).Count(&count)
|
||||||
|
if result.Error != nil {
|
||||||
|
return 0, result.Error
|
||||||
|
} else {
|
||||||
|
return count, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *FsOrderModel) TableName() string {
|
||||||
|
return m.name
|
||||||
|
}
|
||||||
|
|
|
@ -72,7 +72,11 @@ func (p *FsProductModel) GetRandomProductList(ctx context.Context, limit int) (r
|
||||||
Where("`is_del` =? and `is_shelf` = ?", 0, 1).Order("RAND()").Limit(limit).Find(&resp).Error
|
Where("`is_del` =? and `is_shelf` = ?", 0, 1).Order("RAND()").Limit(limit).Find(&resp).Error
|
||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
|
func (p *FsProductModel) GetIgnoreRandomProductList(ctx context.Context, limit int, notInProductIds []int64) (resp []FsProduct, err error) {
|
||||||
|
err = p.db.WithContext(ctx).Model(&FsProduct{}).
|
||||||
|
Where("`is_del` =? and `is_shelf` = ? and `id` not in(?)", 0, 1, notInProductIds).Order("RAND()").Limit(limit).Find(&resp).Error
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
func (p *FsProductModel) FindAllOnlyByIds(ctx context.Context, ids []int64) (resp []FsProduct, err error) {
|
func (p *FsProductModel) FindAllOnlyByIds(ctx context.Context, ids []int64) (resp []FsProduct, err error) {
|
||||||
err = p.db.WithContext(ctx).Model(&FsProduct{}).Where("`id` IN (?)", ids).Find(&resp).Error
|
err = p.db.WithContext(ctx).Model(&FsProduct{}).Where("`id` IN (?)", ids).Find(&resp).Error
|
||||||
return resp, err
|
return resp, err
|
||||||
|
|
|
@ -75,3 +75,18 @@ func (d *FsProductModel3dModel) GetAll(ctx context.Context) (resp []FsProductMod
|
||||||
err = d.db.WithContext(ctx).Model(&FsProductModel3d{}).Find(&resp).Error
|
err = d.db.WithContext(ctx).Model(&FsProductModel3d{}).Find(&resp).Error
|
||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GetGroupPartListByProductIdsRsp struct {
|
||||||
|
PartList string `json:"part_list"`
|
||||||
|
ProductId int64 `json:"product_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *FsProductModel3dModel) GetGroupPartListByProductIds(ctx context.Context, productIds []int64) (resp []GetGroupPartListByProductIdsRsp, err error) {
|
||||||
|
if len(productIds) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = d.db.WithContext(ctx).Model(&FsProductModel3d{}).
|
||||||
|
Select("product_id,group_concat(part_list) as part_list").
|
||||||
|
Group("product_id").Find(&resp).Error
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
21
model/gmodel/fs_product_recommend_gen.go
Normal file
21
model/gmodel/fs_product_recommend_gen.go
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
package gmodel
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// fs_product_recommend 推荐商品表
|
||||||
|
type FsProductRecommend struct {
|
||||||
|
Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` //
|
||||||
|
ProductId *int64 `gorm:"unique_key;default:0;" json:"product_id"` // 产品ID
|
||||||
|
Status *int64 `gorm:"default:1;" json:"status"` // 状态 1正常 0不正常
|
||||||
|
Ctime *int64 `gorm:"default:0;" json:"ctime"` // 添加时间
|
||||||
|
}
|
||||||
|
type FsProductRecommendModel struct {
|
||||||
|
db *gorm.DB
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFsProductRecommendModel(db *gorm.DB) *FsProductRecommendModel {
|
||||||
|
return &FsProductRecommendModel{db: db, name: "fs_product_recommend"}
|
||||||
|
}
|
46
model/gmodel/fs_product_recommend_logic.go
Normal file
46
model/gmodel/fs_product_recommend_logic.go
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
package gmodel
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetRecommendProductListReq struct {
|
||||||
|
Ctx context.Context
|
||||||
|
Page int
|
||||||
|
Limit int
|
||||||
|
OrderBy string
|
||||||
|
Status *int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *FsProductRecommendModel) GetRecommendProductList(req GetRecommendProductListReq) (resp []FsProductRecommend, total int64, err error) {
|
||||||
|
db := r.db.WithContext(req.Ctx).Model(&FsProductRecommend{})
|
||||||
|
if req.Status != nil {
|
||||||
|
db = db.Where("`status` = ?", *req.Status)
|
||||||
|
}
|
||||||
|
if req.OrderBy != "" {
|
||||||
|
db = db.Order(req.OrderBy)
|
||||||
|
}
|
||||||
|
if err = db.Limit(1).Count(&total).Error; err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
offset := (req.Page - 1) * req.Limit
|
||||||
|
err = db.Offset(offset).Limit(req.Limit).Find(&resp).Error
|
||||||
|
return resp, total, err
|
||||||
|
}
|
||||||
|
func (r *FsProductRecommendModel) GetIgnoreRandomRecommendProductList(ctx context.Context, limit int, idNotInt []int64) (resp []FsProductRecommend, err error) {
|
||||||
|
err = r.db.WithContext(ctx).Model(&FsProductRecommend{}).Where("`product_id` not in(?)", idNotInt).Order("RAND()").Limit(limit).Find(&resp).Error
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
func (r *FsProductRecommendModel) CreateOrUpdate(ctx context.Context, productId int64, data *FsProductRecommend) error {
|
||||||
|
var info FsProductRecommend
|
||||||
|
err := r.db.WithContext(ctx).Model(&FsProductRecommend{}).Where("`product_id` = ?", productId).Take(&info).Error
|
||||||
|
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if info.Id == 0 {
|
||||||
|
return r.db.WithContext(ctx).Model(&FsProductRecommend{}).Create(data).Error
|
||||||
|
}
|
||||||
|
return r.db.WithContext(ctx).Model(&FsProductRecommend{}).Where("`product_id` = ?", productId).Updates(data).Error
|
||||||
|
}
|
|
@ -60,6 +60,7 @@ type AllModelsGen struct {
|
||||||
FsProductModel3dLight *FsProductModel3dLightModel // fs_product_model3d_light 模型-灯光组表
|
FsProductModel3dLight *FsProductModel3dLightModel // fs_product_model3d_light 模型-灯光组表
|
||||||
FsProductOption *FsProductOptionModel // fs_product_option 产品选项表(已废弃)
|
FsProductOption *FsProductOptionModel // fs_product_option 产品选项表(已废弃)
|
||||||
FsProductPrice *FsProductPriceModel // fs_product_price 阶梯价格表
|
FsProductPrice *FsProductPriceModel // fs_product_price 阶梯价格表
|
||||||
|
FsProductRecommend *FsProductRecommendModel // fs_product_recommend 推荐商品表
|
||||||
FsProductRenderDesign *FsProductRenderDesignModel // fs_product_render_design
|
FsProductRenderDesign *FsProductRenderDesignModel // fs_product_render_design
|
||||||
FsProductScene *FsProductSceneModel // fs_product_scene 产品场景表
|
FsProductScene *FsProductSceneModel // fs_product_scene 产品场景表
|
||||||
FsProductSize *FsProductSizeModel // fs_product_size 产品尺寸表
|
FsProductSize *FsProductSizeModel // fs_product_size 产品尺寸表
|
||||||
|
@ -149,6 +150,7 @@ func NewAllModels(gdb *gorm.DB) *AllModelsGen {
|
||||||
FsProductModel3dLight: NewFsProductModel3dLightModel(gdb),
|
FsProductModel3dLight: NewFsProductModel3dLightModel(gdb),
|
||||||
FsProductOption: NewFsProductOptionModel(gdb),
|
FsProductOption: NewFsProductOptionModel(gdb),
|
||||||
FsProductPrice: NewFsProductPriceModel(gdb),
|
FsProductPrice: NewFsProductPriceModel(gdb),
|
||||||
|
FsProductRecommend: NewFsProductRecommendModel(gdb),
|
||||||
FsProductRenderDesign: NewFsProductRenderDesignModel(gdb),
|
FsProductRenderDesign: NewFsProductRenderDesignModel(gdb),
|
||||||
FsProductScene: NewFsProductSceneModel(gdb),
|
FsProductScene: NewFsProductSceneModel(gdb),
|
||||||
FsProductSize: NewFsProductSizeModel(gdb),
|
FsProductSize: NewFsProductSizeModel(gdb),
|
||||||
|
|
78
server/orders/internal/handler/getuserorderlisthandler.go
Normal file
78
server/orders/internal/handler/getuserorderlisthandler.go
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
"github.com/zeromicro/go-zero/rest/httpx"
|
||||||
|
|
||||||
|
"fusenapi/utils/auth"
|
||||||
|
"fusenapi/utils/basic"
|
||||||
|
|
||||||
|
"fusenapi/server/orders/internal/logic"
|
||||||
|
"fusenapi/server/orders/internal/svc"
|
||||||
|
"fusenapi/server/orders/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetUserOrderListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
var (
|
||||||
|
// 定义错误变量
|
||||||
|
err error
|
||||||
|
// 定义用户信息变量
|
||||||
|
userinfo *auth.UserInfo
|
||||||
|
)
|
||||||
|
// 解析JWT token,并对空用户进行判断
|
||||||
|
claims, err := svcCtx.ParseJwtToken(r)
|
||||||
|
// 如果解析JWT token出错,则返回未授权的JSON响应并记录错误消息
|
||||||
|
if err != nil {
|
||||||
|
httpx.OkJsonCtx(r.Context(), w, &basic.Response{
|
||||||
|
Code: 401, // 返回401状态码,表示未授权
|
||||||
|
Message: "unauthorized", // 返回未授权信息
|
||||||
|
})
|
||||||
|
logx.Info("unauthorized:", err.Error()) // 记录错误日志
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if claims != nil {
|
||||||
|
// 从token中获取对应的用户信息
|
||||||
|
userinfo, err = auth.GetUserInfoFormMapClaims(claims)
|
||||||
|
// 如果获取用户信息出错,则返回未授权的JSON响应并记录错误消息
|
||||||
|
if err != nil {
|
||||||
|
httpx.OkJsonCtx(r.Context(), w, &basic.Response{
|
||||||
|
Code: 401,
|
||||||
|
Message: "unauthorized",
|
||||||
|
})
|
||||||
|
logx.Info("unauthorized:", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 如果claims为nil,则认为用户身份为白板用户
|
||||||
|
userinfo = &auth.UserInfo{UserId: 0, GuestId: 0}
|
||||||
|
}
|
||||||
|
|
||||||
|
var req types.GetUserOrderListReq
|
||||||
|
// 如果端点有请求结构体,则使用httpx.Parse方法从HTTP请求体中解析请求数据
|
||||||
|
if err := httpx.Parse(r, &req); err != nil {
|
||||||
|
httpx.OkJsonCtx(r.Context(), w, &basic.Response{
|
||||||
|
Code: 510,
|
||||||
|
Message: "parameter error",
|
||||||
|
})
|
||||||
|
logx.Info(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 创建一个业务逻辑层实例
|
||||||
|
l := logic.NewGetUserOrderListLogic(r.Context(), svcCtx)
|
||||||
|
resp := l.GetUserOrderList(&req, userinfo)
|
||||||
|
// 如果响应不为nil,则使用httpx.OkJsonCtx方法返回JSON响应;
|
||||||
|
if resp != nil {
|
||||||
|
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
|
} else {
|
||||||
|
err := errors.New("server logic is error, resp must not be nil")
|
||||||
|
httpx.ErrorCtx(r.Context(), w, err)
|
||||||
|
logx.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,6 +22,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||||
Path: "/api/order/detail",
|
Path: "/api/order/detail",
|
||||||
Handler: GetOrderDetailHandler(serverCtx),
|
Handler: GetOrderDetailHandler(serverCtx),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Method: http.MethodGet,
|
||||||
|
Path: "/api/user/order-list",
|
||||||
|
Handler: GetUserOrderListHandler(serverCtx),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
146
server/orders/internal/logic/getuserorderlistlogic.go
Normal file
146
server/orders/internal/logic/getuserorderlistlogic.go
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
package logic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fusenapi/constants"
|
||||||
|
"fusenapi/model/gmodel"
|
||||||
|
"fusenapi/utils/auth"
|
||||||
|
"fusenapi/utils/basic"
|
||||||
|
"fusenapi/utils/format"
|
||||||
|
"math"
|
||||||
|
|
||||||
|
"fusenapi/server/orders/internal/svc"
|
||||||
|
"fusenapi/server/orders/internal/types"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetUserOrderListLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGetUserOrderListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetUserOrderListLogic {
|
||||||
|
return &GetUserOrderListLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *GetUserOrderListLogic) GetUserOrderList(req *types.GetUserOrderListReq, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||||
|
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
||||||
|
// userinfo 传入值时, 一定不为null
|
||||||
|
orderDetailModel := gmodel.NewFsOrderDetailModel(l.svcCtx.MysqlConn)
|
||||||
|
orderModel := gmodel.NewFsOrderModel(l.svcCtx.MysqlConn)
|
||||||
|
rowBuilder := orderModel.RowSelectBuilder(nil)
|
||||||
|
if userinfo == nil || userinfo.UserId == 0 {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "order not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询条件
|
||||||
|
var page = req.Page
|
||||||
|
var pageSize = req.PageSize
|
||||||
|
var listRes []*gmodel.FsOrderRel
|
||||||
|
rowBuilder = rowBuilder.Where("user_id =?", userinfo.UserId).Where("status =?", req.Status)
|
||||||
|
|
||||||
|
// 查询总数
|
||||||
|
total, err := orderModel.FindCount(l.ctx, rowBuilder, nil)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "order not found")
|
||||||
|
}
|
||||||
|
logx.Error(err)
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get order info")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询数据
|
||||||
|
if total > 0 {
|
||||||
|
rowBuilder = rowBuilder.Preload("FsOrderDetails", func(dbPreload *gorm.DB) *gorm.DB {
|
||||||
|
return dbPreload.Table(orderDetailModel.TableName()).Preload("FsOrderDetailTemplateInfo").Preload("FsProductInfo")
|
||||||
|
})
|
||||||
|
listRes, err = orderModel.FindPageListByPage(l.ctx, rowBuilder, &page, &pageSize, nil, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "order not found")
|
||||||
|
}
|
||||||
|
logx.Error(err)
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get order info")
|
||||||
|
}
|
||||||
|
listResLen := len(listRes)
|
||||||
|
|
||||||
|
var respList []types.Items
|
||||||
|
if listResLen > 0 {
|
||||||
|
// 数据处理
|
||||||
|
for _, item := range listRes {
|
||||||
|
var pbData types.Items
|
||||||
|
pbData.ID = item.Id
|
||||||
|
pbData.Sn = *item.Sn
|
||||||
|
pbData.UserID = *item.UserId
|
||||||
|
pbData.TotalAmount = *item.TotalAmount
|
||||||
|
pbData.Ctime = format.TimeIntToFormat(*item.Ctime)
|
||||||
|
pbData.Status = *item.Status
|
||||||
|
pbData.DeliveryMethod = *item.DeliveryMethod
|
||||||
|
pbData.TsTime = format.TimeToFormat(*item.TsTime)
|
||||||
|
pbData.IsPayCompleted = *item.IsPayCompleted
|
||||||
|
pbData.DeliverSn = *item.DeliverSn
|
||||||
|
|
||||||
|
var pcsBox int64
|
||||||
|
var pcs int64
|
||||||
|
var productList []*types.Product
|
||||||
|
if len(item.FsOrderDetails) > 0 {
|
||||||
|
for _, fsOrderDetailItem := range item.FsOrderDetails {
|
||||||
|
fsOrderDetailBuyNum := *fsOrderDetailItem.FsOrderDetail.BuyNum
|
||||||
|
fsOrderDetailEachBoxNum := *fsOrderDetailItem.FsOrderDetailTemplateInfo.EachBoxNum
|
||||||
|
pcs = pcs + fsOrderDetailBuyNum
|
||||||
|
pcsBoxNum := fsOrderDetailBuyNum / fsOrderDetailEachBoxNum
|
||||||
|
var csBoxNumF int64
|
||||||
|
if (fsOrderDetailBuyNum % fsOrderDetailEachBoxNum) > 0 {
|
||||||
|
csBoxNumF = 1
|
||||||
|
}
|
||||||
|
pcsBox = pcsBox + pcsBoxNum + csBoxNumF
|
||||||
|
|
||||||
|
var product types.Product
|
||||||
|
product.Cover = *fsOrderDetailItem.Cover
|
||||||
|
product.Fitting = *fsOrderDetailItem.OptionalTitle
|
||||||
|
product.OptionPrice = *fsOrderDetailItem.OptionPrice
|
||||||
|
product.OrderDetailTemplateId = *fsOrderDetailItem.OrderDetailTemplateId
|
||||||
|
product.OrderId = *fsOrderDetailItem.OrderId
|
||||||
|
product.Pcs = fsOrderDetailBuyNum
|
||||||
|
product.PcsBox = pcsBox
|
||||||
|
product.Price = *fsOrderDetailItem.FsOrderDetail.Amount
|
||||||
|
product.ProductId = *fsOrderDetailItem.OptionPrice
|
||||||
|
//product.Size = *fsOrderDetailItem.FsProductInfo.s
|
||||||
|
product.Title = *fsOrderDetailItem.FsProductInfo.Title
|
||||||
|
|
||||||
|
productList = append(productList, &product)
|
||||||
|
}
|
||||||
|
pbData.ProductList = productList
|
||||||
|
}
|
||||||
|
|
||||||
|
pbData.PcsBox = pcsBox
|
||||||
|
pbData.Pcs = pcs
|
||||||
|
pbData.SurplusAt = *item.Ctime + constants.CANCLE_ORDER_EXPIRE
|
||||||
|
pbData.LogisticsStatus = 1
|
||||||
|
pbData.Deposit = *item.TotalAmount / 2
|
||||||
|
pbData.Remaining = pbData.Deposit
|
||||||
|
respList = append(respList, pbData)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeOK, "success", types.GetUserOrderListRsp{
|
||||||
|
Items: respList,
|
||||||
|
Meta: types.Meta{
|
||||||
|
TotalCount: total,
|
||||||
|
PageCount: int64(math.Ceil(float64(total) / float64(pageSize))),
|
||||||
|
CurrentPage: int(page),
|
||||||
|
PerPage: int(pageSize),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
|
@ -76,6 +76,47 @@ type Deposit struct {
|
||||||
TransNo string `json:"trans_no"`
|
TransNo string `json:"trans_no"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GetUserOrderListReq struct {
|
||||||
|
Page int64 `form:"page"` // 分页
|
||||||
|
PageSize int64 `form:"page_size"` // 每页数量
|
||||||
|
Status int64 `form:"status"` // 状态筛选
|
||||||
|
Time int64 `form:"time"` // 时间筛选
|
||||||
|
Total int64 `form:"total"` // 总数
|
||||||
|
Size int64 `form:"size"` // 图片尺寸
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetUserOrderListRsp struct {
|
||||||
|
Items []Items `json:"items"`
|
||||||
|
Meta Meta `json:"_meta"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type StatusTime struct {
|
||||||
|
Key int `json:"key"`
|
||||||
|
Time string `json:"time"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Items struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
Sn string `json:"sn"`
|
||||||
|
UserID int64 `json:"user_id"`
|
||||||
|
TotalAmount int64 `json:"total_amount"`
|
||||||
|
Ctime string `json:"ctime"`
|
||||||
|
Status int64 `json:"status"`
|
||||||
|
DeliveryMethod int64 `json:"delivery_method"`
|
||||||
|
TsTime string `json:"ts_time"`
|
||||||
|
IsPayCompleted int64 `json:"is_pay_completed"`
|
||||||
|
DeliverSn string `json:"deliver_sn"`
|
||||||
|
PcsBox int64 `json:"pcs_box"`
|
||||||
|
Pcs int64 `json:"pcs"`
|
||||||
|
SurplusAt int64 `json:"surplus_at"`
|
||||||
|
LogisticsStatus int64 `json:"logistics_status"`
|
||||||
|
StatusTimes []*StatusTime `json:"status_times"`
|
||||||
|
Deposit int64 `json:"deposit"`
|
||||||
|
Remaining int64 `json:"remaining"`
|
||||||
|
ProductList []*Product `json:"productList"`
|
||||||
|
IsStop int64 `json:"is_stop"`
|
||||||
|
}
|
||||||
|
|
||||||
type Request struct {
|
type Request struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
7
server/orders/orders_test.go
Normal file
7
server/orders/orders_test.go
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestMain(t *testing.T) {
|
||||||
|
main()
|
||||||
|
}
|
|
@ -30,18 +30,54 @@ func NewGetRecommandProductListLogic(ctx context.Context, svcCtx *svc.ServiceCon
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *GetRecommandProductListLogic) GetRecommandProductList(req *types.GetRecommandProductListReq, userinfo *auth.UserInfo) (resp *basic.Response) {
|
func (l *GetRecommandProductListLogic) GetRecommandProductList(req *types.GetRecommandProductListReq, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||||
req.Num = 8 //目前写死
|
req.Num = 4 //写死4个
|
||||||
if req.Size > 0 {
|
if req.Size > 0 {
|
||||||
req.Size = image.GetCurrentSize(req.Size)
|
req.Size = image.GetCurrentSize(req.Size)
|
||||||
}
|
}
|
||||||
//随机取产品列表
|
productInfo, err := l.svcCtx.AllModels.FsProduct.FindOneBySn(l.ctx, req.Sn)
|
||||||
productList, err := l.svcCtx.AllModels.FsProduct.GetRandomProductList(l.ctx, int(req.Num))
|
if err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "detail`s product is not found")
|
||||||
|
}
|
||||||
|
logx.Error(err)
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get detail product info")
|
||||||
|
}
|
||||||
|
//随机取产品列表(不包含详情产品)
|
||||||
|
recommendList, err := l.svcCtx.AllModels.FsProductRecommend.GetIgnoreRandomRecommendProductList(l.ctx, int(req.Num), []int64{productInfo.Id})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Error(err)
|
logx.Error(err)
|
||||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get random recommend product list")
|
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get random recommend list")
|
||||||
}
|
}
|
||||||
if len(productList) == 0 {
|
//需要填充时需要忽略的id
|
||||||
return resp.SetStatusWithMessage(basic.CodeOK, "success")
|
ignoreProductIds := make([]int64, 0, len(recommendList)+1)
|
||||||
|
ignoreProductIds = append(ignoreProductIds, productInfo.Id)
|
||||||
|
recommendProductIds := make([]int64, 0, len(recommendList))
|
||||||
|
for _, v := range recommendList {
|
||||||
|
ignoreProductIds = append(ignoreProductIds, *v.ProductId)
|
||||||
|
recommendProductIds = append(recommendProductIds, *v.ProductId)
|
||||||
|
}
|
||||||
|
//获取推荐产品列表
|
||||||
|
recommendProductList, err := l.svcCtx.AllModels.FsProduct.GetProductListByIds(l.ctx, recommendProductIds, "")
|
||||||
|
if err != nil {
|
||||||
|
logx.Error(err)
|
||||||
|
return resp.SetStatus(basic.CodeDbSqlErr, "failed to get recommend product list")
|
||||||
|
}
|
||||||
|
//在合并之前记住推荐的产品
|
||||||
|
mapRecommend := make(map[int64]struct{})
|
||||||
|
for _, v := range recommendProductList {
|
||||||
|
mapRecommend[v.Id] = struct{}{}
|
||||||
|
}
|
||||||
|
//小于请求的数量则需要从产品表中随机填补上
|
||||||
|
lenRecommendProduct := len(recommendProductList)
|
||||||
|
if lenRecommendProduct < int(req.Num) {
|
||||||
|
appendNum := int(req.Num) - lenRecommendProduct
|
||||||
|
productList, err := l.svcCtx.AllModels.FsProduct.GetIgnoreRandomProductList(l.ctx, appendNum, ignoreProductIds)
|
||||||
|
if err != nil {
|
||||||
|
logx.Error(err)
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product list")
|
||||||
|
}
|
||||||
|
//合并列表
|
||||||
|
recommendProductList = append(recommendProductList, productList...)
|
||||||
}
|
}
|
||||||
//获取用户信息(不用判断存在)
|
//获取用户信息(不用判断存在)
|
||||||
user, err := l.svcCtx.AllModels.FsUser.FindUserById(l.ctx, userinfo.UserId)
|
user, err := l.svcCtx.AllModels.FsUser.FindUserById(l.ctx, userinfo.UserId)
|
||||||
|
@ -49,8 +85,8 @@ func (l *GetRecommandProductListLogic) GetRecommandProductList(req *types.GetRec
|
||||||
logx.Error(err)
|
logx.Error(err)
|
||||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get user")
|
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get user")
|
||||||
}
|
}
|
||||||
list := make([]types.GetRecommandProductListRsp, 0, len(productList))
|
list := make([]types.GetRecommandProductListRsp, 0, len(recommendProductList))
|
||||||
for _, v := range productList {
|
for _, v := range recommendProductList {
|
||||||
r := image.ThousandFaceImageFormatReq{
|
r := image.ThousandFaceImageFormatReq{
|
||||||
Size: int(req.Size),
|
Size: int(req.Size),
|
||||||
IsThousandFace: 0,
|
IsThousandFace: 0,
|
||||||
|
@ -63,7 +99,12 @@ func (l *GetRecommandProductListLogic) GetRecommandProductList(req *types.GetRec
|
||||||
if user.Id != 0 {
|
if user.Id != 0 {
|
||||||
r.IsThousandFace = int(*user.IsThousandFace)
|
r.IsThousandFace = int(*user.IsThousandFace)
|
||||||
}
|
}
|
||||||
|
//千人前面处理
|
||||||
image.ThousandFaceImageFormat(&r)
|
image.ThousandFaceImageFormat(&r)
|
||||||
|
isRecommend := int64(0)
|
||||||
|
if _, ok := mapRecommend[v.Id]; ok {
|
||||||
|
isRecommend = 1
|
||||||
|
}
|
||||||
list = append(list, types.GetRecommandProductListRsp{
|
list = append(list, types.GetRecommandProductListRsp{
|
||||||
Id: v.Id,
|
Id: v.Id,
|
||||||
Sn: *v.Sn,
|
Sn: *v.Sn,
|
||||||
|
@ -73,6 +114,7 @@ func (l *GetRecommandProductListLogic) GetRecommandProductList(req *types.GetRec
|
||||||
CoverImg: r.CoverImg,
|
CoverImg: r.CoverImg,
|
||||||
CoverDefault: r.CoverDefault,
|
CoverDefault: r.CoverDefault,
|
||||||
Intro: *v.Intro,
|
Intro: *v.Intro,
|
||||||
|
IsRecommend: isRecommend,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return resp.SetStatusWithMessage(basic.CodeOK, "success", list)
|
return resp.SetStatusWithMessage(basic.CodeOK, "success", list)
|
||||||
|
|
|
@ -78,6 +78,8 @@ func (l *GetTagProductListLogic) GetTagProductList(req *types.GetTagProductListR
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
productList []gmodel.FsProduct //产品列表(select 字段需要看查询的地方)
|
productList []gmodel.FsProduct //产品列表(select 字段需要看查询的地方)
|
||||||
|
productOptionalPartList []gmodel.GetGroupPartListByProductIdsRsp //产品配件列表
|
||||||
|
mapProductHaveOptionFitting = make(map[int64]struct{})
|
||||||
productPriceList []gmodel.GetPriceListByProductIdsRsp //产品价格列表(select 字段需要看查询的地方)
|
productPriceList []gmodel.GetPriceListByProductIdsRsp //产品价格列表(select 字段需要看查询的地方)
|
||||||
mapProductMinPrice = make(map[int64]int64) //产品最小价格map
|
mapProductMinPrice = make(map[int64]int64) //产品最小价格map
|
||||||
productTemplatesV2 []gmodel.FsProductTemplateV2 //产品模板列表(select 字段需要看查询的地方)
|
productTemplatesV2 []gmodel.FsProductTemplateV2 //产品模板列表(select 字段需要看查询的地方)
|
||||||
|
@ -108,6 +110,21 @@ func (l *GetTagProductListLogic) GetTagProductList(req *types.GetTagProductListR
|
||||||
for _, product := range productList {
|
for _, product := range productList {
|
||||||
productIds = append(productIds, product.Id)
|
productIds = append(productIds, product.Id)
|
||||||
}
|
}
|
||||||
|
//获取商品可选配件
|
||||||
|
productOptionalPartList, err = l.svcCtx.AllModels.FsProductModel3d.GetGroupPartListByProductIds(l.ctx, productIds)
|
||||||
|
if err != nil {
|
||||||
|
logx.Error(err)
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product part list")
|
||||||
|
}
|
||||||
|
//存储有配件的map
|
||||||
|
for _, partList := range productOptionalPartList {
|
||||||
|
partList.PartList = strings.Trim(partList.PartList, " ")
|
||||||
|
partList.PartList = strings.Trim(partList.PartList, ",")
|
||||||
|
if partList.PartList == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
mapProductHaveOptionFitting[partList.ProductId] = struct{}{}
|
||||||
|
}
|
||||||
//获取产品价格列表
|
//获取产品价格列表
|
||||||
productPriceList, err = l.svcCtx.AllModels.FsProductPrice.GetSimplePriceListByProductIds(l.ctx, productIds)
|
productPriceList, err = l.svcCtx.AllModels.FsProductPrice.GetSimplePriceListByProductIds(l.ctx, productIds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -158,6 +175,7 @@ func (l *GetTagProductListLogic) GetTagProductList(req *types.GetTagProductListR
|
||||||
MapProductTemplate: mapProductTemplate,
|
MapProductTemplate: mapProductTemplate,
|
||||||
MapProductSizeCount: mapProductSizeCount,
|
MapProductSizeCount: mapProductSizeCount,
|
||||||
MapTagLevel: mapTagLevel,
|
MapTagLevel: mapTagLevel,
|
||||||
|
MapProductHaveOptionFitting: mapProductHaveOptionFitting,
|
||||||
Size: req.Size,
|
Size: req.Size,
|
||||||
user: user,
|
user: user,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
|
@ -185,6 +203,7 @@ type dealWithTagMenuDataReq struct {
|
||||||
MapProductTemplate map[int64]struct{}
|
MapProductTemplate map[int64]struct{}
|
||||||
MapProductSizeCount map[int64]int64
|
MapProductSizeCount map[int64]int64
|
||||||
MapTagLevel map[string]*types.TagItem
|
MapTagLevel map[string]*types.TagItem
|
||||||
|
MapProductHaveOptionFitting map[int64]struct{}
|
||||||
Size uint32
|
Size uint32
|
||||||
user gmodel.FsUser
|
user gmodel.FsUser
|
||||||
}
|
}
|
||||||
|
@ -211,6 +230,7 @@ func (l *GetTagProductListLogic) dealWithTagMenuData(req dealWithTagMenuDataReq)
|
||||||
MapProductMinPrice: req.MapProductMinPrice,
|
MapProductMinPrice: req.MapProductMinPrice,
|
||||||
MapProductTemplate: req.MapProductTemplate,
|
MapProductTemplate: req.MapProductTemplate,
|
||||||
MapProductSizeCount: req.MapProductSizeCount,
|
MapProductSizeCount: req.MapProductSizeCount,
|
||||||
|
MapProductHaveOptionFitting: req.MapProductHaveOptionFitting,
|
||||||
Size: req.Size,
|
Size: req.Size,
|
||||||
User: req.user,
|
User: req.user,
|
||||||
})
|
})
|
||||||
|
@ -257,6 +277,7 @@ func (l *GetTagProductListLogic) organizationLevelRelation(mapTagLevel map[strin
|
||||||
})
|
})
|
||||||
return rspList
|
return rspList
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取对应tag的产品列表
|
// 获取对应tag的产品列表
|
||||||
type getTagProductsReq struct {
|
type getTagProductsReq struct {
|
||||||
TagId int64
|
TagId int64
|
||||||
|
@ -264,6 +285,7 @@ type getTagProductsReq struct {
|
||||||
MapProductMinPrice map[int64]int64
|
MapProductMinPrice map[int64]int64
|
||||||
MapProductTemplate map[int64]struct{}
|
MapProductTemplate map[int64]struct{}
|
||||||
MapProductSizeCount map[int64]int64
|
MapProductSizeCount map[int64]int64
|
||||||
|
MapProductHaveOptionFitting map[int64]struct{}
|
||||||
Size uint32
|
Size uint32
|
||||||
User gmodel.FsUser
|
User gmodel.FsUser
|
||||||
}
|
}
|
||||||
|
@ -286,6 +308,11 @@ func (l *GetTagProductListLogic) getTagProducts(req getTagProductsReq) (productL
|
||||||
if mapSizeNum, ok := req.MapProductSizeCount[productInfo.Id]; ok {
|
if mapSizeNum, ok := req.MapProductSizeCount[productInfo.Id]; ok {
|
||||||
sizeNum = mapSizeNum
|
sizeNum = mapSizeNum
|
||||||
}
|
}
|
||||||
|
//有无可选配件
|
||||||
|
haveOptionalFitting := false
|
||||||
|
if _, ok = req.MapProductHaveOptionFitting[productInfo.Id]; ok {
|
||||||
|
haveOptionalFitting = true
|
||||||
|
}
|
||||||
item := types.TagProduct{
|
item := types.TagProduct{
|
||||||
ProductId: productInfo.Id,
|
ProductId: productInfo.Id,
|
||||||
Sn: *productInfo.Sn,
|
Sn: *productInfo.Sn,
|
||||||
|
@ -295,6 +322,7 @@ func (l *GetTagProductListLogic) getTagProducts(req getTagProductsReq) (productL
|
||||||
IsMicro: *productInfo.IsMicrowave,
|
IsMicro: *productInfo.IsMicrowave,
|
||||||
SizeNum: uint32(sizeNum),
|
SizeNum: uint32(sizeNum),
|
||||||
MiniPrice: minPrice,
|
MiniPrice: minPrice,
|
||||||
|
HaveOptionalFitting: haveOptionalFitting,
|
||||||
}
|
}
|
||||||
//千人千面处理
|
//千人千面处理
|
||||||
r := image.ThousandFaceImageFormatReq{
|
r := image.ThousandFaceImageFormatReq{
|
||||||
|
|
|
@ -242,6 +242,7 @@ type GetRecommandProductListRsp struct {
|
||||||
CoverImg string `json:"cover_img"`
|
CoverImg string `json:"cover_img"`
|
||||||
CoverDefault string `json:"cover_default"`
|
CoverDefault string `json:"cover_default"`
|
||||||
Intro string `json:"intro"`
|
Intro string `json:"intro"`
|
||||||
|
IsRecommend int64 `json:"is_recommend"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetTagProductListReq struct {
|
type GetTagProductListReq struct {
|
||||||
|
@ -279,6 +280,7 @@ type TagProduct struct {
|
||||||
SizeNum uint32 `json:"size_num"`
|
SizeNum uint32 `json:"size_num"`
|
||||||
MiniPrice int64 `json:"mini_price"`
|
MiniPrice int64 `json:"mini_price"`
|
||||||
CoverDefault string `json:"cover_default"`
|
CoverDefault string `json:"cover_default"`
|
||||||
|
HaveOptionalFitting bool `json:"have_optional_fitting"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetRenderDesignReq struct {
|
type GetRenderDesignReq struct {
|
||||||
|
|
|
@ -16,6 +16,10 @@ service orders {
|
||||||
//获取订单详情
|
//获取订单详情
|
||||||
@handler GetOrderDetailHandler
|
@handler GetOrderDetailHandler
|
||||||
get /api/order/detail (GetOrderDetailReq) returns (response);
|
get /api/order/detail (GetOrderDetailReq) returns (response);
|
||||||
|
|
||||||
|
//获取订单列表
|
||||||
|
@handler GetUserOrderListHandler
|
||||||
|
get /api/user/order-list (GetUserOrderListReq) returns (response);
|
||||||
}
|
}
|
||||||
|
|
||||||
//获取订单发票
|
//获取订单发票
|
||||||
|
@ -83,3 +87,47 @@ type Deposit {
|
||||||
Method string `json:"method"`
|
Method string `json:"method"`
|
||||||
TransNo string `json:"trans_no"`
|
TransNo string `json:"trans_no"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取订单列表
|
||||||
|
type (
|
||||||
|
GetUserOrderListReq {
|
||||||
|
Page int64 `form:"page"` // 分页
|
||||||
|
PageSize int64 `form:"page_size"` // 每页数量
|
||||||
|
Status int64 `form:"status"` // 状态筛选
|
||||||
|
Time int64 `form:"time"` // 时间筛选
|
||||||
|
Total int64 `form:"total"` // 总数
|
||||||
|
Size int64 `form:"size"` // 图片尺寸
|
||||||
|
}
|
||||||
|
|
||||||
|
GetUserOrderListRsp {
|
||||||
|
Items []Items `json:"items"`
|
||||||
|
Meta Meta `json:"_meta"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
type StatusTime {
|
||||||
|
Key int `json:"key"`
|
||||||
|
Time string `json:"time"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Items {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
Sn string `json:"sn"`
|
||||||
|
UserID int64 `json:"user_id"`
|
||||||
|
TotalAmount int64 `json:"total_amount"`
|
||||||
|
Ctime string `json:"ctime"`
|
||||||
|
Status int64 `json:"status"`
|
||||||
|
DeliveryMethod int64 `json:"delivery_method"`
|
||||||
|
TsTime string `json:"ts_time"`
|
||||||
|
IsPayCompleted int64 `json:"is_pay_completed"`
|
||||||
|
DeliverSn string `json:"deliver_sn"`
|
||||||
|
PcsBox int64 `json:"pcs_box"`
|
||||||
|
Pcs int64 `json:"pcs"`
|
||||||
|
SurplusAt int64 `json:"surplus_at"`
|
||||||
|
LogisticsStatus int64 `json:"logistics_status"`
|
||||||
|
StatusTimes []*StatusTime `json:"status_times"`
|
||||||
|
Deposit int64 `json:"deposit"`
|
||||||
|
Remaining int64 `json:"remaining"`
|
||||||
|
ProductList []*Product `json:"productList"`
|
||||||
|
IsStop int64 `json:"is_stop"`
|
||||||
|
}
|
|
@ -69,6 +69,9 @@ service product {
|
||||||
@handler GetLastProductDesignHandler
|
@handler GetLastProductDesignHandler
|
||||||
get /api/product/get_last_product_design(request) returns (response);
|
get /api/product/get_last_product_design(request) returns (response);
|
||||||
//*********************产品详情分解接口结束***********************
|
//*********************产品详情分解接口结束***********************
|
||||||
|
//*********************推荐产品接口开始××××××××××××××××××××××××××
|
||||||
|
|
||||||
|
//*********************推荐产品接口结束××××××××××××××××××××××××××
|
||||||
}
|
}
|
||||||
|
|
||||||
//获取产品列表
|
//获取产品列表
|
||||||
|
@ -288,6 +291,7 @@ type GetRecommandProductListRsp {
|
||||||
CoverImg string `json:"cover_img"`
|
CoverImg string `json:"cover_img"`
|
||||||
CoverDefault string `json:"cover_default"`
|
CoverDefault string `json:"cover_default"`
|
||||||
Intro string `json:"intro"`
|
Intro string `json:"intro"`
|
||||||
|
IsRecommend int64 `json:"is_recommend"`
|
||||||
}
|
}
|
||||||
//获取分类产品列表
|
//获取分类产品列表
|
||||||
type GetTagProductListReq {
|
type GetTagProductListReq {
|
||||||
|
@ -322,6 +326,7 @@ type TagProduct {
|
||||||
SizeNum uint32 `json:"size_num"`
|
SizeNum uint32 `json:"size_num"`
|
||||||
MiniPrice int64 `json:"mini_price"`
|
MiniPrice int64 `json:"mini_price"`
|
||||||
CoverDefault string `json:"cover_default"`
|
CoverDefault string `json:"cover_default"`
|
||||||
|
HaveOptionalFitting bool `json:"have_optional_fitting"`
|
||||||
}
|
}
|
||||||
//获取云渲染设计方案信息
|
//获取云渲染设计方案信息
|
||||||
type GetRenderDesignReq {
|
type GetRenderDesignReq {
|
||||||
|
|
11
utils/format/time.go
Normal file
11
utils/format/time.go
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
package format
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
func TimeToFormat(t time.Time) string {
|
||||||
|
return time.Time(t).Format("2006-01-02 15:04:05")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TimeIntToFormat(unixTime int64) string {
|
||||||
|
return time.Unix(unixTime, 0).Format("2006-01-02 15:04:05")
|
||||||
|
}
|
146
utils/handler/gormHandler.go
Normal file
146
utils/handler/gormHandler.go
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"fusenapi/constants"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"unicode"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FilterData 条件过滤
|
||||||
|
func FilterData(filterMap map[string]string) func(db *gorm.DB) *gorm.DB {
|
||||||
|
return func(db *gorm.DB) *gorm.DB {
|
||||||
|
// 组合索引
|
||||||
|
db = db.Where("id <> ?", 0)
|
||||||
|
for fieldName, item := range filterMap {
|
||||||
|
options := strings.Split(item, "|")
|
||||||
|
conditionKey := options[1]
|
||||||
|
|
||||||
|
var conditionValueType string
|
||||||
|
if len(options) == 3 {
|
||||||
|
conditionValueType = options[2]
|
||||||
|
}
|
||||||
|
|
||||||
|
var conditionValue interface{}
|
||||||
|
|
||||||
|
if conditionKey == "=" || conditionKey == "<>" || conditionKey == ">=" || conditionKey == "<=" {
|
||||||
|
conditionStr := options[0]
|
||||||
|
if conditionValueType == "string" {
|
||||||
|
conditionValue = options[0]
|
||||||
|
} else {
|
||||||
|
if ss := CheckIsDigit(conditionStr); ss != 0 {
|
||||||
|
conditionValue = ss
|
||||||
|
} else {
|
||||||
|
conditionValue = options[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var conditionArrNew []int64
|
||||||
|
conditionArr := strings.Split(options[0], ",")
|
||||||
|
for _, s := range conditionArr {
|
||||||
|
if ss := CheckIsDigit(s); ss != 0 {
|
||||||
|
conditionArrNew = append(conditionArrNew, ss)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(conditionArrNew) > 0 {
|
||||||
|
conditionValue = conditionArrNew
|
||||||
|
} else {
|
||||||
|
conditionValue = conditionArr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch conditionKey {
|
||||||
|
case "LIKE":
|
||||||
|
db = db.Where(fmt.Sprintf("%v LIKE ?", fieldName), fmt.Sprintf("%%%v%%", conditionValue))
|
||||||
|
case "BETWEEN":
|
||||||
|
db = db.Where(fmt.Sprintf("%v BETWEEN ? AND ?", fieldName), conditionValue.([]interface{})[0], conditionValue.([]interface{})[1])
|
||||||
|
default:
|
||||||
|
db = db.Where(fmt.Sprintf("%v %v ?", fieldName, conditionKey), conditionValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return db
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// OrderCheck 公共排序--检测
|
||||||
|
func OrderCheck(orderData string, fields map[string]struct{}) func(db *gorm.DB) *gorm.DB {
|
||||||
|
return func(db *gorm.DB) *gorm.DB {
|
||||||
|
var orderType = "desc"
|
||||||
|
if orderData != "" {
|
||||||
|
var sortData []map[string]interface{}
|
||||||
|
_ = json.Unmarshal([]byte(orderData), &sortData)
|
||||||
|
|
||||||
|
sortCount := len(sortData)
|
||||||
|
for i := 0; i < sortCount; i++ {
|
||||||
|
data := sortData[i]
|
||||||
|
prop, existProp := data["prop"]
|
||||||
|
sort, existSort := data["order"]
|
||||||
|
if existProp && existSort {
|
||||||
|
propData := strings.TrimSpace(prop.(string))
|
||||||
|
sortData := strings.TrimSpace(sort.(string))
|
||||||
|
if propData != "" && sortData != "" {
|
||||||
|
// 判断数据库字段
|
||||||
|
_, existFields := fields[propData]
|
||||||
|
if existFields {
|
||||||
|
if sortData == "descending" || sortData == "desc" {
|
||||||
|
orderType = "desc"
|
||||||
|
} else {
|
||||||
|
orderType = "asc"
|
||||||
|
}
|
||||||
|
db.Order(fmt.Sprintf("%v %v", prop, orderType))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return db
|
||||||
|
} else {
|
||||||
|
return db.Order("id asc")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Paginate 公共分页
|
||||||
|
func Paginate(page *int64, pageSize *int64) func(db *gorm.DB) *gorm.DB {
|
||||||
|
return func(db *gorm.DB) *gorm.DB {
|
||||||
|
page, _ := strconv.Atoi(strconv.FormatInt(*page, 10))
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case page == 0:
|
||||||
|
page = constants.DEFAULT_PAGE
|
||||||
|
case page > constants.MAX_PAGE:
|
||||||
|
page = constants.MAX_PAGE
|
||||||
|
}
|
||||||
|
|
||||||
|
pageSize, _ := strconv.Atoi(strconv.FormatInt(*pageSize, 10))
|
||||||
|
switch {
|
||||||
|
case pageSize > constants.MAX_PAGE_SIZE:
|
||||||
|
pageSize = constants.MAX_PAGE_SIZE
|
||||||
|
case pageSize <= 0:
|
||||||
|
pageSize = constants.DEFAULT_PAGE_SIZE
|
||||||
|
}
|
||||||
|
|
||||||
|
offset := (page - 1) * pageSize
|
||||||
|
return db.Offset(offset).Limit(pageSize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckIsDigit 判断int
|
||||||
|
func CheckIsDigit(s string) int64 {
|
||||||
|
isDigit := true
|
||||||
|
for _, r := range s {
|
||||||
|
if !unicode.IsDigit(r) {
|
||||||
|
isDigit = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if isDigit {
|
||||||
|
ss, _ := strconv.ParseInt(s, 10, 64)
|
||||||
|
return ss
|
||||||
|
} else {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user