Skip to content

Commit

Permalink
add enterprise feature
Browse files Browse the repository at this point in the history
  • Loading branch information
zmh-program committed Oct 30, 2023
1 parent 60e096f commit 4845912
Show file tree
Hide file tree
Showing 10 changed files with 99 additions and 32 deletions.
6 changes: 5 additions & 1 deletion app/src/assets/subscription.less
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.sub-dialog {
max-width: min(90vw, 844px) !important;
max-width: min(90vw, 1100px) !important;
}

.sub-wrapper {
Expand Down Expand Up @@ -77,6 +77,10 @@
border-color: hsl(var(--text-secondary));
}

&.enterprise {
border-color: hsl(var(--accent));
}

.title {
text-align: center;
font-size: 16px;
Expand Down
5 changes: 3 additions & 2 deletions app/src/components/home/ModelSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { selectAuthenticated } from "@/store/auth.ts";
import { useToast } from "@/components/ui/use-toast.ts";
import { Model } from "@/conversation/types.ts";
import { modelEvent } from "@/events/model.ts";
import { isSubscribedSelector } from "@/store/subscription.ts";
import {enterpriseSelector, isSubscribedSelector} from "@/store/subscription.ts";
import { teenagerSelector } from "@/store/package.ts";
import { ToastAction } from "@/components/ui/toast.tsx";

Expand All @@ -27,6 +27,7 @@ function ModelSelector(props: ModelSelectorProps) {
const model = useSelector(selectModel);
const auth = useSelector(selectAuthenticated);
const subscription = useSelector(isSubscribedSelector);
const enterprise = useSelector(enterpriseSelector);
const student = useSelector(teenagerSelector);

modelEvent.bind((target: string) => {
Expand Down Expand Up @@ -58,7 +59,7 @@ function ModelSelector(props: ModelSelectorProps) {
return {
name: model.id,
value: model.name,
badge: { variant: "gold", name: "pro" },
badge: { variant: "gold", name: enterprise ? "enterprise" : "pro" },
} as SelectItemProps;
}

Expand Down
2 changes: 1 addition & 1 deletion app/src/conf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
} from "@/utils/env.ts";
import { getMemory } from "@/utils/memory.ts";

export const version = "3.6.2";
export const version = "3.6.3";
export const dev: boolean = getDev();
export const deploy: boolean = true;
export let rest_api: string = getRestApi(deploy);
Expand Down
1 change: 1 addition & 0 deletions app/src/conversation/addition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type SubscriptionResponse = {
status: boolean;
is_subscribed: boolean;
expired: number;
enterprise?: boolean;
usage: {
gpt4: number;
dalle: number;
Expand Down
56 changes: 38 additions & 18 deletions app/src/dialogs/Subscription.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {
dialogSelector,
dialogSelector, enterpriseSelector,
expiredSelector,
isSubscribedSelector,
refreshSubscription,
Expand Down Expand Up @@ -159,6 +159,7 @@ function Subscription() {
const { t } = useTranslation();
const open = useSelector(dialogSelector);
const subscription = useSelector(isSubscribedSelector);
const enterprise = useSelector(enterpriseSelector);
const expired = useSelector(expiredSelector);
const usage = useSelector(usageSelector);
const dispatch = useDispatch();
Expand All @@ -182,22 +183,28 @@ function Subscription() {
<Calendar className={`h-4 w-4 mr-1`} />
{t("sub.expired", { expired })}
</div>
<div className={`sub-column`}>
<Compass className={`h-4 w-4 mr-1`} />
GPT-4
<div className={`grow`} />
<div className={`sub-value`}>
<p>{usage?.gpt4}</p> / <p> 50 </p>
</div>
</div>
<div className={`sub-column`}>
<ImagePlus className={`h-4 w-4 mr-1`} />
DALL-E
<div className={`grow`} />
<div className={`sub-value`}>
<p>{usage?.dalle}</p> / <p> 2000 </p>
</div>
</div>
{
!enterprise && (
<>
<div className={`sub-column`}>
<Compass className={`h-4 w-4 mr-1`} />
GPT-4
<div className={`grow`} />
<div className={`sub-value`}>
<p>{usage?.gpt4}</p> / <p> 50 </p>
</div>
</div>
<div className={`sub-column`}>
<ImagePlus className={`h-4 w-4 mr-1`} />
DALL-E
<div className={`grow`} />
<div className={`sub-value`}>
<p>{usage?.dalle}</p> / <p> 2000 </p>
</div>
</div>
</>
)
}
</div>
)}
<div className={`plan-wrapper`}>
Expand Down Expand Up @@ -257,10 +264,23 @@ function Subscription() {
</div>
<Upgrade>
<Button className={`action`} variant={`default`}>
{subscription ? t("sub.renew") : t("sub.upgrade")}
{
subscription ? (enterprise ? t("sub.cannot-select") : t("sub.renew")) :
t("sub.upgrade")
}
</Button>
</Upgrade>
</div>
<div className={`plan enterprise`}>
<div className={`title`}>{t("sub.enterprise")}</div>
<div className={`price`}>{t("sub.contact-sale")}</div>
<div className={`desc`}>

</div>
<Button className={`action`} variant={`outline`}>
{t('sub.contact-sale')}
</Button>
</div>
</div>
</div>
</DialogDescription>
Expand Down
22 changes: 19 additions & 3 deletions app/src/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,15 @@ const resources = {
"pro-claude": "Claude 100k Free",
"pro-service": "Priority Service Support",
"pro-thread": "Concurrency Increase",
enterprise: "Enterprise",
"contact-sale": "Contact Sales",
current: "Current Plan",
upgrade: "Upgrade",
renew: "Renew",
"cannot-select": "Cannot Select",
"select-time": "Select Subscription Time",
price: "Price {{price}} CNY",
expired: "Your Pro subscription will expire in {{expired}} days",
expired: "Your subscription will expire in {{expired}} days",
time: {
1: "1 Month",
3: "3 Months",
Expand Down Expand Up @@ -218,6 +220,11 @@ const resources = {
contact: {
title: "Contact Us",
},
settings: {
title: "Settings",
context: "Keep Context",
align: "Chatbox Centered",
}
},
},
cn: {
Expand Down Expand Up @@ -328,13 +335,15 @@ const resources = {
"pro-claude": "Claude 100k 免费",
"pro-service": "优先服务支持",
"pro-thread": "并发数提升",
enterprise: "企业版",
"contact-sale": "联系销售",
current: "当前计划",
upgrade: "升级",
renew: "续费",
"cannot-select": "无法选择",
"select-time": "选择订阅时间",
price: "价格 {{price}} 元",
expired: "您的专业版订阅还有 {{expired}} 天到期",
expired: "您的订阅还有 {{expired}} 天到期",
time: {
1: "1个月",
3: "3个月",
Expand Down Expand Up @@ -544,13 +553,15 @@ const resources = {
"pro-claude": "Claude 100k бесплатно",
"pro-service": "Приоритетная служба поддержки",
"pro-thread": "Увеличение параллелизма",
enterprise: "Корпоративный",
"contact-sale": "Связаться с отделом продаж",
current: "Текущая подписка",
upgrade: "Обновить",
renew: "Продлить",
"cannot-select": "Невозможно выбрать",
"select-time": "Выберите время подписки",
price: "Цена {{price}} CNY",
expired: "Ваша подписка Pro истечет через {{expired}} дней",
expired: "Ваша подписка истекает через {{expired}} дней",
time: {
1: "1 месяц",
3: "3 месяца",
Expand Down Expand Up @@ -639,6 +650,11 @@ const resources = {
contact: {
title: "Связаться с нами",
},
settings: {
title: "Настройки",
context: "Сохранить контекст",
align: "Выравнивание чата по центру",
},
},
},
};
Expand Down
5 changes: 4 additions & 1 deletion app/src/store/subscription.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const subscriptionSlice = createSlice({
initialState: {
dialog: false,
is_subscribed: false,
enterprise: false,
expired: 0,
usage: {
gpt4: 0,
Expand All @@ -30,6 +31,7 @@ export const subscriptionSlice = createSlice({
state.is_subscribed = action.payload.is_subscribed;
state.expired = action.payload.expired;
state.usage = action.payload.usage;
state.enterprise = action.payload.enterprise;
},
},
});
Expand All @@ -50,12 +52,13 @@ export const isSubscribedSelector = (state: any): boolean =>
export const expiredSelector = (state: any): number =>
state.subscription.expired;
export const usageSelector = (state: any): any => state.subscription.usage;
export const enterpriseSelector = (state: any): boolean => state.subscription.enterprise;

export const refreshSubscription = async (dispatch: AppDispatch) => {
const current = new Date().getTime(); //@ts-ignore
if (
window.hasOwnProperty("subscription") && //@ts-ignore
current - window.subscription < 2500
current - window.subscription < 15000
)
return; //@ts-ignore
window.subscription = current;
Expand Down
1 change: 1 addition & 0 deletions auth/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ func SubscriptionAPI(c *gin.Context) {
c.JSON(200, gin.H{
"status": true,
"is_subscribed": user.IsSubscribe(db),
"enterprise": user.IsEnterprise(db),
"expired": user.GetSubscriptionExpiredDay(db),
"usage": user.GetSubscriptionUsage(db, cache),
})
Expand Down
32 changes: 26 additions & 6 deletions auth/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ import (
)

type User struct {
ID int64 `json:"id"`
Username string `json:"username"`
BindID int64 `json:"bind_id"`
Password string `json:"password"`
Token string `json:"token"`
ID int64 `json:"id"`
Username string `json:"username"`
BindID int64 `json:"bind_id"`
Password string `json:"password"`
Token string `json:"token"`
Subscription *time.Time `json:"subscription"`
}

type LoginForm struct {
Expand Down Expand Up @@ -148,17 +149,36 @@ func (u *User) UseQuota(db *sql.DB, quota float32) bool {
}

func (u *User) GetSubscription(db *sql.DB) time.Time {
if u.Subscription != nil && u.Subscription.Unix() > 0 {
return *u.Subscription
}

var expiredAt []uint8
if err := db.QueryRow("SELECT expired_at FROM subscription WHERE user_id = ?", u.GetID(db)).Scan(&expiredAt); err != nil {
return time.Unix(0, 0)
}
return *utils.ConvertTime(expiredAt)

u.Subscription = utils.ConvertTime(expiredAt)
return *u.Subscription
}

func (u *User) IsSubscribe(db *sql.DB) bool {
return u.GetSubscription(db).Unix() > time.Now().Unix()
}

func (u *User) IsEnterprise(db *sql.DB) bool {
if !u.IsSubscribe(db) {
return false
}

var enterprise sql.NullBool
if err := db.QueryRow("SELECT enterprise FROM subscription WHERE user_id = ?", u.GetID(db)).Scan(&enterprise); err != nil {
return false
}

return enterprise.Valid && enterprise.Bool
}

func (u *User) GetSubscriptionExpiredDay(db *sql.DB) int {
stamp := u.GetSubscription(db).Sub(time.Now())
return int(math.Round(stamp.Hours() / 24))
Expand Down
1 change: 1 addition & 0 deletions connection/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ func CreateSubscriptionTable(db *sql.DB) {
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
total_month INT DEFAULT 0,
enterprise BOOLEAN DEFAULT FALSE,
FOREIGN KEY (user_id) REFERENCES auth(id)
);
`)
Expand Down

0 comments on commit 4845912

Please sign in to comment.