基础架构变更 增加模块化

This commit is contained in:
pixel
2021-07-17 14:18:52 +08:00
parent b5c1babec9
commit c7de76b849
95 changed files with 1283 additions and 714 deletions

View File

@@ -0,0 +1,8 @@
package example
type ServiceGroup struct {
FileUploadAndDownloadService
CustomerService
ExcelService
SimpleUploaderService
}

View File

@@ -0,0 +1,62 @@
package example
import (
"errors"
"gin-vue-admin/global"
"gin-vue-admin/model/example"
"gorm.io/gorm"
)
type FileUploadAndDownloadService struct {
}
//@author: [piexlmax](https://github.com/piexlmax)
//@function: FindOrCreateFile
//@description: 上传文件时检测当前文件属性,如果没有文件则创建,有则返回文件的当前切片
//@param: fileMd5 string, fileName string, chunkTotal int
//@return: err error, file model.ExaFile
func (e *FileUploadAndDownloadService) FindOrCreateFile(fileMd5 string, fileName string, chunkTotal int) (err error, file example.ExaFile) {
var cfile example.ExaFile
cfile.FileMd5 = fileMd5
cfile.FileName = fileName
cfile.ChunkTotal = chunkTotal
if errors.Is(global.GVA_DB.Where("file_md5 = ? AND is_finish = ?", fileMd5, true).First(&file).Error, gorm.ErrRecordNotFound) {
err = global.GVA_DB.Where("file_md5 = ? AND file_name = ?", fileMd5, fileName).Preload("ExaFileChunk").FirstOrCreate(&file, cfile).Error
return err, file
}
cfile.IsFinish = true
cfile.FilePath = file.FilePath
err = global.GVA_DB.Create(&cfile).Error
return err, cfile
}
//@author: [piexlmax](https://github.com/piexlmax)
//@function: CreateFileChunk
//@description: 创建文件切片记录
//@param: id uint, fileChunkPath string, fileChunkNumber int
//@return: error
func (e *FileUploadAndDownloadService) CreateFileChunk(id uint, fileChunkPath string, fileChunkNumber int) error {
var chunk example.ExaFileChunk
chunk.FileChunkPath = fileChunkPath
chunk.ExaFileID = id
chunk.FileChunkNumber = fileChunkNumber
err := global.GVA_DB.Create(&chunk).Error
return err
}
//@author: [piexlmax](https://github.com/piexlmax)
//@function: DeleteFileChunk
//@description: 删除文件切片记录
//@param: fileMd5 string, fileName string, filePath string
//@return: error
func (e *FileUploadAndDownloadService) DeleteFileChunk(fileMd5 string, fileName string, filePath string) error {
var chunks []example.ExaFileChunk
var file example.ExaFile
err := global.GVA_DB.Where("file_md5 = ? AND file_name = ?", fileMd5, fileName).First(&file).Update("IsFinish", true).Update("file_path", filePath).Error
err = global.GVA_DB.Where("exa_file_id = ?", file.ID).Delete(&chunks).Unscoped().Error
return err
}

View File

@@ -0,0 +1,83 @@
package example
import (
"gin-vue-admin/global"
"gin-vue-admin/model/common/request"
"gin-vue-admin/model/example"
"gin-vue-admin/model/system"
systemService "gin-vue-admin/service/system"
)
type CustomerService struct {
}
//@author: [piexlmax](https://github.com/piexlmax)
//@function: CreateExaCustomer
//@description: 创建客户
//@param: e model.ExaCustomer
//@return: err error
func (exa *CustomerService) CreateExaCustomer(e example.ExaCustomer) (err error) {
err = global.GVA_DB.Create(&e).Error
return err
}
//@author: [piexlmax](https://github.com/piexlmax)
//@function: DeleteFileChunk
//@description: 删除客户
//@param: e model.ExaCustomer
//@return: err error
func (exa *CustomerService) DeleteExaCustomer(e example.ExaCustomer) (err error) {
err = global.GVA_DB.Delete(&e).Error
return err
}
//@author: [piexlmax](https://github.com/piexlmax)
//@function: UpdateExaCustomer
//@description: 更新客户
//@param: e *model.ExaCustomer
//@return: err error
func (exa *CustomerService) UpdateExaCustomer(e *example.ExaCustomer) (err error) {
err = global.GVA_DB.Save(e).Error
return err
}
//@author: [piexlmax](https://github.com/piexlmax)
//@function: GetExaCustomer
//@description: 获取客户信息
//@param: id uint
//@return: err error, customer model.ExaCustomer
func (exa *CustomerService) GetExaCustomer(id uint) (err error, customer example.ExaCustomer) {
err = global.GVA_DB.Where("id = ?", id).First(&customer).Error
return
}
//@author: [piexlmax](https://github.com/piexlmax)
//@function: GetCustomerInfoList
//@description: 分页获取客户列表
//@param: sysUserAuthorityID string, info request.PageInfo
//@return: err error, list interface{}, total int64
func (exa *CustomerService) GetCustomerInfoList(sysUserAuthorityID string, info request.PageInfo) (err error, list interface{}, total int64) {
limit := info.PageSize
offset := info.PageSize * (info.Page - 1)
db := global.GVA_DB.Model(&example.ExaCustomer{})
var a system.SysAuthority
a.AuthorityId = sysUserAuthorityID
err, auth := systemService.AuthorityServiceApp.GetAuthorityInfo(a)
var dataId []string
for _, v := range auth.DataAuthorityId {
dataId = append(dataId, v.AuthorityId)
}
var CustomerList []example.ExaCustomer
err = db.Where("sys_user_authority_id in ?", dataId).Count(&total).Error
if err != nil {
return err, CustomerList, total
} else {
err = db.Limit(limit).Offset(offset).Preload("SysUser").Where("sys_user_authority_id in ?", dataId).Find(&CustomerList).Error
}
return err, CustomerList, total
}

