package service import ( "context" "encoding/base64" "fmt" "io/ioutil" "net/http" "strconv" "time" "github.com/dubbogo/gost/log/logger" "github.com/exhibition-main/api/exhibition" "github.com/exhibition-main/internal/config" "github.com/exhibition-main/internal/model" "github.com/exhibition-main/internal/msg" "github.com/exhibition-main/internal/response" "github.com/exhibition-main/pkg/utils" "github.com/gin-gonic/gin" "github.com/gin-gonic/gin/binding" "github.com/xuri/excelize/v2" ) func RegisterList(c *gin.Context) { var recordListReq exhibition.RecordListReq if err := c.ShouldBind(&recordListReq); err != nil { logger.Errorf("RegisterRecordList ShouldBind err", err) response.ResponseQuickMsg(c, msg.Fail, msg.INVALID_PARAMS, nil) return } resp, err := GrpcExhibitionClientImpl.RegisterRecordList(context.Background(), &recordListReq) if err != nil { response.ResponseQuickMsg(c, msg.Fail, err.Error(), nil) return } response.ResponseQuickMsg(c, msg.Ok, resp.Msg, resp) return } func CheckByPhone(c *gin.Context) { var registerInfo exhibition.RegisterInfo if err := c.ShouldBind(®isterInfo); err != nil { logger.Errorf("CheckPhone ShouldBind err", err) response.ResponseQuickMsg(c, msg.Fail, msg.INVALID_PARAMS, nil) return } resp, err := GrpcExhibitionClientImpl.CheckPhone(context.Background(), ®isterInfo) if err != nil { response.ResponseQuickMsg(c, msg.Fail, err.Error(), nil) return } if resp.IsExist { img := resp.Data.IdCardBackPhoto response1, err := http.Get(img) if err != nil { fmt.Println("网络请求错误:", err) return } defer response1.Body.Close() // 读取图片数据 imageData, err := ioutil.ReadAll(response1.Body) if err != nil { fmt.Println("读取图片数据错误:", err) return } // 将图片数据转换为base64编码 base64Data := base64.StdEncoding.EncodeToString(imageData) result, err := model.OcrGetIdCard(base64Data, "back") if err != nil { response.ResponseQuickMsg(c, msg.Fail, err.Error(), nil) return } resp.Data.IdCardStartDate = result.IssueDate resp.Data.IdCardEndDate = result.ExpirationDate } response.ResponseQuickMsg(c, msg.Ok, resp.Msg, resp) return } func CheckIdCard(c *gin.Context) { var registerInfo exhibition.RegisterInfo if err := c.ShouldBind(®isterInfo); err != nil { logger.Errorf("CheckIdCard ShouldBind err", err) response.ResponseQuickMsg(c, msg.Fail, msg.INVALID_PARAMS, nil) return } resp, err := GrpcExhibitionClientImpl.CheckIdCard(context.Background(), ®isterInfo) if err != nil { response.ResponseQuickMsg(c, msg.Fail, err.Error(), nil) return } response.ResponseQuickMsg(c, msg.Ok, resp.Msg, nil) return } func SaveRegister(c *gin.Context) { var registerInfo exhibition.RegisterInfo if err := c.ShouldBind(®isterInfo); err != nil { logger.Errorf("SaveRegisterRecord ShouldBind err", err) response.ResponseQuickMsg(c, msg.Fail, msg.INVALID_PARAMS, nil) return } resp, err := GrpcExhibitionClientImpl.SaveRegisterRecord(context.Background(), ®isterInfo) if err != nil { response.ResponseQuickMsg(c, msg.Fail, err.Error(), nil) return } img := resp.Data.IdCardBackPhoto response1, err := http.Get(img) if err != nil { fmt.Println("网络请求错误:", err) return } defer response1.Body.Close() // 读取图片数据 imageData, err := ioutil.ReadAll(response1.Body) if err != nil { fmt.Println("读取图片数据错误:", err) return } // 将图片数据转换为base64编码 base64Data := base64.StdEncoding.EncodeToString(imageData) result, err := model.OcrGetIdCard(base64Data, "back") if err != nil { response.ResponseQuickMsg(c, msg.Fail, err.Error(), nil) return } resp.Data.IdCardStartDate = result.IssueDate resp.Data.IdCardEndDate = result.ExpirationDate response.ResponseQuickMsg(c, msg.Ok, resp.Msg, resp) return } // ExportRegister 导出报名信息列表 func ExportRegister(c *gin.Context) { var exportRecordReq exhibition.ExportRecordReq resp, err := GrpcExhibitionClientImpl.ExportRegisterRecord(context.Background(), &exportRecordReq) if err != nil { response.ResponseQuickMsg(c, msg.Fail, err.Error(), nil) return } if len(resp.Data) == 0 { resp.Data = []*exhibition.ExportInfo{} } columns := []string{"初评评选号", "复评评选号", "画家姓名", "性别", "手机号", "身份证号", "通讯地址", "身份证照片", "本人近照", "省份", "作品名称", "作品类型", "画作尺寸", "报名时间", "更新时间"} exportFileName := fmt.Sprintf("国展报名%s.xlsx", time.Now().Format("20060102")) filePath := fmt.Sprintf("./runtime/%s", exportFileName) data := make([]interface{}, 0) for _, v := range resp.Data { var temp []string temp = append(temp, v.PreliminaryRatingNo) temp = append(temp, v.ReRatingNo) temp = append(temp, v.ArtistName) var gender string if v.Gender == 1 { gender = "男" } else if v.Gender == 2 { gender = "女" } else { gender = " " } temp = append(temp, gender) temp = append(temp, v.PhoneNum) temp = append(temp, v.IdCard) temp = append(temp, v.Address) temp = append(temp, v.IdCardPhoto) temp = append(temp, v.ArtistPhoto) temp = append(temp, v.Province) temp = append(temp, v.ArtworkName) var artworkType string if v.ArtworkType == 1 { artworkType = "中国画" } else { artworkType = " " } temp = append(temp, artworkType) temp = append(temp, v.ArtworkSize) temp = append(temp, v.CreatedAt) temp = append(temp, v.UpdatedAt) data = append(data, &temp) } _, err = utils.ToExcelByType(columns, data, "slice", filePath) if err != nil { response.ResponseQuickMsg(c, msg.Fail, err.Error(), nil) return } //处理图片 // err = logic.DealExcelImg(filePath) // if err != nil { // response.ResponseQuickMsg(c, msg.Fail, err.Error(), nil) // return // } var httpType string if config.Data.System.Mode == "prod" { httpType = model.HttpsType } else { httpType = model.HttpType } var exportUrl string exportUrl = fmt.Sprintf("%s%s/api/static/%s", httpType, c.Request.Host, exportFileName) response.ResponseQuickMsg(c, msg.Ok, resp.Msg, map[string]string{ "exportUrl": exportUrl, }) return } func OcrBase64(c *gin.Context) { var req model.OcrQuery if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil { logger.Errorf("OcrBase64 ShouldBind err", err) response.ResponseQuickMsg(c, msg.Fail, msg.INVALID_PARAMS, nil) return } img := req.IdCardUrl response1, err := http.Get(img) if err != nil { fmt.Println("网络请求错误:", err) return } defer response1.Body.Close() // 读取图片数据 imageData, err := ioutil.ReadAll(response1.Body) if err != nil { fmt.Println("读取图片数据错误:", err) return } // 将图片数据转换为base64编码 base64Data := base64.StdEncoding.EncodeToString(imageData) fmt.Println(base64Data) side := "" if req.Side == 1 { side = "front" } else { side = "back" } result, err := model.OcrGetIdCard(base64Data, side) if err != nil { response.ResponseQuickMsg(c, msg.Fail, err.Error(), nil) return } res := model.OcrRes{} if side == "front" { res.IDNum = result.IdCard res.RealName = result.Name res.Path = result.Path res.Age = result.Age res.Birthday = result.Birthday res.Sex = result.Sex fmt.Println("身份证和名字", res.IDNum, res.RealName) res.CheckIdAndName() fmt.Println("身份证和名字", res.IDNum, res.RealName) } else { res.IssueDate = result.IssueDate res.ExpirationDate = result.ExpirationDate } response.ResponseQuickMsg(c, msg.Ok, "操作成功", res) return } func ImportRecordByExcel(c *gin.Context) { file, err := c.FormFile("file") if err != nil { logger.Errorf("获取文件失败: %v", err) response.ResponseQuickMsg(c, msg.Fail, msg.INVALID_PARAMS, nil) return } //打开Excel文件 f, err := file.Open() if err != nil { logger.Errorf("打开文件失败: %v", err) response.ResponseQuickMsg(c, msg.Fail, "文件打开失败", nil) return } defer f.Close() excelFile, err := excelize.OpenReader(f) if err != nil { logger.Errorf("读取Excel失败: %v", err) response.ResponseQuickMsg(c, msg.Fail, "Excel解析失败", nil) return } sheetName := excelFile.GetSheetName(0) if sheetName == "" { logger.Errorf("Excel文件中没有工作表") response.ResponseQuickMsg(c, msg.Fail, "Excel文件中没有工作表", nil) return } rows, err := excelFile.GetRows(sheetName) if err != nil { logger.Errorf("读取工作表失败: %v", err) response.ResponseQuickMsg(c, msg.Fail, "工作表读取失败"+err.Error(), nil) return } // 遍历行数据(跳过标题行) var records []*exhibition.RegisterInfo for i, row := range rows { if i == 0 { // 跳过标题行 continue } if len(row) < 12 { // 确保列数足够 continue } // artworkUrl := "" // if pics, err := excelFile.GetPictures(sheetName, fmt.Sprintf("K%d", i+1)); err == nil && len(pics) > 0 { // tmpFile, err := ioutil.TempFile("", fmt.Sprintf("oss_upload_%d*.jpg", i)) // if err != nil { // logger.Errorf("创建临时文件失败: %v", err) // response.ResponseQuickMsg(c, msg.Fail, "创建临时文件失败", nil) // return // } // defer os.Remove(tmpFile.Name()) // if _, err := tmpFile.Write(pics[0].File); err != nil { // logger.Errorf("写入临时文件失败: %v", err) // response.ResponseQuickMsg(c, msg.Fail, "写入临时文件失败", nil) // return // } // //objectKey := fmt.Sprintf("artwork/%s/%d.jpg", time.Now().Format("20060102"), time.Now().UnixNano()) // if url, err := common.PutBos(tmpFile.Name(), "image", false); err == nil { // artworkUrl = url // } else { // logger.Errorf("上传图片失败: %v", err) // } // } record := &exhibition.RegisterInfo{ PreliminaryRatingNo: row[0], ReRatingNo: row[1], ArtworkName: row[2], ArtworkType: 1, //中国画 ArtworkSize: row[4], Address1: row[5], ArtistName: row[6], PhoneNum: string(row[7]), Province: string(row[8]), IdCard: string(row[9]), //ArtworkFile: artworkUrl, } record.Gender = GetGenderByIdCard(record.IdCard) records = append(records, record) } for i, r := range records { recordListReq := exhibition.RecordListReq{ Keyword: r.ArtistName, } resp, err := GrpcExhibitionClientImpl.RegisterRecordList(context.Background(), &recordListReq) if err != nil { response.ResponseQuickMsg(c, msg.Fail, err.Error(), nil) return } records[i].Uuid = resp.Data[i].Uuid } for _, r := range records { _, err := GrpcExhibitionClientImpl.SaveRegisterRecord(context.Background(), r) if err != nil { response.ResponseQuickMsg(c, msg.Fail, err.Error(), nil) return } } response.ResponseQuickMsg(c, msg.Ok, "ok", "") return } // GetGenderByIdCard 根据身份证号判断性别 // 参数:idCard - 身份证号码字符串 // 返回值:1-男,2-女,0-未知 func GetGenderByIdCard(idCard string) int32 { if len(idCard) != 18 && len(idCard) != 15 { return 0 } // 18位身份证取第17位,15位身份证取最后一位 genderChar := idCard[16:17] if len(idCard) == 15 { genderChar = idCard[14:15] } genderNum, err := strconv.Atoi(genderChar) if err != nil { return 0 } if genderNum%2 == 0 { return 2 // 女 } return 1 // 男 }