正在显示
7 个修改的文件
包含
307 行增加
和
4 行删除
@@ -18,6 +18,8 @@ var ( | @@ -18,6 +18,8 @@ var ( | ||
18 | BUSINESS_ADMIN_HOST = "http://suplus-business-admin-test.fjmaimaimai.com" //企业平台的地址 | 18 | BUSINESS_ADMIN_HOST = "http://suplus-business-admin-test.fjmaimaimai.com" //企业平台的地址 |
19 | ) | 19 | ) |
20 | 20 | ||
21 | +var EXCEL_COLUMN = 12 | ||
22 | + | ||
21 | func init() { | 23 | func init() { |
22 | if os.Getenv("LOG_LEVEL") != "" { | 24 | if os.Getenv("LOG_LEVEL") != "" { |
23 | LOG_LEVEL = os.Getenv("LOG_LEVEL") | 25 | LOG_LEVEL = os.Getenv("LOG_LEVEL") |
@@ -35,7 +35,7 @@ type AdminUserFindOneQuery struct { | @@ -35,7 +35,7 @@ type AdminUserFindOneQuery struct { | ||
35 | 35 | ||
36 | type AdminUserRepository interface { | 36 | type AdminUserRepository interface { |
37 | Save(AdminUser) (*AdminUser, error) | 37 | Save(AdminUser) (*AdminUser, error) |
38 | - FindOne(qureyOptions AdminUserFindOneQuery) (*AdminUser, error) | 38 | + FindOne(queryOptions AdminUserFindOneQuery) (*AdminUser, error) |
39 | Find(queryOptions AdminUserFindQuery) ([]AdminUser, error) | 39 | Find(queryOptions AdminUserFindQuery) ([]AdminUser, error) |
40 | CountAll(queryOption AdminUserFindQuery) (int, error) | 40 | CountAll(queryOption AdminUserFindQuery) (int, error) |
41 | } | 41 | } |
@@ -31,3 +31,19 @@ func GenerateRangeNum(min, max int) int { | @@ -31,3 +31,19 @@ func GenerateRangeNum(min, max int) int { | ||
31 | randNum := rand.Intn(max-min) + min | 31 | randNum := rand.Intn(max-min) + min |
32 | return randNum | 32 | return randNum |
33 | } | 33 | } |
34 | + | ||
35 | +/** | ||
36 | + * @Author SteveChan | ||
37 | + * @Description // 判断数组是否包含 | ||
38 | + * @Date 14:30 2021/1/6 | ||
39 | + * @Param | ||
40 | + * @return | ||
41 | + **/ | ||
42 | +func IsContain(items []string, item string) bool { | ||
43 | + for _, eachItem := range items { | ||
44 | + if eachItem == item { | ||
45 | + return true | ||
46 | + } | ||
47 | + } | ||
48 | + return false | ||
49 | +} |
1 | package controllers | 1 | package controllers |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | + "encoding/json" | ||
4 | "errors" | 5 | "errors" |
5 | "fmt" | 6 | "fmt" |
7 | + "path" | ||
6 | "regexp" | 8 | "regexp" |
7 | "strconv" | 9 | "strconv" |
8 | "strings" | 10 | "strings" |
9 | "time" | 11 | "time" |
10 | "unicode/utf8" | 12 | "unicode/utf8" |
11 | 13 | ||
14 | + "github.com/360EntSecGroup-Skylar/excelize/v2" | ||
15 | + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/constant" | ||
16 | + | ||
12 | "github.com/astaxie/beego/logs" | 17 | "github.com/astaxie/beego/logs" |
13 | orderCmd "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/orderinfo/command" | 18 | orderCmd "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/orderinfo/command" |
14 | orderQuery "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/orderinfo/query" | 19 | orderQuery "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/orderinfo/query" |
15 | orderService "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/orderinfo/service" | 20 | orderService "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/orderinfo/service" |
16 | "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain" | 21 | "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain" |
22 | + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/utils" | ||
17 | "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/lib" | 23 | "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/lib" |
18 | "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/lib/exceltool" | 24 | "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/lib/exceltool" |
19 | ) | 25 | ) |
@@ -603,3 +609,256 @@ func (c *OrderInfoController) ListOrderForExcel() { | @@ -603,3 +609,256 @@ func (c *OrderInfoController) ListOrderForExcel() { | ||
603 | c.ResponseExcelByFile(c.Ctx, excelMaker) | 609 | c.ResponseExcelByFile(c.Ctx, excelMaker) |
604 | return | 610 | return |
605 | } | 611 | } |
612 | + | ||
613 | +/** | ||
614 | + * @Author SteveChan | ||
615 | + * @Description //TODO 导入excel订单 | ||
616 | + * @Date 10:52 2021/1/6 | ||
617 | + * @Param | ||
618 | + * @return | ||
619 | + **/ | ||
620 | +func (c *OrderInfoController) ImportOrderFromExcel() { | ||
621 | + where := c.GetString("where") | ||
622 | + file, h, _ := c.GetFile("file") | ||
623 | + | ||
624 | + jsonMap := make(map[string]interface{}) | ||
625 | + | ||
626 | + err := json.Unmarshal([]byte(where), &jsonMap) | ||
627 | + if err != nil { | ||
628 | + logs.Error(err) | ||
629 | + c.ResponseError(errors.New("json数据解析失败")) | ||
630 | + } | ||
631 | + | ||
632 | + // 返回字段定义 | ||
633 | + ret := map[string]interface{}{} | ||
634 | + | ||
635 | + // 返回信息表头定义 | ||
636 | + // 0: 订单号, 1: 发货单号, 3: 客户名称, 3: 订单区域, 4: 编号, 5: 合伙人, 6: 类型, 7: 业务抽成比例, 8: 产品名称, 9: 数量, 10: 单价, 11: 合伙人分红比例 | ||
637 | + var tableHeader = []string{"错误详情", "行号", "订单号", "发货单号", "客户名称", "订单区域", "编号", "合伙人", "类型", "业务抽成比例", "产品名称", "数量", "单价", "合伙人分红比例"} | ||
638 | + | ||
639 | + // 文件后缀名校验 | ||
640 | + ext := path.Ext(h.Filename) | ||
641 | + AllowExtMap := map[string]bool{ | ||
642 | + ".xlsx": true, | ||
643 | + } | ||
644 | + if _, ok := AllowExtMap[ext]; !ok { | ||
645 | + c.ResponseError(errors.New("文件后缀名不符合上传要求,请上传正确的文件")) | ||
646 | + return | ||
647 | + } | ||
648 | + | ||
649 | + // 打开文件 | ||
650 | + xlsx, err := excelize.OpenReader(file) | ||
651 | + if err != nil { | ||
652 | + c.ResponseError(errors.New("文件打开失败")) | ||
653 | + return | ||
654 | + } | ||
655 | + | ||
656 | + // 文件行数校验 | ||
657 | + rows, _ := xlsx.GetRows("工作表1") | ||
658 | + if len(rows) > 303 { | ||
659 | + c.ResponseError(errors.New("导入文件的行数超过300行,请调整行数后重新导入")) | ||
660 | + return | ||
661 | + } | ||
662 | + | ||
663 | + // 空文件校验 | ||
664 | + if len(rows) < 3 { | ||
665 | + c.ResponseError(errors.New("导入的excel文件为空文件,请上传正确的文件")) | ||
666 | + } | ||
667 | + | ||
668 | + // 必填项校验 | ||
669 | + nullLine := make([]interface{}, 0) | ||
670 | + nullFlag := false | ||
671 | + for i, row := range rows { | ||
672 | + if i > 2 { | ||
673 | + if len(row) == constant.EXCEL_COLUMN { // 中间空字符校验 | ||
674 | + var myRow = row | ||
675 | + for j, cell := range row { | ||
676 | + if j != 8 { // 业务员抽成比例不校验 | ||
677 | + if cell == "" || cell == " " { // 空字符串填充 | ||
678 | + myRow[j] = "null" | ||
679 | + nullFlag = true | ||
680 | + } | ||
681 | + } | ||
682 | + } | ||
683 | + if nullFlag { | ||
684 | + myRow = append(myRow, "必填项不能为空") // 错误信息 | ||
685 | + s := strconv.Itoa(i + 1) | ||
686 | + myRow = append(myRow, s) // 行号 | ||
687 | + myRow = append(myRow, row...) // 错误行数据 | ||
688 | + nullLine = append(nullLine, myRow) | ||
689 | + nullFlag = false | ||
690 | + } | ||
691 | + } else if len(row) < constant.EXCEL_COLUMN && len(row) > 0 { // 尾部空字符校验 | ||
692 | + var myRow []string | ||
693 | + for i := 0; i < constant.EXCEL_COLUMN-len(row); i++ { | ||
694 | + myRow = append(myRow, "null") | ||
695 | + } | ||
696 | + myRow = append(myRow, "必填项不能为空") // 错误信息 | ||
697 | + s := strconv.Itoa(i + 1) | ||
698 | + myRow = append(myRow, s) // 行号 | ||
699 | + myRow = append(myRow, row...) // 错误行数据 | ||
700 | + nullLine = append(nullLine, myRow) | ||
701 | + } | ||
702 | + } | ||
703 | + } | ||
704 | + | ||
705 | + if len(nullLine) > 0 { | ||
706 | + ret = map[string]interface{}{ | ||
707 | + "successCount": 0, | ||
708 | + "fail": map[string]interface{}{ | ||
709 | + "tableHeader": tableHeader, | ||
710 | + "tableData": nullLine, | ||
711 | + }, | ||
712 | + } | ||
713 | + c.ResponseData(ret) | ||
714 | + return | ||
715 | + } | ||
716 | + | ||
717 | + // 单元格长度、内容校验 | ||
718 | + errorLine := make([]interface{}, 0) | ||
719 | + var partnerType = []string{"事业合伙", "业务合伙", "研发合伙", "业务-产品应用合伙"} | ||
720 | + for i, row := range rows { | ||
721 | + if i > 2 && len(row) == constant.EXCEL_COLUMN { // 数据行 | ||
722 | + var myRow []string | ||
723 | + for j, cell := range row { | ||
724 | + switch j { | ||
725 | + case 0, 1, 2, 3, 4, 5, 8: // 订单号、发货单号、客户名称、订单区域、编号、合伙人、产品名称、 | ||
726 | + { | ||
727 | + if len(cell) > 50 { | ||
728 | + var tmpRow []string | ||
729 | + tmpRow = append(tmpRow, tableHeader[j+2]+"长度超过50,请重新输入") // 错误信息 | ||
730 | + s := strconv.Itoa(i + 1) | ||
731 | + tmpRow = append(tmpRow, s) // 行号 | ||
732 | + tmpRow = append(tmpRow, row...) // 错误行数据 | ||
733 | + myRow = tmpRow | ||
734 | + } | ||
735 | + } | ||
736 | + case 6: // 合伙人类型校验(事业合伙、业务合伙、研发合伙、业务-产品应用合伙) | ||
737 | + { | ||
738 | + if !utils.IsContain(partnerType, cell) { | ||
739 | + var tmpRow []string | ||
740 | + tmpRow = append(tmpRow, "合伙人类型须为以下类型:事业合伙、业务合伙、研发合伙、业务-产品应用合伙") // 错误信息 | ||
741 | + s := strconv.Itoa(i + 1) | ||
742 | + tmpRow = append(tmpRow, s) // 行号 | ||
743 | + tmpRow = append(tmpRow, row...) // 错误行数据 | ||
744 | + myRow = tmpRow | ||
745 | + } | ||
746 | + } | ||
747 | + case 7: // 业务员抽成比例,非必填,精确到小数点后两位 | ||
748 | + { | ||
749 | + if len(cell) > 0 { | ||
750 | + _, err := strconv.ParseFloat(cell, 64) | ||
751 | + if err != nil { | ||
752 | + var tmpRow []string | ||
753 | + tmpRow = append(tmpRow, "业务员抽成比例格式错误,请输入正确的业务员抽成比例比例,保留两位小数") // 错误信息 | ||
754 | + s := strconv.Itoa(i + 1) | ||
755 | + tmpRow = append(tmpRow, s) // 行号 | ||
756 | + tmpRow = append(tmpRow, row...) // 错误行数据 | ||
757 | + myRow = tmpRow | ||
758 | + } | ||
759 | + //if isOk, _ := regexp.MatchString("^(.[0-9]{0,1,2})?$", cell); !isOk { // 最多两位小数 | ||
760 | + // var tmpRow []string | ||
761 | + // tmpRow = append(tmpRow, "业务员员抽成比例格式错误,请输入正确的单价,保留两位小数") // 错误信息 | ||
762 | + // s := strconv.Itoa(i + 1) | ||
763 | + // tmpRow = append(tmpRow, s) // 行号 | ||
764 | + // tmpRow = append(tmpRow, row...) // 错误行数据 | ||
765 | + // myRow = tmpRow | ||
766 | + //} | ||
767 | + } | ||
768 | + } | ||
769 | + case 9: // 数量不超过16位正整数 | ||
770 | + { | ||
771 | + _, err := strconv.ParseInt(cell, 10, 64) | ||
772 | + if err != nil { | ||
773 | + var tmpRow []string | ||
774 | + tmpRow = append(tmpRow, "数量须为整数,请重新填写") // 错误信息 | ||
775 | + s := strconv.Itoa(i + 1) | ||
776 | + tmpRow = append(tmpRow, s) // 行号 | ||
777 | + tmpRow = append(tmpRow, row...) // 错误行数据 | ||
778 | + myRow = tmpRow | ||
779 | + } | ||
780 | + | ||
781 | + if len(cell) > 16 { | ||
782 | + var tmpRow []string | ||
783 | + tmpRow = append(tmpRow, "数量长度超过最大限制十六位整数,请重新填写") // 错误信息 | ||
784 | + s := strconv.Itoa(i + 1) | ||
785 | + tmpRow = append(tmpRow, s) // 行号 | ||
786 | + tmpRow = append(tmpRow, row...) // 错误行数据 | ||
787 | + myRow = tmpRow | ||
788 | + } | ||
789 | + } | ||
790 | + case 10: // 单价,精确到小数点后两位,小数点左侧最多可输入16位数字 | ||
791 | + { | ||
792 | + _, err := strconv.ParseFloat(cell, 64) | ||
793 | + if err != nil { | ||
794 | + var tmpRow []string | ||
795 | + tmpRow = append(tmpRow, "单价格式错误,请输入正确的单价,保留两位小数点,小数点前面不能超过十六位数字") // 错误信息 | ||
796 | + s := strconv.Itoa(i + 1) | ||
797 | + tmpRow = append(tmpRow, s) // 行号 | ||
798 | + tmpRow = append(tmpRow, row...) // 错误行数据 | ||
799 | + myRow = tmpRow | ||
800 | + } | ||
801 | + //if isOk, _ := regexp.MatchString("^d{1,16}(.[0-9]{0,1,2})?$", cell); !isOk { // 非负的16位整数最多两位小数 | ||
802 | + // var tmpRow []string | ||
803 | + // tmpRow = append(tmpRow, "单价格式错误,请输入正确的单价,保留两位小数点,小数点前面不能超过十六位数字") // 错误信息 | ||
804 | + // s := strconv.Itoa(i + 1) | ||
805 | + // tmpRow = append(tmpRow, s) // 行号 | ||
806 | + // tmpRow = append(tmpRow, row...) // 错误行数据 | ||
807 | + // myRow = tmpRow | ||
808 | + //} | ||
809 | + } | ||
810 | + case 11: // 合伙人分红比例,精确到小数点后两位 | ||
811 | + { | ||
812 | + _, err := strconv.ParseFloat(cell, 64) | ||
813 | + if err != nil { | ||
814 | + var tmpRow []string | ||
815 | + tmpRow = append(tmpRow, "合伙人分红比例格式错误,请输入正确的合伙人分红比例,保留两位小数") // 错误信息 | ||
816 | + s := strconv.Itoa(i + 1) | ||
817 | + tmpRow = append(tmpRow, s) // 行号 | ||
818 | + tmpRow = append(tmpRow, row...) // 错误行数据 | ||
819 | + myRow = tmpRow | ||
820 | + } | ||
821 | + //if isOk, _ := regexp.MatchString("^(.[0-9]{1,2})?$", cell); !isOk { // 最多两位小数 | ||
822 | + // var tmpRow []string | ||
823 | + // tmpRow = append(tmpRow, "合伙人分红比例错误,请输入正确的合伙人分红比例,保留两位小数") // 错误信息 | ||
824 | + // s := strconv.Itoa(i + 1) | ||
825 | + // tmpRow = append(tmpRow, s) // 行号 | ||
826 | + // tmpRow = append(tmpRow, row...) // 错误行数据 | ||
827 | + // myRow = tmpRow | ||
828 | + //} | ||
829 | + } | ||
830 | + } | ||
831 | + } | ||
832 | + errorLine = append(errorLine, myRow) | ||
833 | + } | ||
834 | + } | ||
835 | + | ||
836 | + if len(errorLine) > 0 { | ||
837 | + ret = map[string]interface{}{ | ||
838 | + "successCount": 0, | ||
839 | + "fail": map[string]interface{}{ | ||
840 | + "tableHeader": tableHeader, | ||
841 | + "tableData": errorLine, | ||
842 | + }, | ||
843 | + } | ||
844 | + c.ResponseData(ret) | ||
845 | + return | ||
846 | + } | ||
847 | + | ||
848 | + // 归类订单 | ||
849 | + for i, row := range rows { | ||
850 | + if i > 2 && len(row) == 13 { | ||
851 | + | ||
852 | + } | ||
853 | + } | ||
854 | + | ||
855 | + // 新增失败记录 | ||
856 | + failureDataList := make([]interface{}, 0) | ||
857 | + | ||
858 | + // 新增成功记录计数 | ||
859 | + //var successDataCount int64 | ||
860 | + | ||
861 | + c.ResponseData(failureDataList) | ||
862 | + | ||
863 | + return | ||
864 | +} |
@@ -36,19 +36,18 @@ func init() { | @@ -36,19 +36,18 @@ func init() { | ||
36 | ), | 36 | ), |
37 | beego.NSNamespace("/order", | 37 | beego.NSNamespace("/order", |
38 | beego.NSRouter("/actual/list", &controllers.OrderInfoController{}, "POST:PageListOrderReal"), | 38 | beego.NSRouter("/actual/list", &controllers.OrderInfoController{}, "POST:PageListOrderReal"), |
39 | - beego.NSRouter("/actual/list/excel", &controllers.OrderInfoController{}, "POST:ListOrderForExcel"), | 39 | + beego.NSRouter("/actual/list/excel", &controllers.OrderInfoController{}, "POST:ListOrderForExcel"), // 导出excel |
40 | + beego.NSRouter("/actual/import/excel", &controllers.OrderInfoController{}, "POST:ImportOrderFromExcel"), // 导入订单数据 | ||
40 | beego.NSRouter("/actual/detail", &controllers.OrderInfoController{}, "POST:GetOrderReal"), | 41 | beego.NSRouter("/actual/detail", &controllers.OrderInfoController{}, "POST:GetOrderReal"), |
41 | beego.NSRouter("/actual/del", &controllers.OrderInfoController{}, "POST:RemoveOrderReal"), | 42 | beego.NSRouter("/actual/del", &controllers.OrderInfoController{}, "POST:RemoveOrderReal"), |
42 | beego.NSRouter("/actual/update", &controllers.OrderInfoController{}, "POST:UpdateOrderReal"), | 43 | beego.NSRouter("/actual/update", &controllers.OrderInfoController{}, "POST:UpdateOrderReal"), |
43 | beego.NSRouter("/actual/close", &controllers.OrderInfoController{}, "POST:OrderDisable"), | 44 | beego.NSRouter("/actual/close", &controllers.OrderInfoController{}, "POST:OrderDisable"), |
44 | ), | 45 | ), |
45 | - | ||
46 | beego.NSNamespace("/common", | 46 | beego.NSNamespace("/common", |
47 | beego.NSRouter("/partner", &controllers.CommonController{}, "POST:GetPartnerList"), | 47 | beego.NSRouter("/partner", &controllers.CommonController{}, "POST:GetPartnerList"), |
48 | beego.NSRouter("/partnerType", &controllers.CommonController{}, "POST:GetPartnerCategory"), | 48 | beego.NSRouter("/partnerType", &controllers.CommonController{}, "POST:GetPartnerCategory"), |
49 | beego.NSRouter("/orderType", &controllers.CommonController{}, "POST:GetOrderType"), | 49 | beego.NSRouter("/orderType", &controllers.CommonController{}, "POST:GetOrderType"), |
50 | ), | 50 | ), |
51 | - | ||
52 | beego.NSNamespace("/enterprises", | 51 | beego.NSNamespace("/enterprises", |
53 | beego.NSRouter("/setPhone", &controllers.CompanyController{}, "POST:SetPhone"), | 52 | beego.NSRouter("/setPhone", &controllers.CompanyController{}, "POST:SetPhone"), |
54 | ), | 53 | ), |
1 | +package utils | ||
2 | + | ||
3 | +import ( | ||
4 | + "github.com/astaxie/beego/context" | ||
5 | + "github.com/linmadan/egglib-go/core/application" | ||
6 | +) | ||
7 | + | ||
8 | +type JsonResponse map[string]interface{} | ||
9 | + | ||
10 | +func ResponseData(ctx *context.Context, data interface{}) JsonResponse { | ||
11 | + jsonResponse := JsonResponse{} | ||
12 | + jsonResponse["code"] = 0 | ||
13 | + jsonResponse["msg"] = "ok" | ||
14 | + jsonResponse["data"] = data | ||
15 | + ctx.Input.SetData("outputData", jsonResponse) | ||
16 | + return jsonResponse | ||
17 | +} | ||
18 | + | ||
19 | +func ResponseError(ctx *context.Context, err error) JsonResponse { | ||
20 | + serviceError := err.(*application.ServiceError) | ||
21 | + jsonResponse := JsonResponse{} | ||
22 | + jsonResponse["code"] = serviceError.Code | ||
23 | + jsonResponse["msg"] = serviceError.Error() | ||
24 | + ctx.Input.SetData("outputData", jsonResponse) | ||
25 | + return jsonResponse | ||
26 | +} |
@@ -105,6 +105,7 @@ github.com/klauspost/compress/zlib | @@ -105,6 +105,7 @@ github.com/klauspost/compress/zlib | ||
105 | github.com/linmadan/egglib-go/core/application | 105 | github.com/linmadan/egglib-go/core/application |
106 | github.com/linmadan/egglib-go/core/domain | 106 | github.com/linmadan/egglib-go/core/domain |
107 | github.com/linmadan/egglib-go/utils/snowflake | 107 | github.com/linmadan/egglib-go/utils/snowflake |
108 | +github.com/linmadan/egglib-go/web/beego/utils | ||
108 | # github.com/mattn/go-colorable v0.1.6 | 109 | # github.com/mattn/go-colorable v0.1.6 |
109 | ## explicit | 110 | ## explicit |
110 | # github.com/matttproud/golang_protobuf_extensions v1.0.1 | 111 | # github.com/matttproud/golang_protobuf_extensions v1.0.1 |
-
请 注册 或 登录 后发表评论