diff --git a/app/admin/enum/enum_company.go b/app/admin/enum/enum_company.go new file mode 100644 index 0000000..7966aac --- /dev/null +++ b/app/admin/enum/enum_company.go @@ -0,0 +1,19 @@ +package enum + +type CompanyState int32 + +const ( + CompanyStateForNormal = 1 + CompanyStateForFreeze = 2 +) + +func (gt CompanyState) String() string { + switch gt { + case CompanyStateForNormal: + return "正常" + case CompanyStateForFreeze: + return "冻结" + default: + return "未知" + } +} diff --git a/app/admin/enum/enum_enterprise.go b/app/admin/enum/enum_enterprise.go new file mode 100644 index 0000000..16f0224 --- /dev/null +++ b/app/admin/enum/enum_enterprise.go @@ -0,0 +1,19 @@ +package enum + +type EnterpriseState int32 + +const ( + EnterpriseStateForNormal = 1 + EnterpriseStateForFreeze = 2 +) + +func (gt EnterpriseState) String() string { + switch gt { + case EnterpriseStateForNormal: + return "正常" + case EnterpriseStateForFreeze: + return "冻结" + default: + return "未知" + } +} diff --git a/app/admin/enum/goods.go b/app/admin/enum/goods.go new file mode 100644 index 0000000..4380d7f --- /dev/null +++ b/app/admin/enum/goods.go @@ -0,0 +1,20 @@ +package enum + +// MallGoodsSaleState 商品上架状态 +type MallGoodsSaleState int + +const ( + MallGoodsSaleStateOnShelf MallGoodsSaleState = iota + 1 + MallGoodsSaleStateOffShelf +) + +func (em MallGoodsSaleState) String() string { + switch em { + case MallGoodsSaleStateOnShelf: + return "销售中" + case MallGoodsSaleStateOffShelf: + return "下架" + default: + return "未知类型" + } +} diff --git a/app/admin/hdl/category/hdl_index.go b/app/admin/hdl/category/hdl_index.go new file mode 100644 index 0000000..0ad4f0c --- /dev/null +++ b/app/admin/hdl/category/hdl_index.go @@ -0,0 +1,69 @@ +package category + +import ( + "applet/app/admin/svc/category" + "applet/app/e" + "github.com/gin-gonic/gin" +) + +func List(c *gin.Context) { + r, err := svc.List(c) + if err != nil { + e.OutErr(c, e.ERR_DB_ORM, err.Error()) + return + } + e.OutSuc(c, r, nil) +} + +func Add(c *gin.Context) { + var name = c.DefaultQuery("name", "") + var pid = c.DefaultQuery("pid", "0") + err := svc.Add(c, name, pid) + if err != nil { + e.OutErr(c, e.ERR_DB_ORM, err.Error()) + return + } + e.OutSuc(c, nil, nil) +} + +func Del(c *gin.Context) { + var categoryId = c.DefaultQuery("categoryId", "1") + err := svc.Del(c, categoryId) + if err != nil { + e.OutErr(c, e.ERR_DB_ORM, err.Error()) + return + } + e.OutSuc(c, nil, nil) +} + +func Sort(c *gin.Context) { + var args struct { + Ids []string `json:"ids" binding:"required"` + } + if err := c.ShouldBindJSON(&args); err != nil { + e.OutErr(c, e.ERR_INVALID_ARGS, err) + return + } + err := svc.Sort(c, args.Ids) + if err != nil { + e.OutErr(c, e.ERR_DB_ORM, err.Error()) + return + } + e.OutSuc(c, nil, nil) +} + +func Save(c *gin.Context) { + var args struct { + Data map[string]interface{} `json:"data" binding:"required"` + } + if err := c.ShouldBindJSON(&args); err != nil { + e.OutErr(c, e.ERR_INVALID_ARGS, err) + return + } + err := svc.Save(c, args.Data) + if err != nil { + e.OutErr(c, e.ERR_DB_ORM, err.Error()) + return + } + e.OutSuc(c, nil, nil) +} diff --git a/app/admin/hdl/goods/hdl_goods.go b/app/admin/hdl/goods/hdl_goods.go new file mode 100644 index 0000000..c8cd3eb --- /dev/null +++ b/app/admin/hdl/goods/hdl_goods.go @@ -0,0 +1,96 @@ +package goods + +// 自营商城商品管理 +import ( + "applet/app/admin/md" + "applet/app/admin/svc/goods" + "applet/app/db" + "applet/app/db/model" + "applet/app/e" + "applet/app/svc" + "applet/app/utils" + "fmt" + "github.com/gin-gonic/gin" + "github.com/mcuadros/go-defaults" +) + +func DelMallGoods(c *gin.Context) { + var idsMap map[string][]string + if err := c.ShouldBindJSON(&idsMap); err != nil { + e.OutErr(c, e.ERR_INVALID_ARGS, err) + return + } + goods.DelMallGoods(c, idsMap["ids"]) +} + +// AddMallGoods 添加商品、编辑、复制 +func AddMallGoods(c *gin.Context) { + var req md.AddGoodsReq + // 设置默认值(结构体default标签的值) + defaults.SetDefaults(&req) + // 初始化翻译器 + if err := utils.ValidatorTransInitZh(); err != nil { + e.OutErr(c, e.ERR, fmt.Sprintf("init trans failed, err:%v\n", err)) + return + } + + err := c.ShouldBindJSON(&req) + if err != nil { + err = svc.HandleValidateErr(err) + err1 := err.(e.E) + e.OutErr(c, err1.Code, err1.Error()) + return + } + err = goods.AddMallGoods(c, &req) + if err != nil { + switch err.(type) { + case e.E: + err1 := err.(e.E) + e.OutErr(c, err1.Code, err1) + return + default: + e.OutErr(c, e.ERR, err) + return + } + } + + e.OutSuc(c, 1, nil) + return +} + +func MallGoodsDetail(c *gin.Context) { + id := c.Query("id") + if id == "" { + id = "0" + } + resp, err := goods.MallGoodsDetail(c, utils.StrToInt(id)) + if err != nil { + e.OutErr(c, 400, err) + return + } + e.OutSuc(c, resp, nil) + return +} + +func ChangeSaleState(c *gin.Context) { + var args struct { + GoodsIds []string `json:"goods_ids"` + SaleState int `json:"sale_state"` + } + err := c.ShouldBindJSON(&args) + if err != nil { + e.OutErr(c, e.ERR_INVALID_ARGS, err.Error()) + return + } + if args.SaleState != 1 && args.SaleState != 2 { + e.OutErr(c, e.ERR_INVALID_ARGS, "状态值不正确") + return + } + eg := db.Db + _, err = eg.In("goods_id", args.GoodsIds).Update(&model.Goods{SaleState: args.SaleState}) + if err != nil { + e.OutErr(c, e.ERR_DB_ORM, err) + return + } + e.OutSuc(c, 1, nil) +} diff --git a/app/admin/hdl/goods/hdl_goods_list.go b/app/admin/hdl/goods/hdl_goods_list.go new file mode 100644 index 0000000..ee8bb8f --- /dev/null +++ b/app/admin/hdl/goods/hdl_goods_list.go @@ -0,0 +1,71 @@ +package goods + +import ( + "applet/app/admin/md" + svc "applet/app/admin/svc/category" + "applet/app/admin/svc/goods" + "applet/app/e" + "github.com/gin-gonic/gin" +) + +// 商品列表接口 +func GetMallGoodsList(c *gin.Context) { + var args md.MallGoodsListReq + args.Title = c.Query("title") + args.CategoryId = c.Query("category_id") + args.SaleState = c.Query("sale_state") + args.PageId = c.Query("page") + args.PageSize = c.Query("limit") + args.SkuCode = c.Query("sku_code") + + tree, err := svc.GetAllCategory(c) + data, total, err := goods.GetMallGoodsList(c, &args) + if err != nil { + e.OutErr(c, e.ERR_NO_DATA, err) + return + } + var returnData = map[string]interface{}{ + "total": total, + "cateList": tree, + // "dataList": data, + //-1审核拒绝 0审核中 1销售中 2已售罄 3放入仓库 4下架 + "stateList": []map[string]interface{}{ + {"name": "全部", "value": 99}, + {"name": "销售中", "value": 1}, + {"name": "已下架", "value": 2}, + }, + } + + if data == nil { + returnData["dataList"] = []string{} + } else { + returnData["dataList"] = data + } + + e.OutSuc(c, returnData, nil) + return +} + +func CheckSkuCode(c *gin.Context) { + skuCode := c.Query("sku_code") + goodsId := c.DefaultQuery("goods_id", "0") + isHas, err := goods.CheckSkuCode(c, skuCode, goodsId) + if err != nil { + e.OutErr(c, e.ERR, err) + return + } + var result = true + if isHas { + result = false + e.OutSuc(c, map[string]interface{}{ + "result": result, + "msg": "該sku編碼已存在,請保持唯一性", + }, nil) + return + } + e.OutSuc(c, map[string]interface{}{ + "result": result, + "msg": "success", + }, nil) + return +} diff --git a/app/admin/hdl/hdl_company.go b/app/admin/hdl/hdl_company.go new file mode 100644 index 0000000..3210516 --- /dev/null +++ b/app/admin/hdl/hdl_company.go @@ -0,0 +1,127 @@ +package hdl + +import ( + "applet/app/admin/enum" + "applet/app/admin/lib/validate" + "applet/app/admin/md" + "applet/app/db" + "applet/app/db/model" + "applet/app/e" + "applet/app/utils" + "github.com/gin-gonic/gin" + "time" +) + +func CompanyList(c *gin.Context) { + companyDb := db.CompanyDb{} + companyDb.Set() + companies, err := companyDb.FindCompany(0, 0) + if err != nil { + e.OutErr(c, e.ERR_DB_ORM, err.Error()) + return + } + e.OutSuc(c, map[string]interface{}{ + "list": companies, + "state": []map[string]interface{}{ + { + "name": "正常", + "value": enum.CompanyStateForNormal, + }, + { + "name": "冻结", + "value": enum.CompanyStateForFreeze, + }, + }, + }, nil) + return +} + +func CompanyAdd(c *gin.Context) { + var req md.CompanyAddReq + err := c.ShouldBindJSON(&req) + if err != nil { + err = validate.HandleValidateErr(err) + err1 := err.(e.E) + e.OutErr(c, err1.Code, err1.Error()) + return + } + companyDb := db.CompanyDb{} + companyDb.Set() + now := time.Now() + company := model.Company{ + Name: req.Name, + State: enum.CompanyStateForNormal, + Memo: req.Memo, + LeadName: req.LeadName, + LeadPhone: req.LeadPhone, + CreateAt: now.Format("2006-01-02 15:04:05"), + UpdateAt: now.Format("2006-01-02 15:04:05"), + } + _, err = companyDb.CompanyInsert(&company) + if err != nil { + e.OutErr(c, e.ERR_DB_ORM, err.Error()) + return + } + e.OutSuc(c, "success", nil) + return +} + +func CompanyUpdate(c *gin.Context) { + var req md.CompanyUpdateReq + err := c.ShouldBindJSON(&req) + if err != nil { + err = validate.HandleValidateErr(err) + err1 := err.(e.E) + e.OutErr(c, err1.Code, err1.Error()) + return + } + companyDb := db.CompanyDb{} + companyDb.Set() + company, err := companyDb.GetCompany(req.Id) + if err != nil { + e.OutErr(c, e.ERR_DB_ORM, err.Error()) + return + } + if company == nil { + e.OutErr(c, e.ERR_NO_DATA, "未查询到对应记录") + return + } + now := time.Now() + company.Name = req.Name + company.LeadName = req.LeadName + company.LeadPhone = req.LeadPhone + if req.State != 0 { + company.State = req.State + } + company.UpdateAt = now.Format("2006-01-02 15:04:05") + _, err = companyDb.CompanyUpdate(company, "name", "memo", "state", "lead_name", "lead_phone", "update_at") + if err != nil { + e.OutErr(c, e.ERR_DB_ORM, err.Error()) + return + } + e.OutSuc(c, "success", nil) + return +} + +func CompanyDelete(c *gin.Context) { + id := c.Param("id") + companyDb := db.CompanyDb{} + companyDb.Set() + company, err := companyDb.GetCompany(utils.StrToInt(id)) + if err != nil { + e.OutErr(c, e.ERR_DB_ORM, err.Error()) + return + } + if company == nil { + e.OutErr(c, e.ERR_NO_DATA, "未查询到对应记录") + return + } + + _, err = companyDb.CompanyDelete(id) + if err != nil { + e.OutErr(c, e.ERR_DB_ORM, err.Error()) + return + } + e.OutSuc(c, "success", nil) + return +} diff --git a/app/admin/hdl/hdl_enterprise.go b/app/admin/hdl/hdl_enterprise.go new file mode 100644 index 0000000..ac3b0e2 --- /dev/null +++ b/app/admin/hdl/hdl_enterprise.go @@ -0,0 +1,191 @@ +package hdl + +import ( + "applet/app/admin/enum" + "applet/app/admin/lib/validate" + "applet/app/admin/md" + "applet/app/admin/svc" + "applet/app/db" + "applet/app/db/model" + "applet/app/e" + "github.com/gin-gonic/gin" + "time" +) + +func EnterpriseList(c *gin.Context) { + var req md.EnterpriseListReq + err := c.ShouldBindJSON(&req) + if err != nil { + err = validate.HandleValidateErr(err) + err1 := err.(e.E) + e.OutErr(c, err1.Code, err1.Error()) + return + } + enterpriseDb := db.EnterpriseDb{} + enterpriseDb.Set() + engine := enterpriseDb.Db.Desc("enterprise.id").Limit(req.Limit, (req.Page-1)*req.Limit) + if req.Name != "" { + engine.And("enterprise.name like ?", "%"+req.Name+"%") + } + if req.Memo != "" { + engine.And("enterprise.memo like ?", "%"+req.Memo+"%") + } + if req.LeadPhone != "" { + engine.And("company.lead_phone like ?", "%"+req.LeadPhone+"%") + } + if req.LeadName != "" { + engine.And("company.lead_name like ?", "%"+req.LeadName+"%") + } + var list []db.EnterpriseWithCompany + count, err := engine.Join("LEFT", "grade", "enterprise.id = grade.enterprise_id"). + Join("LEFT", "class", "class.grade_id = grade.id"). + FindAndCount(&list) + if err != nil { + e.OutErr(c, e.ERR_DB_ORM, err.Error()) + return + } + + var result []md.EnterpriseListResp + for _, v := range list { + result = append(result, md.EnterpriseListResp{ + Id: v.Enterprise.Id, + State: v.Enterprise.State, + Name: v.Enterprise.Name, + Memo: v.Enterprise.Memo, + LeadName: v.Company.LeadName, + LeadPhone: v.Company.LeadPhone, + CreateAt: v.Enterprise.CreateAt, + UpdateAt: v.Enterprise.UpdateAt, + }) + } + e.OutSuc(c, map[string]interface{}{ + "list": list, + "total": count, + "state": []map[string]interface{}{ + { + "name": enum.EnterpriseState(enum.EnterpriseStateForNormal).String(), + "value": enum.EnterpriseStateForNormal, + }, + { + "name": enum.EnterpriseState(enum.EnterpriseStateForFreeze).String(), + "value": enum.EnterpriseStateForFreeze, + }, + }, + }, nil) + return +} + +func EnterpriseUpdateState(c *gin.Context) { + var req md.EnterpriseUpdateStateReq + err := c.ShouldBindJSON(&req) + if err != nil { + err = validate.HandleValidateErr(err) + err1 := err.(e.E) + e.OutErr(c, err1.Code, err1.Error()) + return + } + enterpriseDb := db.EnterpriseDb{} + enterpriseDb.Set() + enterprise, err := enterpriseDb.GetEnterprise(req.Id) + if err != nil { + e.OutErr(c, e.ERR_DB_ORM, err.Error()) + return + } + if enterprise == nil { + e.OutErr(c, e.ERR_NO_DATA, "未查询到对应记录") + return + } + now := time.Now() + enterprise.State = req.State + enterprise.UpdateAt = now.Format("2006-01-02 15:04:05") + _, err = enterpriseDb.EnterpriseUpdate(enterprise, "state", "update_at") + if err != nil { + e.OutErr(c, e.ERR_DB_ORM, err.Error()) + return + } + e.OutSuc(c, "success", nil) + return +} + +func EnterpriseDelete(c *gin.Context) { + var req md.EnterpriseDeleteReq + err := c.ShouldBindJSON(&req) + if err != nil { + err = validate.HandleValidateErr(err) + err1 := err.(e.E) + e.OutErr(c, err1.Code, err1.Error()) + return + } + err = svc.EnterpriseDelete(req.EnterpriseIds) + if err != nil { + e.OutErr(c, e.ERR_DB_ORM, err.Error()) + return + } + e.OutSuc(c, "success", nil) + return +} + +func EnterpriseAdd(c *gin.Context) { + var req md.EnterpriseAddReq + err := c.ShouldBindJSON(&req) + if err != nil { + err = validate.HandleValidateErr(err) + err1 := err.(e.E) + e.OutErr(c, err1.Code, err1.Error()) + return + } + enterpriseDb := db.EnterpriseDb{} + enterpriseDb.Set() + now := time.Now() + + enterprise := model.Enterprise{ + Name: req.Name, + CompanyId: req.CompanyId, + State: enum.EnterpriseStateForNormal, + Memo: req.Memo, + CreateAt: now.Format("2006-01-02 15:04:05"), + UpdateAt: now.Format("2006-01-02 15:04:05"), + } + _, err = enterpriseDb.EnterpriseInsert(&enterprise) + if err != nil { + e.OutErr(c, e.ERR_DB_ORM, err.Error()) + return + } + + e.OutSuc(c, "success", nil) + return +} + +func EnterpriseUpdate(c *gin.Context) { + var req md.EnterpriseUpdateReq + err := c.ShouldBindJSON(&req) + if err != nil { + err = validate.HandleValidateErr(err) + err1 := err.(e.E) + e.OutErr(c, err1.Code, err1.Error()) + return + } + enterpriseDb := db.EnterpriseDb{} + enterpriseDb.Set() + enterprise, err := enterpriseDb.GetEnterprise(req.Id) + if err != nil { + e.OutErr(c, e.ERR_DB_ORM, err.Error()) + return + } + if enterprise == nil { + e.OutErr(c, e.ERR_NO_DATA, "未查询到对应记录") + return + } + now := time.Now() + enterprise.Name = req.Name + enterprise.Memo = req.Name + enterprise.CompanyId = req.CompanyId + enterprise.UpdateAt = now.Format("2006-01-02 15:04:05") + _, err = enterpriseDb.EnterpriseUpdate(enterprise, "name", "memo", "update_at") + if err != nil { + e.OutErr(c, e.ERR_DB_ORM, err.Error()) + return + } + e.OutSuc(c, "success", nil) + return +} diff --git a/app/admin/md/category.go b/app/admin/md/category.go new file mode 100644 index 0000000..9d9d9ac --- /dev/null +++ b/app/admin/md/category.go @@ -0,0 +1,10 @@ +package md + +type CateGoryTreeList struct { + Id int `json:"id"` + Pid int `json:"pid"` + Name string `json:"name"` + CreateAt string `json:"create_time"` + UpdateAt string `json:"update_time"` + Children []CateGoryTreeList `json:"children"` +} diff --git a/app/admin/md/good_list_resp.go b/app/admin/md/good_list_resp.go new file mode 100644 index 0000000..2df6bf4 --- /dev/null +++ b/app/admin/md/good_list_resp.go @@ -0,0 +1,17 @@ +package md + +import "applet/app/db/model" + +type MallGoodListResp struct { + GoodsId string `json:"id"` // 商品id + Price string `json:"price"` + CreateAt string `json:"create_at"` + UpdateAt string `json:"update_at"` + SkuList []model.Sku `json:"skuList"` + Title string `json:"title"` + Image string `json:"image"` + SaleStateText string `json:"state_text"` + SaleState int `json:"sale_state"` + StateCode int `json:"state_code"` + CategoryId string `json:"category_id"` +} diff --git a/app/admin/md/md_company.go b/app/admin/md/md_company.go new file mode 100644 index 0000000..c36bba6 --- /dev/null +++ b/app/admin/md/md_company.go @@ -0,0 +1,17 @@ +package md + +type CompanyAddReq struct { + Name string `json:"name" binding:"required" label:"名称"` + Memo string `json:"memo" label:"备注"` + LeadName string `json:"lead_name" label:"负责人姓名"` + LeadPhone string `json:"lead_phone" label:"负责人手机号"` +} + +type CompanyUpdateReq struct { + Id int `json:"id" binding:"required" label:"公司id"` + State int32 `json:"state" label:"状态"` + Name string `json:"name" binding:"required" label:"名称"` + Memo string `json:"memo" label:"备注"` + LeadName string `json:"lead_name" label:"负责人姓名"` + LeadPhone string `json:"lead_phone" label:"负责人手机号"` +} diff --git a/app/admin/md/md_enterprise.go b/app/admin/md/md_enterprise.go new file mode 100644 index 0000000..7227553 --- /dev/null +++ b/app/admin/md/md_enterprise.go @@ -0,0 +1,43 @@ +package md + +type EnterpriseListReq struct { + Limit int `json:"limit"` + Page int `json:"page" ` + Name string `json:"name" binding:"required" label:"名称"` + Memo string `json:"memo" label:"备注"` + LeadName string `json:"lead_name" label:"负责人姓名"` + LeadPhone string `json:"lead_phone" label:"负责人手机号"` +} + +type EnterpriseListResp struct { + Id int `json:"id" binding:"required" label:"公司id"` + State int32 `json:"state" label:"状态"` + Name string `json:"name" binding:"required" label:"名称"` + Memo string `json:"memo" label:"备注"` + LeadName string `json:"lead_name" label:"负责人姓名"` + LeadPhone string `json:"lead_phone" label:"负责人手机号"` + CreateAt string `json:"create_at" label:"创建时间"` + UpdateAt string `json:"update_at" label:"更新时间"` +} + +type EnterpriseUpdateStateReq struct { + Id int `json:"id" binding:"required" label:"企业id"` + State int32 `json:"state" label:"状态"` +} + +type EnterpriseDeleteReq struct { + EnterpriseIds []int `json:"enterprise_ids"` +} + +type EnterpriseAddReq struct { + Name string `json:"name" binding:"required" label:"名称"` + CompanyId int `json:"company_id" binding:"required" label:"所属公司id"` + Memo string `json:"memo" label:"备注"` +} + +type EnterpriseUpdateReq struct { + Id int `json:"id" binding:"required" label:"公司id"` + Name string `json:"name" binding:"required" label:"名称"` + CompanyId int `json:"company_id" binding:"required" label:"所属公司id"` + Memo string `json:"memo" label:"备注"` +} diff --git a/app/admin/md/md_goods.go b/app/admin/md/md_goods.go new file mode 100644 index 0000000..60cbb23 --- /dev/null +++ b/app/admin/md/md_goods.go @@ -0,0 +1,42 @@ +package md + +import ( + "applet/app/admin/enum" +) + +type AddGoodsReq struct { + Base MallBaseGoods `json:"base" binding:"required" label:"商品基本信息"` // 基本信息 + SkuList []*MallGoodsSku `json:"sku_list" binding:"required,gt=0" label:"商品规格"` // sku列表 +} + +type MallBaseGoods struct { + GoodsId string `json:"goods_id,omitempty" label:"商品ID"` // 商品id,0或不传为新建 + Title string `json:"title" binding:"required,lte=200" label:"标题"` // 商品标题 + CategoryId int `json:"category_id" binding:"required" label:"商品类目"` // 商品类目id + ImageList []string `json:"image_list" binding:"required,gt=0" label:"商品主图"` // 主图列表 + ImageListUrl []string `json:"image_list_url" ` // 主图列表 + SaleState enum.MallGoodsSaleState `json:"sale_state" label:"开售时间"` // 销售状态 + Spe []Spe `json:"spe" binding:"required,gt=0" label:"商品规格"` // 规格 + Detail []string `json:"detail" label:"商品详情"` // 商品详情 + DetailUrl []string `json:"detail_url" ` // 商品详情 + Price string `json:"price" binding:"required" label:"价格"` // 价格 + Sort int `json:"sort" label:"排序"` // 排序 +} + +type Spe struct { + Name string `json:"name" label:"规格名"` // 规格名 + Values []string `json:"values" label:"规格值"` // 规格值 +} + +type MallGoodsSku struct { + SkuID int `json:"sku_id,omitempty" label:"skuID" copier:"-"` // sku_id 0或不传为新建 + GoodsID int `json:"goods_id,omitempty" label:"商品ID"` // 0或不传为新建 + SkuCode string `json:"sku_code,omitempty" label:"sku編碼"` + Price string `json:"price" binding:"required" label:"价格"` // 价格 + Sku []MallGoodsSkuSku `json:"sku" label:"规格组合"` // 规格组合 +} + +type MallGoodsSkuSku struct { + Name string `json:"name" binding:"required" label:"规格名"` // 规格名 + Value string `json:"value" binding:"required" label:"规格值"` // 规格值 +} diff --git a/app/admin/md/md_goods_list.go b/app/admin/md/md_goods_list.go new file mode 100644 index 0000000..3530abb --- /dev/null +++ b/app/admin/md/md_goods_list.go @@ -0,0 +1,52 @@ +package md + +import ( + "applet/app/db/model" +) + +// MallGoodsListReq +// +// Title 标题 +// CategoryId 类目id +// SaleState 销售状态 +// GoodsId 销售状态 +// ActivityType 参加的活动类型 +// PageId 页数 +// PageSize 每页显示记录数 +type MallGoodsListReq struct { + Title string `json:"title"` + CategoryId string `json:"category_id"` + SkuCode string `json:"sku_code"` + SaleState string `json:"sale_state"` + PageId string `json:"pageId"` + PageSize string `json:"pageSize"` + OrderBy string `json:"order_by"` + OrderBySate string `json:"order_by_sate"` +} + +type GoodsRangeData struct { + PriceRange string `json:"price_range"` + LinePriceRange string `json:"line_price_range"` + ProfitRange string `json:"profit_range"` + WeightRange string `json:"weight_range"` +} + +type GoodsListReq struct { + Title string `form:"title"` + MerchantName string `form:"merchant_name"` + PageId string `form:"page"` + PageSize string `form:"limit"` +} + +type GoodListResp struct { + GoodsId int64 `json:"id"` // 商品id + Price float64 `json:"price"` + CreateTime string `json:"create_time"` + UpdateTIme string `json:"update_time"` + Stock int `json:"stock"` + SkuList []*model.Sku `json:"sku_list"` + SaleCount int `json:"sale_count"` + Title string `json:"title"` + Image string `json:"image"` + State string `json:"state"` +} diff --git a/app/admin/md/md_role.go b/app/admin/md/md_role.go index 825132a..6fb4306 100644 --- a/app/admin/md/md_role.go +++ b/app/admin/md/md_role.go @@ -49,6 +49,7 @@ type AdminListReq struct { Page int `json:"page" ` UserName string `json:"username"` State int `json:"state"` + RoleId int `json:"role_id"` } type AdminListResp struct { diff --git a/app/admin/svc/category/svc_index.go b/app/admin/svc/category/svc_index.go new file mode 100644 index 0000000..19561cb --- /dev/null +++ b/app/admin/svc/category/svc_index.go @@ -0,0 +1,233 @@ +package svc + +import ( + "applet/app/admin/md" + "applet/app/db" + "applet/app/db/model" + "applet/app/utils" + "errors" + "github.com/gin-gonic/gin" + "reflect" + "time" + "xorm.io/xorm" +) + +func List(c *gin.Context) ([]map[string]interface{}, error) { + engine := db.Db + //1、获取当前主营类目下所有 一级类目 + firstCategoryList, err := db.GetCategoryList(engine, "1") + if err != nil { + return nil, err + } + var firstCategoryListIds []int + for _, v := range *firstCategoryList { + firstCategoryListIds = append(firstCategoryListIds, v.Id) + } + + //2、获取所有 二级类目 + secondCategoryList, _ := db.CategoryListFindByParams(engine, map[string]interface{}{ + "key": "pid", + "value": firstCategoryListIds, + }) + var secondCategoryListIds []int + for _, v := range *secondCategoryList { + secondCategoryListIds = append(secondCategoryListIds, v.Id) + } + + var tempResult = map[string][]map[string]interface{}{} + for _, v := range *secondCategoryList { + var tmp = map[string]interface{}{} + tmp["id"] = v.Id + tmp["pid"] = v.Pid + tmp["name"] = v.Name + tmp["level"] = v.Level + tmp["create_at"] = v.CreateAt + tmp["update_at"] = v.UpdateAt + tempResult[utils.AnyToString(v.Pid)] = append(tempResult[utils.AnyToString(v.Pid)], tmp) + } + + var result []map[string]interface{} + for _, v := range *firstCategoryList { + var temp = map[string]interface{}{} + temp["id"] = v.Id + temp["pid"] = v.Pid + temp["name"] = v.Name + temp["level"] = v.Level + temp["create_at"] = v.CreateAt + temp["update_at"] = v.UpdateAt + temp["child"] = tempResult[utils.AnyToString(v.Id)] + result = append(result, temp) + } + return result, nil +} + +func Add(c *gin.Context, name string, pid string) error { + engine := db.Db + var level = 1 + if pid != "0" { + fatherCategory, err := db.GetCategoryById(engine, pid) + if err != nil { + return err + } + if fatherCategory == nil { + return errors.New("未找到该分类的父类") + } + level = fatherCategory.Level + 1 + } + m := model.GoodsCategory{ + Name: name, + Level: level, + Pid: utils.StrToInt(pid), + CreateAt: time.Now().Format("2006-01-02 15:04:05"), + UpdateAt: time.Now().Format("2006-01-02 15:04:05"), + } + _, err := db.CategoryInsert(engine, &m) + if err != nil { + return err + } + return nil +} + +func Del(c *gin.Context, categoryId string) error { + engine := db.Db + delModel := new(model.GoodsCategory) + _, err := engine.ID(categoryId).Delete(delModel) + if err != nil { + return err + } + _, err = engine.Table("goods_category").Where("pid = ?", categoryId).Delete(new(model.GoodsCategory)) + if err != nil { + return err + } + return nil +} + +func Sort(c *gin.Context, ids []string) error { + engine := db.Db + categoryList, _ := db.CategoryListFindByParams(engine, map[string]interface{}{ + "key": "id", + "value": ids, + }) + for _, v := range *categoryList { + err := db.UpdateCategoryById(engine, &v) + if err != nil { + return err + } + } + return nil +} + +func Save(c *gin.Context, data map[string]interface{}) error { + engine := db.Db + //todo::处理一级类目 + err := db.UpdateOrInsert(engine, &model.GoodsCategory{ + Id: utils.StrToInt(utils.AnyToString(data["id"])), + Pid: utils.StrToInt(utils.AnyToString(data["pid"])), + Name: utils.AnyToString(data["name"]), + Level: 1, + CreateAt: utils.AnyToString(data["create_at"]), + UpdateAt: time.Now().Format("2006-01-02 15:04:05"), + }) + if err != nil { + return err + } + + if data["child"] != nil { + //todo::有二级类目 + child := reflect.ValueOf(data["child"]) + if child.Len() > 0 { + //1、查询出所有三级类目 + secondCategoryListData, _ := db.CategoryListFindByParams(engine, map[string]interface{}{ + "key": "pid", + "value": data["id"], + }) + var secondCategoryList = map[string]interface{}{} + for _, secondCategory := range *secondCategoryListData { + secondCategoryList[utils.AnyToString(secondCategory.Id)] = secondCategory + } + + tempSave := map[string]interface{}{} + for i := 0; i < child.Len(); i++ { + tempChild := child.Index(i).Interface().(map[string]interface{}) + tempSave[utils.AnyToString(tempChild["id"])] = tempChild + m := &model.GoodsCategory{ + Id: utils.StrToInt(utils.AnyToString(tempChild["id"])), + Pid: utils.StrToInt(utils.AnyToString(data["id"])), + Name: utils.AnyToString(tempChild["name"]), + Level: 2, + CreateAt: utils.AnyToString(tempChild["create_at"]), + UpdateAt: time.Now().Format("2006-01-02 15:04:05"), + } + err := db.UpdateOrInsert(engine, m) + if err != nil { + return err + } + } + + for key, _ := range secondCategoryList { + if tempSave[key] == nil { + engine.Where("id=?", key).Delete(model.GoodsCategory{}) + } + } + } else { + //删除所有二级类目 + engine.Where("pid=?", data["id"]).Delete(model.GoodsCategory{}) + } + } else { + //删除所有二级类目 + engine.Where("pid=?", data["id"]).Delete(model.GoodsCategory{}) + } + return nil +} + +func GetAllCategory(c *gin.Context) (interface{}, error) { + engine := db.Db + var result interface{} + result, err := MakeCategoryOptionV2(engine) + if err != nil { + return nil, err + } + return result, nil +} + +// 按照父级子级进行分类 +func MakeCategoryOptionV2(engine *xorm.Engine) ([]md.CateGoryTreeList, error) { + //1、获取当前主营类目下所有 一级类目 + firstCategoryList, err := db.GetCategoryList(engine, "1") + if err != nil { + return nil, err + } + var firstCategoryListIds []int + for _, v := range *firstCategoryList { + firstCategoryListIds = append(firstCategoryListIds, v.Id) + } + //2、获取所有 二级类目 + secondCategoryList, _ := db.CategoryListFindByParams(engine, map[string]interface{}{ + "key": "pid", + "value": firstCategoryListIds, + }) + + var tempResult = map[string][]md.CateGoryTreeList{} + for _, v := range *secondCategoryList { + tempResult[utils.AnyToString(v.Pid)] = append(tempResult[utils.AnyToString(v.Pid)], md.CateGoryTreeList{ + Id: v.Id, + Pid: v.Pid, + Name: v.Name, + CreateAt: v.CreateAt, + UpdateAt: v.CreateAt, + }) + } + + var result []md.CateGoryTreeList + for _, v := range *firstCategoryList { + result = append(result, md.CateGoryTreeList{ + Id: v.Id, + Pid: v.Pid, + Name: v.Name, + CreateAt: v.CreateAt, + UpdateAt: v.CreateAt, + Children: tempResult[utils.AnyToString(v.Id)], + }) + } + return result, nil +} diff --git a/app/admin/svc/goods/svc_goods.go b/app/admin/svc/goods/svc_goods.go new file mode 100644 index 0000000..c447105 --- /dev/null +++ b/app/admin/svc/goods/svc_goods.go @@ -0,0 +1,444 @@ +package goods + +import ( + "applet/app/admin/enum" + "applet/app/admin/md" + "applet/app/db" + "applet/app/db/model" + "applet/app/e" + "applet/app/svc" + "applet/app/utils" + "applet/app/utils/logx" + "fmt" + "github.com/gin-gonic/gin" + "github.com/jinzhu/copier" + "github.com/pkg/errors" + "reflect" + "strings" + "time" +) + +// 处理图片 +func DealImg(c *gin.Context, imageListUrl []string) []string { + //七牛云配置 + scheme, host, subDomain, moreSubDomain := svc.ImageBucketNew(c) + domain := fmt.Sprintf("%s://%s/", scheme, host) + secondDomain := fmt.Sprintf("%s://%s/", scheme, subDomain) + fmt.Println("") + //处理图片链接 + for k, v := range imageListUrl { + imageListUrl[k] = strings.ReplaceAll(v, domain, "{{host}}") + imageListUrl[k] = strings.ReplaceAll(imageListUrl[k], secondDomain, "{{subhost}}") + //兼容商品是迁移过来的 + for moreK, moreV := range moreSubDomain { + keys := strings.ReplaceAll(moreK, "file_bucket_sub_host", "") + moreDomain := fmt.Sprintf("%s://%s/", scheme, moreV) + imageListUrl[k] = strings.ReplaceAll(imageListUrl[k], moreDomain, "{{subhost"+keys+"}}") + } + } + return imageListUrl +} + +// AddMallGoods 添加、编辑商品 +func AddMallGoods(c *gin.Context, req *md.AddGoodsReq) error { + if req.Base.GoodsId != "" { + _, has, err := db.GetComm(db.Db, &model.Goods{GoodsId: utils.StrToInt64(req.Base.GoodsId)}) + if err != nil { + return e.NewErr(e.ERR_DB_ORM, err.Error()) + } + if !has { + return e.NewErr(e.ERR_INVALID_ARGS, "编辑的商品ID不存在") + } + } + + sess := db.Db.NewSession() + defer func() { + _ = sess.Close() + }() + err := sess.Begin() + if err != nil { + return e.NewErr(e.ERR_DB_ORM, err.Error()) + } + + // 基本信息保存 + var goodsModel model.Goods + err = copier.Copy(&goodsModel, req.Base) + goodsModel.GoodsId = utils.StrToInt64(req.Base.GoodsId) + if err != nil { + return e.NewErr(e.ERR_DB_ORM, err.Error()) + } + now := time.Now() + goodsModel.SaleState = int(enum.MallGoodsSaleStateOnShelf) + goodsModel.CreateAt = now.Format("2006-01-02 03:04:05") + goodsModel.UpdateAt = now.Format("2006-01-02 03:04:05") + //处理图片链接 + req.Base.ImageListUrl = DealImg(c, req.Base.ImageList) + goodsModel.ImageList = utils.SerializeStr(req.Base.ImageListUrl) + goodsModel.Spe = utils.SerializeStr(req.Base.Spe) + //处理图片链接 + req.Base.DetailUrl = DealImg(c, req.Base.Detail) + goodsModel.Detail = utils.SerializeStr(req.Base.DetailUrl) // detail为详情图列表 + + if req.Base.GoodsId == "" { + category, err := db.GetCategoryById(db.Db, utils.AnyToString(req.Base.CategoryId)) + if err != nil { + _ = sess.Rollback() + return err + } + goodsId, err := MakeGoodsId(c, utils.AnyToString(category.Id)) + if err != nil { + _ = sess.Rollback() + return err + } + goodsModel.GoodsId = utils.StrToInt64(goodsId) + affect, err := sess.Insert(&goodsModel) + if err != nil || affect != 1 { + _ = sess.Rollback() + return e.NewErr(e.ERR_DB_ORM, "插入商品失败") + } + } else { + affect, err := sess.Where("goods_id=?", req.Base.GoodsId).AllCols().Update(&goodsModel) + if err != nil || affect != 1 { + return e.NewErr(e.ERR_DB_ORM, "更新商品失败") + } + } + + // 统计总库存 + + // sku保存 + // 创建商品,则全部为插入 + skuModelList := make([]*model.Sku, 0, len(req.SkuList)) + for key, item := range req.SkuList { + skuModelList = append(skuModelList, &model.Sku{ + SkuId: utils.StrToInt64(utils.AnyToString(goodsModel.GoodsId) + utils.AnyToString(key)), + GoodsId: goodsModel.GoodsId, + SkuCode: item.SkuCode, + Price: item.Price, + Indexes: GetIndexesStr(&req.Base, item), + Sku: utils.SerializeStr(&item.Sku), + CreateAt: now.Format("2006-01-02 03:04:05"), + UpdateAt: now.Format("2006-01-02 03:04:05"), + }) + } + if req.Base.GoodsId != "" { + // 如果是更新 先删除旧的再插入 + _, err = sess.Delete(&model.Sku{GoodsId: goodsModel.GoodsId}) + if err != nil { + return e.NewErr(e.ERR_DB_ORM, "规格更新失败") + } + } + + // 插入sku + insert, err := sess.Insert(skuModelList) + if err != nil { + fmt.Println(err) + logx.Warn(err) + return err + } + if insert < 1 { + return e.NewErr(e.ERR_DB_ORM, "插入商品规格失败") + } + + err = sess.Commit() + if err != nil { + return e.NewErr(e.ERR_DB_ORM, "更新商品失败") + } + return nil +} + +// EditMallGoods 編辑商品 +func EditMallGoods(c *gin.Context, req *md.AddGoodsReq) error { + _, has, err := db.GetComm(db.Db, &model.Goods{GoodsId: utils.StrToInt64(req.Base.GoodsId)}) + if err != nil { + return e.NewErr(e.ERR_DB_ORM, err.Error()) + } + if !has { + return e.NewErr(e.ERR_INVALID_ARGS, "编辑的商品ID不存在") + } + + sess := db.Db.NewSession() + defer func() { + _ = sess.Close() + }() + err = sess.Begin() + if err != nil { + return e.NewErr(e.ERR_DB_ORM, err.Error()) + } + + // 基本信息保存 + var goodsModel model.Goods + err = copier.Copy(&goodsModel, req.Base) + goodsModel.GoodsId = utils.StrToInt64(req.Base.GoodsId) + if err != nil { + return e.NewErr(e.ERR_DB_ORM, err.Error()) + } + now := time.Now() + goodsModel.UpdateAt = now.Format("2006-01-02 03:04:05") + //处理图片链接 + req.Base.ImageListUrl = DealImg(c, req.Base.ImageList) + goodsModel.ImageList = utils.SerializeStr(req.Base.ImageListUrl) + goodsModel.Spe = utils.SerializeStr(req.Base.Spe) + //处理图片链接 + req.Base.DetailUrl = DealImg(c, req.Base.Detail) + goodsModel.Detail = utils.SerializeStr(req.Base.DetailUrl) // detail为详情图列表 + + if req.Base.GoodsId == "" { + goodsModel.SaleState = 0 + affect, err := sess.Insert(&goodsModel) + if err != nil || affect != 1 { + _ = sess.Rollback() + return e.NewErr(e.ERR_DB_ORM, "插入商品失败") + + } + } else { + _, err := sess.Where("goods_id=?", req.Base.GoodsId).AllCols().Update(&goodsModel) + if err != nil { + return e.NewErr(e.ERR_DB_ORM, "更新商品失败") + } + } + + // sku保存 + // 创建商品,则全部为插入 + skuModelList := make([]*model.Sku, 0, len(req.SkuList)) + for key, item := range req.SkuList { + skuModelList = append(skuModelList, &model.Sku{ + SkuId: utils.StrToInt64(utils.AnyToString(goodsModel.GoodsId) + "0" + utils.AnyToString(key)), + GoodsId: goodsModel.GoodsId, + Price: item.Price, + SkuCode: item.SkuCode, + Indexes: GetIndexesStr(&req.Base, item), + Sku: utils.SerializeStr(&item.Sku), + CreateAt: now.Format("2006-01-02 03:04:05"), + UpdateAt: now.Format("2006-01-02 03:04:05"), + }) + } + //先删除旧的再插入 + _, err = sess.Delete(&model.Sku{GoodsId: goodsModel.GoodsId}) + if err != nil { + return e.NewErr(e.ERR_DB_ORM, "规格更新失败") + } + + // 插入sku + insert, err := sess.Insert(skuModelList) + if err != nil || insert < 1 { + return e.NewErr(e.ERR_DB_ORM, "插入商品规格失败") + } + + err = sess.Commit() + if err != nil { + return e.NewErr(e.ERR_DB_ORM, "更新商品失败") + } + return nil +} + +// GetIndexesStr sku属性值在spe中的index +func GetIndexesStr(baseGoods *md.MallBaseGoods, goodsSku *md.MallGoodsSku) string { + spe := baseGoods.Spe + sku := goodsSku.Sku + + result := "" + + for index, item := range sku { + for _, itm := range spe { + if item.Name == itm.Name { + for i, v := range spe[index].Values { + if v == item.Value { + result = result + utils.IntToStr(i) + "-" + } + } + } + } + } + + return strings.Trim(result, "-") +} + +func MallGoodsDetail(c *gin.Context, id int) (map[string]interface{}, error) { + resp := make(map[string]interface{}) + var skuList []*model.Sku + var goodsModel *model.Goods + + // 新增商品的时候默认数据 + if id == 0 { + resp["base_goods"] = nil + resp["sku"] = nil + return resp, nil + } + + goodsModelInterface, has, err := db.GetComm(db.Db, &model.Goods{GoodsId: int64(id)}) + if !has { + return nil, errors.New("当前商品不存在") + } + if err != nil { + _ = logx.Error(err) + return nil, e.NewErr(e.ERR_DB_ORM, fmt.Sprintf("查询商品失败:%#v", err)) + } + goodsModel = goodsModelInterface.(*model.Goods) + + err = db.Db.Where("goods_id=?", id).Find(&skuList) + if err != nil || len(skuList) == 0 { + _ = logx.Error(err) + return nil, e.NewErr(e.ERR_DB_ORM, fmt.Sprintf("查询商品规格失败:%#v\n", err)) + } + + var goodsMap map[string]interface{} + utils.Unserialize([]byte(utils.SerializeStr(goodsModel)), &goodsMap) + goodsMap["goods_id"] = utils.AnyToString(goodsModel.GoodsId) + // 分类名称 + if goodsModel != nil && goodsModel.CategoryId != 0 { + categoryInterface, has, err := db.GetComm(db.Db, &model.GoodsCategory{Id: goodsModel.CategoryId}) + if err != nil { + return nil, errors.New("查询商品类目失败") + } + categoryModel := categoryInterface.(*model.GoodsCategory) + if !has { + goodsMap["category_name"] = "" + } else { + goodsMap["category_name"] = categoryModel.Name + } + } + + // **处理各复合结构** + var tmpMap interface{} + + scheme, host, subDomain, moreSubDomain := svc.ImageBucketNew(c) + + // 商品主图 + if goodsMap["image_list"] != nil && goodsMap["image_list"] != "null" { + utils.Unserialize([]byte(goodsMap["image_list"].(string)), &tmpMap) + goodsMap["image_list"] = tmpMap + var imageListUrlTmp []string + for _, v := range goodsMap["image_list"].([]interface{}) { + imageListUrlTmp = append(imageListUrlTmp, svc.ImageFormatWithBucketNew(scheme, host, subDomain, moreSubDomain, v.(string))) + } + goodsMap["image_list_url"] = imageListUrlTmp + } else { + goodsMap["image_list"] = []struct{}{} + goodsMap["image_list_url"] = []struct{}{} + } + + // 详情图 + if goodsMap["detail"] != nil && goodsMap["detail"] != "null" { + var tmpDetailImageList []interface{} + utils.Unserialize([]byte(goodsMap["detail"].(string)), &tmpDetailImageList) + goodsMap["detail"] = tmpDetailImageList + var detailImageUrlTmp []string + for _, v := range goodsMap["detail"].([]interface{}) { + detailImageUrlTmp = append(detailImageUrlTmp, svc.ImageFormatWithBucketNew(scheme, host, subDomain, moreSubDomain, v.(string))) + } + goodsMap["detail_url"] = detailImageUrlTmp + } + + if goodsMap["detail"] == nil || reflect.ValueOf(goodsMap["detail"]).IsNil() { + goodsMap["detail"] = []interface{}{} + goodsMap["detail_url"] = []interface{}{} + } + + // 规格属性 + speJson, ok := goodsMap["spe"].(string) + if ok { + if goodsMap["spe"] != nil && speJson != "" && speJson != "null" { + utils.Unserialize([]byte(speJson), &tmpMap) + goodsMap["spe"] = tmpMap + } else { + utils.Unserialize([]byte("[{\"name\": \"默认\",\"values\": [\"默认\"]}]"), &tmpMap) + goodsMap["spe"] = tmpMap + } + } else { + utils.Unserialize([]byte("[{\"name\": \"默认\",\"values\": [\"默认\"]}]"), &tmpMap) + goodsMap["spe"] = tmpMap + } + if goodsMap["spe_images"] != nil && goodsMap["spe_images"] != "null" && goodsMap["spe_images"] != "[]" && goodsMap["spe_images"] != "" { + var speImageListUrlTmp []string + utils.Unserialize([]byte(goodsMap["spe_images"].(string)), &tmpMap) + goodsMap["spe_images"] = tmpMap + for _, v := range goodsMap["spe_images"].([]interface{}) { + speImageListUrlTmp = append(speImageListUrlTmp, svc.ImageFormatWithBucketNew(scheme, host, subDomain, moreSubDomain, v.(string))) + } + goodsMap["spe_images_url"] = speImageListUrlTmp + } else { + goodsMap["spe_images"] = []struct{}{} + goodsMap["spe_images_url"] = []struct{}{} + } + + // sku处理 + skuListMap := make([]map[string]interface{}, 0, len(skuList)) + for _, item := range skuList { + tmp := make(map[string]interface{}) + tmp["goods_id"] = item.GoodsId + tmp["sku_id"] = item.SkuId + tmp["sku_code"] = item.SkuCode + tmp["price"] = item.Price + tmp["indexes"] = item.Indexes + utils.Unserialize([]byte(item.Sku), &tmpMap) + tmp["sku"] = tmpMap + if item.Indexes == "" || item.Indexes == " " { + tmp["indexes"] = "0" + utils.Unserialize([]byte("[{\"name\": \"默认\",\"values\": [\"默认\"]}]"), &tmpMap) + tmp["sku"] = tmpMap + } + skuListMap = append(skuListMap, tmp) + } + + // 清理不用的字段 + if _, ok := goodsMap["create_time"]; ok { + delete(goodsMap, "create_at") + } + if _, ok := goodsMap["update_time"]; ok { + delete(goodsMap, "update_at") + } + if _, ok := goodsMap["delete_at"]; ok { + delete(goodsMap, "delete_at") + } + + goodsMap["sale_state_zh"] = "" + if _, ok := goodsMap["sale_state"]; ok { + switch goodsMap["sale_state"] { + case 1.00: + goodsMap["sale_state_zh"] = "销售中" + break + case 2.00: + goodsMap["sale_state_zh"] = "下架" + break + } + } + + goodsMap["create_at"] = goodsModel.CreateAt + goodsMap["update_at"] = goodsModel.UpdateAt + + resp["base_goods"] = goodsMap + resp["sku"] = skuListMap + + return resp, nil + +} + +func MakeGoodsId(c *gin.Context, categoryId string) (string, error) { + + var goodsId = categoryId + utils.AnyToString(time.Now().UnixNano()/1e6) + + return goodsId, nil +} + +func DelMallGoods(c *gin.Context, ids []string) { + engine := db.Db + session := engine.NewSession() + defer func() { + session.Close() + }() + session.Begin() + _, err := session.Table("goods").Where(fmt.Sprintf("goods_id in (%s)", strings.Join(ids, ","))).Delete(new(model.Goods)) + if err != nil { + session.Rollback() + e.OutErr(c, e.ERR_DB_ORM, err) + return + } + _, err = session.Table("sku").In("goods_id", ids).Delete(new(model.Sku)) + if err != nil { + session.Rollback() + e.OutErr(c, e.ERR_DB_ORM, err) + return + } + session.Commit() + e.OutSuc(c, []int{}, nil) +} diff --git a/app/admin/svc/goods/svc_goods_list.go b/app/admin/svc/goods/svc_goods_list.go new file mode 100644 index 0000000..d0af935 --- /dev/null +++ b/app/admin/svc/goods/svc_goods_list.go @@ -0,0 +1,70 @@ +package goods + +import ( + "applet/app/admin/md" + "applet/app/db" + "applet/app/svc" + "applet/app/utils" + "github.com/gin-gonic/gin" +) + +// 获取列表数据 +func GetMallGoodsList(c *gin.Context, req *md.MallGoodsListReq) (interface{}, int64, error) { + var goodsListResp []md.MallGoodListResp + // 获取分库链接 + engine := db.Db + // 查询goods数据表获取数据 + mallGoodsList, skus, total, err := db.GetMallGoodsListLeftOnMallSku(engine, req) + if err != nil { + return nil, 0, err + } + var tmpMap interface{} + scheme, host, subDomain, moreSubDomain := svc.ImageBucketNew(c) + + if err != nil { + return nil, 0, err + } + + for _, item := range mallGoodsList { + var goods md.MallGoodListResp + goods.GoodsId = item["goods_id"] + goods.SaleState = utils.StrToInt(item["sale_state"]) + goods.CreateAt = item["create_at"] + + // 商品主图 + if item["image_list"] != "" { + utils.Unserialize([]byte(item["image_list"]), &tmpMap) + var imageListUrlTmp []string + for _, v := range tmpMap.([]interface{}) { + imageListUrlTmp = append(imageListUrlTmp, svc.ImageFormatWithBucketNew(scheme, host, subDomain, moreSubDomain, v.(string))) + } + if imageListUrlTmp != nil { + goods.Image = imageListUrlTmp[0] + } + } + + goods.UpdateAt = item["update_at"] + goods.Title = item["title"] + + // sku + for _, skuItem := range skus { + if skuItem.GoodsId == utils.StrToInt64(item["goods_id"]) { + goods.SkuList = append(goods.SkuList, skuItem) + } + } + // 获取价格、库存、重量范围、利润空间 + goods.Price = item["price"] + goodsListResp = append(goodsListResp, goods) + } + + return goodsListResp, total, err +} + +func CheckSkuCode(c *gin.Context, skuCode, goodsId string) (bool, error) { + engine := db.Db + isHas, _, err := db.GetMallSkuBySkuCode(engine, skuCode, goodsId) + if err != nil { + return false, err + } + return isHas, nil +} diff --git a/app/admin/svc/svc_enterprise.go b/app/admin/svc/svc_enterprise.go new file mode 100644 index 0000000..dbe409b --- /dev/null +++ b/app/admin/svc/svc_enterprise.go @@ -0,0 +1,21 @@ +package svc + +import ( + "applet/app/db" +) + +func EnterpriseDelete(enterpriseIds []int) (err error) { + session := db.Db.NewSession() + defer session.Close() + session.Begin() + //1、删除所在单位 + enterpriseDb := db.EnterpriseDb{} + enterpriseDb.Set() + _, err = enterpriseDb.EnterpriseDeleteBySession(session, enterpriseIds) + if err != nil { + _ = session.Rollback() + return + } + + return session.Commit() +} diff --git a/app/db/db_category.go b/app/db/db_category.go new file mode 100644 index 0000000..19ea479 --- /dev/null +++ b/app/db/db_category.go @@ -0,0 +1,116 @@ +package db + +import ( + "applet/app/db/model" + "applet/app/utils" + "applet/app/utils/logx" + "errors" + "fmt" + "reflect" + "time" + "xorm.io/xorm" +) + +// 获取所有类目原始数据 +func GetAllCategory(Db *xorm.Engine) (GoodsCategoryList *[]model.GoodsCategory, err error) { + var categoryList []model.GoodsCategory + err = Db.Find(&categoryList) + GoodsCategoryList = &categoryList + return +} + +func GetCategoryList(Db *xorm.Engine, level string) (GoodsCategoryList *[]model.GoodsCategory, err error) { + var categoryList []model.GoodsCategory + if level == "" { + err = Db.Find(&categoryList) + } else { + err = Db.Where("level = ?", level).Find(&categoryList) + } + + GoodsCategoryList = &categoryList + return +} + +// CategoryListFindByParams 通过传入的参数查询数据(多条) +func CategoryListFindByParams(Db *xorm.Engine, params map[string]interface{}) (*[]model.GoodsCategory, error) { + var m []model.GoodsCategory + if params["value"] == nil { + return nil, errors.New("参数有误") + } + if params["key"] == nil { + //查询全部数据 + err := Db.Find(&m) + if err != nil { + return nil, logx.Error(err) + } + return &m, nil + } else { + if reflect.TypeOf(params["value"]).Kind() == reflect.Slice { + //指定In查询 + if err := Db.In(utils.AnyToString(params["key"]), params["value"]).Find(&m); err != nil { + return nil, logx.Warn(err) + } + return &m, nil + } else { + var query = fmt.Sprintf("%s =?", params["key"]) + err := Db.Where(query, params["value"]).Find(&m) + if err != nil { + return nil, logx.Error(err) + } + return &m, nil + } + + } +} + +func GetCategoryById(Db *xorm.Engine, pid string) (GoodsCategoryList *model.GoodsCategory, err error) { + var m model.GoodsCategory + has, err := Db.Where("id=?", pid).Get(&m) + if has == false || err != nil { + return nil, err + } + return &m, nil +} + +func UpdateCategoryById(eg *xorm.Engine, m *model.GoodsCategory, columns ...string) error { + var ( + affected int64 + err error + ) + if columns == nil || len(columns) == 0 { + affected, err = eg.Where("id = ?", m.Id).AllCols().Update(m) + } else { + affected, err = eg.Where("id = ?", m.Id).Cols(columns...).Update(m) + } + if err != nil { + return err + } + if affected == 0 { + return errors.New("更新类目数据失败,稍后再试") + } + return nil +} + +func CategoryInsert(Db *xorm.Engine, m *model.GoodsCategory) (int, error) { + _, err := Db.InsertOne(m) + if err != nil { + return 0, err + } + return m.Id, nil +} + +func UpdateOrInsert(Db *xorm.Engine, m *model.GoodsCategory) error { + if m.Id != 0 { + err := UpdateCategoryById(Db, m) + if err != nil { + return err + } + } else { + m.CreateAt = time.Now().Format("2006-01-02 15:04:05") + _, err := CategoryInsert(Db, m) + if err != nil { + return err + } + } + return nil +} diff --git a/app/db/db_company.go b/app/db/db_company.go new file mode 100644 index 0000000..b624289 --- /dev/null +++ b/app/db/db_company.go @@ -0,0 +1,87 @@ +package db + +import ( + "applet/app/db/model" + "applet/app/utils/logx" + "reflect" + "xorm.io/xorm" +) + +type CompanyDb struct { + Db *xorm.Engine `json:"db"` +} + +func (companyDb *CompanyDb) Set() { // set方法 + companyDb.Db = Db +} + +func (companyDb *CompanyDb) GetCompany(id int) (m *model.Company, err error) { + m = new(model.Company) + has, err := companyDb.Db.Where("id =?", id).Get(m) + if err != nil { + return nil, logx.Error(err) + } + if has == false { + return nil, nil + } + return m, nil +} + +func (companyDb *CompanyDb) FindCompany(limit, start int) (*[]model.Company, error) { + var m []model.Company + if limit == 0 || start == 0 { + if err := companyDb.Db.Desc("id").Find(&m); err != nil { + return nil, logx.Error(err) + } + } else { + if err := companyDb.Db.Desc("id").Limit(limit, start).Find(m); err != nil { + return nil, logx.Error(err) + } + } + return &m, nil +} + +func (companyDb *CompanyDb) GetCompanyByName(name string) (m *model.Company, err error) { + m = new(model.Company) + has, err := companyDb.Db.Where("name =?", name).Get(m) + if err != nil { + return nil, logx.Error(err) + } + if has == false { + return nil, nil + } + return m, nil +} + +func (companyDb *CompanyDb) CompanyInsert(m *model.Company) (int, error) { + _, err := companyDb.Db.InsertOne(m) + if err != nil { + return 0, err + } + return m.Id, nil +} + +func (companyDb *CompanyDb) CompanyUpdate(m *model.Company, columns ...string) (int64, error) { + affected, err := companyDb.Db.Where("id =?", m.Id).Cols(columns...).Update(m) + if err != nil { + return 0, err + } + return affected, nil +} + +func (companyDb *CompanyDb) CompanyDelete(id interface{}) (int64, error) { + if reflect.TypeOf(id).Kind() == reflect.Slice { + return Db.In("id", id).Delete(model.Company{}) + } else { + return Db.Where("id = ?", id).Delete(model.Company{}) + } +} + +type EnterpriseWithCompany struct { + model.Enterprise `xorm:"extends"` + model.Company `xorm:"extends"` +} + +func (EnterpriseWithCompany) TableName() string { + return "enterprise" +} diff --git a/app/db/db_enterprise.go b/app/db/db_enterprise.go new file mode 100644 index 0000000..6991974 --- /dev/null +++ b/app/db/db_enterprise.go @@ -0,0 +1,78 @@ +package db + +import ( + "applet/app/db/model" + "applet/app/utils/logx" + "reflect" + "xorm.io/xorm" +) + +type EnterpriseDb struct { + Db *xorm.Engine `json:"db"` +} + +func (enterpriseDb *EnterpriseDb) Set() { // set方法 + enterpriseDb.Db = Db +} + +func (enterpriseDb *EnterpriseDb) GetEnterprise(id int) (m *model.Enterprise, err error) { + m = new(model.Enterprise) + has, err := enterpriseDb.Db.Where("id =?", id).Get(m) + if err != nil { + return nil, logx.Error(err) + } + if has == false { + return nil, nil + } + return m, nil +} + +func (enterpriseDb *EnterpriseDb) EnterpriseDeleteBySession(session *xorm.Session, id interface{}) (int64, error) { + if reflect.TypeOf(id).Kind() == reflect.Slice { + return session.In("id", id).Delete(model.Enterprise{}) + } else { + return session.Where("id = ?", id).Delete(model.Enterprise{}) + } +} + +func (enterpriseDb *EnterpriseDb) FindEnterprise(limit, start int) (*[]model.Enterprise, error) { + var m []model.Enterprise + if limit == 0 || start == 0 { + if err := enterpriseDb.Db.Desc("id").Find(&m); err != nil { + return nil, logx.Error(err) + } + } else { + if err := enterpriseDb.Db.Desc("id").Limit(limit, start).Find(m); err != nil { + return nil, logx.Error(err) + } + } + return &m, nil +} + +func (enterpriseDb *EnterpriseDb) GetEnterpriseByName(name string) (m *model.Enterprise, err error) { + m = new(model.Enterprise) + has, err := enterpriseDb.Db.Where("name =?", name).Get(m) + if err != nil { + return nil, logx.Error(err) + } + if has == false { + return nil, nil + } + return m, nil +} + +func (enterpriseDb *EnterpriseDb) EnterpriseInsert(m *model.Enterprise) (int, error) { + _, err := enterpriseDb.Db.InsertOne(m) + if err != nil { + return 0, err + } + return m.Id, nil +} + +func (enterpriseDb *EnterpriseDb) EnterpriseUpdate(m *model.Enterprise, columns ...string) (int64, error) { + affected, err := enterpriseDb.Db.Where("id =?", m.Id).Cols(columns...).Update(m) + if err != nil { + return 0, err + } + return affected, nil +} diff --git a/app/db/db_goods_list.go b/app/db/db_goods_list.go new file mode 100644 index 0000000..357cb2b --- /dev/null +++ b/app/db/db_goods_list.go @@ -0,0 +1,277 @@ +package db + +import ( + "applet/app/admin/md" + "applet/app/db/model" + "applet/app/utils" + "applet/app/utils/logx" + "errors" + "fmt" + "reflect" + "strings" + "xorm.io/xorm" +) + +// 递归获取所以下级 +func GetCateIds(engine *xorm.Engine, cateList []string, ids []string) []string { + var cateIds []string + var list []string + for _, v := range cateList { + ids = append(ids, v) + err := engine.Table("goods_category").Where("pid = ?", v).Cols("id").Find(&cateIds) + if err != nil { + continue + } + for _, v1 := range cateIds { + ids = append(ids, v1) + list = append(list, v1) + } + } + if len(list) > 0 { + return GetCateIds(engine, list, ids) + } + return ids + +} + +func GetMallGoodsList(engine *xorm.Engine, req *md.MallGoodsListReq) ([]map[string]string, []model.Sku, int64, error) { + var whereCondition = "1=1" // 用作where的查询条件 + if req.Title != "" { // 按照商品标题查找 + whereCondition = whereCondition + " AND title LIKE '%" + req.Title + "%'" + } + if req.CategoryId != "0" && req.CategoryId != "" { // 类目 + var cateIds = GetCateIds(engine, []string{req.CategoryId}, []string{}) + whereCondition = whereCondition + " AND category_id IN(" + strings.Join(cateIds, ",") + ")" + } + + if req.Title != "" { + whereCondition += " AND title LIKE '%" + req.Title + "%'" + } + + if req.SaleState == "1" { // 销售中 + whereCondition = whereCondition + " AND sale_state = 1" + } else if req.SaleState == "2" { // 已下架 + whereCondition = whereCondition + " AND sale_state = 2" + } + + orderBy := "goods_id DESC" + if req.OrderBySate == "" { + req.OrderBySate = "desc" + } + if req.OrderBySate == "desc" { + switch req.OrderBy { + case "create_desc": + orderBy = "create_at DESC" + } + } + + if req.OrderBySate == "asc" { + switch req.OrderBy { + case "create_desc": + orderBy = "create_at ASC" + } + } + + sql := ` + SELECT * FROM goods WHERE %s ORDER BY %s limit %d, %d +` + + if req.PageId == "0" || req.PageId == "" { + req.PageId = "1" + } + if req.PageSize == "0" || req.PageSize == "" || utils.StrToInt(req.PageSize) > 300 { + req.PageSize = "20" + } + + offset := (utils.StrToInt(req.PageId) - 1) * utils.StrToInt(req.PageSize) + size := utils.StrToInt(req.PageSize) + sql = fmt.Sprintf(sql, whereCondition, orderBy, offset, size) + fmt.Printf("----- %s\n", sql) + mapArr, err := QueryNativeString(engine, sql) + + if err != nil { + return nil, nil, 0, err + } + + // 统计数据记录数 + countSql := "SELECT COUNT(*) as total FROM goods where " + whereCondition + fmt.Printf("----- %s\n", countSql) + totalMap, err := QueryNativeString(engine, countSql) + + if err != nil { + return nil, nil, 0, err + } + + var goodsIds []string + for _, item := range mapArr { + goodsIds = append(goodsIds, item["goods_id"]) + } + var skus []model.Sku + err = engine.Table("sku").In("goods_id", goodsIds).Find(&skus) + + if err != nil { + return nil, nil, 0, err + } + return mapArr, skus, utils.StrToInt64(totalMap[0]["total"]), err +} + +func GetMallGoodsListLeftOnMallSku(engine *xorm.Engine, req *md.MallGoodsListReq) ([]map[string]string, []model.Sku, int64, error) { + var whereCondition = "1=1" // 用作where的查询条件 + + if req.CategoryId != "0" && req.CategoryId != "" { // 类目 + var cateIds = GetCateIds(engine, []string{req.CategoryId}, []string{}) + whereCondition = whereCondition + " AND mg.category_id IN(" + strings.Join(cateIds, ",") + ")" + } + + if req.Title != "" { + whereCondition += " AND mg.title LIKE '%" + req.Title + "%'" + } + + if req.SaleState == "1" { // 销售中 + whereCondition = whereCondition + " AND sale_state = 1" + } else if req.SaleState == "2" { // 已下架 + whereCondition = whereCondition + " AND sale_state = 2" + } + + if req.OrderBySate == "" { + req.OrderBySate = "desc" + } + + orderBy := "mg.create_at DESC" + if req.OrderBySate == "desc" { + switch req.OrderBy { + case "create_desc": + orderBy = "mg.create_at DESC" + case "profit_desc": + orderBy = "mg.profit_rate DESC" + case "sale_count_desc": + orderBy = "mg.sale_count DESC" + } + } + if req.OrderBySate == "asc" { + switch req.OrderBy { + case "create_desc": + orderBy = "mg.create_at ASC" + case "profit_desc": + orderBy = "mg.profit_rate ASC" + case "sale_count_desc": + orderBy = "mg.sale_count ASC" + } + } + + sql := ` + SELECT mg.* FROM goods AS mg WHERE %s GROUP BY %s limit %d, %d +` + + if req.PageId == "0" || req.PageId == "" { + req.PageId = "1" + } + if req.PageSize == "0" || req.PageSize == "" || utils.StrToInt(req.PageSize) > 300 { + req.PageSize = "20" + } + + offset := (utils.StrToInt(req.PageId) - 1) * utils.StrToInt(req.PageSize) + size := utils.StrToInt(req.PageSize) + sql = fmt.Sprintf(sql, whereCondition, orderBy, offset, size) + fmt.Printf("----- %s\n", sql) + mapArr, err := QueryNativeString(engine, sql) + + if err != nil { + return nil, nil, 0, err + } + + // 统计数据记录数 + countSql := "SELECT mg.* FROM goods AS mg WHERE " + whereCondition + " GROUP BY mg.goods_id" + fmt.Printf("----- %s\n", countSql) + totalMap, err := QueryNativeString(engine, countSql) + + if err != nil { + return nil, nil, 0, err + } + + var goodsIds []string + for _, item := range mapArr { + goodsIds = append(goodsIds, item["goods_id"]) + } + var skus []model.Sku + err = engine.Table("sku").In("goods_id", goodsIds).Find(&skus) + + if err != nil { + return nil, nil, 0, err + } + + var total int64 + if totalMap == nil { + total = 0 + } else { + total = int64(len(totalMap)) + } + return mapArr, skus, total, err +} + +func GetALlMallGoodsList(engine *xorm.Engine) ([]model.Goods, error) { + var goodsList []model.Goods + //查詢出所有不是"倉庫中"的產品 + err := engine.Table("goods").Where("sale_state != 3").Find(&goodsList) + if err != nil { + return goodsList, err + } + return goodsList, nil +} + +// MallGoodsFindByParams 通过传入的参数查询数据(多条) +func MallGoodsFindByParams(Db *xorm.Engine, params map[string]interface{}) (*[]model.Goods, error) { + var m []model.Goods + if params["key"] == nil { + //查询全部数据 + err := Db.Find(&m) + if err != nil { + return nil, logx.Error(err) + } + return &m, nil + } else { + if reflect.TypeOf(params["value"]).Kind() == reflect.Slice { + //指定In查询 + if err := Db.In(utils.AnyToString(params["key"]), params["value"]).Find(&m); err != nil { + return nil, logx.Warn(err) + } + return &m, nil + } else { + var query = fmt.Sprintf("%s = ?", params["key"]) + err := Db.Where(query, params["value"]).Find(&m) + if err != nil { + return nil, logx.Error(err) + } + return &m, nil + } + + } +} + +func UpdateMallGoodsByGoodsId(eg *xorm.Engine, m *model.Goods, columns ...string) error { + var ( + affected int64 + err error + ) + if columns == nil || len(columns) == 0 { + affected, err = eg.Where("goods_id = ?", m.GoodsId).AllCols().Update(m) + } else { + affected, err = eg.Where("goods_id = ?", m.GoodsId).Cols(columns...).Update(m) + } + if err != nil { + return err + } + if affected == 0 { + return errors.New("更新数据失败,稍后再试") + } + return nil +} + +func GetMallGoodsById(Db *xorm.Engine, goodsId string) (mm *model.Goods, err error) { + var m model.Goods + has, err := Db.Where("goods_id=?", goodsId).Get(&m) + if has == false || err != nil { + return nil, err + } + return &m, nil +} diff --git a/app/db/db_sku.go b/app/db/db_sku.go new file mode 100644 index 0000000..3cbf791 --- /dev/null +++ b/app/db/db_sku.go @@ -0,0 +1,22 @@ +package db + +import ( + "applet/app/db/model" + "xorm.io/xorm" +) + +func FindSkuByGoodsID(engine *xorm.Engine, goodsId string) ([]*model.Sku, error) { + var skus []*model.Sku + err := engine.Where("goods_id = ?", goodsId).Find(&skus) + return skus, err +} + +func GetMallSkuBySkuCode(engine *xorm.Engine, skuCode, goodsId string) (isHas bool, mm *model.Sku, err error) { + isHas = false + var m model.Sku + isHas, err = engine.Where("sku_code=?", skuCode).And("goods_id!=?", goodsId).Get(&m) + if err != nil { + return isHas, &m, err + } + return isHas, &m, nil +} diff --git a/app/db/model/company.go b/app/db/model/company.go new file mode 100644 index 0000000..e5f8a57 --- /dev/null +++ b/app/db/model/company.go @@ -0,0 +1,12 @@ +package model + +type Company struct { + Id int `json:"id" xorm:"not null pk autoincr INT(11)"` + Name string `json:"name" xorm:"not null default '' comment('名称') VARCHAR(255)"` + State int32 `json:"state" xorm:"not null default 1 comment('状态(1:正常 2:冻结)') TINYINT(1)"` + LeadName string `json:"lead_name" xorm:"not null default '' comment('负责人姓名') VARCHAR(50)"` + LeadPhone string `json:"lead_phone" xorm:"not null default '' comment('负责人手机号') VARCHAR(50)"` + Memo string `json:"memo" xorm:"not null default '' comment('备注信息') VARCHAR(244)"` + CreateAt string `json:"create_at" xorm:"not null default 'CURRENT_TIMESTAMP' DATETIME"` + UpdateAt string `json:"update_at" xorm:"not null default 'CURRENT_TIMESTAMP' DATETIME"` +} diff --git a/app/db/model/enterprise.go b/app/db/model/enterprise.go new file mode 100644 index 0000000..d9c90b5 --- /dev/null +++ b/app/db/model/enterprise.go @@ -0,0 +1,11 @@ +package model + +type Enterprise struct { + Id int `json:"id" xorm:"not null pk autoincr INT(11)"` + Name string `json:"name" xorm:"not null default '' comment('名称') VARCHAR(255)"` + CompanyId int `json:"company_id" xorm:"not null default 0 comment('所属公司id') INT(11)"` + State int32 `json:"state" xorm:"not null default 1 comment('状态(1:正常 2:冻结)') TINYINT(1)"` + Memo string `json:"memo" xorm:"not null default '' comment('备注信息') VARCHAR(244)"` + CreateAt string `json:"create_at" xorm:"not null default 'CURRENT_TIMESTAMP' DATETIME"` + UpdateAt string `json:"update_at" xorm:"not null default 'CURRENT_TIMESTAMP' DATETIME"` +} diff --git a/app/db/model/goods_category.go b/app/db/model/goods_category.go new file mode 100644 index 0000000..646fee2 --- /dev/null +++ b/app/db/model/goods_category.go @@ -0,0 +1,10 @@ +package model + +type GoodsCategory struct { + Id int `json:"id" xorm:"not null pk INT(11)"` + Pid int `json:"pid" xorm:"comment('上级id') index INT(11)"` + Name string `json:"name" xorm:"comment('类目名称') VARCHAR(255)"` + Level int `json:"level" xorm:"comment('类目级别') index INT(3)"` + CreateAt string `json:"create_at" xorm:"default 'CURRENT_TIMESTAMP' comment('创建时间') TIMESTAMP"` + UpdateAt string `json:"update_at" xorm:"default 'CURRENT_TIMESTAMP' comment('更新时间') TIMESTAMP"` +} diff --git a/app/router/admin_router.go b/app/router/admin_router.go index d916aaa..2c8232b 100644 --- a/app/router/admin_router.go +++ b/app/router/admin_router.go @@ -2,6 +2,8 @@ package router import ( "applet/app/admin/hdl" + categoryHdl "applet/app/admin/hdl/category" + goodsHdl "applet/app/admin/hdl/goods" "applet/app/admin/mw" "applet/app/cfg" "github.com/gin-gonic/gin" @@ -34,12 +36,15 @@ func Init() *gin.Engine { }) r.Use(mw.Cors) AdminRoute(r.Group("/api/admin")) - CustomerInit(r.Group("/api/v1")) + IpadInit(r.Group("/api/ipad")) return r } func rCompany(r *gin.RouterGroup) { - + r.GET("/list", hdl.CompanyList) + r.POST("/add", hdl.CompanyAdd) + r.POST("/update", hdl.CompanyUpdate) + r.DELETE("/delete/:id", hdl.CompanyDelete) } func rHomePage(r *gin.RouterGroup) { @@ -68,7 +73,28 @@ func rUser(r *gin.RouterGroup) { } func rEnterprise(r *gin.RouterGroup) { + r.GET("/list", hdl.EnterpriseList) + r.POST("/add", hdl.EnterpriseAdd) + r.POST("/update", hdl.EnterpriseUpdate) + r.POST("/updateState", hdl.EnterpriseUpdateState) + r.POST("/delete", hdl.EnterpriseDelete) +} + +func rCategory(r *gin.RouterGroup) { + r.GET("/list", categoryHdl.List) + r.GET("/add", categoryHdl.Add) + r.GET("/del", categoryHdl.Del) + r.POST("/sort", categoryHdl.Sort) + r.POST("/save", categoryHdl.Save) +} +func rGoods(r *gin.RouterGroup) { + r.POST("/del", goodsHdl.DelMallGoods) + r.POST("/add", goodsHdl.AddMallGoods) + r.GET("/detail", goodsHdl.MallGoodsDetail) + r.GET("/list", goodsHdl.GetMallGoodsList) + r.GET("/checkSkuCode", goodsHdl.CheckSkuCode) + r.POST("/change-sale-state", goodsHdl.ChangeSaleState) } func rRole(r *gin.RouterGroup) { @@ -76,7 +102,7 @@ func rRole(r *gin.RouterGroup) { r.POST("/addRole", hdl.AddRole) //角色添加 r.POST("/roleBindPermissionGroup", hdl.RoleBindPermissionGroup) //角色绑定权限组 r.POST("/updateRoleState", hdl.UpdateRoleState) //修改角色状态 - r.POST("/updateRole", hdl.UpdateRole) //修改角色状态 + r.POST("/updateRole", hdl.UpdateRole) //修改角色 r.DELETE("/deleteRole/:id", hdl.DeleteRole) //删除角色 r.GET("/permissionGroupList", hdl.PermissionGroupList) //权限组列表 r.POST("/adminList", hdl.AdminList) //管理员列表 @@ -106,8 +132,9 @@ func AdminRoute(r *gin.RouterGroup) { rCompany(r.Group("/company")) //公司管理 rBanner(r.Group("/banner")) //轮播图管理 rEnterprise(r.Group("/enterprise")) //校企 + rCategory(r.Group("/category")) //商品类目 + rGoods(r.Group("/goods")) //商品 - // 管理 rRole(r.Group("/role")) //权限管理 rSetCenter(r.Group("/setCenter")) //设置中心 rUser(r.Group("/user")) //用户管理 diff --git a/app/router/customer_router.go b/app/router/ipad_router.go similarity index 82% rename from app/router/customer_router.go rename to app/router/ipad_router.go index 03e6f3a..826a5ae 100644 --- a/app/router/customer_router.go +++ b/app/router/ipad_router.go @@ -5,7 +5,7 @@ import ( "github.com/gin-gonic/gin" ) -func CustomerInit(r *gin.RouterGroup) { +func IpadInit(r *gin.RouterGroup) { rTest(r.Group("/test")) r.Use(mw.Auth) //检测登录状态 diff --git a/app/svc/svc_file_img_format.go b/app/svc/svc_file_img_format.go new file mode 100644 index 0000000..7208cfb --- /dev/null +++ b/app/svc/svc_file_img_format.go @@ -0,0 +1,67 @@ +package svc + +import ( + "applet/app/utils" + "fmt" + "github.com/gin-gonic/gin" + "strings" +) + +// ImageFormat is 格式化 图片 +func ImageFormat(c *gin.Context, name string) string { + if strings.Contains(name, "https:") || strings.Contains(name, "http:") { + return name + } + scheme := SysCfgGet(c, "file_bucket_scheme") + domain := SysCfgGet(c, "file_bucket_host") + return fmt.Sprintf("%s://%s/%s", scheme, domain, name) +} + +// OffImageFormat is 格式化官方 图片 +func OffImageFormat(c *gin.Context, name string) string { + if strings.Contains(name, "https:") || strings.Contains(name, "http:") { + return name + } + return fmt.Sprintf("%s://%s/%s", "http", "ossq.izhyin.cn", name) +} + +// ImageBucket is 获取域名 +func ImageBucket(c *gin.Context) (string, string) { + return SysCfgGet(c, "file_bucket_scheme"), SysCfgGet(c, "file_bucket_host") +} + +// ImageFormatWithBucket is 格式化成oss 域名 +func ImageFormatWithBucket(scheme, domain, name string) string { + return fmt.Sprintf("%s://%s/%s", scheme, domain, name) +} + +// ImageBucketNew is 获取域名 +func ImageBucketNew(c *gin.Context) (string, string, string, map[string]string) { + var list = make(map[string]string, 0) + for i := 1; i < 10; i++ { + keys := "file_bucket_sub_host" + utils.IntToStr(i) + list[keys] = SysCfgGet(c, keys) + } + return SysCfgGet(c, "file_bucket_scheme"), SysCfgGet(c, "file_bucket_host"), SysCfgGet(c, "file_bucket_sub_host"), list +} + +// ImageFormatWithBucket is 格式化成oss 域名 +func ImageFormatWithBucketNew(scheme, domain, subDomain string, moreSubDomain map[string]string, name string) string { + if strings.Contains(name, "http") { + return name + } + if strings.Contains(name, "{{subhost}}") && subDomain != "" { //读副域名 有可能是其他平台的 + domain = subDomain + } + //为了兼容一些客户自营商城导到不同系统 并且七牛云不一样 + for i := 1; i < 10; i++ { + keys := "file_bucket_sub_host" + utils.IntToStr(i) + if strings.Contains(name, "{{subhost"+utils.IntToStr(i)+"}}") && moreSubDomain[keys] != "" { + domain = moreSubDomain[keys] + } + name = strings.ReplaceAll(name, "{{subhost"+utils.IntToStr(i)+"}}", "") + } + name = strings.ReplaceAll(name, "{{host}}", "") + name = strings.ReplaceAll(name, "{{subhost}}", "") + return fmt.Sprintf("%s://%s/%s", scheme, domain, name) +} diff --git a/app/svc/svc_sys_cfg_get.go b/app/svc/svc_sys_cfg_get.go new file mode 100644 index 0000000..1edd7a0 --- /dev/null +++ b/app/svc/svc_sys_cfg_get.go @@ -0,0 +1,134 @@ +package svc + +import ( + "applet/app/admin/md" + "applet/app/db" + "applet/app/utils/cache" + "fmt" + "github.com/gin-gonic/gin" +) + +// 单挑记录获取 +func SysCfgGet(c *gin.Context, key string) string { + sysCfgDb := db.SysCfgDb{} + sysCfgDb.Set() + return sysCfgDb.SysCfgGetWithDb(key) +} + +func SysCfgDel(c *gin.Context, key string) bool { + sysCfgDb := db.SysCfgDb{} + sysCfgDb.Set() + err := sysCfgDb.SysCfgDel(key) + if err != nil { + return false + } + return true +} + +// 多条记录获取 +func SysCfgFind(c *gin.Context, keys ...string) map[string]string { + var masterId string + if c == nil { + masterId = "" + } else { + masterId = c.GetString("mid") + } + tmp := SysCfgFindComm(masterId, keys...) + return tmp +} + +// SysCfgGetByMasterId get one config by master id +func SysCfgGetByMasterId(masterId, key string) string { + res := SysCfgFindComm(masterId, key) + if _, ok := res[key]; !ok { + return "" + } + return res[key] +} + +// SysCfgFindComm get cfg by master id +func SysCfgFindComm(masterId string, keys ...string) map[string]string { + sysCfgDb := db.SysCfgDb{} + sysCfgDb.Set() + res := map[string]string{} + + cfgKey := fmt.Sprintf("%s:cfg_cache", masterId) + + err := cache.GetJson(cfgKey, &res) + if err != nil || len(res) == 0 { + cfgList, _ := sysCfgDb.SysCfgGetAll() + if cfgList == nil { + return nil + } + for _, v := range *cfgList { + res[v.Key] = v.Val + } + cache.SetJson(cfgKey, res, 1800) + } + if len(keys) == 0 { + return res + } + tmp := map[string]string{} + for _, v := range keys { + if val, ok := res[v]; ok { + tmp[v] = val + } else { + tmp[v] = "" + } + } + return tmp +} + +// 多条记录获取 +func EgSysCfgFind(keys ...string) map[string]string { + sysCfgDb := db.SysCfgDb{} + sysCfgDb.Set() + res := map[string]string{} + if len(res) == 0 { + cfgList, _ := sysCfgDb.SysCfgGetAll() + if cfgList == nil { + return nil + } + for _, v := range *cfgList { + res[v.Key] = v.Val + } + // 先不设置缓存 + // cache.SetJson(md.KEY_SYS_CFG_CACHE, res, 60) + } + if len(keys) == 0 { + return res + } + tmp := map[string]string{} + for _, v := range keys { + if val, ok := res[v]; ok { + tmp[v] = val + } else { + tmp[v] = "" + } + } + return tmp +} + +// 清理系统配置信息 +func SysCfgCleanCache(c *gin.Context) { + var tmp = []string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"} + for _, v := range tmp { + cacheKey := fmt.Sprintf(md.AppCfgCacheKey, v) + cache.Del(cacheKey) + } +} + +// 写入系统设置 +func SysCfgSet(c *gin.Context, key, val, memo string) bool { + sysCfgDb := db.SysCfgDb{} + sysCfgDb.Set() + cfg, err := sysCfgDb.SysCfgGetOne(key) + if err != nil || cfg == nil { + return sysCfgDb.SysCfgInsert(key, val, memo) + } + if memo != "" && cfg.Memo != memo { + cfg.Memo = memo + } + SysCfgCleanCache(c) + return sysCfgDb.SysCfgUpdate(key, val) +} diff --git a/cmd_db.bat b/cmd_db.bat index 7a9e8d5..0cc9e0b 100644 --- a/cmd_db.bat +++ b/cmd_db.bat @@ -12,7 +12,7 @@ if "%one%" NEQ "" ( set BasePath="./" set DBUSER="root" set DBPSW="Fnuo123com@" -set DBNAME="fnuoos_test1" +set DBNAME="bakery" set DBHOST="119.23.182.117" set DBPORT="3306" diff --git a/go.mod b/go.mod index db73635..2757707 100644 --- a/go.mod +++ b/go.mod @@ -27,6 +27,7 @@ require ( github.com/gomodule/redigo v2.0.0+incompatible github.com/gookit/color v1.3.8 // indirect github.com/gorilla/sessions v1.2.1 // indirect + github.com/jinzhu/copier v0.4.0 // indirect github.com/json-iterator/go v1.1.10 // indirect github.com/kennygrant/sanitize v1.2.4 // indirect github.com/leodido/go-urn v1.2.1 // indirect diff --git a/k8s/deployment-dev.yaml b/k8s/deployment-dev.yaml index 8ebdce5..d159c44 100644 --- a/k8s/deployment-dev.yaml +++ b/k8s/deployment-dev.yaml @@ -1,46 +1,55 @@ kind: Deployment apiVersion: apps/v1 metadata: - name: app-bakery - namespace: develop + name: zhios-app-order-task-v3 + namespace: zhios labels: - app: app-bakery + app: zhios-app-order-task-v3 annotations: - kubesphere.io/creator: dengbiao - kubesphere.io/description: 面包店 + kubesphere.io/creator: huangjiajun + kubesphere.io/description: 智莺生活跟单 spec: replicas: 1 selector: matchLabels: - app: app-bakery + app: zhios-app-order-task-v3 template: metadata: labels: - app: app-bakery + app: zhios-app-order-task-v3 spec: volumes: - name: host-time hostPath: path: /etc/localtime type: '' - - name: app-bakery + - name: zhios-app-order-task-v3 configMap: - name: app-bakery + name: zhios-app-order-task + items: + - key: task.yml + path: task.yml defaultMode: 420 containers: - - name: container-app-comm-one-circles - image: 'registry-vpc.cn-shenzhen.aliyuncs.com/fnuoos-prd/app-bakery:0.0.1' - ports: - - name: httpcomm4001 - containerPort: 4001 - protocol: TCP + - name: zhios-app-order-task-v3 + image: 'registry.cn-shenzhen.aliyuncs.com/fnuoos-prd/zyos-task-v3:240313193' + resources: + limits: + cpu: 500m + memory: 1000Mi + requests: + cpu: 200m + memory: 100Mi volumeMounts: - name: host-time readOnly: true mountPath: /etc/localtime - - name: app-comm-one-circles + - name: zhios-app-order-task-v3 readOnly: true - mountPath: /var/zyos + mountPath: /var/zyos/task.yml + subPath: task.yml + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File imagePullPolicy: Always restartPolicy: Always terminationGracePeriodSeconds: 30 diff --git a/k8s/ingress-dev.yaml b/k8s/ingress-dev.yaml new file mode 100644 index 0000000..f91e494 --- /dev/null +++ b/k8s/ingress-dev.yaml @@ -0,0 +1,17 @@ +kind: Ingress +apiVersion: extensions/v1beta1 +metadata: + name: bakery # ingress名称 + namespace: develop + annotations: + kubesphere.io/creator: dengbiao +spec: + rules: + - host: bakery.dengbiao.top # 使用的域名 + http: + paths: + - path: / + pathType: ImplementationSpecific + backend: + serviceName: bakery # 流量转发到的服务 + servicePort: 80 \ No newline at end of file