package dao

import (
	"fmt"
	"regexp"
	"strconv"
	"time"

	"git.rosy.net.cn/baseapi/utils"
	"git.rosy.net.cn/jx-callback/business/jxutils"
	"git.rosy.net.cn/jx-callback/business/model"
)

const (
	AfsOrderStatus = -1
)

var (
	regexpNumber = regexp.MustCompile(`^\d+$`)
)

type StoresOrderSaleInfo struct {
	StoreID              int   `orm:"column(store_id)" json:"storeID"`
	VendorID             int   `orm:"column(vendor_id)" json:"vendorID"`
	Status               int   `json:"status"`
	Count                int   `json:"count"`
	ShopPrice            int64 `json:"shopPrice"`
	VendorPrice          int64 `json:"vendorPrice"`
	SalePrice            int64 `json:"salePrice"`
	ActualPayPrice       int64 `json:"actualPayPrice"`
	EarningPrice         int64 `json:"earningPrice"`         // 预估结算给门店老板的钱
	NewEarningPrice      int64 `json:"newEarningPrice"`      // 预估结算给门店老板的钱(新规则)
	DistanceFreightMoney int64 `json:"distanceFreightMoney"` // 商户承担的远距离配送费（当前只有京东到家有值）
	WaybillTipMoney      int64 `json:"waybillTipMoney"`      // 京西加的平台配送小费
	RealEarningPrice     int64 `json:"realEarningPrice"`
	PlatformSettlement   int64 `json:"platformSettlement"` // 真实订单的平台结算(无扣点)
	ActualFee            int64 `json:"actualFee"`          // 真三方运单配送费
	ServerFee            int64 `json:"serverFee"`          // 附加服务费
	FineFee              int64 `json:"fineFee"`            // 罚款金额
}

type OrderSkuWithActualPayPrice struct {
	model.OrderSku

	ActualPayPrice       int64 `json:"actualPayPrice"`       // 单位为分 顾客实际支付
	DistanceFreightMoney int64 `json:"distanceFreightMoney"` // 商户承担的远距离配送费（当前只有京东到家有值）
	WaybillTipMoney      int64 `json:"waybillTipMoney"`      // 京西加的平台配送小费

	StoreID int `orm:"column(store_id)" json:"storeID"` // 外部系统里记录的 jxstoreid
	Status  int `json:"status"`                         // 参见OrderStatus*相关的常量定义

	PayPercentage      int   `json:"payPercentage"`
	OrderPayPercentage int   `json:"orderPayPercentage"`
	NewEarningPrice    int64 `json:"newEarningPrice"`
	EarningType        int   `json:"earningType"`
	CityCode           int   `json:"cityCode"`
}

type tGoodsAndOrder struct {
	model.GoodsOrder
	OrderSkuID      int64  `orm:"column(order_sku_id)" json:"orderSkuID"`
	StoreSubID      int    `orm:"column(store_sub_id)" json:"storeSubID"` // 当前这个字段被当成结算活动ID用
	StoreSubName    string `orm:"size(64)" json:"storeSubName"`           // 当前这个字段被用作vendorActType
	Count           int    `json:"count"`
	VendorSkuID     string `orm:"column(vendor_sku_id);size(48)" json:"vendorSkuID"`
	SkuID           int    `orm:"column(sku_id)" json:"skuID"`      // 外部系统里记录的 jxskuid
	JxSkuID         int    `orm:"column(jx_sku_id)" json:"jxSkuID"` // 根据VendorSkuID在本地系统里查询出来的 jxskuid
	SkuName         string `orm:"size(255)" json:"skuName"`
	SkuShopPrice    int64  `json:"shopPrice"`     // 京西价
	SkuVendorPrice  int64  `json:"vendorPrice"`   // 平台价
	SkuSalePrice    int64  `json:"salePrice"`     // 售卖价
	SkuEarningPrice int64  `json:"earningPrice"`  // 活动商品设置，结算给门店老板的钱，如果结算活动ID为0，是按结算比例算的，否则就是结算表中的值
	Weight          int    `json:"weight"`        // 单位为克
	SkuType         int    `json:"skuType"`       // 当前如果为gift就为1，否则缺省为0
	PromotionType   int    `json:"promotionType"` // todo 当前是用于记录京东的PromotionType(生成jxorder用)，没有做转换
}

type GoodsOrderPay struct {
	model.GoodsOrder
	TransactionID string `orm:"column(transaction_id)" json:"transactionID"`
}

//actID指结算活动的id
func QueryOrders(db *DaoDB, vendorOrderID string, actID int, vendorIDs []int, storeID int, fromDate, toDate time.Time) (orderList []*model.GoodsOrder, err error) {
	sqlParams := []interface{}{}
	var (
		orderNewList []*tGoodsAndOrder
		orderNewMap  map[string][]*model.OrderSku
	)
	sql := `
	SELECT a.*,
	b.id order_sku_id, b.store_sub_id, b.store_sub_name, b.count, b.vendor_sku_id, b.sku_id, b.jx_sku_id, b.sku_name, b.shop_price sku_shop_price,
	b.vendor_price sku_vendor_price, b.sale_price sku_sale_price, b.earning_price sku_earning_price, b.weight, b.sku_type, b.promotion_type
	FROM goods_order a
	JOIN order_sku b ON a.vendor_order_id = b.vendor_order_id
	`
	if actID > 0 {
		sql += `
		JOIN ( SELECT t4.vendor_order_id, t4.vendor_id
			FROM act t1
			JOIN act_store_sku t2 ON t2.act_id = t1.id 
			JOIN order_sku t3 ON t3.sku_id = t2.sku_id
			JOIN goods_order t4 ON t4.vendor_order_id = t3.vendor_order_id 
			AND t4.vendor_id = t3.vendor_id
			AND t2.store_id = IF(t4.jx_store_id <> 0, t4.jx_store_id, t4.store_id)
			AND t4.order_created_at BETWEEN t1.begin_at AND t1.end_at
			WHERE t1.status = 1
			AND t1.id = ?
			GROUP BY 1,2
		)s ON s.vendor_order_id = a.vendor_order_id AND s.vendor_id = a.vendor_id	
		`
		sqlParams = append(sqlParams, actID)
	}
	sql += `
	WHERE 1=1
	`
	if vendorOrderID != "" {
		sql += " AND a.vendor_order_id = ?"
		sqlParams = append(sqlParams, vendorOrderID)
	}
	if len(vendorIDs) > 0 {
		sql += " AND a.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")"
		sqlParams = append(sqlParams, vendorIDs)
	}
	if storeID > 0 {
		sql += " AND IF(a.jx_store_id <> 0, a.jx_store_id, a.store_id) = ?"
		sqlParams = append(sqlParams, storeID)
	}
	if !utils.IsTimeZero(fromDate) && !utils.IsTimeZero(toDate) {
		sql += " AND a.order_created_at BETWEEN ? AND ?"
		sqlParams = append(sqlParams, fromDate, toDate)
	}
	err = GetRows(db, &orderNewList, sql, sqlParams...)
	if len(orderNewList) > 0 {
		orderNewMap = make(map[string][]*model.OrderSku)
		for _, v := range orderNewList {
			if orderNewMap[v.VendorOrderID] == nil {
				orderList = append(orderList, &v.GoodsOrder)
			}
			orderNewMap[v.VendorOrderID] = append(orderNewMap[v.VendorOrderID], &model.OrderSku{
				ID:            v.OrderSkuID,
				VendorOrderID: v.VendorOrderID,
				VendorID:      v.VendorID,
				StoreSubID:    int64(v.StoreSubID),
				StoreSubName:  v.StoreSubName,
				Count:         v.Count,
				VendorSkuID:   v.VendorSkuID,
				SkuID:         v.SkuID,
				JxSkuID:       v.JxSkuID,
				SkuName:       v.SkuName,
				ShopPrice:     v.SkuShopPrice,
				VendorPrice:   v.SkuVendorPrice,
				SalePrice:     v.SkuSalePrice,
				EarningPrice:  v.SkuEarningPrice,
				Weight:        v.Weight,
				SkuType:       v.SkuType,
				PromotionType: v.PromotionType,
			})
		}
		for _, v := range orderList {
			v.Skus = orderNewMap[v.VendorOrderID]
		}
	}

	return orderList, err
}

// func QueryOrders(db *DaoDB, vendorOrderID string, vendorIDs []int, storeID int, orderCreatedAtBegin, orderCreatedAtEnd time.Time) (orderList []*model.GoodsOrder, err error) {
// 	sql := `
// 	SELECT t1.*
// 	FROM goods_order t1
// 	WHERE t1.order_created_at >= ?`
// 	sqlParams := []interface{}{
// 		orderCreatedAtBegin,
// 	}
// 	if vendorOrderID != "" {
// 		sql += " AND t1.vendor_order_id = ?"
// 		sqlParams = append(sqlParams, vendorOrderID)
// 	}
// 	if len(vendorIDs) > 0 {
// 		sql += " AND t1.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")"
// 		sqlParams = append(sqlParams, vendorIDs)
// 	}
// 	if storeID > 0 {
// 		sql += " AND IF(t1.jx_store_id <> 0, t1.jx_store_id, t1.store_id) = ?"
// 		sqlParams = append(sqlParams, storeID)
// 	}
// 	if !utils.IsTimeZero(orderCreatedAtEnd) {
// 		sql += " AND t1.order_created_at <= ?"
// 		sqlParams = append(sqlParams, orderCreatedAtEnd)
// 	}
// 	// sql += " ORDER BY t1.order_created_at DESC, t1.id DESC;"
// 	return orderList, GetRows(db, &orderList, sql, sqlParams...)
// }

func GetStoreOrderAfterTime(db *DaoDB, storeID int, orderTime time.Time, lastOrderSeqID int64) (orderList []*model.GoodsOrderExt, err error) {
	sql := `
	SELECT t1.*,
	t2.status waybill_status, t2.courier_name, t2.courier_mobile,
	t2.actual_fee, t2.desired_fee, t2.waybill_created_at, t2.waybill_finished_at
	FROM goods_order t1
	LEFT JOIN waybill t2 ON t1.vendor_waybill_id = t2.vendor_waybill_id AND t1.waybill_vendor_id = t2.waybill_vendor_id
	WHERE IF(t1.jx_store_id <> 0, t1.jx_store_id, t1.store_id) = ? AND t1.order_created_at >= ? AND t1.id > ? AND t1.status >= ? AND t1.status < ?
	AND (t1.flag & ?) = 0
	ORDER BY t1.order_created_at DESC, t1.id DESC;
	`
	sqlParams := []interface{}{
		storeID,
		orderTime,
		lastOrderSeqID,
		model.OrderStatusNew,
		model.OrderStatusEndBegin,
		model.OrderFlagMaskFake,
	}
	return orderList, GetRows(db, &orderList, sql, sqlParams...)
}

func SetOrderPrintFlag(db *DaoDB, userName string, vendorOrderID string, vendorID int, isPrinted bool) (err error) {
	if isPrinted {
		err = SetOrderFlag(db, userName, vendorOrderID, vendorID, model.OrderFlagMaskPrinted)
	} else {
		err = SetOrderFlag(db, userName, vendorOrderID, vendorID, ^model.OrderFlagMaskPrinted)
	}
	return err
}

func SetOrderFlag(db *DaoDB, userName string, vendorOrderID string, vendorID int, flag int) (err error) {
	_, err = ExecuteSQL(db, `
	UPDATE goods_order
	SET flag = flag | ?
	WHERE vendor_order_id = ? AND vendor_id = ?
	`, flag, vendorOrderID, vendorID)
	return err
}

func ClearOrderFlag(db *DaoDB, userName string, vendorOrderID string, vendorID int, flag int) (err error) {
	_, err = ExecuteSQL(db, `
	UPDATE goods_order
	SET flag = flag & ?
	WHERE vendor_order_id = ? AND vendor_id = ?
	`, ^flag, vendorOrderID, vendorID)
	return err
}

func ClearOrderFlag2(db *DaoDB, userName string, vendorOrderID string, vendorID int, flag int) (err error) {
	_, err = ExecuteSQL(db, `
	UPDATE goods_order
	SET flag = ?
	WHERE vendor_order_id = ? AND vendor_id = ?
	`, flag, vendorOrderID, vendorID)
	return err
}

