|
|
package controllers
|
|
|
|
|
|
import (
|
|
|
"encoding/json"
|
|
|
"errors"
|
|
|
"fmt"
|
|
|
"path"
|
|
|
"regexp"
|
|
|
"strconv"
|
|
|
"strings"
|
|
|
"time"
|
|
|
"unicode/utf8"
|
|
|
|
|
|
"github.com/360EntSecGroup-Skylar/excelize/v2"
|
|
|
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/constant"
|
|
|
|
|
|
"github.com/astaxie/beego/logs"
|
|
|
orderCmd "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/orderinfo/command"
|
|
|
orderQuery "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/orderinfo/query"
|
|
|
orderService "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/orderinfo/service"
|
|
|
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain"
|
|
|
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/utils"
|
|
|
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/lib"
|
|
|
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/lib/exceltool"
|
|
|
)
|
...
|
...
|
@@ -603,3 +609,256 @@ func (c *OrderInfoController) ListOrderForExcel() { |
|
|
c.ResponseExcelByFile(c.Ctx, excelMaker)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @Author SteveChan
|
|
|
* @Description //TODO 导入excel订单
|
|
|
* @Date 10:52 2021/1/6
|
|
|
* @Param
|
|
|
* @return
|
|
|
**/
|
|
|
func (c *OrderInfoController) ImportOrderFromExcel() {
|
|
|
where := c.GetString("where")
|
|
|
file, h, _ := c.GetFile("file")
|
|
|
|
|
|
jsonMap := make(map[string]interface{})
|
|
|
|
|
|
err := json.Unmarshal([]byte(where), &jsonMap)
|
|
|
if err != nil {
|
|
|
logs.Error(err)
|
|
|
c.ResponseError(errors.New("json数据解析失败"))
|
|
|
}
|
|
|
|
|
|
// 返回字段定义
|
|
|
ret := map[string]interface{}{}
|
|
|
|
|
|
// 返回信息表头定义
|
|
|
// 0: 订单号, 1: 发货单号, 3: 客户名称, 3: 订单区域, 4: 编号, 5: 合伙人, 6: 类型, 7: 业务抽成比例, 8: 产品名称, 9: 数量, 10: 单价, 11: 合伙人分红比例
|
|
|
var tableHeader = []string{"错误详情", "行号", "订单号", "发货单号", "客户名称", "订单区域", "编号", "合伙人", "类型", "业务抽成比例", "产品名称", "数量", "单价", "合伙人分红比例"}
|
|
|
|
|
|
// 文件后缀名校验
|
|
|
ext := path.Ext(h.Filename)
|
|
|
AllowExtMap := map[string]bool{
|
|
|
".xlsx": true,
|
|
|
}
|
|
|
if _, ok := AllowExtMap[ext]; !ok {
|
|
|
c.ResponseError(errors.New("文件后缀名不符合上传要求,请上传正确的文件"))
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 打开文件
|
|
|
xlsx, err := excelize.OpenReader(file)
|
|
|
if err != nil {
|
|
|
c.ResponseError(errors.New("文件打开失败"))
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 文件行数校验
|
|
|
rows, _ := xlsx.GetRows("工作表1")
|
|
|
if len(rows) > 303 {
|
|
|
c.ResponseError(errors.New("导入文件的行数超过300行,请调整行数后重新导入"))
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 空文件校验
|
|
|
if len(rows) < 3 {
|
|
|
c.ResponseError(errors.New("导入的excel文件为空文件,请上传正确的文件"))
|
|
|
}
|
|
|
|
|
|
// 必填项校验
|
|
|
nullLine := make([]interface{}, 0)
|
|
|
nullFlag := false
|
|
|
for i, row := range rows {
|
|
|
if i > 2 {
|
|
|
if len(row) == constant.EXCEL_COLUMN { // 中间空字符校验
|
|
|
var myRow = row
|
|
|
for j, cell := range row {
|
|
|
if j != 8 { // 业务员抽成比例不校验
|
|
|
if cell == "" || cell == " " { // 空字符串填充
|
|
|
myRow[j] = "null"
|
|
|
nullFlag = true
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if nullFlag {
|
|
|
myRow = append(myRow, "必填项不能为空") // 错误信息
|
|
|
s := strconv.Itoa(i + 1)
|
|
|
myRow = append(myRow, s) // 行号
|
|
|
myRow = append(myRow, row...) // 错误行数据
|
|
|
nullLine = append(nullLine, myRow)
|
|
|
nullFlag = false
|
|
|
}
|
|
|
} else if len(row) < constant.EXCEL_COLUMN && len(row) > 0 { // 尾部空字符校验
|
|
|
var myRow []string
|
|
|
for i := 0; i < constant.EXCEL_COLUMN-len(row); i++ {
|
|
|
myRow = append(myRow, "null")
|
|
|
}
|
|
|
myRow = append(myRow, "必填项不能为空") // 错误信息
|
|
|
s := strconv.Itoa(i + 1)
|
|
|
myRow = append(myRow, s) // 行号
|
|
|
myRow = append(myRow, row...) // 错误行数据
|
|
|
nullLine = append(nullLine, myRow)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if len(nullLine) > 0 {
|
|
|
ret = map[string]interface{}{
|
|
|
"successCount": 0,
|
|
|
"fail": map[string]interface{}{
|
|
|
"tableHeader": tableHeader,
|
|
|
"tableData": nullLine,
|
|
|
},
|
|
|
}
|
|
|
c.ResponseData(ret)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 单元格长度、内容校验
|
|
|
errorLine := make([]interface{}, 0)
|
|
|
var partnerType = []string{"事业合伙", "业务合伙", "研发合伙", "业务-产品应用合伙"}
|
|
|
for i, row := range rows {
|
|
|
if i > 2 && len(row) == constant.EXCEL_COLUMN { // 数据行
|
|
|
var myRow []string
|
|
|
for j, cell := range row {
|
|
|
switch j {
|
|
|
case 0, 1, 2, 3, 4, 5, 8: // 订单号、发货单号、客户名称、订单区域、编号、合伙人、产品名称、
|
|
|
{
|
|
|
if len(cell) > 50 {
|
|
|
var tmpRow []string
|
|
|
tmpRow = append(tmpRow, tableHeader[j+2]+"长度超过50,请重新输入") // 错误信息
|
|
|
s := strconv.Itoa(i + 1)
|
|
|
tmpRow = append(tmpRow, s) // 行号
|
|
|
tmpRow = append(tmpRow, row...) // 错误行数据
|
|
|
myRow = tmpRow
|
|
|
}
|
|
|
}
|
|
|
case 6: // 合伙人类型校验(事业合伙、业务合伙、研发合伙、业务-产品应用合伙)
|
|
|
{
|
|
|
if !utils.IsContain(partnerType, cell) {
|
|
|
var tmpRow []string
|
|
|
tmpRow = append(tmpRow, "合伙人类型须为以下类型:事业合伙、业务合伙、研发合伙、业务-产品应用合伙") // 错误信息
|
|
|
s := strconv.Itoa(i + 1)
|
|
|
tmpRow = append(tmpRow, s) // 行号
|
|
|
tmpRow = append(tmpRow, row...) // 错误行数据
|
|
|
myRow = tmpRow
|
|
|
}
|
|
|
}
|
|
|
case 7: // 业务员抽成比例,非必填,精确到小数点后两位
|
|
|
{
|
|
|
if len(cell) > 0 {
|
|
|
_, err := strconv.ParseFloat(cell, 64)
|
|
|
if err != nil {
|
|
|
var tmpRow []string
|
|
|
tmpRow = append(tmpRow, "业务员抽成比例格式错误,请输入正确的业务员抽成比例比例,保留两位小数") // 错误信息
|
|
|
s := strconv.Itoa(i + 1)
|
|
|
tmpRow = append(tmpRow, s) // 行号
|
|
|
tmpRow = append(tmpRow, row...) // 错误行数据
|
|
|
myRow = tmpRow
|
|
|
}
|
|
|
//if isOk, _ := regexp.MatchString("^(.[0-9]{0,1,2})?$", cell); !isOk { // 最多两位小数
|
|
|
// var tmpRow []string
|
|
|
// tmpRow = append(tmpRow, "业务员员抽成比例格式错误,请输入正确的单价,保留两位小数") // 错误信息
|
|
|
// s := strconv.Itoa(i + 1)
|
|
|
// tmpRow = append(tmpRow, s) // 行号
|
|
|
// tmpRow = append(tmpRow, row...) // 错误行数据
|
|
|
// myRow = tmpRow
|
|
|
//}
|
|
|
}
|
|
|
}
|
|
|
case 9: // 数量不超过16位正整数
|
|
|
{
|
|
|
_, err := strconv.ParseInt(cell, 10, 64)
|
|
|
if err != nil {
|
|
|
var tmpRow []string
|
|
|
tmpRow = append(tmpRow, "数量须为整数,请重新填写") // 错误信息
|
|
|
s := strconv.Itoa(i + 1)
|
|
|
tmpRow = append(tmpRow, s) // 行号
|
|
|
tmpRow = append(tmpRow, row...) // 错误行数据
|
|
|
myRow = tmpRow
|
|
|
}
|
|
|
|
|
|
if len(cell) > 16 {
|
|
|
var tmpRow []string
|
|
|
tmpRow = append(tmpRow, "数量长度超过最大限制十六位整数,请重新填写") // 错误信息
|
|
|
s := strconv.Itoa(i + 1)
|
|
|
tmpRow = append(tmpRow, s) // 行号
|
|
|
tmpRow = append(tmpRow, row...) // 错误行数据
|
|
|
myRow = tmpRow
|
|
|
}
|
|
|
}
|
|
|
case 10: // 单价,精确到小数点后两位,小数点左侧最多可输入16位数字
|
|
|
{
|
|
|
_, err := strconv.ParseFloat(cell, 64)
|
|
|
if err != nil {
|
|
|
var tmpRow []string
|
|
|
tmpRow = append(tmpRow, "单价格式错误,请输入正确的单价,保留两位小数点,小数点前面不能超过十六位数字") // 错误信息
|
|
|
s := strconv.Itoa(i + 1)
|
|
|
tmpRow = append(tmpRow, s) // 行号
|
|
|
tmpRow = append(tmpRow, row...) // 错误行数据
|
|
|
myRow = tmpRow
|
|
|
}
|
|
|
//if isOk, _ := regexp.MatchString("^d{1,16}(.[0-9]{0,1,2})?$", cell); !isOk { // 非负的16位整数最多两位小数
|
|
|
// var tmpRow []string
|
|
|
// tmpRow = append(tmpRow, "单价格式错误,请输入正确的单价,保留两位小数点,小数点前面不能超过十六位数字") // 错误信息
|
|
|
// s := strconv.Itoa(i + 1)
|
|
|
// tmpRow = append(tmpRow, s) // 行号
|
|
|
// tmpRow = append(tmpRow, row...) // 错误行数据
|
|
|
// myRow = tmpRow
|
|
|
//}
|
|
|
}
|
|
|
case 11: // 合伙人分红比例,精确到小数点后两位
|
|
|
{
|
|
|
_, err := strconv.ParseFloat(cell, 64)
|
|
|
if err != nil {
|
|
|
var tmpRow []string
|
|
|
tmpRow = append(tmpRow, "合伙人分红比例格式错误,请输入正确的合伙人分红比例,保留两位小数") // 错误信息
|
|
|
s := strconv.Itoa(i + 1)
|
|
|
tmpRow = append(tmpRow, s) // 行号
|
|
|
tmpRow = append(tmpRow, row...) // 错误行数据
|
|
|
myRow = tmpRow
|
|
|
}
|
|
|
//if isOk, _ := regexp.MatchString("^(.[0-9]{1,2})?$", cell); !isOk { // 最多两位小数
|
|
|
// var tmpRow []string
|
|
|
// tmpRow = append(tmpRow, "合伙人分红比例错误,请输入正确的合伙人分红比例,保留两位小数") // 错误信息
|
|
|
// s := strconv.Itoa(i + 1)
|
|
|
// tmpRow = append(tmpRow, s) // 行号
|
|
|
// tmpRow = append(tmpRow, row...) // 错误行数据
|
|
|
// myRow = tmpRow
|
|
|
//}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
errorLine = append(errorLine, myRow)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if len(errorLine) > 0 {
|
|
|
ret = map[string]interface{}{
|
|
|
"successCount": 0,
|
|
|
"fail": map[string]interface{}{
|
|
|
"tableHeader": tableHeader,
|
|
|
"tableData": errorLine,
|
|
|
},
|
|
|
}
|
|
|
c.ResponseData(ret)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 归类订单
|
|
|
for i, row := range rows {
|
|
|
if i > 2 && len(row) == 13 {
|
|
|
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 新增失败记录
|
|
|
failureDataList := make([]interface{}, 0)
|
|
|
|
|
|
// 新增成功记录计数
|
|
|
//var successDataCount int64
|
|
|
|
|
|
c.ResponseData(failureDataList)
|
|
|
|
|
|
return
|
|
|
} |
...
|
...
|
|