基于Go开发PaaS平台3

Go开发PaaS平台核心功能

代码仓库地址GitHub - yunixiangfeng/gopaas

10-18 中间件前端页面以及核心API开发(中)

C:\Users\Administrator\Desktop\gopaas\middlewareapi\handler\middlewareApiHandler.go

package handler

import (
	"context"
	"encoding/json"
	"errors"
	"strconv"

	log "github.com/asim/go-micro/v3/logger"
	"ithub.com/yunixiangfeng/gopaas/middlewareApi/plugin/form"
	"github.com/yunixiangfeng/gopaas/common"
	middleware "github.com/yunixiangfeng/gopaas/middleware/proto/middleware"
	middlewareApi "github.com/yunixiangfeng/gopaas/middlewareApi/proto/middlewareApi"
)

type MiddlewareApi struct{
    MiddlewareService middleware.MiddlewareService
}


// middlewareApi.FindMiddlewareById 通过API向外暴露为/middlewareApi/findMiddlewareById,接收http请求
// 即:/middlewareApi/FindMiddlewareById 请求会调用go.micro.api.middlewareApi 服务的middlewareApi.FindMiddlewareById 方法
func (e *MiddlewareApi) FindMiddlewareById(ctx context.Context, req *middlewareApi.Request, rsp *middlewareApi.Response) error {
	log.Info("Received middlewareApi.FindMiddlewareById request")
	if _,ok:=req.Get["middle_id"];!ok{
		return errors.New("参数异常!")
	}
	idString := req.Get["middle_id"].Values[0]
	id,err := strconv.ParseInt(idString,10,64)
	if err != nil {
		common.Error(err)
		return err
	}
	middleInfo,err:=e.MiddlewareService.FindMiddlewareByID(ctx,&middleware.MiddlewareId{Id:id})
	rsp.StatusCode = 200
	b, _ := json.Marshal(middleInfo)
	rsp.Body = string(b)
	return nil
}

// middlewareApi.AddMiddleware 通过API向外暴露为/middlewareApi/AddMiddleware,接收http请求
// 即:/middlewareApi/AddMiddleware 请求会调用go.micro.api.middlewareApi 服务的middlewareApi.AddMiddleware 方法
func (e *MiddlewareApi) AddMiddleware(ctx context.Context, req *middlewareApi.Request, rsp *middlewareApi.Response) error {
	log.Info("Received middlewareApi.AddMiddleware request")
	addMiddleInfo := &middleware.MiddlewareInfo{}
	//设置端口
	port,err := e.setMiddlePort(req)
	if err != nil {
		common.Error(err)
		return err
	}
	addMiddleInfo.MiddlePort = port

	//设置环境变量
	addMiddleInfo.MiddleEnv = e.setMiddleEnv(req)

	//设置存储
	addMiddleInfo.MiddleStorage = e.setMiddleStorage(req)

	//获取类型
	middleTypeInfo := e.getMiddleType(req)

	//判断不同的类型设置不同的值
	switch middleTypeInfo.MiddleTypeName {
	case "MYSQL":
		middleConfig := e.setMiddleConfig(req)
		addMiddleInfo.MiddleConfig = &middleConfig
	}

	//处理表单
	form.FormToMiddlewareStruct(req.Post,addMiddleInfo)
	//调用后端服务添加数据
	response,err := e.MiddlewareService.AddMiddleware(ctx,addMiddleInfo)
	if err != nil {
		common.Error(err)
		return err
	}
	rsp.StatusCode = 200
	b, _ := json.Marshal(response)
	rsp.Body = string(b)
	return nil
}

//设置mysql config 设置
func (e *MiddlewareApi) setMiddleConfig(req *middlewareApi.Request)(middleConfig middleware.MiddleConfig) {
	middleConfig.MiddleConfigRootUser = e.getValue(req,"middle_config_root_user")
	middleConfig.MiddleConfigRootPwd = e.getValue(req,"middle_config_root_pwd")
	middleConfig.MiddleConfigUser = e.getValue(req,"middle_config_user")
	middleConfig.MiddleConfigPwd = e.getValue(req,"middle_config_pwd")
	middleConfig.MiddleConfigDataBase = e.getValue(req,"middle_config_data_base")
	return
}

file:///home/gopath/src/gopaas/go-paas-front/middleware-create.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="description" content="">
    <meta name="author" content="">
    <link rel="shortcut icon" href="assets/img/logo-fav.png">
    <title>CPaaS</title>
    <link rel="stylesheet" type="text/css" href="assets/lib/perfect-scrollbar/css/perfect-scrollbar.min.css"/>
    <link rel="stylesheet" type="text/css" href="assets/lib/material-design-icons/css/material-design-iconic-font.min.css"/><!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
    <link rel="stylesheet" type="text/css" href="assets/lib/datatables/css/dataTables.bootstrap.min.css"/>
    <link rel="stylesheet" href="assets/css/style.css" type="text/css"/>
  </head>
  <body>
    <div class="be-wrapper">
      <nav class="navbar navbar-default navbar-fixed-top be-top-header">
        <div class="container-fluid">
          <div class="navbar-header"><a href="index.html" class="navbar-brand"></a>
          </div>
          <div class="be-right-navbar">
            <ul class="nav navbar-nav navbar-right be-user-nav">
              <li class="dropdown"><a href="#" data-toggle="dropdown" role="button" aria-expanded="false" class="dropdown-toggle"><img src="assets/img/avatar.png" alt="Avatar"><span class="user-name">Túpac Amaru</span></a>
                <ul role="menu" class="dropdown-menu">
                  <li>
                    <div class="user-info">
                      <div class="user-name">wu123</div>
                      <div class="user-position online">在线</div>
                    </div>
                  </li>
                  <li><a href="#"><span class="icon mdi mdi-face"></span> 账户</a></li>
                  <li><a href="#"><span class="icon mdi mdi-settings"></span> 设置</a></li>
                  <li><a href="#"><span class="icon mdi mdi-power"></span> 推出登录</a></li>
                </ul>
              </li>
            </ul>
            <div class="page-title"></div>
            <ul class="nav navbar-nav navbar-right be-icons-nav">
              <li class="dropdown"><a href="#" role="button" aria-expanded="false" class="be-toggle-right-sidebar"><span class="icon mdi mdi-settings"></span></a></li>
              <li class="dropdown"><a href="#" data-toggle="dropdown" role="button" aria-expanded="false" class="dropdown-toggle"><span class="icon mdi mdi-notifications"></span><span class="indicator"></span></a>
                <ul class="dropdown-menu be-notifications">
                  <li>
                    <div class="title">消息提醒<span class="badge">3</span></div>
                    <div class="list">
                      <div class="be-scroller">
                        <div class="content">
                          <ul>
                            <li class="notification notification-unread"><a href="#">
                                <div class="image"><img src="assets/img/avatar2.png" alt="Avatar"></div>
                                <div class="notification-info">
                                  <div class="text"><span class="user-name">Jessica Caruso</span> accepted your invitation to join the team.</div><span class="date">2 min ago</span>
                                </div></a></li>
                            <li class="notification"><a href="#">
                                <div class="image"><img src="assets/img/avatar3.png" alt="Avatar"></div>
                                <div class="notification-info">
                                  <div class="text"><span class="user-name">Joel King</span> is now following you</div><span class="date">2 days ago</span>
                                </div></a></li>
                            <li class="notification"><a href="#">
                                <div class="image"><img src="assets/img/avatar4.png" alt="Avatar"></div>
                                <div class="notification-info">
                                  <div class="text"><span class="user-name">John Doe</span> is watching your main repository</div><span class="date">2 days ago</span>
                                </div></a></li>
                            <li class="notification"><a href="#">
                                <div class="image"><img src="assets/img/avatar5.png" alt="Avatar"></div>
                                <div class="notification-info"><span class="text"><span class="user-name">Emily Carter</span> is now following you</span><span class="date">5 days ago</span></div></a></li>
                          </ul>
                        </div>
                      </div>
                    </div>
                    <div class="footer"> <a href="#">View all notifications</a></div>
                  </li>
                </ul>
              </li>
              <li class="dropdown"><a href="#" data-toggle="dropdown" role="button" aria-expanded="false" class="dropdown-toggle"><span class="icon mdi mdi-apps"></span></a>
                <ul class="dropdown-menu be-connections">
                  <li>
                    <div class="list">
                      <div class="content">
                        <div class="row">
                          <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/github.png" alt="Github"><span>GitHub</span></a></div>
                          <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/bitbucket.png" alt="Bitbucket"><span>Bitbucket</span></a></div>
                          <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/slack.png" alt="Slack"><span>Slack</span></a></div>
                        </div>
                        <div class="row">
                          <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/dribbble.png" alt="Dribbble"><span>Dribbble</span></a></div>
                          <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/mail_chimp.png" alt="Mail Chimp"><span>Mail Chimp</span></a></div>
                          <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/dropbox.png" alt="Dropbox"><span>Dropbox</span></a></div>
                        </div>
                      </div>
                    </div>
                    <div class="footer"> <a href="#">More</a></div>
                  </li>
                </ul>
              </li>
            </ul>
          </div>
        </div>
      </nav>
<!--
  侧边栏-开始
-->
<div class="be-left-sidebar">
  <div class="left-sidebar-wrapper"><a href="#" class="left-sidebar-toggle">看版</a>
    <div class="left-sidebar-spacer">
      <div class="left-sidebar-scroll">
        <div class="left-sidebar-content">
          <ul class="sidebar-elements">
            <li class="divider">菜单</li>
            <li class="parent"><a href="#"><i class="icon mdi mdi-home"></i><span>控制台</span></a>
            </li>
            <li class="parent"><a href="#"><i class="icon mdi mdi-face"></i><span>应用管理</span></a>
              <ul class="sub-menu">
                <li ><a href="pod-index.html">添加应用</a>
                </li>
              </ul>
            </li>
            <li class="parent"><a href="charts.html"><i class="icon mdi mdi-chart-donut"></i><span>服务管理</span></a>
              <ul class="sub-menu">
                <li ><a href="svc-index.html">添加服务</a>
                </li>
              </ul>
            </li>
            <li class="parent"><a href="#"><i class="icon mdi mdi-dot-circle"></i><span>域名管理</span></a>
              <ul class="sub-menu">
                <li  ><a href="route-index.html">添加路由</a>
                </li>
              </ul>
            </li>
            <li class="parent"><a href="#"><i class="icon mdi mdi-dot-circle"></i><span>中间件</span></a>
              <ul class="sub-menu">
                <li class="active"><a href="middleware-create.html">创建中间件</a>
                </li>
              </ul>
            </li>
            <li class="parent"><a href="#"><i class="icon mdi mdi-border-all"></i><span>中间件</span></a>
              <ul class="sub-menu">
                <li><a href="tables-general.html">General</a>
                </li>
                <li><a href="tables-datatables.html">Data Tables</a>
                </li>
                <li><a href="tables-filters.html"><span class="label label-primary pull-right">New</span>Table Filters</a>
                </li>
              </ul>
            </li>
            <li class="parent"><a href="#"><i class="icon mdi mdi-layers"></i><span>应用市场</span></a>
              <ul class="sub-menu">
                <li><a href="pages-blank.html">Blank Page</a>
                </li>
                <li><a href="pages-blank-header.html">Blank Page Header</a>
                </li>
                <li><a href="pages-login.html">Login</a>
                </li>
                <li><a href="pages-login2.html">Login v2</a>
                </li>
                <li><a href="pages-404.html">404 Page</a>
                </li>
                <li><a href="pages-sign-up.html">Sign Up</a>
                </li>
                <li><a href="pages-forgot-password.html">Forgot Password</a>
                </li>
                <li><a href="pages-profile.html">Profile</a>
                </li>
                <li><a href="pages-pricing-tables.html">Pricing Tables</a>
                </li>
                <li><a href="pages-pricing-tables2.html">Pricing Tables v2</a>
                </li>
                <li><a href="pages-timeline.html">Timeline</a>
                </li>
                <li><a href="pages-timeline2.html">Timeline v2</a>
                </li>
                <li><a href="pages-invoice.html"><span class="label label-primary pull-right">New</span>Invoice</a>
                </li>
                <li><a href="pages-calendar.html">Calendar</a>
                </li>
                <li><a href="pages-gallery.html">Gallery</a>
                </li>
                <li><a href="pages-code-editor.html"><span class="label label-primary pull-right">New    </span>Code Editor</a>
                </li>
                <li><a href="pages-booking.html"><span class="label label-primary pull-right">New</span>Booking</a>
                </li>
                <li><a href="pages-loaders.html"><span class="label label-primary pull-right">New</span>Loaders</a>
                </li>
              </ul>
            </li>
         
          </ul>
        </div>
      </div>
    </div>
    <div class="progress-widget">
      <div class="progress-data"><span class="progress-value">60%</span><span class="name">Current Project</span></div>
      <div class="progress">
        <div style="width: 60%;" class="progress-bar progress-bar-primary"></div>
      </div>
    </div>
  </div>
</div>
<!--
侧边栏-结束
-->
      <div class="be-content">
        <div class="page-head">
          <h2 class="page-head-title">中间件</h2>
          <ol class="breadcrumb page-head-nav">
            <li><a href="#">控制台</a></li>
            <li><a href="#">中间件</a></li>
            <li class="active">中间件列表</li>
          </ol>
        </div>
        <div class="main-content container-fluid">
          <div class="row pricing-tables">
            <div class="col-md-3">
              <div class="pricing-table pricing-table-primary">
                <div class="pricing-table-image">
                  <img src="./assets/img/Consul.jpeg">
                </div>
                <div class="pricing-table-title">Consul</div>
                <div class="panel-divider panel-divider-xl"></div>
                <ul class="pricing-table-features">
                  <li>Consul 简化了分布式环境中的服务的注册和发现流程,通过 HTTP 或者 DNS 接口发现。支持外部 SaaS 提供者等。</li>
                  <li></li>
                </ul><a href="#" class="btn btn-primary">开始创建</a>
              </div>
            </div>
            <div class="col-md-3">
              <div class="pricing-table pricing-table-primary">
                <div class="pricing-table-image">
                  <img src="./assets/img/Mysql.jpeg">
                </div>
                <div class="pricing-table-title">Mysql</div>
                <div class="panel-divider panel-divider-xl"></div>
                <ul class="pricing-table-features">
                  <li>MySQL 是一种关系型数据库管理系统,关系数据库将数据保存在不同的表中,这样就增加了速度并提高了灵活性。
                  </li>
                  <li></li>
                </ul><a href="middleware-create-mysql.html" class="btn btn-primary">开始创建</a>
              </div>
            </div>
            <div class="col-md-3">
              <div class="pricing-table pricing-table-primary">
                <div class="pricing-table-image">
                  <img src="./assets/img/Redis.jpeg">
                </div>
                <div class="pricing-table-title">Redis</div>
                <div class="panel-divider panel-divider-xl"></div>
                <ul class="pricing-table-features">
                  <li>Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
                  </li>
                  <li></li>
                </ul><a href="#" class="btn btn-primary">开始创建</a>
              </div>
            </div>
            <div class="col-md-3">
              <div class="pricing-table pricing-table-primary">
                <div class="pricing-table-image">
                  <img src="./assets/img/MariaDB.jpeg">
                </div>
                <div class="pricing-table-title">MariaDB</div>
                <div class="panel-divider panel-divider-xl"></div>
                <ul class="pricing-table-features">
                  <li>MariaDB数据库管理系统是MySQL的一个分支, MariaDB的目的是完全兼容MySQL,使之能轻松成为MySQL的代替品。</li>
                  <li></li>
                </ul><a href="#" class="btn btn-primary">开始创建</a>
              </div>
            </div>
          </div>
        </div>

      </div>
      <nav class="be-right-sidebar">
        <div class="sb-content">
          <div class="tab-navigation">
            <ul role="tablist" class="nav nav-tabs nav-justified">
              <li role="presentation" class="active"><a href="#tab1" aria-controls="tab1" role="tab" data-toggle="tab">Chat</a></li>
              <li role="presentation"><a href="#tab2" aria-controls="tab2" role="tab" data-toggle="tab">Todo</a></li>
              <li role="presentation"><a href="#tab3" aria-controls="tab3" role="tab" data-toggle="tab">Settings</a></li>
            </ul>
          </div>
          <div class="tab-panel">
            <div class="tab-content">
              <div id="tab1" role="tabpanel" class="tab-pane tab-chat active">
                <div class="chat-contacts">
                  <div class="chat-sections">
                    <div class="be-scroller">
                      <div class="content">
                        <h2>Recent</h2>
                        <div class="contact-list contact-list-recent">
                          <div class="user"><a href="#"><img src="assets/img/avatar1.png" alt="Avatar">
                              <div class="user-data"><span class="status away"></span><span class="name">Claire Sassu</span><span class="message">Can you share the...</span></div></a></div>
                          <div class="user"><a href="#"><img src="assets/img/avatar2.png" alt="Avatar">
                              <div class="user-data"><span class="status"></span><span class="name">Maggie jackson</span><span class="message">I confirmed the info.</span></div></a></div>
                          <div class="user"><a href="#"><img src="assets/img/avatar3.png" alt="Avatar">
                              <div class="user-data"><span class="status offline"></span><span class="name">Joel King		</span><span class="message">Ready for the meeti...</span></div></a></div>
                        </div>
                        <h2>Contacts</h2>
                        <div class="contact-list">
                          <div class="user"><a href="#"><img src="assets/img/avatar4.png" alt="Avatar">
                              <div class="user-data2"><span class="status"></span><span class="name">Mike Bolthort</span></div></a></div>
                          <div class="user"><a href="#"><img src="assets/img/avatar5.png" alt="Avatar">
                              <div class="user-data2"><span class="status"></span><span class="name">Maggie jackson</span></div></a></div>
                          <div class="user"><a href="#"><img src="assets/img/avatar6.png" alt="Avatar">
                              <div class="user-data2"><span class="status offline"></span><span class="name">Jhon Voltemar</span></div></a></div>
                        </div>
                      </div>
                    </div>
                  </div>
                  <div class="bottom-input">
                    <input type="text" placeholder="Search..." name="q"><span class="mdi mdi-search"></span>
                  </div>
                </div>
                <div class="chat-window">
                  <div class="title">
                    <div class="user"><img src="assets/img/avatar2.png" alt="Avatar">
                      <h2>Maggie jackson</h2><span>Active 1h ago</span>
                    </div><span class="icon return mdi mdi-chevron-left"></span>
                  </div>
                  <div class="chat-messages">
                    <div class="be-scroller">
                      <div class="content">
                        <ul>
                          <li class="friend">
                            <div class="msg">Hello</div>
                          </li>
                          <li class="self">
                            <div class="msg">Hi, how are you?</div>
                          </li>
                          <li class="friend">
                            <div class="msg">Good, I'll need support with my pc</div>
                          </li>
                          <li class="self">
                            <div class="msg">Sure, just tell me what is going on with your computer?</div>
                          </li>
                          <li class="friend">
                            <div class="msg">I don't know it just turns off suddenly</div>
                          </li>
                        </ul>
                      </div>
                    </div>
                  </div>
                  <div class="chat-input">
                    <div class="input-wrapper"><span class="photo mdi mdi-camera"></span>
                      <input type="text" placeholder="Message..." name="q" autocomplete="off"><span class="send-msg mdi mdi-mail-send"></span>
                    </div>
                  </div>
                </div>
              </div>
              <div id="tab2" role="tabpanel" class="tab-pane tab-todo">
                <div class="todo-container">
                  <div class="todo-wrapper">
                    <div class="be-scroller">
                      <div class="todo-content"><span class="category-title">Today</span>
                        <ul class="todo-list">
                          <li>
                            <div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
                              <input id="todo1" type="checkbox" checked="">
                              <label for="todo1">Initialize the project</label>
                            </div>
                          </li>
                          <li>
                            <div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
                              <input id="todo2" type="checkbox">
                              <label for="todo2">Create the main structure</label>
                            </div>
                          </li>
                          <li>
                            <div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
                              <input id="todo3" type="checkbox">
                              <label for="todo3">Updates changes to GitHub</label>
                            </div>
                          </li>
                        </ul><span class="category-title">Tomorrow</span>
                        <ul class="todo-list">
                          <li>
                            <div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
                              <input id="todo4" type="checkbox">
                              <label for="todo4">Initialize the project</label>
                            </div>
                          </li>
                          <li>
                            <div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
                              <input id="todo5" type="checkbox">
                              <label for="todo5">Create the main structure</label>
                            </div>
                          </li>
                          <li>
                            <div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
                              <input id="todo6" type="checkbox">
                              <label for="todo6">Updates changes to GitHub</label>
                            </div>
                          </li>
                          <li>
                            <div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
                              <input id="todo7" type="checkbox">
                              <label for="todo7" title="This task is too long to be displayed in a normal space!">This task is too long to be displayed in a normal space!</label>
                            </div>
                          </li>
                        </ul>
                      </div>
                    </div>
                  </div>
                  <div class="bottom-input">
                    <input type="text" placeholder="Create new task..." name="q"><span class="mdi mdi-plus"></span>
                  </div>
                </div>
              </div>
              <div id="tab3" role="tabpanel" class="tab-pane tab-settings">
                <div class="settings-wrapper">
                  <div class="be-scroller"><span class="category-title">General</span>
                    <ul class="settings-list">
                      <li>
                        <div class="switch-button switch-button-sm">
                          <input type="checkbox" checked="" name="st1" id="st1"><span>
                            <label for="st1"></label></span>
                        </div><span class="name">Available</span>
                      </li>
                      <li>
                        <div class="switch-button switch-button-sm">
                          <input type="checkbox" checked="" name="st2" id="st2"><span>
                            <label for="st2"></label></span>
                        </div><span class="name">Enable notifications</span>
                      </li>
                      <li>
                        <div class="switch-button switch-button-sm">
                          <input type="checkbox" checked="" name="st3" id="st3"><span>
                            <label for="st3"></label></span>
                        </div><span class="name">Login with Facebook</span>
                      </li>
                    </ul><span class="category-title">Notifications</span>
                    <ul class="settings-list">
                      <li>
                        <div class="switch-button switch-button-sm">
                          <input type="checkbox" name="st4" id="st4"><span>
                            <label for="st4"></label></span>
                        </div><span class="name">Email notifications</span>
                      </li>
                      <li>
                        <div class="switch-button switch-button-sm">
                          <input type="checkbox" checked="" name="st5" id="st5"><span>
                            <label for="st5"></label></span>
                        </div><span class="name">Project updates</span>
                      </li>
                      <li>
                        <div class="switch-button switch-button-sm">
                          <input type="checkbox" checked="" name="st6" id="st6"><span>
                            <label for="st6"></label></span>
                        </div><span class="name">New comments</span>
                      </li>
                      <li>
                        <div class="switch-button switch-button-sm">
                          <input type="checkbox" name="st7" id="st7"><span>
                            <label for="st7"></label></span>
                        </div><span class="name">Chat messages</span>
                      </li>
                    </ul><span class="category-title">Workflow</span>
                    <ul class="settings-list">
                      <li>
                        <div class="switch-button switch-button-sm">
                          <input type="checkbox" name="st8" id="st8"><span>
                            <label for="st8"></label></span>
                        </div><span class="name">Deploy on commit</span>
                      </li>
                    </ul>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </nav>
    </div>
    <script src="assets/lib/jquery/jquery.min.js" type="text/javascript"></script>
    <script src="assets/lib/perfect-scrollbar/js/perfect-scrollbar.jquery.min.js" type="text/javascript"></script>
    <script src="assets/js/main.js" type="text/javascript"></script>
    <script src="assets/lib/bootstrap/dist/js/bootstrap.min.js" type="text/javascript"></script>
    <script src="assets/lib/datatables/js/jquery.dataTables.min.js" type="text/javascript"></script>
    <script src="assets/lib/datatables/js/dataTables.bootstrap.min.js" type="text/javascript"></script>
    <script src="assets/lib/datatables/plugins/buttons/js/dataTables.buttons.js" type="text/javascript"></script>
    <script src="assets/lib/datatables/plugins/buttons/js/buttons.html5.js" type="text/javascript"></script>
    <script src="assets/lib/datatables/plugins/buttons/js/buttons.flash.js" type="text/javascript"></script>
    <script src="assets/lib/datatables/plugins/buttons/js/buttons.print.js" type="text/javascript"></script>
    <script src="assets/lib/datatables/plugins/buttons/js/buttons.colVis.js" type="text/javascript"></script>
    <script src="assets/lib/datatables/plugins/buttons/js/buttons.bootstrap.js" type="text/javascript"></script>
    <script src="assets/js/app-tables-datatables.js" type="text/javascript"></script>
 
    <script type="text/javascript">
      $(document).ready(function(){
        
      	//initialize the javascript
      	App.init();
  
      	App.dataTables();
         
      $.ajax({
          type:"get",
          url:"http://127.0.0.1:8080/middlewareApi/",
          success: function(data){
            console.log(data);
            $("#table-data").html("");
            $.each(data['route_info'],function (i,item) {
              $("#table-data").append('                      <tr class="gradeA">\
                        <td>'+item.id+'</td>\
                        <td>'+item.route_name+'</td>\
                        <td>'+item.route_namespace+'</td>\
                        <td class="center">'+item.route_host+'</td>\
                        <td class="center"><a href="route-detail.html?route_id='+item.id+'">详情</a> <a href="http://localhost:8080/routeApi/deleteRouteById?route_id='+item.id+'" style="color:red;" >删除</a></td>\
                      </tr>'
              );
            })
          },
          error: function(result){
            console.log(result);
          }
        });
      });
    

 
    </script>

  </body>
</html>

 file:///home/gopath/src/gopaas/go-paas-front/middleware-create-mysql.html 

10-19 中间件前端页面以及核心API开发(下) 

C:\Users\Administrator\Desktop\gopaas\middlewareapi\handler\middlewareApiHandler.go

package handler

import (
	"context"
	"encoding/json"
	"errors"
	"strconv"

	log "github.com/asim/go-micro/v3/logger"
	"ithub.com/yunixiangfeng/gopaas/middlewareApi/plugin/form"
	"github.com/yunixiangfeng/gopaas/common"
	middleware "github.com/yunixiangfeng/gopaas/middleware/proto/middleware"
	middlewareApi "github.com/yunixiangfeng/gopaas/middlewareApi/proto/middlewareApi"
)

type MiddlewareApi struct {
	MiddlewareService middleware.MiddlewareService
}

// middlewareApi.FindMiddlewareById 通过API向外暴露为/middlewareApi/findMiddlewareById,接收http请求
// 即:/middlewareApi/FindMiddlewareById 请求会调用go.micro.api.middlewareApi 服务的middlewareApi.FindMiddlewareById 方法
func (e *MiddlewareApi) FindMiddlewareById(ctx context.Context, req *middlewareApi.Request, rsp *middlewareApi.Response) error {
	log.Info("Received middlewareApi.FindMiddlewareById request")
	if _, ok := req.Get["middle_id"]; !ok {
		return errors.New("参数异常!")
	}
	idString := req.Get["middle_id"].Values[0]
	id, err := strconv.ParseInt(idString, 10, 64)
	if err != nil {
		common.Error(err)
		return err
	}
	middleInfo, err := e.MiddlewareService.FindMiddlewareByID(ctx, &middleware.MiddlewareId{Id: id})
	rsp.StatusCode = 200
	b, _ := json.Marshal(middleInfo)
	rsp.Body = string(b)
	return nil
}

// middlewareApi.AddMiddleware 通过API向外暴露为/middlewareApi/AddMiddleware,接收http请求
// 即:/middlewareApi/AddMiddleware 请求会调用go.micro.api.middlewareApi 服务的middlewareApi.AddMiddleware 方法
func (e *MiddlewareApi) AddMiddleware(ctx context.Context, req *middlewareApi.Request, rsp *middlewareApi.Response) error {
	log.Info("Received middlewareApi.AddMiddleware request")
	addMiddleInfo := &middleware.MiddlewareInfo{}
	//设置端口
	port, err := e.setMiddlePort(req)
	if err != nil {
		common.Error(err)
		return err
	}
	addMiddleInfo.MiddlePort = port

	//设置环境变量
	addMiddleInfo.MiddleEnv = e.setMiddleEnv(req)

	//设置存储
	addMiddleInfo.MiddleStorage = e.setMiddleStorage(req)

	//获取类型
	middleTypeInfo := e.getMiddleType(req)

	//判断不同的类型设置不同的值
	switch middleTypeInfo.MiddleTypeName {
	case "MYSQL":
		middleConfig := e.setMiddleConfig(req)
		addMiddleInfo.MiddleConfig = &middleConfig
	}

	//处理表单
	form.FormToMiddlewareStruct(req.Post, addMiddleInfo)
	//调用后端服务添加数据
	response, err := e.MiddlewareService.AddMiddleware(ctx, addMiddleInfo)
	if err != nil {
		common.Error(err)
		return err
	}
	rsp.StatusCode = 200
	b, _ := json.Marshal(response)
	rsp.Body = string(b)
	return nil
}

//设置mysql config 设置
func (e *MiddlewareApi) setMiddleConfig(req *middlewareApi.Request) (middleConfig middleware.MiddleConfig) {
	middleConfig.MiddleConfigRootUser = e.getValue(req, "middle_config_root_user")
	middleConfig.MiddleConfigRootPwd = e.getValue(req, "middle_config_root_pwd")
	middleConfig.MiddleConfigUser = e.getValue(req, "middle_config_user")
	middleConfig.MiddleConfigPwd = e.getValue(req, "middle_config_pwd")
	middleConfig.MiddleConfigDataBase = e.getValue(req, "middle_config_data_base")
	return
}

//获取post值
func (e *MiddlewareApi) getValue(req *middlewareApi.Request, key string) string {
	value, ok := req.Post[key]
	if ok {
		return value.Values[0]
	}
	return ""
}

//获取类型
func (e *MiddlewareApi) getMiddleType(req *middlewareApi.Request) (middleTypeInfo middleware.MiddleTypeInfo) {
	typeValue, ok := req.Post["middle_type_id"]
	if ok {
		typeId, err := strconv.ParseInt(typeValue.Values[0], 10, 64)
		if err != nil {
			common.Error(err)
			return
		}
		typeInfo, err := e.MiddlewareService.FindMiddleTypeByID(context.TODO(), &middleware.MiddleTypeId{
			Id: typeId,
		})
		if err != nil {
			common.Error(err)
			return
		}
		middleTypeInfo = *typeInfo
	}
	return
}

//设置中间件的存储
func (e *MiddlewareApi) setMiddleStorage(req *middlewareApi.Request) []*middleware.MiddleStorage {
	storageSlice := []*middleware.MiddleStorage{}
	//处理环境变量
	i := 1
	for {
		nameTag := "middle_storage.name." + strconv.Itoa(i)
		sizeTag := "middle_storage.size." + strconv.Itoa(i)
		pathTag := "middle_storage.path." + strconv.Itoa(i)
		key, ok := req.Post[nameTag]
		if ok {
			sizeValue, _ := strconv.ParseFloat(req.Post[sizeTag].Values[0], 32)
			storage := &middleware.MiddleStorage{
				MiddleStorageName:       key.Values[0],
				MiddleStorageSize:       float32(sizeValue),
				MiddleStoragePath:       req.Post[pathTag].Values[0],
				MiddleStorageClass:      "csi-rbd-sc",
				MiddleStorageAccessMode: "ReadWriteOnce",
			}
			storageSlice = append(storageSlice, storage)
		} else {
			break
		}
		i++
	}
	return storageSlice
}

//设置中间件环境变量
func (e *MiddlewareApi) setMiddleEnv(req *middlewareApi.Request) []*middleware.MiddleEnv {
	envSlice := []*middleware.MiddleEnv{}
	//处理环境变量
	i := 1
	for {
		tag := "middle_env.key." + strconv.Itoa(i)
		valueTag := "middle_env.value." + strconv.Itoa(i)
		key, ok := req.Post[tag]
		if ok {
			env := &middleware.MiddleEnv{
				EnvKey:   key.Values[0],
				EnvValue: req.Post[valueTag].Values[0],
			}
			envSlice = append(envSlice, env)
		} else {
			break
		}
		i++
	}
	return envSlice
}