func SetAfsOrderFlag(db *DaoDB, userName string, afsOrderID string, vendorID int, flag int) (err error) {
	_, err = ExecuteSQL(db, `
	UPDATE afs_order
	SET flag = flag | ?,last_operator = ? 
	WHERE afs_order_id = ? AND vendor_id = ?
	`, flag, userName, afsOrderID, vendorID)
	return err
}

func GetAfsOrders(db *DaoDB, vendorID int, vendorOrderID, afsOrderID string) (afsOrderList []*model.AfsOrder, err error) {
	sql := `
	SELECT *
	FROM afs_order t1
	WHERE t1.vendor_id = ?
	`
	sqlParams := []interface{}{
		vendorID,
	}
	if vendorOrderID != "" {
		sql += " AND t1.vendor_order_id = ?"
		sqlParams = append(sqlParams, vendorOrderID)
	}
	if afsOrderID != "" {
		sql += " AND t1.afs_order_id = ?"
		sqlParams = append(sqlParams, afsOrderID)
	}
	sql += " ORDER BY t1.afs_order_id DESC"
	err = GetRows(db, &afsOrderList, sql, sqlParams...)
	return afsOrderList, err
}

// 时间范围是订单完成时间
func GetStoresOrderSaleInfo(db *DaoDB, storeIDList []int, fromTime time.Time, toTime time.Time, statusList []int) (saleInfoList []*StoresOrderSaleInfo, err error) {
	if utils.IsTimeZero(fromTime) {
		return nil, fmt.Errorf("查询订单信息必须指定起始时间")
	}
	if utils.IsTimeZero(toTime) {
		toTime = time.Now()
	}
	if toTime.Sub(fromTime) > time.Hour*24*60 {
		return nil, fmt.Errorf("查询时间范围不能超过60天")
	}

	// 用int64类型去取float型的数据库返回值，会取不到
	// order_finished_at
	sql := fmt.Sprintf(`
		SELECT IF(t1.jx_store_id > 0, t1.jx_store_id, t1.store_id) store_id, t1.vendor_id, IF(t1.status < ?, 0, t1.status) status,
		COUNT(*) count, SUM(t1.shop_price) shop_price, SUM(t1.vendor_price) vendor_price, SUM(t1.sale_price) sale_price, SUM(t1.actual_pay_price) actual_pay_price,
		CAST(SUM(IF(t1.earning_price <> 0, t1.earning_price, IF(t1.shop_price <> 0 && t1.shop_price < t1.sale_price, t1.shop_price, t1.sale_price) * IF(t5.pay_percentage > 0, t5.pay_percentage, %d) / 100)) AS SIGNED) earning_price
		FROM goods_order t1
		LEFT JOIN store t5 ON t5.id = IF(t1.jx_store_id <> 0, t1.jx_store_id, t1.store_id)
		WHERE t1.order_created_at >= ? AND t1.order_created_at <= ?
		`, model.DefaultEarningPricePercentage)
	sqlParams := []interface{}{
		model.OrderStatusEndBegin,
		fromTime,
		toTime,
	}
	if len(storeIDList) > 0 {
		sql += " AND IF(t1.jx_store_id > 0, t1.jx_store_id, t1.store_id) IN (" + GenQuestionMarks(len(storeIDList)) + ")"
		sqlParams = append(sqlParams, storeIDList)
	}
	if len(statusList) > 0 {
		sql += " AND t1.status IN (" + GenQuestionMarks(len(statusList)) + ")"
		sqlParams = append(sqlParams, statusList)
	}
	sql += `
		GROUP BY 1,2,3`
	sql += fmt.Sprintf(`
		UNION
		SELECT IF(t0.jx_store_id > 0, t0.jx_store_id, t0.store_id) store_id, t0.vendor_id, -1 status,
		COUNT(DISTINCT(t0.id)) count, SUM(t1.shop_price) shop_price, SUM(t1.vendor_price) vendor_price, SUM(t1.sale_price) sale_price, 0 actual_pay_price,
		CAST(SUM(IF(t1.earning_price <> 0, t1.earning_price, IF(t1.shop_price <> 0 && t1.shop_price < t1.sale_price, t1.shop_price, t1.sale_price) * IF(t5.pay_percentage > 0, t5.pay_percentage, %d) / 100)) AS SIGNED) earning_price
		FROM afs_order t0
		JOIN order_sku_financial t2 ON t2.afs_order_id = t0.afs_order_id AND t2.vendor_id = t0.vendor_id AND t2.is_afs_order = 1
		JOIN order_sku t1 ON t1.vendor_order_id = t2.vendor_order_id AND t1.vendor_id = t2.vendor_id AND t1.sku_id = t2.sku_id
		LEFT JOIN store t5 ON t5.id = IF(t0.jx_store_id <> 0, t0.jx_store_id, t0.store_id)
		WHERE t0.afs_finished_at >= ? AND t0.afs_finished_at <= ?`, model.DefaultEarningPricePercentage)
	sqlParams = append(sqlParams, []interface{}{
		fromTime,
		toTime,
	})
	if len(storeIDList) > 0 {
		sql += " AND IF(t0.jx_store_id > 0, t0.jx_store_id, t0.store_id) IN (" + GenQuestionMarks(len(storeIDList)) + ")"
		sqlParams = append(sqlParams, storeIDList)
	}
	sql += `
		GROUP BY 1,2,3`

	sql += " ORDER BY 1,2,3"
	err = GetRows(db, &saleInfoList, sql, sqlParams...)
	return saleInfoList, err
}

func GetAfsOrderSkuInfo(db *DaoDB, vendorOrderID, afsOrderID string, vendorID int, isNotFaild bool) (skus []*model.OrderFinancialSkuExt, err error) {
	if vendorOrderID == "" && afsOrderID == "" {
		return nil, fmt.Errorf("必须指定订单或售后单ID")
	}
	sql := `
	SELECT t1.*, t3.img image
	FROM order_sku_financial t1
	LEFT JOIN sku t2 ON t2.id = IF(t1.jx_sku_id <> 0, t1.jx_sku_id, t1.sku_id)
	LEFT JOIN sku_name t3 ON t3.id = t2.name_id
	LEFT JOIN afs_order t4 ON t4.afs_order_id = t1.afs_order_id
	WHERE t1.is_afs_order = 1 AND t1.vendor_id = ?`
	sqlParams := []interface{}{
		vendorID,
	}

	if vendorOrderID != "" {
		sql += " AND t1.vendor_order_id = ?"
		sqlParams = append(sqlParams, vendorOrderID)
	}
	if afsOrderID != "" {
		sql += " AND t1.afs_order_id = ?"
		sqlParams = append(sqlParams, afsOrderID)
	}
	if isNotFaild {
		sql += " AND t4.status <> ?"
		sqlParams = append(sqlParams, model.AfsOrderStatusFailed)
	}
	err = GetRows(db, &skus, sql, sqlParams...)
	return skus, err
}

func GetStoreOrderSkuList(db *DaoDB, storeIDs []int, finishedAtBegin, finishedAtEnd time.Time, statusList []int, isFinish bool, isService int) (skuList []*OrderSkuWithActualPayPrice, err error) {
	sql := `
	SELECT t1.*,
	IF(t2.jx_store_id > 0, t2.jx_store_id, t2.store_id) store_id, t2.status, t2.actual_pay_price, t2.distance_freight_money, t2.waybill_tip_money, t2.new_earning_price,
	t3.pay_percentage, t2.earning_type, t2.order_pay_percentage, t3.city_code
	FROM order_sku t1
	JOIN goods_order t2 ON t2.vendor_order_id = t1.vendor_order_id AND t2.vendor_id = t1.vendor_id
	LEFT JOIN store t3 ON t3.id = IF(t2.jx_store_id > 0, t2.jx_store_id, t2.store_id)
	WHERE 1=1`
	if isFinish {
		sql += " AND t2.order_finished_at >= ? AND t2.order_finished_at <= ?"
	} else {
		sql += " AND t2.order_created_at >= ? AND t2.order_created_at <= ?"
	}
	sqlParams := []interface{}{
		finishedAtBegin,
		finishedAtEnd,
	}
	if len(storeIDs) > 0 {
		sql += " AND IF(t2.jx_store_id > 0, t2.jx_store_id, t2.store_id) IN (" + GenQuestionMarks(len(storeIDs)) + ")"
		sqlParams = append(sqlParams, storeIDs)
	}
	if len(statusList) > 0 {
		sql += " AND t2.status IN (" + GenQuestionMarks(len(statusList)) + ")"
		sqlParams = append(sqlParams, statusList)
	}
	if isService == model.YES {
		sql += "AND t2.vendor_id <> ?"
		sqlParams = append(sqlParams, model.VendorIDMTWM)
	}

	err = GetRows(db, &skuList, sql, sqlParams...)
	return skuList, err
}

// GetStoreServerFee 统计门店服务费
func GetStoreServerFee(db *DaoDB, storeIDs []int, finishedAtBegin, finishedAtEnd time.Time, statusList []int, isFinish bool) ([]*ServerFeeInfo, error) {
	sql := ` SELECT sum(t2.package_price) server_fee,t2.vendor_id,t2.jx_store_id FROM goods_order t2 WHERE  1=1 `
	if isFinish {
		sql += " AND t2.order_finished_at >= ? AND t2.order_finished_at <= ?"
	} else {
		sql += " AND t2.order_created_at >= ? AND t2.order_created_at <= ?"
	}
	sqlParams := []interface{}{
		finishedAtBegin,
		finishedAtEnd,
	}
	if len(storeIDs) > 0 {
		sql += " AND IF(t2.jx_store_id > 0, t2.jx_store_id, t2.store_id) IN (" + GenQuestionMarks(len(storeIDs)) + ")"
		sqlParams = append(sqlParams, storeIDs)
	}
	if len(statusList) > 0 {
		sql += " AND t2.status IN (" + GenQuestionMarks(len(statusList)) + ")"
		sqlParams = append(sqlParams, statusList)
	}
	sql += ` GROUP BY t2.vendor_id,t2.jx_store_id`

	feeList := make([]*ServerFeeInfo, 0, 0)
	if err := GetRows(db, &feeList, sql, sqlParams...); err != nil {
		return nil, err
	}

	return feeList, nil
}

type ServerFeeInfo struct {
	ServerFee int64 `orm:"column(server_fee)" json:"serverFee"`
	VendorID  int   `orm:"column(vendor_id)" json:"vendorID"`
	JxStoreID int   `orm:"column(jx_store_id)" json:"jxStoreID"`
}

// GetPlatformSettlement 统计平台的结算信息
func GetPlatformSettlement(db *DaoDB, storeIDs []int, finishedAtBegin, finishedAtEnd time.Time) ([]*TotalShopMoney, error) {
	sql := `
		SELECT SUM(t2.total_shop_money) total_shop_money,t2.vendor_id FROM goods_order t2 WHERE t2.order_finished_at >= ? AND t2.order_finished_at <= ? 
`
	sqlParams := []interface{}{
		finishedAtBegin,
		finishedAtEnd,
	}
	if len(storeIDs) > 0 {
		sql += " AND IF(t2.jx_store_id > 0, t2.jx_store_id, t2.store_id) IN (" + GenQuestionMarks(len(storeIDs)) + ")"
		sqlParams = append(sqlParams, storeIDs)
	}
	sql += ` AND t2.status = ?  GROUP BY t2.vendor_id`
	sqlParams = append(sqlParams, model.OrderStatusFinished)

	var total []*TotalShopMoney
	err := GetRows(db, &total, sql, sqlParams...)
	return total, err
}

type TotalShopMoney struct {
	TotalShopMoney int64 `orm:"column(total_shop_money)" json:"totalShopMoney"`
	VendorID       int   `orm:"column(vendor_id)" json:"vendorID"`
}

type DeliveryFee struct {
	ActualFee int64 `orm:"column(actual_fee)" json:"actualFee"`
	VendorID  int   `orm:"column(vendor_id)" json:"vendorID"`
}

