123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422 |
- package backend
- import (
- "context"
- "fmt"
- "kpt-pasture/config"
- "kpt-pasture/model"
- "kpt-pasture/util"
- "mime/multipart"
- "os"
- "path/filepath"
- "reflect"
- "strconv"
- "strings"
- "time"
- "gorm.io/gorm"
- pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
- "gitee.com/xuyiping_admin/pkg/xerr"
- )
- func (s *StoreEntry) Photos(ctx context.Context, files []*multipart.FileHeader) ([]string, error) {
- userModel, err := s.GetUserModel(ctx)
- if err != nil {
- return nil, err
- }
- workDir := fmt.Sprintf("%s", config.WorkDir)
- pathDir := fmt.Sprintf("/files/photos/%d/%s", userModel.AppPasture.Id, time.Now().Local().Format("20060102"))
- saveDir := filepath.Join(workDir, pathDir)
- if _, err = os.Stat(saveDir); os.IsNotExist(err) {
- if err = os.MkdirAll(saveDir, 0755); err != nil {
- return nil, xerr.Customf("创建目录失败: %s", err.Error())
- }
- }
- // 处理每个文件
- filePaths := make([]string, len(files))
- for i, file := range files {
- contentType := file.Header.Get("Content-Type")
- if contentType != "image/jpeg" && contentType != "image/png" && contentType != "image/gif" {
- return nil, xerr.Customf("图片格式错误: %s", file.Filename)
- }
- if file.Size > 1024*1024*5 {
- return nil, xerr.Customf("单个图片文件不能超过5MB")
- }
- ext := filepath.Ext(file.Filename)
- if ext == "" {
- switch contentType {
- case "image/jpeg":
- ext = ".jpg"
- case "image/png":
- ext = ".png"
- case "image/gif":
- ext = ".gif"
- default:
- ext = ".jpg" // 默认
- }
- }
- randomName := util.GenerateRandomNumberString(32)
- finalFilename := randomName + ext
- fPath := filepath.Join(saveDir, finalFilename)
- urlPath := filepath.Join(pathDir, finalFilename)
- if err = util.SaveUploadedFile(file, fPath); err != nil {
- return nil, xerr.Customf("保存文件失败: %s", err.Error())
- }
- filePaths[i] = urlPath
- }
- return filePaths, nil
- }
- func (s *StoreEntry) ImportExcel(ctx context.Context, data [][]string) error {
- // 获取当前用户信息
- userModel, err := s.GetUserModel(ctx)
- if err != nil {
- return err
- }
- penMap := s.PenMap2(ctx, userModel.AppPasture.Id)
- if userModel.AppPasture.Id <= 0 {
- return xerr.Custom("无效的牧场ID")
- }
- // 处理Excel数据
- //headers := data[0]
- eventEnterList := make([]*pasturePb.EventEnterRequest, 0)
- for _, row := range data[1:] {
- if len(row) <= 0 {
- continue
- }
- ts := &pasturePb.EventEnterRequest{
- OperationId: 33,
- OperationName: "kpt_admin",
- MessengerId: 33,
- MessengerName: "kpt_admin",
- }
- for j, d := range row {
- switch j {
- case 0:
- continue
- case 1:
- continue
- case 2:
- ts.EarNumber = d
- case 3:
- if pn, ok := penMap[d]; ok {
- ts.PenId = pn.Id
- ts.PenName = d
- }
- case 4:
- ts.Sex = pasturePb.Genders_Female
- if d == "公" {
- ts.Sex = pasturePb.Genders_Male
- }
- case 5:
- if d == "成母牛" {
- ts.CowType = pasturePb.CowType_Breeding_Calf
- } else if d == "犊牛" {
- ts.CowType = pasturePb.CowType_Lactating_Calf
- } else if d == "青年牛" {
- ts.CowType = pasturePb.CowType_Youth_Calf
- } else if d == "育成牛" {
- ts.CowType = pasturePb.CowType_Reserve_Calf
- }
- case 6:
- continue
- case 7:
- bat, _ := util.TimeParseLocal(model.LayoutTime2, d)
- if !bat.IsZero() {
- ts.BirthAt = int32(bat.Local().Unix())
- }
- case 8:
- lact, _ := strconv.Atoi(d)
- ts.Lact = int32(lact)
- case 9:
- eat, _ := util.TimeParseLocal(model.LayoutTime2, d)
- if !eat.IsZero() {
- ts.EnterAt = int32(eat.Local().Unix())
- }
- case 10:
- ts.FatherNumber = d
- case 11:
- ts.MotherNumber = d
- case 12:
- mat, _ := util.TimeParseLocal(model.LayoutTime2, d)
- if !mat.IsZero() {
- ts.MatingAt = int32(mat.Local().Unix())
- }
- case 13:
- continue
- case 14:
- continue
- case 15:
- mt, _ := strconv.Atoi(d)
- ts.MatingTimes = int32(mt)
- case 16:
- continue
- case 17:
- pat, _ := util.TimeParseLocal(model.LayoutTime2, d)
- if !pat.IsZero() {
- ts.PregnancyCheckAt = int32(pat.Local().Unix())
- }
- case 18:
- continue
- case 19:
- continue
- case 20:
- cat, _ := util.TimeParseLocal(model.LayoutTime2, d)
- if !cat.IsZero() {
- ts.CalvingAt = int32(cat.Local().Unix())
- }
- case 21:
- continue
- case 22:
- continue
- case 23:
- continue
- case 24:
- ts.CowKind = pasturePb.CowKind_AGSN
- }
- }
- eventEnterList = append(eventEnterList, ts)
- }
- if len(eventEnterList) <= 0 {
- return nil
- }
- pastureId := userModel.AppPasture.Id
- if pastureId != 4 {
- pastureId = 4
- }
- return s.ExecExcelData(ctx, pastureId, eventEnterList)
- }
- func (s *StoreEntry) ImportExcel2(ctx context.Context, data [][]string, excelHeader []string) error {
- // 获取当前用户信息
- userModel, err := s.GetUserModel(ctx)
- if err != nil {
- return err
- }
- penMap := s.PenMap2(ctx, userModel.AppPasture.Id)
- if userModel.AppPasture.Id <= 0 {
- return xerr.Custom("无效的牧场ID")
- }
- // 处理Excel数据
- //headers := data[0]
- eventEnterList := make([]*pasturePb.EventEnterRequest, 0)
- /*for _, row := range data[1:] {
- if len(row) <= 0 {
- continue
- }
- ts := &pasturePb.EventEnterRequest{
- OperationId: int32(userModel.SystemUser.Id),
- OperationName: userModel.SystemUser.Name,
- MessengerId: int32(userModel.SystemUser.Id),
- MessengerName: userModel.SystemUser.Name,
- }
- for j, d := range row {
- switch j {
- case 0:
- continue
- case 1:
- continue
- case 2:
- ts.EarNumber = d
- case 3:
- if pn, ok := penMap[d]; ok {
- ts.PenId = pn.Id
- ts.PenName = pn.Name
- }
- case 4:
- ts.Sex = pasturePb.Genders_Female
- if d == "公" {
- ts.Sex = pasturePb.Genders_Male
- }
- case 5:
- if d == "成母牛" {
- ts.CowType = pasturePb.CowType_Breeding_Calf
- } else if d == "犊牛" {
- ts.CowType = pasturePb.CowType_Lactating_Calf
- } else if d == "青年牛" {
- ts.CowType = pasturePb.CowType_Youth_Calf
- } else if d == "育成牛" {
- ts.CowType = pasturePb.CowType_Reserve_Calf
- }
- case 6:
- continue
- case 7:
- bat, _ := util.TimeParseLocal(model.LayoutTime2, d)
- if !bat.IsZero() {
- ts.BirthAt = int32(bat.Local().Unix())
- }
- case 8:
- lact, _ := strconv.Atoi(d)
- ts.Lact = int32(lact)
- case 9:
- eat, _ := util.TimeParseLocal(model.LayoutTime2, d)
- if !eat.IsZero() {
- ts.EnterAt = int32(eat.Local().Unix())
- }
- case 10:
- ts.FatherNumber = d
- case 11:
- ts.MotherNumber = d
- case 12:
- mat, _ := util.TimeParseLocal(model.LayoutTime2, d)
- if !mat.IsZero() {
- ts.MatingAt = int32(mat.Local().Unix())
- }
- case 13:
- continue
- case 14:
- continue
- case 15:
- mt, _ := strconv.Atoi(d)
- ts.MatingTimes = int32(mt)
- case 16:
- continue
- case 17:
- pat, _ := util.TimeParseLocal(model.LayoutTime2, d)
- if !pat.IsZero() {
- ts.PregnancyCheckAt = int32(pat.Local().Unix())
- }
- case 18:
- continue
- case 19:
- continue
- case 20:
- cat, _ := util.TimeParseLocal(model.LayoutTime2, d)
- if !cat.IsZero() {
- ts.CalvingAt = int32(cat.Local().Unix())
- }
- case 21:
- continue
- case 22:
- continue
- case 23:
- continue
- case 24:
- ts.CowKind = pasturePb.CowKind_AGSN
- }
- }
- eventEnterList = append(eventEnterList, ts)
- }*/
- // 遍历数据行(跳过表头)
- for _, row := range data[1:] {
- if len(row) == 0 {
- continue
- }
- ts := &pasturePb.EventEnterRequest{
- OperationId: int32(userModel.SystemUser.Id),
- OperationName: userModel.SystemUser.Name,
- MessengerId: int32(userModel.SystemUser.Id),
- MessengerName: userModel.SystemUser.Name,
- }
- // 使用反射动态匹配字段
- val := reflect.ValueOf(ts).Elem()
- typ := val.Type()
- for i := 0; i < val.NumField(); i++ {
- field := typ.Field(i)
- fieldVal := val.Field(i)
- // 获取字段的 excel 标签(如 excel:"耳标号")
- excelTag := strings.ReplaceAll(field.Tag.Get("json"), ",omitempty", "")
- if excelTag == "" {
- continue // 没有 excel 标签的字段跳过
- }
- // 查找 excelHeader 中匹配的列索引
- colIndex := -1
- for j, colName := range excelHeader {
- if colName == "" {
- continue // 跳过空列名
- }
- if colName == excelTag {
- colIndex = j
- break
- }
- }
- if colIndex == -1 || colIndex >= len(row) {
- continue // 列名不匹配或数据越界
- }
- cellValue := row[colIndex]
- if cellValue == "" {
- continue // 空值跳过
- }
- // 根据字段类型设置值
- switch fieldVal.Kind() {
- case reflect.String:
- fieldVal.SetString(cellValue)
- case reflect.Int32:
- if num, err := strconv.ParseInt(cellValue, 10, 32); err == nil {
- fieldVal.SetInt(num)
- }
- case reflect.Struct: // 处理枚举或时间类型
- switch field.Type {
- case reflect.TypeOf(pasturePb.Genders_Female):
- if cellValue == "公" {
- fieldVal.Set(reflect.ValueOf(pasturePb.Genders_Male))
- } else {
- fieldVal.Set(reflect.ValueOf(pasturePb.Genders_Female))
- }
- // 添加其他自定义类型的处理...
- }
- }
- }
- // 特殊处理 PenId 和 PenName(依赖 penMap)
- if ts.PenName != "" {
- if pen, ok := penMap[ts.PenName]; ok {
- ts.PenId = pen.Id
- }
- }
- eventEnterList = append(eventEnterList, ts)
- }
- if len(eventEnterList) <= 0 {
- return nil
- }
- return nil
- return s.ExecExcelData(ctx, userModel.AppPasture.Id, eventEnterList)
- }
- func (s *StoreEntry) ExecExcelData(ctx context.Context, pastureId int64, dataList []*pasturePb.EventEnterRequest) error {
- if len(dataList) <= 0 {
- return nil
- }
- return s.DB.Transaction(func(tx *gorm.DB) error {
- for _, data := range dataList {
- var count int64
- if err := tx.Model(new(model.Cow)).
- Where("pasture_id = ?", pastureId).
- Where("ear_number = ?", data.EarNumber).
- Count(&count).Error; err != nil {
- return err
- }
- if count > 0 {
- continue
- }
- if err := s.CreateEnter(ctx, data); err != nil {
- return err
- }
- }
- return nil
- })
- }
|