jiaojiao7 3 年之前
父節點
當前提交
7daf273508

二進制
api/go_build_message_API_go_linux


+ 29 - 0
api/internal/handler/multiplesavemsghandler.go

@@ -0,0 +1,29 @@
+package handler
+
+import (
+	"net/http"
+
+	"app.yhyue.com/moapp/MessageCenter/api/internal/logic"
+	"app.yhyue.com/moapp/MessageCenter/api/internal/svc"
+	"app.yhyue.com/moapp/MessageCenter/api/internal/types"
+
+	"github.com/tal-tech/go-zero/rest/httpx"
+)
+
+func MultipleSaveMsgHandler(ctx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		var req types.MultipleSaveMsgReq
+		if err := httpx.Parse(r, &req); err != nil {
+			httpx.Error(w, err)
+			return
+		}
+
+		l := logic.NewMultipleSaveMsgLogic(r.Context(), ctx)
+		resp, err := l.MultipleSaveMsg(req)
+		if err != nil {
+			httpx.Error(w, err)
+		} else {
+			httpx.OkJson(w, resp)
+		}
+	}
+}

+ 5 - 0
api/internal/handler/routes.go

@@ -62,6 +62,11 @@ func RegisterHandlers(engine *rest.Server, serverCtx *svc.ServiceContext) {
 				Path:    "/message/SendMsg",
 				Handler: SendMsgHandler(serverCtx),
 			},
+			{
+				Method:  http.MethodPost,
+				Path:    "/message/MultipleSaveMsg",
+				Handler: MultipleSaveMsgHandler(serverCtx),
+			},
 		},
 	)
 }

+ 69 - 0
api/internal/logic/multiplesavemsglogic.go

@@ -0,0 +1,69 @@
+package logic
+
+import (
+	"app.yhyue.com/moapp/MessageCenter/rpc/messageclient"
+	"app.yhyue.com/moapp/MessageCenter/util"
+	"context"
+	"encoding/json"
+	"log"
+
+	"app.yhyue.com/moapp/MessageCenter/api/internal/svc"
+	"app.yhyue.com/moapp/MessageCenter/api/internal/types"
+
+	"github.com/tal-tech/go-zero/core/logx"
+)
+
+type MultipleSaveMsgLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewMultipleSaveMsgLogic(ctx context.Context, svcCtx *svc.ServiceContext) MultipleSaveMsgLogic {
+	return MultipleSaveMsgLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx,
+	}
+}
+
+func (l *MultipleSaveMsgLogic) MultipleSaveMsg(req types.MultipleSaveMsgReq) (*types.MultipleSaveMsgResp, error) {
+	// todo: add your logic here and delete this line
+	log.Println("请求参数:", req)
+	var reqData = []map[string]interface{}{}
+	err := json.Unmarshal([]byte(req.SaveData), reqData)
+	if err != nil {
+		return &types.MultipleSaveMsgResp{
+			Code:     0,
+			Message:  "失败",
+			ErrCount: 0,
+		}, nil
+	}
+
+	errCount := 0
+	lsi := l.svcCtx.MessageCenter
+	for _, val := range reqData {
+
+		resp, err := lsi.SendUserMsg(l.ctx, &messageclient.SendMsgRequest{
+			Appid:         util.ObjToString(val["appid"]),
+			ReceiveUserId: util.ObjToString(val["receiveUserId"]),
+			ReceiveName:   util.ObjToString(val["receiveName"]),
+			SendUserId:    util.ObjToString(val["sendUserId"]),
+			SendName:      util.ObjToString(val["sendName"]),
+			Title:         util.ObjToString(val["title"]),
+			Content:       util.ObjToString(val["content"]),
+			MsgType:       util.Int64All(val["msgType"]),
+			Link:          util.ObjToString(val["link"]),
+			CiteId:        util.Int64All(val["citeId"]),
+		})
+		log.Println(resp)
+		if err != nil {
+			errCount++
+		}
+	}
+	return &types.MultipleSaveMsgResp{
+		Code:     1,
+		Message:  "保存成功",
+		ErrCount: int64(errCount),
+	}, nil
+}

