fix: 订阅模式登录验证、永久会员类型区分、动态代码HTTP返回值修复、侧边栏滚动位置保持
- 修复订阅模式登录时错误检查余额的问题 - 区分无限余额和永久订阅两种永久会员类型 - 修复动态代码HTTP请求返回值在JS中无法正确访问的问题 - 添加侧边栏滚动位置保持功能 - 移除developer角色相关代码,统一使用admin - 添加缺失的i18n翻译key
This commit is contained in:
@@ -22,8 +22,8 @@ export const agentAppSchema = z.object({
|
||||
|
||||
export const agentRequestSchema = z.object({
|
||||
id: z.number(),
|
||||
developer_id: z.number(),
|
||||
developer_name: z.string(),
|
||||
admin_id: z.number(),
|
||||
admin_name: z.string(),
|
||||
agent_id: z.number(),
|
||||
agent_name: z.string(),
|
||||
application_id: z.number(),
|
||||
|
||||
@@ -66,8 +66,8 @@ const allItems = computed<CombinedItem[]>(() => {
|
||||
.filter(item => item.status === 'pending')
|
||||
.map(item => ({
|
||||
id: item.id,
|
||||
agent_id: item.developer_id,
|
||||
agent_name: item.developer_name,
|
||||
agent_id: item.admin_id,
|
||||
agent_name: item.admin_name,
|
||||
application_id: item.application_id,
|
||||
app_name: item.app_name,
|
||||
status: item.status,
|
||||
|
||||
@@ -13,7 +13,7 @@ const saving = ref(false)
|
||||
const applications = ref<Array<{ id: number, name: string }>>([])
|
||||
|
||||
const form = ref({
|
||||
developer_id: '',
|
||||
admin_id: '',
|
||||
application_id: '',
|
||||
message: '',
|
||||
})
|
||||
@@ -35,7 +35,7 @@ async function fetchApplications() {
|
||||
}
|
||||
|
||||
async function handleSubmit() {
|
||||
if (!form.value.developer_id) {
|
||||
if (!form.value.admin_id) {
|
||||
toast.error('请输入管理员ID')
|
||||
return
|
||||
}
|
||||
@@ -54,7 +54,7 @@ async function handleSubmit() {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
developer_id: Number(form.value.developer_id),
|
||||
admin_id: Number(form.value.admin_id),
|
||||
application_id: Number(form.value.application_id),
|
||||
message: form.value.message,
|
||||
}),
|
||||
@@ -109,12 +109,12 @@ onMounted(() => {
|
||||
</UiCardHeader>
|
||||
<UiCardContent class="space-y-6">
|
||||
<div class="space-y-2">
|
||||
<UiLabel for="developer_id">
|
||||
<UiLabel for="admin_id">
|
||||
管理员ID
|
||||
</UiLabel>
|
||||
<UiInput
|
||||
id="developer_id"
|
||||
v-model="form.developer_id"
|
||||
id="admin_id"
|
||||
v-model="form.admin_id"
|
||||
type="number"
|
||||
placeholder="请输入管理员ID"
|
||||
/>
|
||||
|
||||
@@ -211,13 +211,13 @@ onMounted(() => {
|
||||
<UiCardHeader>
|
||||
<UiCardTitle class="flex items-center gap-2">
|
||||
<Icon icon="lucide:credit-card" class="size-5" />
|
||||
{{ t('admin.cardTypes.create.rechargeConfig') || '充值配置' }}
|
||||
{{ t('admin.cardTypes.create.rechargeConfig') }}
|
||||
</UiCardTitle>
|
||||
<UiCardDescription>{{ t('admin.cardTypes.create.rechargeConfigDesc') || '设置卡密的充值类型和金额' }}</UiCardDescription>
|
||||
<UiCardDescription>{{ t('admin.cardTypes.create.rechargeConfigDesc') }}</UiCardDescription>
|
||||
</UiCardHeader>
|
||||
<UiCardContent class="space-y-6">
|
||||
<div class="space-y-2">
|
||||
<UiLabel>{{ t('admin.cardTypes.create.rechargeType') || '充值类型' }}</UiLabel>
|
||||
<UiLabel>{{ t('admin.cardTypes.create.rechargeType') }}</UiLabel>
|
||||
<UiRadioGroup v-model="form.recharge_type" class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div
|
||||
class="flex items-start gap-3 p-4 rounded-lg border cursor-pointer transition-colors"
|
||||
@@ -227,10 +227,10 @@ onMounted(() => {
|
||||
<UiRadioGroupItem value="balance" class="mt-0.5" />
|
||||
<div>
|
||||
<p class="font-medium">
|
||||
{{ t('admin.cardTypes.create.balanceRecharge') || '余额充值' }}
|
||||
{{ t('admin.cardTypes.create.balanceRecharge') }}
|
||||
</p>
|
||||
<p class="text-sm text-muted-foreground">
|
||||
{{ t('admin.cardTypes.create.balanceRechargeDesc') || '充值账户余额,适用于计时/计次模式' }}
|
||||
{{ t('admin.cardTypes.create.balanceRechargeDesc') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -243,10 +243,10 @@ onMounted(() => {
|
||||
<UiRadioGroupItem value="subscription" class="mt-0.5" />
|
||||
<div>
|
||||
<p class="font-medium">
|
||||
{{ t('admin.cardTypes.create.subscriptionRecharge') || '订阅充值' }}
|
||||
{{ t('admin.cardTypes.create.subscriptionRecharge') }}
|
||||
</p>
|
||||
<p class="text-sm text-muted-foreground">
|
||||
{{ t('admin.cardTypes.create.subscriptionRechargeDesc') || '充值会员时长,适用于订阅模式' }}
|
||||
{{ t('admin.cardTypes.create.subscriptionRechargeDesc') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -272,10 +272,10 @@ onMounted(() => {
|
||||
<div class="flex items-center justify-between pt-4 border-t">
|
||||
<div>
|
||||
<p class="font-medium">
|
||||
{{ t('admin.cardTypes.create.permanent') || '永久会员' }}
|
||||
{{ t('admin.cardTypes.create.permanentLabel') }}
|
||||
</p>
|
||||
<p class="text-sm text-muted-foreground">
|
||||
{{ t('admin.cardTypes.create.permanentDesc') || '开启后,使用此卡密的用户将成为永久会员' }}
|
||||
{{ t('admin.cardTypes.create.permanentLabelDesc') }}
|
||||
</p>
|
||||
</div>
|
||||
<UiSwitch v-model="form.is_permanent" />
|
||||
@@ -283,7 +283,7 @@ onMounted(() => {
|
||||
|
||||
<div v-if="!form.is_permanent" class="space-y-4 pt-4 border-t">
|
||||
<div v-if="form.recharge_type === 'balance'" class="space-y-2">
|
||||
<UiLabel>{{ t('admin.cardTypes.create.rechargeAmount') || '充值金额' }}</UiLabel>
|
||||
<UiLabel>{{ t('admin.cardTypes.create.rechargeAmount') }}</UiLabel>
|
||||
<UiNumberField v-model="form.value" :min="0.01" :step="0.01" class="max-w-[200px]">
|
||||
<UiNumberFieldContent>
|
||||
<UiNumberFieldDecrement />
|
||||
@@ -292,14 +292,14 @@ onMounted(() => {
|
||||
</UiNumberFieldContent>
|
||||
</UiNumberField>
|
||||
<p class="text-xs text-muted-foreground">
|
||||
{{ t('admin.cardTypes.create.rechargeAmountDesc') || '用户充值后获得的余额数量' }}
|
||||
{{ t('admin.cardTypes.create.rechargeAmountDesc') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div v-if="form.recharge_type === 'subscription'" class="space-y-4">
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div class="space-y-2">
|
||||
<UiLabel>{{ t('admin.cardTypes.create.rechargeDuration') || '充值时长' }}</UiLabel>
|
||||
<UiLabel>{{ t('admin.cardTypes.create.rechargeDuration') }}</UiLabel>
|
||||
<UiNumberField v-model="form.value" :min="1" :step="1">
|
||||
<UiNumberFieldContent>
|
||||
<UiNumberFieldDecrement />
|
||||
@@ -310,7 +310,7 @@ onMounted(() => {
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<UiLabel>{{ t('admin.cardTypes.create.durationUnit') || '时长单位' }}</UiLabel>
|
||||
<UiLabel>{{ t('admin.cardTypes.create.durationUnit') }}</UiLabel>
|
||||
<UiSelect v-model="form.value_unit">
|
||||
<UiSelectTrigger>
|
||||
<UiSelectValue />
|
||||
@@ -360,8 +360,8 @@ onMounted(() => {
|
||||
<span>{{ selectedApplication?.name || '-' }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between text-sm">
|
||||
<span class="text-muted-foreground">{{ t('admin.cardTypes.create.rechargeType') || '充值类型' }}</span>
|
||||
<span>{{ form.recharge_type === 'balance' ? (t('admin.cardTypes.create.balanceRecharge') || '余额充值') : (t('admin.cardTypes.create.subscriptionRecharge') || '订阅充值') }}</span>
|
||||
<span class="text-muted-foreground">{{ t('admin.cardTypes.create.rechargeType') }}</span>
|
||||
<span>{{ form.recharge_type === 'balance' ? t('admin.cardTypes.create.balanceRecharge') : t('admin.cardTypes.create.subscriptionRecharge') }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between text-sm">
|
||||
<span class="text-muted-foreground">{{ t('admin.cardTypes.create.previewPrice') }}</span>
|
||||
@@ -386,7 +386,7 @@ onMounted(() => {
|
||||
>
|
||||
<Icon v-if="saving" icon="lucide:loader-2" class="mr-2 h-4 w-4 animate-spin" />
|
||||
<Icon v-else icon="lucide:check" class="mr-2 h-4 w-4" />
|
||||
{{ t('admin.cardTypes.create.saveBtn') || '保存修改' }}
|
||||
{{ t('admin.cardTypes.create.saveBtn') }}
|
||||
</UiButton>
|
||||
<UiButton
|
||||
variant="outline"
|
||||
|
||||
@@ -178,13 +178,13 @@ onMounted(() => {
|
||||
<UiCardHeader>
|
||||
<UiCardTitle class="flex items-center gap-2">
|
||||
<Icon icon="lucide:credit-card" class="size-5" />
|
||||
充值配置
|
||||
{{ t('admin.cardTypes.create.rechargeConfig') }}
|
||||
</UiCardTitle>
|
||||
<UiCardDescription>设置卡密的充值类型和金额</UiCardDescription>
|
||||
<UiCardDescription>{{ t('admin.cardTypes.create.rechargeConfigDesc') }}</UiCardDescription>
|
||||
</UiCardHeader>
|
||||
<UiCardContent class="space-y-6">
|
||||
<div class="space-y-2">
|
||||
<UiLabel>充值类型</UiLabel>
|
||||
<UiLabel>{{ t('admin.cardTypes.create.rechargeType') }}</UiLabel>
|
||||
<UiRadioGroup v-model="form.recharge_type" class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div
|
||||
class="flex items-start gap-3 p-4 rounded-lg border cursor-pointer transition-colors"
|
||||
@@ -194,10 +194,10 @@ onMounted(() => {
|
||||
<UiRadioGroupItem value="balance" class="mt-0.5" />
|
||||
<div>
|
||||
<p class="font-medium">
|
||||
余额充值
|
||||
{{ t('admin.cardTypes.create.balanceRecharge') }}
|
||||
</p>
|
||||
<p class="text-sm text-muted-foreground">
|
||||
充值账户余额,适用于计时/计次模式
|
||||
{{ t('admin.cardTypes.create.balanceRechargeDesc') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -210,10 +210,10 @@ onMounted(() => {
|
||||
<UiRadioGroupItem value="subscription" class="mt-0.5" />
|
||||
<div>
|
||||
<p class="font-medium">
|
||||
订阅充值
|
||||
{{ t('admin.cardTypes.create.subscriptionRecharge') }}
|
||||
</p>
|
||||
<p class="text-sm text-muted-foreground">
|
||||
充值会员时长,适用于订阅模式
|
||||
{{ t('admin.cardTypes.create.subscriptionRechargeDesc') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -239,10 +239,10 @@ onMounted(() => {
|
||||
<div class="flex items-center justify-between pt-4 border-t">
|
||||
<div>
|
||||
<p class="font-medium">
|
||||
永久会员
|
||||
{{ t('admin.cardTypes.create.permanentLabel') }}
|
||||
</p>
|
||||
<p class="text-sm text-muted-foreground">
|
||||
开启后,使用此卡密的用户将成为永久会员
|
||||
{{ t('admin.cardTypes.create.permanentLabelDesc') }}
|
||||
</p>
|
||||
</div>
|
||||
<UiSwitch v-model="form.is_permanent" />
|
||||
@@ -250,7 +250,7 @@ onMounted(() => {
|
||||
|
||||
<div v-if="!form.is_permanent" class="space-y-4 pt-4 border-t">
|
||||
<div v-if="form.recharge_type === 'balance'" class="space-y-2">
|
||||
<UiLabel>充值金额</UiLabel>
|
||||
<UiLabel>{{ t('admin.cardTypes.create.rechargeAmount') }}</UiLabel>
|
||||
<UiNumberField v-model="form.value" :min="0.01" :step="0.01" class="max-w-[200px]">
|
||||
<UiNumberFieldContent>
|
||||
<UiNumberFieldDecrement />
|
||||
@@ -259,14 +259,14 @@ onMounted(() => {
|
||||
</UiNumberFieldContent>
|
||||
</UiNumberField>
|
||||
<p class="text-xs text-muted-foreground">
|
||||
用户充值后获得的余额数量
|
||||
{{ t('admin.cardTypes.create.rechargeAmountDesc') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div v-if="form.recharge_type === 'subscription'" class="space-y-4">
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div class="space-y-2">
|
||||
<UiLabel>充值时长</UiLabel>
|
||||
<UiLabel>{{ t('admin.cardTypes.create.rechargeDuration') }}</UiLabel>
|
||||
<UiNumberField v-model="form.value" :min="1" :step="1">
|
||||
<UiNumberFieldContent>
|
||||
<UiNumberFieldDecrement />
|
||||
@@ -277,26 +277,26 @@ onMounted(() => {
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<UiLabel>时长单位</UiLabel>
|
||||
<UiLabel>{{ t('admin.cardTypes.create.durationUnit') }}</UiLabel>
|
||||
<UiSelect v-model="form.value_unit">
|
||||
<UiSelectTrigger>
|
||||
<UiSelectValue />
|
||||
</UiSelectTrigger>
|
||||
<UiSelectContent>
|
||||
<UiSelectItem value="minute">
|
||||
分钟
|
||||
{{ t('admin.cardTypes.units.minute') }}
|
||||
</UiSelectItem>
|
||||
<UiSelectItem value="hour">
|
||||
小时
|
||||
{{ t('admin.cardTypes.units.hour') }}
|
||||
</UiSelectItem>
|
||||
<UiSelectItem value="day">
|
||||
天
|
||||
{{ t('admin.cardTypes.units.day') }}
|
||||
</UiSelectItem>
|
||||
<UiSelectItem value="month">
|
||||
月
|
||||
{{ t('admin.cardTypes.units.month') }}
|
||||
</UiSelectItem>
|
||||
<UiSelectItem value="year">
|
||||
年
|
||||
{{ t('admin.cardTypes.units.year') }}
|
||||
</UiSelectItem>
|
||||
</UiSelectContent>
|
||||
</UiSelect>
|
||||
@@ -327,8 +327,8 @@ onMounted(() => {
|
||||
<span>{{ selectedApplication?.name || '-' }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between text-sm">
|
||||
<span class="text-muted-foreground">充值类型</span>
|
||||
<span>{{ form.recharge_type === 'balance' ? '余额充值' : '订阅充值' }}</span>
|
||||
<span class="text-muted-foreground">{{ t('admin.cardTypes.create.rechargeType') }}</span>
|
||||
<span>{{ form.recharge_type === 'balance' ? t('admin.cardTypes.create.balanceRecharge') : t('admin.cardTypes.create.subscriptionRecharge') }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between text-sm">
|
||||
<span class="text-muted-foreground">{{ t('admin.cardTypes.create.previewPrice') }}</span>
|
||||
|
||||
@@ -389,7 +389,7 @@ onMounted(() => {
|
||||
<div class="flex items-center gap-2">
|
||||
<Icon icon="lucide:lock" class="size-4 text-primary" />
|
||||
<p class="font-medium">
|
||||
{{ t('admin.cloudVariables.create.developerOnly') }}
|
||||
{{ t('admin.cloudVariables.create.adminOnly') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -467,7 +467,7 @@ onMounted(() => {
|
||||
<div class="flex justify-between text-sm">
|
||||
<span class="text-muted-foreground">{{ t('admin.cloudVariables.create.writePermission') }}</span>
|
||||
<UiBadge variant="secondary">
|
||||
{{ form.write_permission === 'admin' ? t('admin.cloudVariables.create.developerOnly') : form.write_permission === 'app_user' ? '应用用户可写' : t('admin.cloudVariables.create.userWritable') }}
|
||||
{{ form.write_permission === 'admin' ? t('admin.cloudVariables.create.adminOnly') : form.write_permission === 'app_user' ? '应用用户可写' : t('admin.cloudVariables.create.userWritable') }}
|
||||
</UiBadge>
|
||||
</div>
|
||||
<div class="flex justify-between text-sm items-center">
|
||||
|
||||
@@ -74,7 +74,7 @@ export function getColumns(actions: {
|
||||
if (permission === 'user') {
|
||||
return h(Badge, { variant: 'outline', class: 'bg-green-50 text-green-700 dark:bg-green-950 dark:text-green-300' }, () => t('admin.cloudVariables.create.userWritable'))
|
||||
}
|
||||
return h(Badge, { variant: 'outline' }, () => t('admin.cloudVariables.create.developerOnly'))
|
||||
return h(Badge, { variant: 'outline' }, () => t('admin.cloudVariables.create.adminOnly'))
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -364,11 +364,11 @@ onMounted(() => {
|
||||
<div class="flex items-center gap-2">
|
||||
<Icon icon="lucide:lock" class="size-4 text-primary" />
|
||||
<p class="font-medium">
|
||||
{{ t('admin.cloudVariables.create.developerOnly') }}
|
||||
{{ t('admin.cloudVariables.create.adminOnly') }}
|
||||
</p>
|
||||
</div>
|
||||
<p class="text-sm text-muted-foreground mt-1">
|
||||
{{ form.scope === 'app' ? t('admin.cloudVariables.create.developerOnlyAppDesc') : t('admin.cloudVariables.create.developerOnlyDesc') }}
|
||||
{{ form.scope === 'app' ? t('admin.cloudVariables.create.adminOnlyAppDesc') : t('admin.cloudVariables.create.adminOnlyDesc') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -451,7 +451,7 @@ onMounted(() => {
|
||||
<div class="flex justify-between text-sm">
|
||||
<span class="text-muted-foreground">{{ t('admin.cloudVariables.create.writePermission') }}</span>
|
||||
<UiBadge variant="secondary">
|
||||
{{ form.write_permission === 'admin' ? t('admin.cloudVariables.create.developerOnly') : form.write_permission === 'app_user' ? '应用用户可写' : t('admin.cloudVariables.create.userWritable') }}
|
||||
{{ form.write_permission === 'admin' ? t('admin.cloudVariables.create.adminOnly') : form.write_permission === 'app_user' ? '应用用户可写' : t('admin.cloudVariables.create.userWritable') }}
|
||||
</UiBadge>
|
||||
</div>
|
||||
<div class="flex justify-between text-sm items-center">
|
||||
|
||||
@@ -479,7 +479,7 @@ onUnmounted(() => {
|
||||
<template>
|
||||
<BasicPage
|
||||
:title="t('admin.dashboard.title')"
|
||||
:description="`${t('admin.welcomeBack')}, ${currentUser?.username || t('admin.developer')}`"
|
||||
:description="`${t('admin.welcomeBack')}, ${currentUser?.username || t('admin.adminRole')}`"
|
||||
>
|
||||
<div v-if="loading" class="flex items-center justify-center py-12">
|
||||
<div class="text-center">
|
||||
|
||||
@@ -42,7 +42,7 @@ async function fetchUser() {
|
||||
}
|
||||
catch (error) {
|
||||
console.error('获取用户信息失败:', error)
|
||||
toast.error(t('admin.users.editFailed'))
|
||||
toast.error(t('admin.users.edit.failed'))
|
||||
}
|
||||
finally {
|
||||
loading.value = false
|
||||
@@ -68,15 +68,15 @@ const selectedApplication = computed(() => {
|
||||
|
||||
async function handleSave() {
|
||||
if (!form.value.username) {
|
||||
toast.error(t('admin.users.create.usernameRequired'))
|
||||
toast.error(t('admin.users.edit.usernameRequired'))
|
||||
return
|
||||
}
|
||||
if (!form.value.email) {
|
||||
toast.error(t('admin.users.create.emailRequired'))
|
||||
toast.error(t('admin.users.edit.emailRequired'))
|
||||
return
|
||||
}
|
||||
if (!form.value.application_id) {
|
||||
toast.error(t('admin.users.create.applicationRequired'))
|
||||
toast.error(t('admin.users.edit.applicationRequired'))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -93,12 +93,12 @@ async function handleSave() {
|
||||
}
|
||||
|
||||
await api.put(`/dev/app-users/${userId.value}`, payload)
|
||||
toast.success(t('admin.users.editSuccess'))
|
||||
toast.success(t('admin.users.edit.success'))
|
||||
router.push('/admin/users')
|
||||
}
|
||||
catch (error: any) {
|
||||
console.error('更新用户失败:', error)
|
||||
toast.error(error.message || t('admin.users.editFailed'))
|
||||
toast.error(error.message || t('admin.users.edit.failed'))
|
||||
}
|
||||
finally {
|
||||
saving.value = false
|
||||
@@ -113,11 +113,11 @@ onMounted(() => {
|
||||
|
||||
<template>
|
||||
<BasicPage
|
||||
:title="t('admin.users.edit')"
|
||||
:description="t('admin.users.create.basicInfoDesc')"
|
||||
:title="t('admin.users.edit.title')"
|
||||
:description="t('admin.users.edit.basicInfoDesc')"
|
||||
:breadcrumbs="[
|
||||
{ title: t('admin.users.title'), href: '/admin/users' },
|
||||
{ title: t('admin.users.edit') },
|
||||
{ title: t('admin.users.edit.title') },
|
||||
]"
|
||||
sticky
|
||||
>
|
||||
@@ -132,18 +132,18 @@ onMounted(() => {
|
||||
<UiCardHeader>
|
||||
<UiCardTitle class="flex items-center gap-2">
|
||||
<Icon icon="lucide:user-plus" class="size-5" />
|
||||
{{ t('admin.users.create.basicInfo') }}
|
||||
{{ t('admin.users.edit.basicInfo') }}
|
||||
</UiCardTitle>
|
||||
<UiCardDescription>{{ t('admin.users.create.basicInfoDesc') }}</UiCardDescription>
|
||||
<UiCardDescription>{{ t('admin.users.edit.basicInfoDesc') }}</UiCardDescription>
|
||||
</UiCardHeader>
|
||||
<UiCardContent class="space-y-6">
|
||||
<div class="space-y-2">
|
||||
<UiLabel for="application">
|
||||
{{ t('admin.users.create.application') }}
|
||||
{{ t('admin.users.edit.application') }}
|
||||
</UiLabel>
|
||||
<UiSelect v-model="form.application_id">
|
||||
<UiSelectTrigger>
|
||||
<UiSelectValue :placeholder="t('admin.users.create.selectApplication')" />
|
||||
<UiSelectValue :placeholder="t('admin.users.edit.selectApplication')" />
|
||||
</UiSelectTrigger>
|
||||
<UiSelectContent>
|
||||
<UiSelectItem v-for="app in applications" :key="app.id" :value="String(app.id)">
|
||||
@@ -155,25 +155,25 @@ onMounted(() => {
|
||||
|
||||
<div class="space-y-2">
|
||||
<UiLabel for="username">
|
||||
{{ t('admin.users.create.username') }}
|
||||
{{ t('admin.users.edit.username') }}
|
||||
</UiLabel>
|
||||
<UiInput id="username" v-model="form.username" :placeholder="t('admin.users.create.usernamePlaceholder')" />
|
||||
<UiInput id="username" v-model="form.username" :placeholder="t('admin.users.edit.usernamePlaceholder')" />
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<UiLabel for="email">
|
||||
{{ t('admin.users.create.email') }}
|
||||
{{ t('admin.users.edit.email') }}
|
||||
</UiLabel>
|
||||
<UiInput id="email" v-model="form.email" type="email" :placeholder="t('admin.users.create.emailPlaceholder')" />
|
||||
<UiInput id="email" v-model="form.email" type="email" :placeholder="t('admin.users.edit.emailPlaceholder')" />
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<UiLabel for="password">
|
||||
{{ t('admin.users.create.password') }}
|
||||
{{ t('admin.users.edit.password') }}
|
||||
</UiLabel>
|
||||
<UiInput id="password" v-model="form.password" type="password" :placeholder="t('admin.users.create.passwordPlaceholder')" />
|
||||
<UiInput id="password" v-model="form.password" type="password" :placeholder="t('admin.users.edit.passwordPlaceholder')" />
|
||||
<p class="text-xs text-muted-foreground">
|
||||
留空则不修改密码
|
||||
{{ t('admin.users.edit.passwordHint') }}
|
||||
</p>
|
||||
</div>
|
||||
</UiCardContent>
|
||||
@@ -185,21 +185,21 @@ onMounted(() => {
|
||||
<UiCardHeader>
|
||||
<UiCardTitle class="flex items-center gap-2">
|
||||
<Icon icon="lucide:eye" class="size-5" />
|
||||
{{ t('admin.users.create.preview') }}
|
||||
{{ t('admin.users.edit.preview') }}
|
||||
</UiCardTitle>
|
||||
</UiCardHeader>
|
||||
<UiCardContent class="space-y-4">
|
||||
<div class="space-y-3">
|
||||
<div class="flex justify-between text-sm">
|
||||
<span class="text-muted-foreground">{{ t('admin.users.create.app') }}</span>
|
||||
<span class="text-muted-foreground">{{ t('admin.users.edit.app') }}</span>
|
||||
<span>{{ selectedApplication?.name || '-' }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between text-sm">
|
||||
<span class="text-muted-foreground">{{ t('admin.users.create.usernameLabel') }}</span>
|
||||
<span class="text-muted-foreground">{{ t('admin.users.edit.usernameLabel') }}</span>
|
||||
<span>{{ form.username || '-' }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between text-sm">
|
||||
<span class="text-muted-foreground">{{ t('admin.users.create.emailLabel') }}</span>
|
||||
<span class="text-muted-foreground">{{ t('admin.users.edit.emailLabel') }}</span>
|
||||
<span>{{ form.email || '-' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -217,14 +217,14 @@ onMounted(() => {
|
||||
>
|
||||
<Icon v-if="saving" icon="lucide:loader-2" class="mr-2 h-4 w-4 animate-spin" />
|
||||
<Icon v-else icon="lucide:check" class="mr-2 h-4 w-4" />
|
||||
{{ t('admin.users.create.saveBtn') || '保存修改' }}
|
||||
{{ t('admin.users.edit.saveBtn') }}
|
||||
</UiButton>
|
||||
<UiButton
|
||||
variant="outline"
|
||||
class="w-full"
|
||||
@click="router.back()"
|
||||
>
|
||||
{{ t('admin.users.create.cancel') }}
|
||||
{{ t('admin.users.edit.cancel') }}
|
||||
</UiButton>
|
||||
</div>
|
||||
</UiCardContent>
|
||||
|
||||
@@ -92,8 +92,8 @@ onMounted(() => {
|
||||
|
||||
<template>
|
||||
<BasicPage
|
||||
title="创建用户"
|
||||
description="为应用创建新的用户账号,设置基本信息和应用关联"
|
||||
:title="t('admin.users.create.title')"
|
||||
:description="t('admin.users.create.description')"
|
||||
:breadcrumbs="[
|
||||
{ title: t('admin.users.title'), href: '/admin/users' },
|
||||
{ title: t('admin.users.create.title') },
|
||||
|
||||
Reference in New Issue
Block a user