045_add_announcements.sql 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. -- 创建公告表
  2. CREATE TABLE IF NOT EXISTS announcements (
  3. id BIGSERIAL PRIMARY KEY,
  4. title VARCHAR(200) NOT NULL,
  5. content TEXT NOT NULL,
  6. status VARCHAR(20) NOT NULL DEFAULT 'draft',
  7. targeting JSONB NOT NULL DEFAULT '{}'::jsonb,
  8. starts_at TIMESTAMPTZ DEFAULT NULL,
  9. ends_at TIMESTAMPTZ DEFAULT NULL,
  10. created_by BIGINT DEFAULT NULL REFERENCES users(id) ON DELETE SET NULL,
  11. updated_by BIGINT DEFAULT NULL REFERENCES users(id) ON DELETE SET NULL,
  12. created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  13. updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
  14. );
  15. -- 公告已读表
  16. CREATE TABLE IF NOT EXISTS announcement_reads (
  17. id BIGSERIAL PRIMARY KEY,
  18. announcement_id BIGINT NOT NULL REFERENCES announcements(id) ON DELETE CASCADE,
  19. user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
  20. read_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  21. created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  22. UNIQUE(announcement_id, user_id)
  23. );
  24. -- 索引
  25. CREATE INDEX IF NOT EXISTS idx_announcements_status ON announcements(status);
  26. CREATE INDEX IF NOT EXISTS idx_announcements_starts_at ON announcements(starts_at);
  27. CREATE INDEX IF NOT EXISTS idx_announcements_ends_at ON announcements(ends_at);
  28. CREATE INDEX IF NOT EXISTS idx_announcements_created_at ON announcements(created_at);
  29. CREATE INDEX IF NOT EXISTS idx_announcement_reads_announcement_id ON announcement_reads(announcement_id);
  30. CREATE INDEX IF NOT EXISTS idx_announcement_reads_user_id ON announcement_reads(user_id);
  31. CREATE INDEX IF NOT EXISTS idx_announcement_reads_read_at ON announcement_reads(read_at);
  32. COMMENT ON TABLE announcements IS '系统公告';
  33. COMMENT ON COLUMN announcements.status IS '状态: draft, active, archived';
  34. COMMENT ON COLUMN announcements.targeting IS '展示条件(JSON 规则)';
  35. COMMENT ON COLUMN announcements.starts_at IS '开始展示时间(为空表示立即生效)';
  36. COMMENT ON COLUMN announcements.ends_at IS '结束展示时间(为空表示永久生效)';
  37. COMMENT ON TABLE announcement_reads IS '公告已读记录';
  38. COMMENT ON COLUMN announcement_reads.read_at IS '用户首次已读时间';