View File

@@ -0,0 +1,94 @@
package example
import (
"errors"
"fmt"
"gin-vue-admin/global"
"gin-vue-admin/model/system"
"github.com/360EntSecGroup-Skylar/excelize/v2"
"strconv"
)
type ExcelService struct {
}
func (exa *ExcelService) ParseInfoList2Excel(infoList []system.SysBaseMenu, filePath string) error {
excel := excelize.NewFile()
excel.SetSheetRow("Sheet1", "A1", &[]string{"ID", "路由Name", "路由Path", "是否隐藏", "父节点", "排序", "文件名称"})
for i, menu := range infoList {
axis := fmt.Sprintf("A%d", i+2)
excel.SetSheetRow("Sheet1", axis, &[]interface{}{
menu.ID,
menu.Name,
menu.Path,
menu.Hidden,
menu.ParentId,
menu.Sort,
menu.Component,
})
}
err := excel.SaveAs(filePath)
return err
}
func (exa *ExcelService) ParseExcel2InfoList() ([]system.SysBaseMenu, error) {
skipHeader := true
fixedHeader := []string{"ID", "路由Name", "路由Path", "是否隐藏", "父节点", "排序", "文件名称"}
file, err := excelize.OpenFile(global.GVA_CONFIG.Excel.Dir + "ExcelImport.xlsx")
if err != nil {
return nil, err
}
menus := make([]system.SysBaseMenu, 0)
rows, err := file.Rows("Sheet1")
if err != nil {
return nil, err
}
for rows.Next() {
row, err := rows.Columns()
if err != nil {
return nil, err
}
if skipHeader {
if exa.compareStrSlice(row, fixedHeader) {
skipHeader = false
continue
} else {
return nil, errors.New("Excel格式错误")
}
}
if len(row) != len(fixedHeader) {
continue
}
id, _ := strconv.Atoi(row[0])
hidden, _ := strconv.ParseBool(row[3])
sort, _ := strconv.Atoi(row[5])
menu := system.SysBaseMenu{
GVA_MODEL: global.GVA_MODEL{
ID: uint(id),
},
Name: row[1],
Path: row[2],
Hidden: hidden,
ParentId: row[4],
Sort: sort,
Component: row[6],
}
menus = append(menus, menu)
}
return menus, nil
}
func (exa *ExcelService) compareStrSlice(a, b []string) bool {
if len(a) != len(b) {
return false
}
if (b == nil) != (a == nil) {
return false
}
for key, value := range a {
if value != b[key] {
return false
}
}
return true
}

View File

