good-news/main.go

259 lines
6.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package main
import (
"fmt"
"net/http"
"os"
"path/filepath"
"strings"
"github.com/gin-gonic/gin"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
"github.com/google/uuid"
"goodnews/models"
"goodnews/services"
)
// 全局数据库连接
var db *gorm.DB
func main() {
// 初始化数据库
var err error
db, err = gorm.Open(sqlite.Open("goodnews.db"), &gorm.Config{})
if err != nil {
panic("failed to connect database")
}
// 自动迁移数据库
db.AutoMigrate(&models.GoodNews{})
// 初始化Gin路由
r := gin.Default()
// 设置静态文件服务
r.Static("/uploads", "./uploads")
// 设置页面路由
r.StaticFile("/", "./templates/index.html")
r.StaticFile("/manage", "./templates/manage.html")
// API路由组
api := r.Group("/api")
{
api.GET("/news", getGoodNewsList)
api.PUT("/news/:id", updateGoodNews)
api.DELETE("/news/:id", deleteGoodNews)
api.POST("/upload", handleUploadAndCreate)
api.GET("/offices", getOfficesList)
}
// 启动服务
r.Run(":8080")
}
// 获取喜报列表
func getGoodNewsList(c *gin.Context) {
var goodNewsList []models.GoodNews
result := db.Find(&goodNewsList)
if result.Error != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": result.Error.Error()})
return
}
// 处理每条记录添加图片URL并设置Office字段
for i := range goodNewsList {
// 将ImagePath转换为可访问的URL
goodNewsList[i].ImageURL = "/" + goodNewsList[i].ImagePath
// 确保Office字段与Representative字段一致
goodNewsList[i].Office = goodNewsList[i].Representative
}
c.JSON(http.StatusOK, goodNewsList)
}
// 获取代表处列表
func getOfficesList(c *gin.Context) {
var offices []string
result := db.Model(&models.GoodNews{}).Distinct().Pluck("representative", &offices)
if result.Error != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": result.Error.Error()})
return
}
c.JSON(http.StatusOK, offices)
}
// 处理文件上传并创建喜报
func handleUploadAndCreate(c *gin.Context) {
// 获取上传的图片
file, err := c.FormFile("file")
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "请选择要上传的图片文件"})
return
}
// 验证文件类型
ext := filepath.Ext(file.Filename)
allowedExts := map[string]bool{".jpg": true, ".jpeg": true, ".png": true}
if !allowedExts[strings.ToLower(ext)] {
c.JSON(http.StatusBadRequest, gin.H{"error": "只支持jpg、jpeg和png格式的图片"})
return
}
// 验证文件大小限制为10MB
if file.Size > 10<<20 { // 10 MB
c.JSON(http.StatusBadRequest, gin.H{"error": "图片大小不能超过10MB"})
return
}
// 生成唯一的文件名
newFileName := uuid.New().String() + ext
uploadDir := filepath.Join(".", "uploads")
filePath := filepath.Join(uploadDir, newFileName)
// 确保上传目录存在
if err := os.MkdirAll(uploadDir, 0755); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("创建上传目录失败: %v", err)})
return
}
// 保存图片
if err := c.SaveUploadedFile(file, filePath); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("图片保存失败: %v", err)})
return
}
// 创建OCR服务
ocrService, err := services.NewOCRService()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "OCR服务初始化失败"})
return
}
defer ocrService.Close()
// 提取图片信息
projectName, points, representative, err := ocrService.ExtractInfo(filePath)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("图片识别失败: %v", err)})
return
}
fmt.Println("OCR识别信息:", projectName, points, representative)
// 创建喜报记录
goodNews := models.GoodNews{
ProjectName: projectName,
Points: points,
Representative: representative,
ImagePath: filePath,
}
result := db.Create(&goodNews)
if result.Error != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": result.Error.Error()})
return
}
// 重新获取记录以确保包含ID
db.First(&goodNews, goodNews.ID)
goodNews.ImageURL = "/" + goodNews.ImagePath
c.JSON(http.StatusOK, goodNews)
}
// 更新喜报
func updateGoodNews(c *gin.Context) {
var goodNews models.GoodNews
if err := db.First(&goodNews, c.Param("id")).Error; err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "记录不存在"})
return
}
if err := c.ShouldBindJSON(&goodNews); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
db.Save(&goodNews)
c.JSON(http.StatusOK, goodNews)
}
// 删除喜报
func deleteGoodNews(c *gin.Context) {
var goodNews models.GoodNews
if err := db.First(&goodNews, c.Param("id")).Error; err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "记录不存在"})
return
}
db.Delete(&goodNews)
c.JSON(http.StatusOK, gin.H{"message": "删除成功"})
}
// 处理文件上传
func handleFileUpload(c *gin.Context) {
// 获取上传的文件
file, err := c.FormFile("file")
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "请选择要上传的文件"})
return
}
// 验证文件类型
ext := filepath.Ext(file.Filename)
allowedExts := map[string]bool{".jpg": true, ".jpeg": true, ".png": true}
if !allowedExts[strings.ToLower(ext)] {
c.JSON(http.StatusBadRequest, gin.H{"error": "只支持jpg、jpeg和png格式的图片"})
return
}
// 生成唯一的文件名
newFileName := uuid.New().String() + ext
uploadDir := filepath.Join(".", "uploads")
filePath := filepath.Join(uploadDir, newFileName)
// 确保上传目录存在
if err := os.MkdirAll(uploadDir, 0755); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("创建上传目录失败: %v", err)})
return
}
// 保存图片
if err := c.SaveUploadedFile(file, filePath); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("图片保存失败: %v", err)})
return
}
// 创建OCR服务
ocrService, err := services.NewOCRService()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "OCR服务初始化失败"})
return
}
defer ocrService.Close()
// 提取图片信息
projectName, points, representative, err := ocrService.ExtractInfo(filePath)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("图片识别失败: %v", err)})
return
}
// 创建喜报记录
goodNews := models.GoodNews{
ProjectName: projectName,
Points: points,
Representative: representative,
ImagePath: filePath,
}
result := db.Create(&goodNews)
if result.Error != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": result.Error.Error()})
return
}
// 重新获取记录以确保包含ID
db.First(&goodNews, goodNews.ID)
goodNews.ImageURL = "/" + goodNews.ImagePath
c.JSON(http.StatusOK, goodNews)
}