//设置端口
func (e *MiddlewareApi) setMiddlePort(req *middlewareApi.Request) ([]*middleware.MiddlePort, error) {
	dataSlice, ok := req.Post["middle_port"]
	if ok {
		//特殊处理
		middlePortSlice := []*middleware.MiddlePort{}
		for _, v := range dataSlice.Values {
			i, err := strconv.ParseInt(v, 10, 64)
			if err != nil {
				common.Error(err)
			}
			port := &middleware.MiddlePort{
				MiddlePort:     int32(i),
				MiddleProtocol: "TCP",
			}
			middlePortSlice = append(middlePortSlice, port)
		}
		return middlePortSlice, nil
	}
	return nil, errors.New("无端口")
}

// middlewareApi.DeleteMiddlewareById 通过API向外暴露为/middlewareApi/DeleteMiddlewareById,接收http请求
// 即:/middlewareApi/DeleteMiddlewareById 请求会调用go.micro.api.middlewareApi 服务的 middlewareApi.DeleteMiddlewareById 方法
func (e *MiddlewareApi) DeleteMiddlewareById(ctx context.Context, req *middlewareApi.Request, rsp *middlewareApi.Response) error {
	log.Info("Received middlewareApi.DeleteMiddlewareById request")
	if _, ok := req.Get["middle_id"]; !ok {
		return errors.New("参数异常")
	}
	IdString := req.Get["middle_id"].Values[0]
	Id, err := strconv.ParseInt(IdString, 10, 64)
	if err != nil {
		common.Error(err)
		return err
	}
	response, err := e.MiddlewareService.DeleteMiddleware(ctx, &middleware.MiddlewareId{
		Id: Id,
	})
	rsp.StatusCode = 200
	b, _ := json.Marshal(response)
	rsp.Body = string(b)
	return nil
}

// middlewareApi.UpdateMiddleware 通过API向外暴露为/middlewareApi/UpdateMiddleware,接收http请求
// 即:/middlewareApi/UpdateMiddleware 请求会调用go.micro.api.middlewareApi 服务的middlewareApi.UpdateMiddleware 方法
func (e *MiddlewareApi) UpdateMiddleware(ctx context.Context, req *middlewareApi.Request, rsp *middlewareApi.Response) error {
	log.Info("Received middlewareApi.UpdateMiddleware request")
	rsp.StatusCode = 200
	b, _ := json.Marshal("{success:'成功访问/middlewareApi/UpdateMiddleware'}")
	rsp.Body = string(b)
	return nil
}

// 默认的方法middlewareApi.Call 通过API向外暴露为/middlewareApi/call,接收http请求
// 即:/middlewareApi/call或/middlewareApi/ 请求会调用go.micro.api.middlewareApi 服务的middlewareApi.FindMiddlewareById 方法
func (e *MiddlewareApi) Call(ctx context.Context, req *middlewareApi.Request, rsp *middlewareApi.Response) error {
	log.Info("Received middlewareApi.Call request")
	rsp.StatusCode = 200
	b, _ := json.Marshal("{success:'成功访问:Call'}")
	rsp.Body = string(b)
	return nil
}
func (e *MiddlewareApi) FindAllMiddlewareByTypeId(ctx context.Context, req *middlewareApi.Request, rsp *middlewareApi.Response) error {
	log.Info("Received middlewareApi.Call request")
	rsp.StatusCode = 200
	b, _ := json.Marshal("{success:'成功访问:Call'}")
	rsp.Body = string(b)
	return nil
}

func (e *MiddlewareApi) FindMiddleTypeById(ctx context.Context, req *middlewareApi.Request, rsp *middlewareApi.Response) error {
	log.Info("Received middlewareApi.Call request")
	rsp.StatusCode = 200
	b, _ := json.Marshal("{success:'成功访问:Call'}")
	rsp.Body = string(b)
	return nil
}
func (e *MiddlewareApi) AddMiddleType(ctx context.Context, req *middlewareApi.Request, rsp *middlewareApi.Response) error {
	log.Info("Received middlewareApi.Call request")
	typeInfo := &middleware.MiddleTypeInfo{
		//MiddleTypeName:     "CONSUL",
		//MiddleTypeImageSrc: "/consul.jpg",
		//MiddleVersion:      []*middleware.MiddleVersion{
		//	{
		//		MiddleDockerImage: "docker/consul",
		//		MiddleVs:          "v1.0.1",
		//	},
		//	{
		//		MiddleDockerImage: "docker/consul",
		//		MiddleVs:          "v1.0.2",
		//	},
		//},
	}
	rspInfo, err := e.MiddlewareService.AddMiddleType(ctx, typeInfo)
	if err != nil {
		common.Error(err)
		return err
	}

	rsp.StatusCode = 200
	b, _ := json.Marshal(rspInfo)
	rsp.Body = string(b)
	return nil
}
func (e *MiddlewareApi) DeleteMiddleTypeById(ctx context.Context, req *middlewareApi.Request, rsp *middlewareApi.Response) error {
	log.Info("Received middlewareApi.Call request")
	rsp.StatusCode = 200
	b, _ := json.Marshal("{success:'成功访问:Call'}")
	rsp.Body = string(b)
	return nil
}
func (e *MiddlewareApi) UpdateMiddleType(ctx context.Context, req *middlewareApi.Request, rsp *middlewareApi.Response) error {
	log.Info("Received middlewareApi.Call request")
	rsp.StatusCode = 200
	b, _ := json.Marshal("{success:'成功访问:Call'}")
	rsp.Body = string(b)
	return nil
}

func (e *MiddlewareApi) FindAllMiddleType(ctx context.Context, req *middlewareApi.Request, rsp *middlewareApi.Response) error {
	log.Info("Received middlewareApi.Call request")
	allType, err := e.MiddlewareService.FindAllMiddleType(ctx, &middleware.FindAll{})
	if err != nil {
		common.Error(err)
		return err
	}
	rsp.StatusCode = 200
	b, _ := json.Marshal(allType)
	rsp.Body = string(b)
	return nil
}

C:\Users\Administrator\Desktop\gopaas\middlewareapi\plugin\form\form.go 

package form

import (
	"errors"
	"strings"

	"reflect"
	"strconv"
	"time"

	"github.com/yunixiangfeng/gopaas/common"
	"github.com/yunixiangfeng/gopaas/middlewareApi/proto/middlewareApi"
)

//根据结构体中name标签映射数据到结构体中并且转换类型
func FormToMiddlewareStruct(data map[string]*middlewareApi.Pair, obj interface{}) {
	objValue := reflect.ValueOf(obj).Elem()
	for i := 0; i < objValue.NumField(); i++ {
		//获取sql对应的值
		dataTag := strings.Replace(objValue.Type().Field(i).Tag.Get("json"), ",omitempty", "", -1)
		dataSlice, ok := data[dataTag]
		if !ok {
			continue
		}
		valueSlice := dataSlice.Values
		if len(valueSlice) <= 0 {
			continue
		}
		//排除port和env
		if dataTag == "middle_port" {
			continue
		}
		value := valueSlice[0]

		//端口,环境变量的单独处理
		//获取对应字段的名称
		name := objValue.Type().Field(i).Name
		//特殊类型跳过单独处理
		if name == "MiddleStorage" {
			continue
		}
		//获取对应字段类型
		structFieldType := objValue.Field(i).Type()
		//获取变量类型,也可以直接写"string类型"
		val := reflect.ValueOf(value)
		var err error
		if structFieldType != val.Type() {
			//类型转换
			val, err = TypeConversion(value, structFieldType.Name()) //类型转换
			if err != nil {
				common.Error(err)
			}
		}
		//设置类型值
		objValue.FieldByName(name).Set(val)
	}
}

//类型转换
func TypeConversion(value string, ntype string) (reflect.Value, error) {
	if ntype == "string" {
		return reflect.ValueOf(value), nil
	} else if ntype == "time.Time" {
		t, err := time.ParseInLocation("2006-01-02 15:04:05", value, time.Local)
		return reflect.ValueOf(t), err
	} else if ntype == "Time" {
		t, err := time.ParseInLocation("2006-01-02 15:04:05", value, time.Local)
		return reflect.ValueOf(t), err
	} else if ntype == "int" {
		i, err := strconv.Atoi(value)
		return reflect.ValueOf(i), err
	} else if ntype == "int32" {
		i, err := strconv.ParseInt(value, 10, 32)
		if err != nil {
			return reflect.ValueOf(int32(i)), err
		}
		return reflect.ValueOf(int32(i)), err
	} else if ntype == "int64" {
		i, err := strconv.ParseInt(value, 10, 64)
		return reflect.ValueOf(i), err
	} else if ntype == "float32" {
		i, err := strconv.ParseFloat(value, 64)
		return reflect.ValueOf(float32(i)), err
	} else if ntype == "float64" {
		i, err := strconv.ParseFloat(value, 64)
		return reflect.ValueOf(i), err
	}

	//else if .......增加其他一些类型的转换

	return reflect.ValueOf(value), errors.New("未知的类型:" + ntype)
}

 C:\Users\Administrator\Desktop\gopaas\middlewareapi\main.go

package main

import (
	"fmt"

	"github.com/afex/hystrix-go/hystrix"
	"github.com/asim/go-micro/plugins/registry/consul/v3"
	ratelimit "github.com/asim/go-micro/plugins/wrapper/ratelimiter/uber/v3"
	"github.com/asim/go-micro/plugins/wrapper/select/roundrobin/v3"
	opentracing2 "github.com/asim/go-micro/plugins/wrapper/trace/opentracing/v3"
	"github.com/asim/go-micro/v3"
	"github.com/asim/go-micro/v3/registry"
	"github.com/asim/go-micro/v3/server"
	"github.com/yunixiangfeng/gopaas/common"
	go_micro_service_middleware "github.com/yunixiangfeng/gopaas/middleware/proto/middleware"

	"net"
	"net/http"
	"strconv"

	_ "github.com/jinzhu/gorm/dialects/mysql"
	"github.com/opentracing/opentracing-go"
	"github.com/yunixiangfeng/gopaas/middlewareApi/handler"
	hystrix2 "github.com/yunixiangfeng/gopaas/middlewareApi/plugin/hystrix"
	middlewareApi "github.com/yunixiangfeng/gopaas/middlewareApi/proto/middlewareApi"
)

var (
	//服务地址
	hostIp = "192.168.204.130"
	//服务地址
	serviceHost = hostIp
	//服务端口
	servicePort = "8090"
	//注册中心配置
	consulHost       = hostIp
	consulPort int64 = 8500
	//链路追踪
	tracerHost = hostIp
	tracerPort = 6831
	//熔断端口,每个服务不能重复
	hystrixPort = 9100
	//监控端口,每个服务不能重复
	prometheusPort = 9200
)

func main() {
	//需要本地启动,mysql,consul中间件服务
	//1.注册中心
	consul := consul.NewRegistry(func(options *registry.Options) {
		options.Addrs = []string{
			consulHost + ":" + strconv.FormatInt(consulPort, 10),
		}
	})

	//2.添加链路追踪
	t, io, err := common.NewTracer("go.micro.api.middlewareApi", tracerHost+":"+strconv.Itoa(tracerPort))
	if err != nil {
		common.Error(err)
	}
	defer io.Close()
	opentracing.SetGlobalTracer(t)

	//3.添加熔断器
	hystrixStreamHandler := hystrix.NewStreamHandler()
	hystrixStreamHandler.Start()

	//添加日志中心
	//1)需要程序日志打入到日志文件中
	//2)在程序中添加filebeat.yml 文件
	//3) 启动filebeat,启动命令 ./filebeat -e -c filebeat.yml
	fmt.Println("日志统一记录在根目录 micro.log 文件中,请点击查看日志!")

	//启动监听程序
	go func() {
		//http://192.168.204.130:9092/turbine/turbine.stream
		//看板访问地址 http://127.0.0.1:9002/hystrix,url后面一定要带 /hystrix
		err = http.ListenAndServe(net.JoinHostPort("0.0.0.0", strconv.Itoa(hystrixPort)), hystrixStreamHandler)
		if err != nil {
			common.Error(err)
		}
	}()

	//4.添加监控
	common.PrometheusBoot(prometheusPort)

	//5.创建服务
	service := micro.NewService(
		//自定义服务地址,且必须写在其它参数前面
		micro.Server(server.NewServer(func(opts *server.Options) {
			opts.Advertise = serviceHost + ":" + servicePort

		})),
		micro.Name("go.micro.api.middlewareApi"),
		micro.Version("latest"),
		//指定服务端口
		micro.Address(":"+servicePort),
		//添加注册中心
		micro.Registry(consul),
		//添加链路追踪
		micro.WrapHandler(opentracing2.NewHandlerWrapper(opentracing.GlobalTracer())),
		micro.WrapClient(opentracing2.NewClientWrapper(opentracing.GlobalTracer())),
		//只作为客户端的时候起作用
		micro.WrapClient(hystrix2.NewClientHystrixWrapper()),
		//添加限流
		micro.WrapHandler(ratelimit.NewHandlerWrapper(1000)),
		//增加负载均衡
		micro.WrapClient(roundrobin.NewClientWrapper()),
	)

	service.Init()

	// 指定需要访问的服务,可以快速操作已开发的服务,
	// 默认API服务名称带有"Api",程序会自动替换
	// 如果不带有特定字符会使用默认"XXX" 请自行替换
	middlewareService := go_micro_service_middleware.NewMiddlewareService("go.micro.service.middleware", service.Client())
	// 注册控制器
	if err := middlewareApi.RegisterMiddlewareApiHandler(service.Server(), &handler.MiddlewareApi{MiddlewareService: middlewareService}); err != nil {
		common.Error(err)
	}

	// 启动服务
	if err := service.Run(); err != nil {
		//输出启动失败信息
		common.Fatal(err)
	}
}

10-20 总结&思考 

GO PaaS 平台中间件创建与管理

主要内容
中间件服务端开发
中间件服务API开放
中间件页面联调

中间件为什么挂载盘会创建多个?
中间件集群模式如何搞定?

10-21 【扩展阅读】k8s 实战篇 – Mysql 容器化部署详解

第11章 云原生 Go PaaS 平台镜功能开发,商业化镜像市场,完善平台市场功能

开发完成的应用能够包装成各自独立的应用程序,以便于在市场上通过售卖和安装的方式给客户获取到。开发满足业务需求的镜像市场功能,使得我们的应用能够像APP 应用一样在 PaaS 平台上购买和被安装。

11-1 云应用市场开发介绍

GO PaaS 平台云应用市场开发

主要内容
云市场服务开发
云市场API开发
云市场页面联调

11-2 云应用app_store模型开发及管理说明 

yu-tool.exe  newService github.com/yunixiangfeng/gopaas/appStore  

yu-v3 --proto_path=. --micro_out=. --go_out=:. ./proto/appStore/appStore.proto

go mod tidy

C:\Users\Administrator\Desktop\gopaas\appstore\domain\model\appStore.go

package model

//应用市场
type AppStore struct{
	ID int64 `gorm:"primary_key;not_null;auto_increment"`
	//应用的标识
	AppSku string `gorm:"unique_index;not null" json:"app_sku"`
	//应用标题
	AppTitle string `json:"app_title"`
	//应用描述
	AppDetail string `json:"app_detail"`
	//应用价格
	AppPrice float32 `json:"app_price"`
	//安装次数
	AppInstall int64 `json:"app_install"`
	//访问次数
	AppViews int64 `json:"app_views"`
	//应用审核
	AppCheck bool `json:"app_check"`
	//应用分类
	AppCategoryID int64 `json:"app_category_id"`
	//服务商
	AppIsvID int64 `json:"app_isv_id"`
	//应用图片
	AppImage[] AppImage `gorm:"ForeignKey:AppID" json:"app_image"`
	//应用组合,应用的模板
	AppPod[] AppPod `gorm:"ForeignKey:AppID" json:"app_pod"`
	//中间件组合
	AppMiddle[] AppMiddle `gorm:"ForeignKey:AppID" json:"app_middle"`
	//存储组合
	AppVolume[] AppVolume `gorm:"ForeignKey:AppID" json:"app_volume"`
	//评论
	AppComment[] AppComment `gorm:"ForeignKey:AppID" json:"app_comment"`
}

11-3 云应用辅助信息model 开发

appStore.go 重命名 app_store.go

C:\Users\Administrator\Desktop\gopaas\appstore\domain\model\app_category.go

package model

type AppCategory struct {
	ID           int64  `gorm:"primary_key;not_null;auto_increment"`
	CategoryName string `json:"category_name"`
	//@TODO
}

C:\Users\Administrator\Desktop\gopaas\appstore\domain\model\app_pod.go

package model

type AppPod struct {
	ID int64 `gorm:"primary_key;not_null;auto_increment"`
	AppID int64 `json:"app_id"`
	AppPodID int64 `json:"app_pod_id"`
}

C:\Users\Administrator\Desktop\gopaas\appstore\domain\model\app_image.go

package model

//云引用图片
type AppImage struct {
	ID int64 `gorm:"primary_key;not_null;auto_increment"`
	AppID int64 `json:"app_id"`
	//图片地址
	AppImageSrc string `json:"app_image_src"`
}

C:\Users\Administrator\Desktop\gopaas\appstore\domain\model\app_middle.go

package model

type AppMiddle struct {
	ID int64 `gorm:"primary_key;not_null;auto_increment"`
	AppID int64 `json:"app_id"`
	AppMiddleID int64 `json:"app_middle_id"`
}

 C:\Users\Administrator\Desktop\gopaas\appstore\domain\model\app_volume.go

package model

//云应用存储模板
type AppVolume struct {
	ID int64 `gorm:"primary_key;not_null;auto_increment"`
	AppID int64 `json:"app_id"`
	AppVolumeID int64 `json:"app_volume_id"`
}

C:\Users\Administrator\Desktop\gopaas\appstore\domain\model\app_comment.go

package model

//云应用评论
type AppComment struct {
	ID int64 `gorm:"primary_key;not_null;auto_increment"`
	AppID int64 `json:"app_id"`
	AppCommentTitle string `json:"app_comment_title"`
	AppCommentDetail string `json:"app_comment_detail"`
	AppUserID int64 `json:"app_user_id"`
	//@TODO
}

C:\Users\Administrator\Desktop\gopaas\appstore\domain\model\app_isv.go

package model

//服务商
type AppIsv struct {
	ID int64 `gorm:"primary_key;not_null;auto_increment"`
	AppIsvName string `json:"app_isv_name"`
	AppIsvDetail string `json:"app_isv_detail"`
}

11-4 云应用市场 repository 代码开发

C:\Users\Administrator\Desktop\gopaas\appstore\domain\repository\appStore_repository.go

package repository

import (
	"github.com/jinzhu/gorm"
	"github.com/yunixiangfeng/gopaas/appStore/domain/model"
	"github.com/yunixiangfeng/gopaas/common"
)

//创建需要实现的接口
type IAppStoreRepository interface {
	//初始化表
	InitTable() error
	//根据ID查处找数据
	FindAppStoreByID(int64) (*model.AppStore, error)
	//创建一条 appStore 数据
	CreateAppStore(*model.AppStore) (int64, error)
	//根据ID删除一条 appStore 数据
	DeleteAppStoreByID(int64) error
	//修改更新数据
	UpdateAppStore(*model.AppStore) error
	//查找appStore所有数据
	FindAll() ([]model.AppStore, error)

	//添加安装数量
	AddInstallNumber(int64) error
	//获取安装数量
	GetInstallNumber(int64) int64
	//添加浏览量
	AddViewNumber(int64) error
	//获取浏览量
	GetViewNumber(int64) int64
}

//创建appStoreRepository
func NewAppStoreRepository(db *gorm.DB) IAppStoreRepository {
	return &AppStoreRepository{mysqlDb: db}
}

type AppStoreRepository struct {
	mysqlDb *gorm.DB
}

//初始化表
func (u *AppStoreRepository) InitTable() error {
	return u.mysqlDb.CreateTable(&model.AppStore{}, &model.AppComment{}, &model.AppVolume{}, &model.AppPod{}, &model.AppImage{}, &model.AppCategory{}, &model.AppIsv{}, &model.AppMiddle{}).Error
}

//添加安装数量统计
func (u *AppStoreRepository) AddInstallNumber(appID int64) error {
	return u.mysqlDb.Model(&model.AppStore{}).Where("id = ?", appID).UpdateColumn("app_install", gorm.Expr("app_install + ?", 1)).Error
}

//获取安装数量统计
func (u *AppStoreRepository) GetInstallNumber(appID int64) int64 {
	appStore, err := u.FindAppStoreByID(appID)
	if err != nil {
		common.Error(err)
		return 0
	}
	return appStore.AppInstall
}

//添加浏览统计
func (u *AppStoreRepository) AddViewNumber(appID int64) error {
	return u.mysqlDb.Model(&model.AppStore{}).Where("id =  ?", appID).UpdateColumn("app_views", gorm.Expr("app_views + ?", 1)).Error
}

//获取浏览数量
func (u *AppStoreRepository) GetViewNumber(appID int64) int64 {
	appStore, err := u.FindAppStoreByID(appID)
	if err != nil {
		common.Error(err)
		return 0
	}
	return appStore.AppViews
}

//根据ID查找AppStore信息
func (u *AppStoreRepository) FindAppStoreByID(appStoreID int64) (appStore *model.AppStore, err error) {
	appStore = &model.AppStore{}
	return appStore, u.mysqlDb.Preload("AppImage").Preload("AppPod").Preload("AppMiddle").Preload("AppVolume").Preload("AppComment").First(appStore, appStoreID).Error
}

//创建AppStore信息
func (u *AppStoreRepository) CreateAppStore(appStore *model.AppStore) (int64, error) {
	return appStore.ID, u.mysqlDb.Create(appStore).Error
}

//根据ID删除AppStore信息
func (u *AppStoreRepository) DeleteAppStoreByID(appStoreID int64) error {
	//开启事务
	tx := u.mysqlDb.Begin()
	//遇到问题回滚
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()
	//遇到问题返回
	if tx.Error != nil {
		return tx.Error
	}

	//删除应用
	if err := u.mysqlDb.Where("id = ?", appStoreID).Delete(&model.AppStore{}).Error; err != nil {
		tx.Rollback()
		return err
	}
	//删除应用图片
	if err := u.mysqlDb.Where("app_id = ?", appStoreID).Delete(&model.AppImage{}).Error; err != nil {
		tx.Rollback()
		return err
	}
	//删除中间件
	if err := u.mysqlDb.Where("app_id = ?", appStoreID).Delete(&model.AppMiddle{}).Error; err != nil {
		tx.Rollback()
		return err
	}
	//删除对应的Pod组合
	if err := u.mysqlDb.Where("app_id = ?", appStoreID).Delete(&model.AppPod{}).Error; err != nil {
		tx.Rollback()
		return err
	}
	//删除存储
	if err := u.mysqlDb.Where("app_id = ?", appStoreID).Delete(&model.AppVolume{}).Error; err != nil {
		tx.Rollback()
		return err
	}
	//删除应用评论
	if err := u.mysqlDb.Where("app_id = ?", appStoreID).Delete(&model.AppComment{}).Error; err != nil {
		tx.Rollback()
		return err
	}

	return tx.Commit().Error
}

//更新AppStore信息
func (u *AppStoreRepository) UpdateAppStore(appStore *model.AppStore) error {
	return u.mysqlDb.Model(appStore).Update(appStore).Error
}

//获取结果集
func (u *AppStoreRepository) FindAll() (appStoreAll []model.AppStore, err error) {
	return appStoreAll, u.mysqlDb.Find(&appStoreAll).Error
}

11-5 云应用平台Service 代码开发

C:\Users\Administrator\Desktop\gopaas\appstore\domain\service\appStore_data_service.go

package service

import (
	"github.com/yunixiangfeng/gopaas/appStore/domain/model"
	"github.com/yunixiangfeng/gopaas/appStore/domain/repository"
	"k8s.io/client-go/kubernetes"
)

//这里是接口类型
type IAppStoreDataService interface {
	AddAppStore(*model.AppStore) (int64, error)
	DeleteAppStore(int64) error
	UpdateAppStore(*model.AppStore) error
	FindAppStoreByID(int64) (*model.AppStore, error)
	FindAllAppStore() ([]model.AppStore, error)

	//统计服务
	AddInstallNum(int64) error
	GetInstallNum(int64) int64
	AddViewNum(int64) error
	GetViewNum(int64) int64
}

//创建
//注意:返回值 IAppStoreDataService 接口类型
func NewAppStoreDataService(appStoreRepository repository.IAppStoreRepository, clientSet *kubernetes.Clientset) IAppStoreDataService {
	return &AppStoreDataService{AppStoreRepository: appStoreRepository}
}

type AppStoreDataService struct {
	//注意:这里是 IAppStoreRepository 类型
	AppStoreRepository repository.IAppStoreRepository
}

//安装数量统计
func (u *AppStoreDataService) AddInstallNum(appID int64) error {
	return u.AppStoreRepository.AddInstallNumber(appID)
}

//查询安装数量
func (u *AppStoreDataService) GetInstallNum(appID int64) int64 {
	return u.AppStoreRepository.GetInstallNumber(appID)
}

//添加浏览统计
func (u *AppStoreDataService) AddViewNum(appID int64) error {
	return u.AppStoreRepository.AddViewNumber(appID)
}

//获取浏览量
func (u *AppStoreDataService) GetViewNum(appID int64) int64 {
	return u.AppStoreRepository.GetViewNumber(appID)
}

//插入
func (u *AppStoreDataService) AddAppStore(appStore *model.AppStore) (int64, error) {
	return u.AppStoreRepository.CreateAppStore(appStore)
}

//删除
func (u *AppStoreDataService) DeleteAppStore(appStoreID int64) error {
	return u.AppStoreRepository.DeleteAppStoreByID(appStoreID)
}

//更新
func (u *AppStoreDataService) UpdateAppStore(appStore *model.AppStore) error {
	return u.AppStoreRepository.UpdateAppStore(appStore)
}

//查找
func (u *AppStoreDataService) FindAppStoreByID(appStoreID int64) (*model.AppStore, error) {
	return u.AppStoreRepository.FindAppStoreByID(appStoreID)
}

//查找
func (u *AppStoreDataService) FindAllAppStore() ([]model.AppStore, error) {
	return u.AppStoreRepository.FindAll()
}

11-6 云应用市场服务端Proto 开发

C:\Users\Administrator\Desktop\gopaas\appstore\proto\appStore\appStore.proto

syntax = "proto3";

package appStore;

option go_package = "./proto/appStore;appStore";

service AppStore {
	//对外提供添加服务
	rpc AddAppStore(AppStoreInfo) returns (Response) {}
	rpc DeleteAppStore(AppStoreId) returns (Response) {}
	rpc UpdateAppStore(AppStoreInfo) returns (Response) {}
	rpc FindAppStoreByID(AppStoreId) returns (AppStoreInfo) {}
	rpc FindAllAppStore(FindAll) returns (AllAppStore) {}

	//添加常用的接口
	rpc AddInstallNum(AppStoreId) returns (Response){}
	rpc GetInstallNum(AppStoreId) returns (Number){}
	rpc AddViewNum(AppStoreId) returns (Response){}
	rpc GetViewNum(AppStoreId) returns (Number){}
}

message AppStoreInfo {
	int64 id = 1;
	string app_sku =2;
	string app_title= 3;
	string app_describe =4;
	string app_detail =5;
	float app_price =6;
	int64 app_install =7;
	int64 app_views =8;
	bool app_check =9;
	int64 app_category_id =10;
	int64 app_isv_id = 11;
	repeated AppImage app_image =12;
	repeated AppPod app_pod =13;
	repeated AppMiddle app_middle =14;
	repeated AppVolume app_volume =15;
	repeated AppComment app_comment =16;
}

message AppStoreId {
	int64 id = 1;
}

message AppImage {
	int64 app_id =1;
	string app_image_src =2;
}

message AppPod {
	int64 app_id =1;
	int64 app_pod_id =2;
}

message AppMiddle{
	int64 app_id =1;
	int64 app_middle_id=2;
}

message AppComment {
	int64 app_id =1;
	string app_comment_title =2;
	string app_comment_detail =3;
	int64 app_user_id =4;
}

message AppVolume{
	int64 app_id =1;
	int64 app_volume_id =2;
}

message FindAll {

}

message Response {
	string msg =1 ;
}

message AllAppStore {
	repeated AppStoreInfo appStore_info = 1;
}

message Number {
	int64 num =1;
}


make proto 

11-7 云应用市场服务端 handler 开发

C:\Users\Administrator\Desktop\gopaas\appstore\handler\appStoreHandler.go

package handler

import (
	"context"
	"strconv"

	log "github.com/asim/go-micro/v3/logger"
	"github.com/yunixiangfeng/gopaas/appStore/domain/model"
	"github.com/yunixiangfeng/gopaas/appStore/domain/service"
	appStore "github.com/yunixiangfeng/gopaas/appStore/proto/appStore"
	"github.com/yunixiangfeng/gopaas/common"
)

type AppStoreHandler struct {
	//注意这里的类型是 IAppStoreDataService 接口类型
	AppStoreDataService service.IAppStoreDataService
}

//添加安装统计
func (e *AppStoreHandler) AddInstallNum(ctx context.Context, req *appStore.AppStoreId, rsp *appStore.Response) error {
	if err := e.AppStoreDataService.AddInstallNum(req.Id); err != nil {
		common.Error(err)
		rsp.Msg = err.Error()
		return err
	}
	rsp.Msg = "统计成功"
	return nil
}

//获取安装数量
func (e *AppStoreHandler) GetInstallNum(ctx context.Context, req *appStore.AppStoreId, rsp *appStore.Number) error {
	rsp.Num = e.AppStoreDataService.GetInstallNum(req.Id)
	return nil
}

//添加查询统计
func (e *AppStoreHandler) AddViewNum(ctx context.Context, req *appStore.AppStoreId, rsp *appStore.Response) error {
	if err := e.AppStoreDataService.AddViewNum(req.Id); err != nil {
		common.Error(err)
		rsp.Msg = err.Error()
		return err
	}
	rsp.Msg = "统计成功"
	return nil
}

//获取查询数量
func (e *AppStoreHandler) GetViewNum(ctx context.Context, req *appStore.AppStoreId, rsp *appStore.Number) error {
	rsp.Num = e.AppStoreDataService.GetViewNum(req.Id)
	return nil

}

// Call is a single request handler called via client.Call or the generated client code
func (e *AppStoreHandler) AddAppStore(ctx context.Context, info *appStore.AppStoreInfo, rsp *appStore.Response) error {
	log.Info("Received *appStore.AddAppStore request")
	appStoreModel := &model.AppStore{}
	if err := common.SwapTo(info, appStoreModel); err != nil {
		common.Error(err)
		rsp.Msg = err.Error()
		return err
	}

	appStoreID, err := e.AppStoreDataService.AddAppStore(appStoreModel)
	if err != nil {
		common.Error(err)
		rsp.Msg = err.Error()
		return err
	}
	rsp.Msg = "应用市场中新应用添加成功 ID 号为:" + strconv.FormatInt(appStoreID, 10)
	common.Info(rsp.Msg)
	return nil
}

func (e *AppStoreHandler) DeleteAppStore(ctx context.Context, req *appStore.AppStoreId, rsp *appStore.Response) error {
	log.Info("Received *appStore.DeleteAppStore request")
	return e.AppStoreDataService.DeleteAppStore(req.Id)
}

func (e *AppStoreHandler) UpdateAppStore(ctx context.Context, req *appStore.AppStoreInfo, rsp *appStore.Response) error {
	log.Info("Received *appStore.UpdateAppStore request")
	appStoreModel, err := e.AppStoreDataService.FindAppStoreByID(req.Id)
	if err != nil {
		common.Error(err)
		return err
	}
	if err := common.SwapTo(req, appStoreModel); err != nil {
		common.Error(err)
		return err
	}
	return e.AppStoreDataService.UpdateAppStore(appStoreModel)
}

