panghu hace 7 meses
padre
commit
73ce701996
Se han modificado 10 ficheros con 291 adiciones y 245 borrados
  1. 0 8
      api/ceshi.go
  2. 85 6
      api/shop_order.go
  3. 1 1
      go.mod
  4. 2 0
      go.sum
  5. 1 0
      middleware/api.go
  6. 41 0
      model/x_shop_mchids.gen.go
  7. 48 0
      model/x_shop_orders.gen.go
  8. 49 0
      model/x_shop_sets.gen.go
  9. 0 230
      pkg/order/order.go
  10. 64 0
      server/orderSnServer.go

+ 0 - 8
api/ceshi.go

@@ -2,7 +2,6 @@ package api
 
 import (
 	"github.com/gin-gonic/gin"
-	"go_zh/pkg/order"
 )
 
 type CeshiController struct {
@@ -10,11 +9,4 @@ type CeshiController struct {
 }
 
 func (cs CeshiController) GetOrderSn(c *gin.Context) {
-	//order.TestConcurrentGenerationV3()
-	//order.StressTest()
-
-	generator := order.NewOrderNoGenerator(1)
-	//str := generator.Generate()
-	str := generator.GenerateString("382FS")
-	cs.responseSuccess(c, str)
 }

+ 85 - 6
api/shop_order.go

@@ -1,11 +1,14 @@
 package api
 
 import (
+	"encoding/json"
 	"fmt"
 	"github.com/gin-gonic/gin"
 	"github.com/shopspring/decimal"
+	"go_zh/model"
 	"go_zh/pkg/validator"
 	"go_zh/request/api"
+	"go_zh/server"
 )
 
 type ShopOrderController struct {
@@ -14,10 +17,7 @@ type ShopOrderController struct {
 
 func (shopOrder ShopOrderController) GetOrderSn(c *gin.Context) {
 	mId := c.GetInt("mId")
-	if mId == 0 {
-		shopOrder.responseError(c, 401, "缺少登陆信息")
-		return
-	}
+
 	//数据验证
 	var data api.CreateOrderRequest
 	msg, ok := validator.ValidatorData(c, &data)
@@ -25,6 +25,13 @@ func (shopOrder ShopOrderController) GetOrderSn(c *gin.Context) {
 		shopOrder.responseError(c, 400, msg)
 		return
 	}
+	if data.PayType == 1 {
+		if mId == 0 {
+			shopOrder.responseError(c, 401, "缺少登陆信息")
+			return
+		}
+	}
+
 	//对金额进行精度处理
 	money, err := decimal.NewFromString(data.PayMoney)
 	if err != nil {
@@ -37,6 +44,78 @@ func (shopOrder ShopOrderController) GetOrderSn(c *gin.Context) {
 		shopOrder.responseError(c, 400, "金额不合法")
 		return
 	}
-	fmt.Println("money", money)
-	fmt.Println(data)
+
+	redisServer := server.GetRedisServerInstance()
+	//获取商户银联信息
+	shopMchidModel := model.XShopMchid{}
+	var shopMchidInfo = model.XShopMchid{}
+
+	shopMchidKey := fmt.Sprintf("%s%s", "shopMachidInfo", data.ShopId)
+
+	shopMchidJson := redisServer.GetStr(shopMchidKey)
+	if len(shopMchidJson) == 0 { //没缓存信息
+		shopMchidInfo, err = shopMchidModel.GetShopBankMchid(data.ShopId)
+		if err != nil {
+			shopOrder.responseError(c, 400, "商户号信息错误"+err.Error())
+			return
+		}
+		//存入缓存
+		jsonData, _ := json.Marshal(shopMchidInfo)
+		redisServer.SetStr(shopMchidKey, string(jsonData), 120)
+	} else {
+		_ = json.Unmarshal([]byte(shopMchidJson), &shopMchidInfo)
+
+	}
+	isBank := 0
+	if shopMchidInfo.ID > 0 { //如果有银联信息就是银联支付
+		isBank = 1
+	}
+	//获取商户配置
+	shopSetModel := model.XShopSet{}
+	var shopSetInfo = model.XShopSet{}
+
+	shopSetKey := fmt.Sprintf("%s%s", "shopSetInfo", data.ShopId)
+
+	shopSetJson := redisServer.GetStr(shopSetKey)
+	if len(shopSetJson) == 0 { //没缓存信息
+		shopSetInfo, err = shopSetModel.GetShopSetInfo(data.ShopId)
+		if err != nil {
+			shopOrder.responseError(c, 400, "商户配置信息错误")
+			return
+		}
+		//存入缓存
+		shopSetJsonData, _ := json.Marshal(shopSetInfo)
+		redisServer.SetStr(shopSetKey, string(shopSetJsonData), 120)
+	} else {
+		_ = json.Unmarshal([]byte(shopSetJson), &shopSetInfo)
+
+	}
+	var discount decimal.Decimal
+	if shopSetInfo.ID <= 0 { //如果没有
+		discount, _ = decimal.NewFromString("0")
+	} else {
+		discount = shopSetInfo.Discount
+	}
+	orderSnServer := server.GetOrderSnServerInstance(1)
+	orderSn := orderSnServer.GenerateString("382FS")
+	//创建订单信息
+	shopOrderModel := model.XShopOrder{}
+	shopOrderModel.ShopID = data.ShopId
+	shopOrderModel.PayType = data.PayType
+	shopOrderModel.MID = mId
+	shopOrderModel.RsSn = orderSn
+	shopOrderModel.PayMoney = money
+	shopOrderModel.Status = 1
+	shopOrderModel.Discount = discount
+	shopOrderModel.IsClearing = 0
+	shopOrderModel.IsReport = 0
+	shopOrderModel.PayCodeSource = data.PayCodeSource
+	shopOrderModel.IsBank = isBank
+
+	err = shopOrderModel.CreateShopOrder()
+	if err != nil {
+		shopOrder.responseError(c, 400, "订单创建失败")
+		return
+	}
+	shopOrder.responseSuccess(c, shopOrderModel.ID)
 }

+ 1 - 1
go.mod

@@ -5,7 +5,7 @@ go 1.25.6
 require go.uber.org/zap v1.27.1
 
 require (
-	filippo.io/edwards25519 v1.1.0 // indirect
+	filippo.io/edwards25519 v1.1.1 // indirect
 	github.com/bytedance/gopkg v0.1.3 // indirect
 	github.com/bytedance/sonic v1.15.0 // indirect
 	github.com/bytedance/sonic/loader v0.5.0 // indirect

+ 2 - 0
go.sum

@@ -1,5 +1,7 @@
 filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
 filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
+filippo.io/edwards25519 v1.1.1 h1:YpjwWWlNmGIDyXOn8zLzqiD+9TyIlPhGFG96P39uBpw=
+filippo.io/edwards25519 v1.1.1/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
 github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M=
 github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM=
 github.com/bytedance/sonic v1.15.0 h1:/PXeWFaR5ElNcVE84U0dOHjiMHQOwNIx3K4ymzh/uSE=

+ 1 - 0
middleware/api.go

@@ -11,6 +11,7 @@ import (
 // 不需要token验证的路由白名单
 var whiteList = []string{
 	"/api/auth/login",
+	"/api/shopOrder/create",
 }
 
 func ApiMiddleware() gin.HandlerFunc {

+ 41 - 0
model/x_shop_mchids.gen.go

@@ -0,0 +1,41 @@
+// Code generated by gorm.io/gen. DO NOT EDIT.
+// Code generated by gorm.io/gen. DO NOT EDIT.
+// Code generated by gorm.io/gen. DO NOT EDIT.
+
+package model
+
+import (
+	"go_zh/config"
+	"time"
+)
+
+const TableNameXShopMchid = "x_shop_mchids"
+
+// XShopMchid mapped from table <x_shop_mchids>
+type XShopMchid struct {
+	ID         int     `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"`
+	ShopID     int     `gorm:"column:shop_id;not null" json:"shop_id"`
+	SubMchid   string    `gorm:"column:sub_mchid;not null;comment:商户-商户号" json:"sub_mchid"` // 商户-商户号
+	Type       int      `gorm:"column:type;default:1;comment:1微信 2支付宝 3银联" json:"type"`    // 1微信 2支付宝 3银联
+	IsDel      int      `gorm:"column:is_del;comment:是否删除 0:否,1:是" json:"is_del"`          // 是否删除 0:否,1:是
+	CreatedAt  time.Time `gorm:"column:created_at" json:"created_at"`
+	UpdatedAt  time.Time `gorm:"column:updated_at" json:"updated_at"`
+	Enterprise string    `gorm:"column:enterprise;comment:银联 企业用户号" json:"enterprise"` // 银联 企业用户号
+	Tid        string    `gorm:"column:tid;comment:银联 终端编号" json:"tid"`                // 银联 终端编号
+}
+
+// TableName XShopMchid's table name
+func (*XShopMchid) TableName() string {
+	return TableNameXShopMchid
+}
+
+
+//获取商户银联信息
+func (*XShopMchid)  GetShopBankMchid(shopId int) (XShopMchid, error)  {
+	mchidInfo := XShopMchid{}
+	model := config.Mdb.Model(mchidInfo).Where("shop_id = ? AND is_del = ? AND type = ?",shopId,0,3)
+	if err := model.Find(&mchidInfo).Error; err != nil {
+		return mchidInfo,err
+	}
+	return mchidInfo, nil
+}

+ 48 - 0
model/x_shop_orders.gen.go

@@ -0,0 +1,48 @@
+// Code generated by gorm.io/gen. DO NOT EDIT.
+// Code generated by gorm.io/gen. DO NOT EDIT.
+// Code generated by gorm.io/gen. DO NOT EDIT.
+
+package model
+
+import (
+	"github.com/shopspring/decimal"
+	"go_zh/config"
+	"time"
+)
+
+const TableNameXShopOrder = "x_shop_orders"
+
+// XShopOrder mapped from table <x_shop_orders>
+type XShopOrder struct {
+	ID            int     `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"`
+	ShopID        int     `gorm:"column:shop_id;not null;comment:店铺ID" json:"shop_id"`                // 店铺ID
+	MID           int     `gorm:"column:m_id;not null;comment:会员ID" json:"m_id"`                      // 会员ID
+	RsSn          string    `gorm:"column:rs_sn;not null;comment:店铺订单支付编号" json:"rs_sn"`                // 店铺订单支付编号
+	PaySn         string    `gorm:"column:pay_sn;not null;comment:支付编号" json:"pay_sn"`                  // 支付编号
+	PayType       int     `gorm:"column:pay_type;not null;comment:支付类型,1:微信,2:支付宝" json:"pay_type"`   // 支付类型,1:微信,2:支付宝
+	PayMoney      decimal.Decimal   `gorm:"column:pay_money;not null;comment:支付金额" json:"pay_money"`            // 支付金额
+	Status        int     `gorm:"column:status;not null;comment:1:待支付,2:已支付,3:已退款,已完成" json:"status"` // 1:待支付,2:已支付,3:已退款,已完成
+	CreatedAt     time.Time `gorm:"column:created_at" json:"created_at"`
+	UpdatedAt     time.Time `gorm:"column:updated_at" json:"updated_at"`
+	Discount      decimal.Decimal   `gorm:"column:discount;default:0.00;comment:折扣金额" json:"discount"`                             // 折扣金额
+	IsClearing    int      `gorm:"column:is_clearing;comment:是否清分 0:待清分,1:已清分" json:"is_clearing"`                        // 是否清分 0:待清分,1:已清分
+	ServiceMoney  decimal.Decimal   `gorm:"column:service_money;not null;default:0.00;comment:平台手续费" json:"service_money"`         // 平台手续费
+	DiscountMoney decimal.Decimal   `gorm:"column:discount_money;not null;default:0.00;comment:让利金额" json:"discount_money"`        // 让利金额
+	EarningsMoney decimal.Decimal   `gorm:"column:earnings_money;not null;default:0.00;comment:收益金额" json:"earnings_money"`        // 收益金额
+	ReturnSn      string    `gorm:"column:return_sn;comment:退款订单编号" json:"return_sn"`                                      // 退款订单编号
+	IsReport      int      `gorm:"column:is_report;comment:是否播报" json:"is_report"`                                        // 是否播报
+	PayCodeSource int     `gorm:"column:pay_code_source;default:1;comment:支付收款码来源 1普通收款码 2烟草收款码" json:"pay_code_source"` // 支付收款码来源 1普通收款码 2烟草收款码
+	IsBank        int     `gorm:"column:is_bank;comment:是否银联支付 0否1是" json:"is_bank"`                                     // 是否银联支付 0否1是
+}
+
+// TableName XShopOrder's table name
+func (*XShopOrder) TableName() string {
+	return TableNameXShopOrder
+}
+
+//新增订单
+func (so *XShopOrder) CreateShopOrder() error {
+
+	err := config.Mdb.Model(&so).Create(&so).Error
+	return err
+}

+ 49 - 0
model/x_shop_sets.gen.go

@@ -0,0 +1,49 @@
+// Code generated by gorm.io/gen. DO NOT EDIT.
+// Code generated by gorm.io/gen. DO NOT EDIT.
+// Code generated by gorm.io/gen. DO NOT EDIT.
+
+package model
+
+import (
+	"github.com/shopspring/decimal"
+	"go_zh/config"
+	"time"
+)
+
+const TableNameXShopSet = "x_shop_sets"
+
+// XShopSet mapped from table <x_shop_sets>
+type XShopSet struct {
+	ID           int     `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"`
+	ShopID       int     `gorm:"column:shop_id;not null;comment:店铺ID" json:"shop_id"`                // 店铺ID
+	Discount     decimal.Decimal   `gorm:"column:discount;not null;comment:折扣比列" json:"discount"`              // 折扣比列
+	ProvinceNum  decimal.Decimal   `gorm:"column:province_num;not null;comment:省级返佣比列" json:"province_num"`    // 省级返佣比列
+	CityNum      decimal.Decimal   `gorm:"column:city_num;not null;comment:市级返佣比列" json:"city_num"`            // 市级返佣比列
+	AreaNum      decimal.Decimal   `gorm:"column:area_num;not null;comment:区级返佣比列" json:"area_num"`            // 区级返佣比列
+	SalesNum     decimal.Decimal   `gorm:"column:sales_num;not null;comment:分销商返佣比列" json:"sales_num"`         // 分销商返佣比列
+	ShopNum      decimal.Decimal   `gorm:"column:shop_num;not null;comment:店铺返佣比列" json:"shop_num"`            // 店铺返佣比列
+	MemberNum    decimal.Decimal   `gorm:"column:member_num;not null;comment:会员公益豆获取比列" json:"member_num"`     // 会员公益豆获取比列
+	PurchasesNum decimal.Decimal   `gorm:"column:purchases_num;not null;comment:进货金获取比列" json:"purchases_num"` // 进货金获取比列
+	CreatedAt    time.Time `gorm:"column:created_at" json:"created_at"`
+	UpdatedAt    time.Time `gorm:"column:updated_at" json:"updated_at"`
+	FansNum      int     `gorm:"column:fans_num;default:5000;comment:粉丝最大数量" json:"fans_num"`       // 粉丝最大数量
+	MemberCash   decimal.Decimal   `gorm:"column:member_cash;default:0.00;comment:会员返现比列" json:"member_cash"` // 会员返现比列
+	ServiceNum   decimal.Decimal   `gorm:"column:service_num;not null;comment:交易手续费" json:"service_num"`      // 交易手续费
+	Performance  decimal.Decimal   `gorm:"column:performance;comment:业绩" json:"performance"`                  // 业绩
+	IsBean       int      `gorm:"column:is_bean;comment:是否启用分销提成转化振合豆 0否1是" json:"is_bean"`          // 是否启用分销提成转化振合豆 0否1是
+}
+
+// TableName XShopSet's table name
+func (*XShopSet) TableName() string {
+	return TableNameXShopSet
+}
+
+//获取商户配置
+func (se *XShopSet) GetShopSetInfo(shopId int) (XShopSet, error)  {
+	shopSet := XShopSet{}
+	model := config.Mdb.Model(shopSet).Where("shop_id = ?",shopId)
+	if err := model.First(&shopSet).Error; err != nil {
+		return shopSet,err
+	}
+	return shopSet, nil
+}

+ 0 - 230
pkg/order/order.go

@@ -1,230 +0,0 @@
-package order
-
-import (
-	"fmt"
-	"sync"
-	"sync/atomic"
-	"time"
-)
-
-// 更安全的版本:带毫秒时间戳
-type Generator struct {
-	machineID int
-	lastTime  int64 // 上次时间(毫秒)
-	sequence  int64
-	mu        sync.Mutex
-}
-
-func NewOrderNoGenerator(machineID int) *Generator {
-	return &Generator{
-		machineID: machineID,
-		lastTime:  time.Now().UnixMilli(),
-		sequence:  0,
-	}
-}
-
-func (g *Generator) Generate() string {
-	g.mu.Lock()
-	defer g.mu.Unlock()
-
-	currentTime := time.Now().UnixMilli()
-
-	if currentTime == g.lastTime {
-		g.sequence++
-	} else {
-		g.sequence = 1
-		g.lastTime = currentTime
-	}
-
-	// 格式化时间,包含毫秒
-	t := time.UnixMilli(currentTime)
-	// 格式:年月日时分秒 + 毫秒(3位) + 机器ID + 序列号
-	return fmt.Sprintf("%s%03d%02d%04d",
-		t.Format("20060102150405"), // 14位
-		t.Nanosecond()/1e6,         // 3位毫秒
-		g.machineID,                // 2位
-		g.sequence,                 // 4位
-	)
-}
-
-// GenerateString 生成字符串格式订单号
-func (g *Generator) GenerateString(prefix string) string {
-	// 调用无锁Generate获取ID
-	id := g.Generate()
-
-	// 格式化为字符串
-	return fmt.Sprintf("%s%s", prefix, id)
-}
-
-type GeneratorV3 struct {
-	machineID int
-	// 使用一个64位整数存储时间戳(42位)和序列号(22位)
-	// 这样可以原子操作,不需要锁
-	counter uint64
-}
-
-func NewOrderNoGeneratorV3(machineID int) *GeneratorV3 {
-	return &GeneratorV3{
-		machineID: machineID,
-		counter:   0,
-	}
-}
-
-func (g *GeneratorV3) Generate() string {
-	// 获取当前毫秒时间戳
-	now := uint64(time.Now().UnixMilli())
-
-	// 原子操作获取下一个ID
-	var lastTime, seq uint64
-	for {
-		old := atomic.LoadUint64(&g.counter)
-		lastTime = old >> 22 // 高42位是时间戳
-		seq = old & 0x3FFFFF // 低22位是序列号
-
-		if now > lastTime {
-			// 时间戳变化,重置序列号
-			seq = 0
-			lastTime = now
-		} else if seq >= 0x3FFFFF { // 序列号达到最大值
-			// 等待下一毫秒
-			for now <= lastTime {
-				time.Sleep(100 * time.Microsecond)
-				now = uint64(time.Now().UnixMilli())
-			}
-			seq = 0
-			lastTime = now
-		} else {
-			seq++
-		}
-
-		newVal := (lastTime << 22) | (seq & 0x3FFFFF)
-		if atomic.CompareAndSwapUint64(&g.counter, old, newVal) {
-			break
-		}
-	}
-
-	// 格式化输出
-	t := time.UnixMilli(int64(lastTime))
-	return fmt.Sprintf("%s%03d%02d%06d",
-		t.Format("20060102150405"),
-		t.Nanosecond()/1e6,
-		g.machineID,
-		seq,
-	)
-}
-
-// 并发测试函数
-func TestConcurrentGeneration() {
-	fmt.Println("=== 并发测试 ===")
-	generator := NewOrderNoGenerator(1)
-
-	// 使用map检查重复
-	results := sync.Map{}
-	var wg sync.WaitGroup
-	start := time.Now()
-
-	// 启动1000个协程同时生成订单号
-	for i := 0; i < 1000; i++ {
-		wg.Add(1)
-		go func(id int) {
-			defer wg.Done()
-			orderNo := generator.Generate()
-
-			// 检查是否重复
-			if _, loaded := results.LoadOrStore(orderNo, true); loaded {
-				fmt.Printf("⚠️  发现重复订单号: %s\n", orderNo)
-			}
-		}(i)
-	}
-
-	wg.Wait()
-	elapsed := time.Since(start)
-
-	// 统计结果
-	count := 0
-	results.Range(func(key, value interface{}) bool {
-		count++
-		return true
-	})
-
-	fmt.Printf("生成 %d 个订单号,耗时 %v\n", count, elapsed)
-	fmt.Printf("平均每秒生成: %.0f 个\n", float64(count)/elapsed.Seconds())
-}
-
-// 测试V3版本的并发
-func TestConcurrentGenerationV3() {
-	fmt.Println("\n=== 测试V3版本并发 ===")
-	generator := NewOrderNoGeneratorV3(1)
-
-	results := sync.Map{}
-	var wg sync.WaitGroup
-	start := time.Now()
-
-	// 启动10000个协程同时生成订单号
-	for i := 0; i < 10000; i++ {
-		wg.Add(1)
-		go func(id int) {
-			defer wg.Done()
-			orderNo := generator.Generate()
-
-			// 检查是否重复
-			if _, loaded := results.LoadOrStore(orderNo, true); loaded {
-				fmt.Printf("⚠️ V3 - 发现重复订单号: %s\n", orderNo)
-			}
-		}(i)
-	}
-
-	wg.Wait()
-	elapsed := time.Since(start)
-
-	// 统计结果
-	count := 0
-	results.Range(func(key, value interface{}) bool {
-		count++
-		return true
-	})
-
-	fmt.Printf("V3 - 生成 %d 个订单号,耗时 %v\n", count, elapsed)
-	fmt.Printf("V3 - 平均每秒生成: %.0f 个\n", float64(count)/elapsed.Seconds())
-}
-
-// 压力测试:持续生成订单号
-func StressTest() {
-	fmt.Println("\n=== 压力测试 ===")
-	generator := NewOrderNoGeneratorV3(1)
-
-	results := sync.Map{}
-	duplicateCount := 0
-	var duplicateMutex sync.Mutex
-
-	// 持续生成5秒
-	stop := time.After(5 * time.Second)
-	start := time.Now()
-
-	for i := 0; ; i++ {
-		select {
-		case <-stop:
-			elapsed := time.Since(start)
-			totalCount := 0
-			results.Range(func(key, value interface{}) bool {
-				totalCount++
-				return true
-			})
-
-			fmt.Printf("压力测试 - 总生成: %d 个订单号\n", i)
-			fmt.Printf("压力测试 - 唯一订单号: %d 个\n", totalCount)
-			fmt.Printf("压力测试 - 重复数: %d 个\n", duplicateCount)
-			fmt.Printf("压力测试 - 耗时: %v\n", elapsed)
-			fmt.Printf("压力测试 - QPS: %.0f\n", float64(i)/elapsed.Seconds())
-			return
-
-		default:
-			orderNo := generator.Generate()
-			if _, loaded := results.LoadOrStore(orderNo, true); loaded {
-				duplicateMutex.Lock()
-				duplicateCount++
-				duplicateMutex.Unlock()
-			}
-		}
-	}
-}

+ 64 - 0
server/orderSnServer.go

@@ -0,0 +1,64 @@
+package server
+
+import (
+	"fmt"
+	"sync"
+	"time"
+)
+
+type orderSnServer struct {
+	machineID int
+	lastTime  int64 // 上次时间(毫秒)
+	sequence  int64
+	mu        sync.Mutex
+}
+
+var (
+	orderSnServerInstance *orderSnServer
+	orderSnServerOnce     sync.Once
+)
+
+// GetOrderSnServerInstance 获取单例实例
+func GetOrderSnServerInstance(machineID int) *orderSnServer {
+	orderSnServerOnce.Do(func() {
+		orderSnServerInstance = &orderSnServer{
+			machineID: machineID,
+			lastTime:  time.Now().UnixMilli(),
+			sequence:  0,
+		}
+	})
+	return orderSnServerInstance
+}
+
+func (g *orderSnServer) Generate() string {
+	g.mu.Lock()
+	defer g.mu.Unlock()
+
+	currentTime := time.Now().UnixMilli()
+
+	if currentTime == g.lastTime {
+		g.sequence++
+	} else {
+		g.sequence = 1
+		g.lastTime = currentTime
+	}
+
+	// 格式化时间,包含毫秒
+	t := time.UnixMilli(currentTime)
+	// 格式:年月日时分秒 + 毫秒(3位) + 机器ID + 序列号
+	return fmt.Sprintf("%s%03d%02d%04d",
+		t.Format("20060102150405"), // 14位
+		t.Nanosecond()/1e6,         // 3位毫秒
+		g.machineID,                // 2位
+		g.sequence,                 // 4位
+	)
+}
+
+// GenerateString 生成字符串格式订单号
+func (g *orderSnServer) GenerateString(prefix string) string {
+	// 调用无锁Generate获取ID
+	id := g.Generate()
+
+	// 格式化为字符串
+	return fmt.Sprintf("%s%s", prefix, id)
+}