// GetPlatformDesiredFee 统计平台的订单的配送费信息
func GetPlatformDesiredFee(db *DaoDB, storeIDs []int, finishedAtBegin, finishedAtEnd time.Time) (fee []*DeliveryFee, err error) {
	sql := `
		SELECT sum(b.desired_fee) actual_fee,b.order_vendor_id vendor_id FROM goods_order t2 
		RIGHT JOIN waybill b ON t2.vendor_order_id = b.vendor_order_id AND b.vendor_order_id <> b.vendor_waybill_id
		WHERE t2.order_finished_at >= ? AND t2.order_finished_at <= ? 
`
	sqlParams := []interface{}{
		finishedAtBegin,
		finishedAtEnd,
	}
	if len(storeIDs) > 0 {
		sql += " AND IF(t2.jx_store_id > 0, t2.jx_store_id, t2.store_id) IN (" + GenQuestionMarks(len(storeIDs)) + ")"
		sqlParams = append(sqlParams, storeIDs)
	}

	sql += ` GROUP BY b.order_vendor_id `
	err = GetRows(db, &fee, sql, sqlParams...)
	return
}

func GetStoreOrderSkuList4Afs(db *DaoDB, storeIDs []int, finishedAtBegin, finishedAtEnd time.Time, isFinish bool) (skuList []*OrderSkuWithActualPayPrice, err error) {
	sql := `
	SELECT t1.*,
	t2.actual_pay_price, t2.status, IF(t2.jx_store_id > 0, t2.jx_store_id, t2.store_id) store_id, t2.new_earning_price,
	t3.pay_percentage
	FROM order_sku t1
	JOIN goods_order t2 ON t2.vendor_order_id = t1.vendor_order_id AND t2.vendor_id = t1.vendor_id
	LEFT JOIN store t3 ON t3.id = IF(t2.jx_store_id > 0, t2.jx_store_id, t2.store_id)
	JOIN (
		SELECT t12.*
		FROM afs_order t12
		WHERE IF(t12.jx_store_id > 0, t12.jx_store_id, t12.store_id) IN (` + GenQuestionMarks(len(storeIDs))
	if isFinish {
		sql += ") AND t12.afs_finished_at >= ? AND t12.afs_finished_at <= ?"
	} else {
		sql += ") AND t12.afs_created_at >= ? AND t12.afs_created_at <= ?"
	}
	sql += ") t4 ON t4.vendor_order_id = t2.vendor_order_id AND t4.vendor_id = t2.vendor_id"
	sqlParams := []interface{}{
		storeIDs,
		finishedAtBegin,
		finishedAtEnd,
	}
	err = GetRows(db, &skuList, sql, sqlParams...)
	return skuList, err
}

func GetStoreOrderSkuList4Afs2(db *DaoDB, vendorOrderIDs []string) (skuList []*OrderSkuWithActualPayPrice, err error) {
	sql := `
	SELECT t1.*,
	t2.actual_pay_price, t2.status, IF(t2.jx_store_id > 0, t2.jx_store_id, t2.store_id) store_id, t2.new_earning_price,
	t3.pay_percentage
	FROM order_sku t1
	JOIN goods_order t2 ON t2.vendor_order_id = t1.vendor_order_id AND t2.vendor_id = t1.vendor_id
	LEFT JOIN store t3 ON t3.id = IF(t2.jx_store_id > 0, t2.jx_store_id, t2.store_id)
	`
	sqlParams := []interface{}{}
	if len(vendorOrderIDs) > 0 {
		sql += `
			JOIN (
		SELECT t12.*
		FROM afs_order t12
		WHERE t12.vendor_order_id IN (` + GenQuestionMarks(len(vendorOrderIDs)) + `)
		) t4 ON t4.vendor_order_id = t2.vendor_order_id AND t4.vendor_id = t2.vendor_id
		`
		sqlParams = append(sqlParams, vendorOrderIDs)
	}

	err = GetRows(db, &skuList, sql, sqlParams...)
	return skuList, err
}

func GetStoreAfsOrderSkuList(db *DaoDB, storeIDs []int, statusList []int) (afsSkuList []*model.OrderSkuFinancial, err error) {
	sql := `
	SELECT t1.*
	FROM order_sku_financial t1
	JOIN afs_order t2 ON t2.vendor_order_id = t1.vendor_order_id AND t2.vendor_id = t1.vendor_id AND t2.afs_order_id = t1.afs_order_id
	WHERE t1.is_afs_order = 1
	`
	sqlParams := []interface{}{}
	if len(storeIDs) > 0 {
		sql += " AND IF(t2.jx_store_id > 0, t2.jx_store_id, t2.store_id) IN (" + GenQuestionMarks(len(storeIDs)) + ")"
		sqlParams = append(sqlParams, storeIDs)
	}
	if len(statusList) > 0 {
		sql += " AND t2.status IN (" + GenQuestionMarks(len(statusList)) + ")"
		sqlParams = append(sqlParams, statusList)
	}
	err = GetRows(db, &afsSkuList, sql, sqlParams...)
	return afsSkuList, err
}

func GetStoreAfsOrderSkuList2(db *DaoDB, vendorOrderIDs []string) (afsSkuList []*model.OrderSkuFinancial, err error) {
	sql := `
	SELECT t1.*
	FROM order_sku_financial t1
	JOIN afs_order t2 ON t2.vendor_order_id = t1.vendor_order_id AND t2.vendor_id = t1.vendor_id AND t2.afs_order_id = t1.afs_order_id
	WHERE t1.is_afs_order = 1 AND t2.status = ?
	`
	sqlParams := []interface{}{model.AfsOrderStatusFinished}
	if len(vendorOrderIDs) > 0 {
		sql += " AND t2.vendor_order_id IN (" + GenQuestionMarks(len(vendorOrderIDs)) + ")"
		sqlParams = append(sqlParams, vendorOrderIDs)
	}

	err = GetRows(db, &afsSkuList, sql, sqlParams...)
	return afsSkuList, err
}

func GetOrderRefundSkuList(db *DaoDB, vendorOrderIDs []string) (afsSkuList []*model.OrderSkuFinancial, err error) {
	sql := `
	SELECT t1.*
	FROM order_sku_financial t1
	JOIN afs_order t2 ON t2.vendor_order_id = t1.vendor_order_id AND t2.vendor_id = t1.vendor_id AND t2.afs_order_id = t1.afs_order_id
	WHERE t1.is_afs_order = 1 
	`
	sqlParams := []interface{}{}
	if len(vendorOrderIDs) > 0 {
		sql += " AND t2.vendor_order_id IN (" + GenQuestionMarks(len(vendorOrderIDs)) + ")"
		sqlParams = append(sqlParams, vendorOrderIDs)
	}

	err = GetRows(db, &afsSkuList, sql, sqlParams...)
	return afsSkuList, err
}

func GetDailyFinishOrderList(db *DaoDB, storeID int, dateTime time.Time) (orderList []*model.OrderPickupTime, err error) {
	sql := `
	SELECT t2.status_time, t1.pick_deadline
	FROM goods_order t1
	JOIN order_status t2 ON t1.vendor_order_id = t2.vendor_order_id AND t1.vendor_id = t2.vendor_id
	WHERE t1.jx_store_id = ? AND t2.order_type = ? AND t2.status = ? AND DATE(t1.order_finished_at) = DATE(?)
	`
	sqlParams := []interface{}{
		storeID,
		model.OrderTypeOrder,
		model.OrderStatusFinishedPickup,
		dateTime,
	}
	return orderList, GetRows(db, &orderList, sql, sqlParams...)
}

func GetDailyBadCommentOrderCount(db *DaoDB, dateTime time.Time) (storeCountList []*model.StoreCount, err error) {
	beginTime, endTime := utils.GetTimeRange(dateTime, 1, true)
	return GetBadCommentOrderCount(db, beginTime, endTime)
}

func GetBadCommentOrderCountByDayNum(db *DaoDB, dayNum int, includeToday bool) (storeCountList []*model.StoreCount, err error) {
	beginTime, endTime := utils.GetTimeRange(utils.GetCurDate(), dayNum, includeToday)
	return GetBadCommentOrderCount(db, beginTime, endTime)
}

func GetBadCommentOrderCount(db *DaoDB, beginTime, endTime time.Time) (storeCountList []*model.StoreCount, err error) {
	sql := `
	SELECT jxstoreid store_id, COUNT(*) count 
	FROM jx_bad_comments 
	WHERE createtime >= ? AND createtime <= ?
	GROUP BY jxstoreid
	`
	sqlParams := []interface{}{
		beginTime,
		endTime,
	}
	err = GetRows(db, &storeCountList, sql, sqlParams)

	return storeCountList, err
}

func GetDailyUnFinishOrderCount(db *DaoDB, dateTime time.Time) (storeCountList []*model.StoreCount, err error) {
	beginTime, endTime := utils.GetTimeRange(dateTime, 1, true)
	return GetUnFinishOrderCount(db, beginTime, endTime)
}

func GetDailyFinishOrderCount(db *DaoDB, dateTime time.Time) (storeCountList []*model.StoreCount, err error) {
	beginTime, endTime := utils.GetTimeRange(dateTime, 1, true)
	return GetFinishOrderCount(db, beginTime, endTime)
}

func GetDailyAbsentGoodsOrderCount(db *DaoDB, dateTime time.Time) (storeCountList []*model.StoreCount, err error) {
	beginTime, endTime := utils.GetTimeRange(dateTime, 1, true)
	return GetAbsentGoodsOrderCount(db, beginTime, endTime)
}

func GetUnFinishOrderCount(db *DaoDB, beginTime, endTime time.Time) (storeCountList []*model.StoreCount, err error) {
	return GetEndOrderCount(db, []int{model.OrderStatusCanceled}, false, beginTime, endTime)
}

func GetFinishOrderCount(db *DaoDB, beginTime, endTime time.Time) (storeCountList []*model.StoreCount, err error) {
	return GetEndOrderCount(db, []int{model.OrderStatusFinished}, false, beginTime, endTime)
}

func GetAbsentGoodsOrderCount(db *DaoDB, beginTime, endTime time.Time) (storeCountList []*model.StoreCount, err error) {
	return GetEndOrderCount(db, []int{model.OrderStatusFinished}, true, beginTime, endTime)
}

func GetUnFinishOrderCountByDayNum(db *DaoDB, dayNum int, includeToday bool) (storeCountList []*model.StoreCount, err error) {
	return GetEndOrderCountByDayNum(db, []int{model.OrderStatusCanceled}, false, dayNum, includeToday)
}

func GetFinishOrderCountByDayNum(db *DaoDB, dayNum int, includeToday bool) (storeCountList []*model.StoreCount, err error) {
	return GetEndOrderCountByDayNum(db, []int{model.OrderStatusFinished}, false, dayNum, includeToday)
}

func GetAbsentGoodsOrderCountByDayNum(db *DaoDB, dayNum int, includeToday bool) (storeCountList []*model.StoreCount, err error) {
	return GetEndOrderCountByDayNum(db, []int{model.OrderStatusFinished}, true, dayNum, includeToday)
}

func GetEndOrderCountByDayNum(db *DaoDB, statusList []int, checkAbsentOrder bool, dayNum int, includeToday bool) (storeCountList []*model.StoreCount, err error) {
	beginTime, endTime := utils.GetTimeRange(utils.GetCurDate(), dayNum, includeToday)
	return GetEndOrderCount(db, statusList, checkAbsentOrder, beginTime, endTime)
}

func GetEndOrderCount(db *DaoDB, statusList []int, checkAbsentOrder bool, beginTime, endTime time.Time) (storeCountList []*model.StoreCount, err error) {
	sql := `
	SELECT jx_store_id store_id, COUNT(*) count 
	FROM goods_order
	WHERE order_finished_at >= ? AND order_finished_at <= ?
	`
	sqlParams := []interface{}{
		beginTime,
		endTime,
	}
	if len(statusList) > 0 {
		sql += ` AND status IN (` + GenQuestionMarks(len(statusList)) + `)`
		sqlParams = append(sqlParams, statusList)
	}
	if checkAbsentOrder {
		sql += `
		AND adjust_count > 0
		`
	}
	sql += `
	GROUP BY jx_store_id`
	err = GetRows(db, &storeCountList, sql, sqlParams)

	return storeCountList, err
}