func (e *AppStoreHandler) FindAppStoreByID(ctx context.Context, req *appStore.AppStoreId, rsp *appStore.AppStoreInfo) error {
	log.Info("Received *appStore.FindAppStoreByID request")
	appStoreModel, err := e.AppStoreDataService.FindAppStoreByID(req.Id)
	if err != nil {
		common.Error(err)
		return err
	}
	if err := common.SwapTo(appStoreModel, rsp); err != nil {
		common.Error(err)
		return err
	}
	return nil
}

func (e *AppStoreHandler) FindAllAppStore(ctx context.Context, req *appStore.FindAll, rsp *appStore.AllAppStore) error {
	log.Info("Received *appStore.FindAllAppStore request")
	allAppStore, err := e.AppStoreDataService.FindAllAppStore()
	if err != nil {
		common.Error(err)
		return err
	}
	//整理数据格式
	for _, v := range allAppStore {
		appStoreInfo := &appStore.AppStoreInfo{}
		if err := common.SwapTo(v, appStoreInfo); err != nil {
			common.Error(err)
			return err
		}
		rsp.AppStoreInfo = append(rsp.AppStoreInfo, appStoreInfo)
	}
	return nil
}

C:\Users\Administrator\Desktop\gopaas\appstore\main.go

package main

import (
	"flag"
	"fmt"
	"path/filepath"

	"github.com/yunixiangfeng/gopaas/appStore/domain/repository"
	"github.com/yunixiangfeng/gopaas/common"

	//"github.com/afex/hystrix-go/hystrix"
	"github.com/asim/go-micro/plugins/registry/consul/v3"
	ratelimit "github.com/asim/go-micro/plugins/wrapper/ratelimiter/uber/v3"
	opentracing2 "github.com/asim/go-micro/plugins/wrapper/trace/opentracing/v3"
	"github.com/asim/go-micro/v3"
	"github.com/asim/go-micro/v3/registry"
	"github.com/asim/go-micro/v3/server"
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
	"github.com/opentracing/opentracing-go"
	service2 "github.com/yunixiangfeng/gopaas/appStore/domain/service"
	"github.com/yunixiangfeng/gopaas/appStore/handler"

	//hystrix2 "github.com/yunixiangfeng/gopaas/appStore/plugin/hystrix"
	"strconv"

	appStore "github.com/yunixiangfeng/gopaas/appStore/proto/appStore"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/client-go/util/homedir"
)

var (
	//服务地址
	hostIp = "192.168.204.130"
	//服务地址
	serviceHost = hostIp
	//服务端口
	servicePort = "8091"

	//注册中心配置
	consulHost       = hostIp
	consulPort int64 = 8500
	//链路追踪
	tracerHost = hostIp
	tracerPort = 6831
	//熔断端口,每个服务不能重复
	//hystrixPort = 9101
	//监控端口,每个服务不能重复
	prometheusPort = 9201
)

func main() {
	//需要本地启动,mysql,consul中间件服务
	//1.注册中心
	consul := consul.NewRegistry(func(options *registry.Options) {
		options.Addrs = []string{
			consulHost + ":" + strconv.FormatInt(consulPort, 10),
		}
	})
	//2.配置中心,存放经常变动的变量
	consulConfig, err := common.GetConsulConfig(consulHost, consulPort, "/micro/config")
	if err != nil {
		common.Error(err)
	}
	//3.使用配置中心连接 mysql
	mysqlInfo := common.GetMysqlFromConsul(consulConfig, "mysql")
	//初始化数据库
	db, err := gorm.Open("mysql", mysqlInfo.User+":"+mysqlInfo.Pwd+"@("+mysqlInfo.Host+":3306)/"+mysqlInfo.Database+"?charset=utf8&parseTime=True&loc=Local")
	if err != nil {
		//命令行输出下,方便查看错误
		fmt.Println(err)
		common.Fatal(err)
	}
	defer db.Close()
	//禁止复表
	db.SingularTable(true)

	//4.添加链路追踪
	t, io, err := common.NewTracer("go.micro.service.appStore", tracerHost+":"+strconv.Itoa(tracerPort))
	if err != nil {
		common.Error(err)
	}
	defer io.Close()
	opentracing.SetGlobalTracer(t)

	//添加熔断器,作为客户端需要启用
	//hystrixStreamHandler := hystrix.NewStreamHandler()
	//hystrixStreamHandler.Start()

	//添加日志中心
	//1)需要程序日志打入到日志文件中
	//2)在程序中添加filebeat.yml 文件
	//3) 启动filebeat,启动命令 ./filebeat -e -c filebeat.yml
	fmt.Println("日志统一记录在根目录 micro.log 文件中,请点击查看日志!")

	//启动监听程序
	//go func() {
	//	//http://192.168.204.130:9092/turbine/turbine.stream
	//	//看板访问地址 http://127.0.0.1:9002/hystrix,url后面一定要带 /hystrix
	//	err = http.ListenAndServe(net.JoinHostPort("0.0.0.0",strconv.Itoa(hystrixPort)),hystrixStreamHandler)
	//	if err !=nil {
	//		common.Error(err)
	//	}
	//}()

	//5.添加监控
	common.PrometheusBoot(prometheusPort)

	//下载kubectl:https://kubernetes.io/docs/tasks/tools/#tabset-2
	//macos:
	// 1.curl -LO "https://dl.k8s.io/release/v1.21.0/bin/darwin/amd64/kubectl"
	// 2.chmod +x ./kubectl
	// 3.sudo mv ./kubectl /usr/local/bin/kubectl
	//   sudo chown root: /usr/local/bin/kubectl
	// 5.kubectl version --client
	// 6.集群模式下直接拷贝服务端~/.kube/config 文件到本机 ~/.kube/confg 中
	//   注意:- config中的域名要能解析正确
	//        - 生产环境可以创建另一个证书
	// 7.kubectl get ns 查看是否正常
	//
	//6.创建k8s连接
	//在集群外面连接
	var kubeconfig *string
	if home := homedir.HomeDir(); home != "" {
		kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
	} else {
		kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
	}
	flag.Parse()
	config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
	if err != nil {
		common.Fatal(err.Error())
	}

	//在集群中外的配置
	//config, err := rest.InClusterConfig()
	//if err != nil {
	//	panic(err.Error())
	//}

	// create the clientset
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		common.Fatal(err.Error())
	}

	//7.创建服务
	service := micro.NewService(
		//自定义服务地址,且必须写在其它参数前面
		micro.Server(server.NewServer(func(options *server.Options) {
			options.Advertise = serviceHost + ":" + servicePort
		})),
		micro.Name("go.micro.service.appStore"),
		micro.Version("latest"),
		//指定服务端口
		micro.Address(":"+servicePort),
		//添加注册中心
		micro.Registry(consul),
		//添加链路追踪
		micro.WrapHandler(opentracing2.NewHandlerWrapper(opentracing.GlobalTracer())),
		micro.WrapClient(opentracing2.NewClientWrapper(opentracing.GlobalTracer())),
		//只作为客户端的时候起作用,如果存在调用别人的情况,原则上不去主动调用
		//micro.WrapClient(hystrix2.NewClientHystrixWrapper()),
		//添加限流
		micro.WrapHandler(ratelimit.NewHandlerWrapper(1000)),
	)

	service.Init()

	//只能执行一遍
	//err = repository.NewAppStoreRepository(db).InitTable()
	//if err != nil {
	//	common.Fatal(err)
	//}

	// 注册句柄,可以快速操作已开发的服务
	appStoreDataService := service2.NewAppStoreDataService(repository.NewAppStoreRepository(db), clientset)
	appStore.RegisterAppStoreHandler(service.Server(), &handler.AppStoreHandler{AppStoreDataService: appStoreDataService})

	// 启动服务
	if err := service.Run(); err != nil {
		//输出启动失败信息
		common.Fatal(err)
	}
}

11-8 云应用市场APi Proto 开发 

yu-tool.exe  createApi github.com/yunixiangfeng/gopaas/appStoreApi

yu-v3 --proto_path=. --micro_out=. --go_out=:. ./proto/appStoreApi/appStoreApi.proto

go mod tidy

 C:\Users\Administrator\Desktop\gopaas\appstoreapi\proto\appStoreApi\appStoreApi.proto

syntax = "proto3";

package appStoreApi;

option go_package = "./proto/appStoreApi;appStoreApi";

service AppStoreApi {
    rpc FindAppStoreById(Request) returns (Response){}
	rpc AddAppStore(Request) returns (Response){}
	rpc DeleteAppStoreById(Request) returns (Response){}
	rpc UpdateAppStore(Request) returns (Response){}
	//默认接口
	rpc Call(Request) returns (Response){}

	//添加常用的统计接口
	rpc AddInstallNum(Request) returns (Response){}
	rpc GetInstallNum(Request) returns (Response){}
	rpc AddViewNum(Request) returns (Response){}
	rpc GetViewNum(Request) returns (Response){}
}

message Pair {
	string key = 1;
	repeated string values = 2;
}


message Request {
	string method = 1;
	string path = 2;
	map<string, Pair> header = 3;
	map<string, Pair> get = 4;
	map<string, Pair> post = 5;
	string body = 6;
	string url = 7;
}


message Response {
	int32 statusCode = 1;
	map<string, Pair> header = 2;
	string body = 3;
}

C:\Users\Administrator\Desktop\gopaas\appstoreapi\handler\appStoreApiHandler.go

package handler

import (
	"context"
	"encoding/json"
	"errors"
	"strconv"

	log "github.com/asim/go-micro/v3/logger"
	appStore "github.com/yunixiangfeng/gopaas/appStore/proto/appStore"
	appStoreApi "github.com/yunixiangfeng/gopaas/appStoreApi/proto/appStoreApi"
	"github.com/yunixiangfeng/gopaas/common"
)

type AppStoreApi struct {
	AppStoreService appStore.AppStoreService
}

//获取 url 中的应用ID
func (e *AppStoreApi) GetId(req *appStoreApi.Request) (int64, error) {
	if _, ok := req.Get["app_id"]; !ok {
		return 0, errors.New("参数异常")
	}
	//获取到ID后进行转化
	IdString := req.Get["app_id"].Values[0]
	Id, err := strconv.ParseInt(IdString, 10, 64)
	if err != nil {
		common.Error(err)
		return 0, err
	}
	return Id, nil
}

// appStoreApi.FindAppStoreById 通过API向外暴露为/appStoreApi/findAppStoreById,接收http请求
// 即:/appStoreApi/FindAppStoreById 请求会调用go.micro.api.appStoreApi 服务的appStoreApi.FindAppStoreById 方法
func (e *AppStoreApi) FindAppStoreById(ctx context.Context, req *appStoreApi.Request, rsp *appStoreApi.Response) error {
	log.Info("Received appStoreApi.FindAppStoreById request")
	Id, err := e.GetId(req)
	if err != nil {
		common.Error(err)
		return err
	}
	//获取应用市场中应用的相关信息
	info, err := e.AppStoreService.FindAppStoreByID(ctx, &appStore.AppStoreId{
		Id: Id,
	})
	if err != nil {
		common.Error(err)
		return err
	}
	rsp.StatusCode = 200
	b, _ := json.Marshal(info)
	rsp.Body = string(b)
	return nil
}

// appStoreApi.AddAppStore 通过API向外暴露为/appStoreApi/AddAppStore,接收http请求
// 即:/appStoreApi/AddAppStore 请求会调用go.micro.api.appStoreApi 服务的appStoreApi.AddAppStore 方法
func (e *AppStoreApi) AddAppStore(ctx context.Context, req *appStoreApi.Request, rsp *appStoreApi.Response) error {
	log.Info("Received appStoreApi.AddAppStore request")
	addAppStore := &appStore.AppStoreInfo{}
	//进行简单form数据映射
	form.FormToAppStoreStruct(req.Post, addAppStore)
	//设置图片
	e.SetImage(req, addAppStore)
	//设置POD
	e.SetPod(req, addAppStore)
	//设置中间件
	e.SetMiddle(req, addAppStore)
	//设置存储
	e.SetVolume(req, addAppStore)

	//调用后端服务进行更新
	response, err := e.AppStoreService.AddAppStore(ctx, addAppStore)
	if err != nil {
		common.Error(err)
		return err
	}
	rsp.StatusCode = 200
	b, _ := json.Marshal(response)
	rsp.Body = string(b)
	return nil
}

//设置图片
func (e *AppStoreApi) SetImage(req *appStoreApi.Request, appStoreInfo *appStore.AppStoreInfo) {
	dataSlice, ok := req.Post["app_image"]
	if ok {
		imageSlice := []*appStore.AppImage{}
		for _, v := range dataSlice.Values {
			image := &appStore.AppImage{
				AppImageSrc: v,
			}
			imageSlice = append(imageSlice, image)
		}
		appStoreInfo.AppImage = imageSlice
	}
}

//设置POD模板
func (e *AppStoreApi) SetPod(req *appStoreApi.Request, appStoreInfo *appStore.AppStoreInfo) {
	dataSlice, ok := req.Post["app_pod"]
	if ok {
		podSlice := []*appStore.AppPod{}
		for _, v := range dataSlice.Values {
			id, err := strconv.ParseInt(v, 10, 64)
			if err != nil {
				common.Error(err)
				continue
			}
			pod := &appStore.AppPod{
				AppPodId: id,
			}
			podSlice = append(podSlice, pod)
		}
		appStoreInfo.AppPod = podSlice
	}
}

//设置中间件模板
func (e *AppStoreApi) SetMiddle(req *appStoreApi.Request, appStoreInfo *appStore.AppStoreInfo) {
	dataSlice, ok := req.Post["app_middle"]
	if ok {
		middleSlice := []*appStore.AppMiddle{}
		for _, v := range dataSlice.Values {
			id, err := strconv.ParseInt(v, 10, 64)
			if err != nil {
				common.Error(err)
				continue
			}
			middle := &appStore.AppMiddle{
				AppMiddleId: id,
			}
			middleSlice = append(middleSlice, middle)
		}
		appStoreInfo.AppMiddle = middleSlice
	}

}

//设置存储
func (e *AppStoreApi) SetVolume(req *appStoreApi.Request, appStoreInfo *appStore.AppStoreInfo) {
	dataSlice, ok := req.Post["app_volume"]
	if ok {
		volumeSlice := []*appStore.AppVolume{}
		for _, v := range dataSlice.Values {
			id, err := strconv.ParseInt(v, 10, 64)
			if err != nil {
				common.Error(err)
				continue
			}
			volume := &appStore.AppVolume{
				AppVolumeId: id,
			}
			volumeSlice = append(volumeSlice, volume)
		}
		appStoreInfo.AppVolume = volumeSlice
	}
}

// appStoreApi.DeleteAppStoreById 通过API向外暴露为/appStoreApi/DeleteAppStoreById,接收http请求
// 即:/appStoreApi/DeleteAppStoreById 请求会调用go.micro.api.appStoreApi 服务的 appStoreApi.DeleteAppStoreById 方法
func (e *AppStoreApi) DeleteAppStoreById(ctx context.Context, req *appStoreApi.Request, rsp *appStoreApi.Response) error {
	log.Info("Received appStoreApi.DeleteAppStoreById request")
	Id, err := e.GetId(req)
	if err != nil {
		common.Error(err)
		return err
	}
	response, err := e.AppStoreService.DeleteAppStore(ctx, &appStore.AppStoreId{
		Id: Id,
	})
	if err != nil {
		common.Error(err)
		return err
	}
	rsp.StatusCode = 200
	b, _ := json.Marshal(response)
	rsp.Body = string(b)
	return nil
}

// appStoreApi.UpdateAppStore 通过API向外暴露为/appStoreApi/UpdateAppStore,接收http请求
// 即:/appStoreApi/UpdateAppStore 请求会调用go.micro.api.appStoreApi 服务的appStoreApi.UpdateAppStore 方法
func (e *AppStoreApi) UpdateAppStore(ctx context.Context, req *appStoreApi.Request, rsp *appStoreApi.Response) error {
	log.Info("Received appStoreApi.UpdateAppStore request")
	rsp.StatusCode = 200
	b, _ := json.Marshal("{success:'成功访问/appStoreApi/UpdateAppStore'}")
	rsp.Body = string(b)
	return nil
}

// 默认的方法appStoreApi.Call 通过API向外暴露为/appStoreApi/call,接收http请求
// 即:/appStoreApi/call或/appStoreApi/ 请求会调用go.micro.api.appStoreApi 服务的appStoreApi.FindAppStoreById 方法
func (e *AppStoreApi) Call(ctx context.Context, req *appStoreApi.Request, rsp *appStoreApi.Response) error {
	log.Info("Received appStoreApi.Call request")
	rsp.StatusCode = 200
	b, _ := json.Marshal("{success:'成功访问:Call'}")
	rsp.Body = string(b)
	return nil
}

//安装统计接口
func (e *AppStoreApi) AddInstallNum(ctx context.Context, req *appStoreApi.Request, rsp *appStoreApi.Response) error {
	Id, err := e.GetId(req)
	if err != nil {
		common.Error(err)
		return err
	}
	response, err := e.AppStoreService.AddInstallNum(ctx, &appStore.AppStoreId{
		Id: Id,
	})
	if err != nil {
		common.Error(err)
		return err
	}
	rsp.StatusCode = 200
	b, _ := json.Marshal(response)
	rsp.Body = string(b)
	return nil
}

//获取安装数量
func (e *AppStoreApi) GetInstallNum(ctx context.Context, req *appStoreApi.Request, rsp *appStoreApi.Response) error {
	Id, err := e.GetId(req)
	if err != nil {
		common.Error(err)
		return err
	}
	response, err := e.AppStoreService.GetInstallNum(ctx, &appStore.AppStoreId{
		Id: Id,
	})
	if err != nil {
		common.Error(err)
		return err
	}
	rsp.StatusCode = 200
	b, _ := json.Marshal(response)
	rsp.Body = string(b)
	return nil

}

//安装统计接口
func (e *AppStoreApi) AddViewNum(ctx context.Context, req *appStoreApi.Request, rsp *appStoreApi.Response) error {
	Id, err := e.GetId(req)
	if err != nil {
		common.Error(err)
		return err
	}
	response, err := e.AppStoreService.AddViewNum(ctx, &appStore.AppStoreId{
		Id: Id,
	})
	if err != nil {
		common.Error(err)
		return err
	}
	rsp.StatusCode = 200
	b, _ := json.Marshal(response)
	rsp.Body = string(b)
	return nil
}

//获取安装数量
func (e *AppStoreApi) GetViewNum(ctx context.Context, req *appStoreApi.Request, rsp *appStoreApi.Response) error {
	Id, err := e.GetId(req)
	if err != nil {
		common.Error(err)
		return err
	}
	response, err := e.AppStoreService.GetViewNum(ctx, &appStore.AppStoreId{
		Id: Id,
	})
	if err != nil {
		common.Error(err)
		return err
	}
	rsp.StatusCode = 200
	b, _ := json.Marshal(response)
	rsp.Body = string(b)
	return nil

}

file:///C:/Users/Administrator/Desktop/gopaas/go-paas-front/appstore-index.html

11-9 云应用市场 API form 表单处理研发

C:\Users\Administrator\Desktop\gopaas\appstoreapi\plugin\hystrix\form\form.go 

package form

import (
	"errors"
	"sort"
	"strings"

	"reflect"
	"strconv"
	"time"

	"github.com/yunixiangfeng/gopaas/appStoreApi/proto/appStoreApi"
	"github.com/yunixiangfeng/gopaas/common"
)

//判断字符串是否存在
func isIn(target string, strArray []string) bool {
	sort.Strings(strArray)
	index := sort.SearchStrings(strArray, target)
	if index < len(strArray) && strArray[index] == target {
		return true
	}
	return false
}

func FormToAppStoreStruct(data map[string]*appStoreApi.Pair, obj interface{}) {
	objValue := reflect.ValueOf(obj).Elem()
	for i := 0; i < objValue.NumField(); i++ {
		//获取sql对应的值
		dataTag := strings.Replace(objValue.Type().Field(i).Tag.Get("json"), ",omitempty", "", -1)
		dataSlice, ok := data[dataTag]
		if !ok {
			continue
		}
		valueSlice := dataSlice.Values
		if len(valueSlice) <= 0 {
			continue
		}

		//排除列表
		tagList := []string{"app_image", "app_pod", "app_middle", "app_volume", "app_comment"}
		//进行排除
		if isIn(dataTag, tagList) {
			continue
		}
		value := valueSlice[0]

		//端口,环境变量的单独处理
		//获取对应字段的名称
		name := objValue.Type().Field(i).Name

		//获取对应字段类型
		structFieldType := objValue.Field(i).Type()
		//获取变量类型,也可以直接写"string类型"
		val := reflect.ValueOf(value)
		var err error
		if structFieldType != val.Type() {
			//类型转换
			val, err = TypeConversion(value, structFieldType.Name()) //类型转换
			if err != nil {
				common.Error(err)
			}
		}
		//设置类型值
		objValue.FieldByName(name).Set(val)
	}
}

//类型转换
func TypeConversion(value string, ntype string) (reflect.Value, error) {
	if ntype == "string" {
		return reflect.ValueOf(value), nil
	} else if ntype == "time.Time" {
		t, err := time.ParseInLocation("2006-01-02 15:04:05", value, time.Local)
		return reflect.ValueOf(t), err
	} else if ntype == "Time" {
		t, err := time.ParseInLocation("2006-01-02 15:04:05", value, time.Local)
		return reflect.ValueOf(t), err
	} else if ntype == "int" {
		i, err := strconv.Atoi(value)
		return reflect.ValueOf(i), err
	} else if ntype == "int32" {
		i, err := strconv.ParseInt(value, 10, 32)
		if err != nil {
			return reflect.ValueOf(int32(i)), err
		}
		return reflect.ValueOf(int32(i)), err
	} else if ntype == "int64" {
		i, err := strconv.ParseInt(value, 10, 64)
		return reflect.ValueOf(i), err
	} else if ntype == "float32" {
		i, err := strconv.ParseFloat(value, 64)
		return reflect.ValueOf(float32(i)), err
	} else if ntype == "float64" {
		i, err := strconv.ParseFloat(value, 64)
		return reflect.ValueOf(i), err
	}

	//else if .......增加其他一些类型的转换

	return reflect.ValueOf(value), errors.New("未知的类型:" + ntype)
}

11-10 云应用添加应用addAppStore 接口(上)

C:\Users\Administrator\Desktop\gopaas\appstoreapi\handler\appStoreApiHandler.go

// appStoreApi.AddAppStore 通过API向外暴露为/appStoreApi/AddAppStore,接收http请求
// 即:/appStoreApi/AddAppStore 请求会调用go.micro.api.appStoreApi 服务的appStoreApi.AddAppStore 方法
func (e *AppStoreApi) AddAppStore(ctx context.Context, req *appStoreApi.Request, rsp *appStoreApi.Response) error {
	log.Info("Received appStoreApi.AddAppStore request")
	addAppStore := &appStore.AppStoreInfo{}
	//进行简单form数据映射
	form.FormToAppStoreStruct(req.Post, addAppStore)
	//设置图片
	e.SetImage(req, addAppStore)
	//设置POD
	e.SetPod(req, addAppStore)
	//设置中间件
	e.SetMiddle(req, addAppStore)
	//设置存储
	e.SetVolume(req, addAppStore)

	//调用后端服务进行更新
	response, err := e.AppStoreService.AddAppStore(ctx, addAppStore)
	if err != nil {
		common.Error(err)
		return err
	}
	rsp.StatusCode = 200
	b, _ := json.Marshal(response)
	rsp.Body = string(b)
	return nil
}

//设置图片
func (e *AppStoreApi) SetImage(req *appStoreApi.Request, appStoreInfo *appStore.AppStoreInfo) {
	dataSlice, ok := req.Post["app_image"]
	if ok {
		imageSlice := []*appStore.AppImage{}
		for _, v := range dataSlice.Values {
			image := &appStore.AppImage{
				AppImageSrc: v,
			}
			imageSlice = append(imageSlice, image)
		}
		appStoreInfo.AppImage = imageSlice
	}
}

//设置POD模板
func (e *AppStoreApi) SetPod(req *appStoreApi.Request, appStoreInfo *appStore.AppStoreInfo) {
	dataSlice, ok := req.Post["app_pod"]
	if ok {
		podSlice := []*appStore.AppPod{}
		for _, v := range dataSlice.Values {
			id, err := strconv.ParseInt(v, 10, 64)
			if err != nil {
				common.Error(err)
				continue
			}
			pod := &appStore.AppPod{
				AppPodId: id,
			}
			podSlice = append(podSlice, pod)
		}
		appStoreInfo.AppPod = podSlice
	}
}

11-11 云应用addAppStore(中)

C:\Users\Administrator\Desktop\gopaas\appstoreapi\handler\appStoreApiHandler.go

//设置中间件模板
func (e *AppStoreApi) SetMiddle(req *appStoreApi.Request, appStoreInfo *appStore.AppStoreInfo) {
	dataSlice, ok := req.Post["app_middle"]
	if ok {
		middleSlice := []*appStore.AppMiddle{}
		for _, v := range dataSlice.Values {
			id, err := strconv.ParseInt(v, 10, 64)
			if err != nil {
				common.Error(err)
				continue
			}
			middle := &appStore.AppMiddle{
				AppMiddleId: id,
			}
			middleSlice = append(middleSlice, middle)
		}
		appStoreInfo.AppMiddle = middleSlice
	}

}

//设置存储
func (e *AppStoreApi) SetVolume(req *appStoreApi.Request, appStoreInfo *appStore.AppStoreInfo) {
	dataSlice, ok := req.Post["app_volume"]
	if ok {
		volumeSlice := []*appStore.AppVolume{}
		for _, v := range dataSlice.Values {
			id, err := strconv.ParseInt(v, 10, 64)
			if err != nil {
				common.Error(err)
				continue
			}
			volume := &appStore.AppVolume{
				AppVolumeId: id,
			}
			volumeSlice = append(volumeSlice, volume)
		}
		appStoreInfo.AppVolume = volumeSlice
	}
}

11-12 云应用市场API 开发(下)

C:\Users\Administrator\Desktop\gopaas\appstoreapi\handler\appStoreApiHandler.go

//安装统计接口
func (e *AppStoreApi) AddInstallNum(ctx context.Context, req *appStoreApi.Request, rsp *appStoreApi.Response) error {
	Id, err := e.GetId(req)
	if err != nil {
		common.Error(err)
		return err
	}
	response, err := e.AppStoreService.AddInstallNum(ctx, &appStore.AppStoreId{
		Id: Id,
	})
	if err != nil {
		common.Error(err)
		return err
	}
	rsp.StatusCode = 200
	b, _ := json.Marshal(response)
	rsp.Body = string(b)
	return nil
}

//获取安装数量
func (e *AppStoreApi) GetInstallNum(ctx context.Context, req *appStoreApi.Request, rsp *appStoreApi.Response) error {
	Id, err := e.GetId(req)
	if err != nil {
		common.Error(err)
		return err
	}
	response, err := e.AppStoreService.GetInstallNum(ctx, &appStore.AppStoreId{
		Id: Id,
	})
	if err != nil {
		common.Error(err)
		return err
	}
	rsp.StatusCode = 200
	b, _ := json.Marshal(response)
	rsp.Body = string(b)
	return nil

}

//安装统计接口
func (e *AppStoreApi) AddViewNum(ctx context.Context, req *appStoreApi.Request, rsp *appStoreApi.Response) error {
	Id, err := e.GetId(req)
	if err != nil {
		common.Error(err)
		return err
	}
	response, err := e.AppStoreService.AddViewNum(ctx, &appStore.AppStoreId{
		Id: Id,
	})
	if err != nil {
		common.Error(err)
		return err
	}
	rsp.StatusCode = 200
	b, _ := json.Marshal(response)
	rsp.Body = string(b)
	return nil
}

//获取安装数量
func (e *AppStoreApi) GetViewNum(ctx context.Context, req *appStoreApi.Request, rsp *appStoreApi.Response) error {
	Id, err := e.GetId(req)
	if err != nil {
		common.Error(err)
		return err
	}
	response, err := e.AppStoreService.GetViewNum(ctx, &appStore.AppStoreId{
		Id: Id,
	})
	if err != nil {
		common.Error(err)
		return err
	}
	rsp.StatusCode = 200
	b, _ := json.Marshal(response)
	rsp.Body = string(b)
	return nil

}
package handler

import (
	"context"
	"encoding/json"
	"errors"
	"strconv"

	log "github.com/asim/go-micro/v3/logger"
	appStore "github.com/yunixiangfeng/gopaas/appStore/proto/appStore"
	"github.com/yunixiangfeng/gopaas/appStoreApi/plugin/hystrix/form"
	appStoreApi "github.com/yunixiangfeng/gopaas/appStoreApi/proto/appStoreApi"
	"github.com/yunixiangfeng/gopaas/common"
)

type AppStoreApi struct {
	AppStoreService appStore.AppStoreService
}

//获取 url 中的应用ID
func (e *AppStoreApi) GetId(req *appStoreApi.Request) (int64, error) {
	if _, ok := req.Get["app_id"]; !ok {
		return 0, errors.New("参数异常")
	}
	//获取到ID后进行转化
	IdString := req.Get["app_id"].Values[0]
	Id, err := strconv.ParseInt(IdString, 10, 64)
	if err != nil {
		common.Error(err)
		return 0, err
	}
	return Id, nil
}

// appStoreApi.FindAppStoreById 通过API向外暴露为/appStoreApi/findAppStoreById,接收http请求
// 即:/appStoreApi/FindAppStoreById 请求会调用go.micro.api.appStoreApi 服务的appStoreApi.FindAppStoreById 方法
func (e *AppStoreApi) FindAppStoreById(ctx context.Context, req *appStoreApi.Request, rsp *appStoreApi.Response) error {
	log.Info("Received appStoreApi.FindAppStoreById request")
	Id, err := e.GetId(req)
	if err != nil {
		common.Error(err)
		return err
	}
	//获取应用市场中应用的相关信息
	info, err := e.AppStoreService.FindAppStoreByID(ctx, &appStore.AppStoreId{
		Id: Id,
	})
	if err != nil {
		common.Error(err)
		return err
	}
	rsp.StatusCode = 200
	b, _ := json.Marshal(info)
	rsp.Body = string(b)
	return nil
}

// appStoreApi.AddAppStore 通过API向外暴露为/appStoreApi/AddAppStore,接收http请求
// 即:/appStoreApi/AddAppStore 请求会调用go.micro.api.appStoreApi 服务的appStoreApi.AddAppStore 方法
func (e *AppStoreApi) AddAppStore(ctx context.Context, req *appStoreApi.Request, rsp *appStoreApi.Response) error {
	log.Info("Received appStoreApi.AddAppStore request")
	addAppStore := &appStore.AppStoreInfo{}
	//进行简单form数据映射
	form.FormToAppStoreStruct(req.Post, addAppStore)
	//设置图片
	e.SetImage(req, addAppStore)
	//设置POD
	e.SetPod(req, addAppStore)
	//设置中间件
	e.SetMiddle(req, addAppStore)
	//设置存储
	e.SetVolume(req, addAppStore)

	//调用后端服务进行更新
	response, err := e.AppStoreService.AddAppStore(ctx, addAppStore)
	if err != nil {
		common.Error(err)
		return err
	}
	rsp.StatusCode = 200
	b, _ := json.Marshal(response)
	rsp.Body = string(b)
	return nil
}

//设置图片
func (e *AppStoreApi) SetImage(req *appStoreApi.Request, appStoreInfo *appStore.AppStoreInfo) {
	dataSlice, ok := req.Post["app_image"]
	if ok {
		imageSlice := []*appStore.AppImage{}
		for _, v := range dataSlice.Values {
			image := &appStore.AppImage{
				AppImageSrc: v,
			}
			imageSlice = append(imageSlice, image)
		}
		appStoreInfo.AppImage = imageSlice
	}
}

