Files
zsp-project/backend/internal/service/contract_service.go
2026-06-03 20:59:39 +08:00

153 lines
3.7 KiB
Go
Executable File

package service
import (
"fmt"
"io"
"mime/multipart"
"os"
"path/filepath"
"strconv"
"time"
"github.com/rovina/zsp-backend/internal/model"
"github.com/rovina/zsp-backend/internal/repository"
)
type ContractService interface {
CreateContract(contract *model.Contract, files []model.ContractFile) error
SaveFiles(files []model.ContractFile) error
BatchSaveFiles(
basePath string,
files []*multipart.FileHeader,
) (int, error)
List(contractType string) ([]model.Contract, error)
GetByID(id uint) (*model.Contract, error)
Update(contract *model.Contract) error
UpdateWithFiles(id uint, keepFileIDs []uint, newFileModels []model.ContractFile, form map[string]string) error
Delete(id uint) error
}
type contractService struct {
repo repository.ContractRepository
}
func NewContractService(repo repository.ContractRepository) (ContractService, error) {
return &contractService{repo: repo}, nil
}
func (s *contractService) CreateContract(contract *model.Contract, files []model.ContractFile) error {
return s.repo.CreateWithFiles(contract, files)
}
func (s *contractService) SaveFiles(files []model.ContractFile) error {
return s.repo.CreateFiles(files)
}
func (s *contractService) BatchSaveFiles(
basePath string,
files []*multipart.FileHeader,
) (int, error) {
// 相对路径根目录
root := filepath.Join("./data/contract/batch", basePath)
if err := os.MkdirAll(root, os.ModePerm); err != nil {
return 0, err
}
count := 0
for _, file := range files {
filename := fmt.Sprintf("%d_%s", time.Now().UnixNano(), file.Filename)
savePath := filepath.Join(root, filename)
if err := saveUploadedFile(file, savePath); err != nil {
return count, err
}
count++
}
return count, nil
}
func (s *contractService) List(contractType string) ([]model.Contract, error) {
return s.repo.List(contractType)
}
func (s *contractService) GetByID(id uint) (*model.Contract, error) {
return s.repo.GetByID(id)
}
func (s *contractService) Update(contract *model.Contract) error {
return s.repo.Update(contract)
}
func (s *contractService) UpdateWithFiles(id uint, keepFileIDs []uint, newFileModels []model.ContractFile, form map[string]string) error {
contract, err := s.repo.GetByID(id)
if err != nil {
return err
}
// 更新合同元信息
get := func(k string) string { return form[k] }
if v := get("name"); v != "" {
contract.Name = v
}
if v := get("contractType"); v != "" {
contract.ContractType = v
}
if v := get("contractCode"); v != "" {
contract.ContractCode = v
}
if v := get("buyParty"); v != "" {
contract.BuyParty = v
}
if v := get("sellParty"); v != "" {
contract.SellParty = v
}
if v := get("commodity"); v != "" {
contract.Commodity = v
}
if v := get("count"); v != "" {
if n, e := strconv.ParseFloat(v, 64); e == nil {
contract.Count = n
}
}
if v := get("unitPrice"); v != "" {
if n, e := strconv.ParseFloat(v, 64); e == nil {
contract.UnitPrice = n
}
}
if v := get("blNumber"); v != "" {
contract.BLNumber = v
}
contract.DeliveryTime = get("deliveryTime")
contract.PickUpTime = get("pickUpTime")
contract.Packaging = get("packaging")
contract.Remarks = get("remarks")
contract.UpdateTime = time.Now()
return s.repo.UpdateWithFiles(contract, keepFileIDs, newFileModels)
}
func (s *contractService) Delete(id uint) error {
return s.repo.Delete(id)
}
func saveUploadedFile(file *multipart.FileHeader, dst string) error {
src, err := file.Open()
if err != nil {
return err
}
defer src.Close()
out, err := os.Create(dst)
if err != nil {
return err
}
defer out.Close()
_, err = io.Copy(out, src)
return err
}