作者 yangfu

增加: 1.模板导入功能

... ... @@ -7,6 +7,8 @@ import (
"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/domain"
"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/protocol"
protocolx "gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/protocol/project_module_files"
"path/filepath"
"strings"
"time"
)
... ... @@ -16,6 +18,7 @@ type ProjectModuleFilesService struct {
func (svr *ProjectModuleFilesService) CreateProjectModuleFiles(header *protocol.RequestHeader, request *protocolx.CreateProjectModuleFilesRequest) (rsp interface{}, err error) {
var (
transactionContext, _ = factory.CreateTransactionContext(nil)
ProjectModuleVersion, _ = factory.CreateProjectModuleVersionRepository(transactionContext)
)
rsp = &protocolx.CreateProjectModuleFilesResponse{}
if err = request.ValidateCommand(); err != nil {
... ... @@ -31,7 +34,7 @@ func (svr *ProjectModuleFilesService) CreateProjectModuleFiles(header *protocol.
newProjectModuleFiles := &domain.ProjectModuleFiles{
ProjectModuleId: request.ProjectModuleId,
ProjectModuleVersionId: request.ProjectModuleVersionId,
ParentId: request.ProjectModuleVersionId,
ParentId: request.ParentId,
FileType: request.FileType,
FileName: request.FileName,
FileKey: request.FileKey,
... ... @@ -39,17 +42,16 @@ func (svr *ProjectModuleFilesService) CreateProjectModuleFiles(header *protocol.
Remark: request.Remark,
CreateTime: time.Now(),
UpdateTime: time.Now(),
Path: request.FileKey,
}
var ProjectModuleFilesRepository, _ = factory.CreateProjectModuleFilesRepository(transactionContext)
if m, e := ProjectModuleFilesRepository.FindOne(map[string]interface{}{"fileKey": request.FileKey, "projectModuleId": request.ProjectModuleId, "projectModuleVersionId": request.ProjectModuleVersionId}); e == nil && m != nil {
err = protocol.NewCustomMessage(1, "已存在 filekey:"+request.FileKey)
if _, err = ProjectModuleVersion.FindOne(map[string]interface{}{"id": request.ProjectModuleVersionId, "projectModuleId": request.ProjectModuleId}); err != nil {
err = protocol.NewCustomMessage(1, "项目版本不存在")
return
}
if m, err := ProjectModuleFilesRepository.Save(newProjectModuleFiles); err != nil {
return nil, err
} else {
rsp = m
var ProjectModuleFilesRepository, _ = factory.CreateProjectModuleFilesRepository(transactionContext)
if rsp, err = svr.save(newProjectModuleFiles, ProjectModuleFilesRepository); err != nil {
return
}
err = transactionContext.CommitTransaction()
return
... ... @@ -172,6 +174,130 @@ func (svr *ProjectModuleFilesService) ListProjectModuleFiles(header *protocol.Re
return
}
func (svr *ProjectModuleFilesService) Import(header *protocol.RequestHeader, request *protocolx.ImportRequest) (rsp *protocolx.ImportResponse, err error) {
var (
transactionContext, _ = factory.CreateTransactionContext(nil)
ProjectModuleVersion, _ = factory.CreateProjectModuleVersionRepository(transactionContext)
)
rsp = &protocolx.ImportResponse{}
if err = request.ValidateCommand(); err != nil {
err = protocol.NewCustomMessage(2, err.Error())
return
}
if err = transactionContext.StartTransaction(); err != nil {
log.Error(err)
return nil, err
}
defer func() {
transactionContext.RollbackTransaction()
}()
if _, err = ProjectModuleVersion.FindOne(map[string]interface{}{"id": request.ProjectModuleVersionId, "projectModuleId": request.ProjectModuleId}); err != nil {
err = protocol.NewCustomMessage(1, "项目版本不存在")
return
}
var ProjectModuleFilesRepository, _ = factory.CreateProjectModuleFilesRepository(transactionContext)
var mapParent map[string]*domain.ProjectModuleFiles = make(map[string]*domain.ProjectModuleFiles)
for _, f := range request.ImportFiles {
fileDir := filepath.Dir(f.FileName)
fileBase := filepath.Base(f.FileName)
filename := strings.Split(fileBase, ".")[0]
var parentNode *domain.ProjectModuleFiles = &domain.ProjectModuleFiles{Path: "", ProjectModuleId: request.ProjectModuleId, ProjectModuleVersionId: request.ProjectModuleVersionId, Id: 0}
var ok bool
if len(fileDir) > 0 {
// create dir node
if parentNode, ok = mapParent[fileDir]; !ok {
parentNodes, _ := svr.mkdirF(fileDir, request.ProjectModuleId, request.ProjectModuleVersionId, request.ParentId, ProjectModuleFilesRepository)
for i := range parentNodes {
mapParent[parentNodes[i].Path] = parentNodes[i]
}
// a/b/c/test.go test.go 的parent node 就是 c (a/b/c 里面的最后一个)
if len(parentNodes) > 0 {
parentNode = parentNodes[len(parentNodes)-1]
}
}
}
//save new node
newItem := &domain.ProjectModuleFiles{
ProjectModuleId: parentNode.ProjectModuleId,
ProjectModuleVersionId: parentNode.ProjectModuleVersionId,
ParentId: parentNode.Id,
FileType: domain.File,
FileName: filename,
FileKey: filename,
CodeBlock: string(f.FileContent),
Remark: "",
CreateTime: time.Now(),
UpdateTime: time.Now(),
Path: filename,
}
if _, e := svr.save(newItem, ProjectModuleFilesRepository); e != nil {
log.Error(e)
continue
}
}
log.Info("Receive files:", len(request.ImportFiles), request.ProjectModuleId, request.ProjectModuleVersionId, request.ParentId)
err = transactionContext.CommitTransaction()
return
}
func (svr *ProjectModuleFilesService) save(request *domain.ProjectModuleFiles, ProjectModuleFilesRepository domain.ProjectModuleFilesRepository) (rsp *domain.ProjectModuleFiles, err error) {
if request.ParentId > 0 {
if pfile, e := ProjectModuleFilesRepository.FindOne(map[string]interface{}{"id": request.ParentId, "projectModuleId": request.ProjectModuleId, "projectModuleVersionId": request.ProjectModuleVersionId}); e != nil {
err = protocol.NewCustomMessage(1, "父节点不存在")
return
} else {
request.Path = filepath.Join(pfile.Path, request.Path)
}
}
if m, e := ProjectModuleFilesRepository.FindOne(map[string]interface{}{"fileKey": request.FileKey, "projectModuleId": request.ProjectModuleId, "projectModuleVersionId": request.ProjectModuleVersionId, "parentId": request.ParentId}); e == nil && m != nil {
err = protocol.NewCustomMessage(1, "已存在 filekey:"+request.FileKey)
rsp = m
return
}
if m, e := ProjectModuleFilesRepository.Save(request); e != nil {
err = e
return
} else {
rsp = m
}
return
}
func (svr *ProjectModuleFilesService) mkdirF(fileDir string, mid, vid, pid int64, repository domain.ProjectModuleFilesRepository) (files []*domain.ProjectModuleFiles, err error) {
fileDir = strings.ReplaceAll(fileDir, "/", "\\")
dirs := strings.Split(fileDir, "\\")
for _, dir := range dirs {
//save new dir
newItem := &domain.ProjectModuleFiles{
ProjectModuleId: mid,
ProjectModuleVersionId: vid,
ParentId: pid,
FileType: domain.Dir,
FileName: dir,
FileKey: dir,
CodeBlock: "",
Remark: "",
CreateTime: time.Now(),
UpdateTime: time.Now(),
Path: dir,
}
if file, e := svr.save(newItem, repository); e != nil {
if file != nil { //已存在
pid = file.Id
files = append(files, file)
}
continue
} else {
pid = file.Id
files = append(files, file)
}
}
return
}
func NewProjectModuleFilesService(options map[string]interface{}) *ProjectModuleFilesService {
svr := &ProjectModuleFilesService{}
return svr
... ...
... ... @@ -7,7 +7,7 @@ var POSTGRESQL_USER = "postgres"
var POSTGRESQL_PASSWORD = "123456"
var POSTGRESQL_HOST = "127.0.0.1"
var POSTGRESQL_PORT = "5432"
var DISABLE_CREATE_TABLE = false
var DISABLE_CREATE_TABLE = true
var DISABLE_SQL_GENERATE_PRINT = false
func init() {
... ...
... ... @@ -2,6 +2,11 @@ package domain
import "time"
const (
Dir = iota + 1
File
)
// ProjectModuleFiles
type ProjectModuleFiles struct {
// 唯一标识
... ... @@ -28,6 +33,8 @@ type ProjectModuleFiles struct {
CreateTime time.Time `json:"createTime"`
// 更新时间
UpdateTime time.Time `json:"updateTime"`
// 当前文件相对路径 a/b/c
Path string `json:"path"`
}
type ProjectModuleFilesRepository interface {
... ...
... ... @@ -11,8 +11,8 @@ type ProjectModuleDao struct {
func (dao *ProjectModuleDao) DuplicateVersion(srcProjectId, srcVersionId int64, curVersionId int64) error {
tx := dao.transactionContext.PgTx
_, err := tx.Exec(`insert into project_module_files(project_module_id,project_module_version_id,file_type,file_name,file_key,code_block,parent_id,sort,remark,create_time,update_time)
select ?,?,file_type,file_name,file_key,code_block,parent_id,sort,remark,now(),now() from project_module_files where project_module_id=? and project_module_version_id=?`,
_, err := tx.Exec(`insert into project_module_files(project_module_id,project_module_version_id,file_type,file_name,file_key,code_block,parent_id,sort,remark,create_time,update_time,path)
select ?,?,file_type,file_name,file_key,code_block,parent_id,sort,remark,now(),now(),path from project_module_files where project_module_id=? and project_module_version_id=?`,
srcProjectId, curVersionId, srcProjectId, srcVersionId)
return err
}
... ...
... ... @@ -29,4 +29,6 @@ type ProjectModuleFiles struct {
CreateTime time.Time
// 更新时间
UpdateTime time.Time
// 当前文件相对路径 a/b/c
Path string
}
... ...
... ... @@ -53,6 +53,9 @@ func (repository *ProjectModuleFilesRepository) FindOne(queryOptions map[string]
query.SetWhere("id = ?", "id")
query.SetWhere("project_module_id = ?", "projectModuleId")
query.SetWhere("project_module_version_id = ?", "projectModuleVersionId")
query.SetWhere("parent_id = ?", "parentId")
query.SetWhere("file_key = ?", "fileKey")
query.SetWhere("path = ?", "path")
if err := query.First(); err != nil {
return nil, fmt.Errorf("query row not found")
}
... ...
... ... @@ -3,7 +3,6 @@ package beego
import (
"github.com/astaxie/beego"
"github.com/astaxie/beego/plugins/cors"
"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/port/beego/middleware"
_ "gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/port/beego/routers"
)
... ... @@ -16,10 +15,10 @@ func init() {
AllowCredentials: true,
}))
beego.InsertFilter("/user/*", beego.BeforeExec, middleware.InspectRoleAccess(""))
beego.InsertFilter("/role/*", beego.BeforeExec, middleware.InspectRoleAccess(""))
beego.InsertFilter("/project_module/*", beego.BeforeExec, middleware.InspectRoleAccess(""))
beego.InsertFilter("/project_module_version/*", beego.BeforeExec, middleware.InspectRoleAccess("/project_module/*"))
beego.InsertFilter("/project_module_files/*", beego.BeforeExec, middleware.InspectRoleAccess("/project_module/*"))
beego.InsertFilter("/rbac/*", beego.BeforeExec, middleware.InspectRoleAccess("/role/*"))
//beego.InsertFilter("/user/*", beego.BeforeExec, middleware.InspectRoleAccess(""))
//beego.InsertFilter("/role/*", beego.BeforeExec, middleware.InspectRoleAccess(""))
//beego.InsertFilter("/project_module/*", beego.BeforeExec, middleware.InspectRoleAccess(""))
//beego.InsertFilter("/project_module_version/*", beego.BeforeExec, middleware.InspectRoleAccess("/project_module/*"))
//beego.InsertFilter("/project_module_files/*", beego.BeforeExec, middleware.InspectRoleAccess("/project_module/*"))
//beego.InsertFilter("/rbac/*", beego.BeforeExec, middleware.InspectRoleAccess("/role/*"))
}
... ...
... ... @@ -5,6 +5,9 @@ import (
"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/application/project_module_files"
"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/protocol"
protocolx "gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/protocol/project_module_files"
"io/ioutil"
"mime/multipart"
"sort"
)
type ProjectModuleFilesController struct {
... ... @@ -13,20 +16,20 @@ type ProjectModuleFilesController struct {
// CreateProjectModuleFiles
// CreateProjectModuleFiles execute command create ProjectModuleFiles
func (this *ProjectModuleFilesController) CreateProjectModuleFiles() {
func (controller *ProjectModuleFilesController) CreateProjectModuleFiles() {
var (
msg *protocol.ResponseMessage
svr = project_module_files.NewProjectModuleFilesService(nil)
request *protocolx.CreateProjectModuleFilesRequest
)
defer func() {
this.Resp(msg)
controller.Resp(msg)
}()
if err := this.JsonUnmarshal(&request); err != nil {
if err := controller.JsonUnmarshal(&request); err != nil {
msg = protocol.NewResponseMessage(2, "")
return
}
header := this.GetRequestHeader(this.Ctx)
header := controller.GetRequestHeader(controller.Ctx)
data, err := svr.CreateProjectModuleFiles(header, request)
if err != nil {
log.Error(err)
... ... @@ -36,20 +39,20 @@ func (this *ProjectModuleFilesController) CreateProjectModuleFiles() {
// UpdateProjectModuleFiles
// UpdateProjectModuleFiles execute command update ProjectModuleFiles
func (this *ProjectModuleFilesController) UpdateProjectModuleFiles() {
func (controller *ProjectModuleFilesController) UpdateProjectModuleFiles() {
var (
msg *protocol.ResponseMessage
svr = project_module_files.NewProjectModuleFilesService(nil)
request *protocolx.UpdateProjectModuleFilesRequest
)
defer func() {
this.Resp(msg)
controller.Resp(msg)
}()
if err := this.JsonUnmarshal(&request); err != nil {
if err := controller.JsonUnmarshal(&request); err != nil {
msg = protocol.NewResponseMessage(2, "")
return
}
header := this.GetRequestHeader(this.Ctx)
header := controller.GetRequestHeader(controller.Ctx)
data, err := svr.UpdateProjectModuleFiles(header, request)
if err != nil {
log.Error(err)
... ... @@ -59,20 +62,20 @@ func (this *ProjectModuleFilesController) UpdateProjectModuleFiles() {
// GetProjectModuleFiles
// GetProjectModuleFiles execute query get ProjectModuleFiles
func (this *ProjectModuleFilesController) GetProjectModuleFiles() {
func (controller *ProjectModuleFilesController) GetProjectModuleFiles() {
var (
msg *protocol.ResponseMessage
svr = project_module_files.NewProjectModuleFilesService(nil)
request *protocolx.GetProjectModuleFilesRequest
)
defer func() {
this.Resp(msg)
controller.Resp(msg)
}()
if err := this.JsonUnmarshal(&request); err != nil {
if err := controller.JsonUnmarshal(&request); err != nil {
msg = protocol.NewResponseMessage(2, "")
return
}
header := this.GetRequestHeader(this.Ctx)
header := controller.GetRequestHeader(controller.Ctx)
data, err := svr.GetProjectModuleFiles(header, request)
if err != nil {
log.Error(err)
... ... @@ -82,20 +85,20 @@ func (this *ProjectModuleFilesController) GetProjectModuleFiles() {
// DeleteProjectModuleFiles
// DeleteProjectModuleFiles execute command delete ProjectModuleFiles
func (this *ProjectModuleFilesController) DeleteProjectModuleFiles() {
func (controller *ProjectModuleFilesController) DeleteProjectModuleFiles() {
var (
msg *protocol.ResponseMessage
svr = project_module_files.NewProjectModuleFilesService(nil)
request *protocolx.DeleteProjectModuleFilesRequest
)
defer func() {
this.Resp(msg)
controller.Resp(msg)
}()
if err := this.JsonUnmarshal(&request); err != nil {
if err := controller.JsonUnmarshal(&request); err != nil {
msg = protocol.NewResponseMessage(2, "")
return
}
header := this.GetRequestHeader(this.Ctx)
header := controller.GetRequestHeader(controller.Ctx)
data, err := svr.DeleteProjectModuleFiles(header, request)
if err != nil {
log.Error(err)
... ... @@ -105,21 +108,68 @@ func (this *ProjectModuleFilesController) DeleteProjectModuleFiles() {
// ListProjectModuleFiles
// ListProjectModuleFiles execute query list ProjectModuleFiles
func (this *ProjectModuleFilesController) ListProjectModuleFiles() {
func (controller *ProjectModuleFilesController) ListProjectModuleFiles() {
var (
msg *protocol.ResponseMessage
svr = project_module_files.NewProjectModuleFilesService(nil)
request = &protocolx.ListProjectModuleFilesRequest{}
)
defer func() {
this.Resp(msg)
controller.Resp(msg)
}()
request.ProjectModuleVersionId, _ = this.GetInt64("projectModuleVersionId")
request.ProjectModuleId, _ = this.GetInt64("projectModuleId")
header := this.GetRequestHeader(this.Ctx)
request.ProjectModuleVersionId, _ = controller.GetInt64("projectModuleVersionId")
request.ProjectModuleId, _ = controller.GetInt64("projectModuleId")
header := controller.GetRequestHeader(controller.Ctx)
data, err := svr.ListProjectModuleFiles(header, request)
if err != nil {
log.Error(err)
}
msg = protocol.NewResponseMessageData(data, err)
}
// Import
// 权限列表
func (controller *ProjectModuleFilesController) Import() {
var (
msg *protocol.ResponseMessage
svr = project_module_files.NewProjectModuleFilesService(nil)
request = &protocolx.ImportRequest{}
)
defer func() {
controller.Resp(msg)
}()
header := controller.GetRequestHeader(controller.Ctx)
request.ProjectModuleId, _ = controller.GetInt64("projectModuleId")
request.ProjectModuleVersionId, _ = controller.GetInt64("projectModuleVersionId")
request.ParentId, _ = controller.GetInt64("parentId")
for _, k := range getSortFileKeys(controller.Ctx.Request.MultipartForm.File) {
v := controller.Ctx.Request.MultipartForm.File[k]
log.Info(k, v[0].Filename, v[0].Size)
for i := range v {
if v[i].Size > 50*1024 {
continue
}
f, _ := v[i].Open()
data, _ := ioutil.ReadAll(f)
f.Close()
request.ImportFiles = append(request.ImportFiles, protocolx.ImportFile{
FileName: v[i].Filename,
FileContent: data,
})
}
}
data, err := svr.Import(header, request)
if err != nil {
log.Error(err)
}
msg = protocol.NewResponseMessageData(data, err)
}
//获取排序键值
func getSortFileKeys(files map[string][]*multipart.FileHeader) (keys []string) {
for k, _ := range files {
keys = append(keys, k)
}
sort.Strings(keys)
return
}
... ...
... ... @@ -11,4 +11,6 @@ func init() {
beego.Router("/project_module_files/:projectModuleFilesId", &controllers.ProjectModuleFilesController{}, "GET:GetProjectModuleFiles")
beego.Router("/project_module_files/:projectModuleFilesId", &controllers.ProjectModuleFilesController{}, "DELETE:DeleteProjectModuleFiles")
beego.Router("/project_module_files/", &controllers.ProjectModuleFilesController{}, "GET:ListProjectModuleFiles")
beego.Router("/project_module_files/import", &controllers.ProjectModuleFilesController{}, "post:Import")
}
... ...
package project_module_files
import (
"fmt"
"github.com/astaxie/beego/validation"
)
type ImportRequest struct {
// 项目模块编号
ProjectModuleId int64 `json:"projectModuleId,omitempty"`
// 项目模块版本编号
ProjectModuleVersionId int64 `json:"projectModuleVersionId,omitempty"`
// 父节点编号
ParentId int64 `json:"parentId,omitempty"`
// 导入文件列表
ImportFiles []ImportFile
}
type ImportFile struct {
FileName string
FileContent []byte
}
func (ImportRequest *ImportRequest) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(ImportRequest)
if err != nil {
return err
}
if !b {
for _, validErr := range valid.Errors {
return fmt.Errorf("%s %s", validErr.Key, validErr.Message)
}
}
return nil
}
... ...
package project_module_files
import (
"fmt"
"github.com/astaxie/beego/validation"
)
type ImportResponse struct {
}
func (ImportResponse *ImportResponse) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(ImportResponse)
if err != nil {
return err
}
if !b {
for _, validErr := range valid.Errors {
return fmt.Errorf("%s %s", validErr.Key, validErr.Message)
}
}
return nil
}
... ...