repo.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  1. package repo
  2. import (
  3. "3dshow-supplier/db"
  4. "3dshow-supplier/log"
  5. "context"
  6. "fmt"
  7. "go.mongodb.org/mongo-driver/bson"
  8. "go.mongodb.org/mongo-driver/bson/primitive"
  9. "go.mongodb.org/mongo-driver/mongo"
  10. "go.mongodb.org/mongo-driver/mongo/options"
  11. )
  12. type RepoSession struct {
  13. Ctx context.Context
  14. Client *db.MongoDB
  15. }
  16. const (
  17. CollectionSupply = "supply"
  18. CollectionCollect = "collect"
  19. CollectionProduct = "product"
  20. CollectionAddress = "address"
  21. CollectionOrder = "order"
  22. CollectionShopCart = "shopCart"
  23. )
  24. type Map map[string]interface{}
  25. type PageResult struct {
  26. List []map[string]interface{} `json:"list"`
  27. Total int64 `json:"total"`
  28. Page int64 `json:"page"`
  29. Size int64 `json:"size"`
  30. }
  31. type PageSearchOptions struct {
  32. Db string
  33. CollectName string
  34. Page int64
  35. Size int64
  36. Query map[string]interface{}
  37. Project []string
  38. Sort interface{}
  39. }
  40. type DocSearchOptions struct {
  41. Db string
  42. CollectName string
  43. Query Map
  44. Project []string
  45. Sort bson.M
  46. }
  47. func NewDocSearchOptions(filter Map, project []string) *DocSearchOptions {
  48. return &DocSearchOptions{
  49. Query: filter,
  50. Project: project,
  51. }
  52. }
  53. func RepoAddDoc(ctx *RepoSession, collectName string, doc interface{}) (string, error) {
  54. users := ctx.Client.GetCollection(collectName)
  55. result, err := users.InsertOne(ctx.Ctx, doc)
  56. if err != nil {
  57. return "", err
  58. }
  59. return result.InsertedID.(primitive.ObjectID).Hex(), nil
  60. }
  61. func RepoDbAddDoc(ctx *RepoSession, dbName string, collectName string, doc interface{}) (string, error) {
  62. users := ctx.Client.GetDbCollection(dbName, collectName)
  63. result, err := users.InsertOne(ctx.Ctx, doc)
  64. if err != nil {
  65. return "", err
  66. }
  67. return result.InsertedID.(primitive.ObjectID).Hex(), nil
  68. }
  69. func RepoDeleteDoc(ctx *RepoSession, collectName string, id string) (interface{}, error) {
  70. uid, _ := primitive.ObjectIDFromHex(id)
  71. colls := ctx.Client.GetCollection(collectName)
  72. return colls.DeleteOne(ctx.Ctx, &bson.M{"_id": uid})
  73. }
  74. func RepoDeleteDbDoc(ctx *RepoSession, dbName string, collectName string, id string) (interface{}, error) {
  75. uid, _ := primitive.ObjectIDFromHex(id)
  76. colls := ctx.Client.GetDbCollection(dbName, collectName)
  77. return colls.DeleteOne(ctx.Ctx, &bson.M{"_id": uid})
  78. }
  79. func RepoDeleteDocs(ctx *RepoSession, collectName string, query interface{}) (interface{}, error) {
  80. colls := ctx.Client.GetCollection(collectName)
  81. return colls.DeleteMany(ctx.Ctx, query)
  82. }
  83. func RepoUpdateSetDoc(ctx *RepoSession, collectName string, idstr string, model interface{}) (*mongo.UpdateResult, error) {
  84. colls := ctx.Client.GetCollection(collectName)
  85. update := bson.M{"$set": model}
  86. uid, _ := primitive.ObjectIDFromHex(idstr)
  87. return colls.UpdateByID(ctx.Ctx, uid, update)
  88. }
  89. func RepoUpdateSeDbDoc(ctx *RepoSession, db string, collectName string, idstr string, model interface{}) (*mongo.UpdateResult, error) {
  90. colls := ctx.Client.GetDbCollection(db, collectName)
  91. update := bson.M{"$set": model}
  92. uid, _ := primitive.ObjectIDFromHex(idstr)
  93. return colls.UpdateByID(ctx.Ctx, uid, update)
  94. }
  95. func RepoUpdateSetDocProps(ctx *RepoSession, collectName string, idstr string, update interface{}) (*mongo.UpdateResult, error) {
  96. colls := ctx.Client.GetCollection(collectName)
  97. // update := bson.M{"$set": model}
  98. uid, _ := primitive.ObjectIDFromHex(idstr)
  99. return colls.UpdateByID(ctx.Ctx, uid, update)
  100. }
  101. func RepoUpdateSetDbDocProps(ctx *RepoSession, db string, collectName string, idstr string, update interface{}) (*mongo.UpdateResult, error) {
  102. colls := ctx.Client.GetDbCollection(db, collectName)
  103. // update := bson.M{"$set": model}
  104. uid, _ := primitive.ObjectIDFromHex(idstr)
  105. return colls.UpdateByID(ctx.Ctx, uid, update)
  106. }
  107. func RepoSeachDoc(ctx *RepoSession, param *DocSearchOptions, v interface{}) (bool, error) {
  108. colls := ctx.Client.GetDbCollection(param.Db, param.CollectName)
  109. opt := &options.FindOneOptions{}
  110. if len(param.Project) > 0 {
  111. prj := bson.M{}
  112. for _, v := range param.Project {
  113. prj[v] = 1
  114. }
  115. opt.SetProjection(prj)
  116. }
  117. filter := bson.M{}
  118. if len(param.Query) > 0 {
  119. for k, v := range param.Query {
  120. if k == "_id" {
  121. if uid, ok := v.(string); ok {
  122. docId, _ := primitive.ObjectIDFromHex(uid)
  123. filter["_id"] = docId
  124. continue
  125. }
  126. }
  127. filter[k] = v
  128. }
  129. }
  130. err := colls.FindOne(ctx.Ctx, filter, opt).Decode(v)
  131. if err == mongo.ErrNoDocuments {
  132. return false, nil
  133. }
  134. if err != nil {
  135. return false, err
  136. }
  137. return true, nil
  138. }
  139. func RepoSeachDocMap(ctx *RepoSession, param *DocSearchOptions) (bool, map[string]interface{}) {
  140. ret := map[string]interface{}{}
  141. ok := true
  142. colls := ctx.Client.GetDbCollection(param.Db, param.CollectName)
  143. opt := &options.FindOneOptions{}
  144. if len(param.Project) > 0 {
  145. prj := bson.M{}
  146. for _, v := range param.Project {
  147. prj[v] = 1
  148. }
  149. opt.SetProjection(prj)
  150. }
  151. filter := bson.M{}
  152. if len(param.Query) > 0 {
  153. for k, v := range param.Query {
  154. if k == "_id" {
  155. if uid, ok := v.(string); ok {
  156. docId, _ := primitive.ObjectIDFromHex(uid)
  157. filter["_id"] = docId
  158. continue
  159. }
  160. }
  161. filter[k] = v
  162. }
  163. }
  164. ok = true
  165. err := colls.FindOne(ctx.Ctx, filter, opt).Decode(ret)
  166. if err == mongo.ErrNoDocuments {
  167. ok = false
  168. }
  169. if err != nil {
  170. ok = false
  171. }
  172. return ok, ret
  173. }
  174. // PageSearch 单表分页查询
  175. func RepoPageSearch(ctx *RepoSession, para *PageSearchOptions) (out *PageResult, err error) {
  176. var colls *mongo.Collection
  177. if len(para.Db) > 0 {
  178. colls = ctx.Client.GetDbCollection(para.Db, para.CollectName)
  179. } else {
  180. colls = ctx.Client.GetCollection(para.CollectName)
  181. }
  182. findoptions := &options.FindOptions{}
  183. if para.Size > 0 {
  184. findoptions.SetLimit(para.Size)
  185. findoptions.SetSkip(para.Size * (para.Page - 1))
  186. }
  187. if para.Sort != nil {
  188. findoptions.SetSort(para.Sort)
  189. }
  190. if len(para.Project) > 0 {
  191. prj := bson.M{}
  192. for _, v := range para.Project {
  193. prj[v] = 1
  194. }
  195. findoptions.SetProjection(prj)
  196. }
  197. filter := bson.M{}
  198. if len(para.Query) > 0 {
  199. for k, v := range para.Query {
  200. if value, ok := v.(string); ok {
  201. if len(value) > 0 {
  202. filter[k] = v
  203. continue
  204. }
  205. } else if v != nil {
  206. filter[k] = v
  207. }
  208. }
  209. }
  210. cur, err := colls.Find(ctx.Ctx, filter, findoptions)
  211. out = &PageResult{
  212. List: []map[string]interface{}{},
  213. Total: 0,
  214. Page: para.Page,
  215. Size: para.Size,
  216. }
  217. if err != nil {
  218. return out, err
  219. }
  220. defer cur.Close(ctx.Ctx)
  221. err = cur.All(ctx.Ctx, &out.List)
  222. out.Total, _ = colls.CountDocuments(ctx.Ctx, filter)
  223. return
  224. }
  225. func RepoDbCountDoc(ctx *RepoSession, db string, collectionName string, Query Map) (int64, error) {
  226. colls := ctx.Client.GetDbCollection(db, collectionName)
  227. filter := bson.M{}
  228. if len(Query) > 0 {
  229. for k, v := range Query {
  230. if value, ok := v.(string); ok {
  231. if len(value) > 0 {
  232. filter[k] = v
  233. continue
  234. }
  235. } else {
  236. filter[k] = v
  237. }
  238. }
  239. }
  240. return colls.CountDocuments(ctx.Ctx, filter)
  241. }
  242. func RepoCountDoc(ctx *RepoSession, collectionName string, Query Map) (int64, error) {
  243. colls := ctx.Client.GetCollection(collectionName)
  244. filter := bson.M{}
  245. if len(Query) > 0 {
  246. for k, v := range Query {
  247. if value, ok := v.(string); ok {
  248. if len(value) > 0 {
  249. filter[k] = v
  250. continue
  251. }
  252. } else {
  253. filter[k] = v
  254. }
  255. }
  256. }
  257. return colls.CountDocuments(ctx.Ctx, filter)
  258. }
  259. // PageSearch 单表分页查询
  260. func RepoDocsSearch(ctx *RepoSession, para *PageSearchOptions, out interface{}) (err error) {
  261. colls := ctx.Client.GetCollection(para.CollectName)
  262. if len(para.Db) > 0 {
  263. colls = ctx.Client.GetDbCollection(para.Db, para.CollectName)
  264. }
  265. findoptions := &options.FindOptions{}
  266. if para.Size > 0 {
  267. findoptions.SetLimit(para.Size)
  268. findoptions.SetSkip(para.Size * (para.Page - 1))
  269. }
  270. if para.Sort != nil {
  271. findoptions.SetSort(para.Sort)
  272. }
  273. if len(para.Project) > 0 {
  274. prj := bson.M{}
  275. for _, v := range para.Project {
  276. prj[v] = 1
  277. }
  278. findoptions.SetProjection(prj)
  279. }
  280. filter := bson.M{}
  281. if len(para.Query) > 0 {
  282. for k, v := range para.Query {
  283. if value, ok := v.(string); ok {
  284. if len(value) > 0 {
  285. filter[k] = v
  286. continue
  287. }
  288. } else {
  289. filter[k] = v
  290. }
  291. }
  292. }
  293. cur, err := colls.Find(ctx.Ctx, filter, findoptions)
  294. if err != nil {
  295. return err
  296. }
  297. defer cur.Close(ctx.Ctx)
  298. err = cur.All(ctx.Ctx, out)
  299. return
  300. }
  301. func RepoDocArrayAppend(ctx *RepoSession, collectName string, idstr string, fieldpath string, arrayItem interface{}) (*mongo.UpdateResult, error) {
  302. colls := ctx.Client.GetCollection(collectName)
  303. arrayOp := bson.M{}
  304. arrayOp[fieldpath] = arrayItem
  305. update := bson.M{"$push": arrayOp}
  306. uid, _ := primitive.ObjectIDFromHex(idstr)
  307. return colls.UpdateByID(ctx.Ctx, uid, update)
  308. }
  309. // { _id: 4, "grades.grade": 85 },
  310. // { $set: { "grades.$.std" : 6 } }
  311. type ArrayOneUpdateOption struct {
  312. Query Map
  313. Set Map
  314. CollectName string
  315. Id string
  316. }
  317. // if len(scene.Stickers) > 0 {
  318. // optSet["scenes.$.stickers"] = scene.Stickers
  319. // }
  320. // option := &repo.ArrayOneUpdateOption{
  321. // CollectName: repo.CollectionDesigns,
  322. // Id: id,
  323. // Query: repo.Map{"scenes.id": scene.Id},
  324. // Set: optSet,
  325. // }
  326. func RepoDocArrayOneUpdate(ctx *RepoSession, options *ArrayOneUpdateOption) (*mongo.UpdateResult, error) {
  327. colls := ctx.Client.GetCollection(options.CollectName)
  328. docId, _ := primitive.ObjectIDFromHex(options.Id)
  329. query := bson.M{"_id": docId}
  330. if len(options.Query) > 0 {
  331. for k, v := range options.Query {
  332. query[k] = v
  333. }
  334. }
  335. setOp := bson.M{}
  336. for k, v := range options.Set {
  337. setOp[k] = v
  338. }
  339. update := bson.M{"$set": setOp}
  340. return colls.UpdateOne(ctx.Ctx, query, update)
  341. }
  342. type ArrayOneRemoveOption struct {
  343. ArrayQuery Map
  344. CollectName string
  345. Id string
  346. }
  347. // { $pull: { "items" : { id: 23 } } }
  348. func RepoDocArrayOneRemove(ctx *RepoSession, options *ArrayOneRemoveOption) (*mongo.UpdateResult, error) {
  349. colls := ctx.Client.GetCollection(options.CollectName)
  350. docId, _ := primitive.ObjectIDFromHex(options.Id)
  351. query := bson.M{"_id": docId}
  352. arrayQuery := bson.M{}
  353. if len(options.ArrayQuery) > 0 {
  354. for k, v := range options.ArrayQuery {
  355. arrayQuery[k] = v
  356. }
  357. }
  358. update := bson.M{"$pull": arrayQuery}
  359. return colls.UpdateOne(ctx.Ctx, query, update)
  360. }
  361. type ArrayOneSearchOption struct {
  362. ArrayQuery Map
  363. CollectName string
  364. Id string
  365. Field string
  366. }
  367. func RepoDocArraySearch(ctx *RepoSession, options *ArrayOneSearchOption, entity interface{}) error {
  368. colls := ctx.Client.GetCollection(options.CollectName)
  369. docId, _ := primitive.ObjectIDFromHex(options.Id)
  370. match := []bson.E{}
  371. match = append(match, bson.E{"_id", docId})
  372. matchStage := bson.D{
  373. {"$match", match},
  374. }
  375. unwindStage := bson.D{
  376. {"$unwind", fmt.Sprintf("%s%s", "$", options.Field)},
  377. }
  378. pipe := mongo.Pipeline{matchStage, unwindStage}
  379. if len(options.ArrayQuery) > 0 {
  380. match2 := []bson.E{}
  381. for k, v := range options.ArrayQuery {
  382. match2 = append(match2, bson.E{k, v})
  383. }
  384. match2Stage := bson.D{
  385. {"$match", match2},
  386. }
  387. pipe = append(pipe, match2Stage)
  388. }
  389. curr, err := colls.Aggregate(ctx.Ctx, pipe)
  390. if err != nil {
  391. return err
  392. }
  393. defer curr.Close(ctx.Ctx)
  394. if curr.Next(ctx.Ctx) {
  395. err = curr.Decode(entity)
  396. if err != nil {
  397. return err
  398. }
  399. return nil
  400. }
  401. return nil
  402. }
  403. type DocsSearchOptions struct {
  404. CollectName string
  405. Query map[string]interface{}
  406. Project []string
  407. Sort interface{} //bson.D{ bson.E{"update_time", -1}, bson.E{"goods_id", -1},}
  408. }
  409. func RepoSeachDocsMap(ctx *RepoSession, param *DocsSearchOptions) (ok bool, list []map[string]interface{}) {
  410. colls := ctx.Client.GetCollection(param.CollectName)
  411. findoptions := &options.FindOptions{}
  412. if len(param.Project) > 0 {
  413. prj := bson.M{}
  414. for _, v := range param.Project {
  415. prj[v] = 1
  416. }
  417. findoptions.SetProjection(prj)
  418. }
  419. if param.Sort != nil {
  420. findoptions.SetSort(param.Sort)
  421. }
  422. filter := bson.M{}
  423. if len(param.Query) > 0 {
  424. for k, v := range param.Query {
  425. if value, ok := v.(string); ok {
  426. if len(value) > 0 {
  427. filter[k] = v
  428. continue
  429. }
  430. } else {
  431. filter[k] = v
  432. }
  433. }
  434. }
  435. cur, err := colls.Find(ctx.Ctx, filter, findoptions)
  436. if err != nil {
  437. ok = false
  438. return
  439. }
  440. defer cur.Close(ctx.Ctx)
  441. listRes := []map[string]interface{}{}
  442. err = cur.All(ctx.Ctx, &listRes)
  443. if err != nil {
  444. log.Error(err)
  445. ok = false
  446. return
  447. }
  448. list = listRes
  449. ok = true
  450. return
  451. }
  452. type DbDocsSearchOptions struct {
  453. Db string
  454. CollectName string
  455. Query map[string]interface{}
  456. Project []string
  457. Sort interface{} //bson.D{ bson.E{"update_time", -1}, bson.E{"goods_id", -1},}
  458. }
  459. func DbRepoSeachDocsMap(ctx *RepoSession, param *DbDocsSearchOptions) (ok bool, list []map[string]interface{}) {
  460. colls := ctx.Client.GetDbCollection(param.Db, param.CollectName)
  461. findoptions := &options.FindOptions{}
  462. if len(param.Project) > 0 {
  463. prj := bson.M{}
  464. for _, v := range param.Project {
  465. prj[v] = 1
  466. }
  467. findoptions.SetProjection(prj)
  468. }
  469. if param.Sort != nil {
  470. findoptions.SetSort(param.Sort)
  471. }
  472. filter := bson.M{}
  473. if len(param.Query) > 0 {
  474. for k, v := range param.Query {
  475. if value, ok := v.(string); ok {
  476. if len(value) > 0 {
  477. filter[k] = v
  478. continue
  479. }
  480. } else {
  481. filter[k] = v
  482. }
  483. }
  484. }
  485. cur, err := colls.Find(ctx.Ctx, filter, findoptions)
  486. if err != nil {
  487. ok = false
  488. return
  489. }
  490. defer cur.Close(ctx.Ctx)
  491. listRes := []map[string]interface{}{}
  492. err = cur.All(ctx.Ctx, &listRes)
  493. if err != nil {
  494. log.Error(err)
  495. ok = false
  496. return
  497. }
  498. list = listRes
  499. ok = true
  500. return
  501. }