Skip to content

Commit 93f0bd6

Browse files
authored
feat: add global config option enable user usage count limit function (#458)
Signed-off-by: BobDu <i@bobdu.cc>
1 parent 69ffebc commit 93f0bd6

File tree

11 files changed

+53
-40
lines changed

11 files changed

+53
-40
lines changed

service/src/index.ts

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,8 @@ router.post('/chat-process', [auth, limiter], async (req, res) => {
372372
res.setHeader('Content-type', 'application/octet-stream')
373373

374374
let { roomId, uuid, regenerate, prompt, options = {}, systemMessage, temperature, top_p } = req.body as RequestProps
375-
const userId = req.headers.userId as string
375+
const userId = req.headers.userId.toString()
376+
const config = await getCacheConfig()
376377
const room = await getChatRoom(userId, roomId)
377378
if (room == null)
378379
globalThis.console.error(`Unable to get chat room \t ${userId}\t ${roomId}`)
@@ -383,19 +384,19 @@ router.post('/chat-process', [auth, limiter], async (req, res) => {
383384
let message: ChatInfo
384385
let user = await getUserById(userId)
385386
try {
386-
const config = await getCacheConfig()
387-
const userId = req.headers.userId.toString()
388-
// 在调用前判断对话额度是否够用
389-
const useAmount = user ? (user.useAmount ?? 0) : 0
390-
391-
// if use the fixed fakeuserid(some probability of duplicated with real ones), redefine user which is send to chatReplyProcess
392-
if (userId === '6406d8c50aedd633885fa16f')
387+
// If use the fixed fakeuserid(some probability of duplicated with real ones), redefine user which is send to chatReplyProcess
388+
if (userId === '6406d8c50aedd633885fa16f') {
393389
user = { _id: userId, roles: [UserRole.User], useAmount: 999, advanced: { maxContextCount: 999 }, limit_switch: false } as UserInfo
394-
395-
// report if useamount is 0, 6406d8c50aedd633885fa16f is the fakeuserid in nologin situation
396-
if (userId !== '6406d8c50aedd633885fa16f' && Number(useAmount) <= 0 && user.limit_switch) {
397-
res.send({ status: 'Fail', message: '提问次数用完啦 | Question limit reached', data: null })
398-
return
390+
}
391+
else {
392+
// If global usage count limit is enabled, check can use amount before process chat.
393+
if (config.siteConfig?.usageCountLimit) {
394+
const useAmount = user ? (user.useAmount ?? 0) : 0
395+
if (Number(useAmount) <= 0 && user.limit_switch) {
396+
res.send({ status: 'Fail', message: '提问次数用完啦 | Question limit reached', data: null })
397+
return
398+
}
399+
}
399400
}
400401

401402
if (config.auditConfig.enabled || config.auditConfig.customizeEnabled) {
@@ -496,8 +497,10 @@ router.post('/chat-process', [auth, limiter], async (req, res) => {
496497
}
497498
// update personal useAmount moved here
498499
// if not fakeuserid, and has valid user info and valid useAmount set by admin nut null and limit is enabled
499-
if (userId !== '6406d8c50aedd633885fa16f' && user && user.useAmount && user.limit_switch)
500-
await updateAmountMinusOne(userId)
500+
if (config.siteConfig?.usageCountLimit) {
501+
if (userId !== '6406d8c50aedd633885fa16f' && user && user.useAmount && user.limit_switch)
502+
await updateAmountMinusOne(userId)
503+
}
501504
}
502505
catch (error) {
503506
globalThis.console.error(error)
@@ -683,6 +686,7 @@ router.post('/session', async (req, res) => {
683686
title: config.siteConfig.siteTitle,
684687
chatModels,
685688
allChatModels: chatModelOptions,
689+
usageCountLimit: config.siteConfig?.usageCountLimit,
686690
userInfo,
687691
},
688692
})
@@ -830,10 +834,11 @@ router.get('/user-getamtinfo', auth, async (req, res) => {
830834
try {
831835
const userId = req.headers.userId as string
832836
const user = await getUserById(userId)
833-
if (user.limit_switch)
834-
res.send({ status: 'Success', message: null, data: user.useAmount })
835-
else
836-
res.send({ status: 'Success', message: null, data: 99999 })
837+
const data = {
838+
amount: user.useAmount,
839+
limit: user.limit_switch,
840+
}
841+
res.send({ status: 'Success', message: null, data })
837842
}
838843
catch (error) {
839844
console.error(error)

service/src/storage/model.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ export class SiteConfig {
197197
public registerMails?: string,
198198
public siteDomain?: string,
199199
public chatModels?: string,
200+
public usageCountLimit?: boolean,
200201
) { }
201202
}
202203

src/components/common/Setting/General.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script lang="ts" setup>
22
import { computed, onMounted, ref } from 'vue'
3-
import { NButton, NDivider, NInput, NInputNumber, NPopconfirm, NSelect, useMessage } from 'naive-ui'
3+
import { NButton, NDivider, NInput, NPopconfirm, NSelect, useMessage } from 'naive-ui'
44
import { UserConfig } from '@/components/common/Setting/model'
55
import type { Language, Theme } from '@/store/modules/app/helper'
66
import { SvgIcon } from '@/components/common'
@@ -172,13 +172,13 @@ function handleImportButtonClick(): void {
172172
<NInput v-model:value="description" placeholder="" />
173173
</div>
174174
</div>
175-
<div class="flex items-center space-x-4">
175+
<div v-if="authStore.session?.usageCountLimit && userStore.userInfo.limit" class="flex items-center space-x-4">
176176
<span class="flex-shrink-0 w-[100px]">{{ $t('setting.useAmount') }}</span>
177177
<div class="flex-1">
178-
<NInputNumber v-model:value="useAmount" placeholder="" readonly />
178+
<div v-text="useAmount" />
179179
</div>
180180
</div>
181-
<div class="flex items-center space-x-4">
181+
<div v-if="authStore.session?.usageCountLimit && userStore.userInfo.limit" class="flex items-center space-x-4">
182182
<span class="flex-shrink-0 w-[100px]">{{ $t('setting.redeemCardNo') }}</span>
183183
<div class="flex-1">
184184
<NInput v-model:value="redeemCardNo" placeholder="" />

src/components/common/Setting/Site.vue

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,16 @@ onMounted(() => {
129129
/>
130130
</div>
131131
</div>
132+
<div class="flex items-center space-x-4">
133+
<span class="flex-shrink-0 w-[100px]">{{ $t('setting.usageCountLimit') }}</span>
134+
<div class="flex-1">
135+
<NSwitch
136+
:round="false"
137+
:value="config && config.usageCountLimit"
138+
@update:value="(val) => { if (config) config.usageCountLimit = val }"
139+
/>
140+
</div>
141+
</div>
132142
<div class="flex items-center space-x-4">
133143
<span class="flex-shrink-0 w-[100px]" />
134144
<NButton :loading="saving" type="primary" @click="updateSiteInfo(config)">

src/components/common/Setting/User.vue

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -85,36 +85,26 @@ const createColumns = (): DataTableColumns => {
8585
minWidth: 80,
8686
maxWidth: 200,
8787
},
88-
// 新增额度信息
89-
{
90-
title: 'Amts',
91-
key: 'useAmount',
92-
resizable: true,
93-
width: 80,
94-
minWidth: 30,
95-
maxWidth: 100,
96-
},
9788
// switch off amt limit
9889
{
99-
title: 'limit switch',
90+
title: 'Limit Enabled',
10091
key: 'limit_switch',
10192
resizable: true,
10293
width: 100,
10394
minWidth: 30,
10495
maxWidth: 100,
10596
render(row: any) {
106-
return h(NSwitch, {
107-
defaultValue: row.limit_switch,
108-
round: false,
109-
disabled: true,
110-
})
97+
return h('div', row.limit_switch ? 'True' : 'False')
11198
},
11299
},
113100
// 新增额度信息
114101
{
115-
title: 'Amts',
102+
title: 'Amounts',
116103
key: 'useAmount',
104+
resizable: true,
117105
width: 80,
106+
minWidth: 30,
107+
maxWidth: 100,
118108
},
119109
{
120110
title: 'Action',

src/components/common/Setting/model.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export class SiteConfig {
2929
registerMails?: string
3030
siteDomain?: string
3131
chatModels?: string
32+
usageCountLimit?: boolean
3233
}
3334

3435
export class MailConfig {

src/locales/en-US.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ export default {
8181
},
8282
setting: {
8383
limit_switch: 'Open Usage Limitation',
84+
usageCountLimit: 'Enable Usage Count Limit',
8485
redeemCardNo: 'Redeem CardNo',
8586
useAmount: 'No. of questions',
8687
setting: 'Setting',

src/locales/zh-CN.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ export default {
8181
},
8282
setting: {
8383
limit_switch: '打开次数限制',
84+
usageCountLimit: '使用次数限制',
8485
redeemCardNo: '兑换码卡号',
8586
useAmount: '可提问次数',
8687
setting: '设置',

src/store/modules/auth/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ interface SessionResponse {
2121
key: string
2222
value: string
2323
}[]
24+
usageCountLimit: boolean
2425
userInfo: { name: string; description: string; avatar: string; userId: string; root: boolean; config: UserConfig }
2526
}
2627

src/store/modules/user/helper.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export interface UserInfo {
1212
config: UserConfig
1313
roles: UserRole[]
1414
advanced: SettingsState
15+
limit?: boolean
1516
useAmount?: number // chat usage amount
1617
redeemCardNo?: string // add giftcard info
1718
}

src/store/modules/user/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ export const useUserStore = defineStore('user-store', {
2222
},
2323
// 对应页面加载时的读取,为空送10个
2424
async readUserAmt() {
25-
this.userInfo.useAmount = (await (fetchUserAmt())).data ?? 10
25+
const data = (await fetchUserAmt()).data
26+
this.userInfo.limit = data?.limit
27+
this.userInfo.useAmount = data?.amount ?? 10
2628
},
2729

2830
async resetSetting() {

0 commit comments

Comments
 (0)