Files
jx-callback/business/model/dao/store.go
2019-11-13 17:30:54 +08:00

441 lines
14 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package dao
import (
"sort"
"time"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/model"
)
// 带购物平台信息的
type StoreDetail struct {
model.Store
VendorStoreID string `orm:"column(vendor_store_id);size(48)" json:"vendorStoreID"`
VendorStatus int `json:"vendor_status"` // 取值同Store.Status
DeliveryFee int `json:"deliveryFee"`
SyncStatus int8 `orm:"default(2)" json:"syncStatus"`
PricePercentage int16 `orm:"default(100)" json:"pricePercentage"` // todo 厂商价格相对于本地价格的百分比,这个字段的修改会比较特殊,因为可能需要刷新厂商价格
PricePercentagePackStr string `orm:"size(4096)" json:"-"` //
PricePercentagePackObj model.PricePercentagePack `orm:"-" json:"-"`
FreightDeductionPackStr string `orm:"size(4096)" json:"-"` //
FreightDeductionPackObj *model.FreightDeductionPack `orm:"-" json:"-"`
AutoPickup int8 `orm:"default(1)" json:"autoPickup"` // 是否自动拣货
DeliveryType int8 `orm:"default(0)" json:"deliveryType"` // 配送类型
DeliveryCompetition int8 `orm:"default(1)" json:"deliveryCompetition"` // 是否支持配送竞争
IsSync int8 `orm:"default(1)" json:"isSync"` // 是否同步
DistrictName string `json:"districtName"`
CityName string `json:"cityName"`
IsAutoOrder int8 `json:"isAutoOrder"` // 平台是否自动接单,-10未知1
}
// 带快递门店信息的
type StoreDetail2 struct {
model.Store
VendorID int `orm:"column(vendor_id)" json:"vendorID"`
VendorStoreID string `orm:"column(vendor_store_id)" json:"vendorStoreID"` // 这个其实是京西快递门店ID的概念
CourierStatus int `json:"courierStatus"`
AuditStatus int `json:"auditStatus"`
DistrictName string `json:"districtName"`
CityName string `json:"cityName"`
}
type CityBrankBranch struct {
CityCode int
PayeeBankBranchName string `orm:"size(255)" json:"payeeBankBranchName"` // 开户支行
PayeeBankCode string `orm:"size(8)" json:"payeeBankCode"` // 开户行代码
}
func (s *StoreDetail) GetPricePerentage(price int) (pricePercentage int) {
return pricePercentage
}
func getStoreDetail(db *DaoDB, storeID, vendorID int, vendorStoreID string) (storeDetail *StoreDetail, err error) {
sql := `
SELECT t1.*,
t2.vendor_store_id, t2.status vendor_status, t2.delivery_fee, t2.sync_status,
t2.price_percentage, t2.auto_pickup, t2.delivery_type, t2.delivery_competition, t2.is_sync,
t3.value price_percentage_pack_str,
t4.value freight_deduction_pack_str,
district.name district_name,
city.name city_name
FROM store t1
LEFT JOIN store_map t2 ON t1.id = t2.store_id AND t2.vendor_id = ? AND t2.deleted_at = ?
LEFT JOIN place city ON city.code = t1.city_code
LEFT JOIN place district ON district.code = t1.district_code
LEFT JOIN new_config t3 ON t3.key = t2.price_percentage_pack AND t3.type = ? AND t3.deleted_at = ?
LEFT JOIN new_config t4 ON t4.key = t2.freight_deduction_pack AND t4.type = ? AND t4.deleted_at = ?
WHERE t1.deleted_at = ?
`
sqlParams := []interface{}{
vendorID,
utils.DefaultTimeValue,
model.ConfigTypePricePack,
utils.DefaultTimeValue,
model.ConfigTypeFreightPack,
utils.DefaultTimeValue,
utils.DefaultTimeValue,
}
if vendorID != model.VendorIDJX {
sql += " AND t2.id IS NOT NULL"
}
if storeID > 0 {
sql += " AND t1.id = ?"
sqlParams = append(sqlParams, storeID)
}
if vendorStoreID != "" {
sql += " AND t2.vendor_store_id = ?"
sqlParams = append(sqlParams, vendorStoreID)
}
if err = GetRow(db, &storeDetail, sql, sqlParams...); err == nil {
storeDetail.PricePercentagePackObj = PricePercentagePack2Obj(storeDetail.PricePercentagePackStr)
storeDetail.FreightDeductionPackObj = FreightDeductionPack2Obj(storeDetail.FreightDeductionPackStr)
if storeDetail.VendorStoreID == "" {
storeDetail.VendorStatus = storeDetail.Status
storeDetail.PricePercentage = model.DefVendorPricePercentage
storeDetail.AutoPickup = 1
storeDetail.DeliveryType = model.StoreDeliveryTypeByStore
storeDetail.DeliveryCompetition = 1
}
return storeDetail, nil
}
return nil, err
}
func GetStoreDetail(db *DaoDB, storeID, vendorID int) (storeDetail *StoreDetail, err error) {
return getStoreDetail(db, storeID, vendorID, "")
}
func GetStoreDetailByVendorStoreID(db *DaoDB, vendorStoreID string, vendorID int) (storeDetail *StoreDetail, err error) {
if vendorID != model.VendorIDJX {
return getStoreDetail(db, 0, vendorID, vendorStoreID)
}
if storeDetail, err = getStoreDetail(db, int(utils.Str2Int64WithDefault(vendorStoreID, 0)), vendorID, ""); err == nil {
storeDetail.VendorStoreID = vendorStoreID
}
return storeDetail, err
}
// 这个返回的地点信息是城市
func GetStoreDetail2(db *DaoDB, storeID int, vendorStoreID string, vendorID int) (storeDetail *StoreDetail2, err error) {
sql := `
SELECT t1.*,
city.name city_name, district.name district_name,
t3.vendor_store_id, t3.vendor_id, t3.status courier_status, t3.audit_status
FROM store t1
LEFT JOIN place city ON city.code = t1.city_code
LEFT JOIN place district ON district.code = t1.district_code
LEFT JOIN store_courier_map t3 ON t3.store_id = t1.id AND t3.vendor_id = ? AND t3.deleted_at = ?
WHERE t1.deleted_at = ?`
sqlParams := []interface{}{
vendorID,
utils.DefaultTimeValue,
utils.DefaultTimeValue,
}
if storeID != 0 {
sql += " AND t1.id = ?"
sqlParams = append(sqlParams, storeID)
}
if vendorStoreID != "" {
sql += " AND t3.vendor_store_id = ?"
sqlParams = append(sqlParams, vendorStoreID)
}
err = GetRow(db, &storeDetail, sql, sqlParams...)
return storeDetail, err
}
func GetStoreCourierList(db *DaoDB, storeIDs []int, status, auditStatus int) (courierStoreList []*model.StoreCourierMap, err error) {
sql := `
SELECT t1.*
FROM store_courier_map t1
WHERE t1.deleted_at = ?
`
sqlParams := []interface{}{
utils.DefaultTimeValue,
}
if len(storeIDs) > 0 {
sql += " AND t1.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")"
sqlParams = append(sqlParams, storeIDs)
}
if status != model.StoreStatusAll {
sql += " AND t1.status = ?"
sqlParams = append(sqlParams, status)
}
if auditStatus != model.StoreAuditStatusAll {
sql += " AND t1.audit_status = ?"
sqlParams = append(sqlParams, auditStatus)
}
if err = GetRows(db, &courierStoreList, sql, sqlParams...); err == nil {
return courierStoreList, nil
}
return nil, err
}
func GetStoresMapList(db *DaoDB, vendorIDs, storeIDs []int, status, isSync int, pricePack string) (storeMapList []*model.StoreMap, err error) {
sql := `
SELECT t1.*
FROM store_map t1
JOIN store t2 ON t2.id = t1.store_id AND t2.deleted_at = ?
WHERE t1.deleted_at = ?
`
sqlParams := []interface{}{
utils.DefaultTimeValue,
utils.DefaultTimeValue,
}
if len(vendorIDs) > 0 {
sql += " AND t1.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")"
sqlParams = append(sqlParams, vendorIDs)
}
if len(storeIDs) > 0 {
sql += " AND t1.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")"
sqlParams = append(sqlParams, storeIDs)
}
if status != model.StoreStatusAll {
sql += " AND t1.status = ?"
sqlParams = append(sqlParams, status)
}
if isSync != model.StoreIsSyncAll {
sql += " AND t1.is_sync = ?"
sqlParams = append(sqlParams, isSync)
}
if pricePack != "" {
sql += " AND t1.price_percentage_pack = ?"
sqlParams = append(sqlParams, pricePack)
}
sql += " ORDER BY t1.store_id DESC, t1.vendor_id"
if err = GetRows(db, &storeMapList, sql, sqlParams...); err == nil {
return storeMapList, nil
}
return nil, err
}
// 此函数在检测到一个门店的所有平台状态一样且不为StoreStatusOpened时
// 将平台门店状态全部改为StoreStatusOpened则把京西门店状态改为之前那个统一的平台门店状态
func FormalizeStoreStatus(db *DaoDB, storeID, storeStatus int) (err error) {
sql := `
SELECT DISTINCT t1.status
FROM store_map t1
WHERE t1.deleted_at = ? AND t1.store_id = ?
`
sqlParams := []interface{}{
utils.DefaultTimeValue,
storeID,
}
var statusList []int
if err = GetRows(db, &statusList, sql, sqlParams...); err == nil {
if len(statusList) == 1 {
if statusList[0] != model.StoreStatusOpened {
Begin(db)
defer func() {
if r := recover(); r != nil || err != nil {
Rollback(db)
if r != nil {
panic(r)
}
}
}()
if storeStatus != statusList[0] {
store := &model.Store{}
store.ID = storeID
if _, err = UpdateEntityLogically(db, store, map[string]interface{}{
model.FieldStatus: statusList[0],
}, model.AdminName, nil); err != nil {
return err
}
}
if _, err = UpdateEntityLogically(db, &model.StoreMap{}, map[string]interface{}{
model.FieldStatus: model.StoreStatusOpened,
}, model.AdminName, map[string]interface{}{
model.FieldStoreID: storeID,
model.FieldDeletedAt: utils.DefaultTimeValue,
}); err != nil {
return err
}
Commit(db)
}
}
}
return err
}
func GetVendorStoreSnapshot(db *DaoDB, snapshotAt time.Time) (snapshotList []*model.VendorStoreSnapshot, err error) {
sql := `
SELECT t1.*
FROM vendor_store_snapshot t1
LEFT JOIN store t2 ON t2.id = t1.store_id
WHERE t1.snapshot_at = ?
ORDER BY t2.city_code, t1.store_id, t1.vendor_id`
err = GetRows(db, &snapshotList, sql, snapshotAt)
return snapshotList, err
}
func DeleteVendorStoreSnapshot(db *DaoDB, minSnapshotAt time.Time) (err error) {
_, err = ExecuteSQL(db, `
DELETE t1
FROM vendor_store_snapshot t1
WHERE t1.snapshot_at < ?
`, minSnapshotAt)
return err
}
func GetRebindPrinterStoreList(db *DaoDB) (storeList []*model.Store, err error) {
err = GetRows(db, &storeList, `
SELECT *
FROM store t1
WHERE t1.deleted_at = ? AND printer_vendor_id >= ? AND printer_bind_info <> ''
`, utils.DefaultTimeValue, model.VendorIDPrinterBegin)
return storeList, err
}
// 容错用
type tPricePercentageItemFloat struct {
BeginPrice float64 `json:"beginPrice"` // 起始价格区间(包括)
PricePercentage float64 `json:"pricePercentage"` // 调价比例
PriceAdd float64 `json:"priceAdd"` // 调价额定值
}
func PricePercentagePack2Obj(packStr string) (obj model.PricePercentagePack) {
if packStr != "" {
var floatObj []*tPricePercentageItemFloat
if err := utils.UnmarshalUseNumber([]byte(packStr), &floatObj); err == nil {
if len(floatObj) > 0 {
obj = make(model.PricePercentagePack, len(floatObj))
for k, v := range floatObj {
if v.PricePercentage >= 500 || v.PricePercentage <= 80 {
return nil
}
obj[k] = &model.PricePercentageItem{
BeginPrice: int(v.BeginPrice),
PricePercentage: int(v.PricePercentage),
PriceAdd: int(v.PriceAdd),
}
}
sort.Sort(obj)
}
}
}
return obj
}
func AddStoreCategoryMap(db *DaoDB, storeID, categoryID int, vendorID int, vendorCategoryID string, status int8, userName string) (err error) {
storeCat := &model.StoreSkuCategoryMap{
StoreID: storeID,
CategoryID: categoryID,
MtwmSyncStatus: model.SyncFlagNewMask,
EbaiSyncStatus: model.SyncFlagNewMask,
}
storeCat.DeletedAt = utils.DefaultTimeValue
if err = GetEntity(db, storeCat, model.FieldStoreID, model.FieldCategoryID, model.FieldDeletedAt); err != nil && !IsNoRowsError(err) {
return err
}
if vendorID == model.VendorIDMTWM {
storeCat.MtwmID = vendorCategoryID
storeCat.MtwmSyncStatus = status
} else if vendorID == model.VendorIDEBAI {
storeCat.EbaiID = utils.Str2Int64WithDefault(vendorCategoryID, 0)
storeCat.EbaiSyncStatus = status
} else {
panic("unsupported vendor")
}
if storeCat.ID == 0 {
WrapAddIDCULDEntity(storeCat, userName)
if err = CreateEntity(db, storeCat); IsDuplicateError(err) {
err = nil
}
} else {
WrapUpdateULEntity(storeCat, userName)
_, err = UpdateEntity(db, storeCat)
}
return err
}
func GetOpenedStoreCouriersByStoreID(db *DaoDB, storeID, vendorID int) (storeMaps []*model.StoreCourierMap, err error) {
if db == nil {
db = GetDB()
}
if err = utils.CallFuncLogError(func() error {
sql := `
SELECT *
FROM store_courier_map
WHERE store_id = ? AND status = ? AND deleted_at = ?
`
sqlParams := []interface{}{
storeID,
model.StoreStatusOpened,
utils.DefaultTimeValue,
}
if vendorID != -1 {
sql += " AND vendor_id = ?"
sqlParams = append(sqlParams, vendorID)
}
return GetRows(db, &storeMaps, sql, sqlParams...)
}, "GetStoreCouriersByStoreID storeID:%d, vendorID:%d", storeID, vendorID); err != nil {
return nil, err
}
return storeMaps, nil
}
func GetStoreList(db *DaoDB, idList []int, mobileList []string, shortRoleName string) (storeList []*model.Store, err error) {
sql := `
SELECT t1.*
FROM store t1
WHERE t1.deleted_at = ?`
sqlParams := []interface{}{
utils.DefaultTimeValue,
}
if len(idList) > 0 {
sql += " AND t1.id IN (" + GenQuestionMarks(len(idList)) + ")"
sqlParams = append(sqlParams, idList)
}
if len(mobileList) > 0 {
sql += " AND (t1.tel1 IN (" + GenQuestionMarks(len(mobileList)) + ") OR t1.tel2 IN (" + GenQuestionMarks(len(mobileList)) + "))"
sqlParams = append(sqlParams, mobileList, mobileList)
}
if shortRoleName != "" {
sql += " AND (t1.market_man_role = ? OR t1.operator_role = ? OR t1.operator_role2 = ?)"
sqlParams = append(sqlParams, shortRoleName, shortRoleName, shortRoleName)
}
err = GetRows(db, &storeList, sql, sqlParams...)
return storeList, err
}
func GetCityBankBranches(db *DaoDB, cityCode int, bankCode string) (list []*CityBrankBranch, err error) {
sql := `
SELECT payee_bank_code, city_code, payee_bank_branch_name
FROM store
WHERE payee_bank_branch_name <> ''`
sqlParams := []interface{}{}
if cityCode > 0 {
sql += " AND city_code = ?"
sqlParams = append(sqlParams, cityCode)
} else {
sql += " AND city_code <> 0"
}
if bankCode != "" {
sql += " AND payee_bank_code = ?"
sqlParams = append(sqlParams, bankCode)
} else {
sql += " AND payee_bank_code <> ''"
}
sql += " GROUP BY 1,2,3;"
err = GetRows(db, &list, sql, sqlParams...)
return list, err
}
func FreightDeductionPack2Obj(packStr string) (obj *model.FreightDeductionPack) {
if packStr != "" {
if err := utils.UnmarshalUseNumber([]byte(packStr), &obj); err == nil {
sort.Sort(obj)
}
}
return obj
}