func GetFinishOrderCountByDaDa(db *DaoDB, dayNum int, includeToday bool) (storeCountList []*model.StoreCount, err error) {
	return GetFinishOrderCountByWayBillVendorID(db, model.VendorIDDada, dayNum, includeToday)
}

func GetFinishOrderCountBySelfDelivery(db *DaoDB, dayNum int, includeToday bool) (storeCountList []*model.StoreCount, err error) {
	return GetFinishOrderCountByWayBillVendorID(db, model.VendorIDUnknown, dayNum, includeToday)
}

//通过运单平台ID来统计完成的订单量
func GetFinishOrderCountByWayBillVendorID(db *DaoDB, wayBillVendorID, dayNum int, includeToday bool) (storeCountList []*model.StoreCount, err error) {
	sql := `
	SELECT jx_store_id store_id, COUNT(*) count 
	FROM goods_order
	where order_finished_at >= ? AND order_finished_at <= ?
	AND status = ?
	AND waybill_vendor_id = ?
	GROUP BY jx_store_id
	`
	beginTime, endTime := utils.GetTimeRange(utils.GetCurDate(), dayNum, includeToday)
	sqlParams := []interface{}{
		beginTime,
		endTime,
		model.OrderStatusFinished,
		wayBillVendorID,
	}

	return storeCountList, GetRows(db, &storeCountList, sql, sqlParams)
}

//拣货履约订单量, 仅统计达达专送
func GetStandardPickTimeOrderCountByDaDa(db *DaoDB, dayNum int, includeToday bool) (storeCountList []*model.StoreCount, err error) {
	sql := `
	SELECT t1.jx_store_id store_id, COUNT(*) count 
	FROM goods_order t1
	JOIN order_status t2 ON t1.vendor_order_id = t2.vendor_order_id AND t1.vendor_id = t2.vendor_id
	WHERE t1.order_finished_at >= ? AND t1.order_finished_at <= ?
	AND t1.status = ?
	AND t1.waybill_vendor_id = ?
	AND t2.order_type = ?
	AND t2.status = ?
	AND t2.status_time <= t1.pick_deadline
	GROUP BY t1.jx_store_id
	`
	beginTime, endTime := utils.GetTimeRange(utils.GetCurDate(), dayNum, includeToday)
	sqlParams := []interface{}{
		beginTime,
		endTime,
		model.OrderStatusFinished,
		model.VendorIDDada,
		model.OrderTypeOrder,
		model.OrderStatusFinishedPickup,
	}

	return storeCountList, GetRows(db, &storeCountList, sql, sqlParams)
}

//按时履约订单量, 仅统计商家自送门店
func GetStandardFinishTimeOrderCountBySelfDelivery(db *DaoDB, dayNum int, includeToday bool) (storeCountList []*model.StoreCount, err error) {
	sql := `
	SELECT jx_store_id store_id, order_created_at, order_finished_at
	FROM goods_order
	WHERE order_finished_at >= ? AND order_finished_at <= ?
	AND status = ?
	AND waybill_vendor_id = ?
	`
	beginTime, endTime := utils.GetTimeRange(utils.GetCurDate(), dayNum, includeToday)
	sqlParams := []interface{}{
		beginTime,
		endTime,
		model.OrderStatusFinished,
		model.VendorIDUnknown,
	}

	standardTime := int64(3600)
	var storeOrderTimeList []*model.StoreOrderTime
	storeOrderTimeMapData := make(map[int]int)
	err = GetRows(db, &storeOrderTimeList, sql, sqlParams)
	if err == nil && len(storeOrderTimeList) > 0 {
		for _, value := range storeOrderTimeList {
			if value.OrderFinishedTime.Unix()-value.OrderCreateTime.Unix() <= standardTime {
				storeOrderTimeMapData[value.StoreID]++
			}
		}
		for storeID, count := range storeOrderTimeMapData {
			storeCountList = append(storeCountList, &model.StoreCount{storeID, count})
		}
	}

	return storeCountList, err
}

//10分钟取货完成订单量, 仅统计达达专送
func GetStandardPickUpTimeOrderCountByDaDa(db *DaoDB, dayNum int, includeToday bool) (storeCountList []*model.StoreCount, err error) {
	sql := `
	SELECT t1.jx_store_id store_id, t1.vendor_order_id, t2.status_time, t2.status
	FROM goods_order t1
	JOIN order_status t2 ON t1.vendor_order_id = t2.vendor_order_id AND t1.vendor_id = t2.vendor_id
	WHERE t1.order_finished_at >= ? AND t1.order_finished_at <= ?
	AND t1.status = ?
	AND t1.waybill_vendor_id = ?
	AND t2.status in (?, ?)
	ORDER BY t1.vendor_order_id, t2.status_time
	`
	beginTime, endTime := utils.GetTimeRange(utils.GetCurDate(), dayNum, includeToday)
	sqlParams := []interface{}{
		beginTime,
		endTime,
		model.OrderStatusFinished,
		model.VendorIDDada,
		model.OrderStatusFinishedPickup,
		model.OrderStatusDelivering,
	}

	standardTime := int64(600)
	var storeOrderStatusList []*model.StoreOrderStatus
	storeOrderTimeMapData := make(map[int][]*model.StoreOrderStatus)
	err = GetRows(db, &storeOrderStatusList, sql, sqlParams)
	if err == nil && len(storeOrderStatusList) > 0 {
		for _, value := range storeOrderStatusList {
			if storeOrderTimeMapData[value.StoreID] == nil {
				storeOrderTimeMapData[value.StoreID] = []*model.StoreOrderStatus{}
			}
			storeOrderTimeMapData[value.StoreID] = append(storeOrderTimeMapData[value.StoreID], value)
		}
		for storeID, valueList := range storeOrderTimeMapData {
			count := 0
			vendorOrderID := ""
			statusBeginTime := int64(0)
			statusEndTime := int64(0)
			for _, value := range valueList {
				if vendorOrderID != value.VendorOrderID {
					if statusBeginTime != 0 && statusEndTime != 0 {
						if statusEndTime-statusBeginTime <= standardTime {
							count++
						}
					}
					vendorOrderID = value.VendorOrderID
					statusBeginTime = int64(0)
					statusEndTime = int64(0)
				}
				if value.Status == model.OrderStatusFinishedPickup {
					statusBeginTime = value.StatusTime.Unix()
				} else if value.Status == model.OrderStatusDelivering {
					statusEndTime = value.StatusTime.Unix()
				}
			}
			if statusBeginTime != 0 && statusEndTime != 0 {
				if statusEndTime-statusBeginTime <= standardTime {
					count++
				}
			}
			if count > 0 {
				storeCountList = append(storeCountList, &model.StoreCount{storeID, count})
			}
		}
	}

	return storeCountList, err
}

//风控定单(门店相关人员在自己的门店下单)
func GetRiskOrderCount(db *DaoDB, dayNum int, includeToday bool) (storeOrderList []*model.StoreOrder, err error) {
	sql := `
	SELECT t1.jx_store_id store_id, t1.vendor_order_id
	FROM goods_order t1
	JOIN store t2 ON t2.id = t1.jx_store_id
	WHERE t1.order_finished_at >= ? AND t1.order_finished_at <= ?
	AND t1.consignee_mobile2 <> "" 
	AND (t1.consignee_mobile2 = t2.tel1 or t1.consignee_mobile2 = t2.tel2)
	GROUP BY t1.jx_store_id
	`
	beginTime, endTime := utils.GetTimeRange(utils.GetCurDate(), dayNum, includeToday)
	sqlParams := []interface{}{
		beginTime,
		endTime,
	}

	return storeOrderList, GetRows(db, &storeOrderList, sql, sqlParams)
}

func GetOrderPayList(db *DaoDB, vendorOrderID string, vendorID int) (payList []*model.OrderPay, err error) {
	sql := `
	SELECT t1.*
	FROM order_pay t1
	WHERE t1.deleted_at = ? AND t1.vendor_order_id = ? AND t1.vendor_id = ?
	`
	sqlParams := []interface{}{
		utils.DefaultTimeValue,
		vendorOrderID,
		vendorID,
	}
	return payList, GetRows(db, &payList, sql, sqlParams)
}