//设置POD模板
func (e *AppStoreApi) SetPod(req *appStoreApi.Request, appStoreInfo *appStore.AppStoreInfo) {
	dataSlice, ok := req.Post["app_pod"]
	if ok {
		podSlice := []*appStore.AppPod{}
		for _, v := range dataSlice.Values {
			id, err := strconv.ParseInt(v, 10, 64)
			if err != nil {
				common.Error(err)
				continue
			}
			pod := &appStore.AppPod{
				AppPodId: id,
			}
			podSlice = append(podSlice, pod)
		}
		appStoreInfo.AppPod = podSlice
	}
}

//设置中间件模板
func (e *AppStoreApi) SetMiddle(req *appStoreApi.Request, appStoreInfo *appStore.AppStoreInfo) {
	dataSlice, ok := req.Post["app_middle"]
	if ok {
		middleSlice := []*appStore.AppMiddle{}
		for _, v := range dataSlice.Values {
			id, err := strconv.ParseInt(v, 10, 64)
			if err != nil {
				common.Error(err)
				continue
			}
			middle := &appStore.AppMiddle{
				AppMiddleId: id,
			}
			middleSlice = append(middleSlice, middle)
		}
		appStoreInfo.AppMiddle = middleSlice
	}

}

//设置存储
func (e *AppStoreApi) SetVolume(req *appStoreApi.Request, appStoreInfo *appStore.AppStoreInfo) {
	dataSlice, ok := req.Post["app_volume"]
	if ok {
		volumeSlice := []*appStore.AppVolume{}
		for _, v := range dataSlice.Values {
			id, err := strconv.ParseInt(v, 10, 64)
			if err != nil {
				common.Error(err)
				continue
			}
			volume := &appStore.AppVolume{
				AppVolumeId: id,
			}
			volumeSlice = append(volumeSlice, volume)
		}
		appStoreInfo.AppVolume = volumeSlice
	}
}

// appStoreApi.DeleteAppStoreById 通过API向外暴露为/appStoreApi/DeleteAppStoreById,接收http请求
// 即:/appStoreApi/DeleteAppStoreById 请求会调用go.micro.api.appStoreApi 服务的 appStoreApi.DeleteAppStoreById 方法
func (e *AppStoreApi) DeleteAppStoreById(ctx context.Context, req *appStoreApi.Request, rsp *appStoreApi.Response) error {
	log.Info("Received appStoreApi.DeleteAppStoreById request")
	Id, err := e.GetId(req)
	if err != nil {
		common.Error(err)
		return err
	}
	response, err := e.AppStoreService.DeleteAppStore(ctx, &appStore.AppStoreId{
		Id: Id,
	})
	if err != nil {
		common.Error(err)
		return err
	}
	rsp.StatusCode = 200
	b, _ := json.Marshal(response)
	rsp.Body = string(b)
	return nil
}

// appStoreApi.UpdateAppStore 通过API向外暴露为/appStoreApi/UpdateAppStore,接收http请求
// 即:/appStoreApi/UpdateAppStore 请求会调用go.micro.api.appStoreApi 服务的appStoreApi.UpdateAppStore 方法
func (e *AppStoreApi) UpdateAppStore(ctx context.Context, req *appStoreApi.Request, rsp *appStoreApi.Response) error {
	log.Info("Received appStoreApi.UpdateAppStore request")
	rsp.StatusCode = 200
	b, _ := json.Marshal("{success:'成功访问/appStoreApi/UpdateAppStore'}")
	rsp.Body = string(b)
	return nil
}

// 默认的方法appStoreApi.Call 通过API向外暴露为/appStoreApi/call,接收http请求
// 即:/appStoreApi/call或/appStoreApi/ 请求会调用go.micro.api.appStoreApi 服务的appStoreApi.FindAppStoreById 方法
func (e *AppStoreApi) Call(ctx context.Context, req *appStoreApi.Request, rsp *appStoreApi.Response) error {
	log.Info("Received appStoreApi.Call request")
	rsp.StatusCode = 200
	b, _ := json.Marshal("{success:'成功访问:Call'}")
	rsp.Body = string(b)
	return nil
}

//安装统计接口
func (e *AppStoreApi) AddInstallNum(ctx context.Context, req *appStoreApi.Request, rsp *appStoreApi.Response) error {
	Id, err := e.GetId(req)
	if err != nil {
		common.Error(err)
		return err
	}
	response, err := e.AppStoreService.AddInstallNum(ctx, &appStore.AppStoreId{
		Id: Id,
	})
	if err != nil {
		common.Error(err)
		return err
	}
	rsp.StatusCode = 200
	b, _ := json.Marshal(response)
	rsp.Body = string(b)
	return nil
}

//获取安装数量
func (e *AppStoreApi) GetInstallNum(ctx context.Context, req *appStoreApi.Request, rsp *appStoreApi.Response) error {
	Id, err := e.GetId(req)
	if err != nil {
		common.Error(err)
		return err
	}
	response, err := e.AppStoreService.GetInstallNum(ctx, &appStore.AppStoreId{
		Id: Id,
	})
	if err != nil {
		common.Error(err)
		return err
	}
	rsp.StatusCode = 200
	b, _ := json.Marshal(response)
	rsp.Body = string(b)
	return nil

}

//安装统计接口
func (e *AppStoreApi) AddViewNum(ctx context.Context, req *appStoreApi.Request, rsp *appStoreApi.Response) error {
	Id, err := e.GetId(req)
	if err != nil {
		common.Error(err)
		return err
	}
	response, err := e.AppStoreService.AddViewNum(ctx, &appStore.AppStoreId{
		Id: Id,
	})
	if err != nil {
		common.Error(err)
		return err
	}
	rsp.StatusCode = 200
	b, _ := json.Marshal(response)
	rsp.Body = string(b)
	return nil
}

//获取安装数量
func (e *AppStoreApi) GetViewNum(ctx context.Context, req *appStoreApi.Request, rsp *appStoreApi.Response) error {
	Id, err := e.GetId(req)
	if err != nil {
		common.Error(err)
		return err
	}
	response, err := e.AppStoreService.GetViewNum(ctx, &appStore.AppStoreId{
		Id: Id,
	})
	if err != nil {
		common.Error(err)
		return err
	}
	rsp.StatusCode = 200
	b, _ := json.Marshal(response)
	rsp.Body = string(b)
	return nil

}

C:\Users\Administrator\Desktop\gopaas\appstoreapi\main.go

package main

import (
	"fmt"

	"github.com/afex/hystrix-go/hystrix"
	"github.com/asim/go-micro/plugins/registry/consul/v3"
	ratelimit "github.com/asim/go-micro/plugins/wrapper/ratelimiter/uber/v3"
	"github.com/asim/go-micro/plugins/wrapper/select/roundrobin/v3"
	opentracing2 "github.com/asim/go-micro/plugins/wrapper/trace/opentracing/v3"
	"github.com/asim/go-micro/v3"
	"github.com/asim/go-micro/v3/registry"
	"github.com/asim/go-micro/v3/server"
	go_micro_service_appStore "github.com/yunixiangfeng/gopaas/appStore/proto/appStore"
	"github.com/yunixiangfeng/gopaas/common"

	"net"
	"net/http"
	"strconv"

	_ "github.com/jinzhu/gorm/dialects/mysql"
	"github.com/opentracing/opentracing-go"
	"github.com/yunixiangfeng/gopaas/appStoreApi/handler"
	hystrix2 "github.com/yunixiangfeng/gopaas/appStoreApi/plugin/hystrix"

	appStoreApi "github.com/yunixiangfeng/gopaas/appStoreApi/proto/appStoreApi"
)

var (
	//服务地址
	hostIp = "192.168.204.130"
	//服务地址
	serviceHost = hostIp
	//服务端口
	servicePort = "8092"
	//注册中心配置
	consulHost       = hostIp
	consulPort int64 = 8500
	//链路追踪
	tracerHost = hostIp
	tracerPort = 6831
	//熔断端口,每个服务不能重复
	hystrixPort = 9102
	//监控端口,每个服务不能重复
	prometheusPort = 9202
)

func main() {
	//需要本地启动,mysql,consul中间件服务
	//1.注册中心
	consul := consul.NewRegistry(func(options *registry.Options) {
		options.Addrs = []string{
			consulHost + ":" + strconv.FormatInt(consulPort, 10),
		}
	})

	//2.添加链路追踪
	t, io, err := common.NewTracer("go.micro.api.appStoreApi", tracerHost+":"+strconv.Itoa(tracerPort))
	if err != nil {
		common.Error(err)
	}
	defer io.Close()
	opentracing.SetGlobalTracer(t)

	//3.添加熔断器
	hystrixStreamHandler := hystrix.NewStreamHandler()
	hystrixStreamHandler.Start()

	//添加日志中心
	//1)需要程序日志打入到日志文件中
	//2)在程序中添加filebeat.yml 文件
	//3) 启动filebeat,启动命令 ./filebeat -e -c filebeat.yml
	fmt.Println("日志统一记录在根目录 micro.log 文件中,请点击查看日志!")

	//启动监听程序
	go func() {
		//http://192.168.204.130:9092/turbine/turbine.stream
		//看板访问地址 http://127.0.0.1:9002/hystrix,url后面一定要带 /hystrix
		err = http.ListenAndServe(net.JoinHostPort("0.0.0.0", strconv.Itoa(hystrixPort)), hystrixStreamHandler)
		if err != nil {
			common.Error(err)
		}
	}()

	//4.添加监控
	common.PrometheusBoot(prometheusPort)

	//5.创建服务
	service := micro.NewService(
		//自定义服务地址,且必须写在其它参数前面
		micro.Server(server.NewServer(func(opts *server.Options) {
			opts.Advertise = serviceHost + ":" + servicePort

		})),
		micro.Name("go.micro.api.appStoreApi"),
		micro.Version("latest"),
		//指定服务端口
		micro.Address(":"+servicePort),
		//添加注册中心
		micro.Registry(consul),
		//添加链路追踪
		micro.WrapHandler(opentracing2.NewHandlerWrapper(opentracing.GlobalTracer())),
		micro.WrapClient(opentracing2.NewClientWrapper(opentracing.GlobalTracer())),
		//只作为客户端的时候起作用
		micro.WrapClient(hystrix2.NewClientHystrixWrapper()),
		//添加限流
		micro.WrapHandler(ratelimit.NewHandlerWrapper(1000)),
		//增加负载均衡
		micro.WrapClient(roundrobin.NewClientWrapper()),
	)

	service.Init()

	// 指定需要访问的服务,可以快速操作已开发的服务,
	// 默认API服务名称带有"Api",程序会自动替换
	// 如果不带有特定字符会使用默认"XXX" 请自行替换
	appStoreService := go_micro_service_appStore.NewAppStoreService("go.micro.service.appStore", service.Client())
	// 注册控制器
	if err := appStoreApi.RegisterAppStoreApiHandler(service.Server(), &handler.AppStoreApi{AppStoreService: appStoreService}); err != nil {
		common.Error(err)
	}

	// 启动服务
	if err := service.Run(); err != nil {
		//输出启动失败信息
		common.Fatal(err)
	}
}

11-13 总结&思考 

主要内容
云市场服务开发
云市场API开发
云市场页面联调

云市场能满足现在哪些场景?
云市场对私有化有哪些帮助?

第12章 云原生GoPaaS平台用户中心,健全验证统一管理

系统规模愈来愈大,人员规模成倍增长,关联的人员需要有精确的权限控制体系。本章通过权限管理,提供PaaS 平台的权限服务,得每个操作都可以进行权限控制,达到精细化管理PaaS 平台的目的。 

12-1云原生平台用户中心-user-role-permission多对多模型开发

GO PaaS 平台用户中心开发

主要内容
用户中心服务开发
用户中心API开发
用户中心页面联调

yu-tool.exe  newService github.com/yunixiangfeng/gopaas/user

yu-v3 --proto_path=. --micro_out=. --go_out=:. ./proto/user/user.proto

go mod tidy

 C:\Users\Administrator\Desktop\gopaas\user\domain\model\user.go

package model

type User struct {
	ID         int64   `gorm:"primary_key;not_null;auto_increment"`
	UserName   string  `gorm:"not_null;unique" json:"user_name"`
	UserEmail  string  `gorm:"not_null;unique" json:"user_email"`
	IsAdmin    bool    `json:"is_admin"`
	UserPwd    string  `json:"user_pwd`
	UserStatus int32   `json:"user_status"`
	Role       []*Role `gorm:"many2many:user_role"`
}

C:\Users\Administrator\Desktop\gopaas\user\domain\model\role.go

package model

type Role struct {
	ID         int64         `gorm:"primary_key;not_null;auto_increment"`
	RoleName   string        `json:"role_name`
	RoleStatus int32         `json:"role_status"`
	Permission []*Permission `gorm:"many2many:role_permission"`
}

C:\Users\Administrator\Desktop\gopaas\user\domain\model\permission.go

package model

type Permission struct {
	ID                 int64  `gorm:"primary_key;not_null;auto_increment"`
	PermissionName     string `json:"permission_name"`
	PermissionDescribe string `json:"permission_describe"`
	PermissionAction   string `json:"permission_action"`
	PermissionStatus   int32  `json:"permission_status"`
}

12-2云原生平台userrepository开发

C:\Users\Administrator\Desktop\gopaas\user\domain\repository\user_repository.go

package repository

import (
	"github.com/jinzhu/gorm"
	"github.com/yunixiangfeng/gopaas/user/domain/model"
)

//创建需要实现的接口
type IUserRepository interface {
	//初始化表
	InitTable() error
	//根据ID查处找数据
	FindUserByID(int64) (*model.User, error)
	//创建一条 user 数据
	CreateUser(*model.User) (int64, error)
	//根据ID删除一条 user 数据
	DeleteUserByID(int64) error
	//修改更新数据
	UpdateUser(*model.User) error
	//查找user所有数据
	FindAll() ([]model.User, error)

	// 分配角色
	AddRole(*model.User, []*model.Role) error
	// 更新用户角色
	UpdateRole(*model.User, []*model.Role) error
	// 删除用户的角色
	DeleteRole(*model.User, []*model.Role) error
	// 判断用户是否有对应的权限
	IsRight(string, int64) bool
}

//创建userRepository
func NewUserRepository(db *gorm.DB) IUserRepository {
	return &UserRepository{mysqlDb: db}
}

type UserRepository struct {
	mysqlDb *gorm.DB
}

// 为已经存在的用户添加角色
func (u *UserRepository) AddRole(user *model.User, roles []*model.Role) error {
	return u.mysqlDb.Model(&user).Association("Role").Append(roles).Error
}

// 更新用户角色
func (u *UserRepository) UpdateRole(user *model.User, roles []*model.Role) error {
	return u.mysqlDb.Model(&user).Association("Role").Replace(roles).Error
}

// 删除用户角色
func (u *UserRepository) DeleteRole(user *model.User, roles []*model.Role) error {
	return u.mysqlDb.Model(&user).Association("Role").Delete(roles).Error
}

// 检测当前用户是否具备权限
func (u *UserRepository) IsRight(action string, userID int64) bool {
	permission := &model.Permission{}
	sql := "select p.id From user u,user_role ur,role r,role_permission rp, permission p WHERE p.permission_action=? AND p.id = rp.permission_id AND rp.role_id=r,id AND ur.role_id AND ur.user_id=u.id AND u.id=?"
	u.mysqlDb.Raw(sql, action, userID).Scan(permission)
	// 可以写其它判断逻辑
	if permission.ID > 0 {
		return true
	}
	return false
}

//初始化表
func (u *UserRepository) InitTable() error {
	return u.mysqlDb.CreateTable(&model.User{}, &model.Role{}, &model.Permission{}).Error
}

//根据ID查找User信息
func (u *UserRepository) FindUserByID(userID int64) (user *model.User, err error) {
	user = &model.User{}
	return user, u.mysqlDb.First(user, userID).Error
}

//创建User信息
func (u *UserRepository) CreateUser(user *model.User) (int64, error) {
	return user.ID, u.mysqlDb.Create(user).Error
}

//根据ID删除User信息
func (u *UserRepository) DeleteUserByID(userID int64) error {
	return u.mysqlDb.Where("id = ?", userID).Delete(&model.User{}).Error
}

//更新User信息
func (u *UserRepository) UpdateUser(user *model.User) error {
	return u.mysqlDb.Model(user).Update(user).Error
}

//获取结果集
func (u *UserRepository) FindAll() (userAll []model.User, err error) {
	return userAll, u.mysqlDb.Find(&userAll).Error
}

12-3用户中心-角色-repository开发

C:\Users\Administrator\Desktop\gopaas\user\domain\repository\role_respository.go

package repository

import (
	"github.com/jinzhu/gorm"
	"github.com/yunixiangfeng/gopaas/user/domain/model"
)

//创建需要实现的接口
type IRoleRepository interface {
	//根据ID查找role 数据
	FindRoleByID(int64) (*model.Role, error)
	//创建一条 role 数据
	CreateRole(*model.Role) (int64, error)
	//根据ID删除一条 role 数据
	DeleteRoleByID(int64) error
	//修改更新数据
	UpdateRole(*model.Role) error
	//查找role所有数据
	FindAll() ([]model.Role, error)

	// 根据ID查找所有角色
	FindAllRoleById([]int64) ([]*model.Role, error)

	// 添加角色权限
	AddPermission(*model.Role, []*model.Permission) error
	// 更新角色权限
	UpdatePermission(*model.Role, []*model.Permission) error
	// 删除角色权限
	DeletePermission(*model.Role, []*model.Permission) error
}

//创建RoleRepository
func NewRoleRepository(db *gorm.DB) IRoleRepository {
	return &RoleRepository{mysqlDb: db}
}

type RoleRepository struct {
	mysqlDb *gorm.DB
}

// 根据ID查找所有角色
func (u *RoleRepository) FindAllRoleById(id []int64) (roleAll []*model.Role, err error) {
	return roleAll, u.mysqlDb.Find(&roleAll, id).Error
}

// 添加角色权限
func (u *RoleRepository) AddPermission(role *model.Role, permission []*model.Permission) error {
	return u.mysqlDb.Model(&role).Association("Permission").Append(permission).Error
}

// 更新角色权限
func (u *RoleRepository) UpdatePermission(role *model.Role, permission []*model.Permission) error {
	return u.mysqlDb.Model(&role).Association("Permission").Append(permission).Error
}

// 删除角色权限
func (u *RoleRepository) DeletePermission(role *model.Role, permission []*model.Permission) error {
	return u.mysqlDb.Model(&role).Association("Permission").Delete(permission).Error
}

// 为已经存在的用户添加角色
func (u *RoleRepository) AddRole(role *model.Role, roles []*model.Role) error {
	return u.mysqlDb.Model(&role).Association("Role").Append(roles).Error
}

//根据ID查找Role信息
func (u *RoleRepository) FindRoleByID(roleID int64) (role *model.Role, err error) {
	role = &model.Role{}
	return role, u.mysqlDb.Preload("Permission").First(role, roleID).Error
}

//创建Role信息
func (u *RoleRepository) CreateRole(role *model.Role) (int64, error) {
	return role.ID, u.mysqlDb.Create(role).Error
}

//根据ID删除Role信息
func (u *RoleRepository) DeleteRoleByID(roleID int64) error {
	return u.mysqlDb.Where("id = ?", roleID).Delete(&model.Role{}).Error
}

//更新Role信息
func (u *RoleRepository) UpdateRole(role *model.Role) error {
	return u.mysqlDb.Model(role).Update(role).Error
}

//获取结果集
func (u *RoleRepository) FindAll() (roleAll []model.Role, err error) {
	return roleAll, u.mysqlDb.Find(&roleAll).Error
}

12-4用户中心-权限-repository开发

C:\Users\Administrator\Desktop\gopaas\user\domain\repository\permission_respository.go

package repository

import (
	"github.com/jinzhu/gorm"
	"github.com/yunixiangfeng/gopaas/user/domain/model"
)

//创建需要实现的接口
type IPermissionRepository interface {
	//根据ID查找permission数据
	FindPermissionByID(int64) (*model.Permission, error)
	//创建一条 permission 数据
	CreatePermission(*model.Permission) (int64, error)
	//根据ID删除一条 permission 数据
	DeletePermissionByID(int64) error
	//修改更新数据
	UpdatePermission(*model.Permission) error
	//查找permission所有数据
	FindAll() ([]model.Permission, error)

	// 根据ID查找所有权限
	FindAllPermissionById(int64) ([]*model.Permission, error)
}

//创建PermissionRepository
func NewPermissionRepository(db *gorm.DB) IPermissionRepository {
	return &PermissionRepository{mysqlDb: db}
}

type PermissionRepository struct {
	mysqlDb *gorm.DB
}

//根据ID查找Permission信息
func (u *PermissionRepository) FindPermissionByID(permissionID int64) (permission *model.Permission, err error) {
	permission = &model.Permission{}
	return permission, u.mysqlDb.First(permission, permissionID).Error
}

//创建Permission信息
func (u *PermissionRepository) CreatePermission(permission *model.Permission) (int64, error) {
	return permission.ID, u.mysqlDb.Create(permission).Error
}

//根据ID删除Permission信息
func (u *PermissionRepository) DeletePermissionByID(permissionID int64) error {
	return u.mysqlDb.Where("id = ?", permissionID).Delete(&model.Permission{}).Error
}

//更新Permission信息
func (u *PermissionRepository) UpdatePermission(permission *model.Permission) error {
	return u.mysqlDb.Model(permission).Update(permission).Error
}

//获取结果集
func (u *PermissionRepository) FindAll() (permissionAll []model.Permission, err error) {
	return permissionAll, u.mysqlDb.Find(&permissionAll).Error
}

// 根据ID查找所有权限
func (u *PermissionRepository) FindAllPermissionById(id int64) (permissionAll []*model.Permission, err error) {
	return permissionAll, u.mysqlDb.Find(&permissionAll, id).Error
}

12-5用户中心-权限-repository开发

C:\Users\Administrator\Desktop\gopaas\user\domain\repository\permission_respository.go

同上

12-6用户中心-user-service开发

C:\Users\Administrator\Desktop\gopaas\user\domain\service\user_data_service.go

package service

import (
	"github.com/yunixiangfeng/gopaas/user/domain/model"
	"github.com/yunixiangfeng/gopaas/user/domain/repository"
	v1 "k8s.io/api/apps/v1"
	"k8s.io/client-go/kubernetes"
)

//这里是接口类型
type IUserDataService interface {
	AddUser(*model.User) (int64, error)
	DeleteUser(int64) error
	UpdateUser(*model.User) error
	FindUserByID(int64) (*model.User, error)
	FindAllUser() ([]model.User, error)

	// 分配角色
	AddRole(*model.User, []*model.Role) error
	UpdateRole(*model.User, []*model.Role) error
	DeleteRole(*model.User, []*model.Role) error
	// 判断用户是否有权限
	IsRight(string, int64) bool
}

//创建
//注意:返回值 IUserDataService 接口类型
func NewUserDataService(userRepository repository.IUserRepository, clientSet *kubernetes.Clientset) IUserDataService {
	return &UserDataService{UserRepository: userRepository, K8sClientSet: clientSet, deployment: &v1.Deployment{}}
}

type UserDataService struct {
	//注意:这里是 IUserRepository 类型
	UserRepository repository.IUserRepository
}

// 分配角色
func (u *UserDataService) AddRole(user *model.User, role []*model.Role) error {
	return u.UserRepository.AddRole(user, role)
}
func (u *UserDataService) UpdateRole(user *model.User, role []*model.Role) error {
	return u.UserRepository.UpdateRole(user, role)
}

func (u *UserDataService) DeleteRole(user *model.User, role []*model.Role) error {
	return u.UserRepository.DeleteRole(user, role)
}

// 判断用户是否有权限
func (u *UserDataService) IsRight(action string, userID int64) bool {
	return u.UserRepository.IsRight(action, userID)
}

//插入
func (u *UserDataService) AddUser(user *model.User) (int64, error) {
	return u.UserRepository.CreateUser(user)
}

//删除
func (u *UserDataService) DeleteUser(userID int64) error {
	return u.UserRepository.DeleteUserByID(userID)
}

//更新
func (u *UserDataService) UpdateUser(user *model.User) error {
	return u.UserRepository.UpdateUser(user)
}

//查找
func (u *UserDataService) FindUserByID(userID int64) (*model.User, error) {
	return u.UserRepository.FindUserByID(userID)
}

//查找
func (u *UserDataService) FindAllUser() ([]model.User, error) {
	return u.UserRepository.FindAll()
}

12-7用户中心-role-service开发

C:\Users\Administrator\Desktop\gopaas\user\domain\service\role_data_service.go

package service

import (
	"github.com/yunixiangfeng/gopaas/user/domain/model"
	"github.com/yunixiangfeng/gopaas/user/domain/repository"
	"k8s.io/client-go/kubernetes"
)

//这里是接口类型
type IRoleDataService interface {
	AddRole(*model.Role) (int64, error)
	DeleteRole(int64) error
	UpdateRole(*model.Role) error
	FindRoleByID(int64) (*model.Role, error)
	FindAllRole() ([]model.Role, error)

	// 根据ID查找所有角色
	FindAllRoleByID([]int64) ([]*model.Role, error)

	// 添加权限
	AddPermission(*model.Role, []*model.Permission) error
	UpdatePermission(*model.Role, []*model.Permission) error
	DeletePermission(*model.Role, []*model.Permission) error
}

//创建
//注意:返回值 IRoleDataService 接口类型
func NewRoleDataService(roleRepository repository.IRoleRepository, clientSet *kubernetes.Clientset) IRoleDataService {
	return &RoleDataService{RoleRepository: roleRepository}
}

type RoleDataService struct {
	//注意:这里是 IRoleRepository 类型
	RoleRepository repository.IRoleRepository
}

// 根据ID查找所有角色
func (u *RoleDataService) FindAllRoleByID(id []int64) (roleAll []*model.Role, err error) {
	return u.RoleRepository.FindAllRoleById(id)
}

// 添加权限
func (u *RoleDataService) AddPermission(role *model.Role, permission []*model.Permission) error {
	return u.RoleRepository.AddPermission(role, permission)
}

func (u *RoleDataService) UpdatePermission(role *model.Role, permission []*model.Permission) error {
	return u.RoleRepository.UpdatePermission(role, permission)
}

func (u *RoleDataService) DeletePermission(role *model.Role, permission []*model.Permission) error {
	return u.RoleRepository.DeletePermission(role, permission)
}

//插入
func (u *RoleDataService) AddRole(role *model.Role) (int64, error) {
	return u.RoleRepository.CreateRole(role)
}

//删除
func (u *RoleDataService) DeleteRole(roleID int64) error {
	return u.RoleRepository.DeleteRoleByID(roleID)
}

//更新
func (u *RoleDataService) UpdateRole(role *model.Role) error {
	return u.RoleRepository.UpdateRole(role)
}

//查找
func (u *RoleDataService) FindRoleByID(roleID int64) (*model.Role, error) {
	return u.RoleRepository.FindRoleByID(roleID)
}

//查找
func (u *RoleDataService) FindAllRole() ([]model.Role, error) {
	return u.RoleRepository.FindAll()
}

12-8用户中心-权限-service开发

C:\Users\Administrator\Desktop\gopaas\user\domain\service\permission_data_service.go

package service

import (
	"github.com/yunixiangfeng/gopaas/user/domain/model"
	"github.com/yunixiangfeng/gopaas/user/domain/repository"
	"k8s.io/client-go/kubernetes"
)

//这里是接口类型
type IPermissionDataService interface {
	AddPermission(*model.Permission) (int64, error)
	DeletePermission(int64) error
	UpdatePermission(*model.Permission) error
	FindPermissionByID(int64) (*model.Permission, error)
	FindAllPermission() ([]model.Permission, error)

	// 根据ID查询所有权限
	FindAllPermissionByID([]int64) ([]*model.Permission, error)
}

//创建
//注意:返回值 IPermissionDataService 接口类型
func NewPermissionDataService(permissionRepository repository.IPermissionRepository, clientSet *kubernetes.Clientset) IPermissionDataService {
	return &PermissionDataService{PermissionRepository: permissionRepository}
}

type PermissionDataService struct {
	//注意:这里是 IPermissionRepository 类型
	PermissionRepository repository.IPermissionRepository
}

// 根据ID查询所有权限
func (u *PermissionDataService) FindAllPermissionByID(id []int64) ([]*model.Permission, error) {
	return u.PermissionRepository.FindAllPermissionById(id)
}

//插入
func (u *PermissionDataService) AddPermission(permission *model.Permission) (int64, error) {
	return u.PermissionRepository.CreatePermission(permission)
}

//删除
func (u *PermissionDataService) DeletePermission(permissionID int64) error {
	return u.PermissionRepository.DeletePermissionByID(permissionID)
}

//更新
func (u *PermissionDataService) UpdatePermission(permission *model.Permission) error {
	return u.PermissionRepository.UpdatePermission(permission)
}

//查找
func (u *PermissionDataService) FindPermissionByID(permissionID int64) (*model.Permission, error) {
	return u.PermissionRepository.FindPermissionByID(permissionID)
}

//查找
func (u *PermissionDataService) FindAllPermission() ([]model.Permission, error) {
	return u.PermissionRepository.FindAll()
}

12-9用户中心-user-proto开发

C:\Users\Administrator\Desktop\gopaas\user\proto\user\user.proto

syntax = "proto3";

package user;

option go_package = "./proto/user;user";

service User {
	//对外提供添加服务
	rpc AddUser(UserInfo) returns (Response) {}
	rpc DeleteUser(UserId) returns (Response) {}
	rpc UpdateUser(UserInfo) returns (Response) {}
	rpc FindUserByID(UserId) returns (UserInfo) {}
	rpc FindAllUser(FindAll) returns (AllUser) {}

	// 
	rpc AddRole(UserRole) returns (Response) {}
	rpc UpdateRole(UserRole) returns (Response) {}
	rpc DeleteRole(UserRole) returns (Response) {}

	rpc IsRight(UserRight) returns (Right) {}
}

message UserRole {
	int64 user_id=1;
	repeated int64 role_id=2;
}

message UserRight {
	int64 user_id = 1;
	string action =2;
}

message Right {
	bool access =1;
}

message UserInfo {
	int64 id = 1;
	string user_name =2;
	string user_email =3;
	bool is_admin =4;
	string user_pwd =5;
	int32 user_status = 6;
}

message UserId {
	int64 id = 1;
}

message FindAll {

}

message Response {
	string msg =1 ;
}

message AllUser {
	repeated UserInfo user_info = 1;
}


12-10用户中心-角色-权限-proto开发及生成

C:\Users\Administrator\Desktop\gopaas\user\proto\role\role.proto

syntax = "proto3";

package role;

option go_package = "./proto/role;role";

service Role {
	//对外提供添加服务
	rpc AddRole(RoleInfo) returns (Response) {}
	rpc DeleteRole(RoleId) returns (Response) {}
	rpc UpdateRole(RoleInfo) returns (Response) {}
	rpc FindRoleByID(RoleId) returns (RoleInfo) {}
	rpc FindAllRole(FindAll) returns (AllRole) {}

	// 
	rpc AddPermission(RolePermission) returns (Response) {}
	rpc UpdatePermission(RolePermission) returns (Response) {}
	rpc DeletePermission(RolePermission) returns (Response) {}
}

message RolePermission {
	int64 role_id =1;
	repeated int64 permission_id =2;
}

message RoleInfo {
	int64 id = 1;
	string role_name =2;
	int32 role_status = 3;
}

message RoleId {
	int64 id = 1;
}

message FindAll {

}

message Response {
	string msg =1 ;
}

message AllRole {
	repeated RoleInfo role_info = 1;
}


 C:\Users\Administrator\Desktop\gopaas\user\proto\permission\permission.proto

syntax = "proto3";

package permission;

option go_package = "./proto/permission;permission";

