483 lines
14 KiB
Go
Executable File
483 lines
14 KiB
Go
Executable File
package handler
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/rovina/zsp-backend/internal/model"
|
|
"github.com/rovina/zsp-backend/internal/service"
|
|
)
|
|
|
|
func (h *ContractHandler) List(c *gin.Context) {
|
|
contractType := c.Query("contractType")
|
|
list, err := h.service.List(contractType)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": err.Error()})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{"success": true, "data": list})
|
|
}
|
|
|
|
func (h *ContractHandler) Get(c *gin.Context) {
|
|
idStr := c.Param("id")
|
|
id, err := strconv.ParseUint(idStr, 10, 32)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "invalid id"})
|
|
return
|
|
}
|
|
contract, err := h.service.GetByID(uint(id))
|
|
if err != nil {
|
|
c.JSON(http.StatusNotFound, gin.H{"success": false, "message": "contract not found"})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{"success": true, "data": contract})
|
|
}
|
|
|
|
func (h *ContractHandler) Update(c *gin.Context) {
|
|
idStr := c.Param("id")
|
|
id, err := strconv.ParseUint(idStr, 10, 32)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "invalid id"})
|
|
return
|
|
}
|
|
existing, err := h.service.GetByID(uint(id))
|
|
if err != nil {
|
|
c.JSON(http.StatusNotFound, gin.H{"success": false, "message": "contract not found"})
|
|
return
|
|
}
|
|
var body struct {
|
|
Name string `json:"name"`
|
|
ContractType string `json:"contractType"`
|
|
ContractCode string `json:"contractCode"`
|
|
BuyParty string `json:"buyParty"`
|
|
SellParty string `json:"sellParty"`
|
|
Commodity string `json:"commodity"`
|
|
Count float64 `json:"count"`
|
|
UnitPrice float64 `json:"unitPrice"`
|
|
BLNumber string `json:"blNumber"`
|
|
DeliveryTime string `json:"deliveryTime"`
|
|
PickUpTime string `json:"pickUpTime"`
|
|
Packaging string `json:"packaging"`
|
|
Remarks string `json:"remarks"`
|
|
}
|
|
if err := c.ShouldBindJSON(&body); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": err.Error()})
|
|
return
|
|
}
|
|
existing.Name = body.Name
|
|
existing.ContractType = body.ContractType
|
|
existing.ContractCode = body.ContractCode
|
|
existing.BuyParty = body.BuyParty
|
|
existing.SellParty = body.SellParty
|
|
existing.Commodity = body.Commodity
|
|
existing.Count = body.Count
|
|
existing.UnitPrice = body.UnitPrice
|
|
existing.BLNumber = body.BLNumber
|
|
existing.DeliveryTime = body.DeliveryTime
|
|
existing.PickUpTime = body.PickUpTime
|
|
existing.Packaging = body.Packaging
|
|
existing.Remarks = body.Remarks
|
|
existing.UpdateTime = time.Now()
|
|
if err := h.service.Update(existing); err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": err.Error()})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{"success": true, "message": "updated"})
|
|
}
|
|
|
|
func (h *ContractHandler) UpdateWithFiles(c *gin.Context) {
|
|
idStr := c.Param("id")
|
|
id, err := strconv.ParseUint(idStr, 10, 32)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "invalid id"})
|
|
return
|
|
}
|
|
|
|
form, err := c.MultipartForm()
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": err.Error()})
|
|
return
|
|
}
|
|
|
|
formMap := make(map[string]string)
|
|
for k, v := range form.Value {
|
|
if len(v) > 0 {
|
|
formMap[k] = v[0]
|
|
}
|
|
}
|
|
|
|
keepFileIds := parseUintSlice(formMap["keepFileIds"])
|
|
newFileHeaders := form.File["files"]
|
|
|
|
if len(keepFileIds) == 0 && len(newFileHeaders) == 0 {
|
|
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "至少需要保留一个合同扫描件"})
|
|
return
|
|
}
|
|
|
|
var newFileModels []model.ContractFile
|
|
path := "./data/contract/uploads"
|
|
os.MkdirAll(path, os.ModePerm)
|
|
|
|
for _, fh := range newFileHeaders {
|
|
filename := fmt.Sprintf("%d_%s", time.Now().UnixNano(), fh.Filename)
|
|
savePath := filepath.Join(path, filename)
|
|
if err := c.SaveUploadedFile(fh, savePath); err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": err.Error()})
|
|
return
|
|
}
|
|
newFileModels = append(newFileModels, model.ContractFile{
|
|
Name: fh.Filename,
|
|
URL: "uploads/" + filename,
|
|
})
|
|
}
|
|
|
|
if len(keepFileIds)+len(newFileModels) == 0 {
|
|
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "至少需要保留一个合同扫描件"})
|
|
return
|
|
}
|
|
|
|
if err := h.service.UpdateWithFiles(uint(id), keepFileIds, newFileModels, formMap); err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": err.Error()})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{"success": true, "message": "updated"})
|
|
}
|
|
|
|
func parseUintSlice(s string) []uint {
|
|
if s == "" {
|
|
return nil
|
|
}
|
|
parts := strings.Split(s, ",")
|
|
var result []uint
|
|
for _, p := range parts {
|
|
p = strings.TrimSpace(p)
|
|
if p == "" {
|
|
continue
|
|
}
|
|
if v, err := strconv.ParseUint(p, 10, 32); err == nil {
|
|
result = append(result, uint(v))
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
func (h *ContractHandler) Delete(c *gin.Context) {
|
|
idStr := c.Param("id")
|
|
id, err := strconv.ParseUint(idStr, 10, 32)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "invalid id"})
|
|
return
|
|
}
|
|
if err := h.service.Delete(uint(id)); err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": err.Error()})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{"success": true, "message": "deleted"})
|
|
}
|
|
|
|
type ContractHandler struct {
|
|
service service.ContractService
|
|
folderService service.ContractFolderService
|
|
batchService service.ContractBatchService
|
|
}
|
|
|
|
func NewContractHandler(
|
|
service service.ContractService,
|
|
folderService service.ContractFolderService,
|
|
batchService service.ContractBatchService,
|
|
) *ContractHandler {
|
|
return &ContractHandler{
|
|
service: service,
|
|
folderService: folderService,
|
|
batchService: batchService,
|
|
}
|
|
}
|
|
|
|
func (h *ContractHandler) Upload(c *gin.Context) {
|
|
|
|
var contract model.Contract
|
|
|
|
contract.Name = c.PostForm("name")
|
|
contract.ContractType = c.PostForm("contractType")
|
|
contract.ContractCode = c.PostForm("contractCode")
|
|
contract.BuyParty = c.PostForm("buyParty")
|
|
contract.SellParty = c.PostForm("sellParty")
|
|
contract.Commodity = c.PostForm("commodity")
|
|
contract.BLNumber = c.PostForm("BLNumber")
|
|
contract.DeliveryTime = c.PostForm("deliveryTime")
|
|
contract.PickUpTime = c.PostForm("pickUpTime")
|
|
contract.Packaging = c.PostForm("packaging")
|
|
contract.Remarks = c.PostForm("remarks")
|
|
|
|
if countStr := c.PostForm("count"); countStr != "" {
|
|
if v, err := strconv.ParseFloat(countStr, 64); err == nil {
|
|
contract.Count = v
|
|
}
|
|
}
|
|
if priceStr := c.PostForm("unitPrice"); priceStr != "" {
|
|
if v, err := strconv.ParseFloat(priceStr, 64); err == nil {
|
|
contract.UnitPrice = v
|
|
}
|
|
}
|
|
|
|
contract.CreateTime = time.Now()
|
|
contract.UpdateTime = time.Now()
|
|
|
|
form, err := c.MultipartForm()
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": err.Error()})
|
|
return
|
|
}
|
|
|
|
files := form.File["files"]
|
|
|
|
if len(files) == 0 {
|
|
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "no files"})
|
|
return
|
|
}
|
|
path := "./data/contract/uploads"
|
|
os.MkdirAll(path, os.ModePerm)
|
|
|
|
var fileModels []model.ContractFile
|
|
|
|
for _, file := range files {
|
|
|
|
filename := fmt.Sprintf("%d_%s", time.Now().UnixNano(), file.Filename)
|
|
savePath := filepath.Join(path, filename)
|
|
|
|
if err := c.SaveUploadedFile(file, savePath); err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": err.Error()})
|
|
return
|
|
}
|
|
|
|
fileModels = append(fileModels, model.ContractFile{
|
|
Name: file.Filename,
|
|
URL: "uploads/" + filename,
|
|
})
|
|
}
|
|
|
|
if err := h.service.CreateContract(&contract, fileModels); err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"success": true,
|
|
"message": "upload success",
|
|
})
|
|
}
|
|
|
|
func (h *ContractHandler) BatchUpload(c *gin.Context) {
|
|
path := c.PostForm("path")
|
|
if path == "" {
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "path required"})
|
|
return
|
|
}
|
|
|
|
form, err := c.MultipartForm()
|
|
if err != nil {
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid form"})
|
|
return
|
|
}
|
|
|
|
files := form.File["files"]
|
|
if len(files) == 0 {
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "no files"})
|
|
return
|
|
}
|
|
|
|
saved, err := h.service.BatchSaveFiles(path, files)
|
|
if err != nil {
|
|
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"success": true,
|
|
"count": saved,
|
|
})
|
|
}
|
|
|
|
// ========== 批量归档文件夹 ==========
|
|
|
|
func (h *ContractHandler) ListFolders(c *gin.Context) {
|
|
list, err := h.folderService.List()
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": err.Error()})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{"success": true, "data": list})
|
|
}
|
|
|
|
func (h *ContractHandler) CreateFolder(c *gin.Context) {
|
|
var body struct {
|
|
Name string `json:"name" binding:"required"`
|
|
Description string `json:"description"`
|
|
}
|
|
if err := c.ShouldBindJSON(&body); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": err.Error()})
|
|
return
|
|
}
|
|
f, err := h.folderService.Create(body.Name, body.Description)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": err.Error()})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{"success": true, "data": f})
|
|
}
|
|
|
|
func (h *ContractHandler) GetFolder(c *gin.Context) {
|
|
idStr := c.Param("id")
|
|
id, err := strconv.ParseUint(idStr, 10, 32)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "invalid id"})
|
|
return
|
|
}
|
|
f, err := h.folderService.GetByID(uint(id))
|
|
if err != nil {
|
|
c.JSON(http.StatusNotFound, gin.H{"success": false, "message": "not found"})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{"success": true, "data": f})
|
|
}
|
|
|
|
func (h *ContractHandler) UpdateFolder(c *gin.Context) {
|
|
idStr := c.Param("id")
|
|
id, err := strconv.ParseUint(idStr, 10, 32)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "invalid id"})
|
|
return
|
|
}
|
|
var body struct {
|
|
Name string `json:"name" binding:"required"`
|
|
Description string `json:"description"`
|
|
}
|
|
if err := c.ShouldBindJSON(&body); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": err.Error()})
|
|
return
|
|
}
|
|
if err := h.folderService.Update(uint(id), body.Name, body.Description); err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": err.Error()})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{"success": true, "message": "updated"})
|
|
}
|
|
|
|
func (h *ContractHandler) DeleteFolder(c *gin.Context) {
|
|
idStr := c.Param("id")
|
|
id, err := strconv.ParseUint(idStr, 10, 32)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "invalid id"})
|
|
return
|
|
}
|
|
if err := h.folderService.Delete(uint(id)); err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": err.Error()})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{"success": true, "message": "deleted"})
|
|
}
|
|
|
|
// ========== 批量上传记录 ==========
|
|
|
|
func (h *ContractHandler) ListBatches(c *gin.Context) {
|
|
var folderID *uint
|
|
if idStr := c.Query("folderId"); idStr != "" {
|
|
if id, err := strconv.ParseUint(idStr, 10, 32); err == nil {
|
|
uid := uint(id)
|
|
folderID = &uid
|
|
}
|
|
}
|
|
list, err := h.batchService.List(folderID)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": err.Error()})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{"success": true, "data": list})
|
|
}
|
|
|
|
func (h *ContractHandler) CreateBatch(c *gin.Context) {
|
|
folderIDStr := c.PostForm("folderId")
|
|
batchName := c.PostForm("batchName")
|
|
remark := c.PostForm("remark")
|
|
if folderIDStr == "" || batchName == "" {
|
|
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "folderId and batchName required"})
|
|
return
|
|
}
|
|
folderID, err := strconv.ParseUint(folderIDStr, 10, 32)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "invalid folderId"})
|
|
return
|
|
}
|
|
form, err := c.MultipartForm()
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": err.Error()})
|
|
return
|
|
}
|
|
files := form.File["files"]
|
|
if len(files) == 0 {
|
|
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "no files"})
|
|
return
|
|
}
|
|
path := "./data/contract/batch_archive"
|
|
os.MkdirAll(path, os.ModePerm)
|
|
var fileModels []model.ContractBatchFile
|
|
for _, file := range files {
|
|
filename := fmt.Sprintf("%d_%s", time.Now().UnixNano(), file.Filename)
|
|
savePath := filepath.Join(path, filename)
|
|
if err := c.SaveUploadedFile(file, savePath); err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": err.Error()})
|
|
return
|
|
}
|
|
fileModels = append(fileModels, model.ContractBatchFile{
|
|
Name: file.Filename,
|
|
URL: "batch_archive/" + filename,
|
|
FileSize: file.Size,
|
|
})
|
|
}
|
|
b, err := h.batchService.Create(uint(folderID), batchName, remark, fileModels)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": err.Error()})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{"success": true, "data": b, "message": "created"})
|
|
}
|
|
|
|
func (h *ContractHandler) GetBatch(c *gin.Context) {
|
|
idStr := c.Param("id")
|
|
id, err := strconv.ParseUint(idStr, 10, 32)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "invalid id"})
|
|
return
|
|
}
|
|
b, err := h.batchService.GetByID(uint(id))
|
|
if err != nil {
|
|
c.JSON(http.StatusNotFound, gin.H{"success": false, "message": "not found"})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{"success": true, "data": b})
|
|
}
|
|
|
|
func (h *ContractHandler) DeleteBatch(c *gin.Context) {
|
|
idStr := c.Param("id")
|
|
id, err := strconv.ParseUint(idStr, 10, 32)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "invalid id"})
|
|
return
|
|
}
|
|
if err := h.batchService.Delete(uint(id)); err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": err.Error()})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{"success": true, "message": "deleted"})
|
|
}
|