Git Product home page Git Product logo

gfast's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gfast's Issues

cache set error

能不能把使用 说的详细一点,我登录报错这个,没找到问题在哪,能写一个使用手册更好了

代码生成 报 404

http://demo.g-fast.cn/tool/gen/batchGenCode?tables=user 404

看前端有

/** 生成代码操作 */
    handleGenTable(row) {
      const tableNames = row.tableName || this.tableNames;
      if (tableNames == "") {
        this.msgError("请选择要生成的数据");
        return;
      }
      downLoadZip("/tool/gen/batchGenCode?tables=" + tableNames, "ruoyi");
    },

后端代码并没有看到对应的接口

//代码生成
		group.Group("/tools", func(group *ghttp.RouterGroup) {
			group.ALL("/gen", new(admin.Gen))
		})

感谢开源

导入数据库提示数据库数据库语句部分插入失败

数据库类型:utf8mb4 字符排序 utf8mb4_general_ci 插入编码:65001 UTF-8
插入提示:
SQL] Query gfast-v3 start
[ERR] 1292 - Incorrect datetime value: '0000-00-00 00:00:00' for column 'last_login_time' at row 1
[ERR]
INSERT INTO sys_login_log VALUES (643, 'zsa', '127.0.0.1', '内网IP', 'ApiPOST', '', 0, '账号密码错误', '2022-03-16 17:18:41', '系统后台');
INSERT INTO sys_login_log VALUES (644, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 0, '账号密码错误', '2022-03-16 17:18:48', '系统后台');
INSERT INTO sys_login_log VALUES (645, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 0, '账号密码错误', '2022-03-16 17:19:45', '系统后台');
INSERT INTO sys_login_log VALUES (646, 'demo55', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-16 17:21:06', '系统后台');
INSERT INTO sys_login_log VALUES (647, 'demo4564646', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-16 17:21:21', '系统后台');
INSERT INTO sys_login_log VALUES (648, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 17:21:56', '系统后台');
INSERT INTO sys_login_log VALUES (649, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 17:22:52', '系统后台');
INSERT INTO sys_login_log VALUES (650, 'demo2', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-16 17:24:11', '系统后台');
INSERT INTO sys_login_log VALUES (651, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 17:24:37', '系统后台');
INSERT INTO sys_login_log VALUES (652, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 17:25:12', '系统后台');
INSERT INTO sys_login_log VALUES (653, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 17:25:22', '系统后台');
INSERT INTO sys_login_log VALUES (654, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 17:25:27', '系统后台');
INSERT INTO sys_login_log VALUES (655, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 0, '账号密码错误', '2022-03-16 17:25:56', '系统后台');
INSERT INTO sys_login_log VALUES (656, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-16 17:26:03', '系统后台');
INSERT INTO sys_login_log VALUES (657, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 17:26:08', '系统后台');
INSERT INTO sys_login_log VALUES (658, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 17:27:17', '系统后台');
INSERT INTO sys_login_log VALUES (659, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 17:27:52', '系统后台');
INSERT INTO sys_login_log VALUES (660, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 17:28:07', '系统后台');
INSERT INTO sys_login_log VALUES (661, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 17:28:10', '系统后台');
INSERT INTO sys_login_log VALUES (662, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 17:28:31', '系统后台');
INSERT INTO sys_login_log VALUES (663, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 17:29:00', '系统后台');
INSERT INTO sys_login_log VALUES (664, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 17:30:28', '系统后台');
INSERT INTO sys_login_log VALUES (665, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-16 17:30:46', '系统后台');
INSERT INTO sys_login_log VALUES (666, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-16 17:31:12', '系统后台');
INSERT INTO sys_login_log VALUES (667, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-16 17:31:13', '系统后台');
INSERT INTO sys_login_log VALUES (668, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-16 17:32:00', '系统后台');
INSERT INTO sys_login_log VALUES (669, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-16 17:37:39', '系统后台');
INSERT INTO sys_login_log VALUES (670, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-16 17:42:16', '系统后台');
INSERT INTO sys_login_log VALUES (671, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-16 17:44:00', '系统后台');
INSERT INTO sys_login_log VALUES (672, 'zsss', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-16 17:45:23', '系统后台');
INSERT INTO sys_login_log VALUES (673, 'zsss', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-16 17:45:2
[SQL] Finished with error

api路由的疑问

在os-v3里登出的路由是 api/v1/system/loginOut ,为什么使用loginOut 这个词语,是有意写成这样的吗?

app\commom\service\casbin.go的中加载策略重复

原函数:

func (a *adapterCasbin) initPolicy(ctx context.Context) {
	// Because the DB is empty at first,
	// so we need to load the policy from the file adapter (.CSV) first.
	e, err := casbin.NewSyncedEnforcer(g.Cfg().MustGet(ctx, "casbin.modelFile").String(), a)

	if err != nil {
		a.EnforcerErr = err
		return
	}

	// This is a trick to save the current policy to the DB.
	// We can't call e.SavePolicy() because the adapter in the enforcer is still the file adapter.
	// The current policy means the policy in the Casbin enforcer (aka in memory).
	//err = a.SavePolicy(e.GetModel())
	//if err != nil {
	//	return err
	//}
	//set adapter
	//e.SetAdapter(a)
	// Clear the current policy.
	e.ClearPolicy()
	a.Enforcer = e
	// Load the policy from DB.
	err = a.LoadPolicy(e.GetModel())
	if err != nil {
		a.EnforcerErr = err
		return
	}
}

这行代码:e, err := casbin.NewSyncedEnforcer(g.Cfg().MustGet(ctx, "casbin.modelFile").String(), a) (源码调用见casbin\casbin\[email protected]\enforcer.go第178行)

它内部会 *adapterCasbin 的 LoadPolicy方法。
而下面的代码又手动再调用了一次:err = a.LoadPolicy(e.GetModel())
这样它就在数据库里查了两次

开发命名规范

1、目录命名冗余 例如:
比如,service目录下,一些目录命名还带service

2、变量命名驼峰和下划线混用,建议变量命名用驼峰法

请问下下载文件怎么做

我用get请求,到服务端后需要下载文件,使用以下代码,浏览器并不会弹出下载,请问应该怎么做,谢谢

        file := "git-" + todayDate + ".xlsx"

	// 读取文件
	downFile := gfile.GetBytes(file)

	req.Response.Header().Set("Content-Type", "application/octet-stream")
	req.Response.Header().Set("Content-Disposition", "attachment; filename="+file)
	req.Response.Write(downFile)
        req.Exit()

iShot2021-12-23 17 10 05

iShot2021-12-23 17 11 00

ForceLogout

如果是用个gcache, ForceLogout 函数没有删除缓存

gtoken同时使用的问题

我同时在一个电脑上跑两个gfast项目,配置不同的gtoken的信息,但是两个项目不能同时登录,不然会相互影响,提示用户信息验证失败,我用的gotken模式1,没用redis,难道是哪里还需要配置嘛?

Add a security policy

Hello 👋

I run a security community that finds and fixes vulnerabilities in OSS. A researcher (@cokeBeer) has found a potential issue, which I would be eager to share with you.

Could you add a SECURITY.md file with an e-mail address for me to send further details to? GitHub recommends a security policy to ensure issues are responsibly disclosed, and it would help direct researchers in the future.

Looking forward to hearing from you 👍

(cc @huntr-helper)

使用生成器生成的路由设置中间件token无效

使用生成器生成的路由即使设置了中间件后台权限验证依然可以无需登录直接获得内容

//扩展业务
	group.Group("/module", func(group *ghttp.RouterGroup) {
		group.Middleware(middleWare.Auth) //后台权限验证
		//后台操作日志记录
		group.Hook("/*", ghttp.HOOK_AFTER_OUTPUT, hook.OperationLog)

		group.ALL("/accounts", new(module.Fb_accounts))
	})

经测试直接通过

GET http://localhost:8200/module/accounts/list
Accept: application/json

可以获得内容,而不会提示“用户信息验证失败”。

旧 gf 基础库引起的 绑定0.0.0.0:8080 错误

2.0.6存在无法将http修改为0.0.0.0:8080 的问题 会导致 too many colons in address 比较影响使用
建议开发者将库版本升级到 2.1.0 及以上
更换到 2.1.0 之后需要吧 _ "github.com/gogf/gf/contrib/drivers/mysql/v2" 加入到main

v3版本go 1.18下安装报错

☁ gfast [os-v3] ⚡ go mod tidy -v
go: downloading github.com/gogf/gf/v2 v2.1.0
go: finding module for package github.com/gogf/gf/v2/protocol/goai
github.com/tiger1103/gfast/v3/internal/cmd imports
github.com/gogf/gf/v2/protocol/goai: module github.com/gogf/gf/v2@latest found (v2.1.2, replaced by github.com/gogf/gf/[email protected]), but does not contain package github.com/gogf/gf/v2/protocol/goai

full English Version of gfast?

We are new to setting up of gfast, but I had set up gfast in the local by following all the steps, able to login, loaded data in MySQL tables, I'm able to see the Menu, pages and content are all in Mandarin language, I'm not able to convert to English and see, Is there any other way I can see the whole gfast application in English? Any other mandarin key fonts I need to install?

新能功能建议: 文件上传可增加七牛或oss

我在 app/service/admin/upload_service/upload.go 中新增了oss上传代码,可作为参考

后台参数管理新增:
名称:文件上传驱动
键名:sys.uploadFile.driver
键值:oss | local

配置config.toml代码:

#OSS文件存储
[oss]
    accessID = ""
    accessSecret = ""
    bucketName = ""
    endpoint = "oss-cn-hangzhou.aliyuncs.com"
    resUrl = "http://www.xxxx.cn/"

upload.go

package upload_service

import (
	"fmt"
	"gfast/app/model/admin/sys_config"
	"gfast/app/service/admin/params_service"
	"github.com/aliyun/aliyun-oss-go-sdk/oss"
	"github.com/gogf/gf/errors/gerror"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/net/ghttp"
	"github.com/gogf/gf/os/gfile"
	"github.com/gogf/gf/os/gtime"
	"github.com/gogf/gf/text/gregex"
	"github.com/gogf/gf/text/gstr"
	"github.com/gogf/gf/util/gconv"
	"github.com/gogf/gf/util/grand"
	"strconv"
	"strings"
)

const (
	upPath      = "/pub_upload/"
	driverOSS   = "oss"
	driverLocal = "local"
)

var uploadPath string

//上传得文件信息
type FileInfo struct {
	FileName string `json:"fileName"`
	FileSize int64  `json:"fileSize"`
	FileUrl  string `json:"fileUrl"`
	FileType string `json:"fileType"`
}

func init() {
	uploadPath = g.Cfg().GetString("server.ServerRoot") + upPath
}

//上传图片
func UpImg(file *ghttp.UploadFile) (fileInfo *FileInfo, err error) {
	return upByType(file, "img")
}

//上传文件
func UpFile(file *ghttp.UploadFile) (fileInfo *FileInfo, err error) {
	return upByType(file, "file")
}

//批量上传图片
func UpImgs(files []*ghttp.UploadFile) (fileInfos []*FileInfo, err error) {
	return UpBathByType(files, "img")
}

//批量上传文件
func UpFiles(files []*ghttp.UploadFile) (fileInfos []*FileInfo, err error) {
	return UpBathByType(files, "file")
}

//文件上传 img|file
func upByType(file *ghttp.UploadFile, fType string) (fileInfo *FileInfo, err error) {
	if file == nil {
		err = gerror.New("未上传任何文件")
		return
	}
	var (
		typeKey string
		sizeKey string
	)
	if fType == "img" {
		typeKey = "sys.uploadFile.imageType"
		sizeKey = "sys.uploadFile.imageSize"
	} else if fType == "file" {
		typeKey = "sys.uploadFile.fileType"
		sizeKey = "sys.uploadFile.fileSize"
	}
	//获取上传类型配置
	config, err := getUpConfig(typeKey)
	if err != nil {
		return
	}

	//检测文件类型
	rightType := checkFileType(file.Filename, config.ConfigValue)
	if !rightType {
		err = gerror.New("上传文件类型错误,只能包含后缀为:" + config.ConfigValue + "的文件。")
		return
	}
	//获取上传大小配置
	config, err = getUpConfig(sizeKey)
	if err != nil {
		return
	}
	rightSize, err := checkSize(config.ConfigValue, file.Size)
	if err != nil {
		return
	}
	if !rightSize {
		err = gerror.New("上传文件超过最大尺寸:" + config.ConfigValue)
		return
	}

	//获取文件上传驱动
	config, err = getUpConfig("sys.uploadFile.driver")
	if err != nil {
		return
	}

	fileUrl := ""
	fileName := ""

	switch {
	case config.ConfigValue == driverOSS:
		fileName, err = uploadToOss(file)
		if err != nil {
			return
		}
		fileUrl = getOssUrl(fileName)
	case config.ConfigValue == driverLocal:
		path := getUpPath()
		fileName, err = file.Save(path, true)
		if err != nil {
			return
		}
		fileUrl = getUrl(path, fileName)

	default:
		err = gerror.New("未配置上传驱动,请在后台参数管理中新增配置Key=sys.uploadFile.driver")
		return
	}

	fileInfo = &FileInfo{
		FileName: file.Filename,
		FileSize: file.Size,
		FileUrl:  fileUrl,
		FileType: file.Header.Get("Content-type"),
	}
	return
}

//批量上传 img|file
func UpBathByType(files []*ghttp.UploadFile, fType string) (fileInfos []*FileInfo, err error) {
	if len(files) == 0 {
		err = gerror.New("未上传任何文件")
		return
	}
	var (
		typeKey string
		sizeKey string
	)
	if fType == "img" {
		typeKey = "sys.uploadFile.imageType"
		sizeKey = "sys.uploadFile.imageSize"
	} else if fType == "file" {
		typeKey = "sys.uploadFile.fileType"
		sizeKey = "sys.uploadFile.fileSize"
	}
	//获取上传类型配置
	configType, err := getUpConfig(typeKey)
	if err != nil {
		return
	}
	//获取上传大小配置
	configSize, err := getUpConfig(sizeKey)
	if err != nil {
		return
	}
	for _, file := range files {
		//检测文件类型
		rightType := checkFileType(file.Filename, configType.ConfigValue)
		if !rightType {
			err = gerror.New("上传文件类型错误,只能包含后缀为:" + configType.ConfigValue + "的文件。")
			return
		}
		var rightSize bool
		rightSize, err = checkSize(configSize.ConfigValue, file.Size)
		if err != nil {
			return
		}
		if !rightSize {
			err = gerror.New("上传文件超过最大尺寸:" + configSize.ConfigValue)
			return
		}
	}
	path := getUpPath()
	for _, file := range files {
		var fileName string
		fileName, err = file.Save(path, true)
		if err != nil {
			return
		}
		fileInfo := &FileInfo{
			FileName: file.Filename,
			FileSize: file.Size,
			FileUrl:  getUrl(path, fileName),
			FileType: file.Header.Get("Content-type"),
		}
		fileInfos = append(fileInfos, fileInfo)
	}
	return
}

//检查文件大小是否合法
func checkSize(configSize string, fileSize int64) (bool, error) {
	match, err := gregex.MatchString(`^([0-9]+)(?i:([a-z]*))$`, configSize)
	if err != nil {
		return false, err
	}
	if len(match) == 0 {
		err = gerror.New("上传文件大小未设置,请在后台配置,格式为(30M,30k,30MB)")
		return false, err
	}
	var cfSize int64
	switch gstr.ToUpper(match[2]) {
	case "MB", "M":
		cfSize = gconv.Int64(match[1]) * 1024 * 1024
	case "KB", "K":
		cfSize = gconv.Int64(match[1]) * 1024
	case "":
		cfSize = gconv.Int64(match[1])
	}
	if cfSize == 0 {
		err = gerror.New("上传文件大小未设置,请在后台配置,格式为(30M,30k,30MB),最大单位为MB")
		return false, err
	}
	return cfSize >= fileSize, nil
}

//获取上传配置
func getUpConfig(key string) (config *sys_config.Entity, err error) {
	config, err = params_service.GetConfigByKey(key)
	if err != nil {
		return
	}
	if config == nil {
		err = gerror.New("上传文件类型未设置,请在后台配置")
		return
	}
	return
}

//判断上传文件类型是否合法
func checkFileType(fileName, typeString string) bool {
	suffix := gstr.SubStrRune(fileName, gstr.PosRRune(fileName, ".")+1, gstr.LenRune(fileName)-1)
	imageType := gstr.Split(typeString, ",")
	rightType := false
	for _, v := range imageType {
		if gstr.Equal(suffix, v) {
			rightType = true
			break
		}
	}
	return rightType
}

func getUpPath() (upPath string) {
	upPath = uploadPath + gtime.Date() + "/"
	return
}

func getUrl(path, fileName string) string {

	url := gstr.SubStr(path, gstr.Pos(path, upPath)+1) + fileName
	return url
}

//--------------------------------OSS Upload-----------------------------------
const objPrefix = "admin/%s"

func getOssUrl(fileName string) string {
	resUrl := g.Cfg().GetString("oss.resUrl")
	objKey := fmt.Sprintf(objPrefix, fileName)
	return resUrl + objKey
}

func uploadToOss(file *ghttp.UploadFile) (string, error) {

	f, err := file.Open()
	if err != nil {
		g.Log().Error(err)
		return "", err
	}

	accessID := g.Cfg().GetString("oss.accessID")
	accessSecret := g.Cfg().GetString("oss.accessSecret")
	endpoint := g.Cfg().GetString("oss.endpoint")
	bucketName := g.Cfg().GetString("oss.bucketName")

	client, err := oss.New(endpoint, accessID, accessSecret)
	if err != nil {
		g.Log().Error(err)
		return "", err
	}

	//获取存储空间
	bucket, err := client.Bucket(bucketName)
	if err != nil {
		g.Log().Error(err)
		return "", err
	}

	//生成随机文件名
	name := gfile.Basename(file.Filename)
	name = strings.ToLower(strconv.FormatInt(gtime.TimestampNano(), 36) + grand.S(10))
	name = name + gfile.Ext(file.Filename)

	objKey := fmt.Sprintf(objPrefix, name)

	//上传Byte数组
	if err := bucket.PutObject(objKey, f); err != nil {
		g.Log().Error(err)
		return "", err
	}

	if err := bucket.SetObjectACL(objKey, oss.ACLPublicRead); err != nil {
		g.Log().Error(err)
	}

	return name, nil
}

代码生成器

你写的这个框架很完善很强大,要是在做一个代码生成器就更完美了。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.