diff --git a/business/jxcallback/auth/auth.go b/business/jxcallback/auth/auth.go index bddf09156..d35d86dc6 100644 --- a/business/jxcallback/auth/auth.go +++ b/business/jxcallback/auth/auth.go @@ -7,8 +7,8 @@ import ( "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/jxcallback/auth/mobile" "git.rosy.net.cn/jx-callback/business/model" + "git.rosy.net.cn/jx-callback/business/model/dao" "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/gormdb" ) const ( @@ -86,8 +86,10 @@ func BindMobile(token, mobileNum, code string) (err error) { loginInfo := new(LoginInfo) if err = globals.Cacher.GetAs(token, loginInfo); err == nil { if mobile.VerifyCode(mobileNum, code) { - db := gormdb.GetDB() - return db.Model(model.WeiXins{}).Where("openid = ?", loginInfo.ID).Update("tel", mobileNum).Error + user := &model.WeiXins{ + OpenID: loginInfo.ID, + } + err = dao.UpdateEntityByKV(nil, user, utils.Params2Map("Tel", mobileNum), utils.Params2Map("OpenID", loginInfo.ID)) } err = errors.New("验证码错") } diff --git a/business/jxcallback/auth/localpass/localpass.go b/business/jxcallback/auth/localpass/localpass.go index 3b889d687..25dbe8343 100644 --- a/business/jxcallback/auth/localpass/localpass.go +++ b/business/jxcallback/auth/localpass/localpass.go @@ -6,7 +6,7 @@ import ( "git.rosy.net.cn/jx-callback/business/jxcallback/auth" "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/globals/gormdb" + "git.rosy.net.cn/jx-callback/business/model/dao" ) const ( @@ -21,9 +21,10 @@ func init() { } func (a *Auther) Login(uname, password string) (err error) { - user := &model.JxBackendUser{} - db := gormdb.GetDB() - if err = db.Where("uname = ?", uname).First(user).Error; err == nil { + user := &model.JxBackendUser{ + UName: uname, + } + if err = dao.GetEntity(nil, user, "UName"); err == nil { if fmt.Sprintf("%x", md5.Sum([]byte(password))) == user.UPass { return nil } diff --git a/business/jxcallback/auth/weixin/weixin.go b/business/jxcallback/auth/weixin/weixin.go index 74c56d7ab..e7b1bf625 100644 --- a/business/jxcallback/auth/weixin/weixin.go +++ b/business/jxcallback/auth/weixin/weixin.go @@ -9,9 +9,9 @@ import ( "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/jxcallback/auth" "git.rosy.net.cn/jx-callback/business/model" + "git.rosy.net.cn/jx-callback/business/model/dao" "git.rosy.net.cn/jx-callback/globals" "git.rosy.net.cn/jx-callback/globals/api" - "git.rosy.net.cn/jx-callback/globals/gormdb" ) const ( @@ -60,9 +60,10 @@ func GetUserInfo(code string, state string) (token *UserInfoExt, err error) { func (a *Auther) Login(openid, password string) (err error) { if value := globals.Cacher.Get(openid); value != nil { if password == value.(string) { - wxUser := &model.WeiXins{} - db := gormdb.GetDB() - if err = db.Where("openid = ?", openid).First(wxUser).Error; err == nil { + wxUser := &model.WeiXins{ + OpenID: openid, + } + if err = dao.GetEntity(nil, wxUser, "OpenID"); err == nil { globals.Cacher.Del(openid) return nil } diff --git a/business/jxstore/cms/sku.go b/business/jxstore/cms/sku.go index bbea7da17..8a599b1ea 100644 --- a/business/jxstore/cms/sku.go +++ b/business/jxstore/cms/sku.go @@ -2,13 +2,12 @@ package cms import ( "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/globals/gormdb" + "git.rosy.net.cn/jx-callback/business/model/dao" ) func GetVendorCategories(vendorID int) ([]*model.SkuVendorCategory, error) { - db := gormdb.GetDB() cats := []*model.SkuVendorCategory{} - return cats, db.Where("vendor_id = ?", vendorID).Find(&cats).Error + return cats, dao.GetRows(nil, &cats, "SELECT * FROM sku_vendor_category WHERE vendor_id = ?", vendorID) } func GetSkuMetaInfo() (*model.SkuMetaInfo, error) { diff --git a/business/jxstore/cms/store.go b/business/jxstore/cms/store.go index cedfae093..cd26f1c23 100644 --- a/business/jxstore/cms/store.go +++ b/business/jxstore/cms/store.go @@ -10,11 +10,11 @@ import ( "git.rosy.net.cn/jx-callback/business/jxutils" "git.rosy.net.cn/jx-callback/business/model" "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/globals/gormdb" + "git.rosy.net.cn/jx-callback/globals" ) type StoreExt struct { - *model.Store + model.Store CityName string `json:"cityName"` DistrictName string `json:"districtName"` } @@ -30,36 +30,37 @@ var ( ) func GetPlaces(parentCode int, vendorID int, includeDisabled bool) ([]*model.Place, error) { - db := gormdb.GetDB() + db := dao.GetDB() places := []*model.Place{} - sql := "enabled = 1 " + sql := "SELECT * FROM place WHERE enabled = 1 " if includeDisabled { sql = "1 = 1 " } if vendorID >= 0 { if vendorID == model.VendorIDJD { - return places, db.Where(sql + "AND jd_code <> 0 AND level >= 2").Find(&places).Error + return places, dao.GetRows(db, &places, sql+"AND jd_code <> 0 AND level >= 2") } return nil, ErrHaveNotImplementedYet } - return places, db.Where(sql+"AND parent_code = ?", parentCode).Find(&places).Error + return places, dao.GetRows(db, &places, sql+"AND parent_code = ?", parentCode) } -func UpdatePlaces(places []*model.Place, userName string) (err error) { +func UpdatePlaces(places []map[string]interface{}, userName string) (err error) { if len(places) == 0 { return ErrMissingInput } - db := gormdb.GetDB() for _, place := range places { - params := map[string]interface{}{"enabled": place.Enabled, "updated_at": time.Now()} - if place.JdCode != 0 { - params["jd_code"] = place.JdCode + if place["code"] == nil { + return ErrMissingInput } - if place.MtpsPrice != 0 { - params["mtps_price"] = place.MtpsPrice - } - if err = db.Table("place").Where("code = ?", place.Code).Updates(params).Error; err != nil { - break + placeid := &model.Place{} + globals.SugarLogger.Debug(utils.Format4Output(place, false)) + valid, _ := jxutils.FilterMapByFieldList(place, []string{"jdCode", "enabled", "mtpsPrice"}) + valid["updatedAt"] = time.Now() + valid["lastOperator"] = userName + globals.SugarLogger.Debug(valid) + if err = dao.UpdateEntityByKV(nil, placeid, valid, utils.Params2Map("Code", place["code"])); err != nil { + return err } } return err @@ -130,7 +131,8 @@ func GetStores(keyword string, params map[string]interface{}, offset, pageSize i Ct int } countInfo := []tcount{} - if err = dao.GetRows(nil, &countInfo, sqlCount, params2...); err == nil { + db := dao.GetDB() + if err = dao.GetRows(db, &countInfo, sqlCount, params2...); err == nil { sqlData := "SELECT t1.*, city.name city_name, district.name district_name\n" + sql + ` ORDER BY id LIMIT ? OFFSET ?` @@ -144,7 +146,7 @@ func GetStores(keyword string, params map[string]interface{}, offset, pageSize i retVal := &StoresInfo{ TotalCount: countInfo[0].Ct, } - err = dao.GetRows(nil, &retVal.Stores, sqlData, params2...) + err = dao.GetRows(db, &retVal.Stores, sqlData, params2...) return retVal, err } return nil, err @@ -156,9 +158,9 @@ func GetVendorStore(vendorStoreID string, vendorID int) (retVal *StoreExt, err e result, err2 := handler.ReadStore(vendorStoreID) if err = err2; err == nil { retVal = &StoreExt{ - Store: result, + Store: *result, } - db := gormdb.GetDB() + db := dao.GetDB() if city, err2 := dao.GetPlaceByCode(db, result.CityCode); err2 == nil { retVal.CityName = city.Name } @@ -181,8 +183,8 @@ func UpdateStore(params map[string]interface{}, userName string) (err error) { params["updatedAt"] = time.Now() store.ID = int(utils.MustInterface2Int64(params["id"])) - valid, _ := jxutils.FilterMapByStructObject(params, &model.Store{}) - err = dao.UpdateEntity(nil, store, valid) + valid, _ := jxutils.NormalFilterMapByStructObject(params, &model.Store{}) + err = dao.UpdateEntityByKV(nil, store, valid, nil) return err } diff --git a/business/jxstore/qorcms/qorcms.go b/business/jxstore/qorcms/qorcms.go deleted file mode 100644 index c09fb117b..000000000 --- a/business/jxstore/qorcms/qorcms.go +++ /dev/null @@ -1,72 +0,0 @@ -package qorcms - -import ( - "reflect" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/gormdb" - "github.com/qor/admin" - "github.com/qor/qor" - "github.com/qor/qor/resource" -) - -var ( - curAdmin *admin.Admin -) - -func Init() { - gormdb.Init() - curAdmin = admin.New(&admin.AdminConfig{ - DB: gormdb.GetDB(), - SiteName: "京西管理系统v0.0.1", - }) - storeRes := curAdmin.AddResource(&model.Store{}) - lngMeta := storeRes.GetMeta("Lng") - lngMeta.Type = "float" - lngMeta.SetSetter(func(record interface{}, metaValue *resource.MetaValue, context *qor.Context) { - store := record.(*model.Store) - store.Lng = int(utils.Str2Float64((metaValue.Value.([]string))[0]) * 1000000) - globals.SugarLogger.Debugf("metaValue:%v", reflect.TypeOf(metaValue.Value)) - }) - lngMeta.SetValuer(func(record interface{}, context *qor.Context) (result interface{}) { - store := record.(*model.Store) - result = float64(store.Lng) / 1000000 - return result - }) - curAdmin.AddResource(&model.StoreSub{}) - - curAdmin.AddResource(&model.Sku{}) - curAdmin.AddResource(&model.SkuName{}) -} - -func GetAdmin() *admin.Admin { - return curAdmin -} - -// func SaveMapSlice2DB(db *gorm.DB, data []map[string]interface{}, tableName string, keyMaps map[string]string) { -// if len(data) == 0 { -// return -// } - -// sql := "INSERT INTO " + tableName + "(" -// for k := range data[0] { -// realK, ok := keyMaps[k] -// if !ok { -// realK = k -// } -// sql += realK + "," -// } -// sql = sql[:len(sql)-1] + ") " - -// for _, dataRow := range data { -// for k, v := range dataRow { -// realK, ok := keyMaps[k] -// if !ok { -// realK = k -// } -// sql += "(" -// } -// } -// } diff --git a/business/jxutils/dtask/dtask.go b/business/jxutils/dtask/dtask.go new file mode 100644 index 000000000..65ff6ef5f --- /dev/null +++ b/business/jxutils/dtask/dtask.go @@ -0,0 +1,168 @@ +package dtask + +import ( + "bytes" + "encoding/base64" + "encoding/gob" + "errors" + "reflect" + "time" + + "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/business/jxcallback/scheduler/basesch" + "git.rosy.net.cn/jx-callback/business/model" + "git.rosy.net.cn/jx-callback/business/model/dao" +) + +var ( + CurMan *DurableTaskMan +) + +type DurableTaskMan struct { + objCreator func(objHint string) interface{} + tasks map[string]*DurableTask +} + +type DurableTask struct { + cmdChan chan string + data *model.DurableTask + itemCount int + items []*model.DurableTaskItem +} + +func Init(objCreator func(objHint string) interface{}, interfaceTypes ...interface{}) { + if CurMan == nil { + if objCreator == nil { + objCreator = defObjCreator + } + CurMan = &DurableTaskMan{ + tasks: make(map[string]*DurableTask), + objCreator: objCreator, + } + for _, v := range interfaceTypes { + gob.Register(v) + } + } +} + +func (m *DurableTaskMan) LoadPendingTask() (err error) { + db := dao.GetDB() + tasks := make([]*model.DurableTask, 0) + if err = dao.GetRows(db, &tasks, "SELECT * FROM durable_task WHERE status = 0"); err == nil { + for _, task := range tasks { + dTask := &DurableTask{ + data: task, + } + m.tasks[task.TaskID] = dTask + return dao.GetRows(db, &dTask.items, "SELECT * FROM durable_task_item WHERE status = 0") + } + } + return err +} + +func (m *DurableTaskMan) Start() error { + for _, task := range m.tasks { + m.StartTask(task.data.TaskID) + } + return nil +} + +func (m *DurableTaskMan) AddTask(desc, createdBy string) (taskID string, err error) { + task := &DurableTask{} + task.data = &model.DurableTask{ + TaskID: utils.GetUUID(), + Description: desc, + CreatedBy: createdBy, + Status: 0, + FinishedAt: utils.DefaultTimeValue, + } + if err = dao.CreateEntity(nil, task.data); err == nil { + m.tasks[task.data.TaskID] = task + return task.data.TaskID, nil + } + return "", err +} + +func (m *DurableTaskMan) AddItem(taskID, objHint string, funcName string, params ...interface{}) (err error) { + d := m.tasks[taskID] + d.data.TotalItem++ + item := &model.DurableTaskItem{ + ObjHint: objHint, + FuncName: funcName, + TaskID: d.data.TaskID, + TaskIndex: d.data.TotalItem, + FinishedAt: utils.DefaultTimeValue, + } + if item.Params, err = SerializeData(params); err == nil { + db := dao.GetDB() + if err = dao.CreateEntity(db, item); err == nil { + err = dao.UpdateEntity(db, d.data, "TotalItem") + d.items = append(d.items, item) + } + } + d.data.TotalItem-- + return err +} + +func (m *DurableTaskMan) StartTask(taskID string) error { + d := m.tasks[taskID] + if d.cmdChan == nil { + d.cmdChan = make(chan string) + go func() { + failedItemCount := 0 + for _, taskItem := range d.items { + if taskItem.Status == 0 { + obj := m.objCreator(taskItem.ObjHint) + objValue := reflect.ValueOf(obj) + func2Call := objValue.MethodByName(taskItem.FuncName) + params := []interface{}{} + DeSerializeData(taskItem.Params, ¶ms) + valueParams := make([]reflect.Value, len(params)) + + for k, v := range params { + valueParams[k] = reflect.ValueOf(v) + } + if func2Call.Call(valueParams)[0].IsNil() { + taskItem.Status = 1 + taskItem.FinishedAt = time.Now() + taskItem.UpdatedAt = taskItem.FinishedAt + dao.UpdateEntity(nil, taskItem, "Status", "FinishedAt", "UpdatedAt") + } else { + failedItemCount++ + } + } + } + if failedItemCount == 0 { + d.data.Status = 1 + d.data.FinishedAt = time.Now() + d.data.UpdatedAt = d.data.FinishedAt + dao.UpdateEntity(nil, d.data, "Status", "FinishedAt", "UpdatedAt") + } + }() + return nil + } + return errors.New("任务已经启动") +} + +func defObjCreator(objHint string) interface{} { + return basesch.FixedBaseScheduler.GetPurchasePlatformFromVendorID(0) +} + +func SerializeData(data interface{}) (strValue string, err error) { + var buf bytes.Buffer + enc := gob.NewEncoder(&buf) + if err = enc.Encode(data); err == nil { + strValue = base64.StdEncoding.EncodeToString(buf.Bytes()) + return strValue, nil + } + return "", err +} + +func DeSerializeData(strValue string, dataPtr interface{}) (err error) { + byteData, err := base64.StdEncoding.DecodeString(strValue) + if err == nil { + dec := gob.NewDecoder(bytes.NewReader(byteData)) + return dec.Decode(dataPtr) + } + return err +} diff --git a/business/jxutils/dtask/dtask_test.go b/business/jxutils/dtask/dtask_test.go new file mode 100644 index 000000000..7461b28f4 --- /dev/null +++ b/business/jxutils/dtask/dtask_test.go @@ -0,0 +1,100 @@ +package dtask + +import ( + "bytes" + "encoding/gob" + "testing" + "time" + + "git.rosy.net.cn/baseapi/utils" + _ "git.rosy.net.cn/jx-callback/business/jxcallback/scheduler/defsch" + "git.rosy.net.cn/jx-callback/business/model" + _ "git.rosy.net.cn/jx-callback/business/partner/purchase/jd" + "git.rosy.net.cn/jx-callback/globals" + "git.rosy.net.cn/jx-callback/globals/api" + "git.rosy.net.cn/jx-callback/globals/beegodb" + "github.com/astaxie/beego" +) + +func init() { + beego.InitBeegoBeforeTest("/Users/xujianhua/go/src/git.rosy.net.cn/jx-callback/conf/app.conf") + // beego.BConfig.RunMode = "dev" // InitBeegoBeforeTest会将runmode设置为test + + globals.Init() + beegodb.Init() + api.Init() +} + +func TestScope(t *testing.T) { +} + +func TestIt(t *testing.T) { + Init(myObjCreator, []*model.Store{}) + var err error + // taskID, err := CurMan.AddTask("testtask", "xjh") + // if err != nil { + // t.Fatal(err) + // } + // tt := []*model.Store{ + // &model.Store{ + // Name: "storename", + // }, + // } + // pp := "asdfsafs" + // err = CurMan.AddItem(taskID, "0", "DurableTaskTestFunc", 1, "str", map[string]interface{}{ + // "key1": "value1", + // "key2": 100, + // "key3": &pp, + // }, []interface{}{1, "hello"}, tt) + // err = CurMan.AddItem(taskID, "0", "DurableTaskTestFunc", 1, "str", map[string]interface{}{ + // "key1": "value1", + // "key2": 100, + // "key3": &pp, + // }, []interface{}{1, "hello"}, tt) + + // if err != nil { + // t.Fatal(err) + // } + // err = CurMan.StartTask(taskID) + err = CurMan.LoadPendingTask() + if err != nil { + t.Fatal(err) + } + err = CurMan.Start() + if err != nil { + t.Fatal(err) + } + // CurMan.LoadPendingTask() + // CurMan.Start() + time.Sleep(3 * time.Second) +} + +func TestEncode(t *testing.T) { + data := []interface{}{ + 3, + "abc", + float32(3.4), + } + var buf bytes.Buffer + enc := gob.NewEncoder(&buf) + dec := gob.NewDecoder(&buf) + enc.Encode(data) + // t.Log(string(buf.Bytes())) + var kk []interface{} + dec.Decode(&kk) + t.Log(kk) +} + +type tTest struct { +} + +func (p *tTest) DurableTaskTestFunc(intParam int, strParam string, mapParam map[string]interface{}, sliceParam []interface{}, tt []*model.Store) error { + globals.SugarLogger.Debug(intParam, strParam, mapParam, sliceParam) + globals.SugarLogger.Debug(utils.Format4Output(tt, false)) + time.Sleep(1 * time.Second) + return nil // errors.New("hello") +} + +func myObjCreator(objHint string) interface{} { + return new(tTest) +} diff --git a/business/jxutils/jxutils.go b/business/jxutils/jxutils.go index b3302841c..5cdab3fb8 100644 --- a/business/jxutils/jxutils.go +++ b/business/jxutils/jxutils.go @@ -4,6 +4,7 @@ import ( "fmt" "math" "math/rand" + "reflect" "regexp" "strings" "sync" @@ -271,12 +272,41 @@ func SplitSkuName(skuName string) (prefix, name, comment, specUnit, unit string, return prefix, name, comment, specUnit, unit, specQuality } -func FilterMapByStructObject(mapData map[string]interface{}, obj interface{}) (valid map[string]interface{}, invalid map[string]interface{}) { +func FlatMap(in map[string]interface{}) map[string]interface{} { + keys := []string{} + maps := []map[string]interface{}{} + for k, v := range in { + if vMap, ok := v.(map[string]interface{}); ok { + maps = append(maps, vMap) + keys = append(keys, k) + } + } + if len(maps) > 0 { + retVal := utils.MergeMaps(in, maps...) + for _, v := range keys { + delete(retVal, v) + } + return retVal + } + return in +} + +func Struct2FlatMap(obj interface{}) map[string]interface{} { m := structs.Map(obj) + return FlatMap(m) +} + +func FilterMapByStructObject(mapData map[string]interface{}, obj interface{}, excludedFields []string) (valid map[string]interface{}, invalid map[string]interface{}) { + excludedMap := make(map[string]int) + for _, v := range excludedFields { + excludedMap[v] = 1 + } + + m := Struct2FlatMap(obj) valid = make(map[string]interface{}) invalid = make(map[string]interface{}) for k, v := range mapData { - if m[k] != nil { + if m[k] != nil && excludedMap[k] == 0 { valid[k] = v } else { invalid[k] = v @@ -284,3 +314,24 @@ func FilterMapByStructObject(mapData map[string]interface{}, obj interface{}) (v } return valid, invalid } + +func NormalFilterMapByStructObject(mapData map[string]interface{}, obj interface{}) (valid map[string]interface{}, invalid map[string]interface{}) { + return FilterMapByStructObject(mapData, obj, []string{"id", "createdAt"}) +} + +func FilterMapByFieldList(mapData map[string]interface{}, fields []string) (valid map[string]interface{}, invalid map[string]interface{}) { + valid = make(map[string]interface{}) + invalid = make(map[string]interface{}) + for _, field := range fields { + if mapData[field] != nil { + valid[field] = mapData[field] + } else { + invalid[field] = mapData[field] + } + } + return valid, invalid +} + +func GetObjFieldByName(obj interface{}, fieldName string) interface{} { + return reflect.Indirect(reflect.ValueOf(obj)).FieldByName(fieldName).Interface() +} diff --git a/business/model/dao/dao.go b/business/model/dao/dao.go index 61e010f11..03afb23c6 100644 --- a/business/model/dao/dao.go +++ b/business/model/dao/dao.go @@ -4,117 +4,116 @@ import ( "reflect" "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/globals/gormdb" - "github.com/jinzhu/gorm" + "git.rosy.net.cn/jx-callback/business/jxutils" + "github.com/astaxie/beego/orm" ) -func GetRows(db *gorm.DB, inPtr interface{}, sql string, values ...interface{}) (err error) { - if db == nil { - db = gormdb.GetDB() - } - topTypeInfo := reflect.TypeOf(inPtr) - if topTypeInfo.Kind() != reflect.Ptr { - panic("SelectEntities inPtr should be slice ptr (*[]Type)") - } - typeInfo := topTypeInfo.Elem() - if typeInfo.Kind() != reflect.Slice { - panic("SelectEntities inPtr should be slice ptr (*[]Type)") - } - elmType := typeInfo.Elem() +type DaoDB struct { + db orm.Ormer +} - valueInfo := reflect.ValueOf(inPtr) - rows, err := db.Raw(sql, values...).Rows() - if err == nil { - defer rows.Close() - for rows.Next() { - var value reflect.Value - if elmType.Kind() == reflect.Ptr { - value = reflect.New(elmType.Elem()) - } else { - value = reflect.New(elmType) +// func GetRows(db *gorm.DB, inPtr interface{}, sql string, values ...interface{}) (err error) { +// if db == nil { +// db = gormdb.GetDB() +// } +// topTypeInfo := reflect.TypeOf(inPtr) +// if topTypeInfo.Kind() != reflect.Ptr { +// panic("SelectEntities inPtr should be slice ptr (*[]Type)") +// } +// typeInfo := topTypeInfo.Elem() +// if typeInfo.Kind() != reflect.Slice { +// panic("SelectEntities inPtr should be slice ptr (*[]Type)") +// } +// elmType := typeInfo.Elem() + +// valueInfo := reflect.ValueOf(inPtr) +// rows, err := db.Raw(sql, values...).Rows() +// if err == nil { +// defer rows.Close() +// for rows.Next() { +// var value reflect.Value +// if elmType.Kind() == reflect.Ptr { +// value = reflect.New(elmType.Elem()) +// } else { +// value = reflect.New(elmType) +// } +// db.ScanRows(rows, value.Interface()) +// if elmType.Kind() != reflect.Ptr { +// value = value.Elem() +// } +// valueInfo.Elem().Set(reflect.Append(valueInfo.Elem(), value)) +// } +// return nil +// } +// return err +// } + +func GetDB() *DaoDB { + return &DaoDB{db: orm.NewOrm()} +} + +func GetRow(db *DaoDB, inPtr interface{}, sql string, values ...interface{}) (err error) { + if db == nil { + db = GetDB() + } + return db.db.Raw(sql, values).QueryRow(inPtr) +} + +func GetRows(db *DaoDB, inPtr interface{}, sql string, values ...interface{}) (err error) { + if db == nil { + db = GetDB() + } + _, err = db.db.Raw(sql, values).QueryRows(inPtr) + return err +} + +func GetEntity(db *DaoDB, item interface{}, cols ...string) error { + if db == nil { + db = GetDB() + } + err := utils.CallFuncLogError(func() error { + return db.db.Read(item, cols...) + }, reflect.TypeOf(item).Name()) + return err +} + +func UpdateEntity(db *DaoDB, item interface{}, cols ...string) error { + if db == nil { + db = GetDB() + } + err := utils.CallFuncLogError(func() error { + _, err2 := db.db.Update(item, cols...) + return err2 + }, reflect.TypeOf(item).Name()) + return err +} + +func UpdateEntityByKV(db *DaoDB, item interface{}, kvs map[string]interface{}, conditions map[string]interface{}) error { + if db == nil { + db = GetDB() + } + err := utils.CallFuncLogError(func() error { + qs := db.db.QueryTable(item) + if conditions == nil { + qs = qs.Filter("id", jxutils.GetObjFieldByName(item, "ID")) + } else { + for k, v := range conditions { + qs = qs.Filter(k, v) } - db.ScanRows(rows, value.Interface()) - if elmType.Kind() != reflect.Ptr { - value = value.Elem() - } - valueInfo.Elem().Set(reflect.Append(valueInfo.Elem(), value)) } - return nil - } - return err -} - -func GetEntity(db *gorm.DB, item interface{}) error { - if db == nil { - db = gormdb.GetDB() - } - err := utils.CallFuncLogError(func() error { - return db.First(item).Error + _, err2 := qs.Update(kvs) + return err2 }, reflect.TypeOf(item).Name()) return err } -func UpdateEntity(db *gorm.DB, item interface{}, values map[string]interface{}) error { +func CreateEntity(db *DaoDB, item interface{}) error { if db == nil { - db = gormdb.GetDB() + db = GetDB() } err := utils.CallFuncLogError(func() error { - return db.Model(item).Updates(values).Error + _, err2 := db.db.Insert(item) // todo 这里需要将ID赋值么? + return err2 }, reflect.TypeOf(item).Name()) return err } - -func CreateEntity(db *gorm.DB, item interface{}) error { - if db == nil { - db = gormdb.GetDB() - } - err := utils.CallFuncLogError(func() error { - return db.Create(item).Error - }, reflect.TypeOf(item).Name()) - return err -} - -func GetSellCities(skuNameID int, vendorID int, db *gorm.DB) (cities []*model.Place, err error) { - cities = []*model.Place{} - sql := ` - SELECT DISTINCT t3.* - FROM sku_name_place_bind t1 - JOIN place t2 ON t1.place_code = t2.code - JOIN place t3 ON (t2.level = 2 AND t2.code = t3.code) OR (t2.level = 1 AND t2.code = t3.parent_code) - WHERE t1.sku_name_id = ? - ` - if vendorID == model.VendorIDJD { - sql += "AND t3.jd_code <> 0\n" - } - return cities, GetRows(nil, &cities, sql, skuNameID) -} - -func GetPlaceByCode(db *gorm.DB, code int) (place *model.Place, err error) { - if db == nil { - db = gormdb.GetDB() - } - place = new(model.Place) - err = db.Where("code = ?", code).First(place).Error - return place, err -} - -func GetPlaceByName(db *gorm.DB, name string, level int, parentCode int) (place *model.Place, err error) { - if db == nil { - db = gormdb.GetDB() - } - place = new(model.Place) - if err = db.Where("parent_code = ? AND level = ? AND name = ?", parentCode, level, name).First(place).Error; err == gorm.ErrRecordNotFound { - err = db.Where("parent_code = ? AND level = ? AND name LIKE ?", parentCode, level, "%"+name+"%").First(place).Error - } - return place, err -} - -func GetPlaceByJdCode(db *gorm.DB, jdCode int) (place *model.Place, err error) { - if db == nil { - db = gormdb.GetDB() - } - place = new(model.Place) - err = db.Where("jd_code = ?", jdCode).First(place).Error - return place, err -} diff --git a/business/model/dao/dao_test.go b/business/model/dao/dao_test.go index 79f2067f7..ada61ba5b 100644 --- a/business/model/dao/dao_test.go +++ b/business/model/dao/dao_test.go @@ -8,7 +8,6 @@ import ( "git.rosy.net.cn/jx-callback/globals" "git.rosy.net.cn/jx-callback/globals/api" "git.rosy.net.cn/jx-callback/globals/beegodb" - "git.rosy.net.cn/jx-callback/globals/gormdb" "github.com/astaxie/beego" ) @@ -18,7 +17,6 @@ func init() { globals.Init() beegodb.Init() - gormdb.Init() api.Init() } diff --git a/business/model/dao/place.go b/business/model/dao/place.go new file mode 100644 index 000000000..5ab380494 --- /dev/null +++ b/business/model/dao/place.go @@ -0,0 +1,43 @@ +package dao + +import ( + "git.rosy.net.cn/jx-callback/business/model" + "github.com/astaxie/beego/orm" +) + +func GetPlaceByCode(db *DaoDB, code int) (place *model.Place, err error) { + if db == nil { + db = GetDB() + } + place = &model.Place{ + Code: code, + } + err = db.db.Read(place, "Code") + return place, err +} + +func GetPlaceByName(db *DaoDB, name string, level int, parentCode int) (place *model.Place, err error) { + if db == nil { + db = GetDB() + } + place = &model.Place{ + Name: name, + Level: int8(level), + ParentCode: parentCode, + } + if err = db.db.Read(place, "Name", "Level", "ParentCode"); err == orm.ErrNoRows { + err = db.db.Raw("SELECT * FROM place WHERE parent_code = ? AND level = ? AND name LIKE ?", parentCode, level, "%"+name+"%").QueryRow(place) + } + return place, err +} + +func GetPlaceByJdCode(db *DaoDB, jdCode int) (place *model.Place, err error) { + if db == nil { + db = GetDB() + } + place = &model.Place{ + JdCode: jdCode, + } + err = db.db.Read(place, "JdCode") + return place, err +} diff --git a/business/model/dao/sku.go b/business/model/dao/sku.go new file mode 100644 index 000000000..47514a205 --- /dev/null +++ b/business/model/dao/sku.go @@ -0,0 +1,20 @@ +package dao + +import ( + "git.rosy.net.cn/jx-callback/business/model" +) + +func GetSellCities(db *DaoDB, skuNameID int, vendorID int) (cities []*model.Place, err error) { + cities = []*model.Place{} + sql := ` + SELECT DISTINCT t3.* + FROM sku_name_place_bind t1 + JOIN place t2 ON t1.place_code = t2.code + JOIN place t3 ON (t2.level = 2 AND t2.code = t3.code) OR (t2.level = 1 AND t2.code = t3.parent_code) + WHERE t1.sku_name_id = ? + ` + if vendorID == model.VendorIDJD { + sql += "AND t3.jd_code <> 0\n" + } + return cities, GetRows(db, &cities, sql, skuNameID) +} diff --git a/business/model/dtask.go b/business/model/dtask.go new file mode 100644 index 000000000..732cc88c6 --- /dev/null +++ b/business/model/dtask.go @@ -0,0 +1,34 @@ +package model + +import ( + "time" +) + +type DurableTask struct { + ID int `orm:"column(id)" json:"id"` + CreatedAt time.Time `orm:"auto_now_add;type(datetime)" json:"createdAt"` + UpdatedAt time.Time `orm:"auto_now;type(datetime)" json:"updatedAt"` + + TaskID string `orm:"size(48)"` // 用于标识任务 + Description string `orm:"size(255)"` + CreatedBy string `orm:"size(48)"` + FinishedAt time.Time + Status int + + TotalItem int + FinishedItem int +} + +type DurableTaskItem struct { + ID int `orm:"column(id)" json:"id"` + CreatedAt time.Time `orm:"auto_now_add;type(datetime)" json:"createdAt"` + UpdatedAt time.Time `orm:"auto_now;type(datetime)" json:"updatedAt"` + + TaskID string `orm:"size(48)"` // 用于标识任务 + TaskIndex int + ObjHint string `orm:"size(48)"` + FuncName string `orm:"size(48)"` + Params string `orm:"size(2000)"` // 序列化后的参数 + FinishedAt time.Time + Status int +} diff --git a/business/model/legacy.go b/business/model/legacy.go index fa4d2dc29..3669a57e6 100644 --- a/business/model/legacy.go +++ b/business/model/legacy.go @@ -1,33 +1,33 @@ package model type WeiXins struct { - ID int - JxStoreID int `gorm:"column:jxstoreid"` - OpenID string `gorm:"column:openid;type:varchar(70);index"` - Tel string `gorm:"type:varchar(15);index"` - ParentID int `gorm:"column:parentid"` - NickName string `gorm:"column:nickname;type:varchar(30)"` + ID int `orm:"column(id)"` + JxStoreID int `orm:"column(jxstoreid)"` + OpenID string `orm:"column(openid);size(70);index"` + Tel string `orm:"size(15);index"` + ParentID int `orm:"column(parentid)"` + NickName string `orm:"column(nickname);size(30)"` } -func (WeiXins) TableName() string { +func (*WeiXins) TableName() string { return "weixins" } type JxBackendUser struct { - UID int `gorm:"PRIMARY_KEY"` - UName string `gorm:"column:uname;type:varchar(64);unique_index"` - UPass string `gorm:"column:upass;type:varchar(64)"` - Tel string `gorm:"type:varchar(32);index"` - Position string `gorm:"type:varchar(255)"` - Enabled int8 `gorm:"default:1"` - SkuWidget int `gorm:"default:0"` - StoreWidget int `gorm:"default:0"` - UserWidget int `gorm:"default:0"` - BillinfoWidget int `gorm:"default:0"` - GroupWidget int `gorm:"default:0"` - CategoryWidget int `gorm:"default:0"` + UID int `orm:"pk;column(uid)"` + UName string `orm:"column(uname);size(64);index"` + UPass string `orm:"column(upass);size(64)"` + Tel string `orm:"size(32);index"` + Position string `orm:"size(255)"` + Enabled int8 `orm:"default(1)"` + SkuWidget int `orm:"default(0)"` + StoreWidget int `orm:"default(0)"` + UserWidget int `orm:"default(0)"` + BillinfoWidget int `orm:"default(0)"` + GroupWidget int `orm:"default(0)"` + CategoryWidget int `orm:"default(0)"` } -func (JxBackendUser) TableName() string { +func (*JxBackendUser) TableName() string { return "jxbackenduser" } diff --git a/business/model/model.go b/business/model/model.go index d488b44cd..864837ab7 100644 --- a/business/model/model.go +++ b/business/model/model.go @@ -1,24 +1,12 @@ package model -import "time" +import ( + "time" +) -type ModelO struct { - ID int `gorm:"primary_key" json:"id"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` - DeletedAt *time.Time `sql:"index"` - LastOperator string `gorm:"type:varchar(32)" json:"lastOperator"` // 最后操作员 -} - -type ModelIDCU struct { - ID int `gorm:"primary_key" json:"id"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` -} - -type ModelIDCUO struct { - ID int `gorm:"primary_key" json:"id"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` - LastOperator string `gorm:"type:varchar(32)" json:"lastOperator"` // 最后操作员 +type ModelIDCUL struct { + ID int `orm:"column(id)" json:"id"` + CreatedAt time.Time `orm:"auto_now_add;type(datetime)" json:"createdAt"` + UpdatedAt time.Time `orm:"auto_now;type(datetime)" json:"updatedAt"` + LastOperator string `orm:"size(32)" json:"lastOperator"` // 最后操作员 } diff --git a/business/model/place.go b/business/model/place.go index 40fc878bb..fe1b9ab5f 100644 --- a/business/model/place.go +++ b/business/model/place.go @@ -1,7 +1,5 @@ package model -import "time" - // https://github.com/videni/pcr const ( CityLevelProvince = 1 @@ -10,15 +8,15 @@ const ( ) type Place struct { - ID int `json:"-"` - Code int `gorm:"unique_index" json:"code"` // 国家标准代码 - Name string `gorm:"type:varchar(16);index" json:"name"` // 如果是直辖市,省的概念不加“市”来区别 - ParentCode int `json:"parentCode"` // 上级代码 - PostCode string `gorm:"type:varchar(8);index" json:"postCode"` - Level int8 `json:"level"` // 城市级别,参见相关常量定义 - TelCode string `gorm:"type:varchar(8);index" json:"telCode"` - JdCode int `gorm:"index" json:"jdCode"` // 对应的京东代码 - Enabled int8 `json:"enabled"` // 是否启用 - MtpsPrice int `json:"mtpsPrice"` // 分为单位 - UpdatedAt time.Time `json:"updatedAt"` + ModelIDCUL + + Code int `orm:"unique" json:"code"` // 国家标准代码 + Name string `orm:"size(16);index" json:"name"` // 如果是直辖市,省的概念不加“市”来区别 + ParentCode int `json:"parentCode"` // 上级代码 + PostCode string `orm:"size(8);index" json:"postCode"` + Level int8 `json:"level"` // 城市级别,参见相关常量定义 + TelCode string `orm:"size(8);index" json:"telCode"` + JdCode int `orm:"index" json:"jdCode"` // 对应的京东代码 + Enabled int8 `json:"enabled"` // 是否启用 + MtpsPrice int `json:"mtpsPrice"` // 分为单位 } diff --git a/business/model/sku.go b/business/model/sku.go index 9f7636140..612f08add 100644 --- a/business/model/sku.go +++ b/business/model/sku.go @@ -49,89 +49,123 @@ var ( // 这个指的是厂商(比如京东到家,饿百)自已的商品分类,与商家自己的商品分类是两回事 type SkuVendorCategory struct { - ModelIDCUO - VendorCategoryID string `gorm:"type:varchar(48);unique_index:unique_index_id_vendor_id" json:"vendorCategoryID"` - VendorID int `gorm:"unique_index:unique_index_id_vendor_id" json:"vendorID"` - Name string `gorm:"type:varchar(255);index" json:"name"` + ModelIDCUL + + VendorCategoryID string `orm:"size(48);column(vendor_category_id)" json:"vendorCategoryID"` + VendorID int `orm:"column(vendor_id)" json:"vendorID"` + Name string `orm:"size(255);index" json:"name"` IsLeaf int8 `json:"isLeaf"` Level int `json:"level"` - ParentID string `gorm:"type:varchar(255);index" json:"parentID"` // 父ID,引用的是VendorCategoryID而不是ID + ParentID string `orm:"column(parent_id);size(255);index" json:"parentID"` // 父ID,引用的是VendorCategoryID而不是ID +} + +func (*SkuVendorCategory) TableUnique() [][]string { + return [][]string{ + []string{"VendorCategoryID", "VendorID"}, + } } // 基础数据,除了商家商品类别外,基本都以京东到家为准 type SkuCategory struct { - ModelIDCUO - Name string `gorm:"type:varchar(255);unique_index"` - ParentID int + ModelIDCUL + + Name string `orm:"size(255);unique"` + ParentID int `orm:"column(parent_id)"` Level int8 Type int8 // 类别类型 Seq int - JdID int64 `gorm:"index"` // 这个是指商家自己的商品类别在京东平台上的ID - JdCategoryID int // 这个是指对应的京东商品类别 + JdID int64 `orm:"column(jd_id);index"` // 这个是指商家自己的商品类别在京东平台上的ID + JdCategoryID int `orm:"column(jd_category_id)"` // 这个是指对应的京东商品类别 - // ElmID int64 `gorm:"index"` // 饿了么是单店模式,不需要 - ElmCategoryID int64 // 这个是指对应的饿了么商品类别 + ElmCategoryID int64 `orm:"column(elm_category_id)"` // 这个是指对应的饿了么商品类别 + EbaiCategoryID int64 `orm:"column(ebai_category_id)"` // 这个是指对应的饿百商品类别 - // EbaiID int64 `gorm:"index"` // 饿百是单店模式,不需要 - EbaiCategoryID int64 // 这个是指对应的饿百商品类别 - - // MtID string `gorm:"type:varchar(48);index"` - // DidiID string `gorm:"type:varchar(48);index"` + // MtID string `orm:"size(48);index"` + // DidiID string `orm:"size(48);index"` } type SkuName struct { - ModelIDCUO - Prefix string `gorm:"type:varchar(255)"` - Name string `gorm:"type:varchar(255)"` - Comment string `gorm:"type:varchar(255)"` + ModelIDCUL - BrandID int `gorm:"default:0"` // 此属性暂时没有使用 - CategoryID int // 标准类别 + Prefix string `orm:"size(255)"` + Name string `orm:"size(255)"` + Comment string `orm:"size(255)"` + + BrandID int `orm:"column(brand_id);default(0)"` // 此属性暂时没有使用 + CategoryID int `orm:"column(category_id)"` // 标准类别 Status int - IsGlobal int8 `gorm:"default:1"` // 是否是全部(全国)可见,如果否的话,可见性由SkuPlace决定 - Unit string `gorm:"type:varchar(8)"` + IsGlobal int8 `orm:"default(1)"` // 是否是全部(全国)可见,如果否的话,可见性由SkuPlace决定 + Unit string `orm:"size(8)"` Price int // 单位为分,标准价,不为份的就为实际标准价,为份的为每市斤价,实际还要乘质量。todo 为份的确定必须有质量 - Img string `gorm:"type:varchar(255)"` - ElmImgHashCode string `gorm:"type:varchar(64)"` + Img string `orm:"size(255)"` + ElmImgHashCode string `orm:"size(64)"` } -type Sku struct { - ModelIDCUO - CategoryID int // 特殊类别,一般用于秒杀,特价之类的特殊类别 - NameID int `gorm:"index:unique_index_name_Id_quality"` // todo 这个索引应该要求唯一 - SpecQuality float32 `gorm:"index:unique_index_name_Id_quality"` - SpecUnit string `gorm:"type:varchar(8)"` // 质量或容量 - Weight int // 重量/质量,单位为克,当相应的SkuName的SpecUnit为g或kg时,必须等于SpecQuality +// func (*SkuName) TableUnique() [][]string { +// return [][]string{ +// []string{"Name", "Prefix", "Unit"}, +// } +// } - JdID int64 +type Sku struct { + ModelIDCUL + + CategoryID int `orm:"column(category_id)"` // 特殊类别,一般用于秒杀,特价之类的特殊类别 + NameID int `orm:"column(name_id)"` // todo 这个索引应该要求唯一 + SpecQuality float32 + SpecUnit string `orm:"size(8)"` // 质量或容量 + Weight int // 重量/质量,单位为克,当相应的SkuName的SpecUnit为g或kg时,必须等于SpecQuality + + JdID int64 `orm:"column(jd_id)"` +} + +func (*Sku) TableUnique() [][]string { + return [][]string{ + []string{"NameID", "SpecQuality", "SpecUnit"}, + } } type SkuNamePlaceBind struct { - ModelIDCUO - SkuNameID int `gorm:"unique_index:unique_sku_name_id_sku_place_id"` - PlaceCode int `gorm:"unique_index:unique_sku_name_id_sku_place_id"` + ModelIDCUL + + SkuNameID int `orm:"column(sku_name_id)"` + PlaceCode int +} + +func (*SkuNamePlaceBind) TableUnique() [][]string { + return [][]string{ + []string{"SkuNameID", "PlaceCode"}, + } } // 以下为门店相关数据 type StoreSkuCategoryMap struct { - ModelIDCUO - StoreID int - SkuCategoryID int + ModelIDCUL - ElmID int64 `gorm:"index"` - EbaiID int64 `gorm:"index"` + StoreID int `orm:"column(store_id)"` + SkuCategoryID int `orm:"column(sku_category_id)"` + + ElmID int64 `orm:"column(elm_id);index"` + EbaiID int64 `orm:"column(ebai_id);index"` } type StoreSkuBind struct { - ModelIDCUO - StoreID int `gorm:"unique_index:unique_store_id_sku_id"` - SkuID int `gorm:"unique_index:unique_store_id_sku_id"` - SubStoreID int + ModelIDCUL + + StoreID int `orm:"column(store_id)"` + SkuID int `orm:"column(sku_id)"` + SubStoreID int `orm:"column(sub_store_id)"` Price int // 单位为分,不用int64的原因是这里不需要累加 Status int - ElmID int64 `gorm:"index"` - EbaiID int64 `gorm:"index"` + ElmID int64 `orm:"column(elm_id);index"` + EbaiID int64 `orm:"column(ebai_id);index"` +} + +func (*StoreSkuBind) TableUnique() [][]string { + return [][]string{ + []string{"StoreID", "SkuID"}, + } } diff --git a/business/model/store.go b/business/model/store.go index a245dda8b..844823865 100644 --- a/business/model/store.go +++ b/business/model/store.go @@ -18,41 +18,50 @@ const ( ) type Store struct { - ModelIDCUO - Name string `gorm:"type:varchar(255);unique_index" json:"name"` - CityCode int `json:"cityCode"` // todo ? - DistrictCode int `json:"districtCode"` // todo ? - Address string `gorm:"type:varchar(255)" json:"address"` - Tel1 string `gorm:"type:varchar(32)" json:"tel1"` - Tel2 string `gorm:"type:varchar(32)" json:"tel2"` - OpenTime1 int16 `json:"openTime1"` // 930就表示9点半,用两个的原因是为了支持中午休息,1与2的时间段不能交叉,为0表示没有 - CloseTime1 int16 `json:"closeTime1"` // 格式同上 - OpenTime2 int16 `json:"openTime2"` // 格式同上 - CloseTime2 int16 `json:"closeTime2"` // 格式同上 - Lng int `json:"lng"` // 乘了10的6次方 - Lat int `json:"lat"` // 乘了10的6次方 - DeliveryRangeType int8 `json:"deliveryRangeType"` // 参见相关常量定义 - DeliveryRange string `gorm:"type:varchar(2048)" json:"deliveryRange"` // 如果DeliveryRangeType为DeliveryRangeTypePolygon,则为逗号分隔坐标,分号分隔的坐标点(坐标与Lng和Lat一样,都是整数),比如 121361504,31189308;121420555,31150238。否则为半径,单位为米 + ModelIDCUL + + Name string `orm:"size(255);unique" json:"name"` + CityCode int `orm:"default(0);null" json:"cityCode"` // todo ? + DistrictCode int `orm:"default(0);null" json:"districtCode"` // todo ? + Address string `orm:"size(255)" json:"address"` + Tel1 string `orm:"size(32);index" json:"tel1"` + Tel2 string `orm:"size(32);index" json:"tel2"` + OpenTime1 int16 `json:"openTime1"` // 930就表示9点半,用两个的原因是为了支持中午休息,1与2的时间段不能交叉,为0表示没有 + CloseTime1 int16 `json:"closeTime1"` // 格式同上 + OpenTime2 int16 `json:"openTime2"` // 格式同上 + CloseTime2 int16 `json:"closeTime2"` // 格式同上 + Lng int `json:"lng"` // 乘了10的6次方 + Lat int `json:"lat"` // 乘了10的6次方 + DeliveryRangeType int8 `json:"deliveryRangeType"` // 参见相关常量定义 + DeliveryRange string `orm:"size(2048)" json:"deliveryRange"` // 如果DeliveryRangeType为DeliveryRangeTypePolygon,则为逗号分隔坐标,分号分隔的坐标点(坐标与Lng和Lat一样,都是整数),比如 121361504,31189308;121420555,31150238。否则为半径,单位为米 Status int `json:"status"` } type StoreSub struct { - ModelIDCUO - StoreID int `gorm:"unique_index:unique_index1"` - Index int `gorm:"unique_index:unique_index1"` // 子店序号,为0表示主店 - Name string `gorm:"type:varchar(255)"` - Address string `gorm:"type:varchar(255)"` + ModelIDCUL + + StoreID int `orm:"column(store_id)"` + Index int // 子店序号,为0表示主店 + Name string `orm:"size(255);index"` + Address string `orm:"size(255)"` Status int // 取值同Store.Status - Mobile1 string `gorm:"type:varchar(32)"` - Mobile2 string `gorm:"type:varchar(32)"` - Mobile3 string `gorm:"type:varchar(32)"` + Mobile1 string `orm:"size(32)"` + Mobile2 string `orm:"size(32)"` + Mobile3 string `orm:"size(32)"` +} + +func (*StoreSub) TableUnique() [][]string { + return [][]string{ + []string{"StoreID", "Index"}, + } } type StoreMap struct { - ModelIDCUO - StoreID int `gorm:"unique_index:storemap1"` - VendorID int `gorm:"unique_index:storemap1"` - VendorStoreID string `gorm:"type:varchar(48);unique_index"` + ModelIDCUL + + StoreID int `orm:"column(store_id)"` + VendorID int `orm:"column(vendor_id)"` + VendorStoreID string `orm:"column(vendor_store_id);size(48)"` Status int // 取值同Store.Status AutoPickup int8 // 是否自动拣货 @@ -60,10 +69,25 @@ type StoreMap struct { DeliveryCompetition int8 // 是否支持配送竞争 } +func (*StoreMap) TableUnique() [][]string { + return [][]string{ + []string{"StoreID", "VendorID"}, + []string{"VendorStoreID", "VendorID"}, + } +} + type StoreCourierMap struct { - ModelIDCUO - StoreID int `gorm:"unique_index:storemap1"` - VendorID int `gorm:"unique_index:storemap1"` - VendorStoreID string `gorm:"type:varchar(48);unique_index"` + ModelIDCUL + + StoreID int `orm:"column(store_id)"` + VendorID int `orm:"column(vendor_id)"` + VendorStoreID string `orm:"column(vendor_store_id);size(48)"` Status int } + +func (*StoreCourierMap) TableUnique() [][]string { + return [][]string{ + []string{"StoreID", "VendorID"}, + []string{"VendorStoreID", "VendorID"}, + } +} diff --git a/business/model/tasklog.go b/business/model/tasklog.go deleted file mode 100644 index e62274755..000000000 --- a/business/model/tasklog.go +++ /dev/null @@ -1,23 +0,0 @@ -package model - -type TaskLog struct { - ModelIDCU - TaskID string `gorm:"type:varchar(48)"` // 用于标识任务 - CreatedBy string `gorm:"type:varchar(48)"` - Status int -} - -type TaskLogItem struct { - ModelIDCU - TaskID string `gorm:"type:varchar(48)"` // 用于标识任务 - ID1 int - VendorID1 string `gorm:"type:varchar(48)"` - ID2 int - VendorID2 string `gorm:"type:varchar(48)"` - ID3 int - VendorID3 string `gorm:"type:varchar(48)"` - Payload string `gorm:"type:varchar(2000)"` - StatusJD int8 - StatusElm int8 - StatusEbai int8 -} diff --git a/business/partner/purchase/jd/order_test.go b/business/partner/purchase/jd/order_test.go index 1d3f0e11e..f21ee2cb1 100644 --- a/business/partner/purchase/jd/order_test.go +++ b/business/partner/purchase/jd/order_test.go @@ -9,7 +9,6 @@ import ( "git.rosy.net.cn/jx-callback/globals" "git.rosy.net.cn/jx-callback/globals/api" "git.rosy.net.cn/jx-callback/globals/beegodb" - "git.rosy.net.cn/jx-callback/globals/gormdb" "github.com/astaxie/beego" ) @@ -19,7 +18,6 @@ func init() { globals.Init() beegodb.Init() - gormdb.Init() api.Init() } diff --git a/business/partner/purchase/jd/sku.go b/business/partner/purchase/jd/sku.go index c3acfaa99..74b1627fa 100644 --- a/business/partner/purchase/jd/sku.go +++ b/business/partner/purchase/jd/sku.go @@ -9,7 +9,6 @@ import ( "git.rosy.net.cn/jx-callback/business/model/dao" "git.rosy.net.cn/jx-callback/globals" "git.rosy.net.cn/jx-callback/globals/api" - "git.rosy.net.cn/jx-callback/globals/gormdb" ) const ( @@ -84,15 +83,15 @@ func (p *PurchaseHandler) DeleteCategory(cat *model.SkuCategory) error { func (p *PurchaseHandler) cuSku(sku *model.Sku, handler func(skuExt *skuInfoExt, skuName string, shopCategories []int64, addParams map[string]interface{}) (string, error)) (err error) { var otherInfo skuInfoExt - db := gormdb.GetDB() - err = db.Raw(` + db := dao.GetDB() + err = dao.GetRow(nil, &otherInfo, ` SELECT t2.*, t3.jd_id, t3.jd_category_id, t4.jd_id sku_cat_id FROM sku t1 JOIN sku_name t2 ON t1.name_id = t2.id JOIN sku_category t3 ON t2.category_id = t3.id LEFT JOIN sku_category t4 ON t1.category_id = t4.id WHERE t1.id = ? - `, sku.ID).Scan(&otherInfo).Error + `, sku.ID) if err == nil { shopCategories := []int64{otherInfo.JdID} if otherInfo.SkuCatID != 0 { @@ -107,7 +106,7 @@ func (p *PurchaseHandler) cuSku(sku *model.Sku, handler func(skuExt *skuInfoExt, addParams := map[string]interface{}{} if otherInfo.IsGlobal == 0 { //如果不是全国可售,要查可售区域 - sellPlaces, err2 := dao.GetSellCities(otherInfo.ID, model.VendorIDJD, db) + sellPlaces, err2 := dao.GetSellCities(db, otherInfo.ID, model.VendorIDJD) if err = err2; err == nil && len(sellPlaces) > 0 { sellCites := make([]int, len(sellPlaces)) for k, v := range sellPlaces { @@ -161,11 +160,11 @@ func (p *PurchaseHandler) ReadSku(vendorSkuID string) (skuName *model.SkuName, s } sku.ID = int(utils.Str2Int64(utils.Interface2String(mapData["outSkuId"]))) - db := gormdb.GetDB() + db := dao.GetDB() shopCategories := utils.Interface2Int64List(mapData["shopCategories"]) if len(shopCategories) > 0 { skuCat := &model.SkuCategory{} - if db.Where("jd_id = ?", shopCategories[0]).Find(skuCat).Error == nil { + if dao.GetRow(db, skuCat, "SELECT * FROM sku_category WHERE jd_id = ?", shopCategories[0]) == nil { skuName.CategoryID = skuCat.ID } } @@ -174,7 +173,7 @@ func (p *PurchaseHandler) ReadSku(vendorSkuID string) (skuName *model.SkuName, s skuName.IsGlobal = 1 } else { sellPlaces = make([]*model.Place, 0) - err2 := db.Where("jd_code IN (?) AND level = 2", sellCities).Find(&sellPlaces).Error + err2 := dao.GetRows(db, &sellPlaces, "SELECT * FROM place WHERE jd_code IN (?) AND level = 2", sellCities) globals.SugarLogger.Debug("err2:%v", err2) } return skuName, sellPlaces, sku, nil diff --git a/business/partner/purchase/jd/store.go b/business/partner/purchase/jd/store.go index d0a4b2d63..5641490f7 100644 --- a/business/partner/purchase/jd/store.go +++ b/business/partner/purchase/jd/store.go @@ -10,7 +10,6 @@ import ( "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/model" "git.rosy.net.cn/jx-callback/globals/api" - "git.rosy.net.cn/jx-callback/globals/gormdb" ) func (p *PurchaseHandler) ReadStore(vendorStoreID string) (*model.Store, error) { @@ -32,7 +31,7 @@ func (p *PurchaseHandler) ReadStore(vendorStoreID string) (*model.Store, error) } cityCode := int(utils.MustInterface2Int64(result["city"])) if cityCode != 0 { - db := gormdb.GetDB() + db := dao.GetDB() if city, err2 := dao.GetPlaceByJdCode(db, cityCode); err2 == nil { retVal.CityCode = city.Code districtName := utils.Interface2String(result["countyName"]) // 京东的市区号码与通用数据完全无法关联,只有通过名字来关联 diff --git a/controllers/cms_store.go b/controllers/cms_store.go index 4518f15a6..3a9147c62 100644 --- a/controllers/cms_store.go +++ b/controllers/cms_store.go @@ -44,7 +44,8 @@ func (c *StoreController) GetPlaces() { // @router /UpdatePlaces [put] func (c *StoreController) UpdatePlaces() { c.callUpdatePlaces(func(params *tStoreUpdatePlacesParams) (retVal interface{}, errCode string, err error) { - placeList := []*model.Place{} + // placeList := []*model.Place{} + placeList := make([]map[string]interface{}, 0) utils.UnmarshalUseNumber([]byte(params.Payload), &placeList) err = cms.UpdatePlaces(placeList, GetUserNameFromToken(params.Token)) return nil, "", err @@ -96,9 +97,9 @@ func (c *StoreController) GetVendorStore() { // @Param payload formData string true "json数据,store对象" // @Success 200 {object} controllers.CallResult // @Failure 200 {object} controllers.CallResult -// @router /FUpdateStore [put] -func (c *StoreController) FUpdateStore() { - c.callFUpdateStore(func(params *tStoreFUpdateStoreParams) (retVal interface{}, errCode string, err error) { +// @router /UpdateStore [put] +func (c *StoreController) UpdateStore() { + c.callUpdateStore(func(params *tStoreUpdateStoreParams) (retVal interface{}, errCode string, err error) { store := make(map[string]interface{}) utils.UnmarshalUseNumber([]byte(params.Payload), &store) err = cms.UpdateStore(store, GetUserNameFromToken(params.Token)) @@ -121,3 +122,13 @@ func (c *StoreController) CreateStore() { return retVal, "", err }) } + +// @Title 空方法,占位用 +// @Description 空方法,占位用 +// @Param token header string true "认证token" +// @Param payload formData string true "json数据,store对象" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /ZZZZZ [put] +func (c *StoreController) ZZZZZ() { +} diff --git a/globals/beegodb/beegodb.go b/globals/beegodb/beegodb.go index 61cd61797..b9befe540 100644 --- a/globals/beegodb/beegodb.go +++ b/globals/beegodb/beegodb.go @@ -24,6 +24,13 @@ func Init() { orm.RegisterModel(new(legacymodel.Jxorder2)) orm.RegisterModel(new(legacymodel.Jxordersku2)) + orm.RegisterModel(&model.Place{}) + orm.RegisterModel(&model.Store{}, &model.StoreSub{}, &model.StoreMap{}) + orm.RegisterModel(&model.SkuVendorCategory{}, &model.StoreSkuCategoryMap{}, &model.SkuName{}, &model.Sku{}, &model.SkuNamePlaceBind{}, &model.StoreSkuBind{}) + // db.Set("gorm:table_options", "CHARSET=utf8mb4").AutoMigrate(&model.SkuCategory{}) + orm.RegisterModel(&model.SkuCategory{}) + orm.RegisterModel(&model.WeiXins{}, &model.JxBackendUser{}) + orm.RegisterModel(&model.DurableTask{}, &model.DurableTaskItem{}) // create table orm.RunSyncdb("default", false, true) } diff --git a/globals/gormdb/gormdb.go b/globals/gormdb/gormdb.go deleted file mode 100644 index 7515d39fe..000000000 --- a/globals/gormdb/gormdb.go +++ /dev/null @@ -1,48 +0,0 @@ -package gormdb - -import ( - "fmt" - - "git.rosy.net.cn/jx-callback/business/model" - "github.com/astaxie/beego" - "github.com/jinzhu/gorm" -) - -var ( - dbStr string - singletonDB *gorm.DB -) - -func Init() { - dbStr = beego.AppConfig.String("dbConnectStr") - AutoMigrate() -} - -// todo gorm要求用单一的db?如果每次重新调用Open,会导致too many connection错误 -func GetDB() *gorm.DB { - if singletonDB == nil { - db, err := gorm.Open("mysql", dbStr) - if err == nil { - singletonDB = db - return db - } - panic(fmt.Sprintf("AutoMigrate failed with error:%v", err)) - } - return singletonDB -} - -func AutoMigrate() { - db := GetDB() - db.SingularTable(true) - - // db.DropTableIfExists(&model.Place{}) - // db.DropTableIfExists(&model.Store{}, &model.StoreSub{}, &model.StoreMap{}) - // db.DropTableIfExists(&model.SkuVendorCategory{}, &model.StoreSkuCategoryMap{}, &model.SkuName{}, &model.Sku{}, &model.SkuNamePlaceBind{}, &model.StoreSkuBind{}, &model.SkuCategory{}) - - db.AutoMigrate(&model.Place{}) - db.AutoMigrate(&model.Store{}, &model.StoreSub{}, &model.StoreMap{}) - db.AutoMigrate(&model.SkuVendorCategory{}, &model.StoreSkuCategoryMap{}, &model.SkuName{}, &model.Sku{}, &model.SkuNamePlaceBind{}, &model.StoreSkuBind{}) - db.Set("gorm:table_options", "CHARSET=utf8mb4").AutoMigrate(&model.SkuCategory{}) - db.AutoMigrate(&model.WeiXins{}, &model.JxBackendUser{}) - // db.AutoMigrate(&model.DurableTask{}, &model.DurableTaskItem{}) -} diff --git a/main.go b/main.go index af58532a3..51399d1f5 100644 --- a/main.go +++ b/main.go @@ -3,11 +3,9 @@ package main import ( "flag" "fmt" - "net/http" "os" "git.rosy.net.cn/jx-callback/business/jxcallback/orderman" - "git.rosy.net.cn/jx-callback/business/jxstore/qorcms" "git.rosy.net.cn/jx-callback/globals" "git.rosy.net.cn/jx-callback/globals/api" "git.rosy.net.cn/jx-callback/globals/beegodb" @@ -86,13 +84,6 @@ func main() { } orderman.LoadPendingOrders() } - if beego.AppConfig.DefaultBool("enableStore", false) { - qorcms.Init() - mux := http.NewServeMux() - curAdmin := qorcms.GetAdmin() - curAdmin.MountTo("/admin", mux) - beego.Handler("/admin/*", mux) - } if beego.BConfig.RunMode != "prod" { beego.BConfig.WebConfig.DirectoryIndex = true diff --git a/routers/commentsRouter_controllers.go b/routers/commentsRouter_controllers.go index 1af09612d..9579f14c0 100644 --- a/routers/commentsRouter_controllers.go +++ b/routers/commentsRouter_controllers.go @@ -151,14 +151,6 @@ func init() { MethodParams: param.Make(), Params: nil}) - beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreController"], - beego.ControllerComments{ - Method: "FUpdateStore", - Router: `/FUpdateStore`, - AllowHTTPMethods: []string{"put"}, - MethodParams: param.Make(), - Params: nil}) - beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreController"], beego.ControllerComments{ Method: "GetPlaces", @@ -191,4 +183,20 @@ func init() { MethodParams: param.Make(), Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreController"], + beego.ControllerComments{ + Method: "UpdateStore", + Router: `/UpdateStore`, + AllowHTTPMethods: []string{"put"}, + MethodParams: param.Make(), + Params: nil}) + + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreController"], + beego.ControllerComments{ + Method: "ZZZZZ", + Router: `/ZZZZZ`, + AllowHTTPMethods: []string{"put"}, + MethodParams: param.Make(), + Params: nil}) + }