func GetOrders(db *DaoDB, ids []int64, isIncludeSku, isIncludeFake bool, fromDateStr, toDateStr string, isDateFinish bool, skuIDs []int, isJxFirst bool, userID string, params map[string]interface{}, offset, pageSize int) (orders []*model.GoodsOrderExt, totalCount int, err error) {
	pageSize = jxutils.FormalizePageSize(pageSize)
	offset = jxutils.FormalizePageOffset(offset)

	sql := fmt.Sprintf(`
	SELECT SQL_CALC_FOUND_ROWS a.* FROM (
	SELECT 
	 t1.*,
	-- CAST(IF(t1.earning_price <> 0, t1.earning_price, IF(t1.shop_price <> 0 && t1.shop_price < t1.sale_price, t1.shop_price, t1.sale_price) * IF(t1.order_pay_percentage > 0, t1.order_pay_percentage, %d) / 100) AS SIGNED) earning_price,
	t2.status waybill_status, t2.courier_name, t2.courier_mobile,
	t2.actual_fee, t2.desired_fee,t2.punctual_fee, t2.waybill_created_at, t2.waybill_finished_at, t2.vendor_waybill_id2 vendor_waybill_id2_waybill,
	t5.pay_percentage, t5.comment ,t5.old_pay_percentage, t5.market_man_phone, tu.name market_man_name,
	t5.operator_phone, t5.operator_phone2, t5.operator_phone3, tu1.name operator_name, tu2.name operator_name2, tu3.name operator_name3,
	t6.vendor_pay_percentage, 
	city.name city_name, district.name district_name,op.vendor_pay_type,
	ROUND(IF(t1.earning_type = 1, t1.total_shop_money-t1.earning_price-IFNULL(t2.desired_fee,0), t1.total_shop_money *(t1.order_pay_percentage/2)/100)) jx_income`, model.DefaultEarningPricePercentage)
	if isIncludeSku {
		sql += `,
		IF(t3.jx_sku_id > 0, t3.jx_sku_id, t3.sku_id) sku_id,
		t3.count sku_count2,
		t3.shop_price sku_shop_price,
		-- IF(t3.store_sub_id = 0, 0, t3.earning_price) 
		t3.earning_price sku_earning_price,
		t3.sale_price sku_sale_price,
		t3.sku_name`
	}
	sql += `
	FROM goods_order t1
	LEFT JOIN waybill t2 ON t1.vendor_waybill_id = t2.vendor_waybill_id AND t1.waybill_vendor_id = t2.waybill_vendor_id AND t1.vendor_order_id = t2.vendor_order_id
	LEFT JOIN store t5 ON t5.id = IF(t1.jx_store_id <> 0, t1.jx_store_id, t1.store_id)
	LEFT JOIN store_map t6 ON t6.store_id = t5.id AND t6.deleted_at = '1970-01-01 00:00:00' AND t6.vendor_id = t1.vendor_id
	LEFT JOIN place city ON city.code = t5.city_code
	LEFT JOIN place district ON district.code = t5.district_code
	LEFT JOIN user tu ON tu.mobile = t5.market_man_phone	
	LEFT JOIN user tu1 ON tu1.mobile = t5.operator_phone	
	LEFT JOIN user tu2 ON tu2.mobile = t5.operator_phone2	
	LEFT JOIN user tu3 ON tu3.mobile = t5.operator_phone3
	LEFT JOIN order_pay op ON op.vendor_order_id = t1.vendor_order_id 
	-- LEFT JOIN (SELECT MAX(created_at), afs_order_id, vendor_order_id, vendor_id FROM afs_order WHERE status = 180 GROUP BY 2, 3, 4) t7 ON t7.vendor_order_id = t1.vendor_order_id AND t7.vendor_id = t1.vendor_id
	-- LEFT JOIN afs_order t8 ON t8.afs_order_id = t7.afs_order_id 
	`
	if isIncludeSku {
		sql += `JOIN order_sku t3 ON t3.vendor_order_id = t1.vendor_order_id AND t3.vendor_id = t1.vendor_id`
		//	`
		//JOIN order_sku t3 ON t3.vendor_order_id = t1.vendor_order_id AND t3.vendor_id = t1.vendor_id
		//JOIN sku_name tsn ON t3.vendor_order_id = t1.vendor_order_id AND t3.vendor_id = t1.vendor_id
		//`
	}
	sqlWhere := " WHERE 1 = 1"
	var (
		sqlParams []interface{}
	)
	if len(ids) > 0 { // 如果给定了ids，忽略其它所有条件
		sqlWhere += " AND t1.id IN (" + GenQuestionMarks(len(ids)) + ")"
		sqlParams = append(sqlParams, ids)
	} else {
		// 如果搜索关键字可能为订单号，则当成订单号查询
		if params["keyword"] != nil {
			keyword := params["keyword"].(string)
			if jxutils.GetPossibleVendorIDFromVendorOrderID(keyword) > model.VendorIDUnknown && regexpNumber.MatchString(keyword) {
				params["vendorOrderID"] = params["keyword"]
			}
		}
		if params["orderID"] != nil || params["vendorOrderID"] != nil {
			sqlWhere += " AND (t1.vendor_order_id = ? OR t1.vendor_order_id2 = ?)"
			vendorOrderID := params["vendorOrderID"]
			if vendorOrderID == nil {
				vendorOrderID = params["orderID"]
			}
			sqlParams = []interface{}{
				vendorOrderID,
				vendorOrderID,
			}
		} else {
			timeList, err2 := jxutils.BatchStr2Time(fromDateStr, toDateStr)
			if err = err2; err != nil {
				return nil, 0, err
			}
			if utils.IsTimeZero(timeList[0]) {
				return nil, 0, fmt.Errorf("在没有指定订单号时，必须指定查询日期范围")
			}
			if utils.IsTimeZero(timeList[1]) {
				timeList[1] = timeList[0]
			}
			timeList[1] = timeList[1].Add(24 * time.Hour)
			if isDateFinish {
				sqlWhere += `
			AND t1.order_finished_at >= ? AND t1.order_finished_at < ?`
			} else {
				sqlWhere += `
			AND t1.order_created_at >= ? AND t1.order_created_at < ?`
			}
			sqlParams = []interface{}{
				timeList[0],
				timeList[1],
			}
			if params["keyword"] != nil {
				keyword := params["keyword"].(string)
				keywordLike := "%" + keyword + "%"
				sqlWhere += `
			AND (t1.store_name LIKE ? OR t1.vendor_order_id LIKE ? OR t1.vendor_order_id2 LIKE ? OR t1.vendor_store_id LIKE ?
			OR t1.consignee_name LIKE ? OR t1.consignee_mobile LIKE ? OR t1.consignee_mobile2 LIKE ? OR t1.consignee_address LIKE ?
			OR t2.vendor_waybill_id LIKE ? OR t2.courier_name LIKE ? OR t2.courier_mobile LIKE ? OR t5.name LIKE ?
			`
				sqlParams = append(sqlParams, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike)
				if keywordInt64, err2 := strconv.ParseInt(keyword, 10, 64); err2 == nil {
					sqlWhere += " OR t1.store_id = ? OR t1.jx_store_id = ?"
					sqlParams = append(sqlParams, keywordInt64, keywordInt64)
				}
				sqlWhere += ")"
			}
			if params["waybillVendorIDs"] != nil {
				var waybillVendorIDs []int
				if err = utils.UnmarshalUseNumber([]byte(params["waybillVendorIDs"].(string)), &waybillVendorIDs); err != nil {
					return nil, 0, err
				}
				if len(waybillVendorIDs) > 0 {
					sqlWhere += " AND t1.waybill_vendor_id IN (" + GenQuestionMarks(len(waybillVendorIDs)) + ")"
					sqlParams = append(sqlParams, waybillVendorIDs)
				}
			}
			if params["storeIDs"] != nil {
				var storeIDs []int
				if err = utils.UnmarshalUseNumber([]byte(params["storeIDs"].(string)), &storeIDs); err != nil {
					return nil, 0, err
				}
				if len(storeIDs) > 0 {
					if storeIDs[0] == 0 { // 容错
						sqlWhere += " AND 1 = 0"
					} else {
						sqlWhere += " AND IF(t1.jx_store_id != 0, t1.jx_store_id, t1.store_id) IN (" + GenQuestionMarks(len(storeIDs)) + ")"
						sqlParams = append(sqlParams, storeIDs)
					}
				}
			}
			if params["fromStoreIDs"] != nil {
				var fromStoreIDs []int
				if err = utils.UnmarshalUseNumber([]byte(params["fromStoreIDs"].(string)), &fromStoreIDs); err != nil {
					return nil, 0, err
				}
				if len(fromStoreIDs) > 0 {
					if fromStoreIDs[0] == 0 { // 容错
						sqlWhere += " AND 1 = 0"
					} else {
						sqlWhere += " AND  t1.from_store_id IN (" + GenQuestionMarks(len(fromStoreIDs)) + ")"
						sqlParams = append(sqlParams, fromStoreIDs)
					}
				}
			}
			if params["statuss"] != nil {
				var statuss []int
				if err = utils.UnmarshalUseNumber([]byte(params["statuss"].(string)), &statuss); err != nil {
					return nil, 0, err
				}
				if len(statuss) > 0 {
					sqlWhere += " AND t1.status IN (" + GenQuestionMarks(len(statuss)) + ")"
					sqlParams = append(sqlParams, statuss)
				}
			}
			if params["lockStatuss"] != nil {
				var lockStatuss []int
				if err = utils.UnmarshalUseNumber([]byte(params["lockStatuss"].(string)), &lockStatuss); err != nil {
					return nil, 0, err
				}
				if len(lockStatuss) > 0 {
					sqlWhere += " AND t1.lock_status IN (" + GenQuestionMarks(len(lockStatuss)) + ")"
					sqlParams = append(sqlParams, lockStatuss)
				}
			}
			if params["brandID"] != nil {
				if utils.MustInterface2Int64(params["brandID"]) != 0 {
					sqlWhere += " AND t5.brand_id = ?"
					sqlParams = append(sqlParams, utils.MustInterface2Int64(params["brandID"]))
				}
			}
			if params["marketManPhone"] != nil {
				sqlWhere += " AND t5.market_man_phone = ?"
				sqlParams = append(sqlParams, params["marketManPhone"].(string))
			}
			if params["jdPhone"] != nil {
				sqlWhere += " AND t5.operator_phone = ?"
				sqlParams = append(sqlParams, params["jdPhone"].(string))
			}
			if params["mtPhone"] != nil {
				sqlWhere += " AND t5.operator_phone2 = ?"
				sqlParams = append(sqlParams, params["mtPhone"].(string))
			}
			if params["ebaiPhone"] != nil {
				sqlWhere += " AND t5.operator_phone3 = ?"
				sqlParams = append(sqlParams, params["ebaiPhone"].(string))
			}
			if params["deliveryTypes"] != nil {
				var deliveryTypes []string
				if err = utils.UnmarshalUseNumber([]byte(params["deliveryTypes"].(string)), &deliveryTypes); err != nil {
					return nil, 0, err
				}
				if len(deliveryTypes) > 0 {
					sqlWhere += " AND t1.delivery_type IN (" + GenQuestionMarks(len(deliveryTypes)) + ")"
					sqlParams = append(sqlParams, deliveryTypes)
				}
			}
			// if params["deliveryType"] != nil {
			// 	if params["deliveryType"].(string) != "" {
			// 		sqlWhere += " AND t1.delivery_type = ?"
			// 		sqlParams = append(sqlParams, params["deliveryType"].(string))
			// 	}
			// }
			if params["cities"] != nil {
				var cities []int
				if err = utils.UnmarshalUseNumber([]byte(params["cities"].(string)), &cities); err != nil {
					return nil, 0, err
				}
				if len(cities) > 0 {
					sqlWhere += " AND t5.city_code IN (" + GenQuestionMarks(len(cities)) + ") AND t5.id IS NOT NULL"
					sqlParams = append(sqlParams, cities)
				}
			}
			if !isIncludeFake {
				sqlWhere += " AND (t1.flag & ?) = 0"
				sqlParams = append(sqlParams, model.OrderFlagMaskFake)
			}
			if len(skuIDs) > 0 {
				sqlWhere += " AND (SELECT COUNT(*) FROM order_sku t11 WHERE t11.vendor_order_id = t1.vendor_order_id AND t11.vendor_id = t1.vendor_id AND t11.jx_sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")) > 0"
				sqlParams = append(sqlParams, skuIDs)
			}
			if params["adjustCount"] != nil {
				sqlWhere += " AND t1.adjust_count >= ?"
				sqlParams = append(sqlParams, params["adjustCount"])
			}
			if mustInvoice, ok := params["mustInvoice"].(bool); ok && mustInvoice {
				sqlWhere += " AND t1.invoice_taxer_id <> ''"
			}
		}
		if params["vendorIDs"] != nil {
			var vendorIDs []int
			if err = utils.UnmarshalUseNumber([]byte(params["vendorIDs"].(string)), &vendorIDs); err != nil {
				return nil, 0, err
			}
			if len(vendorIDs) > 0 {
				sqlWhere += " AND t1.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")"
				sqlParams = append(sqlParams, vendorIDs)
			}
		}
		if userID != "" {
			sqlWhere += " AND t1.user_id = ?"
			sqlParams = append(sqlParams, userID)
		}
	}
	sql += sqlWhere
	if isJxFirst {
		sql += `
			ORDER BY IF(t1.status < ?, IF(t1.vendor_id = ?, 0, 1), 0), t1.order_created_at DESC`
		sqlParams = append(sqlParams, model.OrderStatusEndBegin, model.VendorIDJX)
	} else {
		if isIncludeSku && userID == "" && len(ids) == 0 {
			sql += `
				ORDER BY t1.id`
		} else {
			sql += `
				ORDER BY t1.order_created_at DESC`
		}
	}
	sql += `
		) a WHERE 1 = 1`

	if params["jxIncomeBegin"] != nil {
		//if utils.MustInterface2Int64(params["jxIncomeBegin"]) != 0 {
		sql += " AND a.jx_income >= ?"
		sqlParams = append(sqlParams, utils.MustInterface2Int64(params["jxIncomeBegin"]))
		//}
	}
	if params["jxIncomeEnd"] != nil {
		//globals.SugarLogger.Debugf("test  end=====%d", utils.MustInterface2Int64(params["jxIncomeEnd"]))
		//if utils.MustInterface2Int64(params["jxIncomeEnd"]) != 0 {
		sql += " AND a.jx_income <= ?"
		sqlParams = append(sqlParams, utils.MustInterface2Int64(params["jxIncomeEnd"]))
		//}
	}
	sql += " LIMIT ? OFFSET ?"
	sqlParams = append(sqlParams, pageSize, offset)
	txDB, _ := Begin(db)
	defer Commit(db, txDB)
	if err = GetRowsTx(txDB, &orders, sql, sqlParams...); err == nil {
		totalCount = GetLastTotalRowCount2(db, txDB)
	}
	return orders, totalCount, err
}

func UpdateOrdersWithoutJxStoreID(db *DaoDB, fromDate, toDate time.Time) (count int64, err error) {
	sql := `
		UPDATE goods_order t1
		JOIN store_map a ON a.vendor_store_id = t1.vendor_store_id AND a.vendor_id = t1.vendor_id
		SET t1.jx_store_id = a.store_id
		WHERE t1.jx_store_id = 0 
		AND a.deleted_at = ?
		AND t1.order_created_at >= ? AND t1.order_created_at <= ?
	`
	sqlParams := []interface{}{
		utils.DefaultTimeValue,
	}
	if !utils.IsTimeZero(fromDate) {
		sqlParams = append(sqlParams, fromDate)
		if !utils.IsTimeZero(toDate) {
			sqlParams = append(sqlParams, toDate)
		} else {
			sqlParams = append(sqlParams, time.Now())
		}
	} else {
		if !utils.IsTimeZero(toDate) {
			sqlParams = append(sqlParams, toDate.AddDate(0, 0, -5))
			sqlParams = append(sqlParams, toDate)
		} else {
			sqlParams = append(sqlParams, time.Now().AddDate(0, 0, -5))
			sqlParams = append(sqlParams, time.Now())
		}
	}
	return ExecuteSQL(db, sql, sqlParams)
}

