diff --git a/upstream/dwd/dwd_token.go b/upstream/dwd/dwd_token.go
index 7b4f935764e985c2ac507b7643b3ed03aa79f432..5a15a5f5cab74fc6b745959985c659553c3abf00 100644
--- a/upstream/dwd/dwd_token.go
+++ b/upstream/dwd/dwd_token.go
@@ -48,14 +48,19 @@ func (s *tokenDwd) Get(ctx context.Context) (res *TokenGetRes, err error) {
 }
 
 func (s *tokenDwd) Access(ctx context.Context) (res string, err error) {
-	cache, _ := g.Redis().DoVar("HGETALL", CacheKey)
+	conn := g.Redis().Ctx(ctx).Conn()
+	defer func() {
+		_ = conn.Close()
+	}()
+	_, _ = conn.DoVar("SELECT", 10)
+	cache, _ := conn.DoVar("HGETALL", CacheKey)
 	if !cache.IsEmpty() {
 		_ = cache.Scan(&s)
 		if s.ExpiresIn > gtime.Timestamp() {
 			res = s.AccessToken
 			return
 		}
-		_, err = g.Redis().DoVar("DEL", CacheKey)
+		_, err = conn.DoVar("DEL", CacheKey)
 	}
 	result, err := s.Get(ctx)
 	if err != nil {
@@ -68,12 +73,12 @@ func (s *tokenDwd) Access(ctx context.Context) (res string, err error) {
 	_ = gjson.New(result.Data).Scan(&s)
 	s.ExpiresIn += gtime.Timestamp()
 	res = s.AccessToken
-	_, _ = g.Redis().Do("HMSET", append(g.Slice{CacheKey}, gutil.MapToSlice(gconv.Map(s))...)...)
+	_, _ = conn.Do("HMSET", append(g.Slice{CacheKey}, gutil.MapToSlice(gconv.Map(s))...)...)
 	return
 }
 
 func (s *tokenDwd) post(ctx context.Context, req interface{}) (res string, err error) {
-	//Start := gtime.TimestampMilli()
+	Start := gtime.TimestampMilli()
 
 	var request = gjson.New(req)
 	_ = request.Set("signature", sign(req))
@@ -85,9 +90,9 @@ func (s *tokenDwd) post(ctx context.Context, req interface{}) (res string, err e
 		ctx = context.WithValue(ctx, "Method", "POST")
 		ctx = context.WithValue(ctx, "URI", "token")
 		if err != nil {
-			//g.Log().Ctx(ctx).Infof("参数【%v】错误【%v】响应时间【%v】", request.MustToJsonString(), err.Error(), gtime.TimestampMilli()-Start)
+			g.Log().Ctx(ctx).Infof("参数【%v】错误【%v】响应时间【%v】", request.MustToJsonString(), err.Error(), gtime.TimestampMilli()-Start)
 		} else {
-			//g.Log().Ctx(ctx).Cat(PkgName).Infof("参数【%v】响应【%v】响应时间【%v】", request.MustToJsonString(), res, gtime.TimestampMilli()-Start)
+			g.Log().Ctx(ctx).Cat(PkgName).Infof("参数【%v】响应【%v】响应时间【%v】", request.MustToJsonString(), res, gtime.TimestampMilli()-Start)
 		}
 	}()
 	res = resp.ReadAllString()
diff --git a/upstream/jingdong/jingdong_token.go b/upstream/jingdong/jingdong_token.go
index b1b94fa30954a5b086062ad54c775e3a3a8bad0f..b58b684dad213d27cb3348aed693cab063b8c8eb 100644
--- a/upstream/jingdong/jingdong_token.go
+++ b/upstream/jingdong/jingdong_token.go
@@ -33,7 +33,12 @@ type accessToken struct {
 //getAccessToken 获取token
 func (s *client) getAccessToken(ctx context.Context) (err error) {
 	var token *accessToken
-	cache, _ := g.Redis().DoVar("HGETALL", CacheKey)
+	conn := g.Redis().Ctx(ctx).Conn()
+	defer func() {
+		_ = conn.Close()
+	}()
+	_, _ = conn.DoVar("SELECT", 10)
+	cache, _ := conn.DoVar("HGETALL", CacheKey)
 	if !cache.IsEmpty() {
 		_ = cache.Scan(&token)
 		if token.Time+token.ExpiresIn*1000 > gtime.TimestampMilli() {
@@ -69,7 +74,7 @@ func (s *client) getAccessToken(ctx context.Context) (err error) {
 		err = errors.New(jdRes.ResultMessage)
 		return
 	}
-	_, _ = g.Redis().Do("HMSET", append(g.Slice{CacheKey}, gutil.MapToSlice(gconv.Map(jdRes.Result))...)...)
+	_, _ = conn.Do("HMSET", append(g.Slice{CacheKey}, gutil.MapToSlice(gconv.Map(jdRes.Result))...)...)
 	s.AccessToken = jdRes.Result.AccessToken
 	return
 }
@@ -101,7 +106,12 @@ func (s *client) refreshToken(ctx context.Context, req *accessToken) (err error)
 		err = errors.New(jdRes.ResultMessage)
 		return
 	}
-	_, _ = g.Redis().Do("HMSET", append(g.Slice{CacheKey}, gutil.MapToSlice(gconv.Map(jdRes.Result))...)...)
+	conn := g.Redis().Ctx(ctx).Conn()
+	defer func() {
+		_ = conn.Close()
+	}()
+	_, _ = conn.DoVar("SELECT", 10)
+	_, _ = conn.Do("HMSET", append(g.Slice{CacheKey}, gutil.MapToSlice(gconv.Map(jdRes.Result))...)...)
 	s.AccessToken = jdRes.Result.AccessToken
 	return
 }
diff --git a/upstream/tm/tm_category.go b/upstream/tm/tm_category.go
new file mode 100644
index 0000000000000000000000000000000000000000..9792fcdf712d624d631c12f3065e600434f3ec1a
--- /dev/null
+++ b/upstream/tm/tm_category.go
@@ -0,0 +1,58 @@
+package tm
+
+import (
+	"context"
+	"github.com/gogf/gf/encoding/gjson"
+)
+
+type category struct {
+}
+
+var Category = category{}
+
+type CategoryDetailRes struct {
+	Code         string `json:"Code"` //成功 0000
+	Message      string `json:"Message"`
+	RequestId    string `json:"RequestId"`
+	CategoryList []struct {
+		CategoryId int    `json:"CategoryId"`
+		Name       string `json:"Name"`
+	} `json:"CategoryList"`
+}
+
+func (category) Detail(ctx context.Context, req string) (res *CategoryDetailRes, err error) {
+	method := "GetCategoryChain"
+
+	request := map[string]string{
+		"BizUid":     server.BizUid,
+		"CategoryId": req,
+	}
+
+	result, err := post(ctx, method, request)
+	err = gjson.New(result).Scan(&res)
+	return
+}
+
+type CategoryListRes struct {
+	Code         string `json:"Code"` //成功 0000
+	Message      string `json:"Message"`
+	RequestId    string `json:"RequestId"`
+	CategoryList struct {
+		Category []struct {
+			CategoryId int    `json:"CategoryId"`
+			Name       string `json:"Name"`
+		} `json:"Category"`
+	} `json:"CategoryList"`
+}
+
+func (category) List(ctx context.Context, req string) (res *CategoryListRes, err error) {
+	method := "GetCategoryList"
+
+	request := map[string]string{
+		"CategoryId": req,
+	}
+
+	result, err := post(ctx, method, request)
+	err = gjson.New(result).Scan(&res)
+	return
+}