package xpyunapi import ( "bytes" "crypto/sha1" "encoding/json" "fmt" "gitrosy.jxc4.com/baseapi/utils" "golang.org/x/text/encoding/simplifiedchinese" "golang.org/x/text/transform" "io/ioutil" "net/http" "regexp" "strconv" "strings" "time" "unicode" ) /** * 发送http的json请求 * * @param url 请求url * @param jsonStr 发送的json字符串 * */ func HttpPostJson(url string, data interface{}) *XPYunResp { b, err := json.Marshal(&data) if err != nil { var msg = fmt.Sprintf("json serialize err:%+v", err) fmt.Println(msg) result := XPYunResp{ HttpStatusCode: 500, } return &result } //var reqMsg = fmt.Sprintf("response result:%+v", string(b)) //fmt.Println(reqMsg) resp, err := http.Post(url, "application/json", bytes.NewBuffer(b)) if err != nil { fmt.Println(err) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { var msg = fmt.Sprintf("post json error:%+v", err) fmt.Println(msg) } result := XPYunResp{ HttpStatusCode: resp.StatusCode, } var content XPYunRespContent err = json.Unmarshal(body, &content) if err == nil { result.Content = &content } else { var msg = fmt.Sprintf("unmarshal body failed, error:%+v", err) fmt.Println(msg) } return &result } /** * 哈稀签名 * @param signSource - 源字符串 * @return */ func Sign(signSource string) string { h := sha1.New() h.Write([]byte(signSource)) result := fmt.Sprintf("%x", h.Sum(nil)) return result } //获得毫秒数 func GetMillisecond() int64 { return time.Now().UnixNano() / 1e6 } /** * 获得字符串重复 * @param str - 要进行重复的字符串 * @param repeatTimes - 重复次数 */ func StrRepeat(str string, repeatTimes int) string { return strings.Repeat(str, repeatTimes) } func CalcGbkLenForPrint(data string) int { gbk, err := Utf8ToGbk(data) if err != nil { return 0 } return len(gbk) } func CalcAsciiLenForPrint(data string) int { return len(data) } func Utf8ToGbk(s string) (string, error) { reader := transform.NewReader(bytes.NewReader([]byte(s)), simplifiedchinese.GBK.NewEncoder()) d, e := ioutil.ReadAll(reader) if e != nil { return "", e } return string(d), nil } //解析返回数据结构体 func GetXpuResponse(data interface{}) *XPYunRespContent { retVal := &XPYunRespContent{} resultJson, _ := json.Marshal(data) decoder := json.NewDecoder(bytes.NewBufferString(string(resultJson))) if err := decoder.Decode(&retVal); err != nil { return nil } return retVal } const ROW_MAX_CHAR_LEN = 32 const MAX_NAME_CHAR_LEN = 20 const NEX_ROW_CHAR_LEN = 8 const LAST_ROW_MAX_NAME_CHAR_LEN = 16 const MAX_QUANTITY_CHAR_LEN = 6 const MAX_PRICE_CHAR_LEN = 6 const LAST_ROW_MAX_NAME_CHAR_LEN80 = 24 //26 const ROW_MAX_CHAR_LEN80 = 48 const MAX_NAME_CHAR_LEN80 = 27 const MAX_QUANTITY_CHAR_LEN80 = 7 //var orderNameEmpty = StrRepeat(" ", MAX_NAME_CHAR_LEN) var orderNameEmpty = StrRepeat(" ", NEX_ROW_CHAR_LEN) //test函数 func FormatPrintOrderItem(foodName string, quantity int, price float64) string { //foodNameLen := CalcGbkLenForPrint(foodName) quantityStr := strconv.Itoa(quantity) quantityLen := CalcAsciiLenForPrint(quantityStr) temprice := price / 100 priceStr := fmt.Sprintf("%.2f", temprice) priceLen := CalcAsciiLenForPrint(priceStr) subtotalStr := fmt.Sprintf("%.2f", utils.Int2Float64(quantity)*temprice) //subtotalLen := CalcAsciiLenForPrint(subtotalStr) result := foodName + "
" //mod := foodNameLen % ROW_MAX_CHAR_LEN //if mod <= LAST_ROW_MAX_NAME_CHAR_LEN { // // 保证各个列的宽度固定,不足部分,利用空格填充 // result = result + StrRepeat(" ", MAX_NAME_CHAR_LEN-mod) // //} else { // // 另起新行 // result = result + "
" // result = result + orderNameEmpty //} result += orderNameEmpty + "x" + quantityStr + StrRepeat(" ", MAX_QUANTITY_CHAR_LEN-quantityLen) result += "¥" + priceStr + StrRepeat(" ", MAX_QUANTITY_CHAR_LEN+1-priceLen) result += "¥" + subtotalStr result += "
" return result } //正则计算宽度 func CalWidth(str string) int { hzc := 0 for _, v := range str { if unicode.Is(unicode.Han, v) { hzc++ } } updateStr := regexp.MustCompile("[\u4e00-\u9fa5]{1,}").ReplaceAllString(str, "") l := len(updateStr) fmt.Println(hzc) ans := 2*hzc + l return ans } const ( MaxLineLength = 30 LineLength = 32 NewLineLength = 28 ) func FormatPrintOrderItemV2(foodName string, quantity, index int) string { var ( restLen int quantityStr = strconv.Itoa(quantity) //quantityLen = CalcAsciiLenForPrint(quantityStr) foodNameLen = CalWidth(foodName) + 3 result = "" ) if foodNameLen >= MaxLineLength { if n := foodNameLen / LineLength; n > 0 { restLen = foodNameLen % LineLength } else { restLen = foodNameLen - LineLength } result += "" + utils.Int2Str(index) + `.` + foodName + "" result += "" + StrRepeat(" ", MaxLineLength-restLen) + `x` + quantityStr + "" } else { result += "" + utils.Int2Str(index) + `.` + foodName + StrRepeat(" ", MaxLineLength-foodNameLen) + `x` + quantityStr + "" } //result += orderNameEmpty + "x" + quantityStr + StrRepeat(" ", MAX_QUANTITY_CHAR_LEN-quantityLen) result += "
" return result }