subscription.ts 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import {
  2. Types, Document, Model, Schema,
  3. } from 'mongoose';
  4. import ActivityDefine from '../util/activityDefine';
  5. import { getOrCreateModel } from '../util/mongoose-utils';
  6. const STATUS_WATCH = 'WATCH';
  7. const STATUS_IGNORE = 'IGNORE';
  8. const STATUSES = [STATUS_WATCH, STATUS_IGNORE];
  9. export interface ISubscription {
  10. user: Types.ObjectId
  11. targetModel: string
  12. target: Types.ObjectId
  13. status: string
  14. createdAt: Date
  15. isWatching(): boolean
  16. isIgnoring(): boolean
  17. }
  18. export interface SubscriptionDocument extends ISubscription, Document {}
  19. export interface SubscriptionModel extends Model<SubscriptionDocument> {
  20. findByUserIdAndTargetId(userId: Types.ObjectId, targetId: Types.ObjectId): any
  21. upsertWatcher(user: Types.ObjectId, targetModel: string, target: Types.ObjectId, status: string): any
  22. watchByPageId(user: Types.ObjectId, pageId: Types.ObjectId, status: string): any
  23. getWatchers(target: Types.ObjectId): Promise<Types.ObjectId[]>
  24. getIgnorers(target: Types.ObjectId): Promise<Types.ObjectId[]>
  25. }
  26. const subscriptionSchema = new Schema<SubscriptionDocument, SubscriptionModel>({
  27. user: {
  28. type: Schema.Types.ObjectId,
  29. ref: 'User',
  30. index: true,
  31. required: true,
  32. },
  33. targetModel: {
  34. type: String,
  35. require: true,
  36. enum: ActivityDefine.getSupportTargetModelNames(),
  37. },
  38. target: {
  39. type: Schema.Types.ObjectId,
  40. refPath: 'targetModel',
  41. require: true,
  42. },
  43. status: {
  44. type: String,
  45. require: true,
  46. enum: STATUSES,
  47. },
  48. createdAt: { type: Date, default: Date.now },
  49. });
  50. subscriptionSchema.methods.isWatching = function() {
  51. return this.status === STATUS_WATCH;
  52. };
  53. subscriptionSchema.methods.isIgnoring = function() {
  54. return this.status === STATUS_IGNORE;
  55. };
  56. subscriptionSchema.statics.findByUserIdAndTargetId = function(userId, targetId) {
  57. return this.findOne({ user: userId, target: targetId });
  58. };
  59. subscriptionSchema.statics.upsertWatcher = function(user, targetModel, target, status) {
  60. const query = { user, targetModel, target };
  61. const doc = { ...query, status };
  62. const options = {
  63. upsert: true, new: true, setDefaultsOnInsert: true, runValidators: true,
  64. };
  65. return this.findOneAndUpdate(query, doc, options);
  66. };
  67. subscriptionSchema.statics.watchByPageId = function(user, pageId, status) {
  68. return this.upsertWatcher(user, 'Page', pageId, status);
  69. };
  70. subscriptionSchema.statics.getWatchers = async function(target) {
  71. return this.find({ target, status: STATUS_WATCH }).distinct('user');
  72. };
  73. subscriptionSchema.statics.getIgnorers = async function(target) {
  74. return this.find({ target, status: STATUS_IGNORE }).distinct('user');
  75. };
  76. subscriptionSchema.statics.STATUS_WATCH = function() {
  77. return STATUS_WATCH;
  78. };
  79. subscriptionSchema.statics.STATUS_IGNORE = function() {
  80. return STATUS_IGNORE;
  81. };
  82. export default getOrCreateModel<SubscriptionDocument, SubscriptionModel>('Subscription', subscriptionSchema);