作者 yangfu

生产制造 - 商品导入导出

package query
import "gitlab.fjmaimaimai.com/allied-creation/allied-creation-gateway/pkg/domain"
type SearchProductQuery struct {
// 产品名称
ProductName string `json:"productName,omitempty"`
// 产品类别
ProductCategory string `cname:"产品类别" json:"productCategory"`
//操作人
Operator domain.Operator `json:"-"`
SelectedField []string `json:"selectedField"`
}
... ...
... ... @@ -2,6 +2,7 @@ package service
import (
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-gateway/pkg/infrastructure/service_gateway/allied_creation_manufacture"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-gateway/pkg/application/web/excelData/query"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-gateway/pkg/domain"
... ... @@ -51,3 +52,16 @@ func (srv ExcelDataService) ExportCooperationUser(companyUserListQuery *query.Co
}
return ExportCooperationUserData{SourceData: result.Users, SelectedField: companyUserListQuery.SelectedField}, nil
}
// ExportCooperationUser 导出共创用户信息列表
func (srv ExcelDataService) ExportProducts(cmd *query.SearchProductQuery) (ExportProductsData, error) {
creationUserGateway := allied_creation_manufacture.NewHttpLibAlliedCreationManufacture(cmd.Operator)
result, err := creationUserGateway.SearchProduct(allied_creation_manufacture.SearchProductRequest{
ProductName: cmd.ProductName,
ProductCategory: cmd.ProductCategory,
})
if err != nil {
return ExportProductsData{}, fmt.Errorf("获取企业用户数据失败:%w", err)
}
return ExportProductsData{SourceData: result.Grid.List, SelectedField: cmd.SelectedField}, nil
}
... ...
... ... @@ -2,6 +2,7 @@ package service
import (
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-gateway/pkg/infrastructure/service_gateway/allied_creation_manufacture"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-gateway/pkg/util/converter"
"strings"
... ... @@ -161,6 +162,43 @@ func (srv ExcelDataService) ImportOrganization(importDataCommand *command.Import
return srv.importResultWithHeader(excelImport.DataFields, result.FailRows, len(items)), nil
}
// ImportProduct 导入生产信息
func (srv ExcelDataService) ImportProduct(importDataCommand *command.ImportDataCommand) (interface{}, error) {
excelImport := excel.NewExcelImport()
excelImport.RowBegin = 3 //第二行开始读取
excelImport.DataFields = []excel.DataField{
{EnName: "productCode", CnName: "产品编号"},
{EnName: "productName", CnName: "*品名"},
{EnName: "unit", CnName: "*规格"},
{EnName: "productCategory", CnName: "*类别"},
{EnName: "unitWeight", CnName: "投入单份重量"},
}
excelData, err := converter.OpenImportFileFromIoReader(excelImport, importDataCommand.Reader, importDataCommand.FileExt) //excelImport.OpenExcelFromIoReader(importDataCommand.Reader)
if err != nil {
return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
}
items := make([]*domain.ImportProductItem, 0)
for _, v := range excelData {
item := &domain.ImportProductItem{
ProductCode: strings.TrimSpace(v["productCode"]),
ProductName: strings.TrimSpace(v["productName"]),
ProductCategory: strings.TrimSpace(v["productCategory"]),
Unit: strings.TrimSpace(v["unit"]),
UnitWeight: strings.TrimSpace(v["unitWeight"]),
}
items = append(items, item)
}
svr := allied_creation_manufacture.NewHttpLibAlliedCreationManufacture(importDataCommand.Operator)
result, err := svr.BatchAddProduct(allied_creation_manufacture.BatchAddProductRequest{
List: items,
})
if err != nil {
return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
}
return srv.importResultWithHeader(excelImport.DataFields, *result, len(items)), nil
}
// 导入结果
func (srv ExcelDataService) importResultWithHeader(headers []excel.DataField, failRows []interface{}, totalRow int) interface{} {
var result = map[string]interface{}{
... ...
package service
import (
"fmt"
"github.com/linmadan/egglib-go/utils/excel"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-gateway/pkg/infrastructure/service_gateway/allied_creation_manufacture"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-gateway/pkg/infrastructure/service_gateway/allied_creation_user"
)
... ... @@ -175,3 +177,65 @@ func (data ExportCooperationUserData) DataListLen() int {
func (data ExportCooperationUserData) TableTitle() []string {
return nil
}
//ExportProductsData 导出产品数据
type ExportProductsData struct {
SourceData []allied_creation_manufacture.SearchProductItem
SelectedField []string
}
var _ excel.ExcelMaker = (*ExportProductsData)(nil)
func (data ExportProductsData) AllFields() []DataFieldOptions {
return []DataFieldOptions{
{EnName: "productCode", CnName: "产品编号"},
{EnName: "productName", CnName: "*品名"},
{EnName: "unit", CnName: "*规格"},
{EnName: "productCategory", CnName: "*类别"},
{EnName: "unitWeight", CnName: "投入单份重量"},
}
}
func (data ExportProductsData) DataFieldList() []excel.DataField {
fields := []excel.DataField{}
allFields := data.AllFields()
for _, value2 := range allFields {
if len(data.SelectedField) == 0 || value2.IsDefault {
fields = append(fields, excel.DataField{EnName: value2.EnName, CnName: value2.CnName})
continue
}
for _, value3 := range data.SelectedField {
if value2.EnName == value3 {
fields = append(fields, excel.DataField{EnName: value2.EnName, CnName: value2.CnName})
}
}
}
return fields
}
func (data ExportProductsData) CellValue(index int, enName string) (value interface{}) {
if index > data.DataListLen() {
return ""
}
switch enName {
case "productCode":
return data.SourceData[index].ProductCode
case "productName":
return data.SourceData[index].ProductName
case "unit":
return data.SourceData[index].Unit
case "productCategory":
return data.SourceData[index].ProductCategory
case "unitWeight":
return fmt.Sprintf("%v", data.SourceData[index].UnitWeight)
}
return nil
}
func (data ExportProductsData) DataListLen() int {
return len(data.SourceData)
}
func (data ExportProductsData) TableTitle() []string {
return nil
}
... ...
... ... @@ -27,6 +27,9 @@ var ALLIED_CREATION_USER_HOST = "http://localhost:8081" //"http://allied-creatio
//天联共创业务模块
var ALLIED_CREATION_COOPERATION_HOST = "http://localhost:8082" // "http://allied-creation-cooperation-dev.fjmaimaimai.com"
// 天联共创 生产制造模块
var ALLIED_CREATION_MANUFACTURE_HOST = "http://localhost:8083"
// 版本更新模块
var SUPLUS_ADMIN_BASE_HOST = "http://suplus-admin-base-dev.fjmaimaimai.com"
... ...
... ... @@ -63,6 +63,9 @@ const (
ImportDividendsOrders = "BUSINESS_ALLIED-CREATION_BONUS_ORDER"
// 导入退货订单
ImportDividendsReturnOrders = "BUSINESS_ALLIED-CREATION_BONUS_RETURN"
// 导入产品
ImportProducts = "ImportProducts"
)
const (
... ... @@ -70,6 +73,9 @@ const (
ExportCompanyUser = "ExportCompanyUser"
// 导入共创用户
ExportCooperationUser = "ExportCooperationUser"
// 导入产品
ExportProducts = "ExportProducts"
)
const (
... ...
package domain
// 导入数据体
type ImportProductItem struct {
// 产品编号 编码规则为“CP”+2 位年+2 位月+2 位日+3 位流水码,如 CP211229001
ProductCode string `json:"productCode,omitempty"`
// 产品名称
ProductName string `json:"productName,omitempty"`
// 产品类别
ProductCategory string `json:"productCategory,omitempty"`
// 单位
Unit string `json:"unit,omitempty"`
// 单份重量(原材料)
UnitWeight string `json:"unitWeight,omitempty"`
// 失败理由
FailReason string `json:"failReason"`
}
... ...
package allied_creation_manufacture
import (
"fmt"
"time"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-gateway/pkg/constant"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-gateway/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-gateway/pkg/infrastructure/service_gateway"
)
//HttpLibAlliedCreationManufacture 生产制造模块
type HttpLibAlliedCreationManufacture struct {
service_gateway.BaseServiceGateway
baseUrL string
}
func NewHttpLibAlliedCreationManufacture(operator domain.Operator) *HttpLibAlliedCreationManufacture {
return &HttpLibAlliedCreationManufacture{
BaseServiceGateway: service_gateway.BaseServiceGateway{
ConnectTimeout: 100 * time.Second,
ReadWriteTimeout: 100 * time.Second,
CompanyId: operator.CompanyId,
OrgId: operator.OrgId,
UserId: operator.UserId,
UserBaseId: operator.UserBaseId,
},
baseUrL: constant.ALLIED_CREATION_MANUFACTURE_HOST,
}
}
func (gateway HttpLibAlliedCreationManufacture) BaseUrl() string {
return gateway.baseUrL
}
//BatchAddProduct 批量添加产品
func (gateway HttpLibAlliedCreationManufacture) BatchAddProduct(param BatchAddProductRequest) (*BatchAddProductResponse, error) {
url := fmt.Sprintf("%s%s", gateway.BaseUrl(), "/products/batch-add")
method := "post"
var data BatchAddProductResponse
err := gateway.FastDoRequest(url, method, param, &data)
return &data, err
}
type BatchAddProductRequest struct {
List []*domain.ImportProductItem `json:"list"`
}
type BatchAddProductResponse []interface{}
//BatchAddProduct 批量添加产品
func (gateway HttpLibAlliedCreationManufacture) SearchProduct(param SearchProductRequest) (*SearchProductResponse, error) {
url := fmt.Sprintf("%s%s", gateway.BaseUrl(), "/products/search")
method := "post"
var data SearchProductResponse
err := gateway.FastDoRequest(url, method, param, &data)
return &data, err
}
type (
SearchProductRequest struct {
// 页码
PageNumber int `cname:"页码" json:"pageNumber,omitempty"`
// 页数
PageSize int `cname:"页数" json:"pageSize,omitempty"`
// 产品名称
ProductName string `json:"productName,omitempty"`
// 产品类别
ProductCategory string `cname:"产品类别" json:"productCategory"`
}
SearchProductResponse struct {
Grid struct {
List []SearchProductItem `json:"list"`
Total int `json:"total"`
} `json:"grid"`
}
SearchProductItem struct {
ProductID int `json:"productId"`
ProductCode string `json:"productCode"`
ProductName string `json:"productName"`
ProductCategory string `json:"productCategory"`
Unit string `json:"unit"`
UnitWeight float64 `json:"unitWeight"`
}
)
... ...
... ... @@ -66,3 +66,40 @@ func (gateway BaseServiceGateway) GetResponseData(result GatewayResponse, data i
}
return nil
}
func (gateway BaseServiceGateway) FastDoRequest(url, method string, param interface{}, data interface{}) error {
err := gateway.DoRequest(Request{
Url: url,
Method: method,
Param: param,
}, &data)
if err != nil {
return err
}
return nil
}
func (gateway BaseServiceGateway) DoRequest(requestParam Request, val interface{}) error {
r := gateway.CreateRequest(requestParam.Url, requestParam.Method)
req, err := r.JSONBody(requestParam.Param)
if err != nil {
return err
}
byteResult, err := req.Bytes()
if err != nil {
return err
}
var result GatewayResponse
err = json.Unmarshal(byteResult, &result)
if err != nil {
return err
}
err = gateway.GetResponseData(result, val)
return nil
}
type Request struct {
Url string
Method string
Param interface{}
}
... ...
... ... @@ -2,6 +2,7 @@ package beego
import (
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-gateway/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-gateway/pkg/infrastructure/service_gateway/allied_creation_manufacture"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-gateway/pkg/infrastructure/service_gateway/allied_creation_user"
"net/http"
"os"
... ... @@ -63,6 +64,9 @@ func init() {
//))
web.InsertFilter("/v1/common/user/area/*", web.BeforeRouter, middleware.RedirectInternalService("/v1/common/user", allied_creation_user.NewHttplibAlliedCreationUser(domain.Operator{})))
web.InsertFilter("/v1/manufacture/*", web.BeforeRouter, middleware.CheckAccessToken())
web.InsertFilter("/v1/manufacture/*", web.BeforeRouter, middleware.RedirectInternalService("/v1/manufacture", allied_creation_manufacture.NewHttpLibAlliedCreationManufacture(domain.Operator{})))
}
func AllowCors() func(ctx *context.Context) {
... ...
... ... @@ -209,6 +209,8 @@ func defaultImport(controller *ExcelDataController) {
data, err = excelService.ImportCooperationUser(cmd)
case domain.ImportOrganization:
data, err = excelService.ImportOrganization(cmd)
case domain.ImportProducts:
data, err = excelService.ImportProduct(cmd)
default:
err = fmt.Errorf("导入不存在 Code:%v", cmd.Code)
}
... ... @@ -261,6 +263,12 @@ func fileExport(controller *ExcelDataController, code string) {
companyUserListQuery.Operator = exportDataCommand.Operator
data, err = excelService.ExportCooperationUser(companyUserListQuery)
filename = "导出共创用户"
case domain.ExportProducts:
companyUserListQuery := &query.SearchProductQuery{}
exportDataCommand.UnmarshalQuery(companyUserListQuery)
companyUserListQuery.Operator = exportDataCommand.Operator
data, err = excelService.ExportProducts(companyUserListQuery)
filename = "导出商品"
default:
err = fmt.Errorf("export type :%v not exists", exportDataCommand.Code)
}
... ...
... ... @@ -14,8 +14,8 @@ type CtxKeyLoginToken struct{}
func FormCtxLoginToken(ctx *context.Context) (domain.LoginToken, bool) {
val := ctx.Input.GetData(CtxKeyLoginToken{})
if v, ok := val.(domain.LoginToken); ok {
return v, true
if v, ok := val.(*domain.LoginToken); ok {
return *v, true
}
return domain.LoginToken{}, false
}
... ...
... ... @@ -34,19 +34,19 @@ func RedirectInternalService(prefix string, svr internalService) web.FilterFunc
"code": 1,
"data": struct{}{},
}, false, false)
} else {
ctx.Output.SetStatus(http.StatusOK)
ctx.Output.JSON(map[string]interface{}{
"msg": "成功",
"code": 0,
"data": data,
}, false, false)
}
}()
method := strings.ToLower(ctx.Request.Method)
url := strings.Replace(ctx.Request.RequestURI, prefix, "", 1)
req := svr.CreateRequest(svr.BaseUrl()+url, method)
// 传递当前登录信息(可配置)
loginToken, ok := FormCtxLoginToken(ctx)
if ok && loginToken.CompanyId > 0 && loginToken.OrgId > 0 {
req.Header("companyId", fmt.Sprintf("%v", loginToken.CompanyId))
req.Header("orgId", fmt.Sprintf("%v", loginToken.OrgId))
}
req.Body(ctx.Input.RequestBody)
response, err := req.Response()
if err != nil {
... ... @@ -63,6 +63,13 @@ func RedirectInternalService(prefix string, svr internalService) web.FilterFunc
}
defer response.Body.Close()
// 透传非json数据
contentType := response.Header.Get("Content-Type")
if contentType != "application/json" {
copyResponse(ctx, response, byteResult)
return
}
var result service_gateway.GatewayResponse
err = json.Unmarshal(byteResult, &result)
if err != nil {
... ... @@ -70,5 +77,25 @@ func RedirectInternalService(prefix string, svr internalService) web.FilterFunc
}
err = svr.GetResponseData(result, &data)
if err != nil {
return
}
ctx.Output.SetStatus(http.StatusOK)
ctx.Output.JSON(map[string]interface{}{
"msg": "成功",
"code": 0,
"data": data,
}, false, false)
}
}
func copyResponse(ctx *context.Context, response *http.Response, data []byte) {
for k, v := range response.Header {
if len(v) == 0 {
continue
}
ctx.Output.Header(k, strings.Join(v, ","))
}
ctx.Output.SetStatus(response.StatusCode)
ctx.Output.Body(data)
}
... ...