fix(tapd): cherrypick #4399#4395 to 0.15 (#4400)

* fix(tapd): convert unicode to string

* fix(tapd): fix order in bug changelog collector
diff --git a/plugins/tapd/tasks/bug_changelog_collector.go b/plugins/tapd/tasks/bug_changelog_collector.go
index 20c242c..3ed21ab 100644
--- a/plugins/tapd/tasks/bug_changelog_collector.go
+++ b/plugins/tapd/tasks/bug_changelog_collector.go
@@ -50,7 +50,7 @@
 			query.Set("workspace_id", fmt.Sprintf("%v", data.Options.WorkspaceId))
 			query.Set("page", fmt.Sprintf("%v", reqData.Pager.Page))
 			query.Set("limit", fmt.Sprintf("%v", reqData.Pager.Size))
-			query.Set("order", "created%20desc")
+			query.Set("order", "created desc")
 			if data.CreatedDateAfter != nil {
 				query.Set("created",
 					fmt.Sprintf(">%s",
diff --git a/plugins/tapd/tasks/story_changelog_extractor.go b/plugins/tapd/tasks/story_changelog_extractor.go
index a9a976f..f9055b1 100644
--- a/plugins/tapd/tasks/story_changelog_extractor.go
+++ b/plugins/tapd/tasks/story_changelog_extractor.go
@@ -20,6 +20,7 @@
 import (
 	"encoding/json"
 	"github.com/apache/incubator-devlake/errors"
+	"strconv"
 	"strings"
 
 	"github.com/apache/incubator-devlake/plugins/core"
@@ -89,14 +90,23 @@
 						default:
 							item.ValueBeforeParsed = valueBeforeMap.(string)
 						}
+						err = convertUnicode(&item)
+						if err != nil {
+							return nil, err
+						}
 						results = append(results, &item)
 					}
 				default:
 					item.ConnectionId = data.Options.ConnectionId
 					item.ChangelogId = storyChangelog.Id
 					item.Field = fc.Field
-					item.ValueAfterParsed = strings.Trim(string(fc.ValueAfterParsed), `"`)
-					item.ValueBeforeParsed = strings.Trim(string(fc.ValueBeforeParsed), `"`)
+					item.ValueAfterParsed = valueAfterMap.(string)
+					// as ValueAfterParsed is string, valueBeforeMap is always string
+					item.ValueBeforeParsed = valueBeforeMap.(string)
+				}
+				err = convertUnicode(&item)
+				if err != nil {
+					return nil, err
 				}
 				if item.Field == "iteration_id" {
 					iterationFrom, iterationTo, err := parseIterationChangelog(taskCtx, item.ValueBeforeParsed, item.ValueAfterParsed)
@@ -119,3 +129,24 @@
 
 	return extractor.Execute()
 }
+
+func unicodeToZh(s string) (string, error) {
+	str, err := strconv.Unquote(strings.Replace(strconv.Quote(s), `\\u`, `\u`, -1))
+	if err != nil {
+		return "", err
+	}
+	return str, nil
+}
+
+func convertUnicode(item *models.TapdStoryChangelogItem) errors.Error {
+	var err errors.Error
+	item.ValueAfterParsed, err = errors.Convert01(unicodeToZh(item.ValueAfterParsed))
+	if err != nil {
+		return err
+	}
+	item.ValueBeforeParsed, err = errors.Convert01(unicodeToZh(item.ValueBeforeParsed))
+	if err != nil {
+		return err
+	}
+	return nil
+}