func GetMyOrderCountInfo(db *DaoDB, userID string, fromDate, toDate time.Time, statuss []int) (countInfo []*model.GoodsOrderCountInfo, err error) {
	if utils.IsTimeZero(fromDate) {
		return nil, fmt.Errorf("必须指定开始日期")
	}
	if !utils.IsTimeZero(fromDate) {
		fromDate = utils.Time2Date(fromDate)
		if utils.IsTimeZero(toDate) {
			toDate = fromDate
		}
	}
	if !utils.IsTimeZero(toDate) {
		toDate = utils.Time2Date(toDate)
		toDate = toDate.Add(24 * time.Hour)
	}

	sql := `
	SELECT t1.lock_status, t1.status, COUNT(*) count
	FROM goods_order t1
	WHERE t1.user_id = ? AND t1.vendor_id = ?
	AND t1.order_created_at >= ? AND t1.order_created_at < ?
	`
	sqlParams := []interface{}{
		userID,
		model.VendorIDJX,
		fromDate, toDate,
	}
	if len(statuss) > 0 {
		sql += " AND t1.status IN (" + GenQuestionMarks(len(statuss)) + ")"
		sqlParams = append(sqlParams, statuss)
	}
	sql += " GROUP BY 1,2"
	err = GetRows(db, &countInfo, sql, sqlParams...)
	return countInfo, err
}

func GetPendingFakeOrders(db *DaoDB, vendorIDs []int, orderCreatedAfter, orderCreatedBefore time.Time) (orderList []*model.GoodsOrder, err error) {
	sql := `
	SELECT t1.*
	FROM goods_order t1
	JOIN new_config t2 ON t2.type = ? AND t2.key = ? AND t2.deleted_at = ?
		AND LOCATE(IF(t1.consignee_mobile2 <> '', t1.consignee_mobile2, t1.consignee_mobile), t2.value) > 0
	WHERE t1.order_created_at >= ? AND t1.order_created_at <= ?
	AND t1.delivery_type = ?
	AND t1.status >= ? AND t1.status < ?
	`
	sqlParams := []interface{}{
		model.ConfigTypeSys,
		model.ConfigSysFakeOrderMobiles,
		utils.DefaultTimeValue,
		orderCreatedAfter,
		orderCreatedBefore,
		model.OrderDeliveryTypeSelfTake,
		model.OrderStatusAccepted,
		model.OrderStatusEndBegin,
	}
	if len(vendorIDs) > 0 {
		sql += " AND t1.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")"
		sqlParams = append(sqlParams, vendorIDs)
	}
	err = GetRows(db, &orderList, sql, sqlParams...)
	return orderList, err
}

// 不会有Skus信息
func LoadPendingOrders(db *DaoDB, orderCreatedAfter time.Time, beforStatus int) (orderList []*model.GoodsOrder, err error) {
	sql := `
	SELECT *
	FROM goods_order
	WHERE order_created_at >= ?
	AND status < ?`
	sqlParams := []interface{}{orderCreatedAfter, beforStatus}
	err = GetRows(db, &orderList, sql, sqlParams...)
	return orderList, err
}

func GetWayBillByOrderID(db *DaoDB, orderStatus, vendorID, waybillVendorID int, vendorOrderID string) (wayBillList []*model.Waybill, err error) {
	sql := `
		SELECT b.*
		FROM goods_order a 
		JOIN waybill b ON IF(a.waybill_vendor_id = -1,a.vendor_order_id,a.vendor_waybill_id) = b.vendor_waybill_id AND b.order_vendor_id = a.vendor_id
		WHERE a.vendor_order_id = ?
		AND a.vendor_id = ?
	`
	sqlParams := []interface{}{
		vendorOrderID,
		vendorID,
	}
	if orderStatus > 0 {
		sql += ` AND a.status = ?`
		sqlParams = append(sqlParams, orderStatus)
	}
	if waybillVendorID > 0 {
		sql += ` AND b.waybill_vendor_id = ?`
		sqlParams = append(sqlParams, waybillVendorID)
	}
	err = GetRows(db, &wayBillList, sql, sqlParams...)
	return wayBillList, err
}

func GetComplaintList(db *DaoDB, orderId string, vendorWaybillId string) ([]*model.Waybill, error) {
	sql := ` SELECT * FROM waybill WHERE vendor_order_id = ? `
	var param []interface{}
	param = append(param, orderId)
	if vendorWaybillId != "" {
		sql += ` AND vendor_waybill_id = ? `
		param = append(param, vendorWaybillId)
	}

	sql += ` AND waybill_vendor_id IN (?,?,?) `
	param = append(param, model.VendorIDFengNiao, model.VendorIDDada, model.VendorIDMTPS)

	var data []*model.Waybill
	if err := GetRows(db, &data, sql, param...); err != nil {
		return nil, err
	}
	return data, nil
}

func GetOrdersSupplement(db *DaoDB, storIDs, vendorIDs, statuss []int, vendorOrderID string, fromTime, toTime time.Time, stype, IsReverse, offset, pageSize int) (orderSupplementFee []*model.OrderSupplementFee, totalCount int, err error) {
	sql := `
		SELECT SQL_CALC_FOUND_ROWS * 
		FROM order_supplement_fee
		WHERE 1=1
		AND deleted_at = ?
	`
	sqlParams := []interface{}{
		utils.DefaultTimeValue,
	}
	if !utils.IsTimeZero(fromTime) {
		sql += " AND supplement_time >= ?"
		sqlParams = append(sqlParams, fromTime)
	}
	if !utils.IsTimeZero(toTime) {
		sql += " AND supplement_time <= ?"
		sqlParams = append(sqlParams, toTime)
	}
	if len(storIDs) > 0 {
		sql += " AND store_id IN (" + GenQuestionMarks(len(storIDs)) + ")"
		sqlParams = append(sqlParams, storIDs)
	}
	if len(vendorIDs) > 0 {
		sql += " AND vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")"
		sqlParams = append(sqlParams, vendorIDs)
	}
	if vendorOrderID != "" {
		sql += " AND vendor_order_id = ?"
		sqlParams = append(sqlParams, vendorOrderID)
	}
	if len(statuss) > 0 {
		sql += " AND status IN (" + GenQuestionMarks(len(statuss)) + ")"
		sqlParams = append(sqlParams, statuss)
	}
	if stype > 0 {
		sql += " AND type = ?"
		sqlParams = append(sqlParams, stype)
	}
	if IsReverse == -1 {
		sql += " AND link_id = 0"
	} else if IsReverse == 1 {
		sql += " AND link_id <> 0"
	}
	sql += " ORDER BY supplement_time DESC"
	sql += " LIMIT ? OFFSET ?"
	sqlParams = append(sqlParams, pageSize, offset)
	txDB, _ := Begin(db)
	defer Commit(db, txDB)
	if err = GetRowsTx(txDB, &orderSupplementFee, sql, sqlParams...); err == nil {
		totalCount = GetLastTotalRowCount2(db, txDB)
	}
	return orderSupplementFee, totalCount, err
}

func GetOrdersSupplementNoPage(db *DaoDB, ID int, storIDs, vendorIDs, statuss []int, vendorOrderID string, fromTime, toTime time.Time, stype, IsReverse int) (orderSupplementFee []*model.OrderSupplementFee, err error) {
	sql := `
		SELECT * 
		FROM order_supplement_fee
		WHERE 1=1
		AND deleted_at = ?
	`
	sqlParams := []interface{}{
		utils.DefaultTimeValue,
	}
	if !utils.IsTimeZero(fromTime) {
		sql += " AND supplement_time >= ?"
		sqlParams = append(sqlParams, fromTime)
	}
	if !utils.IsTimeZero(toTime) {
		sql += " AND supplement_time <= ?"
		sqlParams = append(sqlParams, toTime)
	}
	if len(storIDs) > 0 {
		sql += " AND store_id IN (" + GenQuestionMarks(len(storIDs)) + ")"
		sqlParams = append(sqlParams, storIDs)
	}
	if len(vendorIDs) > 0 {
		sql += " AND vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")"
		sqlParams = append(sqlParams, vendorIDs)
	}
	if vendorOrderID != "" {
		sql += " AND vendor_order_id = ?"
		sqlParams = append(sqlParams, vendorOrderID)
	}
	if len(statuss) > 0 {
		sql += " AND status IN (" + GenQuestionMarks(len(statuss)) + ")"
		sqlParams = append(sqlParams, statuss)
	}
	if stype > 0 {
		sql += " AND type = ?"
		sqlParams = append(sqlParams, stype)
	}
	if ID > 0 {
		sql += " AND id = ?"
		sqlParams = append(sqlParams, ID)
	}
	if IsReverse == -1 {
		sql += " AND link_id = 0"
	} else if IsReverse == 1 {
		sql += " AND link_id <> 0"
	}
	err = GetRows(db, &orderSupplementFee, sql, sqlParams...)
	return orderSupplementFee, err
}

func GetJxOrderCount(db *DaoDB, storeID int, orderID string, date time.Time) (count int, err error) {
	if utils.IsTimeZero(date) {
		date = time.Now()
	}
	sql := `
	SELECT COUNT(*) ct
	FROM goods_order t1
	WHERE t1.vendor_id = ? AND t1.jx_store_id = ? AND (t1.status >= ? OR t1.order_seq > 0) AND t1.order_created_at >= ? AND t1.order_created_at < ?
	`
	sqlParams := []interface{}{
		model.VendorIDJX,
		storeID,
		model.OrderStatusNew,
		utils.Time2Date(date),
		utils.Time2Date(date).Add(24 * time.Hour),
	}

	if orderID != "" {
		sql += " AND t1.vendor_order_id != ?"
		sqlParams = append(sqlParams, orderID)
	}
	err = GetRow(db, &count, sql, sqlParams...)
	return count, err
}

// GetVendorOrderNumber 查询当前平台当然订单数（抖音没有订单seq）
func GetVendorOrderNumber(db *DaoDB, vendorId int64, vendorStoreId string) (count int, err error) {
	nowTime := time.Now()
	date := time.Date(nowTime.Year(), nowTime.Month(), nowTime.Day(), 0, 0, 0, 0, time.Local)
	sql := `
	SELECT COUNT(*) ct
	FROM goods_order t1
	WHERE  t1.vendor_store_id = ? AND t1.vendor_id = ?  AND t1.order_created_at >= ? AND t1.order_created_at < ?
	`
	sqlParams := []interface{}{
		vendorStoreId,
		vendorId,
		utils.Time2Date(date),
		utils.Time2Date(date).Add(24 * time.Hour),
	}
	err = GetRow(db, &count, sql, sqlParams...)
	return count, err
}

func GetOrdersForJxPay(db *DaoDB, finishTimeBegin, finishTimeEnd time.Time) (goods []*GoodsOrderPay, err error) {
	sql := `
		SELECT a.*,b.transaction_id 
		FROM goods_order a
		JOIN order_pay b ON a.vendor_order_id = b.vendor_order_id AND a.vendor_id = b.vendor_id 
		JOIN user c ON c.user_id = a.user_id
		WHERE a.vendor_id = ?
		  AND a.order_finished_at >= ?
		  AND a.order_finished_at <= ?
		  AND a.status = ?
		  AND c.parent_mobile <> ''
		  AND a.store_id <> ?
	`
	sqlParams := []interface{}{
		model.VendorIDJX,
		finishTimeBegin,
		finishTimeEnd,
		model.OrderStatusFinished,
		model.MatterStoreID,
	}
	err = GetRows(db, &goods, sql, sqlParams...)
	return goods, err
}

