From 92b29d8006ecfb75c2187e6bdf8799c56b76dfa0 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Fri, 2 Jun 2023 19:24:58 +0800 Subject: [PATCH 1/8] fix --- constants/domain_render_img.go | 7 + ddl/fs_product_price.sql | 22 + ddl/fs_product_template_v2.sql | 22 + ddl/fs_tags.sql | 16 + model/fscanteentypemodel_gen.go | 12 +- model/fsproductmodel_gen.go | 19 + product.api | 42 +- .../internal/handler/getproductlisthandler.go | 4 +- product/internal/logic/getproductlistlogic.go | 414 +++++++++++++++++- product/internal/types/types.go | 51 ++- utils/auth/auth.go | 4 +- utils/format/price.go | 13 + 12 files changed, 609 insertions(+), 17 deletions(-) create mode 100644 constants/domain_render_img.go create mode 100644 ddl/fs_product_price.sql create mode 100644 ddl/fs_product_template_v2.sql create mode 100644 ddl/fs_tags.sql create mode 100644 utils/format/price.go diff --git a/constants/domain_render_img.go b/constants/domain_render_img.go new file mode 100644 index 00000000..970651c6 --- /dev/null +++ b/constants/domain_render_img.go @@ -0,0 +1,7 @@ +package constants + +// 千人千面windows访问图片的地址 +const DOMAIN_RENDER_IMG_NAME = "https://fusenrenderimg.kayue.cn" + +// 云渲染域名和访问地址 +const DOMAIN_NAME = "https://fusenapi.kayue.cn:8010/" diff --git a/ddl/fs_product_price.sql b/ddl/fs_product_price.sql new file mode 100644 index 00000000..8274e269 --- /dev/null +++ b/ddl/fs_product_price.sql @@ -0,0 +1,22 @@ +-- fusentest.fs_product_price definition + +CREATE TABLE `fs_product_price` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `sn` char(8) NOT NULL COMMENT '唯一编码', + `title` varchar(255) NOT NULL COMMENT '标题描述', + `product_id` int(11) NOT NULL COMMENT '产品ID', + `material_id` int(11) NOT NULL COMMENT '材质ID', + `size_id` int(11) NOT NULL COMMENT '尺寸ID', + `each_box_num` int(11) NOT NULL COMMENT '每一箱的个数', + `each_box_weight` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '每一箱的重量 单位KG', + `min_buy_num` int(11) NOT NULL COMMENT '最少购买量', + `step_num` varchar(255) NOT NULL COMMENT '数量阶梯 eg:10,20,30', + `step_price` varchar(255) NOT NULL COMMENT '价格阶梯 eg:100,50,25', + `status` int(11) DEFAULT '1' COMMENT '是否可用', + `is_default` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否默认', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE KEY `fields_index` (`product_id`,`material_id`,`size_id`) USING BTREE, + KEY `product_id` (`product_id`) USING BTREE, + KEY `material_id` (`material_id`) USING BTREE, + KEY `size_id` (`size_id`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=103 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='阶梯价格表'; \ No newline at end of file diff --git a/ddl/fs_product_template_v2.sql b/ddl/fs_product_template_v2.sql new file mode 100644 index 00000000..8584ddab --- /dev/null +++ b/ddl/fs_product_template_v2.sql @@ -0,0 +1,22 @@ +-- fusentest.fs_product_template_v2 definition + +CREATE TABLE `fs_product_template_v2` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `product_id` int(10) unsigned NOT NULL COMMENT '产品ID', + `model_id` int(11) NOT NULL COMMENT '模型ID', + `title` varchar(255) NOT NULL DEFAULT '' COMMENT '模板(sku),预留字段', + `name` varchar(255) NOT NULL DEFAULT '' COMMENT '名称', + `cover_img` varchar(255) DEFAULT NULL COMMENT '模板背景图', + `template_info` text NOT NULL COMMENT '模板详情', + `material_img` varchar(255) DEFAULT NULL COMMENT '合成好的贴图', + `sort` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT '排序', + `logo_width` int(10) NOT NULL DEFAULT '0' COMMENT 'logo图最大宽度', + `logo_height` int(10) NOT NULL DEFAULT '0' COMMENT 'logo图最大高度', + `is_public` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否可公用(1:可以,0:不可以)', + `status` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '状态1正常 2异常', + `ctime` int(10) unsigned NOT NULL COMMENT '添加时间', + `tag` varchar(255) NOT NULL COMMENT '标签(用户自填)', + `is_del` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否删除 1删除', + PRIMARY KEY (`id`) USING BTREE, + KEY `product_id` (`product_id`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=463 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='产品-模型-模板表'; \ No newline at end of file diff --git a/ddl/fs_tags.sql b/ddl/fs_tags.sql new file mode 100644 index 00000000..4c2896d4 --- /dev/null +++ b/ddl/fs_tags.sql @@ -0,0 +1,16 @@ +-- fusentest.fs_tags definition + +CREATE TABLE `fs_tags` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID', + `title` varchar(32) NOT NULL COMMENT '标题', + `level` int(10) unsigned NOT NULL COMMENT '层级、分类 1 => 二维码分类', + `click_num` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '点击次数', + `sort` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '排序(从大到小)', + `create_at` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间', + `icon` varchar(200) DEFAULT NULL COMMENT '标签图标', + `status` tinyint(3) unsigned NOT NULL DEFAULT '1' COMMENT '状态 1:可用', + `description` varchar(255) NOT NULL DEFAULT '' COMMENT '介绍 Seo', + `recommend_product` varchar(255) DEFAULT NULL COMMENT '推荐产品id例如: 1,3,4,5', + `recommend_product_sort` varchar(255) DEFAULT NULL COMMENT '推荐排序例如:1324', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=40 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='产品分类表'; \ No newline at end of file diff --git a/model/fscanteentypemodel_gen.go b/model/fscanteentypemodel_gen.go index 5ec08874..567ec813 100755 --- a/model/fscanteentypemodel_gen.go +++ b/model/fscanteentypemodel_gen.go @@ -15,8 +15,8 @@ import ( ) var ( - fsCanteenTypeFieldNames = builder.RawFieldNames(&FsCanteenType{}) - fsCanteenTypeRows = strings.Join(fsCanteenTypeFieldNames, ",") + fsCanteenTypeFieldNames = builder.RawFieldNames(&FsCanteenType{}) + fsCanteenTypeRows = strings.Join(fsCanteenTypeFieldNames, ",") // fsCanteenTypeGetTypeRows = strings.Join(stringx.Remove(fsCanteenTypeFieldNames, "`id`", "`name`", "`sort`", "`created_at`", "`status`"), ",") // fsCanteenTypeGetTypeRows = builder.RawFieldNames(&FsGetTypeCanteenType{}) fsCanteenTypeRowsExpectAutoSet = strings.Join(stringx.Remove(fsCanteenTypeFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",") @@ -29,7 +29,7 @@ type ( FindOne(ctx context.Context, id int64) (*FsCanteenType, error) Update(ctx context.Context, data *FsCanteenType) error Delete(ctx context.Context, id int64) error - + FindGetType(ctx context.Context) ([]*FsGetTypeCanteenType, error) } @@ -47,8 +47,8 @@ type ( } FsGetTypeCanteenType struct { - Id int64 `db:"id" json:"key"` // ID - Name string `db:"name" json:"name"` // 餐厅名字 + Id int64 `db:"id" json:"key"` // ID + Name string `db:"name" json:"name"` // 餐厅名字 } ) @@ -80,7 +80,7 @@ func (m *defaultFsCanteenTypeModel) FindOne(ctx context.Context, id int64) (*FsC } func (m *defaultFsCanteenTypeModel) FindGetType(ctx context.Context) ([]*FsGetTypeCanteenType, error) { - + query := fmt.Sprintf("select X.id,X.name from (select %s from %s where status = 1 order by sort desc) X", fsCanteenTypeRows, m.table) var resp []*FsGetTypeCanteenType err := m.conn.QueryRows(&resp, query) diff --git a/model/fsproductmodel_gen.go b/model/fsproductmodel_gen.go index bff1a42e..8f434238 100755 --- a/model/fsproductmodel_gen.go +++ b/model/fsproductmodel_gen.go @@ -28,6 +28,7 @@ type ( FindOneBySn(ctx context.Context, sn string) (*FsProduct, error) Update(ctx context.Context, data *FsProduct) error Delete(ctx context.Context, id int64) error + GetProductListByConditions(ctx context.Context, productType int, isDel int, isShelf int, sort string) ([]FsProduct, error) } defaultFsProductModel struct { @@ -121,6 +122,24 @@ func (m *defaultFsProductModel) Update(ctx context.Context, newData *FsProduct) return err } +func (m *defaultFsProductModel) GetProductListByConditions(ctx context.Context, productType int, isDel int, isShelf int, sort string) (resp []FsProduct, err error) { + query := fmt.Sprintf("select %s from %s where `type` = ? and `is_del` =? and `is_shelf` = ?", + fsProductRows, m.table) + switch sort { + case "sort-asc": + query = fmt.Sprintf("%s order by sort ASC", query) + case "sort-desc": + query = fmt.Sprintf("%s order by sort DESC", query) + default: + query = fmt.Sprintf("%s order by sort DESC", query) + } + err = m.conn.QueryRowsCtx(ctx, &resp, query, productType, isDel, isShelf) + if err != nil { + return nil, err + } + return +} + func (m *defaultFsProductModel) tableName() string { return m.table } diff --git a/product.api b/product.api index fbb01de1..98787a3d 100644 --- a/product.api +++ b/product.api @@ -9,12 +9,50 @@ info ( import "basic.api" type GetProductListReq { // TODO: add members here and delete this comment - Cid uint32 `form:"cid"` + Cid int64 `form:"cid"` Size uint32 `form:"size"` Page uint32 `form:"page"` IsDemo uint32 `form:"is_demo" , options=0|1"` } - +//获取产品列表响应体 +type GetProductListRsp { + Ob Ob `json:"ob"` + TypeName string `json:"typeName"` + Description string `json:"description"` +} +type Ob { + Items []Items `json:"items"` + Links Links `json:"_links"` + Meta Meta `json:"_meta"` +} +type Meta { + TotalCount int32 `json:"totalCount"` + PageCount int32 `json:"pageCount"` + CurrentPage int32 `json:"currentPage"` + PerPage int32 `json:"perPage"` +} +type Links { + Self HrefUrl `json:"self"` + First HrefUrl `json:"first"` + Last HrefUrl `json:"last"` + Next HrefUrl `json:"next"` +} +type HrefUrl { + Href string `json:"href"` +} +type Items { + Id int64 `json:"id"` + Sn string `json:"sn"` + Title string `json:"title"` + Cover string `json:"cover"` + Intro string `json:"intro"` + CoverImg string `json:"cover_img"` + IsEnv uint32 `json:"isEnv"` + IsMicro uint32 `json:"isMicro"` + SizeNum uint32 `json:"sizeNum"` + MiniPrice float64 `json:"miniPrice"` + CoverDefault string `json:"coverDefault"` +} service product { @handler GetProductListHandler get /product/list(GetProductListReq) returns (response); diff --git a/product/internal/handler/getproductlisthandler.go b/product/internal/handler/getproductlisthandler.go index b42aaf5a..44245ea1 100644 --- a/product/internal/handler/getproductlisthandler.go +++ b/product/internal/handler/getproductlisthandler.go @@ -16,13 +16,13 @@ func GetProductListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { userInfo := auth.CheckAuth(r) var req types.GetProductListReq if err := httpx.Parse(r, &req); err != nil { - httpx.ErrorCtx(r.Context(), w, err) + httpx.OkJsonCtx(r.Context(), w, types.Response{Code: 500, Message: err.Error()}) return } l := logic.NewGetProductListLogic(r.Context(), svcCtx) resp, err := l.GetProductList(&req, userInfo) if err != nil { - httpx.ErrorCtx(r.Context(), w, err) + httpx.OkJsonCtx(r.Context(), w, types.Response{Code: 500, Message: err.Error()}) } else { httpx.OkJsonCtx(r.Context(), w, resp) } diff --git a/product/internal/logic/getproductlistlogic.go b/product/internal/logic/getproductlistlogic.go index 4a508910..a75a4bba 100644 --- a/product/internal/logic/getproductlistlogic.go +++ b/product/internal/logic/getproductlistlogic.go @@ -2,11 +2,21 @@ package logic import ( "context" + "encoding/json" + "errors" + "fmt" + "fusenapi/constants" "fusenapi/model" "fusenapi/product/internal/svc" "fusenapi/product/internal/types" "fusenapi/utils/auth" + "fusenapi/utils/format" "fusenapi/utils/image" + "github.com/zeromicro/go-zero/core/stores/sqlx" + "sort" + "strconv" + "strings" + "time" "github.com/zeromicro/go-zero/core/logx" ) @@ -27,22 +37,418 @@ func NewGetProductListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Ge // 获取产品列表 func (l *GetProductListLogic) GetProductList(req *types.GetProductListReq, loginInfo auth.UserInfo) (resp *types.Response, err error) { + loginInfo.UserId = 84 //校验前台登录情况 if loginInfo.UserId == 0 { return &types.Response{Code: 402, Message: "please sign in"}, nil } + //如果是demo + if req.IsDemo == 1 { + var demo types.GetProductListRsp + if err = json.Unmarshal([]byte(l.DemoProductList()), &demo); err != nil { + logx.Error(err) + return &types.Response{Code: 510, Message: "demo data format err"}, nil + } + return &types.Response{Code: 200, Message: "success", Data: demo}, nil + } + if req.Page <= 0 { + req.Page = 1 + } //获取合适尺寸 if req.Size > 0 { req.Size = image.GetCurrentSize(req.Size) } - //获取是否存在千人千面 + //查询用户信息 userModel := model.NewFsUserModel(l.svcCtx.MysqlConn) userInfo, err := userModel.FindOne(l.ctx, loginInfo.UserId) + if err != nil && !errors.Is(err, sqlx.ErrNotFound) { + logx.Error(err) + return &types.Response{Code: 510, Message: "get user info err"}, nil + } + if userInfo == nil { + return &types.Response{Code: 402, Message: "user not exists"}, nil + } + //查询符合的产品列表 + productModel := model.NewFsProductModel(l.svcCtx.MysqlConn) + productList, err := productModel.GetProductListByConditions(l.ctx, int(req.Cid), 0, 1, "sort-desc") if err != nil { - return nil, err + logx.Error(err) + return &types.Response{Code: 510, Message: "failed to get product list"}, nil } - if userInfo.Id == 0 { - return &types.Response{Code: 402, Message: "please sign in"}, nil + fmt.Println(len(productList)) + productLen := len(productList) + if productLen == 0 { + return &types.Response{Code: 200, Message: "success"}, nil } + //提取产品ids + productIds := make([]string, 0, productLen) + for _, v := range productList { + productIds = append(productIds, fmt.Sprintf("%d", v.Id)) + } + productPriceModel := model.NewFsProductPriceModel(l.svcCtx.MysqlConn) + productPriceList, err := productPriceModel.GetPriceList(l.ctx, productIds) + if err != nil { + logx.Error(err) + return &types.Response{Code: 510, Message: "failed to get product min price list"}, nil + } + //存储产品最小价格 + mapProductMinPrice := make(map[int64]int64) + for _, v := range productPriceList { + priceSlic := strings.Split(v.Price, ",") + sort.Strings(priceSlic) + min, err := strconv.ParseInt(priceSlic[0], 10, 64) + if err != nil { + logx.Error(err) + return &types.Response{Code: 510, Message: "parse min product price err"}, nil + } + mapProductMinPrice[v.ProductId] = min + } + //获取模板 + productTemplateModel := model.NewFsProductTemplateV2Model(l.svcCtx.MysqlConn) + productTemplatesV2, err := productTemplateModel.FindAllByCondition(l.ctx, productIds, 0, 1) + if err != nil { + logx.Error(err) + return &types.Response{Code: 510, Message: "get product template_v2 err"}, nil + } + mapProductTemplate := make(map[int64]struct{}) + for _, v := range productTemplatesV2 { + mapProductTemplate[v.ProductId] = struct{}{} + } + //获取分类 + tagsModel := model.NewFsTagsModel(l.svcCtx.MysqlConn) + tagInfo, err := tagsModel.FindOne(l.ctx, req.Cid) + if err != nil && !errors.Is(err, sqlx.ErrNotFound) { + logx.Error(err) + return &types.Response{Code: 510, Message: "get classification err "}, nil + } + if tagInfo == nil { + return &types.Response{Code: 510, Message: "classification not exists "}, nil + } + //拼接返回 + itemList := make([]types.Items, 0, productLen) + for _, v := range productList { + minPrice, ok := mapProductMinPrice[v.Id] + //无最小价格则不显示 + if !ok { + continue + } + _, ok = mapProductTemplate[v.Id] + //没有模板也不显示 + if !ok { + continue + } + item := types.Items{ + Id: v.Id, + Sn: v.Sn, + Title: v.Title, + Cover: v.Cover, + Intro: v.Intro.String, + CoverImg: v.CoverImg, + IsEnv: 1, + IsMicro: 1, + SizeNum: 1, + MiniPrice: format.FentoDollar(minPrice), + } + if req.Size > 0 { + coverSlice := strings.Split(v.Cover, ".") + coverImgSlice := strings.Split(v.CoverImg, ".") + if req.Size >= 200 { + item.Cover = fmt.Sprintf("%s_%d.%s", coverSlice[0], req.Size, coverSlice[1]) + item.CoverImg = fmt.Sprintf("%s_%d.%s", coverImgSlice[0], req.Size, coverImgSlice[1]) + } + //千人千面处理 + if userInfo.IsThousandFace == 1 { + v.Cover = "" + item.CoverDefault = item.CoverImg + if req.Size >= 200 { + item.CoverImg = fmt.Sprintf("%s/test/%d/%d_%d.png?%d", constants.DOMAIN_RENDER_IMG_NAME, userInfo.Id, userInfo.Id, v.Id, time.Now().Unix()) + item.CoverDefault = fmt.Sprintf("%s_%d.%s", coverImgSlice[0], req.Size, coverImgSlice[1]) + } + } + } + itemList = append(itemList, item) + } + return &types.Response{ + Code: 200, + Message: "success", + Data: types.GetProductListRsp{ + Ob: types.Ob{ + Items: itemList, + }, + TypeName: tagInfo.Title, + Description: tagInfo.Description, + }}, nil return } + +// 样本产品列表 +func (l *GetProductListLogic) DemoProductList() string { + return `{ + "ob": { + "items": [ + { + "id": 25, + "sn": "P1ELZGHU", + "title": "Packing box", + "cover": "/icon/icon_25_800.png", + "intro": "打包盒卡纸", + "cover_img": "/uploads/ognhdc6q_800.png", + "isEnv": 1, + "isMicro": 1, + "sizeNum": 5, + "miniPrice": 2 + }, + { + "id": 28, + "sn": "P9KVYAUS", + "title": "Pizza box", + "cover": "/icon/9dmom0g7_800.png", + "intro": "披萨盒 瓦楞纸", + "cover_img": "/uploads/9xf1olkl_800.png", + "isEnv": 1, + "isMicro": 1, + "sizeNum": 1, + "miniPrice": 2 + }, + { + "id": 30, + "sn": "PZWDSROX", + "title": "Paper bag with handle", + "cover": "/icon/iz44vraw_800.png", + "intro": "有提手纸袋牛皮纸", + "cover_img": "/uploads/rpwntxcq_800.png", + "isEnv": 1, + "isMicro": 1, + "sizeNum": 4, + "miniPrice": 2 + }, + { + "id": 20, + "sn": "PNACHNUK", + "title": "Four cups of milk tea cup", + "cover": "/icon/plz43wpo_800.png", + "intro": "卡纸", + "cover_img": "/uploads/9tqgsjqi_800.png", + "isEnv": 1, + "isMicro": 1, + "sizeNum": 2, + "miniPrice": 2 + }, + { + "id": 19, + "sn": "PHHVEXRW", + "title": "Milk tea cup holder double cup", + "cover": "/icon/ipohmmcj_800.png", + "intro": "奶茶杯托奶茶杯托两杯袋", + "cover_img": "/uploads/57ogzeq5_800.png", + "isEnv": 1, + "isMicro": 1, + "sizeNum": 5, + "miniPrice": 2 + }, + { + "id": 11, + "sn": "P7N4D0MK", + "title": "Cup double layer", + "cover": "/icon/nrmzz4du_800.png", + "intro": "牛皮纸双层", + "cover_img": "/uploads/oqjm5own_800.png", + "isEnv": 1, + "isMicro": 1, + "sizeNum": 5, + "miniPrice": 2 + }, + { + "id": 33, + "sn": "P0NFP19Y", + "title": "High paper bowl", + "cover": "/icon/cla4k6om_800.png", + "intro": "牛皮纸", + "cover_img": "/uploads/dt1qjkzg_800.png", + "isEnv": 1, + "isMicro": 1, + "sizeNum": 4, + "miniPrice": 2 + }, + { + "id": 32, + "sn": "PDZ3HIUL", + "title": "Flat paper bowl", + "cover": "/icon/jy14adqz_800.png", + "intro": "牛皮纸", + "cover_img": "/uploads/bzwbxduc_800.png", + "isEnv": 1, + "isMicro": 1, + "sizeNum": 3, + "miniPrice": 2 + }, + { + "id": 31, + "sn": "PEVSMU7I", + "title": "Paper bag without handle", + "cover": "/icon/osdsegor_800.png", + "intro": "牛皮纸", + "cover_img": "/uploads/ouvayny7_800.png", + "isEnv": 1, + "isMicro": 1, + "sizeNum": 2, + "miniPrice": 2 + }, + { + "id": 29, + "sn": "P58ZZOTI", + "title": "plastic bag", + "cover": "/icon/dvsvddks_800.png", + "intro": "塑料袋", + "cover_img": "/uploads/qvvuzkzx_800.png", + "isEnv": 1, + "isMicro": 1, + "sizeNum": 1, + "miniPrice": 2 + }, + { + "id": 24, + "sn": "PG7XIXII", + "title": "Hamburger box", + "cover": "/icon/icon_24_800.png", + "intro": "汉堡盒 卡纸", + "cover_img": "/uploads/fm1itgge_800.png", + "isEnv": 1, + "isMicro": 1, + "sizeNum": 4, + "miniPrice": 2 + }, + { + "id": 23, + "sn": "PIJ2OVUE", + "title": "Milk tea ring portable double cup", + "cover": "/icon/nxb6hjln_800.png", + "intro": "卡纸", + "cover_img": "/uploads/52fash1n_800.png", + "isEnv": 1, + "isMicro": 1, + "sizeNum": 4, + "miniPrice": 2 + }, + { + "id": 21, + "sn": "PMHXGUL6", + "title": "Milk tea ring portable single cup", + "cover": "/icon/qoaf5mtp_800.png", + "intro": "卡纸", + "cover_img": "/uploads/epvkzvyf_800.png", + "isEnv": 1, + "isMicro": 1, + "sizeNum": 5, + "miniPrice": 2 + }, + { + "id": 18, + "sn": "PFCM8KNF", + "title": "Tableware set chopsticks", + "cover": "/icon/tcspod4b_800.png", + "intro": "餐具套装筷子厚牛皮纸包装", + "cover_img": "/uploads/5jgrgzvh_800.png", + "isEnv": 1, + "isMicro": 1, + "sizeNum": 3, + "miniPrice": 2 + }, + { + "id": 17, + "sn": "PQKIQMIK", + "title": "Tableware set four piece set", + "cover": "/icon/mdo0vu1u_800.png", + "intro": "牛皮纸包装", + "cover_img": "/uploads/szsekvbw_800.png", + "isEnv": 1, + "isMicro": 1, + "sizeNum": 4, + "miniPrice": 2 + }, + { + "id": 16, + "sn": "PBFOIOFH", + "title": "Tableware set four piece set", + "cover": "/icon/dzrf59cp_800.png", + "intro": "餐具套装", + "cover_img": "/uploads/svfoebf1_800.png", + "isEnv": 1, + "isMicro": 1, + "sizeNum": 1, + "miniPrice": 2 + }, + { + "id": 15, + "sn": "P02V10AB", + "title": " Hot drink cup holder", + "cover": "/icon/icon_15_800.png", + "intro": "杯托、瓦楞纸", + "cover_img": "/uploads/4qbdid7i_800.png", + "isEnv": 1, + "isMicro": 1, + "sizeNum": 5, + "miniPrice": 2 + }, + { + "id": 13, + "sn": "PER6WLAV", + "title": " Cup pet", + "cover": "/icon/icon_13_800.png", + "intro": "pet", + "cover_img": "/uploads/kfxehwjd_800.png", + "isEnv": 1, + "isMicro": 1, + "sizeNum": 1, + "miniPrice": 2 + }, + { + "id": 12, + "sn": "PGFWRMAU", + "title": " Cup PP", + "cover": "/icon/icon_12_800.png", + "intro": "pp", + "cover_img": "/uploads/azp8uwhz_800.png", + "isEnv": 1, + "isMicro": 1, + "sizeNum": 2, + "miniPrice": 2 + }, + { + "id": 10, + "sn": "P4ZXDVHS", + "title": "Cup monolayer", + "cover": "/icon/icon_10_800.png", + "intro": "牛皮纸单层", + "cover_img": "/uploads/onuzax6l_800.png", + "isEnv": 1, + "isMicro": 1, + "sizeNum": 1, + "miniPrice": 2 + } + ], + "_links": { + "self": { + "href": "https://fusenapi.kayue.cn:8010/product/list?cid=13&size=620&page=1&is_demo=1" + }, + "first": { + "href": "https://fusenapi.kayue.cn:8010/product/list?cid=13&size=620&page=1&is_demo=1" + }, + "last": { + "href": "https://fusenapi.kayue.cn:8010/product/list?cid=13&size=620&page=2&is_demo=1" + }, + "next": { + "href": "https://fusenapi.kayue.cn:8010/product/list?cid=13&size=620&page=2&is_demo=1" + } + }, + "_meta": { + "totalCount": 21, + "pageCount": 2, + "currentPage": 1, + "perPage": 20 + } + }, + "typeName": "Boxes", + "description": "" + }` +} diff --git a/product/internal/types/types.go b/product/internal/types/types.go index a94c8c07..8ec91a11 100644 --- a/product/internal/types/types.go +++ b/product/internal/types/types.go @@ -2,14 +2,63 @@ package types type GetProductListReq struct { - Cid uint32 `form:"cid"` + Cid int64 `form:"cid"` Size uint32 `form:"size"` Page uint32 `form:"page"` IsDemo uint32 `form:"is_demo" , options=0|1"` } +type GetProductListRsp struct { + Ob Ob `json:"ob"` + TypeName string `json:"typeName"` + Description string `json:"description"` +} + +type Ob struct { + Items []Items `json:"items"` + Links Links `json:"_links"` + Meta Meta `json:"_meta"` +} + +type Meta struct { + TotalCount int32 `json:"totalCount"` + PageCount int32 `json:"pageCount"` + CurrentPage int32 `json:"currentPage"` + PerPage int32 `json:"perPage"` +} + +type Links struct { + Self HrefUrl `json:"self"` + First HrefUrl `json:"first"` + Last HrefUrl `json:"last"` + Next HrefUrl `json:"next"` +} + +type HrefUrl struct { + Href string `json:"href"` +} + +type Items struct { + Id int64 `json:"id"` + Sn string `json:"sn"` + Title string `json:"title"` + Cover string `json:"cover"` + Intro string `json:"intro"` + CoverImg string `json:"cover_img"` + IsEnv uint32 `json:"isEnv"` + IsMicro uint32 `json:"isMicro"` + SizeNum uint32 `json:"sizeNum"` + MiniPrice float64 `json:"miniPrice"` + CoverDefault string `json:"coverDefault"` +} + type Response struct { Code int `json:"code"` Message string `json:"msg"` Data interface{} `json:"data"` } + +type Auth struct { + AccessSecret string `json:"AccessSecret"` + AccessExpire int `json:"AccessExpire"` +} diff --git a/utils/auth/auth.go b/utils/auth/auth.go index c219c106..c0862552 100644 --- a/utils/auth/auth.go +++ b/utils/auth/auth.go @@ -58,13 +58,13 @@ func CheckAuth(r *http.Request) UserInfo { token = r.Header.Get("Auth-Key") } if token == "" { - logx.Debug("token is empty") + logx.Error("token is empty") return UserInfo{} } //解析token userInfo, err := ParseJwtToken(token) if err != nil { - logx.Debug(err) + logx.Error(err) return UserInfo{} } return userInfo diff --git a/utils/format/price.go b/utils/format/price.go new file mode 100644 index 00000000..4a6e455a --- /dev/null +++ b/utils/format/price.go @@ -0,0 +1,13 @@ +package format + +import ( + "fmt" + "strconv" +) + +// 美分转美元 +func FentoDollar(price int64) float64 { + str := fmt.Sprintf("%.2f", float64(price)/float64(100)) + dollar, _ := strconv.ParseFloat(str, 64) + return dollar +} From 94212b1003712273171af34fe7b65f542c2ee054 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Mon, 5 Jun 2023 10:18:31 +0800 Subject: [PATCH 2/8] finish product list api --- product/internal/logic/getproductlistlogic.go | 14 +++++++------ utils/format/str_to_int_slice.go | 21 +++++++++++++++++++ 2 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 utils/format/str_to_int_slice.go diff --git a/product/internal/logic/getproductlistlogic.go b/product/internal/logic/getproductlistlogic.go index a75a4bba..83f81ce0 100644 --- a/product/internal/logic/getproductlistlogic.go +++ b/product/internal/logic/getproductlistlogic.go @@ -14,7 +14,6 @@ import ( "fusenapi/utils/image" "github.com/zeromicro/go-zero/core/stores/sqlx" "sort" - "strconv" "strings" "time" @@ -94,14 +93,17 @@ func (l *GetProductListLogic) GetProductList(req *types.GetProductListReq, login //存储产品最小价格 mapProductMinPrice := make(map[int64]int64) for _, v := range productPriceList { - priceSlic := strings.Split(v.Price, ",") - sort.Strings(priceSlic) - min, err := strconv.ParseInt(priceSlic[0], 10, 64) + priceStrSlic := strings.Split(v.Price, ",") + priceSlice, err := format.StrSlicToIntSlice(priceStrSlic) if err != nil { logx.Error(err) - return &types.Response{Code: 510, Message: "parse min product price err"}, nil + return &types.Response{Code: 510, Message: err.Error()}, nil } - mapProductMinPrice[v.ProductId] = min + if len(priceSlice) == 0 { + continue + } + sort.Ints(priceSlice) + mapProductMinPrice[v.ProductId] = int64(priceSlice[0]) } //获取模板 productTemplateModel := model.NewFsProductTemplateV2Model(l.svcCtx.MysqlConn) diff --git a/utils/format/str_to_int_slice.go b/utils/format/str_to_int_slice.go new file mode 100644 index 00000000..e6f28713 --- /dev/null +++ b/utils/format/str_to_int_slice.go @@ -0,0 +1,21 @@ +package format + +import ( + "strconv" +) + +// 字符串切片转int切片 +func StrSlicToIntSlice(input []string) ([]int, error) { + priceSlic := make([]int, 0, len(input)) + for _, p := range input { + if p == "" { + continue + } + price, err := strconv.Atoi(p) + if err != nil { + return nil, err + } + priceSlic = append(priceSlic, price) + } + return priceSlic, nil +} From a933f0d763daee61788b06345d85d0b06af92e97 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Mon, 5 Jun 2023 10:26:25 +0800 Subject: [PATCH 3/8] fix --- model/fsproductpricemodel.go | 24 +++++ model/fsproductpricemodel_gen.go | 123 ++++++++++++++++++++++++++ model/fsproducttemplatev2model.go | 24 +++++ model/fsproducttemplatev2model_gen.go | 105 ++++++++++++++++++++++ model/fstagsmodel.go | 24 +++++ model/fstagsmodel_gen.go | 93 +++++++++++++++++++ 6 files changed, 393 insertions(+) create mode 100755 model/fsproductpricemodel.go create mode 100755 model/fsproductpricemodel_gen.go create mode 100755 model/fsproducttemplatev2model.go create mode 100755 model/fsproducttemplatev2model_gen.go create mode 100755 model/fstagsmodel.go create mode 100755 model/fstagsmodel_gen.go diff --git a/model/fsproductpricemodel.go b/model/fsproductpricemodel.go new file mode 100755 index 00000000..ef9c3d64 --- /dev/null +++ b/model/fsproductpricemodel.go @@ -0,0 +1,24 @@ +package model + +import "github.com/zeromicro/go-zero/core/stores/sqlx" + +var _ FsProductPriceModel = (*customFsProductPriceModel)(nil) + +type ( + // FsProductPriceModel is an interface to be customized, add more methods here, + // and implement the added methods in customFsProductPriceModel. + FsProductPriceModel interface { + fsProductPriceModel + } + + customFsProductPriceModel struct { + *defaultFsProductPriceModel + } +) + +// NewFsProductPriceModel returns a model for the database table. +func NewFsProductPriceModel(conn sqlx.SqlConn) FsProductPriceModel { + return &customFsProductPriceModel{ + defaultFsProductPriceModel: newFsProductPriceModel(conn), + } +} diff --git a/model/fsproductpricemodel_gen.go b/model/fsproductpricemodel_gen.go new file mode 100755 index 00000000..f95facf8 --- /dev/null +++ b/model/fsproductpricemodel_gen.go @@ -0,0 +1,123 @@ +// Code generated by goctl. DO NOT EDIT. + +package model + +import ( + "context" + "database/sql" + "fmt" + "strings" + + "github.com/zeromicro/go-zero/core/stores/builder" + "github.com/zeromicro/go-zero/core/stores/sqlc" + "github.com/zeromicro/go-zero/core/stores/sqlx" + "github.com/zeromicro/go-zero/core/stringx" +) + +var ( + fsProductPriceFieldNames = builder.RawFieldNames(&FsProductPrice{}) + fsProductPriceRows = strings.Join(fsProductPriceFieldNames, ",") + fsProductPriceRowsExpectAutoSet = strings.Join(stringx.Remove(fsProductPriceFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",") + fsProductPriceRowsWithPlaceHolder = strings.Join(stringx.Remove(fsProductPriceFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?" +) + +type ( + fsProductPriceModel interface { + Insert(ctx context.Context, data *FsProductPrice) (sql.Result, error) + FindOne(ctx context.Context, id int64) (*FsProductPrice, error) + FindOneByProductIdMaterialIdSizeId(ctx context.Context, productId int64, materialId int64, sizeId int64) (*FsProductPrice, error) + Update(ctx context.Context, data *FsProductPrice) error + Delete(ctx context.Context, id int64) error + GetPriceList(ctx context.Context, productIds []string) ([]GetPriceListRsp, error) + } + + defaultFsProductPriceModel struct { + conn sqlx.SqlConn + table string + } + + FsProductPrice struct { + Id int64 `db:"id"` + Sn string `db:"sn"` // 唯一编码 + Title string `db:"title"` // 标题描述 + ProductId int64 `db:"product_id"` // 产品ID + MaterialId int64 `db:"material_id"` // 材质ID + SizeId int64 `db:"size_id"` // 尺寸ID + EachBoxNum int64 `db:"each_box_num"` // 每一箱的个数 + EachBoxWeight float64 `db:"each_box_weight"` // 每一箱的重量 单位KG + MinBuyNum int64 `db:"min_buy_num"` // 最少购买量 + StepNum string `db:"step_num"` // 数量阶梯 eg:10,20,30 + StepPrice string `db:"step_price"` // 价格阶梯 eg:100,50,25 + Status int64 `db:"status"` // 是否可用 + IsDefault int64 `db:"is_default"` // 是否默认 + } +) + +func newFsProductPriceModel(conn sqlx.SqlConn) *defaultFsProductPriceModel { + return &defaultFsProductPriceModel{ + conn: conn, + table: "`fs_product_price`", + } +} + +func (m *defaultFsProductPriceModel) Delete(ctx context.Context, id int64) error { + query := fmt.Sprintf("delete from %s where `id` = ?", m.table) + _, err := m.conn.ExecCtx(ctx, query, id) + return err +} + +func (m *defaultFsProductPriceModel) FindOne(ctx context.Context, id int64) (*FsProductPrice, error) { + query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", fsProductPriceRows, m.table) + var resp FsProductPrice + err := m.conn.QueryRowCtx(ctx, &resp, query, id) + switch err { + case nil: + return &resp, nil + case sqlc.ErrNotFound: + return nil, ErrNotFound + default: + return nil, err + } +} + +func (m *defaultFsProductPriceModel) FindOneByProductIdMaterialIdSizeId(ctx context.Context, productId int64, materialId int64, sizeId int64) (*FsProductPrice, error) { + var resp FsProductPrice + query := fmt.Sprintf("select %s from %s where `product_id` = ? and `material_id` = ? and `size_id` = ? limit 1", fsProductPriceRows, m.table) + err := m.conn.QueryRowCtx(ctx, &resp, query, productId, materialId, sizeId) + switch err { + case nil: + return &resp, nil + case sqlc.ErrNotFound: + return nil, ErrNotFound + default: + return nil, err + } +} + +func (m *defaultFsProductPriceModel) Insert(ctx context.Context, data *FsProductPrice) (sql.Result, error) { + query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, fsProductPriceRowsExpectAutoSet) + ret, err := m.conn.ExecCtx(ctx, query, data.Sn, data.Title, data.ProductId, data.MaterialId, data.SizeId, data.EachBoxNum, data.EachBoxWeight, data.MinBuyNum, data.StepNum, data.StepPrice, data.Status, data.IsDefault) + return ret, err +} + +func (m *defaultFsProductPriceModel) Update(ctx context.Context, newData *FsProductPrice) error { + query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, fsProductPriceRowsWithPlaceHolder) + _, err := m.conn.ExecCtx(ctx, query, newData.Sn, newData.Title, newData.ProductId, newData.MaterialId, newData.SizeId, newData.EachBoxNum, newData.EachBoxWeight, newData.MinBuyNum, newData.StepNum, newData.StepPrice, newData.Status, newData.IsDefault, newData.Id) + return err +} + +type GetPriceListRsp struct { + ProductId int64 `json:"product_id"` + Price string `json:"price"` +} + +func (m *defaultFsProductPriceModel) GetPriceList(ctx context.Context, productIds []string) (resp []GetPriceListRsp, err error) { + query := fmt.Sprintf("select %s from %s where `product_id` in (?) and `status` = ? group by product_id", "product_id,group_concat(step_price) as price ", m.table) + if err = m.conn.QueryRowsCtx(ctx, &resp, query, strings.Join(productIds, ","), 1); err != nil { + return nil, err + } + return +} +func (m *defaultFsProductPriceModel) tableName() string { + return m.table +} diff --git a/model/fsproducttemplatev2model.go b/model/fsproducttemplatev2model.go new file mode 100755 index 00000000..6315c103 --- /dev/null +++ b/model/fsproducttemplatev2model.go @@ -0,0 +1,24 @@ +package model + +import "github.com/zeromicro/go-zero/core/stores/sqlx" + +var _ FsProductTemplateV2Model = (*customFsProductTemplateV2Model)(nil) + +type ( + // FsProductTemplateV2Model is an interface to be customized, add more methods here, + // and implement the added methods in customFsProductTemplateV2Model. + FsProductTemplateV2Model interface { + fsProductTemplateV2Model + } + + customFsProductTemplateV2Model struct { + *defaultFsProductTemplateV2Model + } +) + +// NewFsProductTemplateV2Model returns a model for the database table. +func NewFsProductTemplateV2Model(conn sqlx.SqlConn) FsProductTemplateV2Model { + return &customFsProductTemplateV2Model{ + defaultFsProductTemplateV2Model: newFsProductTemplateV2Model(conn), + } +} diff --git a/model/fsproducttemplatev2model_gen.go b/model/fsproducttemplatev2model_gen.go new file mode 100755 index 00000000..c6b7752a --- /dev/null +++ b/model/fsproducttemplatev2model_gen.go @@ -0,0 +1,105 @@ +// Code generated by goctl. DO NOT EDIT. + +package model + +import ( + "context" + "database/sql" + "fmt" + "strings" + + "github.com/zeromicro/go-zero/core/stores/builder" + "github.com/zeromicro/go-zero/core/stores/sqlc" + "github.com/zeromicro/go-zero/core/stores/sqlx" + "github.com/zeromicro/go-zero/core/stringx" +) + +var ( + fsProductTemplateV2FieldNames = builder.RawFieldNames(&FsProductTemplateV2{}) + fsProductTemplateV2Rows = strings.Join(fsProductTemplateV2FieldNames, ",") + fsProductTemplateV2RowsExpectAutoSet = strings.Join(stringx.Remove(fsProductTemplateV2FieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",") + fsProductTemplateV2RowsWithPlaceHolder = strings.Join(stringx.Remove(fsProductTemplateV2FieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?" +) + +type ( + fsProductTemplateV2Model interface { + Insert(ctx context.Context, data *FsProductTemplateV2) (sql.Result, error) + FindOne(ctx context.Context, id int64) (*FsProductTemplateV2, error) + Update(ctx context.Context, data *FsProductTemplateV2) error + Delete(ctx context.Context, id int64) error + FindAllByCondition(ctx context.Context, productIds []string, isDel int, status int) ([]FsProductTemplateV2, error) + } + + defaultFsProductTemplateV2Model struct { + conn sqlx.SqlConn + table string + } + + FsProductTemplateV2 struct { + Id int64 `db:"id"` + ProductId int64 `db:"product_id"` // 产品ID + ModelId int64 `db:"model_id"` // 模型ID + Title string `db:"title"` // 模板(sku),预留字段 + Name string `db:"name"` // 名称 + CoverImg sql.NullString `db:"cover_img"` // 模板背景图 + TemplateInfo string `db:"template_info"` // 模板详情 + MaterialImg sql.NullString `db:"material_img"` // 合成好的贴图 + Sort int64 `db:"sort"` // 排序 + LogoWidth int64 `db:"logo_width"` // logo图最大宽度 + LogoHeight int64 `db:"logo_height"` // logo图最大高度 + IsPublic int64 `db:"is_public"` // 是否可公用(1:可以,0:不可以) + Status int64 `db:"status"` // 状态1正常 2异常 + Ctime int64 `db:"ctime"` // 添加时间 + Tag string `db:"tag"` // 标签(用户自填) + IsDel int64 `db:"is_del"` // 是否删除 1删除 + } +) + +func newFsProductTemplateV2Model(conn sqlx.SqlConn) *defaultFsProductTemplateV2Model { + return &defaultFsProductTemplateV2Model{ + conn: conn, + table: "`fs_product_template_v2`", + } +} + +func (m *defaultFsProductTemplateV2Model) Delete(ctx context.Context, id int64) error { + query := fmt.Sprintf("delete from %s where `id` = ?", m.table) + _, err := m.conn.ExecCtx(ctx, query, id) + return err +} + +func (m *defaultFsProductTemplateV2Model) FindOne(ctx context.Context, id int64) (*FsProductTemplateV2, error) { + query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", fsProductTemplateV2Rows, m.table) + var resp FsProductTemplateV2 + err := m.conn.QueryRowCtx(ctx, &resp, query, id) + switch err { + case nil: + return &resp, nil + case sqlc.ErrNotFound: + return nil, ErrNotFound + default: + return nil, err + } +} + +func (m *defaultFsProductTemplateV2Model) Insert(ctx context.Context, data *FsProductTemplateV2) (sql.Result, error) { + query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, fsProductTemplateV2RowsExpectAutoSet) + ret, err := m.conn.ExecCtx(ctx, query, data.ProductId, data.ModelId, data.Title, data.Name, data.CoverImg, data.TemplateInfo, data.MaterialImg, data.Sort, data.LogoWidth, data.LogoHeight, data.IsPublic, data.Status, data.Ctime, data.Tag, data.IsDel) + return ret, err +} + +func (m *defaultFsProductTemplateV2Model) Update(ctx context.Context, data *FsProductTemplateV2) error { + query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, fsProductTemplateV2RowsWithPlaceHolder) + _, err := m.conn.ExecCtx(ctx, query, data.ProductId, data.ModelId, data.Title, data.Name, data.CoverImg, data.TemplateInfo, data.MaterialImg, data.Sort, data.LogoWidth, data.LogoHeight, data.IsPublic, data.Status, data.Ctime, data.Tag, data.IsDel, data.Id) + return err +} +func (m *defaultFsProductTemplateV2Model) FindAllByCondition(ctx context.Context, productIds []string, isDel int, status int) (resp []FsProductTemplateV2, err error) { + query := fmt.Sprintf("select %s from %s where `id` in (?) and `is_del` = ? and `status` = ?", fsProductTemplateV2Rows, m.table) + if err = m.conn.QueryRowsCtx(ctx, &resp, query, strings.Join(productIds, ","), isDel, status); err != nil { + return nil, err + } + return +} +func (m *defaultFsProductTemplateV2Model) tableName() string { + return m.table +} diff --git a/model/fstagsmodel.go b/model/fstagsmodel.go new file mode 100755 index 00000000..09704cdc --- /dev/null +++ b/model/fstagsmodel.go @@ -0,0 +1,24 @@ +package model + +import "github.com/zeromicro/go-zero/core/stores/sqlx" + +var _ FsTagsModel = (*customFsTagsModel)(nil) + +type ( + // FsTagsModel is an interface to be customized, add more methods here, + // and implement the added methods in customFsTagsModel. + FsTagsModel interface { + fsTagsModel + } + + customFsTagsModel struct { + *defaultFsTagsModel + } +) + +// NewFsTagsModel returns a model for the database table. +func NewFsTagsModel(conn sqlx.SqlConn) FsTagsModel { + return &customFsTagsModel{ + defaultFsTagsModel: newFsTagsModel(conn), + } +} diff --git a/model/fstagsmodel_gen.go b/model/fstagsmodel_gen.go new file mode 100755 index 00000000..7f3e7455 --- /dev/null +++ b/model/fstagsmodel_gen.go @@ -0,0 +1,93 @@ +// Code generated by goctl. DO NOT EDIT. + +package model + +import ( + "context" + "database/sql" + "fmt" + "strings" + + "github.com/zeromicro/go-zero/core/stores/builder" + "github.com/zeromicro/go-zero/core/stores/sqlc" + "github.com/zeromicro/go-zero/core/stores/sqlx" + "github.com/zeromicro/go-zero/core/stringx" +) + +var ( + fsTagsFieldNames = builder.RawFieldNames(&FsTags{}) + fsTagsRows = strings.Join(fsTagsFieldNames, ",") + fsTagsRowsExpectAutoSet = strings.Join(stringx.Remove(fsTagsFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",") + fsTagsRowsWithPlaceHolder = strings.Join(stringx.Remove(fsTagsFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?" +) + +type ( + fsTagsModel interface { + Insert(ctx context.Context, data *FsTags) (sql.Result, error) + FindOne(ctx context.Context, id int64) (*FsTags, error) + Update(ctx context.Context, data *FsTags) error + Delete(ctx context.Context, id int64) error + } + + defaultFsTagsModel struct { + conn sqlx.SqlConn + table string + } + + FsTags struct { + Id int64 `db:"id"` // ID + Title string `db:"title"` // 标题 + Level int64 `db:"level"` // 层级、分类 1 => 二维码分类 + ClickNum int64 `db:"click_num"` // 点击次数 + Sort int64 `db:"sort"` // 排序(从大到小) + CreateAt int64 `db:"create_at"` // 创建时间 + Icon sql.NullString `db:"icon"` // 标签图标 + Status int64 `db:"status"` // 状态 1:可用 + Description string `db:"description"` // 介绍 Seo + RecommendProduct sql.NullString `db:"recommend_product"` // 推荐产品id例如: 1,3,4,5 + RecommendProductSort sql.NullString `db:"recommend_product_sort"` // 推荐排序例如:1324 + } +) + +func newFsTagsModel(conn sqlx.SqlConn) *defaultFsTagsModel { + return &defaultFsTagsModel{ + conn: conn, + table: "`fs_tags`", + } +} + +func (m *defaultFsTagsModel) Delete(ctx context.Context, id int64) error { + query := fmt.Sprintf("delete from %s where `id` = ?", m.table) + _, err := m.conn.ExecCtx(ctx, query, id) + return err +} + +func (m *defaultFsTagsModel) FindOne(ctx context.Context, id int64) (*FsTags, error) { + query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", fsTagsRows, m.table) + var resp FsTags + err := m.conn.QueryRowCtx(ctx, &resp, query, id) + switch err { + case nil: + return &resp, nil + case sqlc.ErrNotFound: + return nil, ErrNotFound + default: + return nil, err + } +} + +func (m *defaultFsTagsModel) Insert(ctx context.Context, data *FsTags) (sql.Result, error) { + query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, fsTagsRowsExpectAutoSet) + ret, err := m.conn.ExecCtx(ctx, query, data.Title, data.Level, data.ClickNum, data.Sort, data.Icon, data.Status, data.Description, data.RecommendProduct, data.RecommendProductSort) + return ret, err +} + +func (m *defaultFsTagsModel) Update(ctx context.Context, data *FsTags) error { + query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, fsTagsRowsWithPlaceHolder) + _, err := m.conn.ExecCtx(ctx, query, data.Title, data.Level, data.ClickNum, data.Sort, data.Icon, data.Status, data.Description, data.RecommendProduct, data.RecommendProductSort, data.Id) + return err +} + +func (m *defaultFsTagsModel) tableName() string { + return m.table +} From f7e7e2d85c51551b91a09a080a3ad3f272e01812 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Mon, 5 Jun 2023 11:27:01 +0800 Subject: [PATCH 4/8] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=BA=A7=E5=93=81?= =?UTF-8?q?=E8=AF=A6=E6=83=85api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- product.api | 106 +++++++++++++++++- .../internal/handler/getproductinfohandler.go | 31 +++++ product/internal/handler/routes.go | 5 + product/internal/logic/getproductinfologic.go | 33 ++++++ product/internal/logic/getproductlistlogic.go | 1 - product/internal/types/types.go | 102 +++++++++++++++++ 6 files changed, 273 insertions(+), 5 deletions(-) create mode 100644 product/internal/handler/getproductinfohandler.go create mode 100644 product/internal/logic/getproductinfologic.go diff --git a/product.api b/product.api index 98787a3d..d5bc11c8 100644 --- a/product.api +++ b/product.api @@ -7,6 +7,17 @@ info ( email: "" ) import "basic.api" + +service product { + //获取产品列表 + @handler GetProductListHandler + get /product/list(GetProductListReq) returns (response); + //获取产品详情信息 + @handler GetProductInfoHandler + get /product/info(GetProductInfoReq) returns (response); +} + +//获取产品列表 type GetProductListReq { // TODO: add members here and delete this comment Cid int64 `form:"cid"` @@ -14,7 +25,6 @@ type GetProductListReq { Page uint32 `form:"page"` IsDemo uint32 `form:"is_demo" , options=0|1"` } -//获取产品列表响应体 type GetProductListRsp { Ob Ob `json:"ob"` TypeName string `json:"typeName"` @@ -53,7 +63,95 @@ type Items { MiniPrice float64 `json:"miniPrice"` CoverDefault string `json:"coverDefault"` } -service product { - @handler GetProductListHandler - get /product/list(GetProductListReq) returns (response); +//获取产品详情 +type GetProductInfoReq { + Pid string `json:"pid"` //sn + Size uint32 `json:"size"` //图片尺寸 + ClientNo string `json:"clientNo"` //页面标识 + HaveCloudRendering bool `json:"haveCloudRendering"` //是否显示云渲染开关 +} +type GetProductInfoRsp { + Id int64 `json:"id"` + Type int32 `json:"type"` + Title string `json:"title"` + IsEnv uint32 `json:"isEnv"` + IsMicro uint32 `json:"isMicro"` + Materials []Materials `json:"materials"` + Sizes []Sizes `json:"sizes"` + TypeName string `json:"typeName"` + Templates Templates `json:"templates"` +} + +type Materials { + Id int64 `json:"id"` + Title string `json:"title"` +} +type Sizes { + Id int64 `json:"id"` + Title SizeTitle `json:"title"` + Capacity string `json:"capacity"` + Cover string `json:"cover"` +} +type SizeTitle { + Cm string `json:"cm"` + Inth string `json:"inth"` +} +type Templates { + Ob484 []Ob484 `json:"4_84"` +} +type Ob484 { + Id int64 `json:"id"` + Title string `json:"title"` + TemplateData TemplateData `json:"templateData"` +} +type TemplateData { + Id int64 `json:"id"` + Cover string `json:"cover"` + Material string `json:"material"` + MaterialList []Material `json:"materialList"` +} +type Material { + Id int64 `json:"id"` + Tag string `json:"tag"` + Title string `json:"title"` + Type string `json:"type"` + Text string `json:"text"` + Fill string `json:"fill"` + FontSize int `json:"fontSize"` + FontFamily string `json:"fontFamily"` + IfBr bool `json:"ifBr"` + IfShow bool `json:"ifShow"` + IfGroup bool `json:"ifGroup"` + MaxNum int `json:"maxNum"` + Rotation int `json:"rotation"` + Align string `json:"align"` + VerticalAlign string `json:"verticalAlign"` + Material string `json:"material"` + QRcodeType string `json:"qRcodeType"` + Width int `json:"width"` + Height int `json:"height"` + X int `json:"x"` + Y int `json:"y"` + Opacity int `json:"opacity"` + OptionalColor []OptionalColor `json:"optionalColor"` + ZIndex int `json:"zIndex"` + SvgPath string `json:"svgPath"` + Follow Follow `json:"follow"` + Group []string `json:"group"` + CameraStand CameraStand `json:"cameraStand"` +} +type CameraStand { + X int `json:"x"` + Y int `json:"y"` + Z int `json:"z"` +} +type Follow { + Fill string `json:"fill"` + IfShow string `json:"ifShow"` + Content string `json:"content"` +} +type OptionalColor { + Color string `json:"color"` + Name string `json:"name"` + Default string `json:"default"` } \ No newline at end of file diff --git a/product/internal/handler/getproductinfohandler.go b/product/internal/handler/getproductinfohandler.go new file mode 100644 index 00000000..5bcbae0a --- /dev/null +++ b/product/internal/handler/getproductinfohandler.go @@ -0,0 +1,31 @@ +package handler + +import ( + "fusenapi/utils/auth" + "net/http" + + "fusenapi/product/internal/logic" + "fusenapi/product/internal/svc" + "fusenapi/product/internal/types" + "github.com/zeromicro/go-zero/rest/httpx" +) + +func GetProductInfoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + //检测登录权限 + userInfo := auth.CheckAuth(r) + var req types.GetProductInfoReq + if err := httpx.Parse(r, &req); err != nil { + httpx.ErrorCtx(r.Context(), w, err) + return + } + + l := logic.NewGetProductInfoLogic(r.Context(), svcCtx) + resp, err := l.GetProductInfo(&req, userInfo) + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, resp) + } + } +} diff --git a/product/internal/handler/routes.go b/product/internal/handler/routes.go index 18f67cbc..278cd1ef 100644 --- a/product/internal/handler/routes.go +++ b/product/internal/handler/routes.go @@ -17,6 +17,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { Path: "/product/list", Handler: GetProductListHandler(serverCtx), }, + { + Method: http.MethodGet, + Path: "/product/info", + Handler: GetProductInfoHandler(serverCtx), + }, }, ) } diff --git a/product/internal/logic/getproductinfologic.go b/product/internal/logic/getproductinfologic.go new file mode 100644 index 00000000..ef8a4c67 --- /dev/null +++ b/product/internal/logic/getproductinfologic.go @@ -0,0 +1,33 @@ +package logic + +import ( + "context" + "fusenapi/utils/auth" + + "fusenapi/product/internal/svc" + "fusenapi/product/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type GetProductInfoLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewGetProductInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetProductInfoLogic { + return &GetProductInfoLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *GetProductInfoLogic) GetProductInfo(req *types.GetProductInfoReq, loginInfo auth.UserInfo) (resp *types.Response, err error) { + //校验前台登录情况 + if loginInfo.UserId == 0 { + return &types.Response{Code: 402, Message: "please sign in"}, nil + } + return +} diff --git a/product/internal/logic/getproductlistlogic.go b/product/internal/logic/getproductlistlogic.go index 83f81ce0..9bb2081d 100644 --- a/product/internal/logic/getproductlistlogic.go +++ b/product/internal/logic/getproductlistlogic.go @@ -36,7 +36,6 @@ func NewGetProductListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Ge // 获取产品列表 func (l *GetProductListLogic) GetProductList(req *types.GetProductListReq, loginInfo auth.UserInfo) (resp *types.Response, err error) { - loginInfo.UserId = 84 //校验前台登录情况 if loginInfo.UserId == 0 { return &types.Response{Code: 402, Message: "please sign in"}, nil diff --git a/product/internal/types/types.go b/product/internal/types/types.go index 8ec91a11..6a7d556f 100644 --- a/product/internal/types/types.go +++ b/product/internal/types/types.go @@ -52,6 +52,108 @@ type Items struct { CoverDefault string `json:"coverDefault"` } +type GetProductInfoReq struct { + Pid string `json:"pid"` //sn + Size uint32 `json:"size"` //图片尺寸 + ClientNo string `json:"clientNo"` //页面标识 + HaveCloudRendering bool `json:"haveCloudRendering"` //是否显示云渲染开关 +} + +type GetProductInfoRsp struct { + Id int64 `json:"id"` + Type int32 `json:"type"` + Title string `json:"title"` + IsEnv uint32 `json:"isEnv"` + IsMicro uint32 `json:"isMicro"` + Materials []Materials `json:"materials"` + Sizes []Sizes `json:"sizes"` + TypeName string `json:"typeName"` + Templates Templates `json:"templates"` +} + +type Materials struct { + Id int64 `json:"id"` + Title string `json:"title"` +} + +type Sizes struct { + Id int64 `json:"id"` + Title SizeTitle `json:"title"` + Capacity string `json:"capacity"` + Cover string `json:"cover"` +} + +type SizeTitle struct { + Cm string `json:"cm"` + Inth string `json:"inth"` +} + +type Templates struct { + Ob484 []Ob484 `json:"4_84"` +} + +type Ob484 struct { + Id int64 `json:"id"` + Title string `json:"title"` + TemplateData TemplateData `json:"templateData"` +} + +type TemplateData struct { + Id int64 `json:"id"` + Cover string `json:"cover"` + Material string `json:"material"` + MaterialList []Material `json:"materialList"` +} + +type Material struct { + Id int64 `json:"id"` + Tag string `json:"tag"` + Title string `json:"title"` + Type string `json:"type"` + Text string `json:"text"` + Fill string `json:"fill"` + FontSize int `json:"fontSize"` + FontFamily string `json:"fontFamily"` + IfBr bool `json:"ifBr"` + IfShow bool `json:"ifShow"` + IfGroup bool `json:"ifGroup"` + MaxNum int `json:"maxNum"` + Rotation int `json:"rotation"` + Align string `json:"align"` + VerticalAlign string `json:"verticalAlign"` + Material string `json:"material"` + QRcodeType string `json:"qRcodeType"` + Width int `json:"width"` + Height int `json:"height"` + X int `json:"x"` + Y int `json:"y"` + Opacity int `json:"opacity"` + OptionalColor []OptionalColor `json:"optionalColor"` + ZIndex int `json:"zIndex"` + SvgPath string `json:"svgPath"` + Follow Follow `json:"follow"` + Group []string `json:"group"` + CameraStand CameraStand `json:"cameraStand"` +} + +type CameraStand struct { + X int `json:"x"` + Y int `json:"y"` + Z int `json:"z"` +} + +type Follow struct { + Fill string `json:"fill"` + IfShow string `json:"ifShow"` + Content string `json:"content"` +} + +type OptionalColor struct { + Color string `json:"color"` + Name string `json:"name"` + Default string `json:"default"` +} + type Response struct { Code int `json:"code"` Message string `json:"msg"` From 19f988eccd9fc203d596dda20f039806f3e1ad80 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Mon, 5 Jun 2023 12:21:15 +0800 Subject: [PATCH 5/8] fix --- product.api | 4 ++-- .../internal/handler/getproductinfohandler.go | 1 + .../internal/handler/getproductlisthandler.go | 1 + product/internal/logic/getproductinfologic.go | 21 +++++++++++++++++++ product/internal/logic/getproductlistlogic.go | 12 +++++------ product/internal/types/types.go | 4 ++-- utils/format/price.go | 2 +- 7 files changed, 34 insertions(+), 11 deletions(-) diff --git a/product.api b/product.api index d5bc11c8..200e2c57 100644 --- a/product.api +++ b/product.api @@ -57,8 +57,8 @@ type Items { Cover string `json:"cover"` Intro string `json:"intro"` CoverImg string `json:"cover_img"` - IsEnv uint32 `json:"isEnv"` - IsMicro uint32 `json:"isMicro"` + IsEnv int64 `json:"isEnv"` + IsMicro int64 `json:"isMicro"` SizeNum uint32 `json:"sizeNum"` MiniPrice float64 `json:"miniPrice"` CoverDefault string `json:"coverDefault"` diff --git a/product/internal/handler/getproductinfohandler.go b/product/internal/handler/getproductinfohandler.go index 5bcbae0a..2a354242 100644 --- a/product/internal/handler/getproductinfohandler.go +++ b/product/internal/handler/getproductinfohandler.go @@ -10,6 +10,7 @@ import ( "github.com/zeromicro/go-zero/rest/httpx" ) +// 获取产品详情 func GetProductInfoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { //检测登录权限 diff --git a/product/internal/handler/getproductlisthandler.go b/product/internal/handler/getproductlisthandler.go index 44245ea1..3777c949 100644 --- a/product/internal/handler/getproductlisthandler.go +++ b/product/internal/handler/getproductlisthandler.go @@ -10,6 +10,7 @@ import ( "github.com/zeromicro/go-zero/rest/httpx" ) +// 获取产品列表 func GetProductListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { //检测登录权限 diff --git a/product/internal/logic/getproductinfologic.go b/product/internal/logic/getproductinfologic.go index ef8a4c67..dd6e4629 100644 --- a/product/internal/logic/getproductinfologic.go +++ b/product/internal/logic/getproductinfologic.go @@ -2,7 +2,12 @@ package logic import ( "context" + "errors" + "fusenapi/model" "fusenapi/utils/auth" + "fusenapi/utils/image" + "github.com/zeromicro/go-zero/core/stores/sqlc" + "strings" "fusenapi/product/internal/svc" "fusenapi/product/internal/types" @@ -24,10 +29,26 @@ func NewGetProductInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Ge } } +// 获取产品详情 func (l *GetProductInfoLogic) GetProductInfo(req *types.GetProductInfoReq, loginInfo auth.UserInfo) (resp *types.Response, err error) { //校验前台登录情况 if loginInfo.UserId == 0 { return &types.Response{Code: 402, Message: "please sign in"}, nil } + req.Pid = strings.Trim(req.Pid, " ") + req.ClientNo = strings.Trim(req.ClientNo, " ") + if req.Size > 0 { + req.Size = image.GetCurrentSize(req.Size) + } + //获取产品详情 + productModel := model.NewFsProductModel(l.svcCtx.MysqlConn) + productInfo, err := productModel.FindOneBySn(l.ctx, req.Pid) + if err != nil && !errors.Is(err, sqlc.ErrNotFound) { + logx.Error(err) + return &types.Response{Code: 510, Message: "failed to get product info"}, nil + } + if productInfo == nil { + return &types.Response{Code: 510, Message: "product not found"}, nil + } return } diff --git a/product/internal/logic/getproductlistlogic.go b/product/internal/logic/getproductlistlogic.go index 9bb2081d..a8885dd7 100644 --- a/product/internal/logic/getproductlistlogic.go +++ b/product/internal/logic/getproductlistlogic.go @@ -12,7 +12,7 @@ import ( "fusenapi/utils/auth" "fusenapi/utils/format" "fusenapi/utils/image" - "github.com/zeromicro/go-zero/core/stores/sqlx" + "github.com/zeromicro/go-zero/core/stores/sqlc" "sort" "strings" "time" @@ -59,7 +59,7 @@ func (l *GetProductListLogic) GetProductList(req *types.GetProductListReq, login //查询用户信息 userModel := model.NewFsUserModel(l.svcCtx.MysqlConn) userInfo, err := userModel.FindOne(l.ctx, loginInfo.UserId) - if err != nil && !errors.Is(err, sqlx.ErrNotFound) { + if err != nil && !errors.Is(err, sqlc.ErrNotFound) { logx.Error(err) return &types.Response{Code: 510, Message: "get user info err"}, nil } @@ -118,7 +118,7 @@ func (l *GetProductListLogic) GetProductList(req *types.GetProductListReq, login //获取分类 tagsModel := model.NewFsTagsModel(l.svcCtx.MysqlConn) tagInfo, err := tagsModel.FindOne(l.ctx, req.Cid) - if err != nil && !errors.Is(err, sqlx.ErrNotFound) { + if err != nil && !errors.Is(err, sqlc.ErrNotFound) { logx.Error(err) return &types.Response{Code: 510, Message: "get classification err "}, nil } @@ -145,10 +145,10 @@ func (l *GetProductListLogic) GetProductList(req *types.GetProductListReq, login Cover: v.Cover, Intro: v.Intro.String, CoverImg: v.CoverImg, - IsEnv: 1, - IsMicro: 1, + IsEnv: v.IsProtection, + IsMicro: v.IsMicrowave, SizeNum: 1, - MiniPrice: format.FentoDollar(minPrice), + MiniPrice: format.CentoDollar(minPrice), } if req.Size > 0 { coverSlice := strings.Split(v.Cover, ".") diff --git a/product/internal/types/types.go b/product/internal/types/types.go index 6a7d556f..f5c1cc76 100644 --- a/product/internal/types/types.go +++ b/product/internal/types/types.go @@ -45,8 +45,8 @@ type Items struct { Cover string `json:"cover"` Intro string `json:"intro"` CoverImg string `json:"cover_img"` - IsEnv uint32 `json:"isEnv"` - IsMicro uint32 `json:"isMicro"` + IsEnv int64 `json:"isEnv"` + IsMicro int64 `json:"isMicro"` SizeNum uint32 `json:"sizeNum"` MiniPrice float64 `json:"miniPrice"` CoverDefault string `json:"coverDefault"` diff --git a/utils/format/price.go b/utils/format/price.go index 4a6e455a..8c7ee70a 100644 --- a/utils/format/price.go +++ b/utils/format/price.go @@ -6,7 +6,7 @@ import ( ) // 美分转美元 -func FentoDollar(price int64) float64 { +func CentoDollar(price int64) float64 { str := fmt.Sprintf("%.2f", float64(price)/float64(100)) dollar, _ := strconv.ParseFloat(str, 64) return dollar From dfe171ea94f7ae06fb9eb032c9e446357e14e18c Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Mon, 5 Jun 2023 12:27:57 +0800 Subject: [PATCH 6/8] fix --- product/internal/logic/getproductlistlogic.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/product/internal/logic/getproductlistlogic.go b/product/internal/logic/getproductlistlogic.go index a8885dd7..f50fbe72 100644 --- a/product/internal/logic/getproductlistlogic.go +++ b/product/internal/logic/getproductlistlogic.go @@ -147,7 +147,7 @@ func (l *GetProductListLogic) GetProductList(req *types.GetProductListReq, login CoverImg: v.CoverImg, IsEnv: v.IsProtection, IsMicro: v.IsMicrowave, - SizeNum: 1, + SizeNum: 1, //???????????????? MiniPrice: format.CentoDollar(minPrice), } if req.Size > 0 { From 52cc2a3d302d2ec024387f70c59d13a6a67e5172 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Mon, 5 Jun 2023 17:13:05 +0800 Subject: [PATCH 7/8] fix --- .idea/sqldialects.xml | 7 -- ddl/fs_product_size.sql | 16 +++ model/fsproductsizemodel.go | 24 +++++ model/fsproductsizemodel_gen.go | 100 ++++++++++++++++++ product/internal/logic/getproductlistlogic.go | 9 +- 5 files changed, 148 insertions(+), 8 deletions(-) delete mode 100644 .idea/sqldialects.xml create mode 100644 ddl/fs_product_size.sql create mode 100755 model/fsproductsizemodel.go create mode 100755 model/fsproductsizemodel_gen.go diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml deleted file mode 100644 index 495fcf38..00000000 --- a/.idea/sqldialects.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/ddl/fs_product_size.sql b/ddl/fs_product_size.sql new file mode 100644 index 00000000..d68942eb --- /dev/null +++ b/ddl/fs_product_size.sql @@ -0,0 +1,16 @@ +-- fusentest.fs_product_size definition + +CREATE TABLE `fs_product_size` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `product_id` int(10) unsigned NOT NULL COMMENT '产品ID', + `title` text NOT NULL COMMENT '标题 10*10*20', + `cover` varchar(255) DEFAULT NULL COMMENT '封面图', + `cover_img` varchar(255) DEFAULT NULL COMMENT '背景图', + `capacity` varchar(255) NOT NULL COMMENT '自己填的尺寸名称', + `status` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '状态位 显示 删除', + `sort` smallint(6) NOT NULL DEFAULT '50' COMMENT '排序', + `remark` varchar(255) DEFAULT NULL COMMENT '备注信息', + `parts_can_deleted` tinyint(1) NOT NULL DEFAULT '1' COMMENT '配件是否可移除 1是0否', + PRIMARY KEY (`id`) USING BTREE, + KEY `product_id` (`product_id`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=130 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='产品尺寸表'; \ No newline at end of file diff --git a/model/fsproductsizemodel.go b/model/fsproductsizemodel.go new file mode 100755 index 00000000..f0a9c932 --- /dev/null +++ b/model/fsproductsizemodel.go @@ -0,0 +1,24 @@ +package model + +import "github.com/zeromicro/go-zero/core/stores/sqlx" + +var _ FsProductSizeModel = (*customFsProductSizeModel)(nil) + +type ( + // FsProductSizeModel is an interface to be customized, add more methods here, + // and implement the added methods in customFsProductSizeModel. + FsProductSizeModel interface { + fsProductSizeModel + } + + customFsProductSizeModel struct { + *defaultFsProductSizeModel + } +) + +// NewFsProductSizeModel returns a model for the database table. +func NewFsProductSizeModel(conn sqlx.SqlConn) FsProductSizeModel { + return &customFsProductSizeModel{ + defaultFsProductSizeModel: newFsProductSizeModel(conn), + } +} diff --git a/model/fsproductsizemodel_gen.go b/model/fsproductsizemodel_gen.go new file mode 100755 index 00000000..34e6cb4e --- /dev/null +++ b/model/fsproductsizemodel_gen.go @@ -0,0 +1,100 @@ +// Code generated by goctl. DO NOT EDIT. + +package model + +import ( + "context" + "database/sql" + "fmt" + "strings" + + "github.com/zeromicro/go-zero/core/stores/builder" + "github.com/zeromicro/go-zero/core/stores/sqlc" + "github.com/zeromicro/go-zero/core/stores/sqlx" + "github.com/zeromicro/go-zero/core/stringx" +) + +var ( + fsProductSizeFieldNames = builder.RawFieldNames(&FsProductSize{}) + fsProductSizeRows = strings.Join(fsProductSizeFieldNames, ",") + fsProductSizeRowsExpectAutoSet = strings.Join(stringx.Remove(fsProductSizeFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",") + fsProductSizeRowsWithPlaceHolder = strings.Join(stringx.Remove(fsProductSizeFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?" +) + +type ( + fsProductSizeModel interface { + Insert(ctx context.Context, data *FsProductSize) (sql.Result, error) + FindOne(ctx context.Context, id int64) (*FsProductSize, error) + Update(ctx context.Context, data *FsProductSize) error + Delete(ctx context.Context, id int64) error + CountByStatus(ctx context.Context, status int) (total int, err error) + } + + defaultFsProductSizeModel struct { + conn sqlx.SqlConn + table string + } + + FsProductSize struct { + Id int64 `db:"id"` + ProductId int64 `db:"product_id"` // 产品ID + Title string `db:"title"` // 标题 10*10*20 + Cover sql.NullString `db:"cover"` // 封面图 + CoverImg sql.NullString `db:"cover_img"` // 背景图 + Capacity string `db:"capacity"` // 自己填的尺寸名称 + Status int64 `db:"status"` // 状态位 显示 删除 + Sort int64 `db:"sort"` // 排序 + Remark sql.NullString `db:"remark"` // 备注信息 + PartsCanDeleted int64 `db:"parts_can_deleted"` // 配件是否可移除 1是0否 + } +) + +func newFsProductSizeModel(conn sqlx.SqlConn) *defaultFsProductSizeModel { + return &defaultFsProductSizeModel{ + conn: conn, + table: "`fs_product_size`", + } +} + +func (m *defaultFsProductSizeModel) Delete(ctx context.Context, id int64) error { + query := fmt.Sprintf("delete from %s where `id` = ?", m.table) + _, err := m.conn.ExecCtx(ctx, query, id) + return err +} + +func (m *defaultFsProductSizeModel) FindOne(ctx context.Context, id int64) (*FsProductSize, error) { + query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", fsProductSizeRows, m.table) + var resp FsProductSize + err := m.conn.QueryRowCtx(ctx, &resp, query, id) + switch err { + case nil: + return &resp, nil + case sqlc.ErrNotFound: + return nil, ErrNotFound + default: + return nil, err + } +} + +func (m *defaultFsProductSizeModel) Insert(ctx context.Context, data *FsProductSize) (sql.Result, error) { + query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, fsProductSizeRowsExpectAutoSet) + ret, err := m.conn.ExecCtx(ctx, query, data.ProductId, data.Title, data.Cover, data.CoverImg, data.Capacity, data.Status, data.Sort, data.Remark, data.PartsCanDeleted) + return ret, err +} + +func (m *defaultFsProductSizeModel) Update(ctx context.Context, data *FsProductSize) error { + query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, fsProductSizeRowsWithPlaceHolder) + _, err := m.conn.ExecCtx(ctx, query, data.ProductId, data.Title, data.Cover, data.CoverImg, data.Capacity, data.Status, data.Sort, data.Remark, data.PartsCanDeleted, data.Id) + return err +} +func (m *defaultFsProductSizeModel) CountByStatus(ctx context.Context, status int) (total int, err error) { + query := fmt.Sprintf("select %s from %s where `status` = ? limit 1", "count(*) as num", m.table) + err = m.conn.QueryRowCtx(ctx, &total, query, status) + if err != nil { + return 0, err + } + return +} +func (m *defaultFsProductSizeModel) tableName() string { + return m.table +} diff --git a/product/internal/logic/getproductlistlogic.go b/product/internal/logic/getproductlistlogic.go index f50fbe72..7366a8f3 100644 --- a/product/internal/logic/getproductlistlogic.go +++ b/product/internal/logic/getproductlistlogic.go @@ -125,6 +125,13 @@ func (l *GetProductListLogic) GetProductList(req *types.GetProductListReq, login if tagInfo == nil { return &types.Response{Code: 510, Message: "classification not exists "}, nil } + //获取产品尺寸数量 + productSizeModel := model.NewFsProductSizeModel(l.svcCtx.MysqlConn) + productSizeCount, err := productSizeModel.CountByStatus(l.ctx, 1) + if err != nil { + logx.Error(err) + return &types.Response{Code: 510, Message: "get product size count err "}, nil + } //拼接返回 itemList := make([]types.Items, 0, productLen) for _, v := range productList { @@ -147,7 +154,7 @@ func (l *GetProductListLogic) GetProductList(req *types.GetProductListReq, login CoverImg: v.CoverImg, IsEnv: v.IsProtection, IsMicro: v.IsMicrowave, - SizeNum: 1, //???????????????? + SizeNum: uint32(productSizeCount), MiniPrice: format.CentoDollar(minPrice), } if req.Size > 0 { From e6c88d83aa34fd5ed1c1eff5809bb148df25dc3e Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Mon, 5 Jun 2023 17:38:37 +0800 Subject: [PATCH 8/8] fix --- model/fsproductsizemodel_gen.go | 15 +++++++++++++++ product/internal/logic/getproductinfologic.go | 19 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/model/fsproductsizemodel_gen.go b/model/fsproductsizemodel_gen.go index 34e6cb4e..fcd125d0 100755 --- a/model/fsproductsizemodel_gen.go +++ b/model/fsproductsizemodel_gen.go @@ -28,6 +28,7 @@ type ( Update(ctx context.Context, data *FsProductSize) error Delete(ctx context.Context, id int64) error CountByStatus(ctx context.Context, status int) (total int, err error) + FindAllByStatus(ctx context.Context, status int, sort int) ([]FsProductSize, error) } defaultFsProductSizeModel struct { @@ -95,6 +96,20 @@ func (m *defaultFsProductSizeModel) CountByStatus(ctx context.Context, status in } return } +func (m *defaultFsProductSizeModel) FindAllByStatus(ctx context.Context, status int, sort int) (resp []FsProductSize, err error) { + query := fmt.Sprintf("select %s from %s where `status` = ? ", fsProductSizeRows, m.table) + switch sort { + case 1: + query = fmt.Sprintf("%s order by `sort` ASC", query) + case 2: + query = fmt.Sprintf("%s order by `sort` DESC", query) + } + err = m.conn.QueryRowsCtx(ctx, &resp, query, status) + if err != nil { + return nil, err + } + return +} func (m *defaultFsProductSizeModel) tableName() string { return m.table } diff --git a/product/internal/logic/getproductinfologic.go b/product/internal/logic/getproductinfologic.go index dd6e4629..a62fa8b3 100644 --- a/product/internal/logic/getproductinfologic.go +++ b/product/internal/logic/getproductinfologic.go @@ -3,6 +3,7 @@ package logic import ( "context" "errors" + "fmt" "fusenapi/model" "fusenapi/utils/auth" "fusenapi/utils/image" @@ -50,5 +51,23 @@ func (l *GetProductInfoLogic) GetProductInfo(req *types.GetProductInfoReq, login if productInfo == nil { return &types.Response{Code: 510, Message: "product not found"}, nil } + //获取产品标签 + tagModel := model.NewFsTagsModel(l.svcCtx.MysqlConn) + tagInfo, err := tagModel.FindOne(l.ctx, productInfo.Type) + if err != nil { + logx.Error(err) + return &types.Response{Code: 510, Message: "failed to get product tag"}, nil + } + //获取产品尺寸列表 + productSizeModel := model.NewFsProductSizeModel(l.svcCtx.MysqlConn) + productSizeList, err := productSizeModel.FindAllByStatus(l.ctx, 1, 1) + if err != nil { + logx.Error(err) + return &types.Response{Code: 510, Message: "failed to get product size list"}, nil + } + sizeIds := make([]string, 0, len(productSizeList)) + for _, v := range productSizeList { + sizeIds = append(sizeIds, fmt.Sprintf("%d", v.Id)) + } return }