@@ -0,0 +1,91 @@
package example
import (
"errors"
"gin-vue-admin/global"
"gin-vue-admin/model/common/request"
"gin-vue-admin/model/example"
"gin-vue-admin/utils/upload"
"mime/multipart"
"strings"
)
//@author: [piexlmax](https://github.com/piexlmax)
//@function: Upload
//@description: 创建文件上传记录
//@param: file model.ExaFileUploadAndDownload
//@return: error
func (e *FileUploadAndDownloadService) Upload(file example.ExaFileUploadAndDownload) error {
return global.GVA_DB.Create(&file).Error
}
//@author: [piexlmax](https://github.com/piexlmax)
//@function: FindFile
//@description: 删除文件切片记录
//@param: id uint
//@return: error, model.ExaFileUploadAndDownload
func (e *FileUploadAndDownloadService) FindFile(id uint) (error, example.ExaFileUploadAndDownload) {
var file example.ExaFileUploadAndDownload
err := global.GVA_DB.Where("id = ?", id).First(&file).Error
return err, file
}
//@author: [piexlmax](https://github.com/piexlmax)
//@function: DeleteFile
//@description: 删除文件记录
//@param: file model.ExaFileUploadAndDownload
//@return: err error
func (e *FileUploadAndDownloadService) DeleteFile(file example.ExaFileUploadAndDownload) (err error) {
var fileFromDb example.ExaFileUploadAndDownload
err, fileFromDb = e.FindFile(file.ID)
oss := upload.NewOss()
if err = oss.DeleteFile(fileFromDb.Key); err != nil {
return errors.New("文件删除失败")
}
err = global.GVA_DB.Where("id = ?", file.ID).Unscoped().Delete(&file).Error
return err
}
//@author: [piexlmax](https://github.com/piexlmax)
//@function: GetFileRecordInfoList
//@description: 分页获取数据
//@param: info requset.PageInfo
//@return: err error, list interface{}, total int64
func (e *FileUploadAndDownloadService) GetFileRecordInfoList(info request.PageInfo) (err error, list interface{}, total int64) {
limit := info.PageSize
offset := info.PageSize * (info.Page - 1)
db := global.GVA_DB
var fileLists []example.ExaFileUploadAndDownload
err = db.Find(&fileLists).Count(&total).Error
err = db.Limit(limit).Offset(offset).Order("updated_at desc").Find(&fileLists).Error
return err, fileLists, total
}
//@author: [piexlmax](https://github.com/piexlmax)
//@function: UploadFile
//@description: 根据配置文件判断是文件上传到本地或者七牛云
//@param: header *multipart.FileHeader, noSave string
//@return: err error, file model.ExaFileUploadAndDownload
func (e *FileUploadAndDownloadService) UploadFile(header *multipart.FileHeader, noSave string) (err error, file example.ExaFileUploadAndDownload) {
oss := upload.NewOss()
filePath, key, uploadErr := oss.UploadFile(header)
if uploadErr != nil {
panic(err)
}
if noSave == "0" {
s := strings.Split(header.Filename, ".")
f := example.ExaFileUploadAndDownload{
Url: filePath,
Name: header.Filename,
Tag: s[len(s)-1],
Key: key,
}
return e.Upload(f), f
}
return
}

View File

@@ -0,0 +1,97 @@
package example
import (
"errors"
"fmt"
"gin-vue-admin/global"
"gin-vue-admin/model/example"
"gorm.io/gorm"
"io/ioutil"
"os"
"strconv"
)
type SimpleUploaderService struct {
}
//@author: [piexlmax](https://github.com/piexlmax)
//@function: SaveChunk
//@description: 保存文件切片路径
//@param: uploader model.ExaSimpleUploader
//@return: err error
func (exa *SimpleUploaderService) SaveChunk(uploader example.ExaSimpleUploader) (err error) {
return global.GVA_DB.Create(uploader).Error
}
//@author: [piexlmax](https://github.com/piexlmax)
//@function: CheckFileMd5
//@description: 检查文件是否已经上传过
//@param: md5 string
//@return: err error, uploads []model.ExaSimpleUploader, isDone bool
func (exa *SimpleUploaderService) CheckFileMd5(md5 string) (err error, uploads []example.ExaSimpleUploader, isDone bool) {
err = global.GVA_DB.Find(&uploads, "identifier = ? AND is_done = ?", md5, false).Error
isDone = errors.Is(global.GVA_DB.First(&example.ExaSimpleUploader{}, "identifier = ? AND is_done = ?", md5, true).Error, gorm.ErrRecordNotFound)
return err, uploads, !isDone
}
//@author: [piexlmax](https://github.com/piexlmax)
//@function: MergeFileMd5
//@description: 合并文件
//@param: md5 string, fileName string
//@return: err error
func (exa *SimpleUploaderService) MergeFileMd5(md5 string, fileName string) (err error) {
finishDir := "./finish/"
dir := "./chunk/" + md5
// 如果文件上传成功 不做后续操作 通知成功即可
if !errors.Is(global.GVA_DB.First(&example.ExaSimpleUploader{}, "identifier = ? AND is_done = ?", md5, true).Error, gorm.ErrRecordNotFound) {
return nil
}
// 打开切片文件夹
rd, err := ioutil.ReadDir(dir)
_ = os.MkdirAll(finishDir, os.ModePerm)
// 创建目标文件
fd, err := os.OpenFile(finishDir+fileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
if err != nil {
return
}
// 关闭文件
defer fd.Close()
// 将切片文件按照顺序写入
for k := range rd {
content, _ := ioutil.ReadFile(dir + "/" + fileName + strconv.Itoa(k+1))
_, err = fd.Write(content)
if err != nil {
_ = os.Remove(finishDir + fileName)
}
}
if err != nil {
return err
}
err = global.GVA_DB.Transaction(func(tx *gorm.DB) error {
// 删除切片信息
if err = tx.Delete(&example.ExaSimpleUploader{}, "identifier = ? AND is_done = ?", md5, false).Error; err != nil {
fmt.Println(err)
return err
}
data := example.ExaSimpleUploader{
Identifier: md5,
IsDone: true,
FilePath: finishDir + fileName,
Filename: fileName,
}
// 添加文件信息
if err = tx.Create(&data).Error; err != nil {
fmt.Println(err)
return err
}
return nil
})
err = os.RemoveAll(dir) // 清除切片
return err
}