windows-pc hai 1 día
pai
achega
8b2527f13a

+ 1 - 0
sku3d/sku3d/Dockerfile

@@ -11,6 +11,7 @@ RUN echo -e https://mirrors.ustc.edu.cn/alpine/v3.15/main > /etc/apk/repositorie
 
 WORKDIR /root/sku3d
 
+ADD ./template.xlsx ./template.xlsx
 ADD ./app.yaml ./app.yaml
 ADD ./sku3dweb-service ./sku3dweb-service
 

+ 29 - 0
sku3d/sku3d/a.json

@@ -0,0 +1,29 @@
+ [
+        {
+            "idStr": "QFFMtls1bioUIUHBTWtbx",
+            "name": "商品分类",
+            "children": [
+                {
+                    "idStr": "bLBljOT-mNL3Wo2QEo6to",
+                    "cusNum": "V",
+                    "name": "革PVC",
+                    "children": [
+                        {
+                            "idStr": "VZ3KfoENGnDBI7H_ZdTS4",
+                            "name": "种类分类",
+                            "children": [
+                                {
+                                    "idStr": "185Lskk7uYZg0MB19gbvM",
+                                    "cusNum": "G2V",
+                                    "name": "PVC",
+                                    "children": null
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ]
+        }
+       
+]
+

+ 534 - 3
sku3d/sku3d/api/a-excel.go

@@ -41,6 +41,7 @@ func RegExcelRouter(router *GinRouter) {
 	// router.POSTJWT("/excel/import", ExcelImport)
 	// router.GETJWT("/excel/export", ExcelExport)
 	router.POSTJWT("/zip/import", ZipImport)
+	router.GET("/zip/export", ZipExport)
 }
 
 func ExcelImportWithImages(c *gin.Context, apictx *ApiSession, file io.Reader, goodsDir, textureDir string) (interface{}, error) {
@@ -152,7 +153,7 @@ func ExcelImportWithImages(c *gin.Context, apictx *ApiSession, file io.Reader, g
 
 		imageMat.Categories = append(imageMat.Categories, row3Cate.IdStr)
 
-		// TODO 跳过图片 后面统一处理
+		// 跳过图片 后面统一处理
 		var str2float64 = func(s string) float64 {
 			f, err := strconv.ParseFloat(s, 64)
 			if err != nil {
@@ -523,6 +524,16 @@ func ZipImport(c *gin.Context, apictx *ApiSession) (interface{}, error) {
 	}
 	defer os.RemoveAll(tempDir) // 确保处理完成后删除临时目录
 
+	// 创建goods和texture子目录
+	goodsDir := filepath.Join(tempDir, "goods")
+	textureDir := filepath.Join(tempDir, "texture")
+	if err := os.Mkdir(goodsDir, 0755); err != nil {
+		return nil, NewError("创建goods目录失败")
+	}
+	if err := os.Mkdir(textureDir, 0755); err != nil {
+		return nil, NewError("创建texture目录失败")
+	}
+
 	// 保存上传的ZIP文件
 	zipFilePath := path.Join(tempDir, "upload.zip")
 	tempZipFile, err := os.Create(zipFilePath)
@@ -563,8 +574,8 @@ func ZipImport(c *gin.Context, apictx *ApiSession) (interface{}, error) {
 	defer excelFile.Close()
 
 	// 商品图片目录和纹理图片目录
-	goodsDir := path.Join(extractDir, "goods")
-	textureDir := path.Join(extractDir, "texture")
+	goodsDir = path.Join(extractDir, "goods")
+	textureDir = path.Join(extractDir, "texture")
 
 	// 检查目录是否存在
 	if _, err := os.Stat(goodsDir); os.IsNotExist(err) {
@@ -699,3 +710,523 @@ func getImageUrl(oss *model.OssType) string {
 	}
 	return oss.Url
 }
+
+type ZipExportReq struct {
+	MatIds []primitive.ObjectID `json:"matIds"`
+}
+
+// ZIP导出功能
+func ZipExport(c *gin.Context, apictx *ApiSession) (interface{}, error) {
+	// 获取要导出的matIds参数
+	var req ZipExportReq
+	err := c.ShouldBindJSON(&req)
+	if err != nil {
+		return nil, fmt.Errorf("参数错误!")
+	}
+	if len(req.MatIds) == 0 {
+		return nil, fmt.Errorf("参数错误!")
+	}
+	// matId, _ := primitive.ObjectIDFromHex("67f4711195ac3622e01cc073")
+	// matId2, _ := primitive.ObjectIDFromHex("67f4710695ac3622e01cc072")
+	// req.MatIds = []primitive.ObjectID{matId, matId2}
+
+	// 创建临时目录
+	tempDir, err := os.MkdirTemp("", "zipexport_"+time.Now().Format("2006"))
+	if err != nil {
+		return nil, NewError("创建临时目录失败")
+	}
+	defer os.RemoveAll(tempDir) // 函数结束时清理临时目录
+
+	// 创建goods和texture子目录
+	goodsDir := filepath.Join(tempDir, "goods")
+	textureDir := filepath.Join(tempDir, "texture")
+	if err := os.Mkdir(goodsDir, 0755); err != nil {
+		return nil, NewError("创建goods目录失败")
+	}
+	if err := os.Mkdir(textureDir, 0755); err != nil {
+		return nil, NewError("创建texture目录失败")
+	}
+
+	// 转换matIds为ObjectID数组
+	objectIds := req.MatIds
+
+	// 查询MatImage记录
+	var matImages []model.MatImage
+	err = repo.RepoSeachDocs(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
+		CollectName: repo.CollectionMatImages,
+		Query:       repo.Map{"_id": repo.Map{"$in": objectIds}},
+	}, &matImages)
+	if err != nil {
+		return nil, NewError("获取商品数据失败")
+	}
+
+	// 获取分类配置
+	cat := []*model.Category{}
+	err = repo.RepoSeachDocs(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
+		CollectName: repo.CollectionCategory,
+		Query:       repo.Map{},
+		Project:     []string{"name", "type", "children", "createTime"},
+	}, &cat)
+	if err != nil {
+		return nil, NewError("获取分类配置失败")
+	}
+	cates := cat[0].Children
+
+	// 使用模板文件
+	templatePath := "./template.xlsx"
+	// 打开模板文件
+	f, err := excelize.OpenFile(templatePath)
+	if err != nil {
+		return nil, NewError("打开模板文件失败")
+	}
+	defer f.Close()
+
+	sheet := "Sheet1"
+
+	// 填充数据
+	for i, img := range matImages {
+		rowIndex := i + 2 // 跳过表头,从第2行开始
+
+		// 下载图片
+		var goodsImagePath, textureImagePath string
+		if img.ProductImage != nil && img.ProductImage.Url != "" {
+			// 从URL中提取原始文件名
+			productImageFileName := getFileNameFromUrl(img.ProductImage.Url)
+			goodsImagePath = filepath.Join(goodsDir, productImageFileName)
+			downloadImage(img.ProductImage.Url, goodsImagePath)
+		}
+		if img.RawImage != nil && img.RawImage.Url != "" {
+			// 从URL中提取原始文件名
+			rawImageFileName := getFileNameFromUrl(img.RawImage.Url)
+			textureImagePath = filepath.Join(textureDir, rawImageFileName)
+			downloadImage(img.RawImage.Url, textureImagePath)
+		}
+
+		// 查找对应的分类名称
+		var typeCategoryName, MainSupplierName, MnemonicSign, TypeCategory2, TypeCategory2Name, productSeriesName, productUsageName string
+		var typeCategory, productSeries, productUsage, baseCloth, baseClothName, surfaceProcess, surfaceProcessName string
+
+		// 先确定商品分类大类/其他大类 排除后用其他id匹配商品分类下面的小类
+		var mainCate *model.Category
+		matCatesMap := map[string]struct{}{}
+		// 复制分类ID到Map中,便于删除已处理的ID
+		for _, ic := range img.Categories {
+			if ic != "" { // 确保分类ID不为空
+				matCatesMap[ic] = struct{}{}
+			}
+		}
+
+		// 第一轮:查找顶级分类(商品分类、首选供应商、报关助记符)
+		for _, catId := range img.Categories {
+			if catId == "" { // 跳过空分类ID
+				continue
+			}
+
+			for _, parentCat := range cates {
+				if parentCat == nil { // 防止空指针
+					continue
+				}
+
+				for _, child := range parentCat.Children {
+					if child == nil || child.IdStr == "" { // 防止空指针或空ID
+						continue
+					}
+
+					if child.IdStr == catId {
+						if parentCat.Name == "商品分类" {
+							mainCate = child
+							typeCategoryName = child.Name
+							typeCategory = catId
+							delete(matCatesMap, catId)
+						} else if parentCat.Name == "首选供应商" {
+							MainSupplierName = child.Name
+							delete(matCatesMap, catId)
+						} else if parentCat.Name == "报关助记符" {
+							MnemonicSign = child.Name
+							delete(matCatesMap, catId)
+						}
+					}
+				}
+			}
+		}
+
+		// 第二轮:如果找到了商品分类,查找其子分类
+		if mainCate != nil && len(matCatesMap) > 0 {
+			for k := range matCatesMap {
+				if k == "" { // 跳过空ID
+					continue
+				}
+
+				// 防止空指针
+				if mainCate.Children == nil {
+					continue
+				}
+
+				for _, mchild := range mainCate.Children {
+					if mchild == nil || mchild.Children == nil { // 防止空指针
+						continue
+					}
+
+					for _, mc := range mchild.Children {
+						if mc == nil || mc.IdStr == "" { // 防止空指针或空ID
+							continue
+						}
+
+						if mc.IdStr == k {
+							if mchild.Name == "种类分类" {
+								TypeCategory2 = mc.CusNum
+								TypeCategory2Name = mc.Name
+							} else if mchild.Name == "产品系列" {
+								productSeriesName = mc.Name
+								productSeries = mc.CusNum
+							} else if mchild.Name == "产品用途" {
+								productUsageName = mc.Name
+								productUsage = mc.CusNum
+							} else if mchild.Name == "基布" {
+								baseCloth = mc.CusNum
+								baseClothName = mc.Name
+							} else if mchild.Name == "表面工艺" {
+								surfaceProcess = mc.CusNum
+								surfaceProcessName = mc.Name
+							}
+						}
+					}
+				}
+			}
+		}
+
+		// 构建行数据
+		f.SetCellValue(sheet, fmt.Sprintf("A%d", rowIndex), img.CusNum)       // 公司商品编号
+		f.SetCellValue(sheet, fmt.Sprintf("B%d", rowIndex), img.NameCN)       // 商品中文名
+		f.SetCellValue(sheet, fmt.Sprintf("C%d", rowIndex), img.NameEN)       // 商品英文名
+		f.SetCellValue(sheet, fmt.Sprintf("D%d", rowIndex), typeCategoryName) // 分类
+		f.SetCellValue(sheet, fmt.Sprintf("E%d", rowIndex), "")               // 图片
+
+		// 体积重量信息
+		if img.PackageGrossWeight != nil {
+			f.SetCellValue(sheet, fmt.Sprintf("F%d", rowIndex), *img.PackageGrossWeight) // 单位包材毛重(KG)
+		} else {
+			f.SetCellValue(sheet, fmt.Sprintf("F%d", rowIndex), 0) // 默认为0
+		}
+
+		if img.PackageVolume != nil {
+			f.SetCellValue(sheet, fmt.Sprintf("G%d", rowIndex), *img.PackageVolume) // 单位包材体积(CBM)
+		} else {
+			f.SetCellValue(sheet, fmt.Sprintf("G%d", rowIndex), 0) // 默认为0
+		}
+
+		if img.PhyHeight != nil {
+			f.SetCellValue(sheet, fmt.Sprintf("H%d", rowIndex), *img.PhyHeight) // 长度(MM)
+		} else {
+			f.SetCellValue(sheet, fmt.Sprintf("H%d", rowIndex), 0) // 默认为0
+		}
+
+		if img.PhyWidth != nil {
+			f.SetCellValue(sheet, fmt.Sprintf("I%d", rowIndex), *img.PhyWidth) // 门幅/宽(MM)
+		} else {
+			f.SetCellValue(sheet, fmt.Sprintf("I%d", rowIndex), 0) // 默认为0
+		}
+
+		if img.Thickness != nil {
+			f.SetCellValue(sheet, fmt.Sprintf("J%d", rowIndex), *img.Thickness) // 厚度/高(MM)
+		} else {
+			f.SetCellValue(sheet, fmt.Sprintf("J%d", rowIndex), 0) // 默认为0
+		}
+
+		f.SetCellValue(sheet, fmt.Sprintf("K%d", rowIndex), img.Remarks)      // 备注
+		f.SetCellValue(sheet, fmt.Sprintf("L%d", rowIndex), MainSupplierName) // 首选供应商
+
+		// 默认采购单价
+		if img.Price != nil {
+			f.SetCellValue(sheet, fmt.Sprintf("M%d", rowIndex), *img.Price)
+		} else {
+			f.SetCellValue(sheet, fmt.Sprintf("M%d", rowIndex), "")
+		}
+
+		// 查询样品搜集人的名称
+		staffName := ""
+		staffId := ""
+		if img.From != "" {
+			staff := model.StaffUser{}
+			found, _ := repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
+				CollectName: repo.CollectionStaffUser,
+				Query:       repo.Map{"name": img.From},
+			}, &staff)
+			if found {
+				staffName = staff.Name
+				staffId = staff.Id.Hex()
+			}
+		}
+		// 样品搜集人 - 注意Excel示例中有两列样品搜集人
+		f.SetCellValue(sheet, fmt.Sprintf("N%d", rowIndex), staffId) // 样品搜集人代码
+
+		f.SetCellValue(sheet, fmt.Sprintf("O%d", rowIndex), staffName) // 样品搜集人名称
+
+		// 开发日期
+		if img.DevTime != nil {
+			f.SetCellValue(sheet, fmt.Sprintf("P%d", rowIndex), img.DevTime.Format("2006/1/2"))
+		} else {
+			f.SetCellValue(sheet, fmt.Sprintf("P%d", rowIndex), "")
+		}
+
+		// 商品属性 - 使用True/False字符串而不是布尔值
+		if img.ExportProperty != nil {
+			f.SetCellValue(sheet, fmt.Sprintf("Q%d", rowIndex), boolToString(*img.ExportProperty)) // 出口属性
+		} else {
+			f.SetCellValue(sheet, fmt.Sprintf("Q%d", rowIndex), "False")
+		}
+
+		if img.DomesticProperty != nil {
+			f.SetCellValue(sheet, fmt.Sprintf("R%d", rowIndex), boolToString(*img.DomesticProperty)) // 内销属性
+		} else {
+			f.SetCellValue(sheet, fmt.Sprintf("R%d", rowIndex), "False")
+		}
+
+		if img.InpurchaseProperty != nil {
+			f.SetCellValue(sheet, fmt.Sprintf("S%d", rowIndex), boolToString(*img.InpurchaseProperty)) // 内购属性
+		} else {
+			f.SetCellValue(sheet, fmt.Sprintf("S%d", rowIndex), "False")
+		}
+
+		if img.OutsourcedProperty != nil {
+			f.SetCellValue(sheet, fmt.Sprintf("T%d", rowIndex), boolToString(*img.OutsourcedProperty)) // 委外属性
+		} else {
+			f.SetCellValue(sheet, fmt.Sprintf("T%d", rowIndex), "False")
+		}
+
+		f.SetCellValue(sheet, fmt.Sprintf("U%d", rowIndex), MnemonicSign)       // 报关助记符
+		f.SetCellValue(sheet, fmt.Sprintf("V%d", rowIndex), img.TaxGoodsNumber) // 报关商品编码
+		f.SetCellValue(sheet, fmt.Sprintf("W%d", rowIndex), img.TaxNameCN)      // 报关商品中文名
+
+		// 录入人名称
+		// f.SetCellValue(sheet, fmt.Sprintf("X%d", rowIndex), apictx.User.Name) // 录入人名称
+		f.SetCellValue(sheet, fmt.Sprintf("X%d", rowIndex), "测试默认") // 录入人名称
+
+		f.SetCellValue(sheet, fmt.Sprintf("Y%d", rowIndex), img.FitMarket)       // 适合的市场
+		f.SetCellValue(sheet, fmt.Sprintf("Z%d", rowIndex), img.SupplierID)      // 供应商编号
+		f.SetCellValue(sheet, fmt.Sprintf("AA%d", rowIndex), TypeCategory2)      // 种类分类
+		f.SetCellValue(sheet, fmt.Sprintf("AB%d", rowIndex), TypeCategory2Name)  // 种类分类名称
+		f.SetCellValue(sheet, fmt.Sprintf("AC%d", rowIndex), baseCloth)          // 基布
+		f.SetCellValue(sheet, fmt.Sprintf("AD%d", rowIndex), baseClothName)      // 基布名称
+		f.SetCellValue(sheet, fmt.Sprintf("AE%d", rowIndex), surfaceProcess)     // 表面工艺
+		f.SetCellValue(sheet, fmt.Sprintf("AF%d", rowIndex), surfaceProcessName) // 表面工艺名称
+
+		// 产品克重
+		if img.ProductWeight != nil {
+			f.SetCellValue(sheet, fmt.Sprintf("AG%d", rowIndex), *img.ProductWeight) // 产品克重(KG)
+		} else {
+			f.SetCellValue(sheet, fmt.Sprintf("AG%d", rowIndex), 0)
+		}
+
+		f.SetCellValue(sheet, fmt.Sprintf("AH%d", rowIndex), img.OperationCycle) // 运营周期
+
+		// 商品单位体积
+		if img.ProductVolume != nil {
+			f.SetCellValue(sheet, fmt.Sprintf("AI%d", rowIndex), *img.ProductVolume) // 商品单位体积
+		} else {
+			f.SetCellValue(sheet, fmt.Sprintf("AI%d", rowIndex), 0)
+		}
+
+		// 商品分类代码
+		// !!!! 商品分类代码哪个字段未明确
+		f.SetCellValue(sheet, fmt.Sprintf("AJ%d", rowIndex), typeCategory)       // 商品分类代码
+		f.SetCellValue(sheet, fmt.Sprintf("AK%d", rowIndex), productSeries)      // 产品系列
+		f.SetCellValue(sheet, fmt.Sprintf("AL%d", rowIndex), productSeriesName)  // 产品系列代码
+		f.SetCellValue(sheet, fmt.Sprintf("AM%d", rowIndex), productUsage)       // 产品用途
+		f.SetCellValue(sheet, fmt.Sprintf("AN%d", rowIndex), productUsageName)   // 产品用途代码
+		f.SetCellValue(sheet, fmt.Sprintf("AO%d", rowIndex), img.SampleNumber)   // 样品编号
+		f.SetCellValue(sheet, fmt.Sprintf("AP%d", rowIndex), img.CatalogNumber)  // 留样册号
+		f.SetCellValue(sheet, fmt.Sprintf("AQ%d", rowIndex), img.OriginalNumber) // 原命名编号
+
+		// 底布克重
+		if img.BackingWeight != nil {
+			f.SetCellValue(sheet, fmt.Sprintf("AR%d", rowIndex), *img.BackingWeight) // 底布克重
+		} else {
+			f.SetCellValue(sheet, fmt.Sprintf("AR%d", rowIndex), 0)
+		}
+
+		// 面布克重
+		if img.SurfaceWeight != nil {
+			f.SetCellValue(sheet, fmt.Sprintf("AS%d", rowIndex), *img.SurfaceWeight) // 面布克重
+		} else {
+			f.SetCellValue(sheet, fmt.Sprintf("AS%d", rowIndex), 0)
+		}
+	}
+
+	// 调整列宽
+	for i := range fixedHeaders {
+		colName := string(rune('A' + i))
+		f.SetColWidth(sheet, colName, colName, 15)
+	}
+
+	// 保存Excel到临时目录
+	excelPath := filepath.Join(tempDir, "export.xlsx")
+	if err := f.SaveAs(excelPath); err != nil {
+		return nil, NewError("保存Excel文件失败")
+	}
+
+	// 创建ZIP文件
+	zipPath := filepath.Join(tempDir, "export.zip")
+	zipFile, err := os.Create(zipPath)
+	if err != nil {
+		return nil, NewError("创建ZIP文件失败")
+	}
+	defer zipFile.Close()
+
+	// 创建ZIP writer
+	zipWriter := zip.NewWriter(zipFile)
+	defer zipWriter.Close()
+
+	// 添加Excel文件到ZIP
+	if err := addFileToZip(zipWriter, excelPath, "export.xlsx"); err != nil {
+		return nil, NewError("添加Excel文件到ZIP失败")
+	}
+
+	// 添加goods目录到ZIP
+	if err := addDirToZip(zipWriter, goodsDir, "goods"); err != nil {
+		return nil, NewError("添加goods目录到ZIP失败")
+	}
+
+	// 添加texture目录到ZIP
+	if err := addDirToZip(zipWriter, textureDir, "texture"); err != nil {
+		return nil, NewError("添加texture目录到ZIP失败")
+	}
+
+	// 关闭ZIP writer
+	zipWriter.Close()
+
+	// 读取ZIP文件内容
+	zipData, err := os.ReadFile(zipPath)
+	if err != nil {
+		return nil, NewError("读取ZIP文件失败")
+	}
+
+	// 设置响应头,使浏览器下载文件
+	c.Header("Content-Description", "File Transfer")
+	c.Header("Content-Disposition", "attachment; filename=export_"+time.Now().Format("20060102150405")+".zip")
+	c.Data(http.StatusOK, "application/zip", zipData)
+
+	return nil, nil
+}
+
+// 下载图片到本地文件
+func downloadImage(url string, destPath string) error {
+	// 发起HTTP GET请求
+	resp, err := http.Get(url)
+	if err != nil {
+		return err
+	}
+	defer resp.Body.Close()
+
+	// 检查响应状态
+	if resp.StatusCode != http.StatusOK {
+		return fmt.Errorf("下载图片失败,状态码: %d", resp.StatusCode)
+	}
+
+	// 创建目标文件
+	out, err := os.Create(destPath)
+	if err != nil {
+		return err
+	}
+	defer out.Close()
+
+	// 将响应内容写入文件
+	_, err = io.Copy(out, resp.Body)
+	return err
+}
+
+// 添加文件到ZIP
+func addFileToZip(zipWriter *zip.Writer, filePath, zipPath string) error {
+	file, err := os.Open(filePath)
+	if err != nil {
+		return err
+	}
+	defer file.Close()
+
+	info, err := file.Stat()
+	if err != nil {
+		return err
+	}
+
+	header, err := zip.FileInfoHeader(info)
+	if err != nil {
+		return err
+	}
+	header.Name = zipPath
+	header.Method = zip.Deflate
+
+	writer, err := zipWriter.CreateHeader(header)
+	if err != nil {
+		return err
+	}
+
+	_, err = io.Copy(writer, file)
+	return err
+}
+
+// 添加目录到ZIP
+func addDirToZip(zipWriter *zip.Writer, dirPath, zipPath string) error {
+	files, err := os.ReadDir(dirPath)
+	if err != nil {
+		return err
+	}
+
+	// 先创建目录条目
+	if zipPath != "" {
+		dirEntry := &zip.FileHeader{
+			Name:   zipPath + "/",
+			Method: zip.Deflate,
+		}
+		dirEntry.SetMode(0755 | os.ModeDir)
+		_, err = zipWriter.CreateHeader(dirEntry)
+		if err != nil {
+			return err
+		}
+	}
+
+	for _, file := range files {
+		filePath := filepath.Join(dirPath, file.Name())
+		// 使用斜杠作为ZIP文件中的路径分隔符,确保跨平台兼容性
+		zipFilePath := zipPath + "/" + file.Name()
+		if zipPath == "" {
+			zipFilePath = file.Name()
+		}
+
+		if file.IsDir() {
+			// 递归添加子目录
+			if err := addDirToZip(zipWriter, filePath, zipFilePath); err != nil {
+				return err
+			}
+		} else {
+			// 添加文件
+			if err := addFileToZip(zipWriter, filePath, zipFilePath); err != nil {
+				return err
+			}
+		}
+	}
+
+	return nil
+}
+
+// 工具函数 - 格式化日期
+func formatDate(t *time.Time) string {
+	if t == nil {
+		return ""
+	}
+	return t.Format("2006-01-02")
+}
+
+// 工具函数 - 将布尔值转换为字符串
+func boolToString(b bool) string {
+	if b {
+		return "True"
+	}
+	return "False"
+}
+
+// 工具函数 - 从URL中提取文件名
+func getFileNameFromUrl(url string) string {
+	// 从URL中提取文件名
+	fileName := path.Base(url)
+	return fileName
+}

+ 1 - 0
sku3d/sku3d/api/router.go

@@ -19,6 +19,7 @@ func RegRouters(svc *Service) {
 	FassiApi(spud3dGroup)
 	CreateCatRouter(spud3dGroup)
 	RegStaffUserRouter(spud3dGroup)
+	RegExcelRouter(spud3dGroup)
 	spud3dGroup.GET("upload/policy", UploadPolicy)
 }
 

+ 1 - 0
sku3d/sku3d/app.yaml

@@ -3,6 +3,7 @@ port: 7902
 
 nats:
   # url: nats://47.96.90.34:14223
+  # url: nats://122.51.156.94:14223
   url: nats://comm-bus:4222
   maxReconnect: 1000
   reconnDelaySecond: 5

BIN=BIN
sku3d/sku3d/template.xlsx