From ad773bac1b9433d200c1a30abd387bb5814be496 Mon Sep 17 00:00:00 2001 From: chenlin Date: Wed, 2 Apr 2025 19:39:51 +0800 Subject: [PATCH] =?UTF-8?q?1.=E6=96=B0=E5=A2=9E=E5=90=88=E5=90=8C=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E6=8E=A5=E5=8F=A3=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/admin/apis/bus_apis/a_common.go | 44 ++ app/admin/apis/bus_apis/a_contract.go | 274 +++++++++ app/admin/models/bus_models/m_common.go | 9 + app/admin/models/bus_models/m_contract.go | 83 +++ app/admin/router/bus_common.go | 18 + app/admin/router/bus_contract.go | 25 + app/admin/router/router.go | 6 + app/admin/service/bus_service/s_contract.go | 271 +++++++++ docs/admin/admin_docs.go | 611 ++++++++++++++++++++ docs/admin/admin_swagger.json | 611 ++++++++++++++++++++ docs/admin/admin_swagger.yaml | 410 +++++++++++++ go.mod | 9 +- tools/ali/oss.go | 87 +++ tools/ali/oss_test.go | 27 + 14 files changed, 2482 insertions(+), 3 deletions(-) create mode 100644 app/admin/apis/bus_apis/a_common.go create mode 100644 app/admin/apis/bus_apis/a_contract.go create mode 100644 app/admin/models/bus_models/m_common.go create mode 100644 app/admin/models/bus_models/m_contract.go create mode 100644 app/admin/router/bus_common.go create mode 100644 app/admin/router/bus_contract.go create mode 100644 app/admin/service/bus_service/s_contract.go create mode 100644 tools/ali/oss.go create mode 100644 tools/ali/oss_test.go diff --git a/app/admin/apis/bus_apis/a_common.go b/app/admin/apis/bus_apis/a_common.go new file mode 100644 index 0000000..7813e14 --- /dev/null +++ b/app/admin/apis/bus_apis/a_common.go @@ -0,0 +1,44 @@ +package bus_apis + +import ( + "github.com/gin-gonic/gin" + "github.com/go-admin-team/go-admin-core/logger" + "github.com/go-admin-team/go-admin-core/sdk/api" + "go-admin/app/admin/models/bus_models" + aliyun "go-admin/tools/ali" + "go-admin/tools/app" +) + +type CommonApi struct { + api.Api +} + +// AliYunStsTokenGet 获取阿里云oss对象存储token +// @Summary 获取阿里云oss对象存储token +// @Tags 公共模块-V1.0.0 +// @Produce json +// @Accept json +// @Success 200 {object} bus_models.RspAliyunStsToken +// @Router /api/v1/common/aliyun/sts_token [post] +func (e CommonApi) AliYunStsTokenGet(c *gin.Context) { + uploadInfo, err := aliyun.GenStsToken("21000505") + if err != nil { + logger.Error("aliyun.GenStsToken err", err) + return + } + + stsToken := bus_models.RspAliyunStsToken{ + AccessKeyId: uploadInfo.AccessKeyId, + AccessKeySecret: uploadInfo.AccessKeySecret, + SecurityToken: uploadInfo.SecurityToken, + BucketName: uploadInfo.BucketName, + Expiration: uint64(uploadInfo.Expiration), + } + + ret := map[string]interface{}{ + "stsToken": stsToken, + "ossUrl": aliyun.AliyunOssUrl, + } + app.OK(c, ret, "") + return +} diff --git a/app/admin/apis/bus_apis/a_contract.go b/app/admin/apis/bus_apis/a_contract.go new file mode 100644 index 0000000..5c83089 --- /dev/null +++ b/app/admin/apis/bus_apis/a_contract.go @@ -0,0 +1,274 @@ +package bus_apis + +import ( + "github.com/gin-gonic/gin" + "github.com/gin-gonic/gin/binding" + "github.com/go-admin-team/go-admin-core/sdk/api" + "go-admin/app/admin/models/bus_models" + "go-admin/app/admin/service/bus_service" + "net/http" +) + +type ContractApi struct { + api.Api +} + +// CreateContract 新建合同 +// @Summary 新建合同 +// @Tags 合同管理-V1.0.0 +// @Produce json +// @Accept json +// @Param request body bus_models.CreateContractReq true "新建合同模型" +// @Success 200 {object} bus_models.CreateContractResp +// @Router /api/v1/contract/create [post] +func (e *ContractApi) CreateContract(c *gin.Context) { + s := bus_service.ContractService{} + var req bus_models.CreateContractReq + + err := e.MakeContext(c). + MakeOrm(). + Bind(&req, binding.JSON). + MakeService(&s.Service). + Errors + if err != nil { + e.Logger.Error(err) + e.Error(500, err, err.Error()) + return + } + + resp, err := s.CreateContract(c, req) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + + c.JSON(http.StatusOK, gin.H{"message": "新增成功", "data": resp}) +} + +// EditContract 编辑合同信息 +// @Summary 编辑合同信息 +// @Tags 合同管理 +// @Produce json +// @Accept json +// @Param request body bus_models.EditContractReq true "编辑合同信息" +// @Success 200 {object} map[string]interface{} "成功返回" +// @Failure 400 {object} map[string]interface{} "请求参数错误" +// @Failure 500 {object} map[string]interface{} "服务器错误" +// @Router /api/v1/contract/edit [post] +func (e *ContractApi) EditContract(c *gin.Context) { + s := bus_service.ContractService{} + var req bus_models.EditContractReq + + err := e.MakeContext(c). + MakeOrm(). + Bind(&req, binding.JSON). + MakeService(&s.Service). + Errors + if err != nil { + e.Logger.Error(err) + e.Error(500, err, err.Error()) + return + } + + // 调用服务层逻辑 + err = s.EditContract(req) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + + // 返回成功响应 + c.JSON(http.StatusOK, gin.H{"message": "合同信息更新成功"}) +} + +// ContractList 获取合同列表 +// @Summary 获取合同列表 +// @Tags 合同管理-V1.0.0 +// @Produce json +// @Accept json +// @Param request body bus_models.ListContractReq true "合同列表请求参数" +// @Success 200 {object} bus_models.ListContractResp +// @Router /api/v1/contract/list [post] +func (e *ContractApi) ContractList(c *gin.Context) { + s := bus_service.ContractService{} + var req bus_models.ListContractReq + + err := e.MakeContext(c). + MakeOrm(). + Bind(&req, binding.JSON). + MakeService(&s.Service). + Errors + if err != nil { + e.Logger.Error(err) + e.Error(500, err, err.Error()) + return + } + + resp, err := s.ListContracts(req) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + + c.JSON(http.StatusOK, gin.H{"data": resp}) +} + +// ContractDetail 获取合同详情 +// @Summary 获取合同详情 +// @Tags 合同管理-V1.0.0 +// @Produce json +// @Accept json +// @Param request body bus_models.ContractDetailReq true "合同详情请求参数" +// @Success 200 {object} bus_models.ContractDetailResp +// @Router /api/v1/contract/detail [post] +func (e *ContractApi) ContractDetail(c *gin.Context) { + s := bus_service.ContractService{} + var req bus_models.ContractDetailReq + + err := e.MakeContext(c). + MakeOrm(). + Bind(&req, binding.JSON). + MakeService(&s.Service). + Errors + if err != nil { + e.Logger.Error(err) + e.Error(500, err, err.Error()) + return + } + + resp, err := s.GetContractDetail(req) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + + c.JSON(http.StatusOK, gin.H{"data": resp}) +} + +// EditContractRemark 编辑合同备注 +// @Summary 编辑合同备注 +// @Tags 合同管理-V1.0.0 +// @Produce json +// @Accept json +// @Param request body bus_models.EditContractRemarkReq true "编辑合同备注请求参数" +// @Success 200 {string} string "备注更新成功" +// @Router /api/v1/contract/remark/edit [post] +func (e *ContractApi) EditContractRemark(c *gin.Context) { + s := bus_service.ContractService{} + var req bus_models.EditContractRemarkReq + + err := e.MakeContext(c). + MakeOrm(). + Bind(&req, binding.JSON). + MakeService(&s.Service). + Errors + if err != nil { + e.Logger.Error(err) + e.Error(500, err, err.Error()) + return + } + + if err := s.UpdateContractRemark(req); err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + + c.JSON(http.StatusOK, gin.H{"message": "备注更新成功"}) +} + +// InvalidContract 作废合同 +// @Summary 作废合同 +// @Tags 合同管理-V1.0.0 +// @Produce json +// @Accept json +// @Param request body bus_models.InvalidContractReq true "作废合同请求参数" +// @Success 200 {string} string "合同已作废" +// @Router /api/v1/contract/invalid [post] +func (e *ContractApi) InvalidContract(c *gin.Context) { + s := bus_service.ContractService{} + var req bus_models.InvalidContractReq + + err := e.MakeContext(c). + MakeOrm(). + Bind(&req, binding.JSON). + MakeService(&s.Service). + Errors + if err != nil { + e.Logger.Error(err) + e.Error(500, err, err.Error()) + return + } + if err := s.InvalidateContract(req); err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + + c.JSON(http.StatusOK, gin.H{"message": "合同已作废"}) +} + +// DeleteContract 删除合同 +// @Summary 删除合同 +// @Tags 合同管理-V1.0.0 +// @Produce json +// @Accept json +// @Param request body bus_models.DeleteContractReq true "删除合同请求参数" +// @Success 200 {string} string "合同已删除" +// @Router /api/v1/contract/delete [post] +func (e *ContractApi) DeleteContract(c *gin.Context) { + s := bus_service.ContractService{} + var req bus_models.DeleteContractReq + + err := e.MakeContext(c). + MakeOrm(). + Bind(&req, binding.JSON). + MakeService(&s.Service). + Errors + if err != nil { + e.Logger.Error(err) + e.Error(500, err, err.Error()) + return + } + + if err = s.RemoveContract(req); err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + + c.JSON(http.StatusOK, gin.H{"message": "合同已删除"}) +} + +// GetContractDownloadLink 获取合同下载链接 +// @Summary 获取合同下载链接 +// @Tags 合同管理 +// @Produce json +// @Accept json +// @Param request body bus_models.GetContractDownloadLinkReq true "获取合同下载链接请求" +// @Success 200 {object} bus_models.GetContractDownloadLinkResp "返回下载链接" +// @Failure 400 {object} map[string]interface{} "请求参数错误" +// @Failure 500 {object} map[string]interface{} "服务器错误" +// @Router /api/v1/contract/download [post] +func (e *ContractApi) GetContractDownloadLink(c *gin.Context) { + s := bus_service.ContractService{} + var req bus_models.GetContractDownloadLinkReq + + err := e.MakeContext(c). + MakeOrm(). + Bind(&req, binding.JSON). + MakeService(&s.Service). + Errors + if err != nil { + e.Logger.Error(err) + e.Error(500, err, err.Error()) + return + } + + // 调用服务层逻辑 + resp, err := s.GetContractDownloadLink(req) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + + // 返回下载链接 + c.JSON(http.StatusOK, resp) +} diff --git a/app/admin/models/bus_models/m_common.go b/app/admin/models/bus_models/m_common.go new file mode 100644 index 0000000..7cc9a4e --- /dev/null +++ b/app/admin/models/bus_models/m_common.go @@ -0,0 +1,9 @@ +package bus_models + +type RspAliyunStsToken struct { + AccessKeyId string `json:"accessKeyId"` + AccessKeySecret string `json:"accessKeySecret"` + SecurityToken string `json:"SecurityToken"` + BucketName string `json:"bucketName"` + Expiration uint64 `json:"expiration"` +} diff --git a/app/admin/models/bus_models/m_contract.go b/app/admin/models/bus_models/m_contract.go new file mode 100644 index 0000000..17f319c --- /dev/null +++ b/app/admin/models/bus_models/m_contract.go @@ -0,0 +1,83 @@ +package bus_models + +import "go-admin/app/admin/models" + +type BusContract struct { + models.Model + + ContractNumber string `gorm:"type:varchar(32);not null;unique" json:"contract_number"` // 合同号 + CooperativeNumber string `gorm:"type:varchar(32);not null" json:"cooperative_number"` // 合作商编号 + CooperativeName string `gorm:"type:varchar(64);not null" json:"cooperative_name"` // 合作商名称 + Status uint8 `gorm:"type:tinyint(1);not null;default:1" json:"status"` // 状态(1: 生效中, 2: 已作废) + SignatoryAccount string `gorm:"type:varchar(32);not null" json:"signatory_account"` // 签署帐户 + Files string `gorm:"type:text" json:"files"` // 文件 + Remark string `gorm:"type:text" json:"remark"` // 备注 +} + +type CreateContractReq struct { + CooperativeNumber string `json:"cooperative_number" binding:"required"` + CooperativeName string `json:"cooperative_name" binding:"required"` + Files string `json:"files" binding:"required"` + Remark string `json:"remark"` +} + +type CreateContractResp struct { + ContractNumber string `json:"contract_number"` // 合同号 +} + +// EditContractReq 编辑合同请求结构体 +type EditContractReq struct { + ContractNumber string `json:"contract_number" binding:"required"` // 合同号(必填,用于匹配要修改的合同) + CooperativeNumber string `json:"cooperative_number"` // 合作商编号(可选) + CooperativeName string `json:"cooperative_name"` // 合作商名称(可选) + SignatoryAccount string `json:"signatory_account"` // 签署账户(可选) + Remark string `json:"remark"` // 备注(可选) +} + +// ListContractReq 获取合同列表请求 +type ListContractReq struct { + Page int `json:"page"` // 页码 + PageSize int `json:"page_size"` // 每页数量 + ContractNumber string `json:"contract_number"` // 合同号(可选) + CooperativeNumber string `json:"cooperative_number"` // 合作商编号(可选) + CooperativeName string `json:"cooperative_name"` // 合作商名称(可选) + Status uint8 `json:"status"` // 合同状态(1: 生效中, 2: 已作废,可选) +} + +type ListContractResp struct { + List []BusContract `json:"list"` + Total int `json:"total"` // 总记录数 + Page int `json:"page"` // 页码 + PageSize int `json:"page_size"` // 每页大小 +} + +type ContractDetailReq struct { + ContractNumber string `json:"contract_number" binding:"required"` // 合同号 +} + +type ContractDetailResp struct { + BusContract +} + +type EditContractRemarkReq struct { + ContractNumber string `json:"contract_number" binding:"required"` // 合同号 + Remark string `json:"remark"` +} + +type InvalidContractReq struct { + ContractNumber string `json:"contract_number" binding:"required"` // 合同号 +} + +type DeleteContractReq struct { + ContractNumber string `json:"contract_number" binding:"required"` // 合同号 +} + +// GetContractDownloadLinkReq 获取合同下载链接请求结构体 +type GetContractDownloadLinkReq struct { + ContractNumber string `json:"contract_number" binding:"required"` // 合同号(必填) +} + +// GetContractDownloadLinkResp 获取合同下载链接响应结构体 +type GetContractDownloadLinkResp struct { + DownloadURL []string `json:"download_url"` // 合同下载链接 +} diff --git a/app/admin/router/bus_common.go b/app/admin/router/bus_common.go new file mode 100644 index 0000000..fe03a3b --- /dev/null +++ b/app/admin/router/bus_common.go @@ -0,0 +1,18 @@ +package router + +import ( + "github.com/gin-gonic/gin" + jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth" + "go-admin/app/admin/apis/bus_apis" + "go-admin/common/middleware" +) + +// 需认证的路由代码 +func registerCommonManageRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) { + api := bus_apis.CommonApi{} + + common := v1.Group("/common").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole()) + { + common.POST("/aliyun/sts_token", api.AliYunStsTokenGet) // 获取oss对象存储token + } +} diff --git a/app/admin/router/bus_contract.go b/app/admin/router/bus_contract.go new file mode 100644 index 0000000..d6d92b0 --- /dev/null +++ b/app/admin/router/bus_contract.go @@ -0,0 +1,25 @@ +package router + +import ( + "github.com/gin-gonic/gin" + jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth" + "go-admin/app/admin/apis/bus_apis" + "go-admin/common/middleware" +) + +// 需认证的路由代码 +func registerContractManageRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) { + api := bus_apis.ContractApi{} + + contract := v1.Group("/contract").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole()) + { + contract.POST("/create", api.CreateContract) // 新建合同 + contract.POST("/edit", api.EditContract) // 编辑合同 + contract.POST("/list", api.ContractList) // 合同列表 + contract.POST("/detail", api.ContractDetail) // 合同详情 + contract.POST("/remark/edit", api.EditContractRemark) // 编辑合同备注 + contract.POST("/invalid", api.InvalidContract) // 作废合同 + contract.POST("/delete", api.DeleteContract) // 删除合同 + contract.POST("/download", api.GetContractDownloadLink) // 下载合同 + } +} diff --git a/app/admin/router/router.go b/app/admin/router/router.go index 65d22ca..5551a5c 100644 --- a/app/admin/router/router.go +++ b/app/admin/router/router.go @@ -39,9 +39,15 @@ func businessCheckRoleRouter(r *gin.Engine, authMiddleware *jwtauth.GinJWTMiddle f(v1, authMiddleware) } + // 通用接口 + registerCommonManageRouter(v1, authMiddleware) + // 产品管理 registerProductManageRouter(v1, authMiddleware) // 合作商管理 registerCooperativeManageRouter(v1, authMiddleware) + + // 合同管理 + registerContractManageRouter(v1, authMiddleware) } diff --git a/app/admin/service/bus_service/s_contract.go b/app/admin/service/bus_service/s_contract.go new file mode 100644 index 0000000..18957d1 --- /dev/null +++ b/app/admin/service/bus_service/s_contract.go @@ -0,0 +1,271 @@ +package bus_service + +import ( + "errors" + "fmt" + "github.com/gin-gonic/gin" + "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user" + "github.com/go-admin-team/go-admin-core/sdk/service" + "go-admin/app/admin/models/bus_models" + aliyun "go-admin/tools/ali" + "gorm.io/gorm" + "math/rand" + "strings" + "time" +) + +type ContractService struct { + service.Service +} + +// CreateContract 新建合同 +func (s *ContractService) CreateContract(c *gin.Context, req bus_models.CreateContractReq) (bus_models.CreateContractResp, error) { + var resp bus_models.CreateContractResp + contract := bus_models.BusContract{ + CooperativeNumber: req.CooperativeNumber, + CooperativeName: req.CooperativeName, + Files: req.Files, + Status: 1, + SignatoryAccount: user.GetUserName(c), + Remark: req.Remark, + } + + contractNumber, err := GenerateContractNumber(s.Orm, "CN") + if err != nil { + fmt.Println("生成合同编号失败:", err) + } else { + fmt.Println("生成的合同编号为:", contractNumber) + } + contract.ContractNumber = contractNumber + + if err := s.Orm.Create(&contract).Error; err != nil { + return resp, errors.New("创建合同失败") + } + + resp.ContractNumber = contract.ContractNumber + return resp, nil +} + +// EditContract 编辑合同信息 +func (s *ContractService) EditContract(req bus_models.EditContractReq) error { + // 查找合同是否存在 + var contract bus_models.BusContract + if err := s.Orm.Where("contract_number = ?", req.ContractNumber).First(&contract).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return errors.New("合同不存在") + } + return err + } + + // 更新字段 + updateData := map[string]interface{}{} + if req.CooperativeNumber != "" { + updateData["cooperative_number"] = req.CooperativeNumber + } + if req.CooperativeName != "" { + updateData["cooperative_name"] = req.CooperativeName + } + if req.SignatoryAccount != "" { + updateData["signatory_account"] = req.SignatoryAccount + } + if req.Remark != "" { + updateData["remark"] = req.Remark + } + + // 执行更新 + if len(updateData) > 0 { + result := s.Orm.Model(&bus_models.BusContract{}). + Where("contract_number = ?", req.ContractNumber). + Updates(updateData) + + if result.Error != nil { + return result.Error + } + if result.RowsAffected == 0 { + return errors.New("合同未更新或不存在") + } + } + + return nil +} + +// ListContracts 获取合同列表 +func (s *ContractService) ListContracts(req bus_models.ListContractReq) (bus_models.ListContractResp, error) { + page := req.Page - 1 + if page < 0 { + page = 0 + } + if req.PageSize == 0 { + req.PageSize = 10 + } + + var resp bus_models.ListContractResp + var contracts []bus_models.BusContract + var total int64 + + query := s.Orm.Model(&bus_models.BusContract{}) + + if req.ContractNumber != "" { + query = query.Where("contract_number = ?", req.ContractNumber) + } + if req.CooperativeNumber != "" { + query = query.Where("cooperative_number = ?", req.CooperativeNumber) + } + if req.Status > 0 { + query = query.Where("status = ?", req.Status) + } + + // 计算总数 + if err := query.Count(&total).Error; err != nil { + return resp, err + } + + // 分页查询 + if err := query.Offset(page * req.PageSize).Limit(req.PageSize).Find(&contracts).Error; err != nil { + return resp, err + } + + resp.List = contracts + resp.Total = len(contracts) + resp.Page = page + 1 + resp.PageSize = req.PageSize + + return resp, nil +} + +// GetContractDetail 获取合同详情 +func (s *ContractService) GetContractDetail(req bus_models.ContractDetailReq) (*bus_models.BusContract, error) { + var contract bus_models.BusContract + if err := s.Orm.Where("contract_number = ?", req.ContractNumber).First(&contract).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, errors.New("合同不存在") + } + return nil, err + } + return &contract, nil +} + +// UpdateContractRemark 编辑合同备注 +func (s *ContractService) UpdateContractRemark(req bus_models.EditContractRemarkReq) error { + result := s.Orm.Model(&bus_models.BusContract{}). + Where("contract_number = ?", req.ContractNumber). + Update("remark", req.Remark) + + if result.Error != nil { + return result.Error + } + if result.RowsAffected == 0 { + return errors.New("合同不存在") + } + return nil +} + +// InvalidateContract 作废合同 +func (s *ContractService) InvalidateContract(req bus_models.InvalidContractReq) error { + result := s.Orm.Model(&bus_models.BusContract{}). + Where("contract_number = ?", req.ContractNumber). + Update("status", 2) + + if result.Error != nil { + return result.Error + } + if result.RowsAffected == 0 { + return errors.New("合同不存在") + } + return nil +} + +// RemoveContract 删除合同 +func (s *ContractService) RemoveContract(req bus_models.DeleteContractReq) error { + // 首先检查合同状态是否是作废(status = 2) + var contract bus_models.BusContract + err := s.Orm.Where("contract_number = ?", req.ContractNumber).First(&contract).Error + if err != nil { + return err // 如果查询失败,返回错误 + } + + // 如果合同的状态是作废(status = 2),则不允许删除 + if contract.Status == 1 { + return errors.New("合同未作废,不能删除") + } + + result := s.Orm.Where("contract_number = ?", req.ContractNumber).Delete(&bus_models.BusContract{}) + + if result.Error != nil { + return result.Error // 返回删除操作中的错误 + } + + if result.RowsAffected == 0 { + return errors.New("合同不存在") // 如果没有找到任何符合条件的合同 + } + + return nil // 删除成功 +} + +// GetContractDownloadLink 获取合同的下载链接 +func (s *ContractService) GetContractDownloadLink(req bus_models.GetContractDownloadLinkReq) ( + bus_models.GetContractDownloadLinkResp, error) { + var resp bus_models.GetContractDownloadLinkResp + + // 查找合同是否存在 + var contract bus_models.BusContract + if err := s.Orm.Where("contract_number = ?", req.ContractNumber).First(&contract).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return resp, errors.New("合同不存在") + } + return resp, err + } + + // 解析 Files 字段,假设它是一个以分号分隔的文件名列表 + files := strings.Split(contract.Files, ";") + if len(files) == 0 { + return resp, errors.New("合同文件不存在") + } + + // 循环获取每个文件的预签名 URL + var downloadLinks []string + for _, file := range files { + // 调用 Aliyun OSS 的 GeneratePresignedURL 方法生成预签名 URL + downloadURL, err := aliyun.GeneratePresignedURL(file) + if err != nil { + return resp, err + } + downloadLinks = append(downloadLinks, downloadURL) + } + + // 将所有的 URL 通过分号连接起来 + resp.DownloadURL = downloadLinks + + // 返回生成的下载链接 + return resp, nil +} + +// GenerateContractNumber 生成唯一的合同编号,格式为:合同简写+日期+8位随机数 +func GenerateContractNumber(db *gorm.DB, contractPrefix string) (string, error) { + // 获取当前日期(年月日) + dateStr := time.Now().Format("20060102") // 格式为:YYYYMMDD + + // 生成一个8位随机数 + rand.Seed(time.Now().UnixNano()) // 设置随机数种子 + randomNum := rand.Int63n(100000000) // 生成一个0到99999999之间的随机数 + + // 将随机数转为固定长度的字符串,确保8位 + randomNumStr := fmt.Sprintf("%08d", randomNum) // 确保为8位,不足补零 + + // 拼接合同简写、日期和随机数 + contractNumber := fmt.Sprintf("%s%s%s", contractPrefix, dateStr, randomNumStr) + + // 检查生成的合同编号是否已存在 + var count int64 + err := db.Model(&bus_models.BusContract{}).Where("contract_number = ?", contractNumber).Count(&count).Error + if err != nil { + return "", err + } + + // 如果已存在,重新生成 + if count > 0 { + return GenerateContractNumber(db, contractPrefix) // 递归重新生成 + } + + return contractNumber, nil +} diff --git a/docs/admin/admin_docs.go b/docs/admin/admin_docs.go index 0654979..80586ad 100644 --- a/docs/admin/admin_docs.go +++ b/docs/admin/admin_docs.go @@ -86,6 +86,321 @@ const docTemplateadmin = `{ } } }, + "/api/v1/common/aliyun/sts_token": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "公共模块-V1.0.0" + ], + "summary": "获取阿里云oss对象存储token", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/bus_models.RspAliyunStsToken" + } + } + } + } + }, + "/api/v1/contract/create": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "合同管理-V1.0.0" + ], + "summary": "新建合同", + "parameters": [ + { + "description": "新建合同模型", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/bus_models.CreateContractReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/bus_models.CreateContractResp" + } + } + } + } + }, + "/api/v1/contract/delete": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "合同管理-V1.0.0" + ], + "summary": "删除合同", + "parameters": [ + { + "description": "删除合同请求参数", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/bus_models.DeleteContractReq" + } + } + ], + "responses": { + "200": { + "description": "合同已删除", + "schema": { + "type": "string" + } + } + } + } + }, + "/api/v1/contract/detail": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "合同管理-V1.0.0" + ], + "summary": "获取合同详情", + "parameters": [ + { + "description": "合同详情请求参数", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/bus_models.ContractDetailReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/bus_models.ContractDetailResp" + } + } + } + } + }, + "/api/v1/contract/download": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "合同管理" + ], + "summary": "获取合同下载链接", + "parameters": [ + { + "description": "获取合同下载链接请求", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/bus_models.GetContractDownloadLinkReq" + } + } + ], + "responses": { + "200": { + "description": "返回下载链接", + "schema": { + "$ref": "#/definitions/bus_models.GetContractDownloadLinkResp" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "500": { + "description": "服务器错误", + "schema": { + "type": "object", + "additionalProperties": true + } + } + } + } + }, + "/api/v1/contract/edit": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "合同管理" + ], + "summary": "编辑合同信息", + "parameters": [ + { + "description": "编辑合同信息", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/bus_models.EditContractReq" + } + } + ], + "responses": { + "200": { + "description": "成功返回", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "500": { + "description": "服务器错误", + "schema": { + "type": "object", + "additionalProperties": true + } + } + } + } + }, + "/api/v1/contract/invalid": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "合同管理-V1.0.0" + ], + "summary": "作废合同", + "parameters": [ + { + "description": "作废合同请求参数", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/bus_models.InvalidContractReq" + } + } + ], + "responses": { + "200": { + "description": "合同已作废", + "schema": { + "type": "string" + } + } + } + } + }, + "/api/v1/contract/list": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "合同管理-V1.0.0" + ], + "summary": "获取合同列表", + "parameters": [ + { + "description": "合同列表请求参数", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/bus_models.ListContractReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/bus_models.ListContractResp" + } + } + } + } + }, + "/api/v1/contract/remark/edit": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "合同管理-V1.0.0" + ], + "summary": "编辑合同备注", + "parameters": [ + { + "description": "编辑合同备注请求参数", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/bus_models.EditContractRemarkReq" + } + } + ], + "responses": { + "200": { + "description": "备注更新成功", + "schema": { + "type": "string" + } + } + } + } + }, "/api/v1/cooperative/adjust_account": { "post": { "consumes": [ @@ -3272,6 +3587,51 @@ const docTemplateadmin = `{ } } }, + "bus_models.BusContract": { + "type": "object", + "properties": { + "contract_number": { + "description": "合同号", + "type": "string" + }, + "cooperative_name": { + "description": "合作商名称", + "type": "string" + }, + "cooperative_number": { + "description": "合作商编号", + "type": "string" + }, + "createdAt": { + "description": "创建时间", + "type": "string" + }, + "files": { + "description": "文件", + "type": "string" + }, + "id": { + "description": "数据库记录编号", + "type": "integer" + }, + "remark": { + "description": "备注", + "type": "string" + }, + "signatory_account": { + "description": "签署帐户", + "type": "string" + }, + "status": { + "description": "状态(1: 生效中, 2: 已作废)", + "type": "integer" + }, + "updatedAt": { + "description": "更新时间", + "type": "string" + } + } + }, "bus_models.BusCooperative": { "type": "object", "properties": { @@ -3429,6 +3789,63 @@ const docTemplateadmin = `{ } } }, + "bus_models.ContractDetailReq": { + "type": "object", + "required": [ + "contract_number" + ], + "properties": { + "contract_number": { + "description": "合同号", + "type": "string" + } + } + }, + "bus_models.ContractDetailResp": { + "type": "object", + "properties": { + "contract_number": { + "description": "合同号", + "type": "string" + }, + "cooperative_name": { + "description": "合作商名称", + "type": "string" + }, + "cooperative_number": { + "description": "合作商编号", + "type": "string" + }, + "createdAt": { + "description": "创建时间", + "type": "string" + }, + "files": { + "description": "文件", + "type": "string" + }, + "id": { + "description": "数据库记录编号", + "type": "integer" + }, + "remark": { + "description": "备注", + "type": "string" + }, + "signatory_account": { + "description": "签署帐户", + "type": "string" + }, + "status": { + "description": "状态(1: 生效中, 2: 已作废)", + "type": "integer" + }, + "updatedAt": { + "description": "更新时间", + "type": "string" + } + } + }, "bus_models.CooperativeDetailReq": { "type": "object", "required": [ @@ -3565,6 +3982,37 @@ const docTemplateadmin = `{ } } }, + "bus_models.CreateContractReq": { + "type": "object", + "required": [ + "cooperative_name", + "cooperative_number", + "files" + ], + "properties": { + "cooperative_name": { + "type": "string" + }, + "cooperative_number": { + "type": "string" + }, + "files": { + "type": "string" + }, + "remark": { + "type": "string" + } + } + }, + "bus_models.CreateContractResp": { + "type": "object", + "properties": { + "contract_number": { + "description": "合同号", + "type": "string" + } + } + }, "bus_models.CreateCooperativeReq": { "type": "object", "required": [ @@ -3717,6 +4165,18 @@ const docTemplateadmin = `{ } } }, + "bus_models.DeleteContractReq": { + "type": "object", + "required": [ + "contract_number" + ], + "properties": { + "contract_number": { + "description": "合同号", + "type": "string" + } + } + }, "bus_models.DeleteCooperativeReq": { "type": "object", "properties": { @@ -3738,6 +4198,49 @@ const docTemplateadmin = `{ } } }, + "bus_models.EditContractRemarkReq": { + "type": "object", + "required": [ + "contract_number" + ], + "properties": { + "contract_number": { + "description": "合同号", + "type": "string" + }, + "remark": { + "type": "string" + } + } + }, + "bus_models.EditContractReq": { + "type": "object", + "required": [ + "contract_number" + ], + "properties": { + "contract_number": { + "description": "合同号(必填,用于匹配要修改的合同)", + "type": "string" + }, + "cooperative_name": { + "description": "合作商名称(可选)", + "type": "string" + }, + "cooperative_number": { + "description": "合作商编号(可选)", + "type": "string" + }, + "remark": { + "description": "备注(可选)", + "type": "string" + }, + "signatory_account": { + "description": "签署账户(可选)", + "type": "string" + } + } + }, "bus_models.EditCooperativeReq": { "type": "object", "properties": { @@ -3876,6 +4379,94 @@ const docTemplateadmin = `{ } } }, + "bus_models.GetContractDownloadLinkReq": { + "type": "object", + "required": [ + "contract_number" + ], + "properties": { + "contract_number": { + "description": "合同号(必填)", + "type": "string" + } + } + }, + "bus_models.GetContractDownloadLinkResp": { + "type": "object", + "properties": { + "download_url": { + "description": "合同下载链接", + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "bus_models.InvalidContractReq": { + "type": "object", + "required": [ + "contract_number" + ], + "properties": { + "contract_number": { + "description": "合同号", + "type": "string" + } + } + }, + "bus_models.ListContractReq": { + "type": "object", + "properties": { + "contract_number": { + "description": "合同号(可选)", + "type": "string" + }, + "cooperative_name": { + "description": "合作商名称(可选)", + "type": "string" + }, + "cooperative_number": { + "description": "合作商编号(可选)", + "type": "string" + }, + "page": { + "description": "页码", + "type": "integer" + }, + "page_size": { + "description": "每页数量", + "type": "integer" + }, + "status": { + "description": "合同状态(1: 生效中, 2: 已作废,可选)", + "type": "integer" + } + } + }, + "bus_models.ListContractResp": { + "type": "object", + "properties": { + "list": { + "type": "array", + "items": { + "$ref": "#/definitions/bus_models.BusContract" + } + }, + "page": { + "description": "页码", + "type": "integer" + }, + "page_size": { + "description": "每页大小", + "type": "integer" + }, + "total": { + "description": "总记录数", + "type": "integer" + } + } + }, "bus_models.ProductDetail": { "type": "object", "properties": { @@ -4064,6 +4655,26 @@ const docTemplateadmin = `{ } } }, + "bus_models.RspAliyunStsToken": { + "type": "object", + "properties": { + "SecurityToken": { + "type": "string" + }, + "accessKeyId": { + "type": "string" + }, + "accessKeySecret": { + "type": "string" + }, + "bucketName": { + "type": "string" + }, + "expiration": { + "type": "integer" + } + } + }, "bus_models.SetCooperativeStatusReq": { "type": "object", "required": [ diff --git a/docs/admin/admin_swagger.json b/docs/admin/admin_swagger.json index 5e85979..4b85e15 100644 --- a/docs/admin/admin_swagger.json +++ b/docs/admin/admin_swagger.json @@ -78,6 +78,321 @@ } } }, + "/api/v1/common/aliyun/sts_token": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "公共模块-V1.0.0" + ], + "summary": "获取阿里云oss对象存储token", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/bus_models.RspAliyunStsToken" + } + } + } + } + }, + "/api/v1/contract/create": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "合同管理-V1.0.0" + ], + "summary": "新建合同", + "parameters": [ + { + "description": "新建合同模型", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/bus_models.CreateContractReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/bus_models.CreateContractResp" + } + } + } + } + }, + "/api/v1/contract/delete": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "合同管理-V1.0.0" + ], + "summary": "删除合同", + "parameters": [ + { + "description": "删除合同请求参数", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/bus_models.DeleteContractReq" + } + } + ], + "responses": { + "200": { + "description": "合同已删除", + "schema": { + "type": "string" + } + } + } + } + }, + "/api/v1/contract/detail": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "合同管理-V1.0.0" + ], + "summary": "获取合同详情", + "parameters": [ + { + "description": "合同详情请求参数", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/bus_models.ContractDetailReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/bus_models.ContractDetailResp" + } + } + } + } + }, + "/api/v1/contract/download": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "合同管理" + ], + "summary": "获取合同下载链接", + "parameters": [ + { + "description": "获取合同下载链接请求", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/bus_models.GetContractDownloadLinkReq" + } + } + ], + "responses": { + "200": { + "description": "返回下载链接", + "schema": { + "$ref": "#/definitions/bus_models.GetContractDownloadLinkResp" + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "500": { + "description": "服务器错误", + "schema": { + "type": "object", + "additionalProperties": true + } + } + } + } + }, + "/api/v1/contract/edit": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "合同管理" + ], + "summary": "编辑合同信息", + "parameters": [ + { + "description": "编辑合同信息", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/bus_models.EditContractReq" + } + } + ], + "responses": { + "200": { + "description": "成功返回", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "请求参数错误", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "500": { + "description": "服务器错误", + "schema": { + "type": "object", + "additionalProperties": true + } + } + } + } + }, + "/api/v1/contract/invalid": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "合同管理-V1.0.0" + ], + "summary": "作废合同", + "parameters": [ + { + "description": "作废合同请求参数", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/bus_models.InvalidContractReq" + } + } + ], + "responses": { + "200": { + "description": "合同已作废", + "schema": { + "type": "string" + } + } + } + } + }, + "/api/v1/contract/list": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "合同管理-V1.0.0" + ], + "summary": "获取合同列表", + "parameters": [ + { + "description": "合同列表请求参数", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/bus_models.ListContractReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/bus_models.ListContractResp" + } + } + } + } + }, + "/api/v1/contract/remark/edit": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "合同管理-V1.0.0" + ], + "summary": "编辑合同备注", + "parameters": [ + { + "description": "编辑合同备注请求参数", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/bus_models.EditContractRemarkReq" + } + } + ], + "responses": { + "200": { + "description": "备注更新成功", + "schema": { + "type": "string" + } + } + } + } + }, "/api/v1/cooperative/adjust_account": { "post": { "consumes": [ @@ -3264,6 +3579,51 @@ } } }, + "bus_models.BusContract": { + "type": "object", + "properties": { + "contract_number": { + "description": "合同号", + "type": "string" + }, + "cooperative_name": { + "description": "合作商名称", + "type": "string" + }, + "cooperative_number": { + "description": "合作商编号", + "type": "string" + }, + "createdAt": { + "description": "创建时间", + "type": "string" + }, + "files": { + "description": "文件", + "type": "string" + }, + "id": { + "description": "数据库记录编号", + "type": "integer" + }, + "remark": { + "description": "备注", + "type": "string" + }, + "signatory_account": { + "description": "签署帐户", + "type": "string" + }, + "status": { + "description": "状态(1: 生效中, 2: 已作废)", + "type": "integer" + }, + "updatedAt": { + "description": "更新时间", + "type": "string" + } + } + }, "bus_models.BusCooperative": { "type": "object", "properties": { @@ -3421,6 +3781,63 @@ } } }, + "bus_models.ContractDetailReq": { + "type": "object", + "required": [ + "contract_number" + ], + "properties": { + "contract_number": { + "description": "合同号", + "type": "string" + } + } + }, + "bus_models.ContractDetailResp": { + "type": "object", + "properties": { + "contract_number": { + "description": "合同号", + "type": "string" + }, + "cooperative_name": { + "description": "合作商名称", + "type": "string" + }, + "cooperative_number": { + "description": "合作商编号", + "type": "string" + }, + "createdAt": { + "description": "创建时间", + "type": "string" + }, + "files": { + "description": "文件", + "type": "string" + }, + "id": { + "description": "数据库记录编号", + "type": "integer" + }, + "remark": { + "description": "备注", + "type": "string" + }, + "signatory_account": { + "description": "签署帐户", + "type": "string" + }, + "status": { + "description": "状态(1: 生效中, 2: 已作废)", + "type": "integer" + }, + "updatedAt": { + "description": "更新时间", + "type": "string" + } + } + }, "bus_models.CooperativeDetailReq": { "type": "object", "required": [ @@ -3557,6 +3974,37 @@ } } }, + "bus_models.CreateContractReq": { + "type": "object", + "required": [ + "cooperative_name", + "cooperative_number", + "files" + ], + "properties": { + "cooperative_name": { + "type": "string" + }, + "cooperative_number": { + "type": "string" + }, + "files": { + "type": "string" + }, + "remark": { + "type": "string" + } + } + }, + "bus_models.CreateContractResp": { + "type": "object", + "properties": { + "contract_number": { + "description": "合同号", + "type": "string" + } + } + }, "bus_models.CreateCooperativeReq": { "type": "object", "required": [ @@ -3709,6 +4157,18 @@ } } }, + "bus_models.DeleteContractReq": { + "type": "object", + "required": [ + "contract_number" + ], + "properties": { + "contract_number": { + "description": "合同号", + "type": "string" + } + } + }, "bus_models.DeleteCooperativeReq": { "type": "object", "properties": { @@ -3730,6 +4190,49 @@ } } }, + "bus_models.EditContractRemarkReq": { + "type": "object", + "required": [ + "contract_number" + ], + "properties": { + "contract_number": { + "description": "合同号", + "type": "string" + }, + "remark": { + "type": "string" + } + } + }, + "bus_models.EditContractReq": { + "type": "object", + "required": [ + "contract_number" + ], + "properties": { + "contract_number": { + "description": "合同号(必填,用于匹配要修改的合同)", + "type": "string" + }, + "cooperative_name": { + "description": "合作商名称(可选)", + "type": "string" + }, + "cooperative_number": { + "description": "合作商编号(可选)", + "type": "string" + }, + "remark": { + "description": "备注(可选)", + "type": "string" + }, + "signatory_account": { + "description": "签署账户(可选)", + "type": "string" + } + } + }, "bus_models.EditCooperativeReq": { "type": "object", "properties": { @@ -3868,6 +4371,94 @@ } } }, + "bus_models.GetContractDownloadLinkReq": { + "type": "object", + "required": [ + "contract_number" + ], + "properties": { + "contract_number": { + "description": "合同号(必填)", + "type": "string" + } + } + }, + "bus_models.GetContractDownloadLinkResp": { + "type": "object", + "properties": { + "download_url": { + "description": "合同下载链接", + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "bus_models.InvalidContractReq": { + "type": "object", + "required": [ + "contract_number" + ], + "properties": { + "contract_number": { + "description": "合同号", + "type": "string" + } + } + }, + "bus_models.ListContractReq": { + "type": "object", + "properties": { + "contract_number": { + "description": "合同号(可选)", + "type": "string" + }, + "cooperative_name": { + "description": "合作商名称(可选)", + "type": "string" + }, + "cooperative_number": { + "description": "合作商编号(可选)", + "type": "string" + }, + "page": { + "description": "页码", + "type": "integer" + }, + "page_size": { + "description": "每页数量", + "type": "integer" + }, + "status": { + "description": "合同状态(1: 生效中, 2: 已作废,可选)", + "type": "integer" + } + } + }, + "bus_models.ListContractResp": { + "type": "object", + "properties": { + "list": { + "type": "array", + "items": { + "$ref": "#/definitions/bus_models.BusContract" + } + }, + "page": { + "description": "页码", + "type": "integer" + }, + "page_size": { + "description": "每页大小", + "type": "integer" + }, + "total": { + "description": "总记录数", + "type": "integer" + } + } + }, "bus_models.ProductDetail": { "type": "object", "properties": { @@ -4056,6 +4647,26 @@ } } }, + "bus_models.RspAliyunStsToken": { + "type": "object", + "properties": { + "SecurityToken": { + "type": "string" + }, + "accessKeyId": { + "type": "string" + }, + "accessKeySecret": { + "type": "string" + }, + "bucketName": { + "type": "string" + }, + "expiration": { + "type": "integer" + } + } + }, "bus_models.SetCooperativeStatusReq": { "type": "object", "required": [ diff --git a/docs/admin/admin_swagger.yaml b/docs/admin/admin_swagger.yaml index bed47c8..c6f6feb 100644 --- a/docs/admin/admin_swagger.yaml +++ b/docs/admin/admin_swagger.yaml @@ -38,6 +38,39 @@ definitions: - cooperative_number - transaction_type type: object + bus_models.BusContract: + properties: + contract_number: + description: 合同号 + type: string + cooperative_name: + description: 合作商名称 + type: string + cooperative_number: + description: 合作商编号 + type: string + createdAt: + description: 创建时间 + type: string + files: + description: 文件 + type: string + id: + description: 数据库记录编号 + type: integer + remark: + description: 备注 + type: string + signatory_account: + description: 签署帐户 + type: string + status: + description: '状态(1: 生效中, 2: 已作废)' + type: integer + updatedAt: + description: 更新时间 + type: string + type: object bus_models.BusCooperative: properties: account: @@ -154,6 +187,47 @@ definitions: description: 更新时间 type: string type: object + bus_models.ContractDetailReq: + properties: + contract_number: + description: 合同号 + type: string + required: + - contract_number + type: object + bus_models.ContractDetailResp: + properties: + contract_number: + description: 合同号 + type: string + cooperative_name: + description: 合作商名称 + type: string + cooperative_number: + description: 合作商编号 + type: string + createdAt: + description: 创建时间 + type: string + files: + description: 文件 + type: string + id: + description: 数据库记录编号 + type: integer + remark: + description: 备注 + type: string + signatory_account: + description: 签署帐户 + type: string + status: + description: '状态(1: 生效中, 2: 已作废)' + type: integer + updatedAt: + description: 更新时间 + type: string + type: object bus_models.CooperativeDetailReq: properties: cooperative_number: @@ -253,6 +327,27 @@ definitions: description: 总记录数 type: integer type: object + bus_models.CreateContractReq: + properties: + cooperative_name: + type: string + cooperative_number: + type: string + files: + type: string + remark: + type: string + required: + - cooperative_name + - cooperative_number + - files + type: object + bus_models.CreateContractResp: + properties: + contract_number: + description: 合同号 + type: string + type: object bus_models.CreateCooperativeReq: properties: account: @@ -365,6 +460,14 @@ definitions: description: 新创建的产品ID type: integer type: object + bus_models.DeleteContractReq: + properties: + contract_number: + description: 合同号 + type: string + required: + - contract_number + type: object bus_models.DeleteCooperativeReq: properties: cooperative_number: @@ -379,6 +482,36 @@ definitions: required: - id type: object + bus_models.EditContractRemarkReq: + properties: + contract_number: + description: 合同号 + type: string + remark: + type: string + required: + - contract_number + type: object + bus_models.EditContractReq: + properties: + contract_number: + description: 合同号(必填,用于匹配要修改的合同) + type: string + cooperative_name: + description: 合作商名称(可选) + type: string + cooperative_number: + description: 合作商编号(可选) + type: string + remark: + description: 备注(可选) + type: string + signatory_account: + description: 签署账户(可选) + type: string + required: + - contract_number + type: object bus_models.EditCooperativeReq: properties: account: @@ -481,6 +614,67 @@ definitions: - product_code - product_name type: object + bus_models.GetContractDownloadLinkReq: + properties: + contract_number: + description: 合同号(必填) + type: string + required: + - contract_number + type: object + bus_models.GetContractDownloadLinkResp: + properties: + download_url: + description: 合同下载链接 + items: + type: string + type: array + type: object + bus_models.InvalidContractReq: + properties: + contract_number: + description: 合同号 + type: string + required: + - contract_number + type: object + bus_models.ListContractReq: + properties: + contract_number: + description: 合同号(可选) + type: string + cooperative_name: + description: 合作商名称(可选) + type: string + cooperative_number: + description: 合作商编号(可选) + type: string + page: + description: 页码 + type: integer + page_size: + description: 每页数量 + type: integer + status: + description: '合同状态(1: 生效中, 2: 已作废,可选)' + type: integer + type: object + bus_models.ListContractResp: + properties: + list: + items: + $ref: '#/definitions/bus_models.BusContract' + type: array + page: + description: 页码 + type: integer + page_size: + description: 每页大小 + type: integer + total: + description: 总记录数 + type: integer + type: object bus_models.ProductDetail: properties: discount: @@ -613,6 +807,19 @@ definitions: description: 总条数 type: integer type: object + bus_models.RspAliyunStsToken: + properties: + SecurityToken: + type: string + accessKeyId: + type: string + accessKeySecret: + type: string + bucketName: + type: string + expiration: + type: integer + type: object bus_models.SetCooperativeStatusReq: properties: cooperative_number: @@ -1737,6 +1944,209 @@ paths: summary: 获取验证码 tags: - 登陆 + /api/v1/common/aliyun/sts_token: + post: + consumes: + - application/json + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/bus_models.RspAliyunStsToken' + summary: 获取阿里云oss对象存储token + tags: + - 公共模块-V1.0.0 + /api/v1/contract/create: + post: + consumes: + - application/json + parameters: + - description: 新建合同模型 + in: body + name: request + required: true + schema: + $ref: '#/definitions/bus_models.CreateContractReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/bus_models.CreateContractResp' + summary: 新建合同 + tags: + - 合同管理-V1.0.0 + /api/v1/contract/delete: + post: + consumes: + - application/json + parameters: + - description: 删除合同请求参数 + in: body + name: request + required: true + schema: + $ref: '#/definitions/bus_models.DeleteContractReq' + produces: + - application/json + responses: + "200": + description: 合同已删除 + schema: + type: string + summary: 删除合同 + tags: + - 合同管理-V1.0.0 + /api/v1/contract/detail: + post: + consumes: + - application/json + parameters: + - description: 合同详情请求参数 + in: body + name: request + required: true + schema: + $ref: '#/definitions/bus_models.ContractDetailReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/bus_models.ContractDetailResp' + summary: 获取合同详情 + tags: + - 合同管理-V1.0.0 + /api/v1/contract/download: + post: + consumes: + - application/json + parameters: + - description: 获取合同下载链接请求 + in: body + name: request + required: true + schema: + $ref: '#/definitions/bus_models.GetContractDownloadLinkReq' + produces: + - application/json + responses: + "200": + description: 返回下载链接 + schema: + $ref: '#/definitions/bus_models.GetContractDownloadLinkResp' + "400": + description: 请求参数错误 + schema: + additionalProperties: true + type: object + "500": + description: 服务器错误 + schema: + additionalProperties: true + type: object + summary: 获取合同下载链接 + tags: + - 合同管理 + /api/v1/contract/edit: + post: + consumes: + - application/json + parameters: + - description: 编辑合同信息 + in: body + name: request + required: true + schema: + $ref: '#/definitions/bus_models.EditContractReq' + produces: + - application/json + responses: + "200": + description: 成功返回 + schema: + additionalProperties: true + type: object + "400": + description: 请求参数错误 + schema: + additionalProperties: true + type: object + "500": + description: 服务器错误 + schema: + additionalProperties: true + type: object + summary: 编辑合同信息 + tags: + - 合同管理 + /api/v1/contract/invalid: + post: + consumes: + - application/json + parameters: + - description: 作废合同请求参数 + in: body + name: request + required: true + schema: + $ref: '#/definitions/bus_models.InvalidContractReq' + produces: + - application/json + responses: + "200": + description: 合同已作废 + schema: + type: string + summary: 作废合同 + tags: + - 合同管理-V1.0.0 + /api/v1/contract/list: + post: + consumes: + - application/json + parameters: + - description: 合同列表请求参数 + in: body + name: request + required: true + schema: + $ref: '#/definitions/bus_models.ListContractReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/bus_models.ListContractResp' + summary: 获取合同列表 + tags: + - 合同管理-V1.0.0 + /api/v1/contract/remark/edit: + post: + consumes: + - application/json + parameters: + - description: 编辑合同备注请求参数 + in: body + name: request + required: true + schema: + $ref: '#/definitions/bus_models.EditContractRemarkReq' + produces: + - application/json + responses: + "200": + description: 备注更新成功 + schema: + type: string + summary: 编辑合同备注 + tags: + - 合同管理-V1.0.0 /api/v1/cooperative/adjust_account: post: consumes: diff --git a/go.mod b/go.mod index 5298fa7..f58e2f1 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,9 @@ go 1.23.0 require ( github.com/alibaba/sentinel-golang v1.0.4 github.com/alibaba/sentinel-golang/pkg/adapters/gin v0.0.0-20241224061304-f4c2c5964666 + github.com/aliyun/alibabacloud-oss-go-sdk-v2 v1.2.1 github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible + github.com/aliyun/aliyun-sts-go-sdk v0.0.0-20171106034748-98d3903a2309 github.com/bitly/go-simplejson v0.5.1 github.com/bytedance/go-tagexpr/v2 v2.9.11 github.com/casbin/casbin/v2 v2.103.0 @@ -15,7 +17,7 @@ require ( github.com/google/uuid v1.6.0 github.com/huaweicloud/huaweicloud-sdk-go-obs v3.24.9+incompatible github.com/mssola/user_agent v0.6.0 - github.com/opentracing/opentracing-go v1.2.0 + github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.21.1 github.com/qiniu/go-sdk/v7 v7.25.2 @@ -28,6 +30,7 @@ require ( github.com/swaggo/swag v1.16.4 github.com/unrolled/secure v1.17.0 golang.org/x/crypto v0.36.0 + golang.org/x/net v0.33.0 gorm.io/driver/mysql v1.5.7 gorm.io/driver/postgres v1.5.11 gorm.io/driver/sqlite v1.5.7 @@ -137,6 +140,7 @@ require ( github.com/prometheus/procfs v0.15.1 // indirect github.com/redis/go-redis/v9 v9.3.1 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/satori/go.uuid v1.2.0 // indirect github.com/shamsher31/goimgext v1.0.0 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/shopspring/decimal v1.2.0 // indirect @@ -155,12 +159,11 @@ require ( golang.org/x/arch v0.8.0 // indirect golang.org/x/image v0.13.0 // indirect golang.org/x/mod v0.17.0 // indirect - golang.org/x/net v0.33.0 // indirect golang.org/x/sync v0.12.0 // indirect golang.org/x/sys v0.31.0 // indirect golang.org/x/term v0.30.0 // indirect golang.org/x/text v0.23.0 // indirect - golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect + golang.org/x/time v0.4.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/protobuf v1.36.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/tools/ali/oss.go b/tools/ali/oss.go new file mode 100644 index 0000000..927642e --- /dev/null +++ b/tools/ali/oss.go @@ -0,0 +1,87 @@ +package aliyun + +import ( + "errors" + "github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss" + "github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials" + stsToken "github.com/aliyun/aliyun-sts-go-sdk/sts" + "github.com/go-admin-team/go-admin-core/logger" + "golang.org/x/net/context" + "os" + "time" +) + +const ( + AliyunAccessKeyID = "LTAI5t9sZ7ZhEirYKETbEhbJ" + AliyunAccessKeySecret = "mtDxepQAAhzQ7g2aQsB5Hq2339ryAI" + AliyunRoleArn = "acs:ram::1069419146450879:role/aliyunoss" + AliyunOssBucketName = "yy-telecom" + AliyunOssUrl = "https://yy-telecom.oss-cn-shenzhen.aliyuncs.com/" + AliyunOssRegion = "cn-shenzhen" + + ExpiredTime = 3600 +) + +type UploadInfo struct { + AccessKeyId string `json:"access_key_id"` + AccessKeySecret string `json:"access_key_secret"` + Expiration int64 `json:"expiration"` + SecurityToken string `json:"security_token"` + BucketName string `json:"bucket_name"` +} + +// init函数用于初始化命令行参数 +func init() { + os.Setenv("OSS_ACCESS_KEY_ID", AliyunAccessKeyID) + os.Setenv("OSS_ACCESS_KEY_SECRET", AliyunAccessKeySecret) +} + +// GenStsToken uid用来区分sts授予了哪个用户,可以传将用户uid转为string传入 +// 传入的字符串长度必须大于1 +// stsToken的默认有效时间为一小时 +func GenStsToken(uid string) (*UploadInfo, error) { + stsClient := stsToken.NewClient(AliyunAccessKeyID, AliyunAccessKeySecret, AliyunRoleArn, uid) + + resp, err := stsClient.AssumeRole(ExpiredTime) + if err != nil { + return nil, err + } + logger.Error("err:%v", err) + logger.Info("AssumeRole:resp:%v", resp) + uploadInfo := &UploadInfo{ + AccessKeyId: resp.Credentials.AccessKeyId, + AccessKeySecret: resp.Credentials.AccessKeySecret, + Expiration: resp.Credentials.Expiration.Unix(), + SecurityToken: resp.Credentials.SecurityToken, + BucketName: AliyunOssBucketName, + } + return uploadInfo, nil +} + +// GeneratePresignedURL 生成 OSS 对象的预签名 URL +func GeneratePresignedURL(objectName string) (string, error) { + if objectName == "" { + return "", errors.New("invalid parameters: object are required") + } + + // 加载默认配置并设置凭证提供者和区域 + cfg := oss.LoadDefaultConfig(). + WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()). + WithRegion(AliyunOssRegion) + + // 创建 OSS 客户端 + client := oss.NewClient(cfg) + + // 生成 GetObject 的预签名 URL + result, err := client.Presign(context.TODO(), &oss.GetObjectRequest{ + Bucket: oss.Ptr(AliyunOssBucketName), + Key: oss.Ptr(objectName), + }, + oss.PresignExpires(5*time.Minute), + ) + if err != nil { + return "", err + } + + return result.URL, nil +} diff --git a/tools/ali/oss_test.go b/tools/ali/oss_test.go new file mode 100644 index 0000000..3604337 --- /dev/null +++ b/tools/ali/oss_test.go @@ -0,0 +1,27 @@ +package aliyun + +import ( + "encoding/json" + "fmt" + "testing" +) + +func TestGenStsToken(t *testing.T) { + + uploadInfo, err := GenStsToken("21000505") + if err != nil { + fmt.Print("err:", err) + } + + uploadInfoJson, _ := json.Marshal(uploadInfo) + fmt.Print("uploadInfoJson:", string(uploadInfoJson)) +} + +func TestGeneratePresignedURL(t *testing.T) { + url, err := GeneratePresignedURL("06b374e0-0ee1-11f0-aabd-6d5e114b6880.png") + if err != nil { + fmt.Print("err:", err) + } + + fmt.Printf("request url:%v\n", url) +}