service Permission {
	//对外提供添加服务
	rpc AddPermission(PermissionInfo) returns (Response) {}
	rpc DeletePermission(PermissionId) returns (Response) {}
	rpc UpdatePermission(PermissionInfo) returns (Response) {}
	rpc FindPermissionByID(PermissionId) returns (PermissionInfo) {}
	rpc FindAllPermission(FindAll) returns (AllPermission) {}

}


message PermissionInfo {
	int64 id = 1;
	string permission_name =2;
	string permission_describe =3;
	string permission_action = 4;
	int32 permission_status = 5;
}

message PermissionId {
	int64 id = 1;
}

message FindAll {

}

message Response {
	string msg =1 ;
}

message AllPermission {
	repeated PermissionInfo permission_info = 1;
}


PS D:\Workspace\Go\bin> D:\Workspace\Go\bin\protoc.exe --proto_path=C:\Users\Administrator\Desktop\gopaas\user --micro_out=C:\Users\Administrator\Desktop\gopaas\user --go_out=:C:\Users\Administrator\Desktop\gopaas\user C:\Users\Administrator\Desktop\gopaas\user\proto\user\user.proto
PS D:\Workspace\Go\bin> D:\Workspace\Go\bin\protoc.exe --proto_path=C:\Users\Administrator\Desktop\gopaas\user --micro_out=C:\Users\Administrator\Desktop\gopaas\user --go_out=:C:\Users\Administrator\Desktop\gopaas\user C:\Users\Administrator\Desktop\gopaas\user\proto\role\role.proto
PS D:\Workspace\Go\bin> D:\Workspace\Go\bin\protoc.exe --proto_path=C:\Users\Administrator\Desktop\gopaas\user --micro_out=C:\Users\Administrator\Desktop\gopaas\user --go_out=:C:\Users\Administrator\Desktop\gopaas\user C:\Users\Administrator\Desktop\gopaas\user\proto\permission\permission.proto 

C:\Users\Administrator\Desktop\gopaas\user\proto\user\user.pb.micro.go

// Code generated by protoc-gen-micro. DO NOT EDIT.
// source: proto/user/user.proto

package user

import (
	fmt "fmt"
	proto "google.golang.org/protobuf/proto"
	math "math"
)

