diff --git a/app/admin/apis/inventorymanage/report.go b/app/admin/apis/inventorymanage/report.go index c2f3a68..fcce617 100644 --- a/app/admin/apis/inventorymanage/report.go +++ b/app/admin/apis/inventorymanage/report.go @@ -103,7 +103,14 @@ func InventoryReportByOther(c *gin.Context) { return } - app.OK(c, "", "OK") + resp, err := req.ReportByOtherList(c) + if err != nil { + //logger.Error("erp commodity list err:", err) + app.Error(c, http.StatusInternalServerError, err, "查询失败:"+err.Error()) + return + } + + app.OK(c, resp, "OK") return } @@ -122,6 +129,13 @@ func InventoryReportOtherDetail(c *gin.Context) { return } - app.OK(c, "", "OK") + resp, err := req.ReportByOtherDetailList(c) + if err != nil { + //logger.Error("erp commodity list err:", err) + app.Error(c, http.StatusInternalServerError, err, "查询失败:"+err.Error()) + return + } + + app.OK(c, resp, "OK") return } diff --git a/app/admin/models/commodity.go b/app/admin/models/commodity.go index c4af5c5..e00a5d2 100644 --- a/app/admin/models/commodity.go +++ b/app/admin/models/commodity.go @@ -32,7 +32,7 @@ const ( PurchaseReturn = 3 // 采购退货 InAllot = 4 // 调拨中(调入门店) OnSale = 5 // 销售锁定中 - ProductReturn = 6 // 产品出库 + SystemOut = 6 // 系统出库 CheckOut = 7 // 盘点出库 ) @@ -2171,9 +2171,9 @@ func SetStockCommodityState(id uint32) error { //更新库存状态为5,并同 return err } - // 更新商品库存详情表状态为5:出库 + // 更新商品库存详情表状态为6:系统出库 if err := begin.Model(&ErpStockCommodity{}).Where("id=?", id).Updates(map[string]interface{}{ - "state": 5}).Error; err != nil { + "state": SystemOut}).Error; err != nil { return fmt.Errorf("[update err]:%v", err) } diff --git a/app/admin/models/inventory_report.go b/app/admin/models/inventory_report.go index 1921e8b..f9bce2c 100644 --- a/app/admin/models/inventory_report.go +++ b/app/admin/models/inventory_report.go @@ -163,7 +163,7 @@ type InventoryReportByOtherResp struct { Total int `json:"total"` // 总条数/记录数 PageIndex int `json:"pageIndex"` // 页码 PageSize int `json:"pageSize"` // 页面条数 - TotalCount int32 `json:"total_count"` // 总数量 + TotalCount uint32 `json:"total_count"` // 总数量 TotalAmount float64 `json:"total_amount"` // 总金额 ExportUrl string `json:"export_url"` // 导出excel路径 List []ReportByOtherData `json:"list"` // @@ -177,8 +177,8 @@ type ReportByOtherData struct { CommodityName string `json:"commodity_name"` // 商品名称 CategoryID uint32 `json:"category_id"` // 商品分类id CategoryName string `json:"category_name"` // 商品分类名称 - State uint32 `json:"state"` // 调拨状态:1-产品入库 2-盘点入库 3-系统出库 4-盘点出库 - Count int32 `json:"count"` // 数量 + Type uint32 `json:"type"` // 调拨状态:1-产品入库 2-盘点入库 3-系统出库 4-盘点出库 + Count int64 `json:"count"` // 数量 Amount float64 `json:"amount"` // 金额 } @@ -188,7 +188,7 @@ type InventoryReportOtherDetailReq struct { StoreId []uint32 `json:"store_id"` // 门店id CommodityName []string `json:"commodity_name"` // 商品名称 CategoryID []uint32 `json:"category_id"` // 商品分类id - State uint32 `json:"state"` // 调拨状态:1-产品入库 2-盘点入库 3-系统出库 4-盘点出库 + Type uint32 `json:"type"` // 出入库方式:1-产品入库 2-盘点入库 3-系统出库 4-盘点出库 StartTime string `json:"start_time"` // 开始时间/入库时间 EndTime string `json:"end_time"` // 结束时间/出库时间 IsExport uint32 `json:"is_export"` // 1-导出 @@ -220,7 +220,7 @@ type ReportOtherDetailData struct { SupplierId uint32 `json:"supplier_id"` // 供应商id SupplierName string `json:"supplier_name"` // 供应商名称 StockTime *time.Time `json:"stock_time"` // 出入库时间 - State uint32 `json:"state"` // 调拨状态:1-产品入库 2-盘点入库 3-系统出库 4-盘点出库 + Type uint32 `json:"type"` // 调拨状态:1-产品入库 2-盘点入库 3-系统出库 4-盘点出库 SerialNumber string `json:"serial_number"` // 单据编号 PurchasePrice float64 `json:"purchase_price"` // 入库采购价 EmployeePrice float64 `json:"employee_price"` // 入库员工成本价 @@ -1150,3 +1150,608 @@ func reportAllotDetailExport(req *InventoryReportAllotDetailResp) (string, error } return url + fileName, nil } + +// ReportByOtherList 其他出入库汇总 +func (m *InventoryReportByOtherReq) ReportByOtherList(c *gin.Context) (*InventoryReportByOtherResp, error) { + // 非管理员才判断所属门店 + if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") { + sysUser, err := GetSysUserByCtx(c) + if err != nil { + return nil, errors.New("操作失败:" + err.Error()) + } + + // 返回sysUser未过期的门店id列表 + storeList := GetValidStoreIDs(sysUser.StoreData) + if len(storeList) > 0 { + m.StoreId = CompareLists(storeList, m.StoreId) + if len(m.StoreId) == 0 { // 没有匹配的数据,表示入参门店不是用户有权限的门店 + return &InventoryReportByOtherResp{}, nil + } + } else { + return nil, errors.New("用户未绑定门店") + } + } + + resp := &InventoryReportByOtherResp{ + PageIndex: m.PageIndex, + PageSize: m.PageSize, + } + page := m.PageIndex - 1 + if page < 0 { + page = 0 + } + if m.PageSize == 0 { + m.PageSize = 10 + } + + // 查询产品入库数据 + var err error + var productList []ReportOtherDetailData + productList, err = getProductOrderData() + if err != nil { + return nil, err + } + + // 查询盘点出入库数据 + var changeList []ReportOtherDetailData + changeList, err = getChangeOrderData() + if err != nil { + return nil, err + } + + // 查询系统出库数据 + var systemList []ReportOtherDetailData + systemList, err = getSystemOutData() + if err != nil { + return nil, err + } + + // 合并数据 + allData := append(productList, changeList...) + allData = append(allData, systemList...) + + var nTotalAllotCount uint32 + var nTotalAllotAmount float64 + // 创建 map 用于存储汇总数据 + summaryMap := make(map[string]*ReportByOtherData) + // 遍历切片 + for _, item := range allData { + if item.Type == 3 || item.Type == 4 { + nTotalAllotCount -= 1 + nTotalAllotAmount -= item.PurchasePrice + } else { + nTotalAllotCount += 1 + nTotalAllotAmount += item.PurchasePrice + } + + // 生成键 + key := fmt.Sprintf("%d_%d_%d", item.CommodityId, item.StoreId, item.Type) + // 检查是否已经存在该键的汇总数据 + if summary, ok := summaryMap[key]; ok { + // 如果已经存在,累加调拨数量和调拨金额 + summary.Count += 1 + // 假设商品金额在 item.CommodityAmount 中 + summary.Amount += item.PurchasePrice + } else { + // 如果不存在,创建新的汇总数据并添加到 map 中 + summaryMap[key] = &ReportByOtherData{ + StoreId: item.StoreId, + StoreName: item.StoreName, + CommodityId: item.CommodityId, + CommodityName: item.CommodityName, + CategoryID: item.CategoryID, + CategoryName: item.CategoryName, + Type: item.Type, + Count: 1, // 初始化为 1 + Amount: item.PurchasePrice, + } + } + } + + var summaryList []ReportByOtherData + for i, summary := range summaryMap { + // 添加分类信息 + commodityInfo, err := GetCommodity(summary.CommodityId) + if err != nil { + logger.Error("SetCategory err:", logger.Field("err", err)) + } + summaryMap[i].CategoryID = commodityInfo.ErpCategoryId + summaryMap[i].CategoryName = commodityInfo.ErpCategoryName + + if summary.Type == 3 || summary.Type == 4 { + summaryMap[i].Count = -summaryMap[i].Count + summaryMap[i].Amount = -summaryMap[i].Amount + } + + summaryList = append(summaryList, *summary) + } + + // 使用排序规则函数对汇总数据进行排序 + sortSummaryList(summaryList) + + // 计算分页所需的切片索引 + startIndex := page * m.PageSize + endIndex := (page + 1) * m.PageSize + if endIndex > len(summaryList) { + endIndex = len(summaryList) + } + + resp.Total = len(summaryList) + resp.TotalCount = nTotalAllotCount + resp.TotalAmount = tools.RoundToTwoDecimalPlaces(nTotalAllotAmount) + + if m.IsExport == 1 { + resp.List = summaryList + resp.ExportUrl, err = reportOtherExport(resp) + if err != nil { + return nil, err + } + resp.List = []ReportByOtherData{} + resp.TotalCount = 0 + resp.TotalAmount = 0 + } else { + resp.List = summaryList[startIndex:endIndex] + } + + return resp, nil +} + +// 排序规则函数 +// 排序规则:商品编号小>门店编号小>产品入库>盘点入库>系统出库>盘点出库 +func sortSummaryList(summaryList []ReportByOtherData) { + sort.Slice(summaryList, func(i, j int) bool { + // 按 CommodityId 排序 + if summaryList[i].CommodityId != summaryList[j].CommodityId { + return summaryList[i].CommodityId < summaryList[j].CommodityId + } + // 如果 CommodityId 相同,则按 StoreId 排序 + if summaryList[i].StoreId != summaryList[j].StoreId { + return summaryList[i].StoreId < summaryList[j].StoreId + } + // 如果 StoreId 相同, 按 Type 排序 + if summaryList[i].Type != summaryList[j].Type { + return summaryList[i].Type < summaryList[j].Type + } + // 如果 Type 相同,则按 Amount 排序 + return summaryList[i].Amount < summaryList[j].Amount + }) +} + +// reportOtherExport 其他出入库汇总导出excel +func reportOtherExport(req *InventoryReportByOtherResp) (string, error) { + file := excelize.NewFile() + fSheet := "Sheet1" + + url := ExportUrl + fileName := time.Now().Format(TimeFormat) + "其他出入库汇总" + ".xlsx" + fmt.Println("url fileName:", url+fileName) + + // 组合标题栏数据 + title := []interface{}{"门店", "商品名称", "商品分类", "出入库方式", "数量", "金额"} + for i, _ := range title { + cell, _ := excelize.CoordinatesToCellName(1+i, 1) + err := file.SetCellValue(fSheet, cell, title[i]) + if err != nil { + logger.Error("file set value err:", logger.Field("err", err)) + } + } + + var row1 []interface{} + nExcelStartRow := 0 + for _, reportData := range req.List { + var inventoryType string + switch reportData.Type { + case 1: + inventoryType = "产品入库" + case 2: + inventoryType = "盘点入库" + case 3: + inventoryType = "系统出库" + case 4: + inventoryType = "盘点出库" + } + + row1 = []interface{}{ + reportData.StoreName, // 门店 + reportData.CommodityName, // 商品名称 + reportData.CategoryName, // 商品分类 + inventoryType, // 出入库方式 + reportData.Count, // 数量 + reportData.Amount, // 金额 + } + + for j, _ := range row1 { + cell, _ := excelize.CoordinatesToCellName(1+j, nExcelStartRow+2) + err := file.SetCellValue(fSheet, cell, row1[j]) + if err != nil { + logger.Error("file set value err:", logger.Field("err", err)) + } + } + nExcelStartRow++ + } + + totalData := "记录数:" + strconv.FormatInt(int64(req.Total), 10) + end := []interface{}{totalData, "", "", "", req.TotalCount, req.TotalAmount} + for i, _ := range end { + cell, _ := excelize.CoordinatesToCellName(1+i, nExcelStartRow+2) + err := file.SetCellValue(fSheet, cell, end[i]) + if err != nil { + logger.Error("file set value err:", logger.Field("err", err)) + } + } + + // 设置所有单元格的样式: 居中、加边框 + style, _ := file.NewStyle(`{"alignment":{"horizontal":"center","vertical":"center"}, + "border":[{"type":"left","color":"000000","style":1}, + {"type":"top","color":"000000","style":1}, + {"type":"right","color":"000000","style":1}, + {"type":"bottom","color":"000000","style":1}]}`) + + //设置单元格高度 + file.SetRowHeight("Sheet1", 1, 20) + + // 设置单元格大小 + file.SetColWidth("Sheet1", "A", "A", 28) + file.SetColWidth("Sheet1", "B", "B", 28) + file.SetColWidth("Sheet1", "C", "C", 20) + file.SetColWidth("Sheet1", "D", "D", 20) + + endRow := fmt.Sprintf("F"+"%d", nExcelStartRow+2) + // 应用样式到整个表格 + _ = file.SetCellStyle("Sheet1", "A1", endRow, style) + + fmt.Println("save fileName:", config.ExportConfig.Path+fileName) + if err := file.SaveAs(config.ExportConfig.Path + fileName); err != nil { + fmt.Println(err) + } + return url + fileName, nil +} + +// ReportByOtherDetailList 其他出入库明细 +func (m *InventoryReportOtherDetailReq) ReportByOtherDetailList(c *gin.Context) (*InventoryReportOtherDetailResp, error) { + // 非管理员才判断所属门店 + if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") { + sysUser, err := GetSysUserByCtx(c) + if err != nil { + return nil, errors.New("操作失败:" + err.Error()) + } + + // 返回sysUser未过期的门店id列表 + storeList := GetValidStoreIDs(sysUser.StoreData) + if len(storeList) > 0 { + m.StoreId = CompareLists(storeList, m.StoreId) + if len(m.StoreId) == 0 { // 没有匹配的数据,表示入参门店不是用户有权限的门店 + return &InventoryReportOtherDetailResp{}, nil + } + } else { + return nil, errors.New("用户未绑定门店") + } + } + + resp := &InventoryReportOtherDetailResp{ + PageIndex: m.PageIndex, + PageSize: m.PageSize, + } + page := m.PageIndex - 1 + if page < 0 { + page = 0 + } + if m.PageSize == 0 { + m.PageSize = 10 + } + + // 查询产品入库数据 + var err error + var productList []ReportOtherDetailData + productList, err = getProductOrderData() + if err != nil { + return nil, err + } + + // 查询盘点出入库数据 + var changeList []ReportOtherDetailData + changeList, err = getChangeOrderData() + if err != nil { + return nil, err + } + + // 查询系统出库数据 + var systemList []ReportOtherDetailData + systemList, err = getSystemOutData() + if err != nil { + return nil, err + } + + // 合并数据 + allData := append(productList, changeList...) + allData = append(allData, systemList...) + + // 进行条件查询 + var startTime time.Time + if m.StartTime != "" { // 出入库开始时间 + startTime, err = time.Parse(QueryTimeFormat, m.StartTime) + if err != nil { + logger.Errorf("ReportByOtherDetailList err:", err) + return nil, err + } + } + var endTime time.Time + if m.EndTime != "" { // 出入库结束时间 + endTime, err = time.Parse(QueryTimeFormat, m.EndTime) + if err != nil { + logger.Errorf("ReportByOtherDetailList err:", err) + return nil, err + } + } + + var totalPurchasePrice, totalEmployeePrice float64 + filteredData := make([]ReportOtherDetailData, 0) + for i, data := range allData { + if allData[i].CategoryID == 0 { + // 添加分类信息 + commodityInfo, err := GetCommodity(data.CommodityId) + if err != nil { + logger.Error("SetCategory err:", logger.Field("err", err)) + } + allData[i].CategoryID = commodityInfo.ErpCategoryId + allData[i].CategoryName = commodityInfo.ErpCategoryName + } + + if (len(m.SerialNumber) == 0 || data.SerialNumber == m.SerialNumber) && + (len(m.StoreId) == 0 || tools.Uint32SliceContains(m.StoreId, data.StoreId)) && + (len(m.CommodityName) == 0 || tools.StringSliceContains(m.CommodityName, data.CommodityName)) && + (len(m.CategoryID) == 0 || tools.Uint32SliceContains(m.CategoryID, allData[i].CategoryID)) && + (m.Type == 0 || m.Type == data.Type) && + ((m.StartTime == "" && m.EndTime == "") || (data.StockTime.After(startTime) && data.StockTime.Before(endTime))) { + if data.Type == 3 || data.Type == 4 { // 系统出库、盘点出库 + totalPurchasePrice -= allData[i].PurchasePrice + totalEmployeePrice -= allData[i].EmployeePrice + + allData[i].PurchasePrice = -allData[i].PurchasePrice + allData[i].EmployeePrice = -allData[i].EmployeePrice + } else { + totalPurchasePrice += allData[i].PurchasePrice + totalEmployeePrice += allData[i].EmployeePrice + } + filteredData = append(filteredData, allData[i]) + } + } + + // 进行排序 + sort.Slice(filteredData, func(i, j int) bool { + return filteredData[i].StockTime.After(*filteredData[j].StockTime) + }) + + resp.TotalPurchasePrice = tools.RoundToTwoDecimalPlaces(totalPurchasePrice) + resp.TotalEmployeePrice = tools.RoundToTwoDecimalPlaces(totalEmployeePrice) + + if m.IsExport == 1 { + resp.List = filteredData + resp.Total = len(filteredData) + resp.ExportUrl, err = reportOtherDetailExport(resp) + if err != nil { + return nil, err + } + resp.List = []ReportOtherDetailData{} + resp.TotalPurchasePrice = 0 + resp.TotalEmployeePrice = 0 + } else { + // 进行分页处理 + startIndex := page * m.PageSize + endIndex := startIndex + m.PageSize + if endIndex > len(filteredData) { + endIndex = len(filteredData) + } + resp.List = filteredData[startIndex:endIndex] + resp.Total = len(filteredData) + } + + return resp, nil +} + +// 查询产品入库数据 +func getProductOrderData() ([]ReportOtherDetailData, error) { + var productList []ReportOtherDetailData + err := orm.Eloquent.Debug().Table("erp_inventory_product_order"). + Select("erp_inventory_product_order.serial_number, "+ + "erp_inventory_product_order.store_id, "+ + "erp_inventory_product_order.store_name, "+ + "erp_inventory_product_order.audit_time as stock_time, "+ + "CASE "+ + "WHEN erp_inventory_product_order.state = 2 THEN 1 "+ + "ELSE erp_inventory_product_order.state "+ + "END AS type, "+ + "erp_inventory_product_commodity.commodity_id, "+ + "erp_inventory_product_commodity.commodity_name, "+ + "erp_inventory_product_commodity.supplier_id, "+ + "erp_inventory_product_commodity.supplier_name, "+ + "erp_inventory_product_commodity.imei_type, "+ + "erp_inventory_product_commodity.imei, "+ + "erp_inventory_product_commodity.price as purchase_price, "+ + "erp_inventory_product_commodity.employee_price as employee_price"). + Joins("JOIN erp_inventory_product_commodity "+ + "ON erp_inventory_product_commodity.product_order_id = erp_inventory_product_order.id"). + Where("erp_inventory_product_order.state = ?", ErpInventoryProductOrderFinished). + Find(&productList).Error // 查询已审核的订单 + if err != nil { + return nil, err + } + + return productList, nil +} + +// 查询盘点出入库数据 +func getChangeOrderData() ([]ReportOtherDetailData, error) { + var changeList []ReportOtherDetailData + err := orm.Eloquent.Debug().Table("erp_inventory_change_order"). + Select("erp_inventory_change_order.serial_number, "+ + "erp_inventory_change_order.store_id, "+ + "erp_inventory_change_order.store_name, "+ + "erp_inventory_change_order.audit_time as stock_time, "+ + "CASE "+ + "WHEN erp_inventory_change_order.change_type = 'add' THEN 2 "+ + "WHEN erp_inventory_change_order.change_type = 'reduce' THEN 4 "+ + "ELSE erp_inventory_change_order.state "+ + "END AS type, "+ + "erp_inventory_change_commodity.commodity_id, "+ + "erp_inventory_change_commodity.commodity_name, "+ + "erp_inventory_change_commodity.supplier_id, "+ + "erp_inventory_change_commodity.supplier_name, "+ + "erp_inventory_change_commodity.imei_type, "+ + "erp_inventory_change_commodity.imei, "+ + "erp_inventory_change_commodity.price as purchase_price, "+ + "erp_inventory_change_commodity.employee_price as employee_price"). + Joins("JOIN erp_inventory_change_commodity "+ + "ON erp_inventory_change_commodity.change_order_id = erp_inventory_change_order.id"). + Where("erp_inventory_change_order.state = ?", ErpInventoryChangeOrderFinished). + Find(&changeList).Error // 查询已审核的订单 + if err != nil { + return nil, err + } + + return changeList, nil +} + +// 查询系统出库数据 +func getSystemOutData() ([]ReportOtherDetailData, error) { + var stockCommodities []ErpStockCommodity + err := orm.Eloquent.Table("erp_stock_commodity"). + Where("state = ?", SystemOut).Find(&stockCommodities).Error + if err != nil { + return nil, err + } + + var systemOutList []ReportOtherDetailData + for _, item := range stockCommodities { + var systemOutData ReportOtherDetailData + systemOutData.CommodityId = item.ErpCommodityId + systemOutData.CommodityName = item.ErpCommodityName + systemOutData.CategoryID = item.ErpCategoryId + systemOutData.CategoryName = item.ErpCategoryName + systemOutData.IMEIType = item.IMEIType + systemOutData.IMEI = item.IMEI + systemOutData.StoreId = item.StoreId + systemOutData.StoreName = item.StoreName + systemOutData.SupplierId = item.ErpSupplierId + systemOutData.SupplierName = item.ErpSupplierName + systemOutData.StockTime = &item.UpdatedAt + systemOutData.Type = 3 + systemOutData.PurchasePrice = item.WholesalePrice + systemOutData.EmployeePrice = item.WholesalePrice + item.StaffCostPrice + + systemOutList = append(systemOutList, systemOutData) + } + + return systemOutList, nil +} + +// reportOtherDetailExport 其他出入库明细导出excel +func reportOtherDetailExport(req *InventoryReportOtherDetailResp) (string, error) { + file := excelize.NewFile() + fSheet := "Sheet1" + + url := ExportUrl + fileName := time.Now().Format(TimeFormat) + "其他出入库明细" + ".xlsx" + fmt.Println("url fileName:", url+fileName) + + // 组合标题栏数据 + title := []interface{}{"商品名称", "商品分类", "是否串码", "商品串码", "所属门店", "供应商", "出/入库时间", "方式", "单据编号", + "入库采购价", "入库员工成本价"} + for i, _ := range title { + cell, _ := excelize.CoordinatesToCellName(1+i, 1) + err := file.SetCellValue(fSheet, cell, title[i]) + if err != nil { + logger.Error("file set value err:", logger.Field("err", err)) + } + } + + var row1 []interface{} + nExcelStartRow := 0 + for _, reportData := range req.List { + var inventoryType string + switch reportData.Type { + case 1: + inventoryType = "产品入库" + case 2: + inventoryType = "盘点入库" + case 3: + inventoryType = "系统出库" + case 4: + inventoryType = "盘点出库" + } + + var IMEIType string + switch reportData.IMEIType { + case 1: + IMEIType = "非串码" + case 2, 3: + IMEIType = "串码类" + } + + var auditTime string + if reportData.StockTime != nil { + auditTime = reportData.StockTime.Format(TimeFormat) + } + + row1 = []interface{}{ + reportData.CommodityName, // 商品名称 + reportData.CategoryName, // 商品分类 + IMEIType, // 是否串码 + reportData.IMEI, // 商品串码 + reportData.StoreName, // 所属门店 + reportData.SupplierName, // 供应商 + auditTime, // 出/入库时间 + inventoryType, // 方式 + reportData.SerialNumber, // 单据编号 + reportData.PurchasePrice, // 入库采购价 + reportData.EmployeePrice, // 入库员工成本价 + } + + for j, _ := range row1 { + cell, _ := excelize.CoordinatesToCellName(1+j, nExcelStartRow+2) + err := file.SetCellValue(fSheet, cell, row1[j]) + if err != nil { + logger.Error("file set value err:", logger.Field("err", err)) + } + } + nExcelStartRow++ + } + + totalData := "记录数:" + strconv.FormatInt(int64(req.Total), 10) + end := []interface{}{totalData, "", "", "", "", "", "", "", "", req.TotalPurchasePrice, req.TotalEmployeePrice} + for i, _ := range end { + cell, _ := excelize.CoordinatesToCellName(1+i, nExcelStartRow+2) + err := file.SetCellValue(fSheet, cell, end[i]) + if err != nil { + logger.Error("file set value err:", logger.Field("err", err)) + } + } + + // 设置所有单元格的样式: 居中、加边框 + style, _ := file.NewStyle(`{"alignment":{"horizontal":"center","vertical":"center"}, + "border":[{"type":"left","color":"000000","style":1}, + {"type":"top","color":"000000","style":1}, + {"type":"right","color":"000000","style":1}, + {"type":"bottom","color":"000000","style":1}]}`) + + //设置单元格高度 + file.SetRowHeight("Sheet1", 1, 20) + + // 设置单元格大小 + file.SetColWidth("Sheet1", "A", "A", 28) + file.SetColWidth("Sheet1", "B", "B", 15) + file.SetColWidth("Sheet1", "D", "D", 18) + file.SetColWidth("Sheet1", "E", "E", 28) + file.SetColWidth("Sheet1", "G", "G", 18) + file.SetColWidth("Sheet1", "I", "I", 18) + + endRow := fmt.Sprintf("K"+"%d", nExcelStartRow+2) + // 应用样式到整个表格 + _ = file.SetCellStyle("Sheet1", "A1", endRow, style) + + fmt.Println("save fileName:", config.ExportConfig.Path+fileName) + if err := file.SaveAs(config.ExportConfig.Path + fileName); err != nil { + fmt.Println(err) + } + return url + fileName, nil +} diff --git a/tools/utils.go b/tools/utils.go index 56149f0..a39cd96 100644 --- a/tools/utils.go +++ b/tools/utils.go @@ -114,3 +114,23 @@ func ConvertTimeToStringByPoint(t *time.Time) string { func RoundToTwoDecimalPlaces(num float64) float64 { return math.Round(num*100) / 100 } + +// Uint32SliceContains 检查 uint32 切片中是否包含特定的值 +func Uint32SliceContains(slice []uint32, val uint32) bool { + for _, item := range slice { + if item == val { + return true + } + } + return false +} + +// StringSliceContains 检查 string 切片中是否包含特定的值 +func StringSliceContains(slice []string, val string) bool { + for _, item := range slice { + if item == val { + return true + } + } + return false +}