diff --git a/server/admin/system_log_sms/system_log_sms_ctl.go b/server/admin/system_log_sms/system_log_sms_ctl.go index 712a64f..c83db47 100644 --- a/server/admin/system_log_sms/system_log_sms_ctl.go +++ b/server/admin/system_log_sms/system_log_sms_ctl.go @@ -4,6 +4,7 @@ import ( "net/http" "strconv" "time" + "x_admin/core" "x_admin/core/request" "x_admin/core/response" "x_admin/util" @@ -151,6 +152,29 @@ func (hd *SystemLogSmsHandler) Del(c *gin.Context) { response.CheckAndResp(c, SystemLogSmsService.Del(delReq.Id)) } +func DecodeTime(value any) any { + t, e := core.ParseStringToTsTime(value.(string)) + if e != nil { + return nil + } + + return t +} + +var cols = []excel2.Col{ + {Name: "场景编号", Key: "Scene", Width: 15, Replace: map[string]interface{}{ + "1": "a", + "2": "b", + }}, + {Name: "手机号码", Key: "Mobile", Width: 15}, + {Name: "发送内容", Key: "Content", Width: 15}, + {Name: "发送状态", Key: "Status", Width: 20}, + {Name: "短信结果", Key: "Results", Width: 21}, + {Name: "发送时间", Key: "SendTime", Width: 20}, + {Name: "创建时间", Key: "CreateTime", Width: 25}, + {Name: "更新时间", Key: "UpdateTime", Width: 30, Decode: DecodeTime}, +} + // @Summary 系统短信日志导出 // @Tags system_log_sms-系统短信日志 // @Produce json @@ -182,16 +206,6 @@ func (hd *SystemLogSmsHandler) ExportFile(c *gin.Context) { // return // } - var cols = []excel2.Col{ - {Name: "场景编号", Key: "Scene", Width: 15}, - {Name: "手机号码", Key: "Mobile", Width: 15}, - {Name: "发送内容", Key: "Content", Width: 15}, - {Name: "发送状态", Key: "Status", Width: 20}, - {Name: "短信结果", Key: "Results", Width: 21}, - {Name: "发送时间", Key: "SendTime", Width: 20}, - {Name: "创建时间", Key: "CreateTime", Width: 25}, - {Name: "更新时间", Key: "UpdateTime", Width: 30}, - } list := util.ConvertUtil.StructsToMaps(res) f, err := excel2.NormalDynamicExport2(list, cols, "Sheet1", "系统短信日志") if err != nil { @@ -214,7 +228,7 @@ func (hd *SystemLogSmsHandler) ImportFile(c *gin.Context) { } defer file.Close() importList := []SystemLogSmsResp{} - err = excel.GetExcelData(file, &importList) + err = excel2.GetExcelData(file, &importList, cols) if err != nil { c.String(http.StatusInternalServerError, err.Error()) return diff --git a/server/util/excel2/excel_export_2.go b/server/util/excel2/excel_export_2.go index 3f5b3b2..82d6bfb 100644 --- a/server/util/excel2/excel_export_2.go +++ b/server/util/excel2/excel_export_2.go @@ -8,9 +8,11 @@ import ( ) type Col struct { - Name string - Key string - Width int + Name string + Key string + Width int + Replace map[string]any + Decode func(value any) any } // GetExcelColumnName2 根据列数生成 Excel 列名 @@ -106,42 +108,21 @@ func normalBuildDataRow2(e *Excel, sheet, endColName string, startDataRow int, l list := lists[i] for j := 0; j < len(cols); j++ { col := cols[j] - val := list[col.Key] - // switch val.(type) { + replace := col.Replace + + val := list[col.Key] + + for replaceKey, v := range replace { + + if replaceKey == fmt.Sprintf("%v", val) { + val = fmt.Sprintf("%v", v) + break + } + } - // default: - // v, _ := json.Marshal(list[col.Key]) - // rowData = append(rowData, v) - // } rowData = append(rowData, val) } - // // 替换 - // if dataCol.Replace != "" { - // split := strings.Split(dataCol.Replace, ",") - // for j := range split { - // s := strings.Split(split[j], "_") // 根据下划线进行分割,格式:需要替换的内容_替换后的内容 - // value := fieldData.String() - // if strings.Contains(fieldData.Type().String(), "int") { - // value = strconv.Itoa(int(fieldData.Int())) - // } else if fieldData.Type().String() == "bool" { - // value = strconv.FormatBool(fieldData.Bool()) - // } else if strings.Contains(fieldData.Type().String(), "float") { - // value = strconv.FormatFloat(fieldData.Float(), 'f', -1, 64) - // } - // if s[0] == value { - // dataCol.Value = s[1] - // } - // } - // } else { - // dataCol.Value = fieldData - // } - // if err != nil { - // return - // } - // exportRow = append(exportRow, dataCol) - // } - if startDataRow%2 == 0 { _ = e.F.SetCellStyle(sheet, startCol, endCol, e.ContentStyle2) } else { diff --git a/server/util/excel2/excel_import.go b/server/util/excel2/excel_import.go index 0c4e6c4..7cb8e7c 100644 --- a/server/util/excel2/excel_import.go +++ b/server/util/excel2/excel_import.go @@ -6,13 +6,12 @@ import ( "fmt" "io" "mime/multipart" - "reflect" - "strconv" + "x_admin/util" "github.com/xuri/excelize/v2" ) -func GetExcelData(file multipart.File, dst interface{}) (err error) { +func GetExcelData(file multipart.File, dst interface{}, cols []Col) (err error) { // 创建缓冲区 buf := new(bytes.Buffer) @@ -32,7 +31,7 @@ func GetExcelData(file multipart.File, dst interface{}) (err error) { err = errors.New("Excel读取失败") return } - err = ImportExcel(f, dst, 1, 2) + err = ImportExcel(f, dst, 2, cols) // if err != nil { // fmt.Println(err) // } @@ -44,20 +43,20 @@ func GetExcelData(file multipart.File, dst interface{}) (err error) { // f 获取到的excel对象、dst 导入目标对象【传指针】 // headIndex 表头的索引,从0开始(用于获取表头名字) // startRow 头行行数(从第startRow+1行开始扫) -func ImportExcel(f *excelize.File, dst interface{}, headIndex, startRow int) (err error) { +func ImportExcel(f *excelize.File, dst interface{}, startRow int, cols []Col) (err error) { sheetName := f.GetSheetName(0) // 单个sheet时,默认读取第一个sheet - err = importData(f, dst, sheetName, headIndex, startRow) + err = importData(f, dst, sheetName, startRow, cols) return } // ImportBySheet 导入数据(读取指定sheet)sheetName Sheet名称 -func ImportBySheet(f *excelize.File, dst interface{}, sheetName string, headIndex, startRow int) (err error) { +func ImportBySheet(f *excelize.File, dst interface{}, sheetName string, startRow int, cols []Col) (err error) { // 当需要读取多个sheet时,可以通过下面的方式,来调用 ImportBySheet 这个函数 //sheetList := f.GetSheetList() //for _, sheetName := range sheetList { - // ImportBySheet(f,dst,sheetName,headIndex,startRow) + // ImportBySheet(f,dst,sheetName,startRow) //} - err = importData(f, dst, sheetName, headIndex, startRow) + err = importData(f, dst, sheetName, startRow, cols) return } @@ -71,106 +70,69 @@ func GetIndex(items []string, item string) int { return -1 } -// 判断数组中是否包含指定元素 -// func IsContain(items interface{}, item interface{}) bool { -// switch items.(type) { -// case []int: -// intArr := items.([]int) -// for _, value := range intArr { -// if value == item.(int) { -// return true -// } -// } -// case []string: -// strArr := items.([]string) -// for _, value := range strArr { -// if value == item.(string) { -// return true -// } -// } -// default: -// return false -// } -// return false -// } - // 解析数据 -func importData(f *excelize.File, dst interface{}, sheetName string, headIndex, startRow int) (err error) { +func importData(f *excelize.File, dst interface{}, sheetName string, startRow int, cols []Col) (err error) { rows, err := f.GetRows(sheetName) // 获取所有行 if err != nil { err = errors.New(sheetName + "工作表不存在") return } - dataValue := reflect.ValueOf(dst) // 取目标对象的元素类型、字段类型和 tag - // 判断数据的类型 - if dataValue.Kind() != reflect.Ptr || dataValue.Elem().Kind() != reflect.Slice { - err = errors.New("invalid data type") - } - heads := []string{} // 表头 - dataType := dataValue.Elem().Type().Elem() // 获取导入目标对象的类型信息 - // 遍历行,解析数据并填充到目标对象中 - for rowIndex, row := range rows { - if rowIndex == headIndex { - heads = row - } - if rowIndex < startRow { // 跳过头行 + // heads := []string{} + + var data = []map[string]interface{}{} + for i := 0; i < len(rows); i++ { + + if i < startRow { // 跳过头行 continue } - newData := reflect.New(dataType).Elem() // 创建新的目标对象 - // 遍历目标对象的字段 - for i := 0; i < dataType.NumField(); i++ { - // 这里要用构造函数,构造函数里指定了Index默认值为-1,当目标结构体的tag没有指定index的话,那么 excelTag.Index 就一直为0 - // 那么 row[excelizeIndex] 就始终是 row[0],始终拿的是第一列的数据 - var excelTag = NewExcelTag() - field := dataType.Field(i) // 获取字段信息和tag - tag := field.Tag.Get(ExcelTagKey) - if tag == "" { // 如果tag不存在,则跳过 - continue - } - err = excelTag.GetTag(tag) - if err != nil { - return - } - cellValue := "" - if excelTag.Index >= 0 { // 当tag里指定了index时,根据这个index来拿数据 - excelizeIndex := excelTag.Index // 解析tag的值 - if excelizeIndex >= len(row) { // 防止下标越界 - continue - } - cellValue = row[excelizeIndex] // 获取单元格的值 - } else { // 否则根据表头名称来拿数据 - var index = GetIndex(heads, excelTag.Name) - if index != -1 { - if index >= len(row) { // 防止下标越界 - continue - } - cellValue = row[index] // 获取单元格的值 + var rowMap = map[string]interface{}{} + + for j := 0; j < len(cols); j++ { + col := cols[j] + key := col.Key + replace := col.Replace + + val := rows[i][j] + // 将val替换为key + for replaceKey, v := range replace { + if fmt.Sprintf("%v", v) == fmt.Sprintf("%v", val) { + val = fmt.Sprintf("%v", replaceKey) + break } } - fmt.Println("Type.Name:", field.Type.Name(), field.Type.Kind()) - // 根据字段类型设置值 - switch field.Type.Kind() { - case reflect.Int: - v, _ := strconv.ParseInt(cellValue, 10, 64) - newData.Field(i).SetInt(v) - case reflect.Int64: - v, _ := strconv.ParseInt(cellValue, 10, 64) - newData.Field(i).SetInt(v) - case reflect.Uint: - v, _ := strconv.ParseUint(cellValue, 10, 64) - newData.Field(i).SetUint(v) - case reflect.Uint8: - v, _ := strconv.ParseUint(cellValue, 10, 64) - newData.Field(i).SetUint(v) - case reflect.Uint16: - v, _ := strconv.ParseUint(cellValue, 10, 64) - newData.Field(i).SetUint(v) - case reflect.String: - newData.Field(i).SetString(cellValue) + + if col.Decode != nil { + rowMap[key] = col.Decode(val) + } else { + rowMap[key] = val } } - // 将新的目标对象添加到导入目标对象的slice中 - dataValue.Elem().Set(reflect.Append(dataValue.Elem(), newData)) + data = append(data, rowMap) + } + util.ConvertUtil.MapToStruct(data, dst) + + // fmt.Println("Type.Name:", field.Type.Name(), field.Type.Kind()) + // // 根据字段类型设置值 + // switch field.Type.Kind() { + // case reflect.Int: + // v, _ := strconv.ParseInt(cellValue, 10, 64) + // newData.Field(i).SetInt(v) + // case reflect.Int64: + // v, _ := strconv.ParseInt(cellValue, 10, 64) + // newData.Field(i).SetInt(v) + // case reflect.Uint: + // v, _ := strconv.ParseUint(cellValue, 10, 64) + // newData.Field(i).SetUint(v) + // case reflect.Uint8: + // v, _ := strconv.ParseUint(cellValue, 10, 64) + // newData.Field(i).SetUint(v) + // case reflect.Uint16: + // v, _ := strconv.ParseUint(cellValue, 10, 64) + // newData.Field(i).SetUint(v) + // case reflect.String: + // newData.Field(i).SetString(cellValue) + // } + return } diff --git a/server/util/excel2/excel_test.go b/server/util/excel2/excel_test.go index 93f2bed..15322e1 100644 --- a/server/util/excel2/excel_test.go +++ b/server/util/excel2/excel_test.go @@ -58,7 +58,7 @@ func TestImports(t *testing.T) { fmt.Println("文件打开失败") } importList := []Test{} - err = ImportExcel(f, &importList, 1, 2) + err = ImportExcel(f, &importList, 2, []Col{}) if err != nil { fmt.Println(err) }