设计一个系统,提供不同的资源访问权限给免费用户和 VIP 用户,这里将分别介绍下整体设计思路和数据库设计,并用 GORM 的方式说明。

整体设计思路

  1. 用户注册和登录模块。
  2. 资源模块,可以是文件、视频、API 调用等。
  3. 订阅模块,有免费和 VIP 两种订阅。
  4. 权限控制模块,根据用户订阅类型控制资源访问权限。

数据库设计

我们需要设计几个主要的数据表:

  • users 表(用户表)
  • subscriptions 表(订阅表)
  • resources 表(资源表)
  • user_resources 表(用户资源表,用于跟踪免费用户使用资源)

users 表

1
2
3
4
5
6
7
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    username VARCHAR(255) UNIQUE NOT NULL,
    password VARCHAR(255) NOT NULL,
    subscription_id INT REFERENCES subscriptions(id),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

subscriptions 表

1
2
3
4
5
CREATE TABLE subscriptions (
    id SERIAL PRIMARY KEY,
    name VARCHAR(50) NOT NULL,   -- 'free' 或者 'vip'
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

resources 表

1
2
3
4
5
6
CREATE TABLE resources (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    resource_type VARCHAR(50) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

user_resources 表

1
2
3
4
5
6
CREATE TABLE user_resources (
    id SERIAL PRIMARY KEY,
    user_id INT REFERENCES users(id),
    resource_id INT REFERENCES resources(id),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

GORM 实现

下面是如何使用 GORM 来实现这些表结构的定义,并编写相关的权限控制逻辑。

首先,定义模型:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package main

import (
    "time"
    "gorm.io/driver/postgres"
    "gorm.io/gorm"
)

type User struct {
    ID             uint `gorm:"primaryKey"`
    Username       string
    Password       string
    SubscriptionID uint
    Subscription   Subscription
    CreatedAt      time.Time
}

type Subscription struct {
    ID        uint `gorm:"primaryKey"`
    Name      string
    CreatedAt time.Time
}

type Resource struct {
    ID            uint `gorm:"primaryKey"`
    Name          string
    ResourceType  string
    CreatedAt     time.Time
}

type UserResource struct {
    ID        uint `gorm:"primaryKey"`
    UserID    uint
    ResourceID uint
    CreatedAt time.Time
}

初始化数据库连接并迁移表结构:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
func main() {
    dsn := "host=localhost user=gorm dbname=gorm password=gorm sslmode=disable"
    db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
    if err != nil {
        panic("failed to connect database")
    }

    // 自动迁移表结构
    db.AutoMigrate(&User{}, &Subscription{}, &Resource{}, &UserResource{})

    // 添加示例数据
    freeSub := Subscription{Name: "free"}
    vipSub := Subscription{Name: "vip"}

    db.Create(&freeSub)
    db.Create(&vipSub)

    user := User{Username: "test_user", Password: "password", SubscriptionID: freeSub.ID}
    db.Create(&user)

    resource := Resource{Name: "sample_resource", ResourceType: "file"}
    db.Create(&resource)
}

权限控制逻辑示例(伪代码):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
func CanAccessResource(user User, resource Resource) bool {
    var userResource UserResource
    db.First(&userResource, "user_id = ? AND resource_id = ?", user.ID, resource.ID)

    if user.Subscription.Name == "vip" {
        return true
    } else if user.Subscription.Name == "free" && userResource.ID == 0 {
        // 免费用户且未使用过该资源
        newUserResource := UserResource{UserID: user.ID, ResourceID: resource.ID}
        db.Create(&newUserResource)
        return true
    }

    return false // 免费用户已经使用过该资源
}

此逻辑假设当免费用户第一次访问某个资源时,会在 user_resources 表中记录此访问。免费用户只能访问一次,VIP 用户则可以无限访问。