Go
/*
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author : geovindu,Geovin Du 涂聚文.
# IDE : goLang 2024.3.6 go 26.2
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/8/4 23:15
# User : geovindu
# Product : GoLand
# Project : BitOperation
# File : bfs_combine.go
*/
package algorithm
import (
"BitOperation/domain/entity"
"container/list"
)
type node struct {
mask int
totalW float64
totalP float64
}
// BfsJewelryCombiner BFS+位掩码搭配算法
type BfsJewelryCombiner struct {
jewels []*entity.Jewelry
n int
maxW float64
maxP float64
bestMask int
bestRate float64
}
func NewBfsJewelryCombiner(list []*entity.Jewelry, maxW, maxP float64) *BfsJewelryCombiner {
return &BfsJewelryCombiner{
jewels: list,
n: len(list),
maxW: maxW,
maxP: maxP,
}
}
func (b *BfsJewelryCombiner) SearchBestCombine() ([]string, float64, float64) {
queue := list.New()
queue.PushBack(node{mask: 0, totalW: 0, totalP: 0})
b.bestMask = 0
b.bestRate = 0
for queue.Len() > 0 {
elem := queue.Front()
queue.Remove(elem)
cur := elem.Value.(node)
rate := 0.0
if cur.totalW > 0 {
rate = cur.totalP / cur.totalW
}
if rate > b.bestRate {
b.bestRate = rate
b.bestMask = cur.mask
}
for i := 0; i < b.n; i++ {
if (cur.mask & (1 << i)) == 0 {
newMask := cur.mask | (1 << i)
newW := cur.totalW + b.jewels[i].Weight
newP := cur.totalP + b.jewels[i].Price
if newW <= b.maxW && newP <= b.maxP {
queue.PushBack(node{mask: newMask, totalW: newW, totalP: newP})
}
}
}
}
// 解析掩码
var ids []string
var tw, tp float64
for i := 0; i < b.n; i++ {
if (b.bestMask & (1 << i)) != 0 {
ids = append(ids, b.jewels[i].JewelID)
tw += b.jewels[i].Weight
tp += b.jewels[i].Price
}
}
return ids, tw, tp
}
/*
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author : geovindu,Geovin Du 涂聚文.
# IDE : goLang 2024.3.6 go 26.2
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/8/4 23:16
# User : geovindu
# Product : GoLand
# Project : BitOperation
# File : bit_array.go
*/
package algorithm
// BitArray 高性能位图,千万级查重、黑名单过滤
type BitArray struct {
size int
arr []byte
}
func NewBitArray(size int) *BitArray {
byteLen := (size + 7) / 8
return &BitArray{
size: size,
arr: make([]byte, byteLen),
}
}
func (b *BitArray) Set(idx int) {
if idx < 0 || idx >= b.size {
return
}
pos := idx / 8
bit := idx % 8
b.arr[pos] |= 1 << bit
}
func (b *BitArray) UnSet(idx int) {
if idx < 0 || idx >= b.size {
return
}
pos := idx / 8
bit := idx % 8
b.arr[pos] &^= 1 << bit
}
func (b *BitArray) Get(idx int) bool {
if idx < 0 || idx >= b.size {
return false
}
pos := idx / 8
bit := idx % 8
return (b.arr[pos] & (1 << bit)) != 0
}
func (b *BitArray) BatchSet(indexList []int) {
for _, idx := range indexList {
b.Set(idx)
}
}
func (b *BitArray) BatchCheck(indexList []int) []bool {
res := make([]bool, len(indexList))
for i, idx := range indexList {
res[i] = b.Get(idx)
}
return res
}
/*
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author : geovindu,Geovin Du 涂聚文.
# IDE : goLang 2024.3.6 go 26.2
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/8/4 23:15
# User : geovindu
# Product : GoLand
# Project : BitOperation
# File : gale_shapley.go
*/
package algorithm
import "BitOperation/domain/entity"
// GaleShapleyMatcher GS稳定婚配算法
type GaleShapleyMatcher struct {
guideList []*entity.Guide
custList []*entity.Customer
guideMap map[string]*entity.Guide
custMap map[string]*entity.Customer
guideMatch map[string]string
custMatch map[string]string
guidePtr map[string]int
}
func NewGaleShapleyMatcher(guides []*entity.Guide, customers []*entity.Customer) *GaleShapleyMatcher {
gm := make(map[string]*entity.Guide)
cm := make(map[string]*entity.Customer)
ptr := make(map[string]int)
for _, g := range guides {
gm[g.GuideID] = g
ptr[g.GuideID] = 0
}
for _, c := range customers {
cm[c.CustomerID] = c
}
return &GaleShapleyMatcher{
guideList: guides,
custList: customers,
guideMap: gm,
custMap: cm,
guideMatch: make(map[string]string),
custMatch: make(map[string]string),
guidePtr: ptr,
}
}
func (g *GaleShapleyMatcher) getCustRank(guide *entity.Guide, cid string) int {
for idx, id := range guide.CustomerPriority {
if id == cid {
return idx
}
}
return 999
}
func (g *GaleShapleyMatcher) getGuideRank(cust *entity.Customer, gid string) int {
guide := g.guideMap[gid]
score := cust.MatchScore(guide.SkillMask)
return -score
}
func (g *GaleShapleyMatcher) Match() map[string]string {
freeGuide := make([]string, 0)
for _, gObj := range g.guideList {
freeGuide = append(freeGuide, gObj.GuideID)
}
for len(freeGuide) > 0 {
gid := freeGuide[0]
freeGuide = freeGuide[1:]
guide := g.guideMap[gid]
ptr := g.guidePtr[gid]
if ptr >= len(guide.CustomerPriority) {
continue
}
cid := guide.CustomerPriority[ptr]
g.guidePtr[gid]++
cust := g.custMap[cid]
if _, ok := g.custMatch[cid]; !ok {
g.guideMatch[gid] = cid
g.custMatch[cid] = gid
} else {
oldGid := g.custMatch[cid]
r1 := g.getGuideRank(cust, gid)
r2 := g.getGuideRank(cust, oldGid)
if r1 < r2 {
g.guideMatch[gid] = cid
g.custMatch[cid] = gid
delete(g.guideMatch, oldGid)
freeGuide = append(freeGuide, oldGid)
} else {
freeGuide = append(freeGuide, gid)
}
}
}
return g.custMatch
}
/*
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author : geovindu,Geovin Du 涂聚文.
# IDE : goLang 2024.3.6 go 26.2
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/8/4 23:12
# User : geovindu
# Product : GoLand
# Project : BitOperation
# File : combine_rule.go
*/
package domain_rule
import (
"BitOperation/domain/entity"
"BitOperation/domain/valueobject"
)
// CombineDomainRule 首饰搭配领域约束规则
type CombineDomainRule struct {
MAX_COMBINE_COUNT int
MIN_COMBINE_WEIGHT float64
MUTEX_GOLD int
MUTEX_PLATINUM int
}
func NewCombineDomainRule() *CombineDomainRule {
return &CombineDomainRule{
MAX_COMBINE_COUNT: 6,
MIN_COMBINE_WEIGHT: 1.0,
MUTEX_GOLD: valueobject.GOLD,
MUTEX_PLATINUM: valueobject.PLATINUM,
}
}
// IsSingleJewelValid 单件首饰校验
func (c *CombineDomainRule) IsSingleJewelValid(j *entity.Jewelry) (bool, string) {
if j == nil {
return false, "对象非首饰Jewelry实体"
}
if j.JewelID == "" {
return false, "首饰唯一ID为空"
}
if j.Weight <= 0 {
return false, "首饰[" + j.JewelID + "]克重非法,必须大于0"
}
if j.Price <= 0 {
return false, "首饰[" + j.JewelID + "]价格非法,必须大于0"
}
return true, "单件首饰校验通过"
}
// CheckMaterialMutex 黄金铂金互斥校验
func (c *CombineDomainRule) CheckMaterialMutex(combineMask int) (bool, string) {
hasGold := (combineMask & c.MUTEX_GOLD) != 0
hasPt := (combineMask & c.MUTEX_PLATINUM) != 0
if hasGold && hasPt {
return false, "搭配组合违反规则:黄金与铂金禁止放入同一礼盒"
}
return true, "材质互斥校验通过"
}
// CheckCombineThreshold 重量价格阈值校验
func (c *CombineDomainRule) CheckCombineThreshold(totalW, totalP, maxW, maxP float64) (bool, string) {
if totalW < c.MIN_COMBINE_WEIGHT {
return false, "总克重低于礼盒最低克重1.0g"
}
if totalW > maxW {
return false, "总克重超出上限"
}
if totalP > maxP {
return false, "总价超出价格上限"
}
return true, "搭配阈值校验通过"
}
// CheckCombineCount 件数上限
func (c *CombineDomainRule) CheckCombineCount(cnt int) (bool, string) {
if cnt > c.MAX_COMBINE_COUNT {
return false, "搭配件数超出礼盒最大件数6件"
}
return true, "件数校验通过"
}
// BatchFilterAvailableJewels 批量过滤合法首饰
func (c *CombineDomainRule) BatchFilterAvailableJewels(list []*entity.Jewelry) ([]*entity.Jewelry, []string) {
var valid []*entity.Jewelry
var errLog []string
for _, j := range list {
ok, msg := c.IsSingleJewelValid(j)
if ok {
valid = append(valid, j)
} else {
errLog = append(errLog, msg)
}
}
return valid, errLog
}
// FullCombineCheck 组合全量综合校验
func (c *CombineDomainRule) FullCombineCheck(mask int, jewels []*entity.Jewelry, totalW, totalP, maxW, maxP float64) (bool, string) {
ok, msg := c.CheckCombineCount(len(jewels))
if !ok {
return false, msg
}
ok, msg = c.CheckMaterialMutex(mask)
if !ok {
return false, msg
}
ok, msg = c.CheckCombineThreshold(totalW, totalP, maxW, maxP)
if !ok {
return false, msg
}
return true, "搭配组合完全合规"
}
/*
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author : geovindu,Geovin Du 涂聚文.
# IDE : goLang 2024.3.6 go 26.2
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/8/4 23:11
# User : geovindu
# Product : GoLand
# Project : BitOperation
# File : match_rule.go
*/
package domain_rule
import (
"BitOperation/domain/entity"
"BitOperation/domain/valueobject"
)
// 包内常量:固定全局掩码标识,编译期常量,合法标准写法
const (
GUIDE_OFFLINE_MASK = 1 << 30
CUSTOMER_BLACK_MASK = 1 << 31
SENIOR_GUIDE_TAG = 1 << 28
)
// MatchDomainRule 导购-客户匹配领域规则结构体,仅保留运行期赋值字段
type MatchDomainRule struct {
LUXURY_MASK int // 高奢组合掩码,构造函数内组合赋值
}
// NewMatchDomainRule 构造函数:统一初始化组合掩码
func NewMatchDomainRule() *MatchDomainRule {
return &MatchDomainRule{
LUXURY_MASK: valueobject.HIGHPRICE | valueobject.DIAMOND,
}
}
// IsGuideValid 导购合法性校验
func (m *MatchDomainRule) IsGuideValid(g *entity.Guide) (bool, string) {
if g == nil {
return false, "实体类型错误,非导购Guide对象"
}
if g.GuideID == "" {
return false, "导购ID不能为空"
}
if len(g.CustomerPriority) == 0 {
return false, "导购未配置客户接待优先级列表,无法参与匹配"
}
if (g.SkillMask & GUIDE_OFFLINE_MASK) != 0 {
return false, "导购[" + g.GuideID + "]当前离岗,禁止分配客户"
}
return true, "导购校验通过"
}
// IsCustomerValid 客户合法性校验
func (m *MatchDomainRule) IsCustomerValid(c *entity.Customer) (bool, string) {
if c == nil {
return false, "实体类型错误,非客户Customer对象"
}
if c.CustomerID == "" {
return false, "客户ID不能为空"
}
if len(c.PriorityList) == 0 {
return false, "客户未配置导购偏好优先级,无法参与匹配"
}
if (c.PreferenceMask & CUSTOMER_BLACK_MASK) != 0 {
return false, "客户[" + c.CustomerID + "]处于黑名单,禁止分配导购接待"
}
return true, "客户校验通过"
}
// CheckLuxuryMatchLimit 高奢导购资质校验
func (m *MatchDomainRule) CheckLuxuryMatchLimit(g *entity.Guide, c *entity.Customer) (bool, string) {
needLuxury := (c.PreferenceMask & m.LUXURY_MASK) != 0
if !needLuxury {
return true, "非高奢需求,无导购等级限制"
}
if (g.SkillMask & SENIOR_GUIDE_TAG) == 0 {
return false, "客户[" + c.CustomerID + "]存在高奢需求,导购[" + g.GuideID + "]非资深导购,禁止匹配"
}
return true, "高奢需求匹配资格校验通过"
}
// BatchCheckMatchEntrance 批量准入过滤
func (m *MatchDomainRule) BatchCheckMatchEntrance(guides []*entity.Guide, customers []*entity.Customer) ([]*entity.Guide, []*entity.Customer, []string) {
var validGuide []*entity.Guide
var validCust []*entity.Customer
var errLog []string
for _, g := range guides {
ok, msg := m.IsGuideValid(g)
if ok {
validGuide = append(validGuide, g)
} else {
errLog = append(errLog, "导购过滤:"+msg)
}
}
for _, c := range customers {
ok, msg := m.IsCustomerValid(c)
if ok {
validCust = append(validCust, c)
} else {
errLog = append(errLog, "客户过滤:"+msg)
}
}
return validGuide, validCust, errLog
}
/*
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author : geovindu,Geovin Du 涂聚文.
# IDE : goLang 2024.3.6 go 26.2
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/8/4 23:14
# User : geovindu
# Product : GoLand
# Project : BitOperation
# File : blacklist.go
*/
package entity
import "sync"
// BlackList 假货黑名单实体
type BlackList struct {
fakeIds map[string]bool
mu sync.RWMutex
}
func NewBlackList() *BlackList {
return &BlackList{
fakeIds: make(map[string]bool),
}
}
func (b *BlackList) AddFake(id string) {
b.mu.Lock()
defer b.mu.Unlock()
b.fakeIds[id] = true
}
func (b *BlackList) BatchAdd(ids []string) {
b.mu.Lock()
defer b.mu.Unlock()
for _, id := range ids {
b.fakeIds[id] = true
}
}
func (b *BlackList) IsFake(id string) bool {
b.mu.RLock()
defer b.mu.RUnlock()
return b.fakeIds[id]
}
/*
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author : geovindu,Geovin Du 涂聚文.
# IDE : goLang 2024.3.6 go 26.2
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/8/4 23:08
# User : geovindu
# Product : GoLand
# Project : BitOperation
# File : customer.go
*/
package entity
// Customer 客户领域实体
type Customer struct {
CustomerID string
PreferenceMask int
PriorityList []string // 导购偏好优先级列表
}
// MatchScore 计算与导购技能掩码匹配重合bit数量
func (c *Customer) MatchScore(guideMask int) int {
sameBit := c.PreferenceMask & guideMask
cnt := 0
for sameBit > 0 {
cnt++
sameBit &= sameBit - 1
}
return cnt
}
/*
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author : geovindu,Geovin Du 涂聚文.
# IDE : goLang 2024.3.6 go 26.2
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/8/4 23:13
# User : geovindu
# Product : GoLand
# Project : BitOperation
# File : guide.go
*/
package entity
// Guide 导购领域实体
type Guide struct {
GuideID string
SkillMask int
CustomerPriority []string // 接待客户优先级
}
/*
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author : geovindu,Geovin Du 涂聚文.
# IDE : goLang 2024.3.6 go 26.2
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/8/4 23:13
# User : geovindu
# Product : GoLand
# Project : BitOperation
# File : jewelry.go
*/
package entity
// Jewelry 首饰实体
type Jewelry struct {
JewelID string
Mask int
Weight float64
Price float64
GroupTag int
}
/*
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author : geovindu,Geovin Du 涂聚文.
# IDE : goLang 2024.3.6 go 26.2
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/8/4 23:07
# User : geovindu
# Product : GoLand
# Project : BitOperation
# File : bit_mask.go
*/
package valueobject
// 材质、风格、价位 位掩码常量
const (
// 材质掩码
GOLD = 1 << 0
KGOLD = 1 << 1
PLATINUM = 1 << 2
DIAMOND = 1 << 3
JADE = 1 << 4
PEARL = 1 << 5
RUBY = 1 << 6
SAPPHIRE = 1 << 7
// 风格掩码
LUXURY = 1 << 10
SIMPLE = 1 << 11
RETRO = 1 << 12
MINIMALIST = 1 << 13
// 价位档位
LOWPRICE = 1 << 20
MIDPRICE = 1 << 21
HIGHPRICE = 1 << 22
)
// BitMaskHelper 辅助结构体,承载材质/价位等掩码常量,供上层以字段形式访问 mask.DIAMOND 等
type BitMaskHelper struct {
GOLD int
KGOLD int
PLATINUM int
DIAMOND int
JADE int
PEARL int
HIGHPRICE int
}
func NewPreferenceBitMask() *BitMaskHelper {
return &BitMaskHelper{
GOLD: GOLD,
KGOLD: KGOLD,
PLATINUM: PLATINUM,
DIAMOND: DIAMOND,
JADE: JADE,
PEARL: PEARL,
HIGHPRICE: HIGHPRICE,
}
}
/*
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author : geovindu,Geovin Du 涂聚文.
# IDE : goLang 2024.3.6 go 26.2
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/8/4 23:06
# User : geovindu
# Product : GoLand
# Project : BitOperation
# File : bit_helper.go
*/
package commonutil
// BitHelper 底层通用位运算工具,基础设施原子能力
type BitHelper struct{}
// AddMask 或运算添加标记
func (bh *BitHelper) AddMask(source, mask int) int {
return source | mask
}
// RemoveMask 清除指定标记
func (bh *BitHelper) RemoveMask(source, mask int) int {
return source & (^mask)
}
// HasMask 判断是否包含完整掩码
func (bh *BitHelper) HasMask(source, mask int) bool {
return (source & mask) == mask
}
// HasAnyMask 包含任意一个掩码
func (bh *BitHelper) HasAnyMask(source int, maskList []int) bool {
unionMask := 0
for _, m := range maskList {
unionMask |= m
}
return (source & unionMask) > 0
}
/*
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author : geovindu,Geovin Du 涂聚文.
# IDE : goLang 2024.3.6 go 26.2
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/8/4 23:07
# User : geovindu
# Product : GoLand
# Project : BitOperation
# File : base_storage.go
*/
package storage
// BaseStorage 仓储顶层抽象接口,依赖倒置
type BaseStorage interface {
Save(key interface{}, value interface{})
Get(key interface{}) interface{}
BatchSave(dataMap map[interface{}]interface{})
BatchExistCheck(keys []interface{}) []bool
}
/*
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author : geovindu,Geovin Du 涂聚文.
# IDE : goLang 2024.3.6 go 26.2
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/8/4 23:07
# User : geovindu
# Product : GoLand
# Project : BitOperation
# File : memory_storage.go
*/
package storage
// MemoryStorage 内存存储实现
type MemoryStorage struct {
dataMap map[interface{}]interface{}
}
func NewMemoryStorage() *MemoryStorage {
return &MemoryStorage{
dataMap: make(map[interface{}]interface{}),
}
}
func (m *MemoryStorage) Save(key interface{}, value interface{}) {
m.dataMap[key] = value
}
func (m *MemoryStorage) Get(key interface{}) interface{} {
return m.dataMap[key]
}
func (m *MemoryStorage) BatchSave(dataMap map[interface{}]interface{}) {
for k, v := range dataMap {
m.dataMap[k] = v
}
}
func (m *MemoryStorage) BatchExistCheck(keys []interface{}) []bool {
res := make([]bool, len(keys))
for i, k := range keys {
_, ok := m.dataMap[k]
res[i] = ok
}
return res
}
Go
/*
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author : geovindu,Geovin Du 涂聚文.
# IDE : goLang 2024.3.6 go 26.2
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/8/4 23:20
# User : geovindu
# Product : GoLand
# Project : BitOperation
# File : combine_api.go
*/
package api
import (
"BitOperation/application"
"BitOperation/domain/entity"
)
var combineService = application.NewJewelryCombineAppService()
func ApiGetJewelryCombine(list []*entity.Jewelry, maxW, maxP float64) application.CombineResult {
return combineService.GetBestCombine(list, maxW, maxP)
}
/*
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author : geovindu,Geovin Du 涂聚文.
# IDE : goLang 2024.3.6 go 26.2
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/8/4 23:21
# User : geovindu
# Product : GoLand
# Project : BitOperation
# File : inventory_filter_api.go
*/
package api
import "BitOperation/application"
func ApiCreateFilterService(maxSize int) *application.InventoryFilterAppService {
return application.NewInventoryFilterAppService(maxSize)
}
/*
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author : geovindu,Geovin Du 涂聚文.
# IDE : goLang 2024.3.6 go 26.2
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/8/4 23:20
# User : geovindu
# Product : GoLand
# Project : BitOperation
# File : match_api.go
*/
package api
import (
"BitOperation/application"
"BitOperation/domain/entity"
)
var matchService = application.NewGuideCustomerMatchAppService()
func ApiMatchGuideCustomer(guides []*entity.Guide, customers []*entity.Customer) application.MatchResult {
return matchService.DoMatch(guides, customers)
}
/*
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author : geovindu,Geovin Du 涂聚文.
# IDE : goLang 2024.3.6 go 26.2
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/8/4 23:18
# User : geovindu
# Product : GoLand
# Project : BitOperation
# File : combine_app_service.go
*/
package application
import (
"BitOperation/domain/algorithm"
"BitOperation/domain/domain_rule"
"BitOperation/domain/entity"
)
type CombineResult struct {
Code int `json:"code"`
Msg string `json:"msg"`
FilterError []string `json:"filter_error"`
SelectIds []string `json:"select_jewel_ids"`
TotalWeight float64 `json:"total_weight"`
TotalPrice float64 `json:"total_price"`
}
type JewelryCombineAppService struct {
rule *domain_rule.CombineDomainRule
}
func NewJewelryCombineAppService() *JewelryCombineAppService {
return &JewelryCombineAppService{
rule: domain_rule.NewCombineDomainRule(),
}
}
func (j *JewelryCombineAppService) GetBestCombine(jewelList []*entity.Jewelry, maxW, maxP float64) CombineResult {
validList, errLog := j.rule.BatchFilterAvailableJewels(jewelList)
if len(validList) == 0 {
return CombineResult{
Code: -1,
Msg: "无合法首饰可搭配",
FilterError: errLog,
SelectIds: []string{},
}
}
combiner := algorithm.NewBfsJewelryCombiner(validList, maxW, maxP)
ids, w, p := combiner.SearchBestCombine()
// 组装掩码
combineMask := 0
var selectObjs []*entity.Jewelry
idMap := make(map[string]*entity.Jewelry)
for _, obj := range validList {
idMap[obj.JewelID] = obj
}
for _, id := range ids {
obj := idMap[id]
combineMask |= obj.Mask
selectObjs = append(selectObjs, obj)
}
ok, msg := j.rule.FullCombineCheck(combineMask, selectObjs, w, p, maxW, maxP)
code := 0
if !ok {
code = -2
}
return CombineResult{
Code: code,
Msg: msg,
FilterError: errLog,
SelectIds: ids,
TotalWeight: w,
TotalPrice: p,
}
}
/*
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author : geovindu,Geovin Du 涂聚文.
# IDE : goLang 2024.3.6 go 26.2
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/8/4 23:18
# User : geovindu
# Product : GoLand
# Project : BitOperation
# File : inventory_app_service.go
*/
package application
import (
"BitOperation/domain/algorithm"
"BitOperation/domain/entity"
)
type InventoryFilterAppService struct {
bitArr *algorithm.BitArray
blackList *entity.BlackList
idIndexMap map[string]int
indexIdMap map[int]string
}
func NewInventoryFilterAppService(maxSize int) *InventoryFilterAppService {
return &InventoryFilterAppService{
bitArr: algorithm.NewBitArray(maxSize),
blackList: entity.NewBlackList(),
idIndexMap: make(map[string]int),
indexIdMap: make(map[int]string),
}
}
func (i *InventoryFilterAppService) RegisterIndex(jid string, idx int) {
i.idIndexMap[jid] = idx
i.indexIdMap[idx] = jid
}
func (i *InventoryFilterAppService) BatchMarkInventory(idList []string) {
var idxList []int
for _, id := range idList {
if idx, ok := i.idIndexMap[id]; ok {
idxList = append(idxList, idx)
}
}
i.bitArr.BatchSet(idxList)
}
func (i *InventoryFilterAppService) CheckRepeat(checkIds []string) [][2]interface{} {
res := make([][2]interface{}, 0, len(checkIds))
for _, id := range checkIds {
idx, ok := i.idIndexMap[id]
exist := false
if ok {
exist = i.bitArr.Get(idx)
}
res = append(res, [2]interface{}{id, exist})
}
return res
}
func (i *InventoryFilterAppService) FilterBlackList(checkIds []string) []string {
var safe []string
for _, id := range checkIds {
if !i.blackList.IsFake(id) {
safe = append(safe, id)
}
}
return safe
}
// MarkBlack 将指定商品ID加入假货黑名单
func (i *InventoryFilterAppService) MarkBlack(id string) {
i.blackList.AddFake(id)
}
/*
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author : geovindu,Geovin Du 涂聚文.
# IDE : goLang 2024.3.6 go 26.2
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/8/4 23:16
# User : geovindu
# Product : GoLand
# Project : BitOperation
# File : match_app_service.go
*/
package application
import (
"BitOperation/domain/algorithm"
"BitOperation/domain/domain_rule"
"BitOperation/domain/entity"
)
type MatchResult struct {
Code int `json:"code"`
Msg string `json:"msg"`
ErrorLog []string `json:"error_log"`
MatchData map[string]string `json:"match_data"`
}
// GuideCustomerMatchAppService 导购客户匹配应用服务
type GuideCustomerMatchAppService struct {
rule *domain_rule.MatchDomainRule
}
func NewGuideCustomerMatchAppService() *GuideCustomerMatchAppService {
return &GuideCustomerMatchAppService{
rule: domain_rule.NewMatchDomainRule(),
}
}
func (g *GuideCustomerMatchAppService) DoMatch(guides []*entity.Guide, customers []*entity.Customer) MatchResult {
validG, validC, errLog := g.rule.BatchCheckMatchEntrance(guides, customers)
if len(validG) == 0 || len(validC) == 0 {
return MatchResult{
Code: -1,
Msg: "无合法导购/客户,匹配终止",
ErrorLog: errLog,
MatchData: make(map[string]string),
}
}
matcher := algorithm.NewGaleShapleyMatcher(validG, validC)
data := matcher.Match()
return MatchResult{
Code: 0,
Msg: "匹配成功",
ErrorLog: errLog,
MatchData: data,
}
}
调用:
Go
/*
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Bit Operation Algorithm
# Author : geovindu,Geovin Du 涂聚文.
# IDE : goLang 2024.3.6 go 26.2
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/8/4 23:06
# User : geovindu
# Product : GoLand
# Project : BitOperation
# File : main.go
*/
package main
import (
"BitOperation/api"
"BitOperation/domain/domain_rule"
"BitOperation/domain/entity"
"BitOperation/domain/valueobject"
"fmt"
)
//TIP <p>To run your code, right-click the code and select <b>Run</b>.</p> <p>Alternatively, click
// the <icon src="AllIcons.Actions.Execute"/> icon in the gutter and select the <b>Run</b> menu item from here.</p>
func main() {
mask := valueobject.NewPreferenceBitMask()
fmt.Println("===导购客户稳定匹配结果(带规则校验)===")
// 构造离岗导购、资深导购
g1 := &entity.Guide{
GuideID: "G001",
SkillMask: mask.DIAMOND | mask.GOLD | domain_rule.GUIDE_OFFLINE_MASK,
CustomerPriority: []string{"C001", "C002"},
}
g2 := &entity.Guide{
GuideID: "G002",
SkillMask: mask.JADE | mask.PEARL | domain_rule.SENIOR_GUIDE_TAG,
CustomerPriority: []string{"C002", "C001"},
}
c1 := &entity.Customer{
CustomerID: "C001",
PreferenceMask: mask.DIAMOND | mask.HIGHPRICE,
PriorityList: []string{"G001", "G002"},
}
c2 := &entity.Customer{
CustomerID: "C002",
PreferenceMask: mask.JADE,
PriorityList: []string{"G002", "G001"},
}
matchRes := api.ApiMatchGuideCustomer([]*entity.Guide{g1, g2}, []*entity.Customer{c1, c2})
fmt.Printf("code:%d, msg:%s\n", matchRes.Code, matchRes.Msg)
fmt.Println("errorLog:", matchRes.ErrorLog)
fmt.Println("match_data:", matchRes.MatchData)
fmt.Println("\n===首饰最优搭配(互斥规则校验)===")
jewels := []*entity.Jewelry{
{JewelID: "J001", Mask: mask.GOLD, Weight: 2.2, Price: 1280},
{JewelID: "J002", Mask: mask.PLATINUM, Weight: 1.5, Price: 2680},
{JewelID: "J003", Mask: mask.PEARL, Weight: 1.1, Price: 890},
{JewelID: "J004", Mask: mask.KGOLD, Weight: 2.8, Price: 1660},
}
comRes := api.ApiGetJewelryCombine(jewels, 5.0, 4000)
fmt.Printf("code:%d, msg:%s\n", comRes.Code, comRes.Msg)
fmt.Println("select_jewel_ids:", comRes.SelectIds)
fmt.Printf("total_weight:%.2f, total_price:%.2f\n", comRes.TotalWeight, comRes.TotalPrice)
fmt.Println("\n===库存查重、黑名单过滤===")
filter := api.ApiCreateFilterService(10000000)
filter.RegisterIndex("J001", 1)
filter.RegisterIndex("J002", 2)
filter.BatchMarkInventory([]string{"J001", "J002"})
repeat := filter.CheckRepeat([]string{"J001", "J005"})
fmt.Println("查重结果:", repeat)
filter.MarkBlack("J999")
safe := filter.FilterBlackList([]string{"J001", "J999"})
fmt.Println("合法商品列表:", safe)
}
输出:
