subscription.ts 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  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_UNWATCH = 'UNWATCH';
  8. const STATUSES = [STATUS_WATCH, STATUS_UNWATCH];
  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. isUnwatching(): 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. getUnwatchers(target: Types.ObjectId): Promise<Types.ObjectId[]>
  25. STATUS_WATCH(): string
  26. STATUS_UNWATCH(): string
  27. }
  28. const subscriptionSchema = new Schema<SubscriptionDocument, SubscriptionModel>({
  29. user: {
  30. type: Schema.Types.ObjectId,
  31. ref: 'User',
  32. index: true,
  33. required: true,
  34. },
  35. targetModel: {
  36. type: String,
  37. require: true,
  38. enum: ActivityDefine.getSupportTargetModelNames(),
  39. },
  40. target: {
  41. type: Schema.Types.ObjectId,
  42. refPath: 'targetModel',
  43. require: true,
  44. },
  45. status: {
  46. type: String,
  47. require: true,
  48. enum: STATUSES,
  49. },
  50. createdAt: { type: Date, default: Date.now },
  51. });
  52. subscriptionSchema.methods.isWatching = function() {
  53. return this.status === STATUS_WATCH;
  54. };
  55. subscriptionSchema.methods.isUnwatching = function() {
  56. return this.status === STATUS_UNWATCH;
  57. };
  58. subscriptionSchema.statics.findByUserIdAndTargetId = function(userId, targetId) {
  59. return this.findOne({ user: userId, target: targetId });
  60. };
  61. subscriptionSchema.statics.upsertWatcher = function(user, targetModel, target, status) {
  62. const query = { user, targetModel, target };
  63. const doc = { ...query, status };
  64. const options = {
  65. upsert: true, new: true, setDefaultsOnInsert: true, runValidators: true,
  66. };
  67. return this.findOneAndUpdate(query, doc, options);
  68. };
  69. subscriptionSchema.statics.watchByPageId = function(user, pageId, status) {
  70. return this.upsertWatcher(user, 'Page', pageId, status);
  71. };
  72. subscriptionSchema.statics.getWatchers = async function(target) {
  73. return this.find({ target, status: STATUS_WATCH }).distinct('user');
  74. };
  75. subscriptionSchema.statics.getUnwatchers = async function(target) {
  76. return this.find({ target, status: STATUS_UNWATCH }).distinct('user');
  77. };
  78. subscriptionSchema.statics.STATUS_WATCH = function() {
  79. return STATUS_WATCH;
  80. };
  81. subscriptionSchema.statics.STATUS_UNWATCH = function() {
  82. return STATUS_UNWATCH;
  83. };
  84. export default getOrCreateModel<SubscriptionDocument, SubscriptionModel>('Subscription', subscriptionSchema);