// UpdateWaybillActualFee 修改运单实际支付价格
func UpdateWaybillActualFee(db *DaoDB, vendorWaybillId, vendorOrderId string, actualFee, desiredFee int64) error {
	sql := ` UPDATE waybill SET actual_fee = ? ,desired_fee = ? WHERE vendor_order_id = ? AND vendor_waybill_id = ?`
	_, err := ExecuteSQL(db, sql, []interface{}{actualFee, desiredFee, vendorOrderId, vendorWaybillId}...)
	return err
}

func GetWaybills(db *DaoDB, vendorOrderID string, vendors []int64) (waybills []*model.Waybill, err error) {
	sql := `		SELECT * 
			FROM waybill 
			WHERE vendor_order_id = ? 
	`
	sqlParams := []interface{}{vendorOrderID}
	if len(vendors) > model.NO {
		sql += " AND waybill_vendor_id IN (" + GenQuestionMarks(len(vendors)) + ")"
		sqlParams = append(sqlParams, vendors)
	}

	sql += ` ORDER BY waybill_created_at asc`
	err = GetRows(db, &waybills, sql, sqlParams...)
	return waybills, err
}

// GetWayBillsByWayBillId 根据运单id获取运单id(专用于抖店查询,抖店返回的运单id实际就是订单id,本地存放的运单id为真实id)
func GetWayBillsByWayBillId(db *DaoDB, vendorWayBillId string) (waybills []*model.Waybill, err error) {
	sql := `SELECT * 
			FROM waybill 
			WHERE vendor_order_id = ? ORDER BY created_at desc
	`
	sqlParams := []interface{}{vendorWayBillId}
	err = GetRows(db, &waybills, sql, sqlParams)
	return waybills, err
}

// GetWayBillFakeOrder 获取当前系统未完成的假订单
func GetWayBillFakeOrder() (waybills []*model.Waybill, err error) {
	sql := `
			SELECT * 
			FROM waybill 
			WHERE waybill_created_at >= ? AND waybill_created_at < ?  AND waybill_vendor_id = ? AND status < ? AND status <> ?  
	`

	sqlParams := []interface{}{time.Now().Add(-120 * 24 * time.Hour), time.Now(), model.VendorJXFakeWL, model.WaybillStatusFailed, model.WaybillStatusCanceled}
	err = GetRows(GetDB(), &waybills, sql, sqlParams)
	return waybills, err
}

func GetMatterChildOrders(db *DaoDB, vendorOrderID string) (goods []*model.GoodsOrder, err error) {
	sql := `SELECT * 
			FROM goods_order
	 		WHERE vendor_order_id LIKE ? OR vendor_order_id LIKE ? OR vendor_order_id LIKE ?
			 AND vendor_id = ?
		ORDER BY vendor_order_id DESC
	`
	sqlParams := []interface{}{
		vendorOrderID + "0%", vendorOrderID + "1%", vendorOrderID + "2%",
		model.VendorIDJX,
	}
	err = GetRows(db, &goods, sql, sqlParams)
	return goods, err
}

func GetSimpleOrder(db *DaoDB, vendorOrderID string) (goods *model.GoodsOrder, err error) {
	sql := `
		SELECT * 
		  FROM goods_order
		 WHERE vendor_order_id = ? 
	`
	sqlParams := []interface{}{vendorOrderID}
	err = GetRow(db, &goods, sql, sqlParams)
	return goods, err
}

func GetSimpleOrderSkus(db *DaoDB, vendorOrderID string, skuIDs []int) (skus []*model.OrderSku, err error) {
	sql := `
		SELECT * 
		  FROM order_sku
		 WHERE vendor_order_id = ? 
	`
	sqlParams := []interface{}{vendorOrderID}
	if len(skuIDs) > 0 {
		sql += " AND sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
		sqlParams = append(sqlParams, skuIDs)
	}
	err = GetRows(db, &skus, sql, sqlParams)
	return skus, err
}

func GetAfsOrdersByPage(db *DaoDB, vendorOrderID, afsOrderID, userID string, fromTime, toTime time.Time, offset, pageSize int) (afsOrderList []*model.AfsOrder, totalCount int, err error) {
	pageSize = jxutils.FormalizePageSize(pageSize)
	offset = jxutils.FormalizePageOffset(offset)
	sql := `
	SELECT SQL_CALC_FOUND_ROWS t1.*
	FROM afs_order t1
	LEFT JOIN goods_order t2 ON t2.vendor_order_id = t1.vendor_order_id AND t2.vendor_id = t1.vendor_id
	WHERE 1 = 1
	`
	sqlParams := []interface{}{}
	if vendorOrderID != "" {
		sql += " AND t1.vendor_order_id = ?"
		sqlParams = append(sqlParams, vendorOrderID)
	}
	if afsOrderID != "" {
		sql += " AND t1.afs_order_id = ?"
		sqlParams = append(sqlParams, afsOrderID)
	}
	if !utils.IsTimeZero(fromTime) {
		sql += " AND t1.afs_created_at >= ?"
		sqlParams = append(sqlParams, fromTime)
	}
	if !utils.IsTimeZero(toTime) {
		sql += " AND t1.afs_created_at <= ?"
		sqlParams = append(sqlParams, toTime)
	}
	if userID != "" {
		sql += " AND t2.user_id = ?"
		sqlParams = append(sqlParams, userID)
	}
	sql += ` ORDER BY t1.afs_order_id DESC 
			 LIMIT ? OFFSET ?
			`
	sqlParams = append(sqlParams, pageSize, offset)
	txDB, _ := Begin(db)
	defer Commit(db, txDB)
	if err = GetRowsTx(txDB, &afsOrderList, sql, sqlParams...); err == nil {
		totalCount = GetLastTotalRowCount2(db, txDB)
	}
	return afsOrderList, totalCount, err
}

func GetOrderStoreSkusCount(db *DaoDB, storeID, skuID int, fromTime, toTime time.Time) (count int64, err error) {
	tmpOrderSku := &model.OrderSku{}
	sql := `
				SELECT SUM(a.count) count
				  FROM order_sku a
			      JOIN goods_order b ON a.vendor_order_id = b.vendor_order_id AND a.vendor_id = b.vendor_id
				 WHERE IF(b.store_id = 0, b.jx_store_id, b.store_id) = ?
				   AND a.sku_id = ? 
				   AND b.order_created_at BETWEEN ? AND ?
				   AND b.status >= ?
			`
	sqlParams := []interface{}{
		storeID,
		skuID,
		fromTime,
		toTime,
		model.OrderStatusDelivering,
	}
	if err = GetRow(db, &tmpOrderSku, sql, sqlParams); err == nil {
		return int64(tmpOrderSku.Count), nil
	}
	return count, err
}

type GetSupplySupportStoreSkusResult struct {
	SkuID     int `orm:"column(sku_id)" json:"skuID"`
	Count     int `json:"count"`
	SalePrice int `json:"salePrice"`
	Stock     int `json:"stock"`
	model.SkuName
}

func GetSupplySupportStoreSkus(db *DaoDB, fromDate, toDate time.Time, fromStoreID, storeID int, percentage float64) (getSupplySupportStoreSkusResult []*GetSupplySupportStoreSkusResult, err error) {
	sql := `
		SELECT c.sku_id,CEIL(c.count) count,CEIL(c.count)  * d.jx_price sale_price, d.stock, f.*
		FROM
		(
			SELECT a.sku_id,SUM(a.count * ? ) count  FROM order_sku a 
			JOIN goods_order b ON b.vendor_order_id = a.vendor_order_id AND a.vendor_id = b.vendor_id
			WHERE b.order_created_at > ?
			AND b.order_created_at < ?
			AND a.sku_id <> ?
			AND IF(b.store_id = 0,b.jx_store_id,b.store_id) = ?
			GROUP BY 1 
		)c
		JOIN store_sku_bind d ON d.store_id = ? AND d.sku_id = c.sku_id AND d.deleted_at = ?
		JOIN sku e ON e.id = d.sku_id 
		JOIN sku_name f ON f.id = e.name_id
	   WHERE d.status <> ?
	     AND d.stock <> ?
		ORDER BY c.count desc
	`
	sqlParams := []interface{}{
		percentage,
		fromDate,
		toDate,
		6039481, //葱姜蒜
		fromStoreID,
		storeID, utils.DefaultTimeValue,
		model.StoreSkuBindStatusDontSale,
		0,
	}
	if err = GetRows(db, &getSupplySupportStoreSkusResult, sql, sqlParams); err == nil {
		return getSupplySupportStoreSkusResult, err
	}
	return getSupplySupportStoreSkusResult, err
}

func GetPriceDefendOrder(db *DaoDB, vendorOrderID string, storeIDs, skuIDs, issues []int, defendPrice, isBuyNowPrice, isSuccess, isPay int, userID string, beginAt, EndAt time.Time, isDesc bool) (priceDefendOrders []*model.PriceDefendOrder, err error) {
	sql := ` 
		SELECT a.*
		  FROM price_defend_order a
		  JOIN user_delivery_address b ON a.address_id = b.id AND b.deleted_at = ?
		 WHERE 1 = 1 
		   AND a.deleted_at = ?
	`
	sqlParams := []interface{}{
		utils.DefaultTimeValue,
		utils.DefaultTimeValue,
	}
	if vendorOrderID != "" {
		sql += " AND a.vendor_order_id = ?"
		sqlParams = append(sqlParams, vendorOrderID)
	}
	if len(storeIDs) > 0 {
		sql += " AND a.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")"
		sqlParams = append(sqlParams, storeIDs)
	}
	if len(skuIDs) > 0 {
		sql += " AND a.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
		sqlParams = append(sqlParams, skuIDs)
	}
	if len(issues) > 0 {
		sql += " AND a.issue IN (" + GenQuestionMarks(len(issues)) + ")"
		sqlParams = append(sqlParams, issues)
	}
	if defendPrice != 0 {
		sql += " AND a.defend_price = ?"
		sqlParams = append(sqlParams, defendPrice)
	}
	if isBuyNowPrice != -1 {
		sql += " AND a.is_buy_now_price = ?"
		sqlParams = append(sqlParams, isBuyNowPrice)
	}
	if isSuccess != -1 {
		sql += " AND a.is_success = ?"
		sqlParams = append(sqlParams, isSuccess)
	}
	if isPay != -1 {
		sql += " AND a.is_pay = ?"
		sqlParams = append(sqlParams, isPay)
	}
	if userID != "" {
		sql += " AND b.user_id = ?"
		sqlParams = append(sqlParams, userID)
	}
	if beginAt != utils.ZeroTimeValue {
		sql += " AND a.created_at >= ?"
		sqlParams = append(sqlParams, beginAt)
	}
	if EndAt != utils.ZeroTimeValue {
		sql += " AND a.created_at <= ?"
		sqlParams = append(sqlParams, EndAt)
	}
	if isDesc {
		sql += " ORDER BY a.created_at DESC"
	} else {
		sql += " ORDER BY a.created_at"
	}
	err = GetRows(db, &priceDefendOrders, sql, sqlParams)
	return priceDefendOrders, err
}

