base_controller.go 6.4 KB
package controllers

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"strconv"
	"strings"

	"github.com/astaxie/beego/context"

	"github.com/astaxie/beego"
	"github.com/astaxie/beego/logs"

	userQuery "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/users/query"
	userService "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/users/service"
	"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/lib"
	"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/lib/exceltool"
	"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/port/beego/protocol"
)

type BaseController struct {
	beego.Controller
}

func (controller BaseController) BindJsonData(v interface{}) error {
	newDecoder := json.NewDecoder(bytes.NewReader(controller.Ctx.Input.RequestBody))
	newDecoder.UseNumber()
	err := newDecoder.Decode(v)
	return err
}

func (controller BaseController) ResponseError(err error) {
	if e, ok := err.(lib.ServiceError); ok {
		if !(e.Code == lib.ARG_ERROR || e.Code == lib.BUSINESS_ERROR) {
			controller.Data["json"] = protocol.ResponseData{
				Code: -1,
				Msg:  "操作失败",
				Data: struct{}{},
			}
			controller.ServeJSON()
			logs.Error(e.Prefix, e.Message)
			return
		} else {
			logs.Error(e.Prefix, e.Message)
		}
	}
	controller.Data["json"] = protocol.ResponseData{
		Code: -1,
		Msg:  err.Error(),
		Data: struct{}{},
	}
	controller.ServeJSON()
	logs.Error(err)
	return
}

func (controller BaseController) ResponseData(data interface{}) {
	if data == nil {
		data = struct{}{}
	}
	controller.Data["json"] = protocol.ResponseData{
		Code: 0,
		Msg:  "ok",
		Data: data,
	}
	controller.ServeJSON()
}

func (controller BaseController) ResponsePageList(data interface{}, totalRow int, pageNumber int) {
	if data == nil {
		data = []interface{}{}
	}
	// controller.Data["json"] = protocol.ResponseData{
	// 	Code: 0,
	// 	Msg:  "ok",
	// 	Data: map[string]map[string]interface{}{
	// 		"gridResult": map[string]interface{}{
	// 			"lists":      data,
	// 			"totalRow":   totalRow,
	// 			"pageNumber": pageNumber,
	// 		},
	// 	},
	// }
	controller.Data["json"] = protocol.ResponseData{
		Code: 0,
		Msg:  "ok",
		Data: map[string]map[string]interface{}{
			"grid": {
				"list":       data,
				"total":      totalRow,
				"pageNumber": pageNumber,
			},
		},
	}
	controller.ServeJSON()
}

// Finish 重写 beego.Controller 的Finish 方法
func (controller *BaseController) Finish() {
	strByte, _ := json.Marshal(controller.Data["json"])
	length := len(strByte)
	if length > 1500 {
		logs.Info("<====Send to client:  RspBodyData: ", string(strByte[:1500]))
	} else {
		logs.Info("<====Send to client:  RspBodyData: ", string(strByte))
	}
}

// //Prepare 重写 beego.Controller 的Prepare方法
func (controller *BaseController) Prepare() {
	logs.Info("====>Recv Request:", controller.Ctx.Input.URI())
	if controller.Ctx.Input.IsPost() || controller.Ctx.Input.IsPut() {
		bodyByte := controller.Ctx.Input.RequestBody
		if len(bodyByte) > 1000 {
			logs.Info("====>Recv data from client: BodyData: ", string(bodyByte[0:1000]))
		} else {
			logs.Info("====>Recv data from client: BodyData: ", string(bodyByte))
		}
	}
	return
}

func (controller *BaseController) GetHeaderToken() string {
	authString := controller.Ctx.Input.Header("Authorization")
	//解出需要的jwt串 例:头Authorization:Bearer 123token456
	s := strings.Split(authString, "\u0020")
	var tokenString string
	if len(s) > 0 {
		tokenString = s[len(s)-1]
	}
	return tokenString
}

func (controller *BaseController) ValidJWTToken() bool {
	headerToken := controller.GetHeaderToken()
	mytoken := new(lib.MyToken)
	tokenData, err := mytoken.ValidJWTToken(headerToken)
	if err != nil {
		logs.Error("校验token失败", err)
		if mytoken.IsJwtErrorExpired(err) {
			//token超时
			controller.Data["json"] = protocol.ResponseData{
				Code: 2,
				Msg:  "token过期,请重新登录",
				Data: struct{}{},
			}
			controller.ServeJSON()
		} else {
			controller.Data["json"] = protocol.ResponseData{
				Code: -1,
				Msg:  "token校验失败",
				Data: struct{}{},
			}
			controller.ServeJSON()
		}
		return false
	}
	controller.setUserId(tokenData.UID)
	controller.setUserCompanyId(tokenData.CompanyId)
	return true
}

func (controller *BaseController) ValidAdminPermission(permissionCode string, excludeURL ...string) bool {
	//排除掉的请求
	reqUrl := controller.Ctx.Input.URL()
	for i := range excludeURL {
		if reqUrl == excludeURL[i] {
			return true
		}
	}
	//权限校验
	userId := controller.GetUserId()
	if userId == 0 {
		controller.ResponseError(errors.New("无操作权限"))
		return false
	}
	comanyId := controller.GetUserCompany()
	newQuery := userQuery.ValidatePermissionQuery{
		UserId:         userId,
		PermissionCode: permissionCode,
		CompanyId:      comanyId,
	}
	newUserService := userService.NewUsersService(nil)
	ok, err := newUserService.ValidateAdminpPermission(newQuery)
	if err != nil {
		logs.Error("用户鉴权失败:%s", err)
		controller.ResponseError(errors.New("无操作权限"))
		return false
	}
	if ok {
		return true
	}
	controller.ResponseError(errors.New("无操作权限"))
	return false
}

func (controller *BaseController) GetUserId() int64 {
	idV := controller.Ctx.Input.GetData("token:admin_user_id")
	uid, _ := strconv.ParseInt(fmt.Sprint(idV), 10, 64)
	return uid
}

func (controller *BaseController) setUserId(id int64) {
	logs.Info("token:admin_user_id = ", id)
	controller.Ctx.Input.SetData("token:admin_user_id", id)
}

func (controller *BaseController) setUserCompanyId(id int64) {
	logs.Info("token:company_id = ", id)
	controller.Ctx.Input.SetData("token:company_id", id)
}

func (controller *BaseController) GetUserCompany() int64 {
	idV := controller.Ctx.Input.GetData("token:company_id")
	uid, err := strconv.ParseInt(fmt.Sprint(idV), 10, 64)
	if err != nil {
		logs.Error(err)
	}
	return uid
}

func (controller *BaseController) ResponseExcelByFile(ctx *context.Context, excelMaker *exceltool.ExcelMaker) error {
	fname := excelMaker.GetFileName()
	ctx.Output.Header("Content-Disposition", "attachment; filename="+fname)
	ctx.Output.Header("Content-Description", "File Transfer")
	ctx.Output.Header("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
	ctx.Output.Header("Content-Transfer-Encoding", "binary")
	ctx.Output.Header("Expires", "0")
	ctx.Output.Header("Cache-Control", "must-revalidate")
	ctx.Output.Header("Pragma", "public")
	//跳过保存文件,直接写入ctx.ResponseWriter
	excelMaker.Xlsx.Write(ctx.ResponseWriter)
	return nil
}