+ 10 - 0
api/internal/types/types.go

@@ -125,3 +125,13 @@ type SendMsgResp struct {
 	Message string `json:"message"`
 	Status  int64  `json:"status"`
 }
+
+type MultipleSaveMsgReq struct {
+	SaveData string `json:"saveData"`
+}
+
+type MultipleSaveMsgResp struct {
+	Code     int64  `json:"code"`
+	Message  string `json:"message"`
+	ErrCount int64  `json:"errCount"`
+}

+ 14 - 0
api/message.api

@@ -123,6 +123,16 @@ type SendMsgResp {
 	Status  int64  `json:"status"`
 }
 
+//批量保存消息
+type MultipleSaveMsgReq {
+	SaveData string `json:"saveData"`
+}
+type MultipleSaveMsgResp {
+	Code     int64  `json:"code"`
+	Message  string `json:"message"`
+	ErrCount int64  `json:"errCount"`
+}
+
 service message-api {
 	//删除消息
 	@handler MessageDeleteHandler // TODO: set handler name and delete this comment
@@ -154,4 +164,8 @@ service message-api {
 	// 发送消息
 	@handler SendMsgHandler
 	post /message/SendMsg (SendMsgReq) returns (SendMsgResp)
+	
+	// 发送消息
+	@handler MultipleSaveMsgHandler
+	post /message/MultipleSaveMsg (MultipleSaveMsgReq) returns (MultipleSaveMsgResp)
 }

+ 593 - 0
util/common.go

@@ -0,0 +1,593 @@
+package util
+
+import (
+	"crypto/md5"
+	cryptoRand "crypto/rand"
+	"encoding/hex"
+	"encoding/json"
+	"encoding/xml"
+	"fmt"
+	"io"
+	"log"
+	"math"
+	"math/big"
+	mathRand "math/rand"
+	"reflect"
+	"regexp"
+	"runtime"
+	"sort"
+	"strconv"
+	"strings"
+	"time"
+)
+
+const (
+	tmp = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345678900"
+)
+
+func Uuid(length int) string {
+	ret := []string{}
+	r := mathRand.New(mathRand.NewSource(time.Now().UnixNano()))
+	for i := 0; i < length; i++ {
+		index := r.Intn(62)
+		ret = append(ret, tmp[index:index+1])
+	}
+	return strings.Join(ret, "")
+}
+
+//计算字符串和值
+func Sumstring(code string) (sum int) {
+	tmp := []rune(code)
+	for _, v := range tmp {
+		sum = sum + int(v)
+	}
+	return
+}
+
+//获取复杂的随机数
+func GetLetterRandom(length int, flag ...bool) string {
+	var idChars = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
+	var mod byte = 52
+	if len(flag) > 0 && flag[0] {
+		idChars = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
+		mod = 26
+	}
+	b := make([]byte, length)
+	maxrb := byte(256 - (256 % int(mod)))
+	i := 0
+EXIT:
+	for {
+		r := make([]byte, length+(length/4))
+		if _, err := io.ReadFull(cryptoRand.Reader, r); err != nil {
+			panic("captcha: error reading random source: " + err.Error())
+		}
+		for _, c := range r {
+			if c > maxrb {
+				continue
+			}
+			b[i] = c % mod
+			i++
+			if i == length {
+				break EXIT
+			}
+		}
+	}
+	for i, c := range b {
+		b[i] = idChars[c]
+	}
+	return string(b)
+}
+
+
+/*隐藏部分账号
+ *返回手机号:150...70765 邮箱:...shenjun@vip.qq.com
+ */
+func EncryCode(value string) string {
+	if len(value) == 0 {
+		return value
+	} else if strings.Contains(value, "@") {
+		start := strings.Index(value, "@") / 2
+		if start == 0 {
+			start++
+		}
+		value = "...." + string(value[start:])
+	} else {
+		value = string(value[0:3]) + "..." + string(value[len(value)-4:])
+	}
+	return value
+}
+
+//生成32位md5字串
+func GetMd5String(s string) string {
+	h := md5.New()
+	h.Write([]byte(s))
+	return hex.EncodeToString(h.Sum(nil))
+}
+
+//obj(string,M)转M,查询用到
+func ObjToMap(obj interface{}) *map[string]interface{} {
+	data := make(map[string]interface{})
+	if s, ok := obj.(string); ok {
+		json.Unmarshal([]byte(strings.Replace(s, "'", "\"", -1)), &data)
+	} else if s1, ok1 := obj.(map[string]interface{}); ok1 {
+		data = s1
+	} else if s1, ok1 := obj.(*map[string]interface{}); ok1 {
+		return s1
+	} else {
+		data = nil
+	}
+	return &data
+}
+
+/*UTC类型时间转字符串
+ *flag==true,日期格式yyyy-mm-dd hh:mm:ss
+ *flag==false,日期格式yyyy-mm-dd
+ */
+func LongToDate(date interface{}, flag bool) string {
+	var int64Date int64
+	if l1, ok1 := date.(float64); ok1 {
+		int64Date = int64(l1)
+	} else if l2, ok2 := date.(int64); ok2 {
+		int64Date = l2
+	} else if l3, ok3 := date.(int); ok3 {
+		int64Date = int64(l3)
+	}
+	t := time.Unix(int64Date, 0)
+	if flag {
+		return t.Format("2006-01-02 15:04:05")
+	} else {
+		return t.Format("2006-01-02")
+	}
+}
+
+func IntAll(num interface{}) int {
+	return IntAllDef(num, 0)
+}
+
+func Int64All(num interface{}) int64 {
+	if i, ok := num.(int64); ok {
+		return int64(i)
+	} else if i0, ok0 := num.(int32); ok0 {
+		return int64(i0)
+	} else if i1, ok1 := num.(float64); ok1 {
+		return int64(i1)
+	} else if i2, ok2 := num.(int); ok2 {
+		return int64(i2)
+	} else if i3, ok3 := num.(float32); ok3 {
+		return int64(i3)
+	} else if i4, ok4 := num.(string); ok4 {
+		i64, _ := strconv.ParseInt(i4, 10, 64)
+		//in, _ := strconv.Atoi(i4)
+		return i64
+	} else if i5, ok5 := num.(int16); ok5 {
+		return int64(i5)
+	} else if i6, ok6 := num.(int8); ok6 {
+		return int64(i6)
+	} else if i7, ok7 := num.(*big.Int); ok7 {
+		in, _ := strconv.ParseInt(fmt.Sprint(i7), 10, 64)
+		return int64(in)
+	} else if i8, ok8 := num.(*big.Float); ok8 {
+		in, _ := strconv.ParseInt(fmt.Sprint(i8), 10, 64)
+		return int64(in)
+	} else {
+		return 0
+	}
+}
+
+func Float64All(num interface{}) float64 {
+	if i, ok := num.(float64); ok {
+		return float64(i)
+	} else if i0, ok0 := num.(int32); ok0 {
+		return float64(i0)
+	} else if i1, ok1 := num.(int64); ok1 {
+		return float64(i1)
+	} else if i2, ok2 := num.(int); ok2 {
+		return float64(i2)
+	} else if i3, ok3 := num.(float32); ok3 {
+		return float64(i3)
+	} else if i4, ok4 := num.(string); ok4 {
+		in, _ := strconv.ParseFloat(i4, 64)
+		return in
+	} else if i5, ok5 := num.(int16); ok5 {
+		return float64(i5)
+	} else if i6, ok6 := num.(int8); ok6 {
+		return float64(i6)
+	} else if i6, ok6 := num.(uint); ok6 {
+		return float64(i6)
+	} else if i6, ok6 := num.(uint8); ok6 {
+		return float64(i6)
+	} else if i6, ok6 := num.(uint16); ok6 {
+		return float64(i6)
+	} else if i6, ok6 := num.(uint32); ok6 {
+		return float64(i6)
+	} else if i6, ok6 := num.(uint64); ok6 {
+		return float64(i6)
+	} else if i7, ok7 := num.(*big.Float); ok7 {
+		in, _ := strconv.ParseFloat(fmt.Sprint(i7), 64)
+		return float64(in)
+	} else if i8, ok8 := num.(*big.Int); ok8 {
+		in, _ := strconv.ParseFloat(fmt.Sprint(i8), 64)
+		return float64(in)
+	} else {
+		return 0
+	}
+}
+
+func IntAllDef(num interface{}, defaultNum int) int {
+	if i, ok := num.(int); ok {
+		return int(i)
+	} else if i0, ok0 := num.(int32); ok0 {
+		return int(i0)
+	} else if i1, ok1 := num.(float64); ok1 {
+		return int(i1)
+	} else if i2, ok2 := num.(int64); ok2 {
+		return int(i2)
+	} else if i3, ok3 := num.(float32); ok3 {
+		return int(i3)
+	} else if i4, ok4 := num.(string); ok4 {
+		in, _ := strconv.Atoi(i4)
+		return int(in)
+	} else if i5, ok5 := num.(int16); ok5 {
+		return int(i5)
+	} else if i6, ok6 := num.(int8); ok6 {
+		return int(i6)
+	} else if i7, ok7 := num.(*big.Int); ok7 {
+		in, _ := strconv.Atoi(fmt.Sprint(i7))
+		return int(in)
+	} else if i8, ok8 := num.(*big.Float); ok8 {
+		in, _ := strconv.Atoi(fmt.Sprint(i8))
+		return int(in)
+	} else {
+		return defaultNum
+	}
+}
+
+func ObjToString(old interface{}) string {
+	if nil == old {
+		return ""
+	} else {
+		r, _ := old.(string)
+		return r
+	}
+}
+
+func ObjToStringDef(old interface{}, defaultstr string) string {
+	if nil == old {
+		return defaultstr
+	} else {
+		r, _ := old.(string)
+		if r == "" {
+			return defaultstr
+		}
+		return r
+	}
+}
+
+//对象数组转成string数组
+func ObjArrToStringArr(old []interface{}) []string {
+	if old != nil {
+		new := make([]string, len(old))
+		for i, v := range old {
+			new[i], _ = v.(string)
+		}
+		return new
+	} else {
+		return nil
+	}
+}
+
+//对象数组转成map数组
+func ObjArrToMapArr(old []interface{}) []map[string]interface{} {
+	if old != nil {
+		new := make([]map[string]interface{}, len(old))
+		for i, v := range old {
+			new[i], _ = v.(map[string]interface{})
+		}
+		return new
+	} else {
+		return nil
+	}
+}
+
+//map数组转成对象数组
+func MapArrToObjArr(old []map[string]interface{}) []interface{} {
+	if old != nil {
+		new := make([]interface{}, len(old))
+		for i, v := range old {
+			new[i] = v
+		}
+		return new
+	} else {
+		return nil
+	}
+}
+
+func SubstrByByte(str string, length int) string {
+	bs := []byte(str)[:length]
+	bl := 0
+	for i := len(bs) - 1; i >= 0; i-- {
+		switch {
+		case bs[i] >= 0 && bs[i] <= 127:
+			return string(bs[:i+1])
+		case bs[i] >= 128 && bs[i] <= 191:
+			bl++
+		case bs[i] >= 192 && bs[i] <= 253:
+			cl := 0
+			switch {
+			case bs[i]&252 == 252:
+				cl = 6
+			case bs[i]&248 == 248:
+				cl = 5
+			case bs[i]&240 == 240:
+				cl = 4
+			case bs[i]&224 == 224:
+				cl = 3
+			default:
+				cl = 2
+			}
+			if bl+1 == cl {
+				return string(bs[:i+cl])
+			}
+			return string(bs[:i])
+		}
+	}
+	return ""
+}
+
+func SubString(str string, begin, length int) (substr string) {
+	// 将字符串的转换成[]rune
+	rs := []rune(str)
+	lth := len(rs)
+	// 简单的越界判断
+	if begin < 0 {
+		begin = 0
+	}
+	if begin >= lth {
+		begin = lth
+	}
+	end := begin + length
+	if end > lth {
+		end = lth
+	}
+
+	// 返回子串
+	return string(rs[begin:end])
+}
+
+//捕获异常
+func Try(fun func(), handler func(interface{})) {
+	defer func() {
+		if err := recover(); err != nil {
+			for skip := 1; ; skip++ {
+				_, file, line, ok := runtime.Caller(skip)
+				if !ok {
+					break
+				}
+				go log.Printf("%v,%v\n", file, line)
+			}
+			handler(err)
+		}
+	}()
+	fun()
+}
+
+//3目运算
+func If(b bool, to, fo interface{}) interface{} {
+	if b {
+		return to
+	} else {
+		return fo
+	}
+}
+
+//HashCode值
+func HashCode(uid string) int {
+	var h uint32 = 0
+	rs := []rune(uid)
+	for i := 0; i < len(rs); i++ {
+		h = 31*h + uint32(rs[i])
+	}
+	return int(h)
+}
+
+//获取离n天的秒差
+func GetDayStartSecond(n int) int64 {
+	now := time.Now()
+	tom := time.Date(now.Year(), now.Month(), now.Day()+n, 0, 0, 0, 0, time.Local)
+	return tom.Unix()
+}
+
+func InterfaceArrTointArr(arr []interface{}) []int {
+	tmp := make([]int, 0)
+	for _, v := range arr {
+		tmp = append(tmp, int(v.(float64)))
+	}
+	return tmp
+}
+func InterfaceArrToint64Arr(arr []interface{}) []int64 {
+	tmp := make([]int64, 0)
+	for _, v := range arr {
+		tmp = append(tmp, int64(v.(float64)))
+	}
+	return tmp
+}
+
+func GetSubDay(t1 int64) int {
+	tt1 := time.Unix(t1, 0)
+	tt2 := time.Now()
+	nt1 := time.Date(tt1.Year(), tt1.Month(), tt1.Day(), 0, 0, 0, 0, time.Local)
+	nt2 := time.Date(tt2.Year(), tt2.Month(), tt2.Day(), 0, 0, 0, 0, time.Local)
+	return int((nt1.Unix() - nt2.Unix()) / 86400)
+}
+func StartWith(value, str string) bool {
+	ok, _ := regexp.MatchString("^"+str, value)
+	return ok
+}
+func EndWith(value, str string) bool {
+	ok, _ := regexp.MatchString(str+"$", value)
+	return ok
+}
+
+//出错拦截
+func Catch() {
+	if r := recover(); r != nil {
+		log.Println(r)
+		for skip := 0; ; skip++ {
+			_, file, line, ok := runtime.Caller(skip)
+			if !ok {
+				break
+			}
+			go log.Printf("%v,%v\n", file, line)
+		}
+	}
+}
+
+func ConvertFileSize(s int) string {
+	size := float64(s)
+	var kb float64 = 1024
+	var mb float64 = kb * 1024
+	var gb float64 = mb * 1024
+	if size >= gb {
+		return fmt.Sprintf("%.1f GB", float64(size/gb))
+	} else if size >= mb {
+		f := float64(size / mb)
+		if f > 100 {
+			return fmt.Sprintf("%.0f MB", f)
+		}
+		return fmt.Sprintf("%.1f MB", f)
+	} else if size >= kb {
+		f := float64(size / kb)
+		if f > 100 {
+			return fmt.Sprintf("%.0f KB", f)
+		}
+		return fmt.Sprintf("%.1f KB", f)
+	}
+	return fmt.Sprintf("%d B", s)
+}
+
+//MD5签名
+func WxSign(format string, param ...interface{}) string {
+	data := fmt.Sprintf(format, param...)
+	h := md5.New()
+	h.Write([]byte(data))
+	sign := strings.ToUpper(hex.EncodeToString(h.Sum(nil)))
+	return sign
+}
+
+
+
+func FloatFormat(tmp float64, n int) float64 {
+	fs := fmt.Sprintf("%."+fmt.Sprint(n)+"f", tmp)
+	f, _ := strconv.ParseFloat(fs, 64)
+	return f
+}
+
+//生成微信支付的签名
+func CreateWxSign(afterStr string, obj interface{}, filter ...string) string {
+	filter = append(filter, "sign", "xml")
+	keys := []string{}
+	m := make(map[string]string)
+	t := reflect.TypeOf(obj)
+	v := reflect.ValueOf(obj)
+	k := t.Kind()
+	if t.Kind() == reflect.Ptr {
+		t = t.Elem()
+		k = t.Kind()
+		v = v.Elem()
+	}
+	if k == reflect.Map {
+		for _, key := range v.MapKeys() {
+			keys = append(keys, key.String())
+			m[key.String()] = fmt.Sprint(v.MapIndex(key).Interface())
+		}
+	} else if k == reflect.Struct {
+		for n := 0; n < t.NumField(); n++ {
+			tagName := t.Field(n).Tag.Get("xml")
+			if tagName == "" {
+				tagName = t.Field(n).Tag.Get("json")
+			}
+			if tagName == "" {
+				tagName = t.Field(n).Name
+			}
+			keys = append(keys, tagName)
+			m[tagName] = fmt.Sprint(v.Field(n))
+		}
+	}
+	sort.Strings(keys)
+	vs := []string{}
+L:
+	for _, v := range keys {
+		for _, f := range filter {
+			if f == v {
+				continue L
+			}
+		}
+		if strings.TrimSpace(m[v]) == "" {
+			continue
+		}
+		vs = append(vs, fmt.Sprintf("%s=%s", v, m[v]))
+	}
+	return WxSign(strings.Join(vs, "&") + afterStr)
+}
+
+//简单的xml转map,只有一个层级,没有多层嵌套
+func XmlToMap(input string) map[string]string {
+	var t xml.Token
+	var err error
+	inputReader := strings.NewReader(input)
+	decoder := xml.NewDecoder(inputReader)
+	isStart := false
+	nodeName := ""
+	m := make(map[string]string)
+	for t, err = decoder.Token(); err == nil; t, err = decoder.Token() {
+		switch token := t.(type) {
+		// 处理元素开始(标签)
+		case xml.StartElement:
+			isStart = true
+			nodeName = token.Name.Local
+		// 处理元素结束(标签)
+		case xml.EndElement:
+			isStart = false
+		// 处理字符数据(这里就是元素的文本)
+		case xml.CharData:
+			if isStart {
+				m[nodeName] = string([]byte(token))
+			}
+		default:
+			// ...
+		}
+	}
+	return m
+}
+
+func SimpleCrontab(flag bool, c string, f func()) {
+	array := strings.Split(c, ":")
+	if len(array) != 2 {
+		log.Fatalln("定时任务参数错误!", c)
+	}
+	if flag {
+		go f()
+	}
+	now := time.Now()
+	t := time.Date(now.Year(), now.Month(), now.Day(), IntAll(array[0]), IntAll(array[1]), 0, 0, time.Local)
+	if t.Before(now) {
+		t = t.AddDate(0, 0, 1)
+	}
+	sub := t.Sub(now)
+	log.Println(c, "run after", sub)
+	timer := time.NewTimer(sub)
+	for {
+		select {
+		case <-timer.C:
+			go f()
+			log.Println(c, "run after", 24*time.Hour)
+			timer.Reset(24 * time.Hour)
+		}
+	}
+}
+
+//v保留n为小数,n后的四舍五入
+func RetainDecimal(v float64, n int) float64 {
+	n10 := math.Pow10(n)
+	return math.Trunc((v+0.5/n10)*n10) / n10
+}