import (
	context "context"
	api "github.com/asim/go-micro/v3/api"
	client "github.com/asim/go-micro/v3/client"
	server "github.com/asim/go-micro/v3/server"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// Reference imports to suppress errors if they are not otherwise used.
var _ api.Endpoint
var _ context.Context
var _ client.Option
var _ server.Option

// Api Endpoints for User service

func NewUserEndpoints() []*api.Endpoint {
	return []*api.Endpoint{}
}

// Client API for User service

type UserService interface {
	//对外提供添加服务
	AddUser(ctx context.Context, in *UserInfo, opts ...client.CallOption) (*Response, error)
	DeleteUser(ctx context.Context, in *UserId, opts ...client.CallOption) (*Response, error)
	UpdateUser(ctx context.Context, in *UserInfo, opts ...client.CallOption) (*Response, error)
	FindUserByID(ctx context.Context, in *UserId, opts ...client.CallOption) (*UserInfo, error)
	FindAllUser(ctx context.Context, in *FindAll, opts ...client.CallOption) (*AllUser, error)
	// 添加常用的接口
	AddRole(ctx context.Context, in *UserRole, opts ...client.CallOption) (*Response, error)
	UpdateRole(ctx context.Context, in *UserRole, opts ...client.CallOption) (*Response, error)
	DeleteRole(ctx context.Context, in *UserRole, opts ...client.CallOption) (*Response, error)
	IsRight(ctx context.Context, in *UserRight, opts ...client.CallOption) (*Right, error)
}

type userService struct {
	c    client.Client
	name string
}

func NewUserService(name string, c client.Client) UserService {
	if c == nil {
		c = client.NewClient()
	}
	if len(name) == 0 {
		name = "user"
	}
	return &userService{
		c:    c,
		name: name,
	}
}

func (c *userService) AddUser(ctx context.Context, in *UserInfo, opts ...client.CallOption) (*Response, error) {
	req := c.c.NewRequest(c.name, "User.AddUser", in)
	out := new(Response)
	err := c.c.Call(ctx, req, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *userService) DeleteUser(ctx context.Context, in *UserId, opts ...client.CallOption) (*Response, error) {
	req := c.c.NewRequest(c.name, "User.DeleteUser", in)
	out := new(Response)
	err := c.c.Call(ctx, req, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *userService) UpdateUser(ctx context.Context, in *UserInfo, opts ...client.CallOption) (*Response, error) {
	req := c.c.NewRequest(c.name, "User.UpdateUser", in)
	out := new(Response)
	err := c.c.Call(ctx, req, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *userService) FindUserByID(ctx context.Context, in *UserId, opts ...client.CallOption) (*UserInfo, error) {
	req := c.c.NewRequest(c.name, "User.FindUserByID", in)
	out := new(UserInfo)
	err := c.c.Call(ctx, req, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *userService) FindAllUser(ctx context.Context, in *FindAll, opts ...client.CallOption) (*AllUser, error) {
	req := c.c.NewRequest(c.name, "User.FindAllUser", in)
	out := new(AllUser)
	err := c.c.Call(ctx, req, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *userService) AddRole(ctx context.Context, in *UserRole, opts ...client.CallOption) (*Response, error) {
	req := c.c.NewRequest(c.name, "User.AddRole", in)
	out := new(Response)
	err := c.c.Call(ctx, req, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *userService) UpdateRole(ctx context.Context, in *UserRole, opts ...client.CallOption) (*Response, error) {
	req := c.c.NewRequest(c.name, "User.UpdateRole", in)
	out := new(Response)
	err := c.c.Call(ctx, req, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *userService) DeleteRole(ctx context.Context, in *UserRole, opts ...client.CallOption) (*Response, error) {
	req := c.c.NewRequest(c.name, "User.DeleteRole", in)
	out := new(Response)
	err := c.c.Call(ctx, req, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *userService) IsRight(ctx context.Context, in *UserRight, opts ...client.CallOption) (*Right, error) {
	req := c.c.NewRequest(c.name, "User.IsRight", in)
	out := new(Right)
	err := c.c.Call(ctx, req, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// Server API for User service

type UserHandler interface {
	//对外提供添加服务
	AddUser(context.Context, *UserInfo, *Response) error
	DeleteUser(context.Context, *UserId, *Response) error
	UpdateUser(context.Context, *UserInfo, *Response) error
	FindUserByID(context.Context, *UserId, *UserInfo) error
	FindAllUser(context.Context, *FindAll, *AllUser) error
	// 添加常用的接口
	AddRole(context.Context, *UserRole, *Response) error
	UpdateRole(context.Context, *UserRole, *Response) error
	DeleteRole(context.Context, *UserRole, *Response) error
	IsRight(context.Context, *UserRight, *Right) error
}

func RegisterUserHandler(s server.Server, hdlr UserHandler, opts ...server.HandlerOption) error {
	type user interface {
		AddUser(ctx context.Context, in *UserInfo, out *Response) error
		DeleteUser(ctx context.Context, in *UserId, out *Response) error
		UpdateUser(ctx context.Context, in *UserInfo, out *Response) error
		FindUserByID(ctx context.Context, in *UserId, out *UserInfo) error
		FindAllUser(ctx context.Context, in *FindAll, out *AllUser) error
		AddRole(ctx context.Context, in *UserRole, out *Response) error
		UpdateRole(ctx context.Context, in *UserRole, out *Response) error
		DeleteRole(ctx context.Context, in *UserRole, out *Response) error
		IsRight(ctx context.Context, in *UserRight, out *Right) error
	}
	type User struct {
		user
	}
	h := &userHandler{hdlr}
	return s.Handle(s.NewHandler(&User{h}, opts...))
}

type userHandler struct {
	UserHandler
}

func (h *userHandler) AddUser(ctx context.Context, in *UserInfo, out *Response) error {
	return h.UserHandler.AddUser(ctx, in, out)
}

func (h *userHandler) DeleteUser(ctx context.Context, in *UserId, out *Response) error {
	return h.UserHandler.DeleteUser(ctx, in, out)
}

func (h *userHandler) UpdateUser(ctx context.Context, in *UserInfo, out *Response) error {
	return h.UserHandler.UpdateUser(ctx, in, out)
}

func (h *userHandler) FindUserByID(ctx context.Context, in *UserId, out *UserInfo) error {
	return h.UserHandler.FindUserByID(ctx, in, out)
}

func (h *userHandler) FindAllUser(ctx context.Context, in *FindAll, out *AllUser) error {
	return h.UserHandler.FindAllUser(ctx, in, out)
}

func (h *userHandler) AddRole(ctx context.Context, in *UserRole, out *Response) error {
	return h.UserHandler.AddRole(ctx, in, out)
}

func (h *userHandler) UpdateRole(ctx context.Context, in *UserRole, out *Response) error {
	return h.UserHandler.UpdateRole(ctx, in, out)
}

func (h *userHandler) DeleteRole(ctx context.Context, in *UserRole, out *Response) error {
	return h.UserHandler.DeleteRole(ctx, in, out)
}

func (h *userHandler) IsRight(ctx context.Context, in *UserRight, out *Right) error {
	return h.UserHandler.IsRight(ctx, in, out)
}

 C:\Users\Administrator\Desktop\gopaas\user\proto\user\user.pb.go

// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.30.0
// 	protoc        v4.23.1
// source: proto/user/user.proto

package user

import (
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
	reflect "reflect"
	sync "sync"
)

const (
	// Verify that this generated code is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
	// Verify that runtime/protoimpl is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)

type UserRole struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	UserId int64   `protobuf:"varint,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
	RoleId []int64 `protobuf:"varint,2,rep,packed,name=role_id,json=roleId,proto3" json:"role_id,omitempty"`
}

func (x *UserRole) Reset() {
	*x = UserRole{}
	if protoimpl.UnsafeEnabled {
		mi := &file_proto_user_user_proto_msgTypes[0]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *UserRole) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*UserRole) ProtoMessage() {}

func (x *UserRole) ProtoReflect() protoreflect.Message {
	mi := &file_proto_user_user_proto_msgTypes[0]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use UserRole.ProtoReflect.Descriptor instead.
func (*UserRole) Descriptor() ([]byte, []int) {
	return file_proto_user_user_proto_rawDescGZIP(), []int{0}
}

func (x *UserRole) GetUserId() int64 {
	if x != nil {
		return x.UserId
	}
	return 0
}

func (x *UserRole) GetRoleId() []int64 {
	if x != nil {
		return x.RoleId
	}
	return nil
}

type UserRight struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	UserId int64  `protobuf:"varint,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
	Action string `protobuf:"bytes,2,opt,name=action,proto3" json:"action,omitempty"`
}

func (x *UserRight) Reset() {
	*x = UserRight{}
	if protoimpl.UnsafeEnabled {
		mi := &file_proto_user_user_proto_msgTypes[1]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *UserRight) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*UserRight) ProtoMessage() {}

func (x *UserRight) ProtoReflect() protoreflect.Message {
	mi := &file_proto_user_user_proto_msgTypes[1]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use UserRight.ProtoReflect.Descriptor instead.
func (*UserRight) Descriptor() ([]byte, []int) {
	return file_proto_user_user_proto_rawDescGZIP(), []int{1}
}

func (x *UserRight) GetUserId() int64 {
	if x != nil {
		return x.UserId
	}
	return 0
}

func (x *UserRight) GetAction() string {
	if x != nil {
		return x.Action
	}
	return ""
}

type Right struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Access bool `protobuf:"varint,1,opt,name=access,proto3" json:"access,omitempty"`
}

func (x *Right) Reset() {
	*x = Right{}
	if protoimpl.UnsafeEnabled {
		mi := &file_proto_user_user_proto_msgTypes[2]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *Right) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*Right) ProtoMessage() {}

func (x *Right) ProtoReflect() protoreflect.Message {
	mi := &file_proto_user_user_proto_msgTypes[2]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use Right.ProtoReflect.Descriptor instead.
func (*Right) Descriptor() ([]byte, []int) {
	return file_proto_user_user_proto_rawDescGZIP(), []int{2}
}

func (x *Right) GetAccess() bool {
	if x != nil {
		return x.Access
	}
	return false
}

type UserInfo struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Id         int64  `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
	UserName   string `protobuf:"bytes,2,opt,name=user_name,json=userName,proto3" json:"user_name,omitempty"`
	UserEmail  string `protobuf:"bytes,3,opt,name=user_email,json=userEmail,proto3" json:"user_email,omitempty"`
	IsAdmin    bool   `protobuf:"varint,4,opt,name=is_admin,json=isAdmin,proto3" json:"is_admin,omitempty"`
	UserPwd    string `protobuf:"bytes,5,opt,name=user_pwd,json=userPwd,proto3" json:"user_pwd,omitempty"`
	UserStatus int32  `protobuf:"varint,6,opt,name=user_status,json=userStatus,proto3" json:"user_status,omitempty"`
}

func (x *UserInfo) Reset() {
	*x = UserInfo{}
	if protoimpl.UnsafeEnabled {
		mi := &file_proto_user_user_proto_msgTypes[3]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *UserInfo) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*UserInfo) ProtoMessage() {}

func (x *UserInfo) ProtoReflect() protoreflect.Message {
	mi := &file_proto_user_user_proto_msgTypes[3]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use UserInfo.ProtoReflect.Descriptor instead.
func (*UserInfo) Descriptor() ([]byte, []int) {
	return file_proto_user_user_proto_rawDescGZIP(), []int{3}
}

func (x *UserInfo) GetId() int64 {
	if x != nil {
		return x.Id
	}
	return 0
}

func (x *UserInfo) GetUserName() string {
	if x != nil {
		return x.UserName
	}
	return ""
}

func (x *UserInfo) GetUserEmail() string {
	if x != nil {
		return x.UserEmail
	}
	return ""
}

func (x *UserInfo) GetIsAdmin() bool {
	if x != nil {
		return x.IsAdmin
	}
	return false
}

func (x *UserInfo) GetUserPwd() string {
	if x != nil {
		return x.UserPwd
	}
	return ""
}

func (x *UserInfo) GetUserStatus() int32 {
	if x != nil {
		return x.UserStatus
	}
	return 0
}

type UserId struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
}

func (x *UserId) Reset() {
	*x = UserId{}
	if protoimpl.UnsafeEnabled {
		mi := &file_proto_user_user_proto_msgTypes[4]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *UserId) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*UserId) ProtoMessage() {}

func (x *UserId) ProtoReflect() protoreflect.Message {
	mi := &file_proto_user_user_proto_msgTypes[4]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use UserId.ProtoReflect.Descriptor instead.
func (*UserId) Descriptor() ([]byte, []int) {
	return file_proto_user_user_proto_rawDescGZIP(), []int{4}
}

func (x *UserId) GetId() int64 {
	if x != nil {
		return x.Id
	}
	return 0
}

type FindAll struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields
}

func (x *FindAll) Reset() {
	*x = FindAll{}
	if protoimpl.UnsafeEnabled {
		mi := &file_proto_user_user_proto_msgTypes[5]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *FindAll) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*FindAll) ProtoMessage() {}

func (x *FindAll) ProtoReflect() protoreflect.Message {
	mi := &file_proto_user_user_proto_msgTypes[5]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use FindAll.ProtoReflect.Descriptor instead.
func (*FindAll) Descriptor() ([]byte, []int) {
	return file_proto_user_user_proto_rawDescGZIP(), []int{5}
}

type Response struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Msg string `protobuf:"bytes,1,opt,name=msg,proto3" json:"msg,omitempty"`
}

func (x *Response) Reset() {
	*x = Response{}
	if protoimpl.UnsafeEnabled {
		mi := &file_proto_user_user_proto_msgTypes[6]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *Response) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*Response) ProtoMessage() {}

func (x *Response) ProtoReflect() protoreflect.Message {
	mi := &file_proto_user_user_proto_msgTypes[6]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use Response.ProtoReflect.Descriptor instead.
func (*Response) Descriptor() ([]byte, []int) {
	return file_proto_user_user_proto_rawDescGZIP(), []int{6}
}

func (x *Response) GetMsg() string {
	if x != nil {
		return x.Msg
	}
	return ""
}

type AllUser struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	UserInfo []*UserInfo `protobuf:"bytes,1,rep,name=user_info,json=userInfo,proto3" json:"user_info,omitempty"`
}

func (x *AllUser) Reset() {
	*x = AllUser{}
	if protoimpl.UnsafeEnabled {
		mi := &file_proto_user_user_proto_msgTypes[7]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *AllUser) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*AllUser) ProtoMessage() {}

func (x *AllUser) ProtoReflect() protoreflect.Message {
	mi := &file_proto_user_user_proto_msgTypes[7]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use AllUser.ProtoReflect.Descriptor instead.
func (*AllUser) Descriptor() ([]byte, []int) {
	return file_proto_user_user_proto_rawDescGZIP(), []int{7}
}

func (x *AllUser) GetUserInfo() []*UserInfo {
	if x != nil {
		return x.UserInfo
	}
	return nil
}

var File_proto_user_user_proto protoreflect.FileDescriptor

var file_proto_user_user_proto_rawDesc = []byte{
	0x0a, 0x15, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2f, 0x75, 0x73, 0x65,
	0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x3c, 0x0a,
	0x08, 0x55, 0x73, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65,
	0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72,
	0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20,
	0x03, 0x28, 0x03, 0x52, 0x06, 0x72, 0x6f, 0x6c, 0x65, 0x49, 0x64, 0x22, 0x3c, 0x0a, 0x09, 0x55,
	0x73, 0x65, 0x72, 0x52, 0x69, 0x67, 0x68, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72,
	0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49,
	0x64, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28,
	0x09, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x1f, 0x0a, 0x05, 0x52, 0x69, 0x67,
	0x68, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01,
	0x28, 0x08, 0x52, 0x06, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0xad, 0x01, 0x0a, 0x08, 0x55,
	0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20,
	0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f,
	0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72,
	0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x65, 0x6d, 0x61,
	0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x45, 0x6d,
	0x61, 0x69, 0x6c, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x73, 0x5f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x18,
	0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x19,
	0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x70, 0x77, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09,
	0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x50, 0x77, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x75, 0x73, 0x65,
	0x72, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a,
	0x75, 0x73, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x18, 0x0a, 0x06, 0x55, 0x73,
	0x65, 0x72, 0x49, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03,
	0x52, 0x02, 0x69, 0x64, 0x22, 0x09, 0x0a, 0x07, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x22,
	0x1c, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d,
	0x73, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x22, 0x36, 0x0a,
	0x07, 0x41, 0x6c, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x12, 0x2b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72,
	0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x75, 0x73,
	0x65, 0x72, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x75, 0x73, 0x65,
	0x72, 0x49, 0x6e, 0x66, 0x6f, 0x32, 0xa8, 0x03, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x2b,
	0x0a, 0x07, 0x41, 0x64, 0x64, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0e, 0x2e, 0x75, 0x73, 0x65, 0x72,
	0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0x0e, 0x2e, 0x75, 0x73, 0x65, 0x72,
	0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x2c, 0x0a, 0x0a, 0x44,
	0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0c, 0x2e, 0x75, 0x73, 0x65, 0x72,
	0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x1a, 0x0e, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x52,
	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x2e, 0x0a, 0x0a, 0x55, 0x70, 0x64,
	0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0e, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x55,
	0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0x0e, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x52,
	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x2e, 0x0a, 0x0c, 0x46, 0x69, 0x6e,
	0x64, 0x55, 0x73, 0x65, 0x72, 0x42, 0x79, 0x49, 0x44, 0x12, 0x0c, 0x2e, 0x75, 0x73, 0x65, 0x72,
	0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x1a, 0x0e, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x55,
	0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x00, 0x12, 0x2d, 0x0a, 0x0b, 0x46, 0x69, 0x6e,
	0x64, 0x41, 0x6c, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0d, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e,
	0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x1a, 0x0d, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x41,
	0x6c, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x22, 0x00, 0x12, 0x2b, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x52,
	0x6f, 0x6c, 0x65, 0x12, 0x0e, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52,
	0x6f, 0x6c, 0x65, 0x1a, 0x0e, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f,
	0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x2e, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52,
	0x6f, 0x6c, 0x65, 0x12, 0x0e, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52,
	0x6f, 0x6c, 0x65, 0x1a, 0x0e, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f,
	0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x2e, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52,
	0x6f, 0x6c, 0x65, 0x12, 0x0e, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52,
	0x6f, 0x6c, 0x65, 0x1a, 0x0e, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f,
	0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x29, 0x0a, 0x07, 0x49, 0x73, 0x52, 0x69, 0x67, 0x68, 0x74,
	0x12, 0x0f, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x69, 0x67, 0x68,
	0x74, 0x1a, 0x0b, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x52, 0x69, 0x67, 0x68, 0x74, 0x22, 0x00,
	0x42, 0x13, 0x5a, 0x11, 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x75, 0x73, 0x65, 0x72,
	0x3b, 0x75, 0x73, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}

var (
	file_proto_user_user_proto_rawDescOnce sync.Once
	file_proto_user_user_proto_rawDescData = file_proto_user_user_proto_rawDesc
)

func file_proto_user_user_proto_rawDescGZIP() []byte {
	file_proto_user_user_proto_rawDescOnce.Do(func() {
		file_proto_user_user_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_user_user_proto_rawDescData)
	})
	return file_proto_user_user_proto_rawDescData
}

var file_proto_user_user_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
var file_proto_user_user_proto_goTypes = []interface{}{
	(*UserRole)(nil),  // 0: user.UserRole
	(*UserRight)(nil), // 1: user.UserRight
	(*Right)(nil),     // 2: user.Right
	(*UserInfo)(nil),  // 3: user.UserInfo
	(*UserId)(nil),    // 4: user.UserId
	(*FindAll)(nil),   // 5: user.FindAll
	(*Response)(nil),  // 6: user.Response
	(*AllUser)(nil),   // 7: user.AllUser
}
var file_proto_user_user_proto_depIdxs = []int32{
	3,  // 0: user.AllUser.user_info:type_name -> user.UserInfo
	3,  // 1: user.User.AddUser:input_type -> user.UserInfo
	4,  // 2: user.User.DeleteUser:input_type -> user.UserId
	3,  // 3: user.User.UpdateUser:input_type -> user.UserInfo
	4,  // 4: user.User.FindUserByID:input_type -> user.UserId
	5,  // 5: user.User.FindAllUser:input_type -> user.FindAll
	0,  // 6: user.User.AddRole:input_type -> user.UserRole
	0,  // 7: user.User.UpdateRole:input_type -> user.UserRole
	0,  // 8: user.User.DeleteRole:input_type -> user.UserRole
	1,  // 9: user.User.IsRight:input_type -> user.UserRight
	6,  // 10: user.User.AddUser:output_type -> user.Response
	6,  // 11: user.User.DeleteUser:output_type -> user.Response
	6,  // 12: user.User.UpdateUser:output_type -> user.Response
	3,  // 13: user.User.FindUserByID:output_type -> user.UserInfo
	7,  // 14: user.User.FindAllUser:output_type -> user.AllUser
	6,  // 15: user.User.AddRole:output_type -> user.Response
	6,  // 16: user.User.UpdateRole:output_type -> user.Response
	6,  // 17: user.User.DeleteRole:output_type -> user.Response
	2,  // 18: user.User.IsRight:output_type -> user.Right
	10, // [10:19] is the sub-list for method output_type
	1,  // [1:10] is the sub-list for method input_type
	1,  // [1:1] is the sub-list for extension type_name
	1,  // [1:1] is the sub-list for extension extendee
	0,  // [0:1] is the sub-list for field type_name
}

func init() { file_proto_user_user_proto_init() }
func file_proto_user_user_proto_init() {
	if File_proto_user_user_proto != nil {
		return
	}
	if !protoimpl.UnsafeEnabled {
		file_proto_user_user_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*UserRole); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_proto_user_user_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*UserRight); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_proto_user_user_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*Right); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_proto_user_user_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*UserInfo); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_proto_user_user_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*UserId); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_proto_user_user_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*FindAll); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_proto_user_user_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*Response); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_proto_user_user_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*AllUser); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
	}
	type x struct{}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
			RawDescriptor: file_proto_user_user_proto_rawDesc,
			NumEnums:      0,
			NumMessages:   8,
			NumExtensions: 0,
			NumServices:   1,
		},
		GoTypes:           file_proto_user_user_proto_goTypes,
		DependencyIndexes: file_proto_user_user_proto_depIdxs,
		MessageInfos:      file_proto_user_user_proto_msgTypes,
	}.Build()
	File_proto_user_user_proto = out.File
	file_proto_user_user_proto_rawDesc = nil
	file_proto_user_user_proto_goTypes = nil
	file_proto_user_user_proto_depIdxs = nil
}

 C:\Users\Administrator\Desktop\gopaas\user\proto\role\role.pb.micro.go

// Code generated by protoc-gen-micro. DO NOT EDIT.
// source: proto/role/role.proto

package role

import (
	fmt "fmt"
	proto "google.golang.org/protobuf/proto"
	math "math"
)

import (
	context "context"
	api "github.com/asim/go-micro/v3/api"
	client "github.com/asim/go-micro/v3/client"
	server "github.com/asim/go-micro/v3/server"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// Reference imports to suppress errors if they are not otherwise used.
var _ api.Endpoint
var _ context.Context
var _ client.Option
var _ server.Option

// Api Endpoints for User service

func NewRoleEndpoints() []*api.Endpoint {
	return []*api.Endpoint{}
}


// Client API for Role service

type RoleService interface {
	//对外提供添加服务
	AddRole(ctx context.Context, in *RoleInfo, opts ...client.CallOption) (*Response, error)
	DeleteRole(ctx context.Context, in *RoleId, opts ...client.CallOption) (*Response, error)
	UpdateRole(ctx context.Context, in *RoleInfo, opts ...client.CallOption) (*Response, error)
	FindRoleByID(ctx context.Context, in *RoleId, opts ...client.CallOption) (*RoleInfo, error)
	FindAllRole(ctx context.Context, in *FindAll, opts ...client.CallOption) (*AllRole, error)
	//
	AddPermission(ctx context.Context, in *RolePermission, opts ...client.CallOption) (*Response, error)
	UpdatePermission(ctx context.Context, in *RolePermission, opts ...client.CallOption) (*Response, error)
	DeletePermission(ctx context.Context, in *RolePermission, opts ...client.CallOption) (*Response, error)
}

type roleService struct {
	c    client.Client
	name string
}

func NewRoleService(name string, c client.Client) RoleService {
	if c == nil {
		c = client.NewClient()
	}
	if len(name) == 0 {
		name = "role"
	}
	return &roleService{
		c:    c,
		name: name,
	}
}

func (c *roleService) AddRole(ctx context.Context, in *RoleInfo, opts ...client.CallOption) (*Response, error) {
	req := c.c.NewRequest(c.name, "Role.AddRole", in)
	out := new(Response)
	err := c.c.Call(ctx, req, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *roleService) DeleteRole(ctx context.Context, in *RoleId, opts ...client.CallOption) (*Response, error) {
	req := c.c.NewRequest(c.name, "Role.DeleteRole", in)
	out := new(Response)
	err := c.c.Call(ctx, req, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *roleService) UpdateRole(ctx context.Context, in *RoleInfo, opts ...client.CallOption) (*Response, error) {
	req := c.c.NewRequest(c.name, "Role.UpdateRole", in)
	out := new(Response)
	err := c.c.Call(ctx, req, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *roleService) FindRoleByID(ctx context.Context, in *RoleId, opts ...client.CallOption) (*RoleInfo, error) {
	req := c.c.NewRequest(c.name, "Role.FindRoleByID", in)
	out := new(RoleInfo)
	err := c.c.Call(ctx, req, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *roleService) FindAllRole(ctx context.Context, in *FindAll, opts ...client.CallOption) (*AllRole, error) {
	req := c.c.NewRequest(c.name, "Role.FindAllRole", in)
	out := new(AllRole)
	err := c.c.Call(ctx, req, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *roleService) AddPermission(ctx context.Context, in *RolePermission, opts ...client.CallOption) (*Response, error) {
	req := c.c.NewRequest(c.name, "Role.AddPermission", in)
	out := new(Response)
	err := c.c.Call(ctx, req, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *roleService) UpdatePermission(ctx context.Context, in *RolePermission, opts ...client.CallOption) (*Response, error) {
	req := c.c.NewRequest(c.name, "Role.UpdatePermission", in)
	out := new(Response)
	err := c.c.Call(ctx, req, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *roleService) DeletePermission(ctx context.Context, in *RolePermission, opts ...client.CallOption) (*Response, error) {
	req := c.c.NewRequest(c.name, "Role.DeletePermission", in)
	out := new(Response)
	err := c.c.Call(ctx, req, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// Server API for Role service

type RoleHandler interface {
	//对外提供添加服务
	AddRole(context.Context, *RoleInfo, *Response) error
	DeleteRole(context.Context, *RoleId, *Response) error
	UpdateRole(context.Context, *RoleInfo, *Response) error
	FindRoleByID(context.Context, *RoleId, *RoleInfo) error
	FindAllRole(context.Context, *FindAll, *AllRole) error
	//
	AddPermission(context.Context, *RolePermission, *Response) error
	UpdatePermission(context.Context, *RolePermission, *Response) error
	DeletePermission(context.Context, *RolePermission, *Response) error
}

func RegisterRoleHandler(s server.Server, hdlr RoleHandler, opts ...server.HandlerOption) error {
	type role interface {
		AddRole(ctx context.Context, in *RoleInfo, out *Response) error
		DeleteRole(ctx context.Context, in *RoleId, out *Response) error
		UpdateRole(ctx context.Context, in *RoleInfo, out *Response) error
		FindRoleByID(ctx context.Context, in *RoleId, out *RoleInfo) error
		FindAllRole(ctx context.Context, in *FindAll, out *AllRole) error
		AddPermission(ctx context.Context, in *RolePermission, out *Response) error
		UpdatePermission(ctx context.Context, in *RolePermission, out *Response) error
		DeletePermission(ctx context.Context, in *RolePermission, out *Response) error
	}
	type Role struct {
		role
	}
	h := &roleHandler{hdlr}
	return s.Handle(s.NewHandler(&Role{h}, opts...))
}

type roleHandler struct {
	RoleHandler
}

func (h *roleHandler) AddRole(ctx context.Context, in *RoleInfo, out *Response) error {
	return h.RoleHandler.AddRole(ctx, in, out)
}

func (h *roleHandler) DeleteRole(ctx context.Context, in *RoleId, out *Response) error {
	return h.RoleHandler.DeleteRole(ctx, in, out)
}

func (h *roleHandler) UpdateRole(ctx context.Context, in *RoleInfo, out *Response) error {
	return h.RoleHandler.UpdateRole(ctx, in, out)
}

func (h *roleHandler) FindRoleByID(ctx context.Context, in *RoleId, out *RoleInfo) error {
	return h.RoleHandler.FindRoleByID(ctx, in, out)
}

func (h *roleHandler) FindAllRole(ctx context.Context, in *FindAll, out *AllRole) error {
	return h.RoleHandler.FindAllRole(ctx, in, out)
}

func (h *roleHandler) AddPermission(ctx context.Context, in *RolePermission, out *Response) error {
	return h.RoleHandler.AddPermission(ctx, in, out)
}

func (h *roleHandler) UpdatePermission(ctx context.Context, in *RolePermission, out *Response) error {
	return h.RoleHandler.UpdatePermission(ctx, in, out)
}

func (h *roleHandler) DeletePermission(ctx context.Context, in *RolePermission, out *Response) error {
	return h.RoleHandler.DeletePermission(ctx, in, out)
}

 C:\Users\Administrator\Desktop\gopaas\user\proto\role\role.pb.go

// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.30.0
// 	protoc        v4.23.1
// source: proto/role/role.proto

package role

import (
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
	reflect "reflect"
	sync "sync"
)

const (
	// Verify that this generated code is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
	// Verify that runtime/protoimpl is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)

type RolePermission struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	RoleId       int64   `protobuf:"varint,1,opt,name=role_id,json=roleId,proto3" json:"role_id,omitempty"`
	PermissionId []int64 `protobuf:"varint,2,rep,packed,name=permission_id,json=permissionId,proto3" json:"permission_id,omitempty"`
}

func (x *RolePermission) Reset() {
	*x = RolePermission{}
	if protoimpl.UnsafeEnabled {
		mi := &file_proto_role_role_proto_msgTypes[0]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *RolePermission) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*RolePermission) ProtoMessage() {}

func (x *RolePermission) ProtoReflect() protoreflect.Message {
	mi := &file_proto_role_role_proto_msgTypes[0]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use RolePermission.ProtoReflect.Descriptor instead.
func (*RolePermission) Descriptor() ([]byte, []int) {
	return file_proto_role_role_proto_rawDescGZIP(), []int{0}
}

func (x *RolePermission) GetRoleId() int64 {
	if x != nil {
		return x.RoleId
	}
	return 0
}

func (x *RolePermission) GetPermissionId() []int64 {
	if x != nil {
		return x.PermissionId
	}
	return nil
}

type RoleInfo struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Id         int64  `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
	RoleName   string `protobuf:"bytes,2,opt,name=role_name,json=roleName,proto3" json:"role_name,omitempty"`
	RoleStatus int32  `protobuf:"varint,3,opt,name=role_status,json=roleStatus,proto3" json:"role_status,omitempty"`
}

func (x *RoleInfo) Reset() {
	*x = RoleInfo{}
	if protoimpl.UnsafeEnabled {
		mi := &file_proto_role_role_proto_msgTypes[1]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *RoleInfo) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*RoleInfo) ProtoMessage() {}

func (x *RoleInfo) ProtoReflect() protoreflect.Message {
	mi := &file_proto_role_role_proto_msgTypes[1]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use RoleInfo.ProtoReflect.Descriptor instead.
func (*RoleInfo) Descriptor() ([]byte, []int) {
	return file_proto_role_role_proto_rawDescGZIP(), []int{1}
}

func (x *RoleInfo) GetId() int64 {
	if x != nil {
		return x.Id
	}
	return 0
}

func (x *RoleInfo) GetRoleName() string {
	if x != nil {
		return x.RoleName
	}
	return ""
}

func (x *RoleInfo) GetRoleStatus() int32 {
	if x != nil {
		return x.RoleStatus
	}
	return 0
}

type RoleId struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
}

func (x *RoleId) Reset() {
	*x = RoleId{}
	if protoimpl.UnsafeEnabled {
		mi := &file_proto_role_role_proto_msgTypes[2]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *RoleId) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*RoleId) ProtoMessage() {}

func (x *RoleId) ProtoReflect() protoreflect.Message {
	mi := &file_proto_role_role_proto_msgTypes[2]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use RoleId.ProtoReflect.Descriptor instead.
func (*RoleId) Descriptor() ([]byte, []int) {
	return file_proto_role_role_proto_rawDescGZIP(), []int{2}
}

func (x *RoleId) GetId() int64 {
	if x != nil {
		return x.Id
	}
	return 0
}

type FindAll struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields
}

func (x *FindAll) Reset() {
	*x = FindAll{}
	if protoimpl.UnsafeEnabled {
		mi := &file_proto_role_role_proto_msgTypes[3]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *FindAll) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*FindAll) ProtoMessage() {}

func (x *FindAll) ProtoReflect() protoreflect.Message {
	mi := &file_proto_role_role_proto_msgTypes[3]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use FindAll.ProtoReflect.Descriptor instead.
func (*FindAll) Descriptor() ([]byte, []int) {
	return file_proto_role_role_proto_rawDescGZIP(), []int{3}
}

type Response struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Msg string `protobuf:"bytes,1,opt,name=msg,proto3" json:"msg,omitempty"`
}

func (x *Response) Reset() {
	*x = Response{}
	if protoimpl.UnsafeEnabled {
		mi := &file_proto_role_role_proto_msgTypes[4]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *Response) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*Response) ProtoMessage() {}

func (x *Response) ProtoReflect() protoreflect.Message {
	mi := &file_proto_role_role_proto_msgTypes[4]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use Response.ProtoReflect.Descriptor instead.
func (*Response) Descriptor() ([]byte, []int) {
	return file_proto_role_role_proto_rawDescGZIP(), []int{4}
}

func (x *Response) GetMsg() string {
	if x != nil {
		return x.Msg
	}
	return ""
}

type AllRole struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	RoleInfo []*RoleInfo `protobuf:"bytes,1,rep,name=role_info,json=roleInfo,proto3" json:"role_info,omitempty"`
}

func (x *AllRole) Reset() {
	*x = AllRole{}
	if protoimpl.UnsafeEnabled {
		mi := &file_proto_role_role_proto_msgTypes[5]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *AllRole) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*AllRole) ProtoMessage() {}

func (x *AllRole) ProtoReflect() protoreflect.Message {
	mi := &file_proto_role_role_proto_msgTypes[5]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use AllRole.ProtoReflect.Descriptor instead.
func (*AllRole) Descriptor() ([]byte, []int) {
	return file_proto_role_role_proto_rawDescGZIP(), []int{5}
}

func (x *AllRole) GetRoleInfo() []*RoleInfo {
	if x != nil {
		return x.RoleInfo
	}
	return nil
}

var File_proto_role_role_proto protoreflect.FileDescriptor

var file_proto_role_role_proto_rawDesc = []byte{
	0x0a, 0x15, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x2f, 0x72, 0x6f, 0x6c,
	0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x22, 0x4e, 0x0a,
	0x0e, 0x52, 0x6f, 0x6c, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12,
	0x17, 0x0a, 0x07, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03,
	0x52, 0x06, 0x72, 0x6f, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x65, 0x72, 0x6d,
	0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x03, 0x52,
	0x0c, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x58, 0x0a,
	0x08, 0x52, 0x6f, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18,
	0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x6f, 0x6c,
	0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x6f,
	0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x73,
	0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x72, 0x6f, 0x6c,
	0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x18, 0x0a, 0x06, 0x52, 0x6f, 0x6c, 0x65, 0x49,
	0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69,
	0x64, 0x22, 0x09, 0x0a, 0x07, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x22, 0x1c, 0x0a, 0x08,
	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18,
	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x22, 0x36, 0x0a, 0x07, 0x41, 0x6c,
	0x6c, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x2b, 0x0a, 0x09, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x6e,
	0x66, 0x6f, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x2e,
	0x52, 0x6f, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x72, 0x6f, 0x6c, 0x65, 0x49, 0x6e,
	0x66, 0x6f, 0x32, 0xa1, 0x03, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x41,
	0x64, 0x64, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x0e, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x2e, 0x52, 0x6f,
	0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0x0e, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x2e, 0x52, 0x65,
	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x2c, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65,
	0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x0c, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x2e, 0x52, 0x6f,
	0x6c, 0x65, 0x49, 0x64, 0x1a, 0x0e, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70,
	0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x2e, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
	0x52, 0x6f, 0x6c, 0x65, 0x12, 0x0e, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x2e, 0x52, 0x6f, 0x6c, 0x65,
	0x49, 0x6e, 0x66, 0x6f, 0x1a, 0x0e, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70,
	0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x2e, 0x0a, 0x0c, 0x46, 0x69, 0x6e, 0x64, 0x52, 0x6f,
	0x6c, 0x65, 0x42, 0x79, 0x49, 0x44, 0x12, 0x0c, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x2e, 0x52, 0x6f,
	0x6c, 0x65, 0x49, 0x64, 0x1a, 0x0e, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x2e, 0x52, 0x6f, 0x6c, 0x65,
	0x49, 0x6e, 0x66, 0x6f, 0x22, 0x00, 0x12, 0x2d, 0x0a, 0x0b, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c,
	0x6c, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x0d, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x2e, 0x46, 0x69, 0x6e,
	0x64, 0x41, 0x6c, 0x6c, 0x1a, 0x0d, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x2e, 0x41, 0x6c, 0x6c, 0x52,
	0x6f, 0x6c, 0x65, 0x22, 0x00, 0x12, 0x37, 0x0a, 0x0d, 0x41, 0x64, 0x64, 0x50, 0x65, 0x72, 0x6d,
	0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x2e, 0x52, 0x6f,
	0x6c, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x0e, 0x2e, 0x72,
	0x6f, 0x6c, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3a,
	0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69,
	0x6f, 0x6e, 0x12, 0x14, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x50, 0x65,
	0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x0e, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x2e,
	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3a, 0x0a, 0x10, 0x44, 0x65,
	0x6c, 0x65, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14,
	0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73,
	0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x0e, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70,
	0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x13, 0x5a, 0x11, 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x74,
	0x6f, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x3b, 0x72, 0x6f, 0x6c, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f,
	0x74, 0x6f, 0x33,
}

var (
	file_proto_role_role_proto_rawDescOnce sync.Once
	file_proto_role_role_proto_rawDescData = file_proto_role_role_proto_rawDesc
)

func file_proto_role_role_proto_rawDescGZIP() []byte {
	file_proto_role_role_proto_rawDescOnce.Do(func() {
		file_proto_role_role_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_role_role_proto_rawDescData)
	})
	return file_proto_role_role_proto_rawDescData
}

var file_proto_role_role_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
var file_proto_role_role_proto_goTypes = []interface{}{
	(*RolePermission)(nil), // 0: role.RolePermission
	(*RoleInfo)(nil),       // 1: role.RoleInfo
	(*RoleId)(nil),         // 2: role.RoleId
	(*FindAll)(nil),        // 3: role.FindAll
	(*Response)(nil),       // 4: role.Response
	(*AllRole)(nil),        // 5: role.AllRole
}
var file_proto_role_role_proto_depIdxs = []int32{
	1, // 0: role.AllRole.role_info:type_name -> role.RoleInfo
	1, // 1: role.Role.AddRole:input_type -> role.RoleInfo
	2, // 2: role.Role.DeleteRole:input_type -> role.RoleId
	1, // 3: role.Role.UpdateRole:input_type -> role.RoleInfo
	2, // 4: role.Role.FindRoleByID:input_type -> role.RoleId
	3, // 5: role.Role.FindAllRole:input_type -> role.FindAll
	0, // 6: role.Role.AddPermission:input_type -> role.RolePermission
	0, // 7: role.Role.UpdatePermission:input_type -> role.RolePermission
	0, // 8: role.Role.DeletePermission:input_type -> role.RolePermission
	4, // 9: role.Role.AddRole:output_type -> role.Response
	4, // 10: role.Role.DeleteRole:output_type -> role.Response
	4, // 11: role.Role.UpdateRole:output_type -> role.Response
	1, // 12: role.Role.FindRoleByID:output_type -> role.RoleInfo
	5, // 13: role.Role.FindAllRole:output_type -> role.AllRole
	4, // 14: role.Role.AddPermission:output_type -> role.Response
	4, // 15: role.Role.UpdatePermission:output_type -> role.Response
	4, // 16: role.Role.DeletePermission:output_type -> role.Response
	9, // [9:17] is the sub-list for method output_type
	1, // [1:9] is the sub-list for method input_type
	1, // [1:1] is the sub-list for extension type_name
	1, // [1:1] is the sub-list for extension extendee
	0, // [0:1] is the sub-list for field type_name
}

func init() { file_proto_role_role_proto_init() }
func file_proto_role_role_proto_init() {
	if File_proto_role_role_proto != nil {
		return
	}
	if !protoimpl.UnsafeEnabled {
		file_proto_role_role_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*RolePermission); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_proto_role_role_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*RoleInfo); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_proto_role_role_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*RoleId); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_proto_role_role_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*FindAll); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_proto_role_role_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*Response); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_proto_role_role_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*AllRole); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
	}
	type x struct{}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
			RawDescriptor: file_proto_role_role_proto_rawDesc,
			NumEnums:      0,
			NumMessages:   6,
			NumExtensions: 0,
			NumServices:   1,
		},
		GoTypes:           file_proto_role_role_proto_goTypes,
		DependencyIndexes: file_proto_role_role_proto_depIdxs,
		MessageInfos:      file_proto_role_role_proto_msgTypes,
	}.Build()
	File_proto_role_role_proto = out.File
	file_proto_role_role_proto_rawDesc = nil
	file_proto_role_role_proto_goTypes = nil
	file_proto_role_role_proto_depIdxs = nil
}

 C:\Users\Administrator\Desktop\gopaas\user\proto\permission\permission.pb.micro.go

// Code generated by protoc-gen-micro. DO NOT EDIT.
// source: proto/permission/permission.proto

package permission

import (
	fmt "fmt"
	proto "google.golang.org/protobuf/proto"
	math "math"
)

import (
	context "context"
	api "github.com/asim/go-micro/v3/api"
	client "github.com/asim/go-micro/v3/client"
	server "github.com/asim/go-micro/v3/server"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// Reference imports to suppress errors if they are not otherwise used.
var _ api.Endpoint
var _ context.Context
var _ client.Option
var _ server.Option

// Api Endpoints for User service

func NewPermissionEndpoints() []*api.Endpoint {
	return []*api.Endpoint{}
}


// Client API for Permission service

type PermissionService interface {
	//对外提供添加服务
	AddPermission(ctx context.Context, in *PermissionInfo, opts ...client.CallOption) (*Response, error)
	DeletePermission(ctx context.Context, in *PermissionId, opts ...client.CallOption) (*Response, error)
	UpdatePermission(ctx context.Context, in *PermissionInfo, opts ...client.CallOption) (*Response, error)
	FindPermissionByID(ctx context.Context, in *PermissionId, opts ...client.CallOption) (*PermissionInfo, error)
	FindAllPermission(ctx context.Context, in *FindAll, opts ...client.CallOption) (*AllPermission, error)
}

type permissionService struct {
	c    client.Client
	name string
}

func NewPermissionService(name string, c client.Client) PermissionService {
	if c == nil {
		c = client.NewClient()
	}
	if len(name) == 0 {
		name = "permission"
	}
	return &permissionService{
		c:    c,
		name: name,
	}
}

func (c *permissionService) AddPermission(ctx context.Context, in *PermissionInfo, opts ...client.CallOption) (*Response, error) {
	req := c.c.NewRequest(c.name, "Permission.AddPermission", in)
	out := new(Response)
	err := c.c.Call(ctx, req, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *permissionService) DeletePermission(ctx context.Context, in *PermissionId, opts ...client.CallOption) (*Response, error) {
	req := c.c.NewRequest(c.name, "Permission.DeletePermission", in)
	out := new(Response)
	err := c.c.Call(ctx, req, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *permissionService) UpdatePermission(ctx context.Context, in *PermissionInfo, opts ...client.CallOption) (*Response, error) {
	req := c.c.NewRequest(c.name, "Permission.UpdatePermission", in)
	out := new(Response)
	err := c.c.Call(ctx, req, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *permissionService) FindPermissionByID(ctx context.Context, in *PermissionId, opts ...client.CallOption) (*PermissionInfo, error) {
	req := c.c.NewRequest(c.name, "Permission.FindPermissionByID", in)
	out := new(PermissionInfo)
	err := c.c.Call(ctx, req, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *permissionService) FindAllPermission(ctx context.Context, in *FindAll, opts ...client.CallOption) (*AllPermission, error) {
	req := c.c.NewRequest(c.name, "Permission.FindAllPermission", in)
	out := new(AllPermission)
	err := c.c.Call(ctx, req, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// Server API for Permission service

type PermissionHandler interface {
	//对外提供添加服务
	AddPermission(context.Context, *PermissionInfo, *Response) error
	DeletePermission(context.Context, *PermissionId, *Response) error
	UpdatePermission(context.Context, *PermissionInfo, *Response) error
	FindPermissionByID(context.Context, *PermissionId, *PermissionInfo) error
	FindAllPermission(context.Context, *FindAll, *AllPermission) error
}

func RegisterPermissionHandler(s server.Server, hdlr PermissionHandler, opts ...server.HandlerOption) error {
	type permission interface {
		AddPermission(ctx context.Context, in *PermissionInfo, out *Response) error
		DeletePermission(ctx context.Context, in *PermissionId, out *Response) error
		UpdatePermission(ctx context.Context, in *PermissionInfo, out *Response) error
		FindPermissionByID(ctx context.Context, in *PermissionId, out *PermissionInfo) error
		FindAllPermission(ctx context.Context, in *FindAll, out *AllPermission) error
	}
	type Permission struct {
		permission
	}
	h := &permissionHandler{hdlr}
	return s.Handle(s.NewHandler(&Permission{h}, opts...))
}

type permissionHandler struct {
	PermissionHandler
}

func (h *permissionHandler) AddPermission(ctx context.Context, in *PermissionInfo, out *Response) error {
	return h.PermissionHandler.AddPermission(ctx, in, out)
}

func (h *permissionHandler) DeletePermission(ctx context.Context, in *PermissionId, out *Response) error {
	return h.PermissionHandler.DeletePermission(ctx, in, out)
}

func (h *permissionHandler) UpdatePermission(ctx context.Context, in *PermissionInfo, out *Response) error {
	return h.PermissionHandler.UpdatePermission(ctx, in, out)
}

func (h *permissionHandler) FindPermissionByID(ctx context.Context, in *PermissionId, out *PermissionInfo) error {
	return h.PermissionHandler.FindPermissionByID(ctx, in, out)
}

func (h *permissionHandler) FindAllPermission(ctx context.Context, in *FindAll, out *AllPermission) error {
	return h.PermissionHandler.FindAllPermission(ctx, in, out)
}

 C:\Users\Administrator\Desktop\gopaas\user\proto\permission\permission.pb.go

// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.30.0
// 	protoc        v4.23.1
// source: proto/permission/permission.proto

package permission

import (
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
	reflect "reflect"
	sync "sync"
)

const (
	// Verify that this generated code is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
	// Verify that runtime/protoimpl is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)

type PermissionInfo struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Id                 int64  `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
	PermissionName     string `protobuf:"bytes,2,opt,name=permission_name,json=permissionName,proto3" json:"permission_name,omitempty"`
	PermissionDescribe string `protobuf:"bytes,3,opt,name=permission_describe,json=permissionDescribe,proto3" json:"permission_describe,omitempty"`
	PermissionAction   string `protobuf:"bytes,4,opt,name=permission_action,json=permissionAction,proto3" json:"permission_action,omitempty"`
	PermissionStatus   int32  `protobuf:"varint,5,opt,name=permission_status,json=permissionStatus,proto3" json:"permission_status,omitempty"`
}

func (x *PermissionInfo) Reset() {
	*x = PermissionInfo{}
	if protoimpl.UnsafeEnabled {
		mi := &file_proto_permission_permission_proto_msgTypes[0]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *PermissionInfo) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*PermissionInfo) ProtoMessage() {}

func (x *PermissionInfo) ProtoReflect() protoreflect.Message {
	mi := &file_proto_permission_permission_proto_msgTypes[0]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use PermissionInfo.ProtoReflect.Descriptor instead.
func (*PermissionInfo) Descriptor() ([]byte, []int) {
	return file_proto_permission_permission_proto_rawDescGZIP(), []int{0}
}

func (x *PermissionInfo) GetId() int64 {
	if x != nil {
		return x.Id
	}
	return 0
}

func (x *PermissionInfo) GetPermissionName() string {
	if x != nil {
		return x.PermissionName
	}
	return ""
}

func (x *PermissionInfo) GetPermissionDescribe() string {
	if x != nil {
		return x.PermissionDescribe
	}
	return ""
}

func (x *PermissionInfo) GetPermissionAction() string {
	if x != nil {
		return x.PermissionAction
	}
	return ""
}

func (x *PermissionInfo) GetPermissionStatus() int32 {
	if x != nil {
		return x.PermissionStatus
	}
	return 0
}

type PermissionId struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
}

func (x *PermissionId) Reset() {
	*x = PermissionId{}
	if protoimpl.UnsafeEnabled {
		mi := &file_proto_permission_permission_proto_msgTypes[1]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *PermissionId) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*PermissionId) ProtoMessage() {}

func (x *PermissionId) ProtoReflect() protoreflect.Message {
	mi := &file_proto_permission_permission_proto_msgTypes[1]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use PermissionId.ProtoReflect.Descriptor instead.
func (*PermissionId) Descriptor() ([]byte, []int) {
	return file_proto_permission_permission_proto_rawDescGZIP(), []int{1}
}

func (x *PermissionId) GetId() int64 {
	if x != nil {
		return x.Id
	}
	return 0
}

type FindAll struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields
}

func (x *FindAll) Reset() {
	*x = FindAll{}
	if protoimpl.UnsafeEnabled {
		mi := &file_proto_permission_permission_proto_msgTypes[2]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *FindAll) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*FindAll) ProtoMessage() {}

func (x *FindAll) ProtoReflect() protoreflect.Message {
	mi := &file_proto_permission_permission_proto_msgTypes[2]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use FindAll.ProtoReflect.Descriptor instead.
func (*FindAll) Descriptor() ([]byte, []int) {
	return file_proto_permission_permission_proto_rawDescGZIP(), []int{2}
}

type Response struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Msg string `protobuf:"bytes,1,opt,name=msg,proto3" json:"msg,omitempty"`
}

func (x *Response) Reset() {
	*x = Response{}
	if protoimpl.UnsafeEnabled {
		mi := &file_proto_permission_permission_proto_msgTypes[3]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *Response) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*Response) ProtoMessage() {}

func (x *Response) ProtoReflect() protoreflect.Message {
	mi := &file_proto_permission_permission_proto_msgTypes[3]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use Response.ProtoReflect.Descriptor instead.
func (*Response) Descriptor() ([]byte, []int) {
	return file_proto_permission_permission_proto_rawDescGZIP(), []int{3}
}

func (x *Response) GetMsg() string {
	if x != nil {
		return x.Msg
	}
	return ""
}

type AllPermission struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	PermissionInfo []*PermissionInfo `protobuf:"bytes,1,rep,name=permission_info,json=permissionInfo,proto3" json:"permission_info,omitempty"`
}

func (x *AllPermission) Reset() {
	*x = AllPermission{}
	if protoimpl.UnsafeEnabled {
		mi := &file_proto_permission_permission_proto_msgTypes[4]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *AllPermission) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*AllPermission) ProtoMessage() {}

func (x *AllPermission) ProtoReflect() protoreflect.Message {
	mi := &file_proto_permission_permission_proto_msgTypes[4]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use AllPermission.ProtoReflect.Descriptor instead.
func (*AllPermission) Descriptor() ([]byte, []int) {
	return file_proto_permission_permission_proto_rawDescGZIP(), []int{4}
}

func (x *AllPermission) GetPermissionInfo() []*PermissionInfo {
	if x != nil {
		return x.PermissionInfo
	}
	return nil
}

var File_proto_permission_permission_proto protoreflect.FileDescriptor

var file_proto_permission_permission_proto_rawDesc = []byte{
	0x0a, 0x21, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69,
	0x6f, 0x6e, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72,
	0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22,
	0xd4, 0x01, 0x0a, 0x0e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e,
	0x66, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02,
	0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e,
	0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x70, 0x65, 0x72,
	0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x13, 0x70,
	0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
	0x62, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73,
	0x73, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x12, 0x2b, 0x0a, 0x11,
	0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f,
	0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73,
	0x69, 0x6f, 0x6e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x11, 0x70, 0x65, 0x72,
	0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05,
	0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e,
	0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x1e, 0x0a, 0x0c, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73,
	0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
	0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x22, 0x09, 0x0a, 0x07, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c,
	0x6c, 0x22, 0x1c, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a,
	0x03, 0x6d, 0x73, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x22,
	0x54, 0x0a, 0x0d, 0x41, 0x6c, 0x6c, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e,
	0x12, 0x43, 0x0a, 0x0f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69,
	0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x65, 0x72, 0x6d,
	0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f,
	0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0e, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f,
	0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x32, 0xf4, 0x02, 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73,
	0x73, 0x69, 0x6f, 0x6e, 0x12, 0x43, 0x0a, 0x0d, 0x41, 0x64, 0x64, 0x50, 0x65, 0x72, 0x6d, 0x69,
	0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x2e, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69,
	0x6f, 0x6e, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66,
	0x6f, 0x1a, 0x14, 0x2e, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x52,
	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x44, 0x0a, 0x10, 0x44, 0x65, 0x6c,
	0x65, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x2e,
	0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69,
	0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x1a, 0x14, 0x2e, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73,
	0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
	0x46, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73,
	0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x2e, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e,
	0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x1a,
	0x14, 0x2e, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73,
	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x12, 0x46, 0x69, 0x6e, 0x64, 0x50,
	0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x79, 0x49, 0x44, 0x12, 0x18, 0x2e,
	0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69,
	0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x1a, 0x1a, 0x2e, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73,
	0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49,
	0x6e, 0x66, 0x6f, 0x22, 0x00, 0x12, 0x45, 0x0a, 0x11, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c,
	0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x13, 0x2e, 0x70, 0x65, 0x72,
	0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x1a,
	0x19, 0x2e, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x6c, 0x6c,
	0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x00, 0x42, 0x1f, 0x5a, 0x1d,
	0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69,
	0x6f, 0x6e, 0x3b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70,
	0x72, 0x6f, 0x74, 0x6f, 0x33,
}

var (
	file_proto_permission_permission_proto_rawDescOnce sync.Once
	file_proto_permission_permission_proto_rawDescData = file_proto_permission_permission_proto_rawDesc
)

func file_proto_permission_permission_proto_rawDescGZIP() []byte {
	file_proto_permission_permission_proto_rawDescOnce.Do(func() {
		file_proto_permission_permission_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_permission_permission_proto_rawDescData)
	})
	return file_proto_permission_permission_proto_rawDescData
}

var file_proto_permission_permission_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
var file_proto_permission_permission_proto_goTypes = []interface{}{
	(*PermissionInfo)(nil), // 0: permission.PermissionInfo
	(*PermissionId)(nil),   // 1: permission.PermissionId
	(*FindAll)(nil),        // 2: permission.FindAll
	(*Response)(nil),       // 3: permission.Response
	(*AllPermission)(nil),  // 4: permission.AllPermission
}
var file_proto_permission_permission_proto_depIdxs = []int32{
	0, // 0: permission.AllPermission.permission_info:type_name -> permission.PermissionInfo
	0, // 1: permission.Permission.AddPermission:input_type -> permission.PermissionInfo
	1, // 2: permission.Permission.DeletePermission:input_type -> permission.PermissionId
	0, // 3: permission.Permission.UpdatePermission:input_type -> permission.PermissionInfo
	1, // 4: permission.Permission.FindPermissionByID:input_type -> permission.PermissionId
	2, // 5: permission.Permission.FindAllPermission:input_type -> permission.FindAll
	3, // 6: permission.Permission.AddPermission:output_type -> permission.Response
	3, // 7: permission.Permission.DeletePermission:output_type -> permission.Response
	3, // 8: permission.Permission.UpdatePermission:output_type -> permission.Response
	0, // 9: permission.Permission.FindPermissionByID:output_type -> permission.PermissionInfo
	4, // 10: permission.Permission.FindAllPermission:output_type -> permission.AllPermission
	6, // [6:11] is the sub-list for method output_type
	1, // [1:6] is the sub-list for method input_type
	1, // [1:1] is the sub-list for extension type_name
	1, // [1:1] is the sub-list for extension extendee
	0, // [0:1] is the sub-list for field type_name
}

func init() { file_proto_permission_permission_proto_init() }
func file_proto_permission_permission_proto_init() {
	if File_proto_permission_permission_proto != nil {
		return
	}
	if !protoimpl.UnsafeEnabled {
		file_proto_permission_permission_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*PermissionInfo); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_proto_permission_permission_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*PermissionId); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_proto_permission_permission_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*FindAll); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_proto_permission_permission_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*Response); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_proto_permission_permission_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*AllPermission); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
	}
	type x struct{}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
			RawDescriptor: file_proto_permission_permission_proto_rawDesc,
			NumEnums:      0,
			NumMessages:   5,
			NumExtensions: 0,
			NumServices:   1,
		},
		GoTypes:           file_proto_permission_permission_proto_goTypes,
		DependencyIndexes: file_proto_permission_permission_proto_depIdxs,
		MessageInfos:      file_proto_permission_permission_proto_msgTypes,
	}.Build()
	File_proto_permission_permission_proto = out.File
	file_proto_permission_permission_proto_rawDesc = nil
	file_proto_permission_permission_proto_goTypes = nil
	file_proto_permission_permission_proto_depIdxs = nil
}

12-11用户中心-userhandler开发

C:\Users\Administrator\Desktop\gopaas\user\handler\userHandler.go

package handler

import (
	"context"

	log "github.com/asim/go-micro/v3/logger"
	"github.com/yunixiangfeng/gopaas/common"
	"github.com/yunixiangfeng/gopaas/user/domain/model"
	"github.com/yunixiangfeng/gopaas/user/domain/service"
	user "github.com/yunixiangfeng/gopaas/user/proto/user"
)

type UserHandler struct {
	//注意这里的类型是 IUserDataService 接口类型
	UserDataService service.IUserDataService
	RoleDataService service.IRoleDataService
}

func (e *UserHandler) getUserRole(userRole *user.UserRole) (user *model.User, role []*model.Role, err error) {
	user, err = e.UserDataService.FindUserByID(userRole.UserId)
	if err != nil {
		common.Error(err)
		return
	}
	role, err = e.RoleDataService.FindAllRoleByID(userRole.RoleId)
	if err != nil {
		common.Error(err)
		return
	}
	return
}

func (e *UserHandler) AddRole(ctx context.Context, userRole *user.UserRole, rsp *user.Response) error {
	// 查找用户和对应的角色
	user, role, err := e.getUserRole(userRole)
	if err != nil {
		common.Error(err)
		rsp.Msg = err.Error()
		return err
	}
	// 添加对应的角色
	if err := e.UserDataService.AddRole(user, role); err != nil {
		common.Error(err)
		rsp.Msg = err.Error()
		return err
	}
	return nil
}

func (e *UserHandler) UpdateRole(ctx context.Context, userRole *user.UserRole, rsp *user.Response) error {
	// 查找用户和对应的角色
	user, role, err := e.getUserRole(userRole)
	if err != nil {
		common.Error(err)
		rsp.Msg = err.Error()
		return err
	}
	// 更新对应的角色
	if err := e.UserDataService.UpdateRole(user, role); err != nil {
		common.Error(err)
		rsp.Msg = err.Error()
		return err
	}
	return nil
}

func (e *UserHandler) DeleteRole(ctx context.Context, userRole *user.UserRole, rsp *user.Response) error {
	// 查找用户和对应的角色
	user, role, err := e.getUserRole(userRole)
	if err != nil {
		common.Error(err)
		rsp.Msg = err.Error()
		return err
	}
	// 删除对应的角色
	if err := e.UserDataService.DeleteRole(user, role); err != nil {
		common.Error(err)
		rsp.Msg = err.Error()
		return err
	}
	return nil
}

func (e *UserHandler) IsRight(ctx context.Context, userRight *user.UserRight, rg *user.Right) error {
	rg.Access = e.UserDataService.IsRight(userRight.Action, userRight.UserId)
	return nil
}

// Call is a single request handler called via client.Call or the generated client code
func (e *UserHandler) AddUser(ctx context.Context, info *user.UserInfo, rsp *user.Response) error {
	log.Info("Received *user.AddUser request")

	return nil
}

func (e *UserHandler) DeleteUser(ctx context.Context, req *user.UserId, rsp *user.Response) error {
	log.Info("Received *user.DeleteUser request")

	return nil
}

func (e *UserHandler) UpdateUser(ctx context.Context, req *user.UserInfo, rsp *user.Response) error {
	log.Info("Received *user.UpdateUser request")

	return nil
}

func (e *UserHandler) FindUserByID(ctx context.Context, req *user.UserId, rsp *user.UserInfo) error {
	log.Info("Received *user.FindUserByID request")

	return nil
}

func (e *UserHandler) FindAllUser(ctx context.Context, req *user.FindAll, rsp *user.AllUser) error {
	log.Info("Received *user.FindAllUser request")

	return nil
}

12-12用户中心-rolehandler开发

C:\Users\Administrator\Desktop\gopaas\user\handler\roleHandler.go

package handler

import (
	"context"

	log "github.com/asim/go-micro/v3/logger"
	"github.com/yunixiangfeng/gopaas/common"
	"github.com/yunixiangfeng/gopaas/user/domain/model"
	"github.com/yunixiangfeng/gopaas/user/domain/service"
	role "github.com/yunixiangfeng/gopaas/user/proto/role"
)

type RoleHandler struct {
	//注意这里的类型是 IRoleDataService 接口类型
	RoleDataService       service.IRoleDataService
	PermissionDataService service.IPermissionDataService
}

func (e *RoleHandler) getRolePermission(rolePermission *role.RolePermission) (role *model.Role, permission []*model.Permission, err error) {
	role, err = e.RoleDataService.FindRoleByID(rolePermission.RoleId)
	if err != nil {
		common.Error(err)
		return
	}
	permission, err = e.PermissionDataService.FindAllPermissionByID(rolePermission.PermissionId)
	if err != nil {
		common.Error(err)
		return
	}
	return
}

func (e *RoleHandler) AddPermission(ctx context.Context, rolePermission *role.RolePermission, rsp *role.Response) error {
	role, permission, err := e.getRolePermission(rolePermission)
	if err != nil {
		common.Error(err)
		rsp.Msg = err.Error()
		return err
	}
	if err := e.RoleDataService.AddPermission(role, permission); err != nil {
		common.Error(err)
		rsp.Msg = err.Error()
		return err
	}
	return nil
}

func (e *RoleHandler) UpdatePermission(ctx context.Context, rolePermission *role.RolePermission, rsp *role.Response) error {
	role, permission, err := e.getRolePermission(rolePermission)
	if err != nil {
		common.Error(err)
		rsp.Msg = err.Error()
		return err
	}
	if err := e.RoleDataService.UpdatePermission(role, permission); err != nil {
		common.Error(err)
		rsp.Msg = err.Error()
		return err
	}
	return nil
}

func (e *RoleHandler) DeletePermission(ctx context.Context, rolePermission *role.RolePermission, rsp *role.Response) error {
	role, permission, err := e.getRolePermission(rolePermission)
	if err != nil {
		common.Error(err)
		rsp.Msg = err.Error()
		return err
	}
	if err := e.RoleDataService.DeletePermission(role, permission); err != nil {
		common.Error(err)
		rsp.Msg = err.Error()
		return err
	}
	return nil
}

// Call is a single request handler called via client.Call or the generated client code
func (e *RoleHandler) AddRole(ctx context.Context, info *role.RoleInfo, rsp *role.Response) error {
	log.Info("Received *role.AddRole request")

	return nil
}

func (e *RoleHandler) DeleteRole(ctx context.Context, req *role.RoleId, rsp *role.Response) error {
	log.Info("Received *role.DeleteRole request")

	return nil
}

func (e *RoleHandler) UpdateRole(ctx context.Context, req *role.RoleInfo, rsp *role.Response) error {
	log.Info("Received *role.UpdateRole request")

	return nil
}

func (e *RoleHandler) FindRoleByID(ctx context.Context, req *role.RoleId, rsp *role.RoleInfo) error {
	log.Info("Received *role.FindRoleByID request")

	return nil
}

func (e *RoleHandler) FindAllRole(ctx context.Context, req *role.FindAll, rsp *role.AllRole) error {
	log.Info("Received *role.FindAllRole request")

	return nil
}

 C:\Users\Administrator\Desktop\gopaas\user\main.go

	// 注册句柄,可以快速操作已开发的服务
	userDataService := service2.NewUserDataService(repository.NewUserRepository(db), clientset)
	roleDataService := service2.NewRoleDataService(repository.NewRoleRepository(db), clientset)
	permissionDataService := service2.NewPermissionDataService(repository.NewPermissionRepository(db), clientset)

	user.RegisterUserHandler(service.Server(), &handler.UserHandler{UserDataService: userDataService, RoleDataService: roleDataService})
	role.RegisterRoleHandler(service.Server(), &handler.RoleHandler{RoleDataService: roleDataService, PermissionDataService: permissionDataService})

12-13用户中心-权限-handler开发

C:\Users\Administrator\Desktop\gopaas\user\handler\permissionHandler.go

package handler

import (
	"context"

	log "github.com/asim/go-micro/v3/logger"
	"github.com/yunixiangfeng/gopaas/user/domain/service"
	permission "github.com/yunixiangfeng/gopaas/user/proto/permission"
)

type PermissionHandler struct {
	//注意这里的类型是 IPermissionDataService 接口类型
	PermissionDataService service.IPermissionDataService
}

// Call is a single request handler called via client.Call or the generated client code
func (e *PermissionHandler) AddPermission(ctx context.Context, info *permission.PermissionInfo, rsp *permission.Response) error {
	log.Info("Received *permission.AddPermission request")

	return nil
}

func (e *PermissionHandler) DeletePermission(ctx context.Context, req *permission.PermissionId, rsp *permission.Response) error {
	log.Info("Received *permission.DeletePermission request")

	return nil
}

func (e *PermissionHandler) UpdatePermission(ctx context.Context, req *permission.PermissionInfo, rsp *permission.Response) error {
	log.Info("Received *permission.UpdatePermission request")

	return nil
}

func (e *PermissionHandler) FindPermissionByID(ctx context.Context, req *permission.PermissionId, rsp *permission.PermissionInfo) error {
	log.Info("Received *permission.FindPermissionByID request")

	return nil
}

func (e *PermissionHandler) FindAllPermission(ctx context.Context, req *permission.FindAll, rsp *permission.AllPermission) error {
	log.Info("Received *permission.FindAllPermission request")

	return nil
}

C:\Users\Administrator\Desktop\gopaas\user\main.go

	permission.RegisterPermissionHandler(service.Server(), &handler.PermissionHandler{PermissionDataService: permissionDataService})

12-14用户中前端API开发

.\yu-tool\yu-tool.exe  createApi github.com/yunixiangfeng/gopaas/userApi

yu-v3 --proto_path=. --micro_out=. --go_out=:. ./proto/userApi/userApi.proto

go mod tidy

C:\Users\Administrator\Desktop\gopaas\go-paas-front\user-role.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="description" content="">
    <meta name="author" content="">
    <link rel="shortcut icon" href="assets/img/logo-fav.png">
    <title>CPaaS</title>
    <link rel="stylesheet" type="text/css" href="assets/lib/perfect-scrollbar/css/perfect-scrollbar.min.css"/>
    <link rel="stylesheet" type="text/css" href="assets/lib/material-design-icons/css/material-design-iconic-font.min.css"/><!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
    <link rel="stylesheet" type="text/css" href="assets/lib/datatables/css/dataTables.bootstrap.min.css"/>
    <link rel="stylesheet" href="assets/css/style.css" type="text/css"/>
  </head>
  <body>
    <div class="be-wrapper">
      <nav class="navbar navbar-default navbar-fixed-top be-top-header">
        <div class="container-fluid">
          <div class="navbar-header"><a href="index.html" class="navbar-brand"></a>
          </div>
          <div class="be-right-navbar">
            <ul class="nav navbar-nav navbar-right be-user-nav">
              <li class="dropdown"><a href="#" data-toggle="dropdown" role="button" aria-expanded="false" class="dropdown-toggle"><img src="assets/img/avatar.png" alt="Avatar"><span class="user-name">Túpac Amaru</span></a>
                <ul role="menu" class="dropdown-menu">
                  <li>
                    <div class="user-info">
                      <div class="user-name">wu123</div>
                      <div class="user-position online">在线</div>
                    </div>
                  </li>
                  <li><a href="#"><span class="icon mdi mdi-face"></span> 账户</a></li>
                  <li><a href="#"><span class="icon mdi mdi-settings"></span> 设置</a></li>
                  <li><a href="#"><span class="icon mdi mdi-power"></span> 推出登录</a></li>
                </ul>
              </li>
            </ul>
            <div class="page-title"></div>
            <ul class="nav navbar-nav navbar-right be-icons-nav">
              <li class="dropdown"><a href="#" role="button" aria-expanded="false" class="be-toggle-right-sidebar"><span class="icon mdi mdi-settings"></span></a></li>
              <li class="dropdown"><a href="#" data-toggle="dropdown" role="button" aria-expanded="false" class="dropdown-toggle"><span class="icon mdi mdi-notifications"></span><span class="indicator"></span></a>
                <ul class="dropdown-menu be-notifications">
                  <li>
                    <div class="title">消息提醒<span class="badge">3</span></div>
                    <div class="list">
                      <div class="be-scroller">
                        <div class="content">
                          <ul>
                            <li class="notification notification-unread"><a href="#">
                                <div class="image"><img src="assets/img/avatar2.png" alt="Avatar"></div>
                                <div class="notification-info">
                                  <div class="text"><span class="user-name">Jessica Caruso</span> accepted your invitation to join the team.</div><span class="date">2 min ago</span>
                                </div></a></li>
                            <li class="notification"><a href="#">
                                <div class="image"><img src="assets/img/avatar3.png" alt="Avatar"></div>
                                <div class="notification-info">
                                  <div class="text"><span class="user-name">Joel King</span> is now following you</div><span class="date">2 days ago</span>
                                </div></a></li>
                            <li class="notification"><a href="#">
                                <div class="image"><img src="assets/img/avatar4.png" alt="Avatar"></div>
                                <div class="notification-info">
                                  <div class="text"><span class="user-name">John Doe</span> is watching your main repository</div><span class="date">2 days ago</span>
                                </div></a></li>
                            <li class="notification"><a href="#">
                                <div class="image"><img src="assets/img/avatar5.png" alt="Avatar"></div>
                                <div class="notification-info"><span class="text"><span class="user-name">Emily Carter</span> is now following you</span><span class="date">5 days ago</span></div></a></li>
                          </ul>
                        </div>
                      </div>
                    </div>
                    <div class="footer"> <a href="#">View all notifications</a></div>
                  </li>
                </ul>
              </li>
              <li class="dropdown"><a href="#" data-toggle="dropdown" role="button" aria-expanded="false" class="dropdown-toggle"><span class="icon mdi mdi-apps"></span></a>
                <ul class="dropdown-menu be-connections">
                  <li>
                    <div class="list">
                      <div class="content">
                        <div class="row">
                          <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/github.png" alt="Github"><span>GitHub</span></a></div>
                          <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/bitbucket.png" alt="Bitbucket"><span>Bitbucket</span></a></div>
                          <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/slack.png" alt="Slack"><span>Slack</span></a></div>
                        </div>
                        <div class="row">
                          <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/dribbble.png" alt="Dribbble"><span>Dribbble</span></a></div>
                          <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/mail_chimp.png" alt="Mail Chimp"><span>Mail Chimp</span></a></div>
                          <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/dropbox.png" alt="Dropbox"><span>Dropbox</span></a></div>
                        </div>
                      </div>
                    </div>
                    <div class="footer"> <a href="#">More</a></div>
                  </li>
                </ul>
              </li>
            </ul>
          </div>
        </div>
      </nav>
<!--
  侧边栏-开始
-->
<div class="be-left-sidebar">
  <div class="left-sidebar-wrapper"><a href="#" class="left-sidebar-toggle">看版</a>
    <div class="left-sidebar-spacer">
      <div class="left-sidebar-scroll">
        <div class="left-sidebar-content">
          <ul class="sidebar-elements">
            <li class="divider">菜单</li>
            <li class="parent"><a href="#"><i class="icon mdi mdi-home"></i><span>控制台</span></a>
            </li>
            <li class="parent"><a href="#"><i class="icon mdi mdi-face"></i><span>应用管理</span></a>
              <ul class="sub-menu">
                <li ><a href="pod-index.html">添加应用</a>
                </li>
              </ul>
            </li>
            <li class="parent"><a href="charts.html"><i class="icon mdi mdi-chart-donut"></i><span>服务管理</span></a>
              <ul class="sub-menu">
                <li ><a href="svc-index.html">添加服务</a>
                </li>
              </ul>
            </li>
            <li class="parent"><a href="#"><i class="icon mdi mdi-dot-circle"></i><span>域名管理</span></a>
              <ul class="sub-menu">
                <li  ><a href="route-index.html">添加路由</a>
                </li>
              </ul>
            </li>
            <li class="parent"><a href="#"><i class="icon mdi mdi-dot-circle"></i><span>权限管理</span></a>
              <ul class="sub-menu">
                <li class="active"><a href="route-index.html">权限管理</a>
                </li>
              </ul>
            </li>
            <li class="parent"><a href="#"><i class="icon mdi mdi-border-all"></i><span>权限管理</span></a>
              <ul class="sub-menu">
                <li><a href="tables-general.html">General</a>
                </li>
                <li><a href="tables-datatables.html">Data Tables</a>
                </li>
                <li><a href="tables-filters.html"><span class="label label-primary pull-right">New</span>Table Filters</a>
                </li>
              </ul>
            </li>
            <li class="parent"><a href="#"><i class="icon mdi mdi-layers"></i><span>权限管理</span></a>
              <ul class="sub-menu">
                <li><a href="pages-blank.html">Blank Page</a>
                </li>
                <li><a href="pages-blank-header.html">Blank Page Header</a>
                </li>
                <li><a href="pages-login.html">Login</a>
                </li>
                <li><a href="pages-login2.html">Login v2</a>
                </li>
                <li><a href="pages-404.html">404 Page</a>
                </li>
                <li><a href="pages-sign-up.html">Sign Up</a>
                </li>
                <li><a href="pages-forgot-password.html">Forgot Password</a>
                </li>
                <li><a href="pages-profile.html">Profile</a>
                </li>
                <li><a href="pages-pricing-tables.html">Pricing Tables</a>
                </li>
                <li><a href="pages-pricing-tables2.html">Pricing Tables v2</a>
                </li>
                <li><a href="pages-timeline.html">Timeline</a>
                </li>
                <li><a href="pages-timeline2.html">Timeline v2</a>
                </li>
                <li><a href="pages-invoice.html"><span class="label label-primary pull-right">New</span>Invoice</a>
                </li>
                <li><a href="pages-calendar.html">Calendar</a>
                </li>
                <li><a href="pages-gallery.html">Gallery</a>
                </li>
                <li><a href="pages-code-editor.html"><span class="label label-primary pull-right">New    </span>Code Editor</a>
                </li>
                <li><a href="pages-booking.html"><span class="label label-primary pull-right">New</span>Booking</a>
                </li>
                <li><a href="pages-loaders.html"><span class="label label-primary pull-right">New</span>Loaders</a>
                </li>
              </ul>
            </li>
         
          </ul>
        </div>
      </div>
    </div>
    <div class="progress-widget">

      <div class="progress">
        <div style="width: 60%;" class="progress-bar progress-bar-primary"></div>
      </div>
    </div>
  </div>
</div>
<!--
侧边栏-结束
-->
      <div class="be-content">
        <div class="page-head">
          <h2 class="page-head-title">角色管理</h2>
          <ol class="breadcrumb page-head-nav">
            <li><a href="#">控制台</a></li>
            <li><a href="#">权限管理</a></li>
            <li class="active">权限管理列表</li>
          </ol>
        </div>
        <div class="main-content container-fluid">
          <div class="main-content container-fluid">

            <div class="row">
              <div class="col-md-12">
                <div class="panel panel-default panel-border-color panel-border-color-primary">
                  <div class="panel-heading panel-heading-divider">角色管理<span class="panel-subtitle">分配系统详细的权限</span></div>
                  <div class="panel-body">
                    <form action="http://127.0.0.1:8080/userApi/AddRole" class="form-horizontal group-border-dashed" method="post" novalidate="">
                      <div class="form-group">
                        <label class="col-sm-3 control-label">用户ID</label>
                        <div class="col-sm-6">
                          <div class="be-checkbox be-checkbox-color inline">
                            <input id="check6" type="text" checked="" hidden value="1" name="user_id">
                            <label for="check6">张三</label>
                          </div>
                        </div>
                      </div>
                      <div class="form-group">
                        <label class="col-sm-3 control-label">角色</label>
                        <div class="col-sm-6">
                          <div class="be-checkbox be-checkbox-color inline">
                            <input id="check61" type="checkbox" value="1" name="role_id">
                            <label for="check61">主管</label>
                          </div>
                          <div class="be-checkbox be-checkbox-color inline">
                            <input id="check7" type="checkbox"    value="2" name="role_id">
                            <label for="check7">组长</label>
                          </div>
                          <div class="be-checkbox be-checkbox-color inline">
                            <input id="check8" type="checkbox"   value="3" name="role_id">
                            <label for="check8">组员</label>
                          </div>
                          <div class="be-checkbox be-checkbox-color inline">
                            <input id="check9" type="checkbox"   value="4" name="role_id">
                            <label for="check9">访客</label>
                          </div>
                          <div class="form-group">
                            <div class="col-sm-2 col-sm-10">
                              <button type="submit" class="btn btn-space btn-primary">提交</button>
                              <button class="btn btn-space btn-default">取消</button>
                            </div>
                          </div>
                        </div>
                      </div>

                    </form>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>

      </div>
      <nav class="be-right-sidebar">
        <div class="sb-content">
          <div class="tab-navigation">
            <ul role="tablist" class="nav nav-tabs nav-justified">
              <li role="presentation" class="active"><a href="#tab1" aria-controls="tab1" role="tab" data-toggle="tab">Chat</a></li>
              <li role="presentation"><a href="#tab2" aria-controls="tab2" role="tab" data-toggle="tab">Todo</a></li>
              <li role="presentation"><a href="#tab3" aria-controls="tab3" role="tab" data-toggle="tab">Settings</a></li>
            </ul>
          </div>
          <div class="tab-panel">
            <div class="tab-content">
              <div id="tab1" role="tabpanel" class="tab-pane tab-chat active">
                <div class="chat-contacts">
                  <div class="chat-sections">
                    <div class="be-scroller">
                      <div class="content">
                        <h2>Recent</h2>
                        <div class="contact-list contact-list-recent">
                          <div class="user"><a href="#"><img src="assets/img/avatar1.png" alt="Avatar">
                              <div class="user-data"><span class="status away"></span><span class="name">Claire Sassu</span><span class="message">Can you share the...</span></div></a></div>
                          <div class="user"><a href="#"><img src="assets/img/avatar2.png" alt="Avatar">
                              <div class="user-data"><span class="status"></span><span class="name">Maggie jackson</span><span class="message">I confirmed the info.</span></div></a></div>
                          <div class="user"><a href="#"><img src="assets/img/avatar3.png" alt="Avatar">
                              <div class="user-data"><span class="status offline"></span><span class="name">Joel King		</span><span class="message">Ready for the meeti...</span></div></a></div>
                        </div>
                        <h2>Contacts</h2>
                        <div class="contact-list">
                          <div class="user"><a href="#"><img src="assets/img/avatar4.png" alt="Avatar">
                              <div class="user-data2"><span class="status"></span><span class="name">Mike Bolthort</span></div></a></div>
                          <div class="user"><a href="#"><img src="assets/img/avatar5.png" alt="Avatar">
                              <div class="user-data2"><span class="status"></span><span class="name">Maggie jackson</span></div></a></div>
                          <div class="user"><a href="#"><img src="assets/img/avatar6.png" alt="Avatar">
                              <div class="user-data2"><span class="status offline"></span><span class="name">Jhon Voltemar</span></div></a></div>
                        </div>
                      </div>
                    </div>
                  </div>
                  <div class="bottom-input">
                    <input type="text" placeholder="Search..." name="q"><span class="mdi mdi-search"></span>
                  </div>
                </div>
                <div class="chat-window">
                  <div class="title">
                    <div class="user"><img src="assets/img/avatar2.png" alt="Avatar">
                      <h2>Maggie jackson</h2><span>Active 1h ago</span>
                    </div><span class="icon return mdi mdi-chevron-left"></span>
                  </div>
                  <div class="chat-messages">
                    <div class="be-scroller">
                      <div class="content">
                        <ul>
                          <li class="friend">
                            <div class="msg">Hello</div>
                          </li>
                          <li class="self">
                            <div class="msg">Hi, how are you?</div>
                          </li>
                          <li class="friend">
                            <div class="msg">Good, I'll need support with my pc</div>
                          </li>
                          <li class="self">
                            <div class="msg">Sure, just tell me what is going on with your computer?</div>
                          </li>
                          <li class="friend">
                            <div class="msg">I don't know it just turns off suddenly</div>
                          </li>
                        </ul>
                      </div>
                    </div>
                  </div>
                  <div class="chat-input">
                    <div class="input-wrapper"><span class="photo mdi mdi-camera"></span>
                      <input type="text" placeholder="Message..." name="q" autocomplete="off"><span class="send-msg mdi mdi-mail-send"></span>
                    </div>
                  </div>
                </div>
              </div>
              <div id="tab2" role="tabpanel" class="tab-pane tab-todo">
                <div class="todo-container">
                  <div class="todo-wrapper">
                    <div class="be-scroller">
                      <div class="todo-content"><span class="category-title">Today</span>
                        <ul class="todo-list">
                          <li>
                            <div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
                              <input id="todo1" type="checkbox" checked="">
                              <label for="todo1">Initialize the project</label>
                            </div>
                          </li>
                          <li>
                            <div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
                              <input id="todo2" type="checkbox">
                              <label for="todo2">Create the main structure</label>
                            </div>
                          </li>
                          <li>
                            <div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
                              <input id="todo3" type="checkbox">
                              <label for="todo3">Updates changes to GitHub</label>
                            </div>
                          </li>
                        </ul><span class="category-title">Tomorrow</span>
                        <ul class="todo-list">
                          <li>
                            <div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
                              <input id="todo4" type="checkbox">
                              <label for="todo4">Initialize the project</label>
                            </div>
                          </li>
                          <li>
                            <div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
                              <input id="todo5" type="checkbox">
                              <label for="todo5">Create the main structure</label>
                            </div>
                          </li>
                          <li>
                            <div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
                              <input id="todo6" type="checkbox">
                              <label for="todo6">Updates changes to GitHub</label>
                            </div>
                          </li>
                          <li>
                            <div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
                              <input id="todo7" type="checkbox">
                              <label for="todo7" title="This task is too long to be displayed in a normal space!">This task is too long to be displayed in a normal space!</label>
                            </div>
                          </li>
                        </ul>
                      </div>
                    </div>
                  </div>
                  <div class="bottom-input">
                    <input type="text" placeholder="Create new task..." name="q"><span class="mdi mdi-plus"></span>
                  </div>
                </div>
              </div>
              <div id="tab3" role="tabpanel" class="tab-pane tab-settings">
                <div class="settings-wrapper">
                  <div class="be-scroller"><span class="category-title">General</span>
                    <ul class="settings-list">
                      <li>
                        <div class="switch-button switch-button-sm">
                          <input type="checkbox" checked="" name="st1" id="st1"><span>
                            <label for="st1"></label></span>
                        </div><span class="name">Available</span>
                      </li>
                      <li>
                        <div class="switch-button switch-button-sm">
                          <input type="checkbox" checked="" name="st2" id="st2"><span>
                            <label for="st2"></label></span>
                        </div><span class="name">Enable notifications</span>
                      </li>
                      <li>
                        <div class="switch-button switch-button-sm">
                          <input type="checkbox" checked="" name="st3" id="st3"><span>
                            <label for="st3"></label></span>
                        </div><span class="name">Login with Facebook</span>
                      </li>
                    </ul><span class="category-title">Notifications</span>
                    <ul class="settings-list">
                      <li>
                        <div class="switch-button switch-button-sm">
                          <input type="checkbox" name="st4" id="st4"><span>
                            <label for="st4"></label></span>
                        </div><span class="name">Email notifications</span>
                      </li>
                      <li>
                        <div class="switch-button switch-button-sm">
                          <input type="checkbox" checked="" name="st5" id="st5"><span>
                            <label for="st5"></label></span>
                        </div><span class="name">Project updates</span>
                      </li>
                      <li>
                        <div class="switch-button switch-button-sm">
                          <input type="checkbox" checked="" name="st6" id="st6"><span>
                            <label for="st6"></label></span>
                        </div><span class="name">New comments</span>
                      </li>
                      <li>
                        <div class="switch-button switch-button-sm">
                          <input type="checkbox" name="st7" id="st7"><span>
                            <label for="st7"></label></span>
                        </div><span class="name">Chat messages</span>
                      </li>
                    </ul><span class="category-title">Workflow</span>
                    <ul class="settings-list">
                      <li>
                        <div class="switch-button switch-button-sm">
                          <input type="checkbox" name="st8" id="st8"><span>
                            <label for="st8"></label></span>
                        </div><span class="name">Deploy on commit</span>
                      </li>
                    </ul>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </nav>
    </div>
    <script src="assets/lib/jquery/jquery.min.js" type="text/javascript"></script>
    <script src="assets/lib/perfect-scrollbar/js/perfect-scrollbar.jquery.min.js" type="text/javascript"></script>
    <script src="assets/js/main.js" type="text/javascript"></script>
    <script src="assets/lib/bootstrap/dist/js/bootstrap.min.js" type="text/javascript"></script>
    <script src="assets/lib/datatables/js/jquery.dataTables.min.js" type="text/javascript"></script>
    <script src="assets/lib/datatables/js/dataTables.bootstrap.min.js" type="text/javascript"></script>
    <script src="assets/lib/datatables/plugins/buttons/js/dataTables.buttons.js" type="text/javascript"></script>
    <script src="assets/lib/datatables/plugins/buttons/js/buttons.html5.js" type="text/javascript"></script>
    <script src="assets/lib/datatables/plugins/buttons/js/buttons.flash.js" type="text/javascript"></script>
    <script src="assets/lib/datatables/plugins/buttons/js/buttons.print.js" type="text/javascript"></script>
    <script src="assets/lib/datatables/plugins/buttons/js/buttons.colVis.js" type="text/javascript"></script>
    <script src="assets/lib/datatables/plugins/buttons/js/buttons.bootstrap.js" type="text/javascript"></script>
    <script src="assets/js/app-tables-datatables.js" type="text/javascript"></script>
 
    <script type="text/javascript">
      $(document).ready(function(){
        
      	//initialize the javascript
      	App.init();
  
      	App.dataTables();
         
      $.ajax({
          type:"get",
          url:"http://127.0.0.1:8080/routeApi/",
          success: function(data){
            console.log(data);
            $("#table-data").html("");
            $.each(data['route_info'],function (i,item) {
              $("#table-data").append('                      <tr class="gradeA">\
                        <td>'+item.id+'</td>\
                        <td>'+item.route_name+'</td>\
                        <td>'+item.route_namespace+'</td>\
                        <td class="center">'+item.route_host+'</td>\
                        <td class="center"><a href="route-detail.html?route_id='+item.id+'">详情</a> <a href="http://localhost:8080/routeApi/deleteRouteById?route_id='+item.id+'" style="color:red;" >删除</a></td>\
                      </tr>'
              );
            })
          },
          error: function(result){
            console.log(result);
          }
        });
      });
    

 
    </script>

  </body>
</html>

C:\Users\Administrator\Desktop\gopaas\go-paas-front\role-permission.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="description" content="">
    <meta name="author" content="">
    <link rel="shortcut icon" href="assets/img/logo-fav.png">
    <title>CPaaS</title>
    <link rel="stylesheet" type="text/css" href="assets/lib/perfect-scrollbar/css/perfect-scrollbar.min.css"/>
    <link rel="stylesheet" type="text/css" href="assets/lib/material-design-icons/css/material-design-iconic-font.min.css"/><!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
    <link rel="stylesheet" type="text/css" href="assets/lib/datatables/css/dataTables.bootstrap.min.css"/>
    <link rel="stylesheet" href="assets/css/style.css" type="text/css"/>
  </head>
  <body>
    <div class="be-wrapper">
      <nav class="navbar navbar-default navbar-fixed-top be-top-header">
        <div class="container-fluid">
          <div class="navbar-header"><a href="index.html" class="navbar-brand"></a>
          </div>
          <div class="be-right-navbar">
            <ul class="nav navbar-nav navbar-right be-user-nav">
              <li class="dropdown"><a href="#" data-toggle="dropdown" role="button" aria-expanded="false" class="dropdown-toggle"><img src="assets/img/avatar.png" alt="Avatar"><span class="user-name">Túpac Amaru</span></a>
                <ul role="menu" class="dropdown-menu">
                  <li>
                    <div class="user-info">
                      <div class="user-name">wu123</div>
                      <div class="user-position online">在线</div>
                    </div>
                  </li>
                  <li><a href="#"><span class="icon mdi mdi-face"></span> 账户</a></li>
                  <li><a href="#"><span class="icon mdi mdi-settings"></span> 设置</a></li>
                  <li><a href="#"><span class="icon mdi mdi-power"></span> 推出登录</a></li>
                </ul>
              </li>
            </ul>
            <div class="page-title"></div>
            <ul class="nav navbar-nav navbar-right be-icons-nav">
              <li class="dropdown"><a href="#" role="button" aria-expanded="false" class="be-toggle-right-sidebar"><span class="icon mdi mdi-settings"></span></a></li>
              <li class="dropdown"><a href="#" data-toggle="dropdown" role="button" aria-expanded="false" class="dropdown-toggle"><span class="icon mdi mdi-notifications"></span><span class="indicator"></span></a>
                <ul class="dropdown-menu be-notifications">
                  <li>
                    <div class="title">消息提醒<span class="badge">3</span></div>
                    <div class="list">
                      <div class="be-scroller">
                        <div class="content">
                          <ul>
                            <li class="notification notification-unread"><a href="#">
                                <div class="image"><img src="assets/img/avatar2.png" alt="Avatar"></div>
                                <div class="notification-info">
                                  <div class="text"><span class="user-name">Jessica Caruso</span> accepted your invitation to join the team.</div><span class="date">2 min ago</span>
                                </div></a></li>
                            <li class="notification"><a href="#">
                                <div class="image"><img src="assets/img/avatar3.png" alt="Avatar"></div>
                                <div class="notification-info">
                                  <div class="text"><span class="user-name">Joel King</span> is now following you</div><span class="date">2 days ago</span>
                                </div></a></li>
                            <li class="notification"><a href="#">
                                <div class="image"><img src="assets/img/avatar4.png" alt="Avatar"></div>
                                <div class="notification-info">
                                  <div class="text"><span class="user-name">John Doe</span> is watching your main repository</div><span class="date">2 days ago</span>
                                </div></a></li>
                            <li class="notification"><a href="#">
                                <div class="image"><img src="assets/img/avatar5.png" alt="Avatar"></div>
                                <div class="notification-info"><span class="text"><span class="user-name">Emily Carter</span> is now following you</span><span class="date">5 days ago</span></div></a></li>
                          </ul>
                        </div>
                      </div>
                    </div>
                    <div class="footer"> <a href="#">View all notifications</a></div>
                  </li>
                </ul>
              </li>
              <li class="dropdown"><a href="#" data-toggle="dropdown" role="button" aria-expanded="false" class="dropdown-toggle"><span class="icon mdi mdi-apps"></span></a>
                <ul class="dropdown-menu be-connections">
                  <li>
                    <div class="list">
                      <div class="content">
                        <div class="row">
                          <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/github.png" alt="Github"><span>GitHub</span></a></div>
                          <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/bitbucket.png" alt="Bitbucket"><span>Bitbucket</span></a></div>
                          <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/slack.png" alt="Slack"><span>Slack</span></a></div>
                        </div>
                        <div class="row">
                          <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/dribbble.png" alt="Dribbble"><span>Dribbble</span></a></div>
                          <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/mail_chimp.png" alt="Mail Chimp"><span>Mail Chimp</span></a></div>
                          <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/dropbox.png" alt="Dropbox"><span>Dropbox</span></a></div>
                        </div>
                      </div>
                    </div>
                    <div class="footer"> <a href="#">More</a></div>
                  </li>
                </ul>
              </li>
            </ul>
          </div>
        </div>
      </nav>
<!--
  侧边栏-开始
-->
<div class="be-left-sidebar">
  <div class="left-sidebar-wrapper"><a href="#" class="left-sidebar-toggle">看版</a>
    <div class="left-sidebar-spacer">
      <div class="left-sidebar-scroll">
        <div class="left-sidebar-content">
          <ul class="sidebar-elements">
            <li class="divider">菜单</li>
            <li class="parent"><a href="#"><i class="icon mdi mdi-home"></i><span>控制台</span></a>
            </li>
            <li class="parent"><a href="#"><i class="icon mdi mdi-face"></i><span>应用管理</span></a>
              <ul class="sub-menu">
                <li ><a href="pod-index.html">添加应用</a>
                </li>
              </ul>
            </li>
            <li class="parent"><a href="charts.html"><i class="icon mdi mdi-chart-donut"></i><span>服务管理</span></a>
              <ul class="sub-menu">
                <li ><a href="svc-index.html">添加服务</a>
                </li>
              </ul>
            </li>
            <li class="parent"><a href="#"><i class="icon mdi mdi-dot-circle"></i><span>域名管理</span></a>
              <ul class="sub-menu">
                <li  ><a href="route-index.html">添加路由</a>
                </li>
              </ul>
            </li>
            <li class="parent"><a href="#"><i class="icon mdi mdi-dot-circle"></i><span>权限管理</span></a>
              <ul class="sub-menu">
                <li class="active"><a href="route-index.html">权限管理</a>
                </li>
              </ul>
            </li>
            <li class="parent"><a href="#"><i class="icon mdi mdi-border-all"></i><span>权限管理</span></a>
              <ul class="sub-menu">
                <li><a href="tables-general.html">General</a>
                </li>
                <li><a href="tables-datatables.html">Data Tables</a>
                </li>
                <li><a href="tables-filters.html"><span class="label label-primary pull-right">New</span>Table Filters</a>
                </li>
              </ul>
            </li>
            <li class="parent"><a href="#"><i class="icon mdi mdi-layers"></i><span>权限管理</span></a>
              <ul class="sub-menu">
                <li><a href="pages-blank.html">Blank Page</a>
                </li>
                <li><a href="pages-blank-header.html">Blank Page Header</a>
                </li>
                <li><a href="pages-login.html">Login</a>
                </li>
                <li><a href="pages-login2.html">Login v2</a>
                </li>
                <li><a href="pages-404.html">404 Page</a>
                </li>
                <li><a href="pages-sign-up.html">Sign Up</a>
                </li>
                <li><a href="pages-forgot-password.html">Forgot Password</a>
                </li>
                <li><a href="pages-profile.html">Profile</a>
                </li>
                <li><a href="pages-pricing-tables.html">Pricing Tables</a>
                </li>
                <li><a href="pages-pricing-tables2.html">Pricing Tables v2</a>
                </li>
                <li><a href="pages-timeline.html">Timeline</a>
                </li>
                <li><a href="pages-timeline2.html">Timeline v2</a>
                </li>
                <li><a href="pages-invoice.html"><span class="label label-primary pull-right">New</span>Invoice</a>
                </li>
                <li><a href="pages-calendar.html">Calendar</a>
                </li>
                <li><a href="pages-gallery.html">Gallery</a>
                </li>
                <li><a href="pages-code-editor.html"><span class="label label-primary pull-right">New    </span>Code Editor</a>
                </li>
                <li><a href="pages-booking.html"><span class="label label-primary pull-right">New</span>Booking</a>
                </li>
                <li><a href="pages-loaders.html"><span class="label label-primary pull-right">New</span>Loaders</a>
                </li>
              </ul>
            </li>
         
          </ul>
        </div>
      </div>
    </div>
    <div class="progress-widget">

      <div class="progress">
        <div style="width: 60%;" class="progress-bar progress-bar-primary"></div>
      </div>
    </div>
  </div>
</div>
<!--
侧边栏-结束
-->
      <div class="be-content">
        <div class="page-head">
          <h2 class="page-head-title">权限管理</h2>
          <ol class="breadcrumb page-head-nav">
            <li><a href="#">控制台</a></li>
            <li><a href="#">权限管理</a></li>
            <li class="active">权限管理列表</li>
          </ol>
        </div>
        <div class="main-content container-fluid">
          <div class="main-content container-fluid">

            <div class="row">
              <div class="col-md-12">
                <div class="panel panel-default panel-border-color panel-border-color-primary">
                  <div class="panel-heading panel-heading-divider">权限设置<span class="panel-subtitle">分配系统详细的权限</span></div>
                  <div class="panel-body">
                    <form action="http://127.0.0.1:8080/userApi/AddPermission" class="form-horizontal group-border-dashed" method="post" novalidate="">
                      <div class="form-group">
                        <label class="col-sm-3 control-label">角色</label>
                        <div class="col-sm-6">
                          <div class="be-checkbox be-checkbox-color inline">
                            <select name="role_id">
                              <option value="1">主管</option>
                              <option value="2">组长</option>
                              <option value="3">组员</option>
                              <option value="4">访客</option>
                            </select>
                          </div>
                        </div>
                      </div>

                      <div class="form-group">
                        <label class="col-sm-3 control-label">应用管理</label>
                        <div class="col-sm-6">
                          <div class="be-checkbox be-checkbox-color inline">
                            <input id="check6" type="checkbox" checked="" name="permission_id" value="1">
                            <label for="check6">应用创建</label>
                          </div>
                          <div class="be-checkbox be-checkbox-color has-danger inline">
                            <input id="check7" type="checkbox" name="permission_id" value="2">
                            <label for="check7">应用删除</label>
                          </div>
                          <div class="be-checkbox be-checkbox-color has-success inline">
                            <input id="check8" type="checkbox" name="permission_id" value="3">
                            <label for="check8">应用查看</label>
                          </div>
                          <div class="be-checkbox be-checkbox-color has-warning inline">
                            <input id="check9" type="checkbox" name="permission_id" value="4">
                            <label for="check9">应用续费</label>
                          </div>
                        </div>

                      </div>
                      <div class="form-group">
                        <label class="col-sm-3 control-label">服务管理</label>
                        <div class="col-sm-6">
                          <div class="be-checkbox be-checkbox-color inline">
                            <input id="check26" type="checkbox" checked="" name="permission_id" value="5">
                            <label for="check26">服务创建</label>
                          </div>
                          <div class="be-checkbox be-checkbox-color  has-danger inline">
                            <input id="check27" type="checkbox" name="permission_id" value="6">
                            <label for="check27">服务删除</label>
                          </div>
                          <div class="be-checkbox be-checkbox-color has-success  inline">
                            <input id="check28" type="checkbox" name="permission_id" value="7">
                            <label for="check28">服务查看</label>
                          </div>
                          <div class="be-checkbox be-checkbox-color has-warning inline">
                            <input id="check29" type="checkbox" name="permission_id" value="8">
                            <label for="check29">应用续费</label>
                          </div>
                        </div>

                      </div>
                      <div class="form-group">
                        <label class="col-sm-3 control-label">域名管理</label>
                        <div class="col-sm-6">
                          <div class="be-checkbox be-checkbox-color inline">
                            <input id="check16" type="checkbox" checked="" name="permission_id" value="9">
                            <label for="check16">域名创建</label>
                          </div>
                          <div class="be-checkbox be-checkbox-color has-danger inline">
                            <input id="check17" type="checkbox" name="permission_id" value="10">
                            <label for="check17">域名删除</label>
                          </div>
                          <div class="be-checkbox be-checkbox-color has-success  inline">
                            <input id="check18" type="checkbox" name="permission_id" value="11">
                            <label for="check18">域名查看</label>
                          </div>
                          <div class="be-checkbox be-checkbox-color has-warning inline">
                            <input id="check19" type="checkbox" name="permission_id" value="12">
                            <label for="check19">域名续费</label>
                          </div>
                        </div>

                      </div>
                      <div class="form-group">
                        <label class="col-sm-3 control-label">云盘管理</label>
                        <div class="col-sm-6">
                          <div class="be-checkbox be-checkbox-color inline">
                            <input id="check36" type="checkbox" checked="">
                            <label for="check36">云盘创建</label>
                          </div>
                          <div class="be-checkbox be-checkbox-color has-danger inline">
                            <input id="check37" type="checkbox">
                            <label for="check37">云盘删除</label>
                          </div>
                          <div class="be-checkbox be-checkbox-color has-success  inline">
                            <input id="check38" type="checkbox">
                            <label for="check38">云盘查看</label>
                          </div>
                          <div class="be-checkbox be-checkbox-color  has-warning inline">
                            <input id="check39" type="checkbox">
                            <label for="check39">云盘续费</label>
                          </div>
                        </div>

                      </div>
                      <div class="form-group">
                        <label class="col-sm-3 control-label">云应用市场</label>
                        <div class="col-sm-6">
                          <div class="be-checkbox be-checkbox-color inline">
                            <input id="check46" type="checkbox" checked="">
                            <label for="check46">云应用安装</label>
                          </div>
                          <div class="be-checkbox be-checkbox-color has-danger inline">
                            <input id="check47" type="checkbox">
                            <label for="check47">云应用删除</label>
                          </div>
                          <div class="be-checkbox be-checkbox-color has-success inline">
                            <input id="check48" type="checkbox">
                            <label for="check48">云市场查看</label>
                          </div>
                          <div class="be-checkbox be-checkbox-color has-warning inline">
                            <input id="check49" type="checkbox">
                            <label for="check49">云市场搜索</label>
                          </div>
                        </div>

                      </div>
                      <div class="form-group">
                        <label class="col-sm-3 control-label">中间件管理</label>
                        <div class="col-sm-6">
                          <div class="be-checkbox be-checkbox-color inline">
                            <input id="check56" type="checkbox" checked="">
                            <label for="check56">中间件创建</label>
                          </div>
                          <div class="be-checkbox be-checkbox-color has-danger inline">
                            <input id="check57" type="checkbox">
                            <label for="check57">中间件删除</label>
                          </div>
                          <div class="be-checkbox be-checkbox-color has-success inline">
                            <input id="check58" type="checkbox">
                            <label for="check58">中间件查看</label>
                          </div>
                          <div class="be-checkbox be-checkbox-color has-warning inline">
                            <input id="check59" type="checkbox">
                            <label for="check59">中间件续费</label>
                          </div>
                          <div class="form-group">
                            <div class="col-sm-2 col-sm-10">
                              <button type="submit" class="btn btn-space btn-primary">提交</button>
                              <button class="btn btn-space btn-default">取消</button>
                            </div>
                          </div>
                        </div>

                      </div>
                    </form>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>

      </div>
      <nav class="be-right-sidebar">
        <div class="sb-content">
          <div class="tab-navigation">
            <ul role="tablist" class="nav nav-tabs nav-justified">
              <li role="presentation" class="active"><a href="#tab1" aria-controls="tab1" role="tab" data-toggle="tab">Chat</a></li>
              <li role="presentation"><a href="#tab2" aria-controls="tab2" role="tab" data-toggle="tab">Todo</a></li>
              <li role="presentation"><a href="#tab3" aria-controls="tab3" role="tab" data-toggle="tab">Settings</a></li>
            </ul>
          </div>
          <div class="tab-panel">
            <div class="tab-content">
              <div id="tab1" role="tabpanel" class="tab-pane tab-chat active">
                <div class="chat-contacts">
                  <div class="chat-sections">
                    <div class="be-scroller">
                      <div class="content">
                        <h2>Recent</h2>
                        <div class="contact-list contact-list-recent">
                          <div class="user"><a href="#"><img src="assets/img/avatar1.png" alt="Avatar">
                              <div class="user-data"><span class="status away"></span><span class="name">Claire Sassu</span><span class="message">Can you share the...</span></div></a></div>
                          <div class="user"><a href="#"><img src="assets/img/avatar2.png" alt="Avatar">
                              <div class="user-data"><span class="status"></span><span class="name">Maggie jackson</span><span class="message">I confirmed the info.</span></div></a></div>
                          <div class="user"><a href="#"><img src="assets/img/avatar3.png" alt="Avatar">
                              <div class="user-data"><span class="status offline"></span><span class="name">Joel King		</span><span class="message">Ready for the meeti...</span></div></a></div>
                        </div>
                        <h2>Contacts</h2>
                        <div class="contact-list">
                          <div class="user"><a href="#"><img src="assets/img/avatar4.png" alt="Avatar">
                              <div class="user-data2"><span class="status"></span><span class="name">Mike Bolthort</span></div></a></div>
                          <div class="user"><a href="#"><img src="assets/img/avatar5.png" alt="Avatar">
                              <div class="user-data2"><span class="status"></span><span class="name">Maggie jackson</span></div></a></div>
                          <div class="user"><a href="#"><img src="assets/img/avatar6.png" alt="Avatar">
                              <div class="user-data2"><span class="status offline"></span><span class="name">Jhon Voltemar</span></div></a></div>
                        </div>
                      </div>
                    </div>
                  </div>
                  <div class="bottom-input">
                    <input type="text" placeholder="Search..." name="q"><span class="mdi mdi-search"></span>
                  </div>
                </div>
                <div class="chat-window">
                  <div class="title">
                    <div class="user"><img src="assets/img/avatar2.png" alt="Avatar">
                      <h2>Maggie jackson</h2><span>Active 1h ago</span>
                    </div><span class="icon return mdi mdi-chevron-left"></span>
                  </div>
                  <div class="chat-messages">
                    <div class="be-scroller">
                      <div class="content">
                        <ul>
                          <li class="friend">
                            <div class="msg">Hello</div>
                          </li>
                          <li class="self">
                            <div class="msg">Hi, how are you?</div>
                          </li>
                          <li class="friend">
                            <div class="msg">Good, I'll need support with my pc</div>
                          </li>
                          <li class="self">
                            <div class="msg">Sure, just tell me what is going on with your computer?</div>
                          </li>
                          <li class="friend">
                            <div class="msg">I don't know it just turns off suddenly</div>
                          </li>
                        </ul>
                      </div>
                    </div>
                  </div>
                  <div class="chat-input">
                    <div class="input-wrapper"><span class="photo mdi mdi-camera"></span>
                      <input type="text" placeholder="Message..." name="q" autocomplete="off"><span class="send-msg mdi mdi-mail-send"></span>
                    </div>
                  </div>
                </div>
              </div>
              <div id="tab2" role="tabpanel" class="tab-pane tab-todo">
                <div class="todo-container">
                  <div class="todo-wrapper">
                    <div class="be-scroller">
                      <div class="todo-content"><span class="category-title">Today</span>
                        <ul class="todo-list">
                          <li>
                            <div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
                              <input id="todo1" type="checkbox" checked="">
                              <label for="todo1">Initialize the project</label>
                            </div>
                          </li>
                          <li>
                            <div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
                              <input id="todo2" type="checkbox">
                              <label for="todo2">Create the main structure</label>
                            </div>
                          </li>
                          <li>
                            <div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
                              <input id="todo3" type="checkbox">
                              <label for="todo3">Updates changes to GitHub</label>
                            </div>
                          </li>
                        </ul><span class="category-title">Tomorrow</span>
                        <ul class="todo-list">
                          <li>
                            <div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
                              <input id="todo4" type="checkbox">
                              <label for="todo4">Initialize the project</label>
                            </div>
                          </li>
                          <li>
                            <div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
                              <input id="todo5" type="checkbox">
                              <label for="todo5">Create the main structure</label>
                            </div>
                          </li>
                          <li>
                            <div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
                              <input id="todo6" type="checkbox">
                              <label for="todo6">Updates changes to GitHub</label>
                            </div>
                          </li>
                          <li>
                            <div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
                              <input id="todo7" type="checkbox">
                              <label for="todo7" title="This task is too long to be displayed in a normal space!">This task is too long to be displayed in a normal space!</label>
                            </div>
                          </li>
                        </ul>
                      </div>
                    </div>
                  </div>
                  <div class="bottom-input">
                    <input type="text" placeholder="Create new task..." name="q"><span class="mdi mdi-plus"></span>
                  </div>
                </div>
              </div>
              <div id="tab3" role="tabpanel" class="tab-pane tab-settings">
                <div class="settings-wrapper">
                  <div class="be-scroller"><span class="category-title">General</span>
                    <ul class="settings-list">
                      <li>
                        <div class="switch-button switch-button-sm">
                          <input type="checkbox" checked="" name="st1" id="st1"><span>
                            <label for="st1"></label></span>
                        </div><span class="name">Available</span>
                      </li>
                      <li>
                        <div class="switch-button switch-button-sm">
                          <input type="checkbox" checked="" name="st2" id="st2"><span>
                            <label for="st2"></label></span>
                        </div><span class="name">Enable notifications</span>
                      </li>
                      <li>
                        <div class="switch-button switch-button-sm">
                          <input type="checkbox" checked="" name="st3" id="st3"><span>
                            <label for="st3"></label></span>
                        </div><span class="name">Login with Facebook</span>
                      </li>
                    </ul><span class="category-title">Notifications</span>
                    <ul class="settings-list">
                      <li>
                        <div class="switch-button switch-button-sm">
                          <input type="checkbox" name="st4" id="st4"><span>
                            <label for="st4"></label></span>
                        </div><span class="name">Email notifications</span>
                      </li>
                      <li>
                        <div class="switch-button switch-button-sm">
                          <input type="checkbox" checked="" name="st5" id="st5"><span>
                            <label for="st5"></label></span>
                        </div><span class="name">Project updates</span>
                      </li>
                      <li>
                        <div class="switch-button switch-button-sm">
                          <input type="checkbox" checked="" name="st6" id="st6"><span>
                            <label for="st6"></label></span>
                        </div><span class="name">New comments</span>
                      </li>
                      <li>
                        <div class="switch-button switch-button-sm">
                          <input type="checkbox" name="st7" id="st7"><span>
                            <label for="st7"></label></span>
                        </div><span class="name">Chat messages</span>
                      </li>
                    </ul><span class="category-title">Workflow</span>
                    <ul class="settings-list">
                      <li>
                        <div class="switch-button switch-button-sm">
                          <input type="checkbox" name="st8" id="st8"><span>
                            <label for="st8"></label></span>
                        </div><span class="name">Deploy on commit</span>
                      </li>
                    </ul>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </nav>
    </div>
    <script src="assets/lib/jquery/jquery.min.js" type="text/javascript"></script>
    <script src="assets/lib/perfect-scrollbar/js/perfect-scrollbar.jquery.min.js" type="text/javascript"></script>
    <script src="assets/js/main.js" type="text/javascript"></script>
    <script src="assets/lib/bootstrap/dist/js/bootstrap.min.js" type="text/javascript"></script>
    <script src="assets/lib/datatables/js/jquery.dataTables.min.js" type="text/javascript"></script>
    <script src="assets/lib/datatables/js/dataTables.bootstrap.min.js" type="text/javascript"></script>
    <script src="assets/lib/datatables/plugins/buttons/js/dataTables.buttons.js" type="text/javascript"></script>
    <script src="assets/lib/datatables/plugins/buttons/js/buttons.html5.js" type="text/javascript"></script>
    <script src="assets/lib/datatables/plugins/buttons/js/buttons.flash.js" type="text/javascript"></script>
    <script src="assets/lib/datatables/plugins/buttons/js/buttons.print.js" type="text/javascript"></script>
    <script src="assets/lib/datatables/plugins/buttons/js/buttons.colVis.js" type="text/javascript"></script>
    <script src="assets/lib/datatables/plugins/buttons/js/buttons.bootstrap.js" type="text/javascript"></script>
    <script src="assets/js/app-tables-datatables.js" type="text/javascript"></script>
 
    <script type="text/javascript">
      $(document).ready(function(){
        
      	//initialize the javascript
      	App.init();
  
      	App.dataTables();
         
      $.ajax({
          type:"get",
          url:"http://127.0.0.1:8080/routeApi/",
          success: function(data){
            console.log(data);
            $("#table-data").html("");
            $.each(data['route_info'],function (i,item) {
              $("#table-data").append('                      <tr class="gradeA">\
                        <td>'+item.id+'</td>\
                        <td>'+item.route_name+'</td>\
                        <td>'+item.route_namespace+'</td>\
                        <td class="center">'+item.route_host+'</td>\
                        <td class="center"><a href="route-detail.html?route_id='+item.id+'">详情</a> <a href="http://localhost:8080/routeApi/deleteRouteById?route_id='+item.id+'" style="color:red;" >删除</a></td>\
                      </tr>'
              );
            })
          },
          error: function(result){
            console.log(result);
          }
        });
      });
    

 
    </script>

  </body>
</html>

C:\Users\Administrator\Desktop\gopaas\userapi\proto\userApi\userApi.proto

service UserApi {
    rpc FindUserById(Request) returns (Response){}
	rpc AddUser(Request) returns (Response){}
	rpc DeleteUserById(Request) returns (Response){}
	rpc UpdateUser(Request) returns (Response){}
	//默认接口
	rpc Call(Request) returns (Response){}

	rpc AddRole(Request) returns (Response){}
	rpc UpdateRole(Request) returns (Response){}
	rpc DeleteRole(Request) returns (Response){}

	rpc IsRight(Request) returns (Response){}

	rpc AddPermission(Request) returns (Response){}
	rpc UpdatePermission(Request) returns (Response){}
	rpc DeletePermission(Request) returns (Response){}
}
PS D:\Workspace\Go\bin> D:\Workspace\Go\bin\protoc.exe --proto_path=C:\Users\Administrator\Desktop\gopaas\userapi --micro_out=C:\Users\Administrator\Desktop\gopaas\userapi --go_out=:C:\Users\Administrator\Desktop\gopaas\userapi C:\Users\Administrator\Desktop\gopaas\userapi\proto\userApi\userApi.proto

 C:\Users\Administrator\Desktop\gopaas\userapi\handler\userApiHandler.go

package handler

import (
	"context"
	"encoding/json"
	"errors"
	"strconv"

	log "github.com/asim/go-micro/v3/logger"
	"github.com/yunixiangfeng/gopaas/common"
	role "github.com/yunixiangfeng/gopaas/user/proto/role"
	user "github.com/yunixiangfeng/gopaas/user/proto/user"
	userApi "github.com/yunixiangfeng/gopaas/userApi/proto/userApi"
)

type UserApi struct {
	UserService user.UserService
	RoleService role.RoleService
}

func (e *UserApi) getPost(req *userApi.Request, key string) (string, error) {
	if _, ok := req.Post[key]; !ok {
		return "", errors.New("参数异常")
	}
	return req.Post[key].Values[0], nil
}

func (e *UserApi) getStringInt64(stringValue string) int64 {
	intValue, err := strconv.ParseInt(stringValue, 10, 64)
	if err != nil {
		common.Error(err)
		return 0
	}
	return intValue
}

func (e *UserApi) AddRole(ctx context.Context, req *userApi.Request, rsp *userApi.Response) error {
	userIdString, err := e.getPost(req, "user_id")
	if err != nil {
		common.Error(err)
		return err
	}
	userId := e.getStringInt64(userIdString)

	if _, ok := req.Post["role_id"]; !ok {
		common.Error(err)
		return err
	}
	roleId := []int64{}
	for _, v := range req.Post["role_id"].Values {
		roleId = append(roleId, e.getStringInt64(v))
	}

	rs, err := e.UserService.AddRole(ctx, &user.UserRole{
		UserId: userId,
		RoleId: roleId,
	})
	if err != nil {
		common.Error(err)
		return err
	}
	rsp.StatusCode = 200
	b, _ := json.Marshal(rs)
	rsp.Body = string(b)
	return nil
}

func (e *UserApi) UpdateRole(ctx context.Context, req *userApi.Request, rsp *userApi.Response) error {
	userIdString, err := e.getPost(req, "user_id")
	if err != nil {
		common.Error(err)
		return err
	}
	userId := e.getStringInt64(userIdString)

	if _, ok := req.Post["role_id"]; !ok {
		common.Error(err)
		return err
	}
	roleId := []int64{}
	for _, v := range req.Post["role_id"].Values {
		roleId = append(roleId, e.getStringInt64(v))
	}

	rs, err := e.UserService.UpdateRole(ctx, &user.UserRole{
		UserId: userId,
		RoleId: roleId,
	})
	if err != nil {
		common.Error(err)
		return err
	}
	rsp.StatusCode = 200
	b, _ := json.Marshal(rs)
	rsp.Body = string(b)
	return nil
}

func (e *UserApi) DeleteRole(ctx context.Context, req *userApi.Request, rsp *userApi.Response) error {
	userIdString, err := e.getPost(req, "user_id")
	if err != nil {
		common.Error(err)
		return err
	}
	userId := e.getStringInt64(userIdString)

	if _, ok := req.Post["role_id"]; !ok {
		common.Error(err)
		return err
	}
	roleId := []int64{}
	for _, v := range req.Post["role_id"].Values {
		roleId = append(roleId, e.getStringInt64(v))
	}

	rs, err := e.UserService.DeleteRole(ctx, &user.UserRole{
		UserId: userId,
		RoleId: roleId,
	})
	if err != nil {
		common.Error(err)
		return err
	}
	rsp.StatusCode = 200
	b, _ := json.Marshal(rs)
	rsp.Body = string(b)
	return nil
}

func (e *UserApi) IsRight(ctx context.Context, req *userApi.Request, rsp *userApi.Response) error {
	if _, ok := req.Get["user_id"]; !ok {
		return errors.New("参数异常")
	}
	idString := req.Get["user_id"].Values[0]
	userId, err := strconv.ParseInt(idString, 10, 64)
	if err != nil {
		common.Error(err)
		return err
	}
	if _, ok := req.Get["user_action"]; !ok {
		return errors.New("参数异常")
	}
	action := req.Get["user_action"].Values[0]

	right, err := e.UserService.IsRight(ctx, &user.UserRight{
		UserId: userId,
		Action: action,
	})
	if err != nil {
		common.Error(err)
		return err
	}
	rsp.StatusCode = 200
	b, _ := json.Marshal(right)
	rsp.Body = string(b)
	return nil
}

func (e *UserApi) AddPermission(ctx context.Context, req *userApi.Request, rsp *userApi.Response) error {
	roleIdString, err := e.getPost(req, "role_id")
	if err != nil {
		common.Error(err)
		return err
	}
	roleId := e.getStringInt64(roleIdString)

	if _, ok := req.Post["permission_id"]; !ok {
		common.Error(err)
		return err
	}
	permissionId := []int64{}
	for _, v := range req.Post["permission_id"].Values {
		permissionId = append(permissionId, e.getStringInt64(v))
	}

	rs, err := e.RoleService.AddPermission(ctx, &role.RolePermission{
		PermissionId: permissionId,
		RoleId:       roleId,
	})
	if err != nil {
		common.Error(err)
		return err
	}
	rsp.StatusCode = 200
	b, _ := json.Marshal(rs)
	rsp.Body = string(b)
	return nil
}

func (e *UserApi) UpdatePermission(ctx context.Context, req *userApi.Request, rsp *userApi.Response) error {
	roleIdString, err := e.getPost(req, "role_id")
	if err != nil {
		common.Error(err)
		return err
	}
	roleId := e.getStringInt64(roleIdString)

	if _, ok := req.Post["permission_id"]; !ok {
		common.Error(err)
		return err
	}
	permissionId := []int64{}
	for _, v := range req.Post["permission_id"].Values {
		permissionId = append(permissionId, e.getStringInt64(v))
	}

	rs, err := e.RoleService.UpdatePermission(ctx, &role.RolePermission{
		PermissionId: permissionId,
		RoleId:       roleId,
	})
	if err != nil {
		common.Error(err)
		return err
	}
	rsp.StatusCode = 200
	b, _ := json.Marshal(rs)
	rsp.Body = string(b)
	return nil
}

func (e *UserApi) DeletePermission(ctx context.Context, req *userApi.Request, rsp *userApi.Response) error {
	roleIdString, err := e.getPost(req, "role_id")
	if err != nil {
		common.Error(err)
		return err
	}
	roleId := e.getStringInt64(roleIdString)

	if _, ok := req.Post["permission_id"]; !ok {
		common.Error(err)
		return err
	}
	permissionId := []int64{}
	for _, v := range req.Post["permission_id"].Values {
		permissionId = append(permissionId, e.getStringInt64(v))
	}

	rs, err := e.RoleService.DeletePermission(ctx, &role.RolePermission{
		PermissionId: permissionId,
		RoleId:       roleId,
	})
	if err != nil {
		common.Error(err)
		return err
	}
	rsp.StatusCode = 200
	b, _ := json.Marshal(rs)
	rsp.Body = string(b)
	return nil
}

// userApi.FindUserById 通过API向外暴露为/userApi/findUserById,接收http请求
// 即:/userApi/FindUserById 请求会调用go.micro.api.userApi 服务的userApi.FindUserById 方法
func (e *UserApi) FindUserById(ctx context.Context, req *userApi.Request, rsp *userApi.Response) error {
	log.Info("Received userApi.FindUserById request")
	rsp.StatusCode = 200
	b, _ := json.Marshal("{success:'成功访问/userApi/FindUserById'}")
	rsp.Body = string(b)
	return nil
}

// userApi.AddUser 通过API向外暴露为/userApi/AddUser,接收http请求
// 即:/userApi/AddUser 请求会调用go.micro.api.userApi 服务的userApi.AddUser 方法
func (e *UserApi) AddUser(ctx context.Context, req *userApi.Request, rsp *userApi.Response) error {
	log.Info("Received userApi.AddUser request")
	rsp.StatusCode = 200
	b, _ := json.Marshal("{success:'成功访问/userApi/AddUser'}")
	rsp.Body = string(b)
	return nil
}

// userApi.DeleteUserById 通过API向外暴露为/userApi/DeleteUserById,接收http请求
// 即:/userApi/DeleteUserById 请求会调用go.micro.api.userApi 服务的 userApi.DeleteUserById 方法
func (e *UserApi) DeleteUserById(ctx context.Context, req *userApi.Request, rsp *userApi.Response) error {
	log.Info("Received userApi.DeleteUserById request")
	rsp.StatusCode = 200
	b, _ := json.Marshal("{success:'成功访问/userApi/DeleteUserById'}")
	rsp.Body = string(b)
	return nil
}

// userApi.UpdateUser 通过API向外暴露为/userApi/UpdateUser,接收http请求
// 即:/userApi/UpdateUser 请求会调用go.micro.api.userApi 服务的userApi.UpdateUser 方法
func (e *UserApi) UpdateUser(ctx context.Context, req *userApi.Request, rsp *userApi.Response) error {
	log.Info("Received userApi.UpdateUser request")
	rsp.StatusCode = 200
	b, _ := json.Marshal("{success:'成功访问/userApi/UpdateUser'}")
	rsp.Body = string(b)
	return nil
}

// 默认的方法userApi.Call 通过API向外暴露为/userApi/call,接收http请求
// 即:/userApi/call或/userApi/ 请求会调用go.micro.api.userApi 服务的userApi.FindUserById 方法
func (e *UserApi) Call(ctx context.Context, req *userApi.Request, rsp *userApi.Response) error {
	log.Info("Received userApi.Call request")
	rsp.StatusCode = 200
	b, _ := json.Marshal("{success:'成功访问:Call'}")
	rsp.Body = string(b)
	return nil
}

 C:\Users\Administrator\Desktop\gopaas\userapi\main.go

	userService := go_micro_service_user.NewUserService("go.micro.service.user", service.Client())
	roleService := go_micro_service_role.NewRoleService("go.micro.service.role", service.Client())

	// 注册控制器
	if err := userApi.RegisterUserApiHandler(service.Server(), &handler.UserApi{UserService: userService, RoleService: roleService}); err != nil {
		common.Error(err)
	}

12-15总结&思考

主要内容
用户中心服务开发
用户中心API开发
用户中心页面联调 

用户中心中添加职位如何操作?
用户中心中的数据权限如何添加?

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值