Browse Source

获取会议系统接口

huangyan 2 months ago
parent
commit
a2c7f36773

+ 3 - 0
cmd/server/wire/wire.go

@@ -23,6 +23,7 @@ var RepositorySet = wire.NewSet(
 	repository.NewUserRepository,
 	repository.NewUserRepository,
 	repository.NewAccessControlRepository,
 	repository.NewAccessControlRepository,
 	repository.NewHikvisionRepository,
 	repository.NewHikvisionRepository,
+	repository.NewConferenceRepository,
 )
 )
 
 
 var ServiceSet = wire.NewSet(
 var ServiceSet = wire.NewSet(
@@ -30,6 +31,7 @@ var ServiceSet = wire.NewSet(
 	service.NewUserService,
 	service.NewUserService,
 	service.NewAccessControlService,
 	service.NewAccessControlService,
 	service.NewHikvisionService,
 	service.NewHikvisionService,
+	service.NewConferenceService,
 )
 )
 
 
 var HandlerSet = wire.NewSet(
 var HandlerSet = wire.NewSet(
@@ -37,6 +39,7 @@ var HandlerSet = wire.NewSet(
 	handler.NewUserHandler,
 	handler.NewUserHandler,
 	handler.NewAccessControlHandler,
 	handler.NewAccessControlHandler,
 	handler.NewHikvisionHandler,
 	handler.NewHikvisionHandler,
+	handler.NewConferenceHandler,
 )
 )
 
 
 func NewWire(*viper.Viper, *log.Logger) (*gin.Engine, func(), error) {
 func NewWire(*viper.Viper, *log.Logger) (*gin.Engine, func(), error) {

+ 7 - 4
cmd/server/wire/wire_gen.go

@@ -31,7 +31,10 @@ func NewWire(viperViper *viper.Viper, logger *log.Logger) (*gin.Engine, func(),
 	hikvisionRepository := repository.NewHikvisionRepository(repositoryRepository)
 	hikvisionRepository := repository.NewHikvisionRepository(repositoryRepository)
 	hikvisionService := service.NewHikvisionService(serviceService, hikvisionRepository, viperViper)
 	hikvisionService := service.NewHikvisionService(serviceService, hikvisionRepository, viperViper)
 	hikvisionHandler := handler.NewHikvisionHandler(handlerHandler, hikvisionService, viperViper)
 	hikvisionHandler := handler.NewHikvisionHandler(handlerHandler, hikvisionService, viperViper)
-	engine := server.NewServerHTTP(logger, accessControlHandler, hikvisionHandler)
+	conferenceRepository := repository.NewConferenceRepository(repositoryRepository)
+	conferenceService := service.NewConferenceService(serviceService, conferenceRepository, viperViper)
+	conferenceHandler := handler.NewConferenceHandler(handlerHandler, conferenceService, viperViper)
+	engine := server.NewServerHTTP(logger, accessControlHandler, hikvisionHandler, conferenceHandler)
 	return engine, func() {
 	return engine, func() {
 	}, nil
 	}, nil
 }
 }
@@ -40,8 +43,8 @@ func NewWire(viperViper *viper.Viper, logger *log.Logger) (*gin.Engine, func(),
 
 
 var ServerSet = wire.NewSet(server.NewServerHTTP)
 var ServerSet = wire.NewSet(server.NewServerHTTP)
 
 
-var RepositorySet = wire.NewSet(repository.NewDb, repository.NewRedis, repository.NewRepository, repository.NewUserRepository, repository.NewAccessControlRepository, repository.NewHikvisionRepository)
+var RepositorySet = wire.NewSet(repository.NewDb, repository.NewRedis, repository.NewRepository, repository.NewUserRepository, repository.NewAccessControlRepository, repository.NewHikvisionRepository, repository.NewConferenceRepository)
 
 
-var ServiceSet = wire.NewSet(service.NewService, service.NewUserService, service.NewAccessControlService, service.NewHikvisionService)
+var ServiceSet = wire.NewSet(service.NewService, service.NewUserService, service.NewAccessControlService, service.NewHikvisionService, service.NewConferenceService)
 
 
-var HandlerSet = wire.NewSet(handler.NewHandler, handler.NewUserHandler, handler.NewAccessControlHandler, handler.NewHikvisionHandler)
+var HandlerSet = wire.NewSet(handler.NewHandler, handler.NewUserHandler, handler.NewAccessControlHandler, handler.NewHikvisionHandler, handler.NewConferenceHandler)

+ 11 - 0
config/local.yml

@@ -44,3 +44,14 @@ hikvision:
     deviceResource: "/api/irds/v2/deviceResource/resources" #根据资源类型分页获取资源列表,主要用于资源信息的全量同步。
     deviceResource: "/api/irds/v2/deviceResource/resources" #根据资源类型分页获取资源列表,主要用于资源信息的全量同步。
     cameras: "/api/resource/v1/cameras"#分页获取监控点资源获取监控点列表接口可用来全量同步监控点信息,返回结果分页展示。
     cameras: "/api/resource/v1/cameras"#分页获取监控点资源获取监控点列表接口可用来全量同步监控点信息,返回结果分页展示。
     previewURLs: "/api/video/v2/cameras/previewURLs"#获取监控点预览取流URLv2
     previewURLs: "/api/video/v2/cameras/previewURLs"#获取监控点预览取流URLv2
+    controlling: "/api/video/v1/ptzs/controlling" #根据监控点编号进行云台操作接口
+    visitorInfo: "/api/v1/visitorInfo/count" #获取今日访客信息包含:今日来访总人数(已签离人数,未签离人数),预约人数
+#会议系统
+conference:
+  mobile: "14000000000"
+  password: "admin@123456"
+  baseurl: "http://183.129.224.253:9998/api"
+  getPublicKey: "/getPublicKey"
+  login: "/login"
+  roomOps: "/ops/statistic/roomOps" #获取会议概要
+  dataAnalysis: "/dataAnalysis" #数据大屏

+ 54 - 0
internal/handler/conference.go

@@ -0,0 +1,54 @@
+package handler
+
+import (
+	"city_chips/internal/service"
+	"city_chips/pkg/helper/resp"
+	"github.com/gin-gonic/gin"
+	"github.com/spf13/viper"
+	"github.com/tidwall/gjson"
+	"net/http"
+)
+
+type ConferenceHandler struct {
+	*Handler
+	conferenceService service.ConferenceService
+	conf              *viper.Viper
+}
+
+func NewConferenceHandler(handler *Handler, conferenceService service.ConferenceService, conf *viper.Viper) *ConferenceHandler {
+	return &ConferenceHandler{
+		Handler:           handler,
+		conferenceService: conferenceService,
+		conf:              conf,
+	}
+}
+
+// RoomOps 会议室运维概览统计数据
+func (h *ConferenceHandler) RoomOps(ctx *gin.Context) {
+	roomOpsurl := h.conf.GetString("conference.baseurl") + h.conf.GetString("conference.roomOps")
+	request, err := h.conferenceService.SendRequest(http.DefaultClient, "GET", roomOpsurl, nil)
+	if err != nil {
+		resp.HandleError(ctx, 1203, "获取会议概要失败", nil)
+		return
+	}
+	if gjson.Get(string(request), "code").Int() == 0 {
+		s := gjson.Get(string(request), "data").String()
+		resp.HandleSuccess(ctx, s)
+		return
+	}
+	resp.HandleError(ctx, 1203, "获取会议概要失败", nil)
+}
+func (h *ConferenceHandler) DataAnalysis(ctx *gin.Context) {
+	dataAnalysisurl := h.conf.GetString("conference.baseurl") + h.conf.GetString("conference.dataAnalysis")
+	request, err := h.conferenceService.SendRequest(http.DefaultClient, "GET", dataAnalysisurl, nil)
+	if err != nil {
+		resp.HandleError(ctx, 1203, "获取数据大屏信息失败", nil)
+		return
+	}
+	if gjson.Get(string(request), "code").Int() == 0 {
+		s := gjson.Get(string(request), "data").String()
+		resp.HandleSuccess(ctx, s)
+		return
+	}
+	resp.HandleError(ctx, 1203, "获取数据大屏信息失败", nil)
+}

+ 143 - 0
internal/handler/hikvision.go

@@ -0,0 +1,143 @@
+package handler
+
+import (
+	"city_chips/internal/service"
+	"city_chips/pkg/helper/resp"
+	"encoding/json"
+	"fmt"
+	"github.com/gin-gonic/gin"
+	"github.com/spf13/viper"
+	"github.com/tidwall/gjson"
+	"strconv"
+)
+
+type HikvisionHandler struct {
+	*Handler
+	hikvisionService service.HikvisionService
+	conf             *viper.Viper
+}
+
+func NewHikvisionHandler(handler *Handler, hikvisionService service.HikvisionService, conf *viper.Viper) *HikvisionHandler {
+	return &HikvisionHandler{
+		Handler:          handler,
+		hikvisionService: hikvisionService,
+		conf:             conf,
+	}
+}
+
+//	GetHikvisionMonitoring 获取视频监控流{
+//		   "cameraIndexCode": "748d84750e3a4a5bbad3cd4af9ed5101",
+//		   "streamType": 0,
+//		   "protocol": "rtsp",
+//		   "transmode": 1,
+//		   "expand": "transcode=0",
+//		   "streamform": "ps"
+//		}
+func (h *HikvisionHandler) GetHikvisionMonitoring(ctx *gin.Context) {
+	m := make(map[string]string)
+	cameraIndexCode := ctx.Query("cameraIndexCode")
+	m["cameraIndexCode"] = cameraIndexCode
+	m["streamType"] = "0"
+	m["protocol"] = "rtsp"
+	m["transmode"] = "1"
+	m["expand"] = "transcode=0"
+	m["streamform"] = "ps"
+	if len(cameraIndexCode) <= 0 || cameraIndexCode == "" {
+		resp.HandleError(ctx, 1203, "设备编码不能为空", nil)
+		return
+	}
+	fmt.Println(m)
+	resp.HandleSuccess(ctx, "rtsp://10.2.145.66:655/EUrl/CLJ52BW")
+	return
+	hikvision, err := h.hikvisionService.Hikvision(h.conf.GetString("hikvision.api.cameras"), m, 15)
+	//返回结果{
+	//    "code": "0",
+	//    "msg": "success",
+	//    "data": {
+	//        "url": "rtsp://10.2.145.66:655/EUrl/CLJ52BW"
+	//    }
+	//}
+	if err != nil {
+		h.logger.Error("获取获取监控点资源失败")
+		resp.HandleError(ctx, 1201, "获取获取监控点资源失败", err)
+		return
+	}
+	if hikvision.Code != "0" {
+		atoi, _ := strconv.Atoi(hikvision.Code)
+		resp.HandleError(ctx, atoi, hikvision.Msg, nil)
+		return
+	}
+	marshalString, err := json.Marshal(hikvision)
+	if err != nil {
+		resp.HandleError(ctx, 1202, "json序列化失败", nil)
+		return
+	}
+	url := gjson.Get(string(marshalString), "data.url")
+	resp.HandleSuccess(ctx, url)
+}
+
+// 视频监控云台控制{
+//    "cameraIndexCode": "748d84750e3a4a5bbad3cd4af9ed5101",
+//    "action": 1, 0-开始
+//1-停止
+//注:GOTO_PRESET命令下填任意值均可转到预置点,建议填0即可
+//    "command": "GOTO_PRESET",
+//    "speed": 4,
+//    "presetIndex": 20
+//}
+
+func (h *HikvisionHandler) Gimbalcontrol(ctx *gin.Context) {
+	m := make(map[string]string)
+	cameraIndexCode := ctx.Query("cameraIndexCode")
+	command := ctx.Query("command")
+	action := ctx.Query("action")
+	speed := ctx.Query("speed")
+	presetIndex := ctx.Query("presetIndex")
+	m["cameraIndexCode"] = cameraIndexCode
+	m["action"] = action
+	m["command"] = command
+	m["speed"] = speed
+	m["presetIndex"] = presetIndex
+	if len(cameraIndexCode) <= 0 || len(command) <= 0 || len(action) <= 0 {
+		resp.HandleError(ctx, 1203, "设备编码不能为空", nil)
+		return
+	}
+
+	resp.HandleSuccess(ctx, m)
+	return
+	hikvision, err := h.hikvisionService.Hikvision(h.conf.GetString("hikvision.api.controlling"), m, 15)
+
+	if err != nil {
+		h.logger.Error("控制云台失败")
+		resp.HandleError(ctx, 1201, "控制云台失败", err)
+		return
+	}
+	if hikvision.Code != "0" {
+		atoi, _ := strconv.Atoi(hikvision.Code)
+		resp.HandleError(ctx, atoi, hikvision.Msg, nil)
+		return
+	}
+	resp.HandleSuccess(ctx, hikvision.Msg)
+}
+
+// VisitorInfoCount 获取今日访客信息包含:今日来访总人数(已签离人数,未签离人数),预约人数
+func (h *HikvisionHandler) VisitorInfoCount(c *gin.Context) {
+	m := make(map[string]string)
+	parkId := c.Query("parkId")
+	m["parkId"] = parkId
+	resp.HandleSuccess(c, "appointmentTotal: 1,    notSignOutTotal: 1,       signOutTotal: 1,        signTotal: 1,      orderCount: 1,        visitCount: 1,        visitCountForTemp: 1,  visitCountForOrder: 1,        signOutCount: 1,       notSignOutCount: 1")
+	return
+	hikvision, err := h.hikvisionService.Hikvision(h.conf.GetString("hikvision.api.visitorInfo"), m, 15)
+
+	if err != nil {
+		h.logger.Error("获取访客信息失败")
+		resp.HandleError(c, 1201, "获取访客信息失败", err)
+		return
+	}
+	if hikvision.Code != "0" {
+		atoi, _ := strconv.Atoi(hikvision.Code)
+		resp.HandleError(c, atoi, hikvision.Msg, nil)
+		return
+	}
+	resp.HandleSuccess(c, hikvision.Data)
+}

+ 11 - 0
internal/model/conference.go

@@ -0,0 +1,11 @@
+package model
+
+import "gorm.io/gorm"
+
+type Conference struct {
+	gorm.Model
+}
+
+func (m *Conference) TableName() string {
+	return "conference"
+}

+ 11 - 0
internal/model/hikvision.go

@@ -0,0 +1,11 @@
+package model
+
+import "gorm.io/gorm"
+
+type Hikvision struct {
+	gorm.Model
+}
+
+func (m *Hikvision) TableName() string {
+	return "hikvision"
+}

+ 28 - 0
internal/repository/conference.go

@@ -0,0 +1,28 @@
+package repository
+
+import (
+	"city_chips/internal/model"
+	
+)
+
+type ConferenceRepository interface {
+	GetConference(ctx context.Context, id int64) (*model.Conference, error)
+}
+
+func NewConferenceRepository(
+	repository *Repository,
+) ConferenceRepository {
+	return &conferenceRepository{
+		Repository: repository,
+	}
+}
+
+type conferenceRepository struct {
+	*Repository
+}
+
+func (r *conferenceRepository) GetConference(ctx context.Context, id int64) (*model.Conference, error) {
+	var conference model.Conference
+
+	return &conference, nil
+}

+ 26 - 0
internal/repository/hikvision.go

@@ -0,0 +1,26 @@
+package repository
+
+import (
+	"city_chips/internal/model"
+	"context"
+)
+
+type HikvisionRepository interface {
+	GetHikvision(ctx context.Context, id int64) (*model.Hikvision, error)
+}
+
+func NewHikvisionRepository(repository *Repository) HikvisionRepository {
+	return &hikvisionRepository{
+		Repository: repository,
+	}
+}
+
+type hikvisionRepository struct {
+	*Repository
+}
+
+func (r *hikvisionRepository) GetHikvision(ctx context.Context, id int64) (*model.Hikvision, error) {
+	var hikvision model.Hikvision
+
+	return &hikvision, nil
+}

+ 9 - 2
internal/server/http.go

@@ -7,7 +7,7 @@ import (
 	"github.com/gin-gonic/gin"
 	"github.com/gin-gonic/gin"
 )
 )
 
 
-func NewServerHTTP(logger *log.Logger, accessHandler *handler.AccessControlHandler, hikvision *handler.HikvisionHandler) *gin.Engine {
+func NewServerHTTP(logger *log.Logger, accessHandler *handler.AccessControlHandler, hikvision *handler.HikvisionHandler, conference *handler.ConferenceHandler) *gin.Engine {
 	gin.SetMode(gin.ReleaseMode)
 	gin.SetMode(gin.ReleaseMode)
 	r := gin.Default()
 	r := gin.Default()
 	r.Use(
 	r.Use(
@@ -22,7 +22,14 @@ func NewServerHTTP(logger *log.Logger, accessHandler *handler.AccessControlHandl
 	Hikvision := r.Group("/Hikvision")
 	Hikvision := r.Group("/Hikvision")
 	{
 	{
 		Hikvision.GET("/getMonitoring", hikvision.GetHikvisionMonitoring)
 		Hikvision.GET("/getMonitoring", hikvision.GetHikvisionMonitoring)
+		Hikvision.GET("/controlling", hikvision.Gimbalcontrol)
+		Hikvision.GET("/visitorInfo", hikvision.VisitorInfoCount)
+	}
+	//会议系统
+	Conference := r.Group("/Conference")
+	{
+		Conference.GET("/roomOps", conference.RoomOps)
+		Conference.GET("/dataAnalysis", conference.DataAnalysis)
 	}
 	}
-
 	return r
 	return r
 }
 }

+ 122 - 0
internal/service/conference.go

@@ -0,0 +1,122 @@
+package service
+
+import (
+	"bytes"
+	"city_chips/internal/repository"
+	"city_chips/pkg/helper/rsaEncrypt"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"github.com/spf13/viper"
+	"github.com/tidwall/gjson"
+	"io"
+	"io/ioutil"
+	"net/http"
+)
+
+type ConferenceService interface {
+	GetToken() (string, error)
+	SendRequest(client HTTPClient, method, url string, body interface{}) ([]byte, error)
+}
+
+func NewConferenceService(service *Service, conferenceRepository repository.ConferenceRepository, conf *viper.Viper) ConferenceService {
+	return &conferenceService{
+		Service:              service,
+		conferenceRepository: conferenceRepository,
+		conf:                 conf,
+	}
+}
+
+type conferenceService struct {
+	*Service
+	conferenceRepository repository.ConferenceRepository
+	conf                 *viper.Viper
+}
+type HTTPClient interface {
+	Do(req *http.Request) (*http.Response, error)
+}
+
+// SendRequest 发送HTTP请求,并返回响应数据或错误信息。
+func (s *conferenceService) SendRequest(client HTTPClient, method, url string, body interface{}) ([]byte, error) {
+	token, err := s.GetToken()
+	if err != nil {
+		return nil, err
+	}
+	token = "Bearer " + token
+	var requestBody io.Reader
+
+	if body != nil {
+		jsonBytes, err := json.Marshal(body)
+		if err != nil {
+			return nil, err
+		}
+		requestBody = bytes.NewBuffer(jsonBytes)
+	}
+
+	req, err := http.NewRequest(method, url, requestBody)
+	if err != nil {
+		return nil, err
+	}
+	// 设置请求头
+	req.Header.Set("Content-Type", "application/json")
+	if token != "" {
+		req.Header.Set("Authorization", token)
+	}
+
+	resp, err := client.Do(req)
+	if err != nil {
+		return nil, err
+	}
+	defer resp.Body.Close()
+
+	responseBody, err := io.ReadAll(resp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	if resp.StatusCode >= 400 {
+		return nil, fmt.Errorf("bad status: %s", resp.Status)
+	}
+
+	return responseBody, nil
+}
+
+func (s *conferenceService) GetToken() (string, error) {
+	baseUrl := s.conf.GetString("conference.baseurl")
+	getPublicKey := baseUrl + s.conf.GetString("conference.getPublicKey")
+	login := baseUrl + s.conf.GetString("conference.login")
+	// 准备登录数据
+	s.conf.GetString("conference.mobile")
+	loginData := map[string]string{
+		"mobile":   s.conf.GetString("conference.mobile"),
+		"password": s.conf.GetString("conference.password"),
+	}
+	jsonStr, err := json.Marshal(loginData)
+	if err != nil {
+		return "", nil
+	}
+	token, err := rsaEncrypt.GetToken(getPublicKey, jsonStr)
+
+	// 构造请求参数
+	data := map[string]string{
+		"admin":       "0",
+		"client_type": "web",
+		"secret":      token,
+	}
+	jsonData, _ := json.Marshal(data)
+	// 发送登录请求
+	resp, err := http.Post(login, "application/json", bytes.NewBuffer(jsonData))
+	if err != nil {
+		return "", err
+	}
+	defer resp.Body.Close()
+	body, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		return "", err
+	}
+	if gjson.Get(string(body), "code").Int() == 0 {
+		s := gjson.Get(string(body), "data.token").String()
+		return s, nil
+	}
+	return "", errors.New("获取token失败")
+}

+ 38 - 0
internal/service/hikvision.go

@@ -0,0 +1,38 @@
+package service
+
+import (
+	"city_chips/internal/repository"
+	"github.com/spf13/viper"
+	"github.com/zxbit2011/hikvisionOpenAPIGo"
+)
+
+type HikvisionService interface {
+	Hikvision(url string, body map[string]string, timeout int) (hikvisionOpenAPIGo.Result, error)
+}
+
+func NewHikvisionService(service *Service, hikvisionRepository repository.HikvisionRepository, conf *viper.Viper) HikvisionService {
+	return &hikvisionService{
+		Service:             service,
+		hikvisionRepository: hikvisionRepository,
+		conf:                conf,
+	}
+}
+
+type hikvisionService struct {
+	*Service
+	hikvisionRepository repository.HikvisionRepository
+	conf                *viper.Viper
+}
+
+// Hikvision 海康威视对接
+func (s *hikvisionService) Hikvision(url string, body map[string]string, timeout int) (hikvisionOpenAPIGo.Result, error) {
+	config := hikvisionOpenAPIGo.HKConfig{
+		Ip:      s.conf.GetString("hikvision.Ip"),
+		Port:    s.conf.GetInt("hikvision.Port"),
+		AppKey:  s.conf.GetString("hikvision.AppKey"),
+		Secret:  s.conf.GetString("hikvision.Secret"),
+		IsHttps: s.conf.GetBool("hikvision.IsHttps"),
+	}
+	result, err := config.HttpPost(url, body, timeout)
+	return result, err
+}

+ 81 - 0
pkg/helper/rsaEncrypt/rsa.go

@@ -0,0 +1,81 @@
+package rsaEncrypt
+
+import (
+	"crypto/rand"
+	"crypto/rsa"
+	"crypto/x509"
+	"encoding/base64"
+	"encoding/pem"
+	"errors"
+	"fmt"
+	"github.com/tidwall/gjson"
+	"io/ioutil"
+	"net/http"
+)
+
+// GetPublicKey 获取公钥的函数
+func GetPublicKey(url string) (string, error) {
+	resp, err := http.Get(url) // 请替换为实际的获取公钥接口URL
+	if err != nil {
+		return "", err
+	}
+	defer resp.Body.Close()
+	body, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		return "", err
+	}
+
+	if gjson.Get(string(body), "code").Int() == 0 {
+		s := gjson.Get(string(body), "data.public_key").String()
+		return s, nil
+	}
+
+	return "", errors.New("未获取到公钥信息")
+}
+
+// ParseRSAPublicKeyFromPEM 解析公钥
+func ParseRSAPublicKeyFromPEM(pubPEM string) (*rsa.PublicKey, error) {
+	block, _ := pem.Decode([]byte(pubPEM))
+	if block == nil || block.Type != "PUBLIC KEY" {
+		return nil, fmt.Errorf("failed to decode PEM block containing public key")
+	}
+
+	pub, err := x509.ParsePKIXPublicKey(block.Bytes)
+	if err != nil {
+		return nil, err
+	}
+
+	switch pub := pub.(type) {
+	case *rsa.PublicKey:
+		return pub, nil
+	default:
+		return nil, fmt.Errorf("not an RSA key")
+	}
+}
+
+// RsaEncrypt 使用RSA公钥加密
+func RsaEncrypt(publicKey *rsa.PublicKey, plainText []byte) (string, error) {
+	encryptedData, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, plainText)
+	if err != nil {
+		return "", err
+	}
+	return base64.StdEncoding.EncodeToString(encryptedData), nil
+}
+func GetToken(url string, plainText []byte) (string, error) {
+	// 获取公钥
+	publicKeyPEM, err := GetPublicKey(url)
+	if err != nil {
+		return "", err
+	}
+	// 解析公钥
+	publicKey, err := ParseRSAPublicKeyFromPEM(publicKeyPEM)
+	if err != nil {
+		return "", err
+	}
+	// 加密数据
+	encryptedData, err := RsaEncrypt(publicKey, plainText)
+	if err != nil {
+		return "", err
+	}
+	return encryptedData, nil
+}