1.库存导入时,添加系统自动生成串码逻辑;2.优化库存导入规则校验逻辑,解决部分数据未校验的问题;3.库存导入时未填写商品名称的数据,导入时自动补齐;4.优化库存导入时间msyql记录比时间晚8小时的问题;5.导出文件地址都改成https;6.增加订单列表导出接口;7.调整订单列表"卡片状态"查询规则:查询卡片状态时优先查询order_card表,组合同类状态数据返回;同一订单非同一类型数据不返回。

This commit is contained in:
chenlin 2023-12-13 20:05:53 +08:00
parent aa3329c25e
commit bcf568a9e0
9 changed files with 671 additions and 104 deletions

View File

@ -35,7 +35,7 @@ func OrderList(c *gin.Context) {
//
//}
list, count, err := req.List()
list, count, _, err := req.List(0)
if err != nil {
logger.Errorf("err:", logger.Field("err", err))
app.Error(c, http.StatusInternalServerError, err, "查询失败")
@ -264,3 +264,35 @@ func FundRecordList(c *gin.Context) {
}
app.OK(c, ret, "")
}
// OrderListExport 导出订单列表
// @Summary 导出订单列表
// @Tags 订单管理
// @Produce json
// @Accept json
// @Param request body models.OrderListReq true "导出订单列表模型"
// @Success 200 {object} app.Response "{"code": 200, "data": { "export_url": "" }}"
// @Router /api/v1/order/list_export [post]
func OrderListExport(c *gin.Context) {
req := &models.OrderListReq{}
if c.ShouldBindJSON(req) != nil {
logger.Errorf("para err")
app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
return
}
reqJson, _ := json.Marshal(req)
fmt.Println("reqJson:", string(reqJson))
_, _, filePath, err := req.List(1)
if err != nil {
logger.Errorf("OrderListExport err:", logger.Field("err", err))
app.Error(c, http.StatusInternalServerError, err, "导出失败")
return
}
ret := map[string]interface{}{
"export_url": filePath,
}
app.OK(c, ret, "")
}

View File

@ -9,6 +9,7 @@ import (
"go-admin/tools/config"
"golang.org/x/sync/errgroup"
"gorm.io/gorm"
"math/rand"
"strconv"
"strings"
"sync"
@ -547,7 +548,18 @@ func (m *StockImporter) ImportStockData(colsMap []map[string]interface{}) error
}
_, ok2 := erpCommodityMap[list[i].Name]
if !ok2 {
if list[i].Name == "" {
//如果商品名称为空,则需要补全
commodityName, err := getCommodityNameBySerialNum(list[i].SerialNum)
if err != nil {
logger.Errorf("getCommodityNameBySerialNum err:", logger.Field("err", err))
return err
}
list[i].Name = commodityName
}
erpCommodityNames = append(erpCommodityNames, list[i].Name)
}
_, ok3 := erpSupplierNameMap[list[i].SupplierName]
if !ok3 {
@ -644,19 +656,30 @@ func (m *StockImporter) ImportStockData(colsMap []map[string]interface{}) error
StockTime: nowTime,
Count: 1,
IMEIType: v2.IMEIType,
IMEI: v2.IMEI,
IMEI: "",
Remark: "",
}
if list[i].StockTime != "" { //导入时间不为空
parsedTime, _ := time.Parse("2006/1/2", list[i].StockTime)
local, _ := time.LoadLocation("Local")
parsedTime, _ := time.ParseInLocation("2006/1/2", list[i].StockTime, local)
//parsedTime, _ := time.Parse("2006/1/2", list[i].StockTime)
stockCommodity.FirstStockTime = parsedTime
stockCommodity.StockTime = parsedTime
}
if list[i].SysGenerate != "" { //导入串码不为空则默认为3手动添加
if list[i].SysGenerate != "" && v2.IMEIType == 3 { //导入串码不为空则默认为3手动添加
stockCommodity.IMEIType = 3
stockCommodity.IMEI = list[i].SysGenerate
} else if v2.IMEIType == 2 { // 如果该商品串码类型是2-串码(系统生成),则系统自动生成
stockCommodity.IMEIType = 2
serialCode, err := generateSerialCode(v2.ErpCategoryId)
if err != nil {
return err
}
stockCommodity.IMEI = serialCode
}
erpStockCommodity = append(erpStockCommodity, stockCommodity)
_, ok4 := m.CensusMap[stockCommodity.StoreId]
@ -675,6 +698,54 @@ func (m *StockImporter) ImportStockData(colsMap []map[string]interface{}) error
return nil
}
// 获取商品名称
func getCommodityNameBySerialNum(serialNumber string) (string, error) {
var commodity ErpCommodity
err := orm.Eloquent.Table("erp_commodity").Where("serial_number=?", serialNumber).Find(&commodity).Error
if err != nil {
return "", err
}
return commodity.Name, nil
}
// generateSerialCode 生成商品串码
func generateSerialCode(categoryID uint32) (string, error) {
// 生成年月日6位数
dateStr := time.Now().Format("060102")
// 生成四位随机数
rand.Seed(time.Now().UnixNano())
randomNumber := rand.Intn(10000)
randomStr := fmt.Sprintf("%04d", randomNumber)
// 获取商品分类编号前3位
categoryStr, err := getCategoryCode(categoryID)
if err != nil {
logger.Errorf("getCategoryCode err:", logger.Field("err", err))
return "", err
}
// 拼接串码
serialCode := categoryStr + dateStr + randomStr
return serialCode, nil
}
// getCategoryCode 根据商品分类ID查询分类编号前3位
func getCategoryCode(categoryID uint32) (string, error) {
// 这里模拟查询数据库,实际中你需要连接数据库进行查询
// 假设这里的数据是从数据库中查询得到的
categoryInfo, err := GetCategoryById(categoryID)
if err != nil {
logger.Errorf("GetCategoryById err:", logger.Field("err", err))
return "", err
}
// 取前3位字符串
return categoryInfo.Number[:3], nil
}
func (m *StockImporter) processErpStocks(erpStocks []ErpStockCommodity) error {
begin := orm.Eloquent.Begin()
total := len(erpStocks)
@ -718,7 +789,7 @@ func (m *StockImporter) processErpStocks(erpStocks []ErpStockCommodity) error {
}
func createStockList(begin *gorm.DB, stockList []ErpStockCommodity) error {
err := begin.Create(&stockList).Error
err := begin.Debug().Create(&stockList).Error
if err != nil {
begin.Rollback()
return err
@ -918,7 +989,7 @@ func ErpCommodityListExport(list []ErpCommodity) (string, error) {
fmt.Println(err)
}
url := "http://39.108.188.218:8000/img/export/"
url := ExportUrl
fileName := time.Now().Format(TimeFormat) + "商品" + ".xlsx"
//title := []interface{}{"供应商编号", "供应商名称", "联系人", "手机号", "地址", "开户银行", "银行账号", "付款周期/天"}
@ -962,7 +1033,7 @@ func InventoryDetailListExport(list []ErpStockCommodity) (string, error) {
fmt.Println(err)
}
url := config.ExportConfig.Url
url := ExportUrl
fileName := time.Now().Format(TimeFormat) + "商品" + ".xlsx"
fmt.Println("url fileName:", url+fileName)
@ -1037,7 +1108,7 @@ func ErpCategoryListExport(list []ErpCategory) (string, error) {
fmt.Println(err)
}
url := "http://39.108.188.218:8000/img/export/"
url := ExportUrl
fileName := time.Now().Format(TimeFormat) + "分类列表数据" + ".xlsx"
//title := []interface{}{"门店", "用户ID", "订单编号", "下单时间", "卡带", "说明", "回收价", "闲麦价", "审核时间", "审核人", "操作", "复核时间", "复核状态"}

View File

@ -372,62 +372,90 @@ func checkStockExcel(sheetCols [][]string) error {
}
}
for i := 1; i < nLow; i++ { // todo
if !isExistingProduct(sheetCols[0][i]) {
return errors.New("第" + strconv.Itoa(i+1) + "行商品不存在,请新建商品")
}
// 商品编号必须为纯数字
if sheetCols[1][i] != "" {
if _, err := strconv.Atoi(sheetCols[1][i]); err != nil {
return errors.New("第" + strconv.Itoa(i+1) + "行商品编号必须为纯数字")
for i := 1; i < nMax; i++ { // todo
if i < len(sheetCols[0]) {
if !isExistingProduct(sheetCols[0][i]) {
return errors.New("第" + strconv.Itoa(i+1) + "行商品不存在,请新建商品")
}
}
if !isExistingProductCode(sheetCols[1][i]) {
return errors.New("第" + strconv.Itoa(i+1) + "行商品编号不存在")
if i < len(sheetCols[1]) {
// 商品编号必须为纯数字
if sheetCols[1][i] != "" {
if _, err := strconv.Atoi(sheetCols[1][i]); err != nil {
return errors.New("第" + strconv.Itoa(i+1) + "行商品编号必须为纯数字")
}
}
if !isExistingProductCode(sheetCols[1][i]) {
return errors.New("第" + strconv.Itoa(i+1) + "行商品编号不存在")
}
}
// 所属门店不能为空
if sheetCols[2][i] == "" {
return errors.New("第" + strconv.Itoa(i+1) + "行所属门店不能为空")
}
if !isExistingStore(sheetCols[2][i]) {
return errors.New("第" + strconv.Itoa(i+1) + "行门店不存在,请新建门店")
if i < len(sheetCols[2]) {
if sheetCols[2][i] == "" {
return errors.New("第" + strconv.Itoa(i+1) + "行所属门店不能为空")
}
if !isExistingStore(sheetCols[2][i]) {
return errors.New("第" + strconv.Itoa(i+1) + "行门店不存在,请新建门店")
}
}
// 商品串码规则校验 当串码行数跟其他一致时正常遍历,如果小于其他行,则最后一行不遍历 todo
// 如串码在商品库存表已经存在,则报错提示
if len(sheetCols[3]) <= nLow && i+1 < nLow {
if err := checkSerialCode(sheetCols[0][i], sheetCols[1][i], sheetCols[3][i], i); err != nil {
//if len(sheetCols[3]) <= nLow && i+1 < nLow {
if i < len(sheetCols[3]) {
productName := ""
if i < len(sheetCols[0]) {
productName = sheetCols[0][i]
}
productCode := ""
if i < len(sheetCols[1]) {
productCode = sheetCols[1][i]
}
count := ""
if i < len(sheetCols[8]) {
count = sheetCols[8][i]
}
if err := checkSerialCode(productName, productCode, sheetCols[3][i], i); err != nil {
return err
}
// 串码类商品数量只能为1
if sheetCols[3][i] != "" && sheetCols[8][i] != "1" {
if sheetCols[3][i] != "" && count != "1" {
return errors.New("第" + strconv.Itoa(i+1) + "行串码类商品数量只能为1")
}
}
// 采购价、员工成本价必须大于0
if purchasePrice, err := strconv.Atoi(sheetCols[4][i]); err != nil || purchasePrice <= 0 {
return errors.New("第" + strconv.Itoa(i+1) + "行采购价必须是大于0的数字")
if i < len(sheetCols[4]) {
if purchasePrice, err := strconv.Atoi(sheetCols[4][i]); err != nil || purchasePrice <= 0 {
return errors.New("第" + strconv.Itoa(i+1) + "行采购价必须是大于0的数字")
}
}
if employeeCost, err := strconv.Atoi(sheetCols[5][i]); err != nil || employeeCost <= 0 {
return errors.New("第" + strconv.Itoa(i+1) + "行员工成本价必须是大于0的数字")
if i < len(sheetCols[5]) {
if employeeCost, err := strconv.Atoi(sheetCols[5][i]); err != nil || employeeCost <= 0 {
return errors.New("第" + strconv.Itoa(i+1) + "行员工成本价必须是大于0的数字")
}
}
// 供应商不能为空
if sheetCols[6][i] == "" {
return errors.New("第" + strconv.Itoa(i+1) + "行供应商不能为空")
}
if !isExistingSupplier(sheetCols[6][i]) {
return errors.New("第" + strconv.Itoa(i+1) + "行供应商不存在,请新建供应商")
if i < len(sheetCols[6]) {
if sheetCols[6][i] == "" {
return errors.New("第" + strconv.Itoa(i+1) + "行供应商不能为空")
}
if !isExistingSupplier(sheetCols[6][i]) {
return errors.New("第" + strconv.Itoa(i+1) + "行供应商不存在,请新建供应商")
}
}
// 入库时间格式校验
//if len(sheetCols[7]) < nLow && i+1 < nLow {
if i+1 <= len(sheetCols[7]) {
if i < len(sheetCols[7]) {
if sheetCols[7][i] != "" {
parsedTime, err := time.Parse("2006/1/2", sheetCols[7][i])
if err != nil {
@ -435,7 +463,7 @@ func checkStockExcel(sheetCols [][]string) error {
}
// 格式化时间为指定格式
formattedTime := parsedTime.Format(DateTimeFormat)
sheetCols[7][i] = formattedTime + "00-00-00"
//sheetCols[7][i] = formattedTime + "00-00-00"
// 需小于当前时间
nFlag, _ := isInputTimeBeforeOrEqualNow(formattedTime)
@ -447,8 +475,10 @@ func checkStockExcel(sheetCols [][]string) error {
}
// 数量必须为正整数
if quantity, err := strconv.Atoi(sheetCols[8][i]); err != nil || quantity < 1 {
return errors.New("第" + strconv.Itoa(i+1) + "行数量必须是大于等于1的整数")
if i < len(sheetCols[8]) {
if quantity, err := strconv.Atoi(sheetCols[8][i]); err != nil || quantity < 1 {
return errors.New("第" + strconv.Itoa(i+1) + "行数量必须是大于等于1的整数")
}
}
}

View File

@ -10,10 +10,13 @@ import (
"github.com/wechatpay-apiv3/wechatpay-go/services/certificates"
"github.com/wechatpay-apiv3/wechatpay-go/services/payments/jsapi"
wechatpayutils "github.com/wechatpay-apiv3/wechatpay-go/utils"
"github.com/xuri/excelize/v2"
"go-admin/app/admin/models/kuaidi"
orm "go-admin/common/global"
"go-admin/logger"
"go-admin/tools/config"
"golang.org/x/sync/errgroup"
"gorm.io/gorm"
"time"
)
@ -185,10 +188,10 @@ type OrderListReq struct {
Uid uint64 `json:"uid" `
OrderId uint64 `json:"order_id"`
GameCardId uint64 `json:"game_card_id" `
StoreId uint64 `json:"store_id" ` // 门店id// 游戏id
CardStatus uint8 `json:"card_status"` // 1-待取货中 2-游玩中 3-归还中 4-已完成
PayStatus uint8 `json:"pay_status"`
DeliveryType uint8 `json:"delivery_type"`
StoreId uint64 `json:"store_id" ` // 门店id// 游戏id
CardStatus uint8 `json:"card_status"` // 1-待取货中 2-游玩中 3-归还中 4-已完成 5-已取消
PayStatus uint8 `json:"pay_status"` // 支付状态 1-未支付 2-已支付
DeliveryType uint8 `json:"delivery_type"` // 取货类型 1-门店自取 2-快递
SerialNumber string `json:"serial_number" ` // 编号
PickupCode string `json:"pickup_code"` // 取货码
StartTime time.Time `json:"start_time"` // 开始时间
@ -197,47 +200,157 @@ type OrderListReq struct {
PageSize int `json:"pageSize"`
}
//type OrderListResp struct {
//}
func (m *OrderListReq) List(exportFlag int) ([]Order, int64, string, error) {
orders := make([]Order, 0)
if m.PageSize == 0 {
m.PageSize = 10
}
func (m *OrderListReq) List() ([]Order, int64, error) {
//orderInfos := make([]OrderInfo, 0)
var count int64
var err error
// 如果卡片类型不为空则优先查询order_card表
if m.CardStatus != 0 {
orders, count, err = m.queryListFormOrderCard(exportFlag)
} else {
orders, count, err = m.queryListFormOrder(exportFlag)
}
filePath := ""
if exportFlag == 1 {
filePath, err = OrderListExport(orders)
if err != nil {
logger.Error("OrderListExport err:", logger.Field("err", err))
return orders, 0, "", err
}
}
return orders, count, filePath, nil
}
func (m *OrderListReq) queryListFormOrderCard(exportFlag int) ([]Order, int64, error) {
var orderCards []OrderCard
orders := make([]Order, 0)
qs := orm.Eloquent.Table("order_card").Where("card_status=?", m.CardStatus)
if m.SerialNumber != "" {
qs = qs.Where("serial_number=?", m.SerialNumber)
}
if m.DeliveryType != 0 { // 共有
qs = qs.Where("delivery_type", m.DeliveryType)
}
if m.Uid != 0 { // 用户id共有
qs = qs.Where("uid", m.Uid)
}
if m.GameCardId != 0 { // 游戏卡id共有
qs = qs.Where("game_card_id", m.GameCardId)
}
if m.StoreId != 0 { // 门店id共有
qs = qs.Where("store_id", m.StoreId)
}
if !m.StartTime.IsZero() { // 共有
fmt.Println("起始时间:", m.StartTime.Unix())
qs = qs.Where("created_at > ?", m.StartTime)
}
if !m.EndTime.IsZero() { // 共有
fmt.Println("时间:", m.StartTime.Unix())
qs = qs.Where("created_at < ?", m.EndTime)
}
err := qs.Find(&orderCards).Error
if err != nil {
logger.Error("err:", logger.Field("err", err))
return nil, 0, err
}
orderIds := make([]uint32, 0)
for i, _ := range orderCards {
orderIds = append(orderIds, orderCards[i].OrderId)
}
orderQs := orm.Eloquent.Table("order").Where("pay_status", 2).Where("id in (?)", orderIds)
var count int64
err = orderQs.Count(&count).Error
if err != nil {
logger.Errorf("err:", logger.Field("err", err))
return nil, 0, err
}
page := m.Page
pageSize := m.PageSize
page -= 1
if page < 0 {
page = 0
}
if exportFlag == 1 { //一次性导出excel
orderQs = orderQs.Preload("User").Order("created_at DESC")
} else {
orderQs = orderQs.Preload("User").Order("created_at DESC").Offset(page * pageSize).Limit(pageSize)
}
err = orderQs.Find(&orders).Error
if err != nil {
logger.Errorf("err:", logger.Field("err", err))
return nil, 0, err
}
ids := make([]uint32, 0, len(orders))
for i, _ := range orders {
ids = append(ids, uint32(orders[i].ID))
}
if len(ids) == 0 {
logger.Error("gameIds is nil")
return nil, 0, err
}
//var orderCards []OrderCard
err = orm.Eloquent.Table("order_card").Where("order_id in (?)", ids).Find(&orderCards).Error
if err != nil {
logger.Error("err:", logger.Field("err", err))
return nil, 0, err
}
orderCards = OrderCardListSetGameInfo(orderCards)
orderCardsMap := make(map[uint32][]OrderCard, 0)
for i, _ := range orderCards {
if orderCards[i].CardStatus == m.CardStatus { //卡片状态相同的租卡订单才返回,方便财务导出数据
orderCardsMap[orderCards[i].OrderId] = append(orderCardsMap[orderCards[i].OrderId], orderCards[i])
}
}
for i, _ := range orders {
//2023-12-12 跟产品讨论后确认状态按原来的5种进行展示
//if orders[i].CardStatus == 2 || orders[i].CardStatus == 3 {
// orders[i].CardStatus = 4
//}
v, ok := orderCardsMap[orders[i].ID]
if ok {
orders[i].OrderCards = v
}
}
return orders, count, nil
}
func (m *OrderListReq) queryListFormOrder(exportFlag int) ([]Order, int64, error) {
var orderCards []OrderCard
orders := make([]Order, 0)
if m.PageSize == 0 {
m.PageSize = 10
}
qs := orm.Eloquent.Table("order").Where("pay_status", 2)
var qs *gorm.DB
qs = orm.Eloquent.Table("order").Where("pay_status", 2)
isDeliver := true
if m.SerialNumber != "" {
isDeliver = false
////qs = qs.Where("game_card_serial_number", m.SerialNumber)
//err := orm.Eloquent.Table("order_card").Where("serial_number=?", m.SerialNumber).
// Order("id DESC").Order("card_status ASC").Limit(30).Find(&orderCards).Error
// //Where("card_status in (?)", []uint32{2, 3}).Order("id DESC").Order("card_status DESC").Limit(30).Find(&orderCards).Error
//if err != nil {
// logger.Error("err:",logger.Field("err",err))
// return orders, 0, err
//}
//order := Order{}
//if len(orderCards) > 0 {
// err := orm.Eloquent.Table("order").Where("id=?", orderCards[0].OrderId).Find(&order).Error
// if err != nil {
// logger.Error("err:",logger.Field("err",err))
// return orders, 0, err
// }
//}
//orders = append(orders, order)
//orders[0].OrderCards = OrderCardListSetGameInfo(orderCards)
//return orders, 1, nil
err := orm.Eloquent.Table("order_card").Where("serial_number=?", m.SerialNumber).
Order("id DESC").Order("card_status ASC").Find(&orderCards).Error
//Where("card_status in (?)", []uint32{2, 3}).Order("id DESC").Order("card_status DESC").Limit(30).Find(&orderCards).Error
if err != nil {
logger.Error("err:", logger.Field("err", err))
return orders, 0, err
return nil, 0, err
}
orderIds := make([]uint32, 0)
for i, _ := range orderCards {
@ -246,6 +359,7 @@ func (m *OrderListReq) List() ([]Order, int64, error) {
qs = qs.Where("id in (?)", orderIds)
}
if m.PickupCode != "" {
isDeliver = false
qs = qs.Where("pickup_code", m.PickupCode)
@ -267,9 +381,7 @@ func (m *OrderListReq) List() ([]Order, int64, error) {
if m.GameCardId != 0 {
qs = qs.Where("game_card_id", m.GameCardId)
}
if m.CardStatus != 0 {
qs = qs.Where("card_status", m.CardStatus)
}
if m.StoreId != 0 {
qs = qs.Where("store_id", m.StoreId)
}
@ -287,7 +399,7 @@ func (m *OrderListReq) List() ([]Order, int64, error) {
err := qs.Count(&count).Error
if err != nil {
logger.Errorf("err:", logger.Field("err", err))
return orders, 0, err
return nil, 0, err
}
page := m.Page
pageSize := m.PageSize
@ -295,10 +407,16 @@ func (m *OrderListReq) List() ([]Order, int64, error) {
if page < 0 {
page = 0
}
err = qs.Preload("User").Order("created_at DESC").Offset(page * pageSize).Limit(pageSize).Find(&orders).Error
if exportFlag == 1 { //一次性导出excel
qs = qs.Preload("User").Order("created_at DESC")
} else {
qs = qs.Preload("User").Order("created_at DESC").Offset(page * pageSize).Limit(pageSize)
}
err = qs.Find(&orders).Error
if err != nil {
logger.Errorf("err:", logger.Field("err", err))
return orders, 0, err
return nil, 0, err
}
ids := make([]uint32, 0, len(orders))
@ -307,14 +425,13 @@ func (m *OrderListReq) List() ([]Order, int64, error) {
}
if len(ids) == 0 {
logger.Error("gameIds is nil")
return orders, 0, err
return nil, 0, err
}
//var orderCards []OrderCard
err = orm.Eloquent.Table("order_card").Where("order_id in (?)", ids).Find(&orderCards).Error
if err != nil {
logger.Error("err:", logger.Field("err", err))
return orders, 0, err
return nil, 0, err
}
orderCards = OrderCardListSetGameInfo(orderCards)
orderCardsMap := make(map[uint32][]OrderCard, 0)
@ -322,37 +439,125 @@ func (m *OrderListReq) List() ([]Order, int64, error) {
orderCardsMap[orderCards[i].OrderId] = append(orderCardsMap[orderCards[i].OrderId], orderCards[i])
}
for i, _ := range orders {
if orders[i].CardStatus == 2 || orders[i].CardStatus == 3 {
orders[i].CardStatus = 4
}
//2023-12-12 跟产品讨论后确认状态按原来的5种进行展示
//if orders[i].CardStatus == 2 || orders[i].CardStatus == 3 {
// orders[i].CardStatus = 4
//}
v, ok := orderCardsMap[orders[i].ID]
if ok {
orders[i].OrderCards = v
}
}
//fmt.Println("orders:", orders)
//fmt.Println("gameIds:", gameIds)
//games := make([]GameCard, 0)
//err = orm.Eloquent.Table("game_card").Where("id IN (?)", gameIds).Find(&games).Error
//if err != nil {
// logger.Errorf("err:",logger.Field("err",err))
// return orders, 0, err
//}
//fmt.Println("games:", games)
//gameMap := make(map[uint32]GameCard, 0)
//for i, _ := range games {
// gameMap[games[i].ID] = games[i]
//}
//for i, _ := range orders {
// game, ok := gameMap[uint32(orders[i].GameCardId)]
// if ok {
// orders = append(orders, orders[i].ToInfo(&game))
// }
//}
return orders, count, nil
}
// OrderListExport 导出订单列表
func OrderListExport(list []Order) (string, error) {
file := excelize.NewFile()
streamWriter, err := file.NewStreamWriter("Sheet1")
if err != nil {
fmt.Println(err)
}
url := ExportUrl
fileName := time.Now().Format(TimeFormat) + "订单" + ".xlsx"
fmt.Println("url fileName:", url+fileName)
title := []interface{}{"租赁ID", "用户ID", "会员剩余时长", "取货方式", "状态", "取货码", "实付款", "下单时间", "租赁卡ID", "游戏卡ID",
"游戏名称", "游戏卡状态"}
cell, _ := excelize.CoordinatesToCellName(1, 1)
if err = streamWriter.SetRow(cell, title); err != nil {
fmt.Println(err)
}
var row []interface{}
nExcelStartRow := 0
for rowId := 0; rowId < len(list); rowId++ {
state := "待取货"
switch list[rowId].CardStatus {
case 2:
state = "游玩中"
case 3:
state = "规划中"
case 4:
state = "已完成"
case 5:
state = "已取消"
}
deliveryType := "门店自提"
switch list[rowId].DeliveryType {
case 1:
deliveryType = "门店自提"
case 2:
deliveryType = "物流配送"
}
// user有可能为空
memberExpire := ""
if list[rowId].User != nil {
memberExpire = calculateRemainingDays(list[rowId].User.MemberExpire)
}
for i := 0; i < len(list[rowId].OrderCards); i++ {
cardState := "待取货"
switch list[rowId].OrderCards[i].CardStatus {
case 2:
cardState = "游玩中"
case 3:
cardState = "规划中"
case 4:
cardState = "已完成"
case 5:
cardState = "已取消"
}
row = []interface{}{
list[rowId].ID,
list[rowId].Uid,
memberExpire,
deliveryType,
state,
list[rowId].PickupCode,
list[rowId].PayPrice,
list[rowId].PayTime,
list[rowId].OrderCards[i].ID,
list[rowId].OrderCards[i].GameCardId,
list[rowId].OrderCards[i].GameName,
cardState}
cell, _ := excelize.CoordinatesToCellName(1, nExcelStartRow+2)
if err := streamWriter.SetRow(cell, row); err != nil {
fmt.Println(err)
}
nExcelStartRow++
}
}
if err := streamWriter.Flush(); err != nil {
fmt.Println(err)
}
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
}
// 计算剩余时长
func calculateRemainingDays(expirationTime time.Time) string {
currentTime := time.Now()
remainingTime := expirationTime.Sub(currentTime)
// 如果过期时间在当前时间之前返回0天
if remainingTime < 0 {
return "0天"
}
remainingDays := int(remainingTime.Hours() / 24)
return fmt.Sprintf("%d天", remainingDays)
}
func (m *Order) Info() (map[string]interface{}, error) {
ret := make(map[string]interface{}, 0)
err := orm.Eloquent.Table("order").Where("id", m.ID).Find(m).Error

View File

@ -11,7 +11,8 @@ import (
func registerOrderManageRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
order := v1.Group("/order")
{
order.POST("/list", ordermanage.OrderList) // 订单列表
order.POST("/list", ordermanage.OrderList) // 订单列表
order.POST("/list_export", ordermanage.OrderListExport) // 订单列表导出
}
}

View File

@ -41,7 +41,7 @@ settings:
driver: mysql
# 数据库连接字符串 mysql 缺省信息 charset=utf8&parseTime=True&loc=Local&timeout=1000ms
source: mh_dev:d9qy46ONI0ZTF9eH@tcp(39.108.188.218:3306)/mh_dev?charset=utf8&parseTime=True&loc=Local&timeout=1000ms
# source: mh_pro:fLeytnBFCRB553ab@tcp(39.108.188.218:3306)/mh_pro?charset=utf8&parseTime=True&loc=Local&timeout=1000ms
# source: mh_pro:c5JBW3X6EEVQluYM@tcp(39.108.188.218:3306)/mh_pro?charset=utf8&parseTime=True&loc=Local&timeout=1000ms
gen:
# 代码生成读取的数据库名称
@ -50,7 +50,7 @@ settings:
frontpath: ../go-admin-ui/src
export:
path: D:\\
path: /Users/max/Documents/
url: http://39.108.188.218:8000/img/export/
# path: /www/server/images/export/
# url: http://39.108.188.218:8000/img/export/
# url: https://dev.admin.deovo.com/load/export/

View File

@ -2278,6 +2278,39 @@ const docTemplate = `{
}
}
},
"/api/v1/order/list_export": {
"post": {
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"订单管理"
],
"summary": "导出订单列表",
"parameters": [
{
"description": "导出订单列表模型",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/models.OrderListReq"
}
}
],
"responses": {
"200": {
"description": "{\"code\": 200, \"data\": { \"export_url\": \"\" }}",
"schema": {
"$ref": "#/definitions/app.Response"
}
}
}
}
},
"/api/v1/post": {
"get": {
"security": [
@ -5326,6 +5359,58 @@ const docTemplate = `{
}
}
},
"models.OrderListReq": {
"type": "object",
"properties": {
"card_status": {
"description": "1-待取货中 2-游玩中 3-归还中 4-已完成 5-已取消",
"type": "integer"
},
"delivery_type": {
"description": "取货类型 1-门店自取 2-快递",
"type": "integer"
},
"end_time": {
"description": "结束时间",
"type": "string"
},
"game_card_id": {
"type": "integer"
},
"order_id": {
"type": "integer"
},
"pageIndex": {
"type": "integer"
},
"pageSize": {
"type": "integer"
},
"pay_status": {
"description": "支付状态 1-未支付 2-已支付",
"type": "integer"
},
"pickup_code": {
"description": "取货码",
"type": "string"
},
"serial_number": {
"description": "编号",
"type": "string"
},
"start_time": {
"description": "开始时间",
"type": "string"
},
"store_id": {
"description": "门店id// 游戏id",
"type": "integer"
},
"uid": {
"type": "integer"
}
}
},
"models.Post": {
"type": "object",
"properties": {

View File

@ -2267,6 +2267,39 @@
}
}
},
"/api/v1/order/list_export": {
"post": {
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"订单管理"
],
"summary": "导出订单列表",
"parameters": [
{
"description": "导出订单列表模型",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/models.OrderListReq"
}
}
],
"responses": {
"200": {
"description": "{\"code\": 200, \"data\": { \"export_url\": \"\" }}",
"schema": {
"$ref": "#/definitions/app.Response"
}
}
}
}
},
"/api/v1/post": {
"get": {
"security": [
@ -5315,6 +5348,58 @@
}
}
},
"models.OrderListReq": {
"type": "object",
"properties": {
"card_status": {
"description": "1-待取货中 2-游玩中 3-归还中 4-已完成 5-已取消",
"type": "integer"
},
"delivery_type": {
"description": "取货类型 1-门店自取 2-快递",
"type": "integer"
},
"end_time": {
"description": "结束时间",
"type": "string"
},
"game_card_id": {
"type": "integer"
},
"order_id": {
"type": "integer"
},
"pageIndex": {
"type": "integer"
},
"pageSize": {
"type": "integer"
},
"pay_status": {
"description": "支付状态 1-未支付 2-已支付",
"type": "integer"
},
"pickup_code": {
"description": "取货码",
"type": "string"
},
"serial_number": {
"description": "编号",
"type": "string"
},
"start_time": {
"description": "开始时间",
"type": "string"
},
"store_id": {
"description": "门店id// 游戏id",
"type": "integer"
},
"uid": {
"type": "integer"
}
}
},
"models.Post": {
"type": "object",
"properties": {

View File

@ -1325,6 +1325,43 @@ definitions:
visible:
type: string
type: object
models.OrderListReq:
properties:
card_status:
description: 1-待取货中 2-游玩中 3-归还中 4-已完成 5-已取消
type: integer
delivery_type:
description: 取货类型 1-门店自取 2-快递
type: integer
end_time:
description: 结束时间
type: string
game_card_id:
type: integer
order_id:
type: integer
pageIndex:
type: integer
pageSize:
type: integer
pay_status:
description: 支付状态 1-未支付 2-已支付
type: integer
pickup_code:
description: 取货码
type: string
serial_number:
description: 编号
type: string
start_time:
description: 开始时间
type: string
store_id:
description: 门店id// 游戏id
type: integer
uid:
type: integer
type: object
models.Post:
properties:
createBy:
@ -3528,6 +3565,27 @@ paths:
summary: 操作日志列表update
tags:
- system/日志
/api/v1/order/list_export:
post:
consumes:
- application/json
parameters:
- description: 导出订单列表模型
in: body
name: request
required: true
schema:
$ref: '#/definitions/models.OrderListReq'
produces:
- application/json
responses:
"200":
description: '{"code": 200, "data": { "export_url": "" }}'
schema:
$ref: '#/definitions/app.Response'
summary: 导出订单列表
tags:
- 订单管理
/api/v1/post:
get:
description: 获取JSON