mh_goadmin_server/app/admin/models/file.go

265 lines
7.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package models
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"github.com/codinl/go-logger"
"github.com/xuri/excelize/v2"
"reflect"
)
type CategoryExcel struct {
FirstCategory string `json:"first_category" binding:"required"` // 一级分类
SecondCategory string `json:"second_category"` // 二级分类
ThreeCategory string `json:"three_category"` // 三级分类
}
type CommodityExcel struct {
Category string `json:"category" binding:"required"` // 商品所属分类
Name string `json:"name" binding:"required"` // 商品名称
IMEIType string `json:"imei_type" binding:"required"` // 是否串码 1-无串码 2-串码(系统生成) 3-串码(手动添加)
SysGenerate string `json:"sys_generate" binding:"required"` // 系统生成串码
SupplierName string `json:"supplier_name" binding:"required"` // 供应商名称
SellBrokerage string `json:"sell_brokerage" binding:"required"` // 销售毛利提成
StaffBrokerage string `json:"staff_brokerage" binding:"required"` // 员工毛利提成
MemberDiscount string `json:"member_discount" binding:"required"` // 会员优惠
RetailPrice string `json:"retail_price" binding:"required"` // 指导零售价
MinRetailPrice string `json:"min_retail_price" binding:"required"` // 最低零售价
WholesalePrice string `json:"wholesale_price" binding:"required"` // 指导采购价
StaffCostPrice string `json:"staff_cost_price" binding:"required"` // 员工成本价加价
Origin string `json:"origin"` // 产地
Remark string `json:"remark"` // 备注
}
// 获取struct的tag标签匹配excel导入数据
func getJSONTagNames(s interface{}) []string {
valueType := reflect.TypeOf(s)
if valueType.Kind() != reflect.Struct {
fmt.Println("传入的不是结构体")
return nil
}
var tagNames []string
for i := 0; i < valueType.NumField(); i++ {
field := valueType.Field(i)
tag := field.Tag.Get("json")
if tag != "" {
tagNames = append(tagNames, tag)
}
}
return tagNames
}
// 预览excel数据不做必填项校验
func FileExcelReader(d []byte, cols []string) ([]byte, []map[string]interface{}, error) {
reader, err := excelize.OpenReader(bytes.NewReader(d))
if err != nil {
logger.Error("open reader err:", err)
return nil, nil, err
}
sheetList := reader.GetSheetList()
if len(sheetList) == 0 {
logger.Error("sheet list nil")
return nil, nil, err
}
rows, err := reader.Rows(sheetList[0])
if err != nil {
logger.Error("reader rows err:", err)
return nil, nil, err
}
sheetCols, err := reader.GetCols(sheetList[0])
if err != nil {
logger.Error("reader get cols err:", err)
return nil, nil, err
}
if len(sheetCols) == 0 {
logger.Error("get cols null err")
return nil, nil, err
}
colsMap := make([]map[string]interface{}, 0)
if len(cols) == 0 {
if sheetList[0] == "导分类" {
cols = getJSONTagNames(CategoryExcel{})
} else if sheetList[0] == "导商品" {
cols = getJSONTagNames(CommodityExcel{})
} else {
cols = make([]string, len(sheetCols))
for i := 0; i < len(sheetCols); i++ {
cols[i] = fmt.Sprintf("c%02d", i)
}
}
} else {
fmt.Println("cols", len(cols))
fmt.Println("sheetCols", len(sheetCols))
if len(cols) != len(sheetCols) {
logger.Error("cols length not equal columns")
return nil, nil, errors.New("cols length not equal columns")
}
}
for rows.Next() {
columns, err := rows.Columns()
if err != nil {
logger.Error("rows columns err:", err)
return nil, nil, err
}
columnMap := make(map[string]interface{}, 0)
for i, _ := range cols {
columnMap[cols[i]] = ""
}
for i, _ := range columns {
columnMap[cols[i]] = columns[i]
}
fmt.Println("columnMap:", columnMap)
colsMap = append(colsMap, columnMap)
}
fmt.Println("colsMap:", colsMap)
mCols, err := json.Marshal(colsMap)
if err != nil {
logger.Error("marshal err:", err)
return mCols, nil, err
}
return mCols, colsMap, nil
}
// 导入excel数据校验必填项
func FileExcelImport(d []byte, cols []string) ([]byte, []map[string]interface{}, error) {
reader, err := excelize.OpenReader(bytes.NewReader(d))
if err != nil {
logger.Error("open reader err:", err)
return nil, nil, err
}
sheetList := reader.GetSheetList()
if len(sheetList) == 0 {
logger.Error("sheet list nil")
return nil, nil, err
}
rows, err := reader.Rows(sheetList[0])
if err != nil {
logger.Error("reader rows err:", err)
return nil, nil, err
}
sheetCols, err := reader.GetCols(sheetList[0])
if err != nil {
logger.Error("reader get cols err:", err)
return nil, nil, err
}
if len(sheetCols) == 0 {
logger.Error("get cols null err")
return nil, nil, err
}
colsMap := make([]map[string]interface{}, 0)
if len(cols) == 0 {
if sheetList[0] == "导分类" {
//校验商品分类导入规则
err := checkCategoryExcel(sheetCols)
if err != nil {
return nil, nil, err
}
cols = getJSONTagNames(CategoryExcel{})
} else if sheetList[0] == "导商品" {
//校验商品资料导入规则
err := checkCommodityExcel(sheetCols)
if err != nil {
return nil, nil, err
}
cols = getJSONTagNames(CommodityExcel{})
} else {
cols = make([]string, len(sheetCols))
for i := 0; i < len(sheetCols); i++ {
cols[i] = fmt.Sprintf("c%02d", i)
}
}
} else {
fmt.Println("cols", len(cols))
fmt.Println("sheetCols", len(sheetCols))
if len(cols) != len(sheetCols) {
logger.Error("cols length not equal columns")
return nil, nil, errors.New("cols length not equal columns")
}
}
for rows.Next() {
columns, err := rows.Columns()
if err != nil {
logger.Error("rows columns err:", err)
return nil, nil, err
}
columnMap := make(map[string]interface{}, 0)
for i, _ := range cols {
columnMap[cols[i]] = ""
for j, _ := range columns {
columnMap[cols[j]] = columns[j]
}
}
//for i, _ := range columns {
// columnMap[cols[i]] = columns[i]
//}
fmt.Println("columnMap:", columnMap)
colsMap = append(colsMap, columnMap)
}
fmt.Println("colsMap:", colsMap)
mCols, err := json.Marshal(colsMap)
if err != nil {
logger.Error("marshal err:", err)
return mCols, nil, err
}
return mCols, colsMap, nil
}
// 校验商品分类导入规则
// 导入商品分类校验报错: 1只有3级没有2级或1级 2有23级但没有1级
func checkCategoryExcel(sheetCols [][]string) error {
if len(sheetCols) != 3 {
return errors.New("模版错误,请检查文件")
}
if len(sheetCols[0]) < len(sheetCols[1]) || len(sheetCols[0]) < len(sheetCols[2]) {
return errors.New("格式错误,缺少一级分类")
} else if len(sheetCols[1]) < len(sheetCols[2]) {
return errors.New("格式错误,缺少二级分类")
}
for i := 1; i < len(sheetCols[2]); i++ {
if sheetCols[0][i] == "" && (sheetCols[1][i] != "" || sheetCols[2][i] != "") {
return errors.New("格式错误,缺少一级分类")
} else if sheetCols[2][i] != "" && sheetCols[1][i] == "" {
return errors.New("格式错误,缺少二级分类")
}
}
return nil
}
// 校验商品资料导入规则
// 导入商品资料校验报错:必填项缺少数据(除了产地、备注,其他都是必填项)
func checkCommodityExcel(sheetCols [][]string) error {
if len(sheetCols) != 14 {
return errors.New("模版错误,请检查文件")
}
for i := 0; i < len(sheetCols)-2; i++ {
if len(sheetCols[i]) < len(sheetCols[i+1]) {
return errors.New("格式错误,有必填项未录入")
}
for _, v := range sheetCols[i] {
if v == "" {
return errors.New("格式错误,有必填项未录入")
}
}
}
return nil
}