Kaynağa Gözat

Merge branch 'gin-vue-admin_v2_dev' of https://github.com/flipped-aurora/gin-vue-admin into gin-vue-admin_v2_dev

jinlan.du 4 yıl önce
ebeveyn
işleme
890030ab3c

+ 9 - 2
README-zh_CN.md

@@ -7,7 +7,7 @@
 <img src="https://img.shields.io/badge/gin-1.4.0-lightBlue"/>
 <img src="https://img.shields.io/badge/vue-2.6.10-brightgreen"/>
 <img src="https://img.shields.io/badge/element--ui-2.12.0-green"/>
-<img src="https://img.shields.io/badge/gorm-1.9.10-red"/>
+<img src="https://img.shields.io/badge/gorm-1.9.12-red"/>
 </div>
 
 [English](./README.md) | 简体中文
@@ -143,8 +143,15 @@ swag init
 
 
 ## 4. 项目架构
+### 4.1 系统架构图
 
-![架构图](./docs/gin-vue-admin.png)
+![系统架构图](./docs/gin-vue-admin.png)
+
+### 4.2 前端详细设计图 (提供者:<a href="https://github.com/baobeisuper">baobeisuper</a>)
+
+![前端详细设计图](http://qmplusimg.henrongyi.top/naotu.png)
+
+### 4.3 目录结构
 
 ```
     ├─server  	     (后端文件夹)

+ 9 - 1
README.md

@@ -7,7 +7,7 @@
 <img src="https://img.shields.io/badge/gin-1.4.0-lightBlue"/>
 <img src="https://img.shields.io/badge/vue-2.6.10-brightgreen"/>
 <img src="https://img.shields.io/badge/element--ui-2.12.0-green"/>
-<img src="https://img.shields.io/badge/gorm-1.9.10-red"/>
+<img src="https://img.shields.io/badge/gorm-1.9.12-red"/>
 </div>
 
 English | [简体中文](./README-zh_CN.md)
@@ -144,8 +144,16 @@ After executing the above command,`docs` will show in `server/`,then open yo
 
 ## 4. Project Architecture
 
+### 4.1 Architecture Diagram
+
 ![Architecture diagram](./docs/gin-vue-admin.png)
 
+### 4.2 Front-end Detailed Design Diagram (Contributor: <a href="https://github.com/baobeisuper">baobeisuper</a>)
+
+![Front-end Detailed Design Diagram](http://qmplusimg.henrongyi.top/naotu.png)
+
+### 4.3 Project Layout
+
 ```
     ├─server  	     (backend)
     │  ├─api            (API entrance)

+ 3 - 0
package-lock.json

@@ -0,0 +1,3 @@
+{
+  "lockfileVersion": 1
+}

+ 48 - 0
server/api/v1/exa_customer.go

@@ -7,6 +7,7 @@ import (
 	"gin-vue-admin/model/request"
 	resp "gin-vue-admin/model/response"
 	"gin-vue-admin/service"
+	"gin-vue-admin/utils"
 	"github.com/gin-gonic/gin"
 )
 
@@ -21,6 +22,15 @@ import (
 func CreateExaCustomer(c *gin.Context) {
 	var cu model.ExaCustomer
 	_ = c.ShouldBindJSON(&cu)
+	CustomerVerify := utils.Rules{
+		"CustomerName":      {utils.NotEmpty()},
+		"CustomerPhoneData": {utils.NotEmpty()},
+	}
+	CustomerVerifyErr := utils.Verify(cu, CustomerVerify)
+	if CustomerVerifyErr != nil {
+		response.FailWithMessage(CustomerVerifyErr.Error(), c)
+		return
+	}
 	claims, _ := c.Get("claims")
 	waitUse := claims.(*request.CustomClaims)
 	cu.SysUserID = waitUse.ID
@@ -44,6 +54,14 @@ func CreateExaCustomer(c *gin.Context) {
 func DeleteExaCustomer(c *gin.Context) {
 	var cu model.ExaCustomer
 	_ = c.ShouldBindJSON(&cu)
+	CustomerVerify := utils.Rules{
+		"ID": {utils.NotEmpty()},
+	}
+	CustomerVerifyErr := utils.Verify(cu.Model, CustomerVerify)
+	if CustomerVerifyErr != nil {
+		response.FailWithMessage(CustomerVerifyErr.Error(), c)
+		return
+	}
 	err := service.DeleteExaCustomer(cu)
 	if err != nil {
 		response.FailWithMessage(fmt.Sprintf("删除失败:%v", err), c)
@@ -63,6 +81,23 @@ func DeleteExaCustomer(c *gin.Context) {
 func UpdateExaCustomer(c *gin.Context) {
 	var cu model.ExaCustomer
 	_ = c.ShouldBindJSON(&cu)
+	IdCustomerVerify := utils.Rules{
+		"ID": {utils.NotEmpty()},
+	}
+	IdCustomerVerifyErr := utils.Verify(cu.Model, IdCustomerVerify)
+	if IdCustomerVerifyErr != nil {
+		response.FailWithMessage(IdCustomerVerifyErr.Error(), c)
+		return
+	}
+	CustomerVerify := utils.Rules{
+		"CustomerName":      {utils.NotEmpty()},
+		"CustomerPhoneData": {utils.NotEmpty()},
+	}
+	CustomerVerifyErr := utils.Verify(cu, CustomerVerify)
+	if CustomerVerifyErr != nil {
+		response.FailWithMessage(CustomerVerifyErr.Error(), c)
+		return
+	}
 	err := service.UpdateExaCustomer(&cu)
 	if err != nil {
 		response.FailWithMessage(fmt.Sprintf("更新失败:%v", err), c)
@@ -82,6 +117,14 @@ func UpdateExaCustomer(c *gin.Context) {
 func GetExaCustomer(c *gin.Context) {
 	var cu model.ExaCustomer
 	_ = c.ShouldBindQuery(&cu)
+	IdCustomerVerify := utils.Rules{
+		"ID": {utils.NotEmpty()},
+	}
+	IdCustomerVerifyErr := utils.Verify(cu.Model, IdCustomerVerify)
+	if IdCustomerVerifyErr != nil {
+		response.FailWithMessage(IdCustomerVerifyErr.Error(), c)
+		return
+	}
 	err, customer := service.GetExaCustomer(cu.ID)
 	if err != nil {
 		response.FailWithMessage(fmt.Sprintf("获取失败:%v", err), c)
@@ -103,6 +146,11 @@ func GetExaCustomerList(c *gin.Context) {
 	waitUse := claims.(*request.CustomClaims)
 	var pageInfo request.PageInfo
 	_ = c.ShouldBindQuery(&pageInfo)
+	PageVerifyErr := utils.Verify(pageInfo, utils.CustomizeMap["PageVerify"])
+	if PageVerifyErr != nil {
+		response.FailWithMessage(PageVerifyErr.Error(), c)
+		return
+	}
 	err, customerList, total := service.GetCustomerInfoList(waitUse.AuthorityId, pageInfo)
 	if err != nil {
 		response.FailWithMessage(fmt.Sprintf("获取失败:%v", err), c)

+ 41 - 0
server/api/v1/sys_api.go

@@ -7,6 +7,7 @@ import (
 	"gin-vue-admin/model/request"
 	resp "gin-vue-admin/model/response"
 	"gin-vue-admin/service"
+	"gin-vue-admin/utils"
 	"github.com/gin-gonic/gin"
 )
 
@@ -21,6 +22,17 @@ import (
 func CreateApi(c *gin.Context) {
 	var api model.SysApi
 	_ = c.ShouldBindJSON(&api)
+	ApiVerify := utils.Rules{
+		"Path":        {utils.NotEmpty()},
+		"Description": {utils.NotEmpty()},
+		"ApiGroup":    {utils.NotEmpty()},
+		"Method":      {utils.NotEmpty()},
+	}
+	ApiVerifyErr := utils.Verify(api, ApiVerify)
+	if ApiVerifyErr != nil {
+		response.FailWithMessage(ApiVerifyErr.Error(), c)
+		return
+	}
 	err := service.CreateApi(api)
 	if err != nil {
 		response.FailWithMessage(fmt.Sprintf("创建失败,%v", err), c)
@@ -40,6 +52,14 @@ func CreateApi(c *gin.Context) {
 func DeleteApi(c *gin.Context) {
 	var a model.SysApi
 	_ = c.ShouldBindJSON(&a)
+	ApiVerify := utils.Rules{
+		"ID": {utils.NotEmpty()},
+	}
+	ApiVerifyErr := utils.Verify(a.Model, ApiVerify)
+	if ApiVerifyErr != nil {
+		response.FailWithMessage(ApiVerifyErr.Error(), c)
+		return
+	}
 	err := service.DeleteApi(a)
 	if err != nil {
 		response.FailWithMessage(fmt.Sprintf("删除失败,%v", err), c)
@@ -62,6 +82,11 @@ func GetApiList(c *gin.Context) {
 	// 此结构体仅本方法使用
 	var sp request.SearchApiParams
 	_ = c.ShouldBindJSON(&sp)
+	PageVerifyErr := utils.Verify(sp.PageInfo, utils.CustomizeMap["PageVerify"])
+	if PageVerifyErr != nil {
+		response.FailWithMessage(PageVerifyErr.Error(), c)
+		return
+	}
 	err, list, total := service.GetAPIInfoList(sp.SysApi, sp.PageInfo, sp.OrderKey, sp.Desc)
 	if err != nil {
 		response.FailWithMessage(fmt.Sprintf("获取数据失败,%v", err), c)
@@ -86,6 +111,11 @@ func GetApiList(c *gin.Context) {
 func GetApiById(c *gin.Context) {
 	var idInfo request.GetById
 	_ = c.ShouldBindJSON(&idInfo)
+	IdVerifyErr := utils.Verify(idInfo, utils.CustomizeMap["IdVerify"])
+	if IdVerifyErr != nil {
+		response.FailWithMessage(IdVerifyErr.Error(), c)
+		return
+	}
 	err, api := service.GetApiById(idInfo.Id)
 	if err != nil {
 		response.FailWithMessage(fmt.Sprintf("获取数据失败,%v", err), c)
@@ -105,6 +135,17 @@ func GetApiById(c *gin.Context) {
 func UpdateApi(c *gin.Context) {
 	var api model.SysApi
 	_ = c.ShouldBindJSON(&api)
+	ApiVerify := utils.Rules{
+		"Path":        {utils.NotEmpty()},
+		"Description": {utils.NotEmpty()},
+		"ApiGroup":    {utils.NotEmpty()},
+		"Method":      {utils.NotEmpty()},
+	}
+	ApiVerifyErr := utils.Verify(api, ApiVerify)
+	if ApiVerifyErr != nil {
+		response.FailWithMessage(ApiVerifyErr.Error(), c)
+		return
+	}
 	err := service.UpdateApi(api)
 	if err != nil {
 		response.FailWithMessage(fmt.Sprintf("修改数据失败,%v", err), c)

+ 54 - 0
server/api/v1/sys_authority.go

@@ -7,6 +7,7 @@ import (
 	"gin-vue-admin/model/request"
 	resp "gin-vue-admin/model/response"
 	"gin-vue-admin/service"
+	"gin-vue-admin/utils"
 	"github.com/gin-gonic/gin"
 )
 
@@ -21,6 +22,16 @@ import (
 func CreateAuthority(c *gin.Context) {
 	var auth model.SysAuthority
 	_ = c.ShouldBindJSON(&auth)
+	AuthorityVerify := utils.Rules{
+		"AuthorityId":   {utils.NotEmpty()},
+		"AuthorityName": {utils.NotEmpty()},
+		"ParentId":      {utils.NotEmpty()},
+	}
+	AuthorityVerifyErr := utils.Verify(auth, AuthorityVerify)
+	if AuthorityVerifyErr != nil {
+		response.FailWithMessage(AuthorityVerifyErr.Error(), c)
+		return
+	}
 	err, authBack := service.CreateAuthority(auth)
 	if err != nil {
 		response.FailWithMessage(fmt.Sprintf("创建失败,%v", err), c)
@@ -40,6 +51,24 @@ func CreateAuthority(c *gin.Context) {
 func CopyAuthority(c *gin.Context) {
 	var copyInfo resp.SysAuthorityCopyResponse
 	_ = c.ShouldBindJSON(&copyInfo)
+	OldAuthorityVerify := utils.Rules{
+		"OldAuthorityId": {utils.NotEmpty()},
+	}
+	OldAuthorityVerifyErr := utils.Verify(copyInfo, OldAuthorityVerify)
+	if OldAuthorityVerifyErr != nil {
+		response.FailWithMessage(OldAuthorityVerifyErr.Error(), c)
+		return
+	}
+	AuthorityVerify := utils.Rules{
+		"AuthorityId":   {utils.NotEmpty()},
+		"AuthorityName": {utils.NotEmpty()},
+		"ParentId":      {utils.NotEmpty()},
+	}
+	AuthorityVerifyErr := utils.Verify(copyInfo.Authority, AuthorityVerify)
+	if AuthorityVerifyErr != nil {
+		response.FailWithMessage(AuthorityVerifyErr.Error(), c)
+		return
+	}
 	err, authBack := service.CopyAuthority(copyInfo)
 	if err != nil {
 		response.FailWithMessage(fmt.Sprintf("拷贝失败,%v", err), c)
@@ -59,6 +88,11 @@ func CopyAuthority(c *gin.Context) {
 func DeleteAuthority(c *gin.Context) {
 	var a model.SysAuthority
 	_ = c.ShouldBindJSON(&a)
+	AuthorityIdVerifyErr := utils.Verify(a, utils.CustomizeMap["AuthorityIdVerify"])
+	if AuthorityIdVerifyErr != nil {
+		response.FailWithMessage(AuthorityIdVerifyErr.Error(), c)
+		return
+	}
 	//删除角色之前需要判断是否有用户正在使用此角色
 	err := service.DeleteAuthority(&a)
 	if err != nil {
@@ -79,6 +113,16 @@ func DeleteAuthority(c *gin.Context) {
 func UpdateAuthority(c *gin.Context) {
 	var auth model.SysAuthority
 	_ = c.ShouldBindJSON(&auth)
+	AuthorityVerify := utils.Rules{
+		"AuthorityId":   {utils.NotEmpty()},
+		"AuthorityName": {utils.NotEmpty()},
+		"ParentId":      {utils.NotEmpty()},
+	}
+	AuthorityVerifyErr := utils.Verify(auth, AuthorityVerify)
+	if AuthorityVerifyErr != nil {
+		response.FailWithMessage(AuthorityVerifyErr.Error(), c)
+		return
+	}
 	err, authority := service.UpdateAuthority(auth)
 	if err != nil {
 		response.FailWithMessage(fmt.Sprintf("更新失败,%v", err), c)
@@ -98,6 +142,11 @@ func UpdateAuthority(c *gin.Context) {
 func GetAuthorityList(c *gin.Context) {
 	var pageInfo request.PageInfo
 	_ = c.ShouldBindJSON(&pageInfo)
+	PageVerifyErr := utils.Verify(pageInfo, utils.CustomizeMap["PageVerify"])
+	if PageVerifyErr != nil {
+		response.FailWithMessage(PageVerifyErr.Error(), c)
+		return
+	}
 	err, list, total := service.GetAuthorityInfoList(pageInfo)
 	if err != nil {
 		response.FailWithMessage(fmt.Sprintf("获取数据失败,%v", err), c)
@@ -122,6 +171,11 @@ func GetAuthorityList(c *gin.Context) {
 func SetDataAuthority(c *gin.Context) {
 	var auth model.SysAuthority
 	_ = c.ShouldBindJSON(&auth)
+	AuthorityIdVerifyErr := utils.Verify(auth, utils.CustomizeMap["AuthorityIdVerify"])
+	if AuthorityIdVerifyErr != nil {
+		response.FailWithMessage(AuthorityIdVerifyErr.Error(), c)
+		return
+	}
 	err := service.SetDataAuthority(auth)
 	if err != nil {
 		response.FailWithMessage(fmt.Sprintf("设置关联失败,%v", err), c)

+ 13 - 1
server/api/v1/sys_auto_code.go

@@ -5,6 +5,7 @@ import (
 	"gin-vue-admin/global/response"
 	"gin-vue-admin/model"
 	"gin-vue-admin/service"
+	"gin-vue-admin/utils"
 	"github.com/gin-gonic/gin"
 	"net/url"
 	"os"
@@ -21,6 +22,17 @@ import (
 func CreateTemp(c *gin.Context) {
 	var a model.AutoCodeStruct
 	_ = c.ShouldBindJSON(&a)
+	AutoCodeVerify := utils.Rules{
+		"Abbreviation":      {utils.NotEmpty()},
+		"StructName":      {utils.NotEmpty()},
+		"PackageName":      {utils.NotEmpty()},
+		"Fields":      {utils.NotEmpty()},
+	}
+	WKVerifyErr := utils.Verify(a, AutoCodeVerify)
+	if WKVerifyErr!=nil {
+		response.FailWithMessage(WKVerifyErr.Error(), c)
+		return
+	}
 	if a.AutoCreateApiToSql {
 		apiList := [5]model.SysApi{
 			{
@@ -39,7 +51,7 @@ func CreateTemp(c *gin.Context) {
 				Path:        "/" + a.Abbreviation + "/" + "update" + a.StructName,
 				Description: "更新" + a.StructName,
 				ApiGroup:    a.Abbreviation,
-				Method:      "POST",
+				Method:      "PUT",
 			},
 			{
 				Path:        "/" + a.Abbreviation + "/" + "find" + a.StructName,

+ 11 - 0
server/api/v1/sys_casbin.go

@@ -6,6 +6,7 @@ import (
 	"gin-vue-admin/model/request"
 	resp "gin-vue-admin/model/response"
 	"gin-vue-admin/service"
+	"gin-vue-admin/utils"
 	"github.com/gin-gonic/gin"
 )
 
@@ -20,6 +21,11 @@ import (
 func UpdateCasbin(c *gin.Context) {
 	var cmr request.CasbinInReceive
 	_ = c.ShouldBindJSON(&cmr)
+	AuthorityIdVerifyErr := utils.Verify(cmr, utils.CustomizeMap["AuthorityIdVerify"])
+	if AuthorityIdVerifyErr != nil {
+		response.FailWithMessage(AuthorityIdVerifyErr.Error(), c)
+		return
+	}
 	err := service.UpdateCasbin(cmr.AuthorityId, cmr.CasbinInfos)
 	if err != nil {
 		response.FailWithMessage(fmt.Sprintf("添加规则失败,%v", err), c)
@@ -39,6 +45,11 @@ func UpdateCasbin(c *gin.Context) {
 func GetPolicyPathByAuthorityId(c *gin.Context) {
 	var cmr request.CasbinInReceive
 	_ = c.ShouldBindJSON(&cmr)
+	AuthorityIdVerifyErr := utils.Verify(cmr, utils.CustomizeMap["AuthorityIdVerify"])
+	if AuthorityIdVerifyErr != nil {
+		response.FailWithMessage(AuthorityIdVerifyErr.Error(), c)
+		return
+	}
 	paths := service.GetPolicyPathByAuthorityId(cmr.AuthorityId)
 	response.OkWithData(resp.PolicyPathResponse{Paths: paths}, c)
 }

+ 75 - 1
server/api/v1/sys_menu.go

@@ -7,6 +7,7 @@ import (
 	"gin-vue-admin/model/request"
 	resp "gin-vue-admin/model/response"
 	"gin-vue-admin/service"
+	"gin-vue-admin/utils"
 	"github.com/gin-gonic/gin"
 )
 
@@ -39,6 +40,11 @@ func GetMenu(c *gin.Context) {
 func GetMenuList(c *gin.Context) {
 	var pageInfo request.PageInfo
 	_ = c.ShouldBindJSON(&pageInfo)
+	PageVerifyErr := utils.Verify(pageInfo, utils.CustomizeMap["PageVerify"])
+	if PageVerifyErr != nil {
+		response.FailWithMessage(PageVerifyErr.Error(), c)
+		return
+	}
 	err, menuList, total := service.GetInfoList()
 	if err != nil {
 		response.FailWithMessage(fmt.Sprintf("获取数据失败,%v", err), c)
@@ -63,6 +69,26 @@ func GetMenuList(c *gin.Context) {
 func AddBaseMenu(c *gin.Context) {
 	var menu model.SysBaseMenu
 	_ = c.ShouldBindJSON(&menu)
+	MenuVerify := utils.Rules{
+		"Path":      {"notEmpty"},
+		"ParentId":  {utils.NotEmpty()},
+		"Name":      {utils.NotEmpty()},
+		"Component": {utils.NotEmpty()},
+		"Sort":      {utils.Ge("0"), "ge=0"},
+	}
+	MenuVerifyErr := utils.Verify(menu, MenuVerify)
+	if MenuVerifyErr != nil {
+		response.FailWithMessage(MenuVerifyErr.Error(), c)
+		return
+	}
+	MetaVerify := utils.Rules{
+		"Title": {utils.NotEmpty()},
+	}
+	MetaVerifyErr := utils.Verify(menu.Meta, MetaVerify)
+	if MetaVerifyErr != nil {
+		response.FailWithMessage(MetaVerifyErr.Error(), c)
+		return
+	}
 	err := service.AddBaseMenu(menu)
 	if err != nil {
 		response.FailWithMessage(fmt.Sprintf("添加失败,%v", err), c)
@@ -98,7 +124,14 @@ func GetBaseMenuTree(c *gin.Context) {
 func AddMenuAuthority(c *gin.Context) {
 	var addMenuAuthorityInfo request.AddMenuAuthorityInfo
 	_ = c.ShouldBindJSON(&addMenuAuthorityInfo)
-
+	MenuVerify := utils.Rules{
+		"AuthorityId": {"notEmpty"},
+	}
+	MenuVerifyErr := utils.Verify(addMenuAuthorityInfo, MenuVerify)
+	if MenuVerifyErr != nil {
+		response.FailWithMessage(MenuVerifyErr.Error(), c)
+		return
+	}
 	err := service.AddMenuAuthority(addMenuAuthorityInfo.Menus, addMenuAuthorityInfo.AuthorityId)
 	if err != nil {
 		response.FailWithMessage(fmt.Sprintf("添加失败,%v", err), c)
@@ -118,6 +151,14 @@ func AddMenuAuthority(c *gin.Context) {
 func GetMenuAuthority(c *gin.Context) {
 	var authorityIdInfo request.AuthorityIdInfo
 	_ = c.ShouldBindJSON(&authorityIdInfo)
+	MenuVerify := utils.Rules{
+		"AuthorityId": {"notEmpty"},
+	}
+	MenuVerifyErr := utils.Verify(authorityIdInfo, MenuVerify)
+	if MenuVerifyErr != nil {
+		response.FailWithMessage(MenuVerifyErr.Error(), c)
+		return
+	}
 	err, menus := service.GetMenuAuthority(authorityIdInfo.AuthorityId)
 	if err != nil {
 		response.FailWithDetailed(response.ERROR, resp.SysMenusResponse{Menus: menus}, fmt.Sprintf("添加失败,%v", err), c)
@@ -137,6 +178,11 @@ func GetMenuAuthority(c *gin.Context) {
 func DeleteBaseMenu(c *gin.Context) {
 	var idInfo request.GetById
 	_ = c.ShouldBindJSON(&idInfo)
+	IdVerifyErr := utils.Verify(idInfo, utils.CustomizeMap["IdVerify"])
+	if IdVerifyErr != nil {
+		response.FailWithMessage(IdVerifyErr.Error(), c)
+		return
+	}
 	err := service.DeleteBaseMenu(idInfo.Id)
 	if err != nil {
 		response.FailWithMessage(fmt.Sprintf("删除失败:%v", err), c)
@@ -157,6 +203,26 @@ func DeleteBaseMenu(c *gin.Context) {
 func UpdateBaseMenu(c *gin.Context) {
 	var menu model.SysBaseMenu
 	_ = c.ShouldBindJSON(&menu)
+	MenuVerify := utils.Rules{
+		"Path":      {"notEmpty"},
+		"ParentId":  {utils.NotEmpty()},
+		"Name":      {utils.NotEmpty()},
+		"Component": {utils.NotEmpty()},
+		"Sort":      {utils.Ge("0"), "ge=0"},
+	}
+	MenuVerifyErr := utils.Verify(menu, MenuVerify)
+	if MenuVerifyErr != nil {
+		response.FailWithMessage(MenuVerifyErr.Error(), c)
+		return
+	}
+	MetaVerify := utils.Rules{
+		"Title": {utils.NotEmpty()},
+	}
+	MetaVerifyErr := utils.Verify(menu.Meta, MetaVerify)
+	if MetaVerifyErr != nil {
+		response.FailWithMessage(MetaVerifyErr.Error(), c)
+		return
+	}
 	err := service.UpdateBaseMenu(menu)
 	if err != nil {
 		response.FailWithMessage(fmt.Sprintf("修改失败:%v", err), c)
@@ -176,6 +242,14 @@ func UpdateBaseMenu(c *gin.Context) {
 func GetBaseMenuById(c *gin.Context) {
 	var idInfo request.GetById
 	_ = c.ShouldBindJSON(&idInfo)
+	MenuVerify := utils.Rules{
+		"Id": {"notEmpty"},
+	}
+	MenuVerifyErr := utils.Verify(idInfo, MenuVerify)
+	if MenuVerifyErr != nil {
+		response.FailWithMessage(MenuVerifyErr.Error(), c)
+		return
+	}
 	err, menu := service.GetBaseMenuById(idInfo.Id)
 	if err != nil {
 		response.FailWithMessage(fmt.Sprintf("查询失败:%v", err), c)

+ 52 - 1
server/api/v1/sys_user.go

@@ -27,6 +27,17 @@ import (
 func Register(c *gin.Context) {
 	var R request.RegisterStruct
 	_ = c.ShouldBindJSON(&R)
+	UserVerify := utils.Rules{
+		"Username":    {utils.NotEmpty()},
+		"NickName":    {utils.NotEmpty()},
+		"Password":    {utils.NotEmpty()},
+		"AuthorityId": {utils.NotEmpty()},
+	}
+	UserVerifyErr := utils.Verify(R, UserVerify)
+	if UserVerifyErr != nil {
+		response.FailWithMessage(UserVerifyErr.Error(), c)
+		return
+	}
 	user := &model.SysUser{Username: R.Username, NickName: R.NickName, Password: R.Password, HeaderImg: R.HeaderImg, AuthorityId: R.AuthorityId}
 	err, userReturn := service.Register(*user)
 	if err != nil {
@@ -45,6 +56,17 @@ func Register(c *gin.Context) {
 func Login(c *gin.Context) {
 	var L request.RegisterAndLoginStruct
 	_ = c.ShouldBindJSON(&L)
+	UserVerify := utils.Rules{
+		"CaptchaId": {utils.NotEmpty()},
+		"Captcha":   {utils.NotEmpty()},
+		"Username":  {utils.NotEmpty()},
+		"Password":  {utils.NotEmpty()},
+	}
+	UserVerifyErr := utils.Verify(L, UserVerify)
+	if UserVerifyErr != nil {
+		response.FailWithMessage(UserVerifyErr.Error(), c)
+		return
+	}
 	if captcha.VerifyString(L.CaptchaId, L.Captcha) {
 		U := &model.SysUser{Username: L.Username, Password: L.Password}
 		if err, user := service.Login(U); err != nil {
@@ -134,6 +156,16 @@ func tokenNext(c *gin.Context, user model.SysUser) {
 func ChangePassword(c *gin.Context) {
 	var params request.ChangePasswordStruct
 	_ = c.ShouldBindJSON(&params)
+	UserVerify := utils.Rules{
+		"Username":    {utils.NotEmpty()},
+		"Password":    {utils.NotEmpty()},
+		"NewPassword": {utils.NotEmpty()},
+	}
+	UserVerifyErr := utils.Verify(params, UserVerify)
+	if UserVerifyErr != nil {
+		response.FailWithMessage(UserVerifyErr.Error(), c)
+		return
+	}
 	U := &model.SysUser{Username: params.Username, Password: params.Password}
 	if err, _ := service.ChangePassword(U, params.NewPassword); err != nil {
 		response.FailWithMessage("修改失败,请检查用户名密码", c)
@@ -193,6 +225,11 @@ func UploadHeaderImg(c *gin.Context) {
 func GetUserList(c *gin.Context) {
 	var pageInfo request.PageInfo
 	_ = c.ShouldBindJSON(&pageInfo)
+	PageVerifyErr := utils.Verify(pageInfo, utils.CustomizeMap["PageVerify"])
+	if PageVerifyErr != nil {
+		response.FailWithMessage(PageVerifyErr.Error(), c)
+		return
+	}
 	err, list, total := service.GetUserInfoList(pageInfo)
 	if err != nil {
 		response.FailWithMessage(fmt.Sprintf("获取数据失败,%v", err), c)
@@ -217,6 +254,15 @@ func GetUserList(c *gin.Context) {
 func SetUserAuthority(c *gin.Context) {
 	var sua request.SetUserAuth
 	_ = c.ShouldBindJSON(&sua)
+	UserVerify := utils.Rules{
+		"UUID":        {utils.NotEmpty()},
+		"AuthorityId": {utils.NotEmpty()},
+	}
+	UserVerifyErr := utils.Verify(sua, UserVerify)
+	if UserVerifyErr != nil {
+		response.FailWithMessage(UserVerifyErr.Error(), c)
+		return
+	}
 	err := service.SetUserAuthority(sua.UUID, sua.AuthorityId)
 	if err != nil {
 		response.FailWithMessage(fmt.Sprintf("修改失败,%v", err), c)
@@ -230,12 +276,17 @@ func SetUserAuthority(c *gin.Context) {
 // @Security ApiKeyAuth
 // @accept application/json
 // @Produce application/json
-// @Param data body request.SetUserAuth true "删除用户"
+// @Param data body request.GetById true "删除用户"
 // @Success 200 {string} string "{"success":true,"data":{},"msg":"修改成功"}"
 // @Router /user/deleteUser [delete]
 func DeleteUser(c *gin.Context) {
 	var reqId request.GetById
 	_ = c.ShouldBindJSON(&reqId)
+	IdVerifyErr := utils.Verify(reqId, utils.CustomizeMap["IdVerify"])
+	if IdVerifyErr != nil {
+		response.FailWithMessage(IdVerifyErr.Error(), c)
+		return
+	}
 	err := service.DeleteUser(reqId.Id)
 	if err != nil {
 		response.FailWithMessage(fmt.Sprintf("删除失败,%v", err), c)

+ 12 - 0
server/api/v1/sys_work_flow.go

@@ -5,6 +5,7 @@ import (
 	"gin-vue-admin/global/response"
 	"gin-vue-admin/model"
 	"gin-vue-admin/service"
+	"gin-vue-admin/utils"
 	"github.com/gin-gonic/gin"
 )
 
@@ -17,6 +18,17 @@ import (
 func CreateWorkFlow(c *gin.Context) {
 	var wk model.SysWorkflow
 	_ = c.ShouldBindJSON(&wk)
+	WKVerify := utils.Rules{
+		"WorkflowNickName":      {utils.NotEmpty()},
+		"WorkflowName":  {utils.NotEmpty()},
+		"WorkflowDescription":      {utils.NotEmpty()},
+		"WorkflowStepInfo":      {utils.NotEmpty()},
+	}
+	WKVerifyErr := utils.Verify(wk, WKVerify)
+	if WKVerifyErr!=nil {
+		response.FailWithMessage(WKVerifyErr.Error(), c)
+		return
+	}
 	err := service.Create(wk)
 	if err != nil {
 		response.FailWithMessage(fmt.Sprintf("获取失败:%v", err), c)

+ 0 - 1
server/initialize/router.go

@@ -14,7 +14,6 @@ import (
 
 func Routers() *gin.Engine {
 	var Router = gin.Default()
-
 	//Router.Use(middleware.LoadTls())  // 打开就能玩https了
 	global.GVA_LOG.Debug("use middleware logger")
 	// 跨域

+ 22 - 0
server/initialize/validator.go

@@ -0,0 +1,22 @@
+package initialize
+
+import "gin-vue-admin/utils"
+
+func init() {
+	_ = utils.RegisterRule("PageVerify",
+		utils.Rules{
+			"Page":     {utils.NotEmpty()},
+			"PageSize": {utils.NotEmpty()},
+		},
+	)
+	_ = utils.RegisterRule("IdVerify",
+		utils.Rules{
+			"Id": {utils.NotEmpty()},
+		},
+	)
+	_ = utils.RegisterRule("AuthorityIdVerify",
+		utils.Rules{
+			"AuthorityId": {utils.NotEmpty()},
+		},
+	)
+}

+ 1 - 1
server/resource/template/te/api.go.tpl

@@ -66,7 +66,7 @@ func Update{{.StructName}}(c *gin.Context) {
 	if err != nil {
 		response.FailWithMessage(fmt.Sprintf("更新失败,%v", err), c)
 	} else {
-		response.OkWithMessage("删除成功", c)
+		response.OkWithMessage("更新成功", c)
 	}
 }
 

+ 0 - 38
server/utils/hasGap.go

@@ -1,38 +0,0 @@
-// 空值校验工具 仅用于检验空字符串 其余类型请勿使用
-
-package utils
-
-import (
-	"errors"
-	"fmt"
-	"reflect"
-)
-
-func HasGap(input interface{}) error {
-	getType := reflect.TypeOf(input)
-	getValue := reflect.ValueOf(input)
-	// 获取方法字段
-	for i := 0; i < getType.NumField(); i++ {
-		field := getType.Field(i)
-		value := getValue.Field(i).Interface()
-		switch value.(type) {
-		case string:
-			if value == "" {
-				fmt.Printf("%s为空", field.Name)
-				return errors.New(fmt.Sprintf("%s为空", field.Name))
-			}
-		default:
-			if value == nil {
-				fmt.Printf("%s为空", field.Name)
-				return errors.New(fmt.Sprintf("%s为空", field.Name))
-			}
-		}
-	}
-	// 获取方法
-	// 1. 先获取interface的reflect.Type,然后通过.NumMethod进行遍历
-	//for i := 0; i < getType.NumMethod(); i++ {
-	//	m := getType.Method(i)
-	//	fmt.Printf("%s: %v\n", m.Name, m.Type)
-	//}
-	return nil
-}

+ 207 - 0
server/utils/validator.go

@@ -0,0 +1,207 @@
+package utils
+
+import (
+	"errors"
+	"reflect"
+	"strconv"
+	"strings"
+)
+
+type Rules map[string][]string
+
+type RulesMap map[string]Rules
+
+var CustomizeMap = make(map[string]Rules)
+
+// 注册自定义规则方案建议在路由初始化层即注册
+func RegisterRule(key string, rule Rules) (err error) {
+	if CustomizeMap[key] != nil {
+		return errors.New(key + "已注册,无法重复注册")
+	} else {
+		CustomizeMap[key] = rule
+		return nil
+	}
+}
+
+// 非空 不能为其对应类型的0值
+func NotEmpty() string {
+	return "notEmpty"
+}
+
+//小于入参(<) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较
+func Lt(mark string) string {
+	return "lt=" + mark
+}
+
+//小于等于入参(<=) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较
+func Le(mark string) string {
+	return "le=" + mark
+}
+
+//等于入参(==) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较
+func Eq(mark string) string {
+	return "eq=" + mark
+}
+
+//不等于入参(!=)  如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较
+func Ne(mark string) string {
+	return "ne=" + mark
+}
+
+//大于等于入参(>=) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较
+func Ge(mark string) string {
+	return "ge=" + mark
+}
+
+//大于入参(>) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较
+func Gt(mark string) string {
+	return "gt=" + mark
+}
+
+// 校验方法 接收两个参数  入参实例,规则map
+func Verify(st interface{}, roleMap Rules) (err error) {
+	compareMap := map[string]bool{
+		"lt": true,
+		"le": true,
+		"eq": true,
+		"ne": true,
+		"ge": true,
+		"gt": true,
+	}
+
+	typ := reflect.TypeOf(st)
+	val := reflect.ValueOf(st) //获取reflect.Type类型
+
+	kd := val.Kind() //获取到st对应的类别
+	if kd != reflect.Struct {
+		return errors.New("expect struct")
+	}
+	num := val.NumField()
+	//遍历结构体的所有字段
+	for i := 0; i < num; i++ {
+		tagVal := typ.Field(i)
+		val := val.Field(i)
+		if len(roleMap[tagVal.Name]) > 0 {
+			for _, v := range roleMap[tagVal.Name] {
+				switch {
+				case v == "notEmpty":
+					if isBlank(val) {
+						return errors.New(tagVal.Name + "值不能为空")
+					}
+				case compareMap[strings.Split(v, "=")[0]]:
+					if !compareVerify(val, v) {
+						return errors.New(tagVal.Name + "长度或值不在合法范围," + v)
+					}
+				}
+			}
+		}
+	}
+	return nil
+}
+
+// 长度和数字的校验方法 根据类型自动校验
+func compareVerify(value reflect.Value, VerifyStr string) bool {
+	switch value.Kind() {
+	case reflect.String, reflect.Slice, reflect.Array:
+		return compare(value.Len(), VerifyStr)
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		return compare(value.Uint(), VerifyStr)
+	case reflect.Float32, reflect.Float64:
+		return compare(value.Float(), VerifyStr)
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return compare(value.Int(), VerifyStr)
+	default:
+		return false
+	}
+}
+
+// 非空校验
+func isBlank(value reflect.Value) bool {
+	switch value.Kind() {
+	case reflect.String:
+		return value.Len() == 0
+	case reflect.Bool:
+		return !value.Bool()
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return value.Int() == 0
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		return value.Uint() == 0
+	case reflect.Float32, reflect.Float64:
+		return value.Float() == 0
+	case reflect.Interface, reflect.Ptr:
+		return value.IsNil()
+	}
+	return reflect.DeepEqual(value.Interface(), reflect.Zero(value.Type()).Interface())
+}
+
+func compare(value interface{}, VerifyStr string) bool {
+	VerifyStrArr := strings.Split(VerifyStr, "=")
+	val := reflect.ValueOf(value)
+	switch val.Kind() {
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		VInt, VErr := strconv.ParseInt(VerifyStrArr[1], 10, 64)
+		if VErr != nil {
+			return false
+		}
+		switch {
+		case VerifyStrArr[0] == "lt":
+			return val.Int() < VInt
+		case VerifyStrArr[0] == "le":
+			return val.Int() <= VInt
+		case VerifyStrArr[0] == "eq":
+			return val.Int() == VInt
+		case VerifyStrArr[0] == "ne":
+			return val.Int() != VInt
+		case VerifyStrArr[0] == "ge":
+			return val.Int() >= VInt
+		case VerifyStrArr[0] == "gt":
+			return val.Int() > VInt
+		default:
+			return false
+		}
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		VInt, VErr := strconv.Atoi(VerifyStrArr[1])
+		if VErr != nil {
+			return false
+		}
+		switch {
+		case VerifyStrArr[0] == "lt":
+			return val.Uint() < uint64(VInt)
+		case VerifyStrArr[0] == "le":
+			return val.Uint() <= uint64(VInt)
+		case VerifyStrArr[0] == "eq":
+			return val.Uint() == uint64(VInt)
+		case VerifyStrArr[0] == "ne":
+			return val.Uint() != uint64(VInt)
+		case VerifyStrArr[0] == "ge":
+			return val.Uint() >= uint64(VInt)
+		case VerifyStrArr[0] == "gt":
+			return val.Uint() > uint64(VInt)
+		default:
+			return false
+		}
+	case reflect.Float32, reflect.Float64:
+		VFloat, VErr := strconv.ParseFloat(VerifyStrArr[1], 64)
+		if VErr != nil {
+			return false
+		}
+		switch {
+		case VerifyStrArr[0] == "lt":
+			return val.Float() < VFloat
+		case VerifyStrArr[0] == "le":
+			return val.Float() <= VFloat
+		case VerifyStrArr[0] == "eq":
+			return val.Float() == VFloat
+		case VerifyStrArr[0] == "ne":
+			return val.Float() != VFloat
+		case VerifyStrArr[0] == "ge":
+			return val.Float() >= VFloat
+		case VerifyStrArr[0] == "gt":
+			return val.Float() > VFloat
+		default:
+			return false
+		}
+	default:
+		return false
+	}
+}

+ 1 - 1
web/src/view/example/customer/customer.vue

@@ -48,7 +48,7 @@
       layout="total, sizes, prev, pager, next, jumper"
     ></el-pagination>
 
-    <el-dialog :before-close="closeDialog" :visible.sync="dialogFormVisible" title="新增Api">
+    <el-dialog :before-close="closeDialog" :visible.sync="dialogFormVisible" title="客户">
       <el-form :inline="true" :model="form" label-width="80px">
         <el-form-item label="客户名">
           <el-input autocomplete="off" v-model="form.customerName"></el-input>

+ 1 - 1
web/src/view/login/login.vue

@@ -230,7 +230,7 @@ export default {
 
     .top {
       text-align: center;
-      margin-top: 20px;
+      margin-top: -40px;
       .header {
         height: 44px;
         line-height: 44px;

+ 1 - 1
web/src/view/login/register.vue

@@ -217,7 +217,7 @@ export default {
 
     .top {
       text-align: center;
-      margin-top: -50px;
+      margin-top: -40px;
       .header {
         height: 44px;
         line-height: 44px;

+ 344 - 0
web/src/view/superAdmin/menu/icon.vue

@@ -0,0 +1,344 @@
+<template>
+  <div>
+    <el-form
+      :inline="true"
+      :model="form"
+      :rules="rules"
+      label-width="85px"
+      ref="menuForm"
+      label-position="top"
+    >
+      <el-form-item prop="icon" style="width:100%">
+        <i
+          class="icon"
+          :class="'el-icon-'+ meta.icon"
+          style="position: absolute; z-index: 9999; padding: 5px 10px; "
+        ></i>
+        <el-select clearable filterable class="gva-select" v-model="meta.icon" placeholder="请选择" @change="propIcon(value)">
+          <el-option v-for="item in options" :key="item.key" :label="item.key" :value="item.key">
+            <span class="icon" :class="item.label"></span>
+            <span style="float: left">{{ item.key }}</span>
+          </el-option>
+        </el-select>
+      </el-form-item>
+    </el-form>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "icon",
+  data() {
+    return {
+      input: "",
+      options: [
+        { key: "platform-eleme", label: "el-icon-platform-eleme" },
+        { key: "eleme", label: "el-icon-eleme" },
+        { key: "delete-solid", label: "el-icon-delete-solid" },
+        { key: "delete", label: "el-icon-delete" },
+        { key: "s-tools", label: "el-icon-s-tools" },
+        { key: "setting", label: "el-icon-setting" },
+        { key: "user-solid", label: "el-icon-user-solid" },
+        { key: "user", label: "el-icon-user" },
+        { key: "phone", label: "el-icon-phone" },
+        { key: "phone-outline", label: "el-icon-phone-outline" },
+        { key: "more", label: "el-icon-more" },
+        { key: "more-outline", label: "el-icon-more-outline" },
+        { key: "star-on", label: "el-icon-star-on" },
+        { key: "star-off", label: "el-icon-star-off" },
+        { key: "s-goods", label: "el-icon-s-goods" },
+        { key: "goods", label: "el-icon-goods" },
+        { key: "warning", label: "el-icon-warning" },
+        { key: "warning-outline", label: "el-icon-warning-outline" },
+        { key: "question", label: "el-icon-question" },
+        { key: "info", label: "el-icon-info" },
+        { key: "remove", label: "el-icon-remove" },
+        { key: "circle-plus", label: "el-icon-circle-plus" },
+        { key: "success", label: "el-icon-success" },
+        { key: "error", label: "el-icon-error" },
+        { key: "zoom-in", label: "el-icon-zoom-in" },
+        { key: "zoom-out", label: "el-icon-zoom-out" },
+        { key: "remove-outline", label: "el-icon-remove-outline" },
+        { key: "circle-plus-outline", label: "el-icon-circle-plus-outline" },
+        { key: "circle-check", label: "el-icon-circle-check" },
+        { key: "circle-close", label: "el-icon-circle-close" },
+        { key: "s-help", label: "el-icon-s-help" },
+        { key: "help", label: "el-icon-help" },
+        { key: "minus", label: "el-icon-minus" },
+        { key: "plus", label: "el-icon-plus" },
+        { key: "check", label: "el-icon-check" },
+        { key: "close", label: "el-icon-close" },
+        { key: "picture", label: "el-icon-picture" },
+        { key: "picture-outline", label: "el-icon-picture-outline" },
+        {
+          key: "picture-outline-round",
+          label: "el-icon-picture-outline-round"
+        },
+        { key: "upload", label: "el-icon-upload" },
+        { key: "upload2", label: "el-icon-upload2" },
+        { key: "download", label: "el-icon-download" },
+        { key: "camera-solid", label: "el-icon-camera-solid" },
+        { key: "camera", label: "el-icon-camera" },
+        { key: "video-camera-solid", label: "el-icon-video-camera-solid" },
+        { key: "video-camera", label: "el-icon-video-camera" },
+        { key: "message-solid", label: "el-icon-message-solid" },
+        { key: "bell", label: "el-icon-bell" },
+        { key: "s-cooperation", label: "el-icon-s-cooperation" },
+        { key: "s-order", label: "el-icon-s-order" },
+        { key: "s-platform", label: "el-icon-s-platform" },
+        { key: "s-fold", label: "el-icon-s-fold" },
+        { key: "s-unfold", label: "el-icon-s-unfold" },
+        { key: "s-operation", label: "el-icon-s-operation" },
+        { key: "s-promotion", label: "el-icon-s-promotion" },
+        { key: "s-home", label: "el-icon-s-home" },
+        { key: "s-release", label: "el-icon-s-release" },
+        { key: "s-ticket", label: "el-icon-s-ticket" },
+        { key: "s-management", label: "el-icon-s-management" },
+        { key: "s-open", label: "el-icon-s-open" },
+        { key: "s-shop", label: "el-icon-s-shop" },
+        { key: "s-marketing", label: "el-icon-s-marketing" },
+        { key: "s-flag", label: "el-icon-s-flag" },
+        { key: "s-comment", label: "el-icon-s-comment" },
+        { key: "s-finance", label: "el-icon-s-finance" },
+        { key: "s-claim", label: "el-icon-s-claim" },
+        { key: "s-custom", label: "el-icon-s-custom" },
+        { key: "s-opportunity", label: "el-icon-s-opportunity" },
+        { key: "s-data", label: "el-icon-s-data" },
+        { key: "s-check", label: "el-icon-s-check" },
+        { key: "s-grid", label: "el-icon-s-grid" },
+        { key: "menu", label: "el-icon-menu" },
+        { key: "share", label: "el-icon-share" },
+        { key: "d-caret", label: "el-icon-d-caret" },
+        { key: "caret-left", label: "el-icon-caret-left" },
+        { key: "caret-right", label: "el-icon-caret-right" },
+        { key: "caret-bottom", label: "el-icon-caret-bottom" },
+        { key: "caret-top", label: "el-icon-caret-top" },
+        { key: "bottom-left", label: "el-icon-bottom-left" },
+        { key: "bottom-right", label: "el-icon-bottom-right" },
+        { key: "back", label: "el-icon-back" },
+        { key: "right", label: "el-icon-right" },
+        { key: "bottom", label: "el-icon-bottom" },
+        { key: "top", label: "el-icon-top" },
+        { key: "top-left", label: "el-icon-top-left" },
+        { key: "top-right", label: "el-icon-top-right" },
+        { key: "arrow-left", label: "el-icon-arrow-left" },
+        { key: "arrow-right", label: "el-icon-arrow-right" },
+        { key: "arrow-down", label: "el-icon-arrow-down" },
+        { key: "arrow-up", label: "el-icon-arrow-up" },
+        { key: "d-arrow-left", label: "el-icon-d-arrow-left" },
+        { key: "d-arrow-right", label: "el-icon-d-arrow-right" },
+        { key: "video-pause", label: "el-icon-video-pause" },
+        { key: "video-play", label: "el-icon-video-play" },
+        { key: "refresh", label: "el-icon-refresh" },
+        { key: "refresh-right", label: "el-icon-refresh-right" },
+        { key: "refresh-left", label: "el-icon-refresh-left" },
+        { key: "finished", label: "el-icon-finished" },
+        { key: "sort", label: "el-icon-sort" },
+        { key: "sort-up", label: "el-icon-sort-up" },
+        { key: "sort-down", label: "el-icon-sort-down" },
+        { key: "rank", label: "el-icon-rank" },
+        { key: "loading", label: "el-icon-loading" },
+        { key: "view", label: "el-icon-view" },
+        { key: "c-scale-to-original", label: "el-icon-c-scale-to-original" },
+        { key: "date", label: "el-icon-date" },
+        { key: "edit", label: "el-icon-edit" },
+        { key: "edit-outline", label: "el-icon-edit-outline" },
+        { key: "folder", label: "el-icon-folder" },
+        { key: "folder-opened", label: "el-icon-folder-opened" },
+        { key: "folder-add", label: "el-icon-folder-add" },
+        { key: "folder-remove", label: "el-icon-folder-remove" },
+        { key: "folder-delete", label: "el-icon-folder-delete" },
+        { key: "folder-checked", label: "el-icon-folder-checked" },
+        { key: "tickets", label: "el-icon-tickets" },
+        { key: "document-remove", label: "el-icon-document-remove" },
+        { key: "document-delete", label: "el-icon-document-delete" },
+        { key: "document-copy", label: "el-icon-document-copy" },
+        { key: "document-checked", label: "el-icon-document-checked" },
+        { key: "document", label: "el-icon-document" },
+        { key: "document-add", label: "el-icon-document-add" },
+        { key: "printer", label: "el-icon-printer" },
+        { key: "paperclip", label: "el-icon-paperclip" },
+        { key: "takeaway-box", label: "el-icon-takeaway-box" },
+        { key: "search", label: "el-icon-search" },
+        { key: "monitor", label: "el-icon-monitor" },
+        { key: "attract", label: "el-icon-attract" },
+        { key: "mobile", label: "el-icon-mobile" },
+        { key: "scissors", label: "el-icon-scissors" },
+        { key: "umbrella", label: "el-icon-umbrella" },
+        { key: "headset", label: "el-icon-headset" },
+        { key: "brush", label: "el-icon-brush" },
+        { key: "mouse", label: "el-icon-mouse" },
+        { key: "coordinate", label: "el-icon-coordinate" },
+        { key: "magic-stick", label: "el-icon-magic-stick" },
+        { key: "reading", label: "el-icon-reading" },
+        { key: "data-line", label: "el-icon-data-line" },
+        { key: "data-board", label: "el-icon-data-board" },
+        { key: "pie-chart", label: "el-icon-pie-chart" },
+        { key: "data-analysis", label: "el-icon-data-analysis" },
+        { key: "collection-tag", label: "el-icon-collection-tag" },
+        { key: "film", label: "el-icon-film" },
+        { key: "suitcase", label: "el-icon-suitcase" },
+        { key: "suitcase-1", label: "el-icon-suitcase-1" },
+        { key: "receiving", label: "el-icon-receiving" },
+        { key: "collection", label: "el-icon-collection" },
+        { key: "files", label: "el-icon-files" },
+        { key: "notebook-1", label: "el-icon-notebook-1" },
+        { key: "notebook-2", label: "el-icon-notebook-2" },
+        { key: "toilet-paper", label: "el-icon-toilet-paper" },
+        { key: "office-building", label: "el-icon-office-building" },
+        { key: "school", label: "el-icon-school" },
+        { key: "table-lamp", label: "el-icon-table-lamp" },
+        { key: "house", label: "el-icon-house" },
+        { key: "no-smoking", label: "el-icon-no-smoking" },
+        { key: "smoking", label: "el-icon-smoking" },
+        { key: "shopping-cart-full", label: "el-icon-shopping-cart-full" },
+        { key: "shopping-cart-1", label: "el-icon-shopping-cart-1" },
+        { key: "shopping-cart-2", label: "el-icon-shopping-cart-2" },
+        { key: "shopping-bag-1", label: "el-icon-shopping-bag-1" },
+        { key: "shopping-bag-2", label: "el-icon-shopping-bag-2" },
+        { key: "sold-out", label: "el-icon-sold-out" },
+        { key: "sell", label: "el-icon-sell" },
+        { key: "present", label: "el-icon-present" },
+        { key: "box", label: "el-icon-box" },
+        { key: "bank-card", label: "el-icon-bank-card" },
+        { key: "money", label: "el-icon-money" },
+        { key: "coin", label: "el-icon-coin" },
+        { key: "wallet", label: "el-icon-wallet" },
+        { key: "discount", label: "el-icon-discount" },
+        { key: "price-tag", label: "el-icon-price-tag" },
+        { key: "news", label: "el-icon-news" },
+        { key: "guide", label: "el-icon-guide" },
+        { key: "male", label: "el-icon-male" },
+        { key: "female", label: "el-icon-female" },
+        { key: "thumb", label: "el-icon-thumb" },
+        { key: "cpu", label: "el-icon-cpu" },
+        { key: "link", label: "el-icon-link" },
+        { key: "connection", label: "el-icon-connection" },
+        { key: "open", label: "el-icon-open" },
+        { key: "turn-off", label: "el-icon-turn-off" },
+        { key: "set-up", label: "el-icon-set-up" },
+        { key: "chat-round", label: "el-icon-chat-round" },
+        { key: "chat-line-round", label: "el-icon-chat-line-round" },
+        { key: "chat-square", label: "el-icon-chat-square" },
+        { key: "chat-dot-round", label: "el-icon-chat-dot-round" },
+        { key: "chat-dot-square", label: "el-icon-chat-dot-square" },
+        { key: "chat-line-square", label: "el-icon-chat-line-square" },
+        { key: "message", label: "el-icon-message" },
+        { key: "postcard", label: "el-icon-postcard" },
+        { key: "position", label: "el-icon-position" },
+        { key: "turn-off-microphone", label: "el-icon-turn-off-microphone" },
+        { key: "microphone", label: "el-icon-microphone" },
+        { key: "close-notification", label: "el-icon-close-notification" },
+        { key: "bangzhu", label: "el-icon-bangzhu" },
+        { key: "time", label: "el-icon-time" },
+        { key: "odometer", label: "el-icon-odometer" },
+        { key: "crop", label: "el-icon-crop" },
+        { key: "aim", label: "el-icon-aim" },
+        { key: "switch-button", label: "el-icon-switch-button" },
+        { key: "full-screen", label: "el-icon-full-screen" },
+        { key: "copy-document", label: "el-icon-copy-document" },
+        { key: "mic", label: "el-icon-mic" },
+        { key: "stopwatch", label: "el-icon-stopwatch" },
+        { key: "medal-1", label: "el-icon-medal-1" },
+        { key: "medal", label: "el-icon-medal" },
+        { key: "trophy", label: "el-icon-trophy" },
+        { key: "trophy-1", label: "el-icon-trophy-1" },
+        { key: "first-aid-kit", label: "el-icon-first-aid-kit" },
+        { key: "discover", label: "el-icon-discover" },
+        { key: "place", label: "el-icon-place" },
+        { key: "location", label: "el-icon-location" },
+        { key: "location-outline", label: "el-icon-location-outline" },
+        { key: "location-information", label: "el-icon-location-information" },
+        { key: "add-location", label: "el-icon-add-location" },
+        { key: "delete-location", label: "el-icon-delete-location" },
+        { key: "map-location", label: "el-icon-map-location" },
+        { key: "alarm-clock", label: "el-icon-alarm-clock" },
+        { key: "timer", label: "el-icon-timer" },
+        { key: "watch-1", label: "el-icon-watch-1" },
+        { key: "watch", label: "el-icon-watch" },
+        { key: "lock", label: "el-icon-lock" },
+        { key: "unlock", label: "el-icon-unlock" },
+        { key: "key", label: "el-icon-key" },
+        { key: "service", label: "el-icon-service" },
+        { key: "mobile-phone", label: "el-icon-mobile-phone" },
+        { key: "bicycle", label: "el-icon-bicycle" },
+        { key: "truck", label: "el-icon-truck" },
+        { key: "ship", label: "el-icon-ship" },
+        { key: "basketball", label: "el-icon-basketball" },
+        { key: "football", label: "el-icon-football" },
+        { key: "soccer", label: "el-icon-soccer" },
+        { key: "baseball", label: "el-icon-baseball" },
+        { key: "wind-power", label: "el-icon-wind-power" },
+        { key: "light-rain", label: "el-icon-light-rain" },
+        { key: "lightning", label: "el-icon-lightning" },
+        { key: "heavy-rain", label: "el-icon-heavy-rain" },
+        { key: "sunrise", label: "el-icon-sunrise" },
+        { key: "sunrise-1", label: "el-icon-sunrise-1" },
+        { key: "sunset", label: "el-icon-sunset" },
+        { key: "sunny", label: "el-icon-sunny" },
+        { key: "cloudy", label: "el-icon-cloudy" },
+        { key: "partly-cloudy", label: "el-icon-partly-cloudy" },
+        { key: "cloudy-and-sunny", label: "el-icon-cloudy-and-sunny" },
+        { key: "moon", label: "el-icon-moon" },
+        { key: "moon-night", label: "el-icon-moon-night" },
+        { key: "dish", label: "el-icon-dish" },
+        { key: "dish-1", label: "el-icon-dish-1" },
+        { key: "food", label: "el-icon-food" },
+        { key: "chicken", label: "el-icon-chicken" },
+        { key: "fork-spoon", label: "el-icon-fork-spoon" },
+        { key: "knife-fork", label: "el-icon-knife-fork" },
+        { key: "burger", label: "el-icon-burger" },
+        { key: "tableware", label: "el-icon-tableware" },
+        { key: "sugar", label: "el-icon-sugar" },
+        { key: "dessert", label: "el-icon-dessert" },
+        { key: "ice-cream", label: "el-icon-ice-cream" },
+        { key: "hot-water", label: "el-icon-hot-water" },
+        { key: "water-cup", label: "el-icon-water-cup" },
+        { key: "coffee-cup", label: "el-icon-coffee-cup" },
+        { key: "cold-drink", label: "el-icon-cold-drink" },
+        { key: "goblet", label: "el-icon-goblet" },
+        { key: "goblet-full", label: "el-icon-goblet-full" },
+        { key: "goblet-square", label: "el-icon-goblet-square" },
+        { key: "goblet-square-full", label: "el-icon-goblet-square-full" },
+        { key: "refrigerator", label: "el-icon-refrigerator" },
+        { key: "grape", label: "el-icon-grape" },
+        { key: "watermelon", label: "el-icon-watermelon" },
+        { key: "cherry", label: "el-icon-cherry" },
+        { key: "apple", label: "el-icon-apple" },
+        { key: "pear", label: "el-icon-pear" },
+        { key: "orange", label: "el-icon-orange" },
+        { key: "coffee", label: "el-icon-coffee" },
+        { key: "ice-tea", label: "el-icon-ice-tea" },
+        { key: "ice-drink", label: "el-icon-ice-drink" },
+        { key: "potato-strips", label: "el-icon-potato-strips" },
+        { key: "lollipop", label: "el-icon-lollipop" },
+        { key: "ice-cream-square", label: "el-icon-ice-cream-square" },
+        { key: "ice-cream-round", label: "el-icon-ice-cream-round" }
+      ],
+      value: ""
+    };
+  },
+  props: {
+    meta: {
+      default: function() {
+        return {};
+      },
+      type: Object
+    }
+  },
+  methods: {}
+};
+</script>
+
+<style lang="scss">
+.icon {
+  float: left;
+  color: rgb(132, 146, 166);
+  font-size: 13px;
+  line-height: 34px;
+  margin-right: 10px;
+}
+.gva-select .el-input__inner {
+    padding:0 30px !important
+}
+</style>

+ 11 - 5
web/src/view/superAdmin/menu/menu.vue

@@ -23,6 +23,7 @@
       </el-table-column>
       <el-table-column label="图标" min-width="140" prop="authorityName">
         <template slot-scope="scope">
+          <i :class="`el-icon-${scope.row.meta.icon}`"></i>
           <span>{{scope.row.meta.icon}}</span>
         </template>
       </el-table-column>
@@ -70,9 +71,9 @@
           <el-input autocomplete="off" v-model="form.meta.title"></el-input>
         </el-form-item>
         <el-form-item label="图标" prop="meta.icon" style="width:30%">
-          <el-input autocomplete="off" v-model="form.meta.icon">
-            <template slot="prepend">el-icon-</template>
-          </el-input>
+          <icon :meta="form.meta">
+            <template slot="prepend" >el-icon-</template>
+          </icon>
         </el-form-item>
         <el-form-item label="排序标记" prop="sort" style="width:30%">
           <el-input autocomplete="off" v-model.number="form.sort"></el-input>
@@ -104,6 +105,7 @@ import {
   getBaseMenuById
 } from "@/api/menu";
 import infoList from "@/components/mixins/infoList";
+import icon from '@/view/superAdmin/menu/icon';
 export default {
   name: "Menus",
   mixins: [infoList],
@@ -141,9 +143,13 @@ export default {
           { required: true, message: "请输入菜单展示名称", trigger: "blur" }
         ]
       },
-      isEdit: false
+      isEdit: false,
+      test:''
     };
   },
+  components:{
+    icon
+  },
   methods: {
     setOptions() {
       this.menuOption = [
@@ -305,4 +311,4 @@ export default {
 .warning {
   color: #dc143c;
 }
-</style>
+</style>

+ 8 - 2
web/src/view/systemTools/formCreate/index.vue

@@ -1,12 +1,18 @@
 <template>
   <div style="height:80vh">
-    <iframe width="100%" height="100%" src="http://127.0.0.1:8888/form-generator/#/" frameborder="0"></iframe>
+    <iframe width="100%" height="100%" :src="basePath+'/form-generator/#/'" frameborder="0"></iframe>
   </div>
 </template>
 
 <script>
+var path = process.env.VUE_APP_BASE_API
 export default {
-    name:"FormGenerator"
+    name:"FormGenerator",
+    data(){
+      return{
+        basePath:path
+      }
+    },
 };
 </script>