265 lines
7.6 KiB
Go
265 lines
7.6 KiB
Go
|
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)有2,3级,但没有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
|
|||
|
}
|