package dao import ( "fmt" "time" "git.rosy.net.cn/jx-callback/globals" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/model" ) type ActMapPureInfo struct { VendorID int `orm:"column(vendor_id)" json:"vendorID"` VendorActID string `orm:"column(vendor_act_id);size(48)" json:"vendorActID"` SyncStatus int `orm:"default(2)" json:"syncStatus"` Remark string `orm:"column(map_remark)" json:"remark"` } type ActVendorInfo struct { model.Act VendorList []*ActMapPureInfo `json:"vendorList"` } type tActAndMap struct { model.Act MapID int `orm:"column(map_id)" json:"-"` // 内部使用,不暴露 ActMapPureInfo } type PagedActListInfo struct { TotalCount int `json:"totalCount"` Data []*ActVendorInfo `json:"data"` } func GetActVendorInfo(db *DaoDB, actID int, vendorIDs []int) (actMap map[int]*model.Act2, err error) { leftOrEmpty := "" if len(vendorIDs) == 1 && vendorIDs[0] == -1 { leftOrEmpty = "LEFT" } sql := fmt.Sprintf(` SELECT t1.*, t2.id map_id, t2.vendor_id, t2.vendor_act_id, t2.sync_status FROM act t1 %s JOIN act_map t2 ON t2.act_id = t1.id AND t2.deleted_at = ?`, leftOrEmpty) sqlParams := []interface{}{ utils.DefaultTimeValue, } if len(vendorIDs) > 0 { sql += " AND t2.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")" sqlParams = append(sqlParams, vendorIDs) } sql += ` WHERE t1.deleted_at = ? AND t1.id = ?` sqlParams = append(sqlParams, utils.DefaultTimeValue, actID) var actList []*model.Act2 if err = GetRows(db, &actList, sql, sqlParams...); err == nil { actMap = make(map[int]*model.Act2) for _, v := range actList { if leftOrEmpty != "" { v.VendorID = -1 } actMap[v.VendorID] = v } } return actMap, err } func GetActStoreSkuVendorList(db *DaoDB, actID int, vendorIDs, storeIDs, skuIDs []int, keyword string, offset, pageSize int) (totalCount int, actStoreSkuList []*model.ActStoreSku2, err error) { globals.SugarLogger.Debugf("GetActStoreSkuVendorList actID:%d", actID) offset = FormalizePageOffset(offset) pageSize = FormalizePageSize(pageSize) leftOrEmpty := "" if len(vendorIDs) == 1 && vendorIDs[0] == -1 { leftOrEmpty = "LEFT" } sql := fmt.Sprintf(` SELECT SQL_CALC_FOUND_ROWS t1.*, t2.id map_id, t2.vendor_id, t2.vendor_act_id, t2.sync_status, t2.actual_act_price, t2.vendor_price, t3.vendor_store_id, CASE t2.vendor_id WHEN 0 THEN t4.jd_id WHEN 1 THEN t5.mtwm_id WHEN 3 THEN t5.ebai_id ELSE '' END vendor_sku_id, t4.comment, t4.spec_quality, t4.spec_unit, t6.name store_name, t7.name sku_name_name, t7.unit, t7.prefix FROM act_store_sku t1 %s JOIN act_store_sku_map t2 ON t2.act_id = ? AND t2.bind_id = t1.id AND t2.deleted_at = ?`, leftOrEmpty) sqlParams := []interface{}{ actID, utils.DefaultTimeValue, } if len(vendorIDs) > 0 { sql += " AND t2.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")" sqlParams = append(sqlParams, vendorIDs) } sql += fmt.Sprintf(` %s JOIN store_map t3 ON t3.store_id = t1.store_id AND t3.vendor_id = t2.vendor_id AND t3.deleted_at = ? JOIN sku t4 ON t4.id = t1.sku_id LEFT JOIN store_sku_bind t5 ON t5.sku_id = t1.sku_id AND t5.store_id = t1.store_id AND t5.deleted_at = ? LEFT JOIN store t6 ON t6.id = t1.store_id JOIN sku_name t7 ON t7.id = t4.name_id WHERE t1.act_id = ? `, leftOrEmpty) sqlParams = append(sqlParams, utils.DefaultTimeValue, utils.DefaultTimeValue, actID, ) if keyword != "" { keywordLike := "%" + keyword + "%" sql += " AND (t7.name LIKE ? OR t6.name LIKE ?" sqlParams = append(sqlParams, keywordLike, keywordLike) if intKeyword := int(utils.Str2Int64WithDefault(keyword, 0)); intKeyword > 0 { sql += " OR t1.sku_id = ? OR t1.store_id = ?" sqlParams = append(sqlParams, intKeyword, intKeyword) } sql += ")" } if leftOrEmpty != "" { sql += " AND t1.deleted_at = ?" sqlParams = append(sqlParams, utils.DefaultTimeValue) } if len(storeIDs) > 0 { sql += " AND t1.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")" sqlParams = append(sqlParams, storeIDs) } if len(skuIDs) > 0 { sql += " AND t1.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")" sqlParams = append(sqlParams, skuIDs) } sql += " LIMIT ? OFFSET ?;" sqlParams = append(sqlParams, pageSize, offset) // globals.SugarLogger.Debug(sql) // globals.SugarLogger.Debug(utils.Format4Output(sqlParams, false)) // globals.SugarLogger.Debug(utils.Format4Output(actStoreSkuList, false)) Begin(db) defer Rollback(db) if err = GetRows(db, &actStoreSkuList, sql, sqlParams...); err == nil { totalCount = GetLastTotalRowCount(db) } return totalCount, actStoreSkuList, err } func GetActStoreSkuVendorInfo(db *DaoDB, actID int, vendorIDs, storeIDs, skuIDs []int) (actStoreSkuMap map[int][]*model.ActStoreSku2, err error) { leftOrEmpty := "" if len(vendorIDs) == 1 && vendorIDs[0] == -1 { leftOrEmpty = "LEFT" } _, actStoreSkuList, err := GetActStoreSkuVendorList(db, actID, vendorIDs, storeIDs, skuIDs, "", 0, -1) if err == nil { actStoreSkuMap = make(map[int][]*model.ActStoreSku2) for _, v := range actStoreSkuList { if leftOrEmpty != "" { v.VendorID = -1 } actStoreSkuMap[v.VendorID] = append(actStoreSkuMap[v.VendorID], v) } } return actStoreSkuMap, err } func QueryActs(db *DaoDB, actID int, offset, pageSize int, keyword string, vendorID int, statusList, actTypeList, createTypeList []int, storeID, skuID, cityCode int, beginAt, endAt, createdAtFrom, createdAtTo time.Time) (pagedInfo *PagedActListInfo, err error) { if actID == 0 && utils.IsTimeZero(createdAtFrom) && utils.IsTimeZero(beginAt) { return nil, fmt.Errorf("actID,createdAtFrom和beginAt中,至少要指定一个条件") } offset = FormalizePageOffset(offset) pageSize = FormalizePageSize(pageSize) isGetAll := offset == 0 && pageSize == model.UnlimitedPageSize sql := ` SELECT SQL_CALC_FOUND_ROWS t1.id FROM act t1` sqlParams := []interface{}{} if isGetAll { sql = ` SELECT t1.*, t2.id map_id, t2.vendor_id, t2.vendor_act_id, t2.sync_status, t2.remark map_remark FROM act t1 LEFT JOIN act_map t2 ON t2.act_id = t1.id AND t2.deleted_at = ?` sqlParams = []interface{}{utils.DefaultTimeValue} } sql += ` WHERE t1.deleted_at = ?` sqlParams = append(sqlParams, utils.DefaultTimeValue) keywordInt := int64(0) if keyword != "" { keywordLike := "%" + keyword + "%" sql += " AND ( t1.name LIKE ? OR t1.advertising LIKE ? OR t1.remark LIKE ?" sqlParams = append(sqlParams, keywordLike, keywordLike, keywordLike) keywordInt = utils.Str2Int64WithDefault(keyword, 0) if keywordInt > 0 { sql += ` OR t1.id = ?` sqlParams = append(sqlParams, keywordInt) } sql += ")" } if storeID > 0 || skuID > 0 || cityCode > 0 { sql += ` AND (SELECT COUNT(*) FROM act_store_sku t2` if cityCode > 0 { sql += " JOIN store t3 ON t3.id = t2.store_id AND t3.city_code = ?" sqlParams = append(sqlParams, cityCode) } sql += ` WHERE t2.act_id = t1.id AND t2.deleted_at = ?` sqlParams = append(sqlParams, utils.DefaultTimeValue) if storeID > 0 { sql += " AND t2.store_id = ?" sqlParams = append(sqlParams, storeID) } if skuID > 0 { sql += " AND t2.sku_id = ?" sqlParams = append(sqlParams, skuID) } sql += ") > 0" } if actID > 0 { sql += " AND t1.id = ?" sqlParams = append(sqlParams, actID) } if vendorID >= 0 { sql += " AND t1.vendor_mask & ? <> 0" sqlParams = append(sqlParams, model.GetVendorMask(vendorID)) } if len(statusList) > 0 { sql += " AND t1.status IN (" + GenQuestionMarks(len(statusList)) + ")" sqlParams = append(sqlParams, statusList) } if len(actTypeList) > 0 { sql += " AND t1.type IN (" + GenQuestionMarks(len(actTypeList)) + ")" sqlParams = append(sqlParams, actTypeList) } if len(createTypeList) > 0 { sql += " AND t1.create_type IN (" + GenQuestionMarks(len(createTypeList)) + ")" sqlParams = append(sqlParams, createTypeList) } if !utils.IsTimeZero(beginAt) { sql += " AND t1.begin_at <= ?" sqlParams = append(sqlParams, beginAt) } if !utils.IsTimeZero(endAt) { sql += " AND t1.end_at >= ?" sqlParams = append(sqlParams, endAt) } if !utils.IsTimeZero(createdAtFrom) { sql += " AND t1.created_at >= ?" sqlParams = append(sqlParams, createdAtFrom) } if !utils.IsTimeZero(createdAtTo) { sql += " AND t1.created_at <= ?" sqlParams = append(sqlParams, createdAtTo) } pagedInfo = &PagedActListInfo{} if isGetAll { sql += ` ORDER BY t1.id DESC, t2.vendor_id` } else { sql += ` ORDER BY 1 DESC LIMIT ? OFFSET ? ` sqlParams = append(sqlParams, pageSize, offset) var idList []int Begin(db) defer func() { if r := recover(); r != nil { Rollback(db) panic(r) } }() if err = GetRows(db, &idList, sql, sqlParams...); err != nil || len(idList) == 0 { Rollback(db) return pagedInfo, err } pagedInfo.TotalCount = GetLastTotalRowCount(db) Commit(db) sql = ` SELECT t1.*, t2.id map_id, t2.vendor_id, t2.vendor_act_id, t2.sync_status, t2.remark map_remark FROM act t1 LEFT JOIN act_map t2 ON t2.act_id = t1.id AND t2.deleted_at = ? WHERE t1.id IN (` + GenQuestionMarks(len(idList)) + `) ORDER BY t1.id DESC, t2.vendor_id ` sqlParams = []interface{}{ utils.DefaultTimeValue, idList, } } var actList []*tActAndMap if err = GetRows(db, &actList, sql, sqlParams...); err != nil { return nil, err } actMap := make(map[int]*ActVendorInfo) for _, v := range actList { tmpAct := actMap[v.ID] if tmpAct == nil { tmpAct = &ActVendorInfo{ Act: v.Act, } actMap[v.ID] = tmpAct pagedInfo.Data = append(pagedInfo.Data, tmpAct) } if v.MapID > 0 { tmpAct.VendorList = append(tmpAct.VendorList, &v.ActMapPureInfo) } } if isGetAll { pagedInfo.TotalCount = len(pagedInfo.Data) } return pagedInfo, err } func GetExistVendorActIDs(db *DaoDB, vendorID int) (vendorActIDs []string, err error) { // todo 不应该是全表扫描 sql := ` SELECT DISTINCT t1.vendor_act_id FROM act_store_sku_map t1 WHERE t1.deleted_at = ? AND t1.vendor_id = ?` sqlParams := []interface{}{ utils.DefaultTimeValue, vendorID, } err = GetRows(db, &vendorActIDs, sql, sqlParams...) return vendorActIDs, err } func GetEffectiveActStoreSkuInfo(db *DaoDB, actID int, vendorIDs []int, storeIDs, skuIDs []int, beginAt, endAt time.Time) (actStoreSkuList []*model.ActStoreSku2, err error) { if utils.IsTimeZero(beginAt) { return nil, fmt.Errorf("GeActStoreSkuInfo必须指定活动开始时间") } if utils.IsTimeZero(endAt) { endAt = beginAt } sql := ` SELECT t2.*, t3.actual_act_price, t3.sync_status, t3.vendor_price, t3.vendor_id FROM act t1 JOIN act_store_sku t2 ON t2.act_id = t1.id AND t2.deleted_at = ? JOIN act_store_sku_map t3 ON t3.bind_id = t2.id AND t3.act_id = t1.id AND (t3.sync_status & ? = 0 OR t1.type = ?) JOIN act_map t4 ON t4.act_id = t1.id AND t4.vendor_id = t3.vendor_id AND t4.deleted_at = ? AND (t4.sync_status & ? = 0 OR t1.type = ?) WHERE t1.deleted_at = ? AND t1.status = ? AND NOT (t1.begin_at > ? OR t1.end_at < ?)` sqlParams := []interface{}{ utils.DefaultTimeValue, model.SyncFlagNewMask, model.ActSkuFake, utils.DefaultTimeValue, model.SyncFlagNewMask, model.ActSkuFake, utils.DefaultTimeValue, model.ActStatusCreated, endAt, beginAt, } if len(vendorIDs) > 0 { sql += " AND (t1.vendor_mask & ?) <> 0 AND t3.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")" sqlParams = append(sqlParams, model.GetVendorMask(vendorIDs...), vendorIDs) } if actID > 0 { sql = " AND t1.id = ?" sqlParams = append(sqlParams, actID) } if len(storeIDs) > 0 { sql += " AND t2.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")" sqlParams = append(sqlParams, storeIDs) } if len(skuIDs) > 0 { sql += " AND t2.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")" sqlParams = append(sqlParams, skuIDs) } // globals.SugarLogger.Debug(sql) // globals.SugarLogger.Debug(utils.Format4Output(sqlParams, false)) err = GetRows(db, &actStoreSkuList, sql, sqlParams...) return actStoreSkuList, err } func UpdateActStatusByTime(db *DaoDB, refTime time.Time) (num int64, err error) { sql := ` UPDATE act t1 SET t1.status = ? WHERE t1.deleted_at = ? AND t1.status < ? AND t1.end_at < ?;` sqlParams := []interface{}{ model.ActStatusEnded, utils.DefaultTimeValue, model.ActStatusCanceled, refTime, } num, err = ExecuteSQL(db, sql, sqlParams...) return num, err }