package controllers import ( "encoding/json" "errors" "eta/eta_mini_crm_ht/models" "eta/eta_mini_crm_ht/models/request" "eta/eta_mini_crm_ht/models/response" "eta/eta_mini_crm_ht/services" "eta/eta_mini_crm_ht/utils" "github.com/go-sql-driver/mysql" "github.com/rdlucklib/rdluck_tools/paging" "github.com/shopspring/decimal" "strconv" "strings" "sync" "time" ) type ProductController struct { BaseAuthController } // UnSetProductList // @Title 未设置的产品列表 // @Description 未设置的产品列表 // @Param PageSize query int true "每页数据条数" // @Param CurrentIndex query int true "当前页页码,从1开始" // @Param ClassifyIds query string true "二级分类id,可多选用英文,隔开" // @Param KeyWord query string true "报告标题/创建人" // @Param SortType query string true "排序方式" // @Success 200 {object} models.ReportAuthorResp // @router /unSetProductList [get] func (this *ProductController) UnSetProductList() { br := new(models.BaseResponse).Init() defer func() { this.Data["json"] = br this.ServeJSON() }() pageSize, _ := this.GetInt("PageSize") currentIndex, _ := this.GetInt("CurrentIndex") sortType := this.GetString("SortType") ProductType := this.GetString("ProductType") permissionIds := this.GetString("PermissionIds") KeyWord := this.GetString("KeyWord") var condition string var pars []interface{} if pageSize <= 0 { pageSize = utils.PageSize20 } if currentIndex <= 0 { currentIndex = 1 } if ProductType == "" { br.Msg = "产品类型不能为空" br.ErrMsg = "获取未设置产品列表失败,Err:产品类型为空" return } if KeyWord != "" { switch ProductType { case "report": condition += " AND title like '%?%'" case "media": condition += " AND media_name like '%?%'" } pars = append(pars, KeyWord) } sortCondition := " ORDER BY published_time " if sortType == "" { sortType = "DESC" } sortCondition = sortCondition + sortType var permissionIdsList []int if permissionIds != "" { permissionStr := strings.Split(permissionIds, ",") for _, permissionItem := range permissionStr { permissionId, _ := strconv.Atoi(permissionItem) permissionIdsList = append(permissionIdsList, permissionId) } } total, ids, err := services.GetUnsetProductCountByCondition(ProductType, permissionIdsList, condition, pars) if err != nil { br.Msg = "获取未设置产品列表失败" br.ErrMsg = "获取未设置产品列表失败,Err:" + err.Error() return } var list []*services.ProductView if len(ids) > 0 { startSize := utils.StartIndex(currentIndex, pageSize) list, err = services.GetUnsetProductByCondition(ProductType, ids, sortCondition, startSize, pageSize) if err != nil { br.Msg = "获取未设置产品列表失败" br.ErrMsg = "获取未设置产品列表失败,Err:" + err.Error() return } } var wg sync.WaitGroup wg.Add(len(list)) for _, product := range list { go func(product *services.ProductView) { defer wg.Done() switch product.ProductType { case "report": product.RiskLevel, _, _ = services.GetRiskLevel("report", product.SourceId) product.ProductType = "报告" case "video": product.RiskLevel, _, _ = services.GetRiskLevel("media", product.SourceId) product.ProductType = "视频" case "audio": product.RiskLevel, _, _ = services.GetRiskLevel("media", product.SourceId) product.ProductType = "音频" } }(product) } wg.Wait() page := paging.GetPaging(currentIndex, pageSize, total) resp := new(response.ProductListResp) resp.List = list resp.Paging = page br.Ret = 200 br.Success = true br.Data = resp br.Msg = "获取成功" } // AddProduct @Title 新增单品 // @Description 新增单品 // @Param File query file true "文件" // @Success 200 {object} models.ReportAuthorResp // @router /addProduct [post] func (this *ProductController) AddProduct() { br := new(models.BaseResponse).Init() defer func() { this.Data["json"] = br this.ServeJSON() }() var req request.ProductReq err := json.Unmarshal(this.Ctx.Input.RequestBody, &req) if err != nil { br.Msg = "参数解析异常!" br.ErrMsg = "参数解析失败,Err:" + err.Error() return } var product models.MerchantProduct if req.Type == "package" { if req.ValidDays <= 0 { br.Msg = "套餐有效期非法" br.ErrMsg = "套餐有效期非法,天数不能是负数" return } if req.ProductName == "" { br.Msg = "套餐名称不能为空" br.ErrMsg = "套餐名称不能为空" return } product.Title = req.ProductName product.ValidDays = req.ValidDays product.Description = req.Description product.CoverSrc = req.CoverSrc } switch req.Type { case "report": product.RiskLevel, product.Title, err = services.GetRiskLevel("report", req.SourceId) case "audio": product.RiskLevel, product.Title, err = services.GetRiskLevel("audio", req.SourceId) case "video": product.RiskLevel, product.Title, err = services.GetRiskLevel("video", req.SourceId) case "package": product.RiskLevel, _, err = services.GetRiskLevel("package", req.SourceId) default: br.Msg = "产品类型错误" br.ErrMsg = "获取产品列表失败,Err:产品类型错误" return } if err != nil { utils.FileLog.Error("新增单品失败", err.Error()) br.Msg = "新增产品错误" if strings.Contains(err.Error(), " no row found") { br.Msg = "新增产品错误,产品信息不存在" } else { br.Msg = "新增产品错误" + err.Error() } return } if product.RiskLevel == "" { br.Msg = "新增产品错误" br.ErrMsg = "未获取到风险等级" return } if !checkProductRiskLevel(product.RiskLevel) { br.Msg = "产品风险等级不合法" br.ErrMsg = "产品风险等级不合法:" + product.RiskLevel return } if product.Title == "" { br.Msg = "产品名称不能为空" br.ErrMsg = "产品名称不能为空" return } var price decimal.Decimal price, err = decimal.NewFromString(req.Price) if err != nil { br.Msg = "产品价格格式不正确" br.ErrMsg = "产品价格格式不正确,err:" + err.Error() + "price:" + product.Price return } if price.Cmp(decimal.New(0, 0)) <= 0 { br.Msg = "产品价格不能小于0" br.ErrMsg = "产品价格不能小于0" return } product.SaleStatus = models.OnSale product.CreatedTime = time.Now() product.Price = req.Price product.SourceId = req.SourceId product.Type = models.MerchantProductType(req.Type) if product.Type == "" { br.Msg = "新增产品错误" br.ErrMsg = "产品类型为空" return } err = product.AddProduct() if err != nil { var mysqlErr *mysql.MySQLError if errors.As(err, &mysqlErr) { if mysqlErr.Number == 1062 { br.Msg = "该产品已设置付费,请刷新后重试" br.ErrMsg = "该产品已设置付费,请刷新后重试" } else { utils.FileLog.Error("新增产品失败,err:" + err.Error()) br.Msg = "新增产品失败" br.ErrMsg = "新增产品失败,err:" + err.Error() } } else { utils.FileLog.Error("新增产品失败,err:" + err.Error()) br.Msg = "新增产品失败" br.ErrMsg = "新增产品失败,err:" + err.Error() } return } br.Ret = 200 br.Success = true br.Msg = "新增产品成功" return } // UpdateSaleStatus @Title 上下架产品 // @Description 上下架产品 // @Param File query file true "文件" // @Success 200 {object} models.ReportAuthorResp // @router /updateSaleStatus [post] func (this *ProductController) UpdateSaleStatus() { br := new(models.BaseResponse).Init() defer func() { this.Data["json"] = br this.ServeJSON() }() defer func() { this.Data["json"] = br this.ServeJSON() }() var req request.ProductSaleStatusReq err := json.Unmarshal(this.Ctx.Input.RequestBody, &req) if err != nil { br.Msg = "参数解析异常!" br.ErrMsg = "参数解析失败,Err:" + err.Error() return } if req.ProductId <= 0 { br.Msg = "产品编号非法!" br.ErrMsg = "产品编号非法,不能小于0" return } if req.SaleStatus != "onSale" && req.SaleStatus != "offSale" { br.Msg = "产品销售状态非法!" br.ErrMsg = "产品销售状态非法,未知的上下架类型:" + req.SaleStatus return } var saleStatus models.SaleStatus var messageStatus string switch req.SaleStatus { case "onSale": saleStatus = models.OnSale messageStatus = "上架" case "offSale": saleStatus = models.OffSale messageStatus = "下架" } product := models.MerchantProduct{ Id: req.ProductId, SaleStatus: saleStatus, UpdatedTime: time.Now(), } err = product.UpdateProductSaleStatus() if err != nil { br.Msg = messageStatus + "失败" br.ErrMsg = messageStatus + "失败,err:" + err.Error() return } br.Msg = messageStatus + "成功" br.Ret = 200 br.Success = true } // DeleteProduct @Title 删除产品 // @Description 删除产品 // @Param File query file true "文件" // @Success 200 {object} models.ReportAuthorResp // @router /deleteProduct [post] func (this *ProductController) DeleteProduct() { br := new(models.BaseResponse).Init() defer func() { this.Data["json"] = br this.ServeJSON() }() defer func() { this.Data["json"] = br this.ServeJSON() }() var req request.ProductSaleStatusReq err := json.Unmarshal(this.Ctx.Input.RequestBody, &req) if err != nil { br.Msg = "参数解析异常!" br.ErrMsg = "参数解析失败,Err:" + err.Error() return } if req.ProductId <= 0 { br.Msg = "产品编号非法!" br.ErrMsg = "产品编号非法,不能小于0" return } product := models.MerchantProduct{ Id: req.ProductId, Deleted: true, UpdatedTime: time.Now(), } err = product.Delete() if err != nil { br.Msg = "删除产品失败" br.ErrMsg = "删除产品失败,err:" + err.Error() return } br.Msg = "删除产品成功" br.Ret = 200 br.Success = true } // //// OnSale @Title 上架产品 //// @Description 上架产品 //// @Param File query file true "文件" //// @Success 200 {object} models.ReportAuthorResp //// @router /onSale [post] //func (this *ProductController) OnSale() { // br := new(models.BaseResponse).Init() // defer func() { // this.Data["json"] = br // this.ServeJSON() // }() // f, h, err := this.GetFile("File") // if err != nil { // br.Msg = "获取资源信息失败" // br.ErrMsg = "获取资源信息失败,Err:" + err.Error() // return // } // defer f.Close() // size, err := strconv.Atoi(utils.UPLOAD_IMG_SIZE) // if err != nil { // size = 100 // } // if h.Size > 1024*1024*int64(size) { // br.Msg = fmt.Sprintf("图片大小不能超过%dK", size) // br.ErrMsg = "图片上传失败,Err:" + err.Error() // return // } // ext := path.Ext(h.Filename) // //if ext != ".mp3" { // // br.Msg = "音频格式不正确" // // br.ErrMsg = "音频上传失败,Err:" + err.Error() // // return // //} // dateDir := time.Now().Format("20060102") // uploadDir := utils.STATIC_DIR + "ht/audio" + dateDir // err = os.MkdirAll(uploadDir, utils.DIR_MOD) // if err != nil { // br.Msg = "存储目录创建失败" // br.ErrMsg = "存储目录创建失败,Err:" + err.Error() // return // } // randStr := utils.GetRandStringNoSpecialChar(28) // fileName := randStr + ext // fpath := uploadDir + "/" + fileName // err = this.SaveToFile("File", fpath) // if err != nil { // br.Msg = "图片上传失败" // br.ErrMsg = "图片上传失败,Err:" + err.Error() // return // } // audioUploadDir := utils.RESOURCE_DIR + "img/" // savePdfToOssPath := audioUploadDir + time.Now().Format("200601/20060102/") // audioName := utils.GetRandStringNoSpecialChar(28) // savePdfToOssPath += audioName + ext // // defer func() { // err = os.Remove(fpath) // fmt.Sprintf("删除文件失败:%v", err) // }() // ossClient := services.NewOssClient() // if ossClient == nil { // br.Msg = "图片上传失败" // br.ErrMsg = "初始化OSS服务失败" // return // } // mp3Url, err := ossClient.UploadFile("", fpath, savePdfToOssPath) // if err != nil { // br.Msg = "图片上传失败" // br.ErrMsg = "图片上传失败,Err:" + err.Error() // return // } // base := path.Base(h.Filename) // resp := new(response.MediaUploadResp) // resp.Url = mp3Url // resp.FileName = base // br.Data = resp // br.Msg = "上架成功" // br.Ret = 200 // br.Success = true //}