func GetCoupons(db *DaoDB, couponType int, couponStatuss, storeIDs []int, userID, mobile, keyword string) (coupons []*model.Coupons, err error) {
	sqlParams := []interface{}{}
	sql := `
		SELECT DISTINCT a.* 
		  FROM coupons a
	`
	if userID != "" || mobile != "" {
		sql += " JOIN user_coupons b ON a.id = b.coupon_id"
		if userID != "" {
			sql += " AND b.user_id = ?"
			sqlParams = append(sqlParams, userID)
		}
		if mobile != "" {
			sql += " AND b.mobile = ?"
			sqlParams = append(sqlParams, mobile)
		}
	}
	sql += `
		 WHERE a.is_all = ?
	 `
	sqlParams = append(sqlParams, model.YES)
	if couponType != 0 {
		sql += " AND a.coupon_type = ?"
		sqlParams = append(sqlParams, couponType)
	}
	if keyword != "" {
		sql += " AND (a.name LIKE ? OR a.desc LIKE ?)"
		sqlParams = append(sqlParams, "%"+keyword+"%", "%"+keyword+"%")
	}
	if len(couponStatuss) > 0 {
		sql += " AND a.coupon_status IN (" + GenQuestionMarks(len(couponStatuss)) + ")"
		sqlParams = append(sqlParams, couponStatuss)
	}
	sql += `
		UNION 
		SELECT DISTINCT a.*
		  FROM coupons a
		  LEFT JOIN store_coupons b ON a.id = b.coupon_id AND b.deleted_at = ?
	`
	if userID != "" || mobile != "" {
		sql += " JOIN user_coupons c ON a.id = c.coupon_id"
		if userID != "" {
			sql += " AND c.user_id = ?"
			sqlParams = append(sqlParams, userID)
		}
		if mobile != "" {
			sql += " AND c.mobile = ?"
			sqlParams = append(sqlParams, mobile)
		}
	}
	sql += `
		 WHERE 1 = 1
	`
	sqlParams = append(sqlParams, utils.DefaultTimeValue)
	if couponType != 0 {
		sql += " AND a.coupon_type = ?"
		sqlParams = append(sqlParams, couponType)
	}
	if keyword != "" {
		sql += " AND (a.name LIKE ? OR a.desc LIKE ?)"
		sqlParams = append(sqlParams, "%"+keyword+"%", "%"+keyword+"%")
	}
	if len(couponStatuss) > 0 {
		sql += " AND a.coupon_status IN (" + GenQuestionMarks(len(couponStatuss)) + ")"
		sqlParams = append(sqlParams, couponStatuss)
	}
	if len(storeIDs) > 0 {
		sql += " AND b.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")"
		sqlParams = append(sqlParams, storeIDs)
	}
	err = GetRows(db, &coupons, sql, sqlParams)
	return coupons, err
}

func GetStoreCoupons(db *DaoDB, couponIDs, storeIDs []int) (storeCoupons []*model.StoreCoupons, err error) {
	sql := `
		SELECT *
		  FROM store_coupons
		 WHERE deleted_at = ? 
	`
	sqlParams := []interface{}{utils.DefaultTimeValue}
	if len(couponIDs) > 0 {
		sql += " AND coupon_id IN (" + GenQuestionMarks(len(couponIDs)) + ")"
		sqlParams = append(sqlParams, couponIDs)
	}
	if len(storeIDs) > 0 {
		sql += " AND store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")"
		sqlParams = append(sqlParams, storeIDs)
	}
	err = GetRows(db, &storeCoupons, sql, sqlParams)
	return storeCoupons, err
}

func GetUserCoupons(db *DaoDB, couponIDs []int, userIDs, mobiles []string, userStatus int) (userCoupons []*model.UserCoupons, err error) {
	sql := `
		SELECT *
		  FROM user_coupons
		 WHERE 1 = 1
	`
	sqlParams := []interface{}{}
	if len(couponIDs) > 0 {
		sql += " AND coupon_id IN (" + GenQuestionMarks(len(couponIDs)) + ")"
		sqlParams = append(sqlParams, couponIDs)
	}
	if len(userIDs) > 0 {
		sql += " AND user_id IN (" + GenQuestionMarks(len(userIDs)) + ")"
		sqlParams = append(sqlParams, userIDs)
	}
	if len(mobiles) > 0 {
		sql += " AND mobile IN (" + GenQuestionMarks(len(mobiles)) + ")"
		sqlParams = append(sqlParams, mobiles)
	}
	if userStatus != 0 {
		sql += " AND user_coupon_status = ?"
		sqlParams = append(sqlParams, userStatus)
	}
	err = GetRows(db, &userCoupons, sql, sqlParams)
	return userCoupons, err
}

type QueryOrdersForManageStateResult struct {
	VendorOrderID string `orm:"column(vendor_order_id)"`
	BindID        int    `orm:"column(bind_id)"`
}

func QueryOrdersForManageState(db *DaoDB, storeID, vendorID, status int, fromTime, toTime time.Time) (userCoupons []*QueryOrdersForManageStateResult, err error) {
	sql := `
		SELECT a.vendor_order_id ,b.id bind_id
		  FROM goods_order a
		  LEFT JOIN waybill b ON a.vendor_order_id = b.vendor_order_id
		 WHERE 1 = 1
	`
	sqlParams := []interface{}{}
	if storeID != 0 {
		sql += " AND (a.storeID = ? OR a.jx_store_id = ?)"
		sqlParams = append(sqlParams, storeID, storeID)
	}
	if vendorID != -1 {
		sql += " AND a.vendor_id = ?"
		sqlParams = append(sqlParams, vendorID)
	}
	if status != 0 {
		sql += " AND a.status = ?"
		sqlParams = append(sqlParams, status)
	}
	if !utils.IsTimeZero(fromTime) {
		sql += " AND a.order_created_at > ?"
		sqlParams = append(sqlParams, fromTime)
	}
	if !utils.IsTimeZero(toTime) {
		sql += " AND a.order_created_at < ?"
		sqlParams = append(sqlParams, toTime)
	}
	err = GetRows(db, &userCoupons, sql, sqlParams)
	return userCoupons, err
}

func GetTaoOrderVendor(db *DaoDB, startTime, endTime time.Time) (map[string]string, error) {
	sql := ` SELECT * FROM goods_order g WHERE g.order_created_at >= ? AND g.order_created_at <= ? AND g.vendor_id = ? AND g.total_shop_money = ? `
	param := []interface{}{startTime, endTime, model.VendorIDTaoVegetable, model.NO}
	result := make([]*model.GoodsOrder, 0, 0)

	if err := GetRows(db, &result, sql, param); err != nil {
		return nil, err
	}

	data := make(map[string]string, 0)
	if len(result) > 0 {
		for _, v := range result {
			data[v.VendorStoreID] = v.VendorOrgCode
		}
	}
	return data, nil
}

func GetOrderStoreIDs(db *DaoDB, beginAt, endAt time.Time, vendorID int) (storeIDs []int, err error) {
	var (
		stores []*model.Store
	)
	sql := `
		SELECT DISTINCT IF(store_id = 0, jx_store_id, store_id) id
 		  FROM goods_order
		 WHERE order_created_at > ? AND order_created_at < ?
		   AND vendor_id = ?
		   AND status = ?
	`
	sqlParams := []interface{}{beginAt, endAt, vendorID, model.OrderStatusFinished}
	if err = GetRows(db, &stores, sql, sqlParams); err == nil {
		for _, v := range stores {
			storeIDs = append(storeIDs, v.ID)
		}
	}
	return storeIDs, err
}

// GetOrderListByStoreList 根据门店id获取正在刷单的门店商品
func GetOrderListByStoreList(db *DaoDB, storeId []int64, vendorId int) (order []*model.GoodsOrder, err error) {
	sql := `SELECT * FROM goods_order g WHERE g.order_created_at >= ? AND g.order_created_at <= ? AND g.jx_store_id IN (` + GenQuestionMarks(len(storeId)) + `)` + ` AND g.vendor_id = ? ` + `AND g.status < ?`
	sqlParam := []interface{}{time.Now().AddDate(0, 0, -5), time.Now().AddDate(0, 0, 1), storeId, vendorId, model.OrderStatusDelivering}

	if err := GetRows(db, &order, sql, sqlParam...); err != nil {
		return nil, err
	}

	return order, nil
}

type CourierInfo struct {
	CourierName   string `json:"courier_name"`
	CourierMobile string `json:"courier_mobile"`
}

// GetAddressRiderInfo 获取同区域的骑手信息
func GetAddressRiderInfo(db *DaoDB, address string) ([]*CourierInfo, error) {
	sql := `			
		SELECT DISTINCT w.courier_mobile,w.courier_name FROM goods_order s
      	LEFT JOIN waybill w ON s.vendor_order_id = w.vendor_order_id AND w.courier_name <>"" AND w.courier_mobile <>""
		WHERE s.order_created_at >= ?  AND s.consignee_address LIKE ? `
	param := []interface{}{time.Now().AddDate(-2, 0, 0), "%" + fmt.Sprintf("%s", address) + "%"}

	var courier []*CourierInfo
	if err := GetRows(db, &courier, sql, param); err != nil {
		return nil, err
	}

	return courier, nil
}

func StaticStoreOrderChange(db *DaoDB, storeId []int, start, end time.Time, rank string, offSet, pageSize int) ([]*StoreOrderRank, int, error) {
	dailyOrders := `
	SELECT 
        g.jx_store_id,
        DATE(g.order_created_at) AS order_date,
        COUNT(g.vendor_order_id) AS order_count
    FROM goods_order g WHERE 1=1 `
	dailyParam := []interface{}{}
	if len(storeId) != 0 {
		dailyOrders += ` AND g.jx_store_id IN (` + GenQuestionMarks(len(storeId)) + `)`
		dailyParam = append(dailyParam, storeId)
	}
	if !utils.IsTimeZero(start) {
		dailyOrders += ` AND g.order_created_at >= ?`
		dailyParam = append(dailyParam, start)
	}
	if !utils.IsTimeZero(end) {
		dailyOrders += ` AND g.order_created_at <= ?`
		dailyParam = append(dailyParam, end)
	}
	dailyOrders += ` AND  g.status <> 115  GROUP BY g.jx_store_id,DATE(g.order_created_at) )AS daily_orders `

	storeTotals := `
	SELECT 
		jx_store_id,
		SUM(order_count) AS total_orders
	FROM (
			SELECT 
				g.jx_store_id,
				COUNT(g.vendor_order_id) AS order_count
			FROM goods_order g 
			WHERE 1=1 `
	if len(storeId) != 0 {
		storeTotals += ` AND g.jx_store_id IN (` + GenQuestionMarks(len(storeId)) + `)`
		dailyParam = append(dailyParam, storeId)
	}
	if !utils.IsTimeZero(start) {
		storeTotals += ` AND g.order_created_at >= ?`
		dailyParam = append(dailyParam, start)
	}
	if !utils.IsTimeZero(end) {
		storeTotals += ` AND g.order_created_at <= ?`
		dailyParam = append(dailyParam, end)
	}
	storeTotals += ` AND g.status <> 115 GROUP BY g.jx_store_id ) AS store_counts GROUP BY jx_store_id) AS store_totals `

	lastSql := `
			SELECT 
				daily_orders.jx_store_id,
				s.name,
				daily_orders.order_date,
				daily_orders.order_count,
				store_totals.total_orders
			FROM (
`
	lastSql += dailyOrders
	lastSql += `JOIN (` + storeTotals
	lastSql += `ON daily_orders.jx_store_id = store_totals.jx_store_id
				JOIN store s ON s.id = daily_orders.jx_store_id
				ORDER BY store_totals.total_orders %s,daily_orders.jx_store_id,daily_orders.order_date`

	lastSql = fmt.Sprintf(lastSql, rank)
	offSet = jxutils.FormalizePageOffset(offSet)
	pageSize = jxutils.FormalizePageSize(pageSize)
	lastSql += " LIMIT ? OFFSET ?"
	dailyParam = append(dailyParam, pageSize, offSet)
	data := make([]*StoreOrderRank, 0, 0)

	txDB, _ := Begin(db)
	defer func() {
		if r := recover(); r != nil {
			Rollback(db, txDB)
			panic(r)
		}
	}()
	defer Commit(db, txDB)
	if err := GetRowsTx(txDB, &data, lastSql, dailyParam...); err != nil {
		Rollback(db, txDB)
		return nil, 0, err
	}
	totalCount := GetLastTotalRowCount2(db, txDB)

	return data, totalCount, nil
}

// StoreOrderRank 门店订单排名
type StoreOrderRank struct {
	JxStoreId   int    `json:"jx_store_id"`
	Name        string `json:"name"`
	OrderDate   string `json:"order_date"`
	OrderCount  int    `json:"order_count"`
	TotalOrders int    `json:"total_orders"`
}

func GetOrderStatusList(vendorOrderId string, orderType, vendorId int) (orderStatus []*model.OrderStatus, err error) {
	sql := ` SELECT * FROM order_status WHERE ref_vendor_order_id = ? AND vendor_id = ? AND order_type = ? ORDER BY status_time asc `
	param := []interface{}{vendorOrderId, vendorId, orderType}
	if err = GetRows(GetDB(), &orderStatus, sql, param...); err != nil {
		return nil, err
	}
	return orderStatus, nil
}
