fix: 修复授权管理API路径和页面布局
- POST /dev/agent-apps → POST /dev/agent-apps/authorize - PUT /dev/agent-apps/:id → PUT /dev/agent-apps/:id/card-types - 参考版本管理页面优化布局样式 - 编辑页面禁用代理和应用选择(不可修改) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -37,7 +37,7 @@ const agents = ref<Agent[]>([])
|
||||
const applications = ref<Application[]>([])
|
||||
const cardTypes = ref<CardType[]>([])
|
||||
|
||||
const form = ref({
|
||||
const formData = ref({
|
||||
agent_id: '',
|
||||
application_id: '',
|
||||
card_type_id: '',
|
||||
@@ -46,22 +46,22 @@ const form = ref({
|
||||
})
|
||||
|
||||
const selectedAgent = computed(() => {
|
||||
if (form.value.agent_id) {
|
||||
return agents.value.find(a => String(a.id) === form.value.agent_id)
|
||||
if (formData.value.agent_id) {
|
||||
return agents.value.find(a => String(a.id) === formData.value.agent_id)
|
||||
}
|
||||
return null
|
||||
})
|
||||
|
||||
const selectedApplication = computed(() => {
|
||||
if (form.value.application_id) {
|
||||
return applications.value.find(app => String(app.id) === form.value.application_id)
|
||||
if (formData.value.application_id) {
|
||||
return applications.value.find(app => String(app.id) === formData.value.application_id)
|
||||
}
|
||||
return null
|
||||
})
|
||||
|
||||
const selectedCardType = computed(() => {
|
||||
if (form.value.card_type_id) {
|
||||
return cardTypes.value.find(ct => String(ct.id) === form.value.card_type_id)
|
||||
if (formData.value.card_type_id) {
|
||||
return cardTypes.value.find(ct => String(ct.id) === formData.value.card_type_id)
|
||||
}
|
||||
return null
|
||||
})
|
||||
@@ -107,17 +107,16 @@ async function fetchAgentApp() {
|
||||
const agentApp = data?.agent_app || data
|
||||
|
||||
if (agentApp) {
|
||||
form.value.agent_id = String(agentApp.agent_id)
|
||||
form.value.application_id = String(agentApp.application_id)
|
||||
form.value.remark = agentApp.remark || ''
|
||||
formData.value.agent_id = String(agentApp.agent_id)
|
||||
formData.value.application_id = String(agentApp.application_id)
|
||||
|
||||
await fetchCardTypes(String(agentApp.application_id))
|
||||
|
||||
// 取第一个卡类权限
|
||||
if (agentApp.card_types && agentApp.card_types.length > 0) {
|
||||
const firstCardType = agentApp.card_types[0]
|
||||
form.value.card_type_id = String(firstCardType.card_type_id)
|
||||
form.value.price = firstCardType.price || 0
|
||||
formData.value.card_type_id = String(firstCardType.card_type_id)
|
||||
formData.value.price = firstCardType.price || 0
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -132,38 +131,34 @@ async function fetchAgentApp() {
|
||||
|
||||
watch(selectedCardType, (ct) => {
|
||||
if (ct && !loading.value) {
|
||||
form.value.price = ct.price
|
||||
formData.value.price = ct.price
|
||||
}
|
||||
})
|
||||
|
||||
async function handleSave() {
|
||||
if (!form.value.agent_id) {
|
||||
async function handleSubmit() {
|
||||
if (!formData.value.agent_id) {
|
||||
toast.error(t('admin.agentApps.createForm.selectAgentRequired'))
|
||||
return
|
||||
}
|
||||
|
||||
if (!form.value.application_id) {
|
||||
if (!formData.value.application_id) {
|
||||
toast.error(t('admin.agentApps.createForm.selectAppRequired'))
|
||||
return
|
||||
}
|
||||
|
||||
if (!form.value.card_type_id) {
|
||||
if (!formData.value.card_type_id) {
|
||||
toast.error(t('admin.agentApps.createForm.selectCardRequired'))
|
||||
return
|
||||
}
|
||||
|
||||
saving.value = true
|
||||
try {
|
||||
await api.put(`/dev/agent-apps/${agentAppId.value}`, {
|
||||
agent_id: Number(form.value.agent_id),
|
||||
application_id: Number(form.value.application_id),
|
||||
await api.put(`/dev/agent-apps/${agentAppId.value}/card-types`, {
|
||||
card_types: [{
|
||||
card_type_id: Number(form.value.card_type_id),
|
||||
card_type_id: Number(formData.value.card_type_id),
|
||||
can_generate: true,
|
||||
price: Number(form.value.price),
|
||||
price: Number(formData.value.price),
|
||||
}],
|
||||
discount: 0,
|
||||
remark: form.value.remark,
|
||||
})
|
||||
toast.success(t('admin.agentApps.createForm.updateSuccess'))
|
||||
router.push('/admin/agent-apps')
|
||||
@@ -209,48 +204,46 @@ onMounted(() => {
|
||||
<UiCardDescription>{{ t('admin.agentApps.createForm.authConfigDesc') }}</UiCardDescription>
|
||||
</UiCardHeader>
|
||||
<UiCardContent class="space-y-6">
|
||||
<div class="grid gap-4 sm:grid-cols-2">
|
||||
<div class="space-y-2">
|
||||
<UiLabel>{{ t('admin.agentApps.createForm.selectAgent') }} <span class="text-destructive">*</span></UiLabel>
|
||||
<UiSelect v-model="form.agent_id" :disabled="saving">
|
||||
<UiSelectTrigger>
|
||||
<UiSelectValue :placeholder="t('admin.agentApps.createForm.selectAgentPlaceholder')" />
|
||||
</UiSelectTrigger>
|
||||
<UiSelectContent>
|
||||
<UiSelectItem
|
||||
v-for="agent in agents"
|
||||
:key="agent.id"
|
||||
:value="String(agent.id)"
|
||||
>
|
||||
{{ agent.username }}
|
||||
</UiSelectItem>
|
||||
</UiSelectContent>
|
||||
</UiSelect>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<UiLabel>{{ t('admin.agentApps.createForm.selectAgent') }}</UiLabel>
|
||||
<UiSelect v-model="formData.agent_id" disabled>
|
||||
<UiSelectTrigger>
|
||||
<UiSelectValue :placeholder="t('admin.agentApps.createForm.selectAgentPlaceholder')" />
|
||||
</UiSelectTrigger>
|
||||
<UiSelectContent>
|
||||
<UiSelectItem
|
||||
v-for="agent in agents"
|
||||
:key="agent.id"
|
||||
:value="String(agent.id)"
|
||||
>
|
||||
{{ agent.username }}
|
||||
</UiSelectItem>
|
||||
</UiSelectContent>
|
||||
</UiSelect>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<UiLabel>{{ t('admin.agentApps.createForm.selectApp') }} <span class="text-destructive">*</span></UiLabel>
|
||||
<UiSelect v-model="form.application_id" :disabled="saving" @update:model-value="fetchCardTypes($event)">
|
||||
<UiSelectTrigger>
|
||||
<UiSelectValue :placeholder="t('admin.agentApps.createForm.selectAppPlaceholder')" />
|
||||
</UiSelectTrigger>
|
||||
<UiSelectContent>
|
||||
<UiSelectItem
|
||||
v-for="app in applications"
|
||||
:key="app.id"
|
||||
:value="String(app.id)"
|
||||
>
|
||||
{{ app.name }}
|
||||
</UiSelectItem>
|
||||
</UiSelectContent>
|
||||
</UiSelect>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<UiLabel>{{ t('admin.agentApps.createForm.selectApp') }}</UiLabel>
|
||||
<UiSelect v-model="formData.application_id" disabled>
|
||||
<UiSelectTrigger>
|
||||
<UiSelectValue :placeholder="t('admin.agentApps.createForm.selectAppPlaceholder')" />
|
||||
</UiSelectTrigger>
|
||||
<UiSelectContent>
|
||||
<UiSelectItem
|
||||
v-for="app in applications"
|
||||
:key="app.id"
|
||||
:value="String(app.id)"
|
||||
>
|
||||
{{ app.name }}
|
||||
</UiSelectItem>
|
||||
</UiSelectContent>
|
||||
</UiSelect>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-4 sm:grid-cols-2">
|
||||
<div class="space-y-2">
|
||||
<UiLabel>{{ t('admin.agentApps.createForm.selectCardType') }} <span class="text-destructive">*</span></UiLabel>
|
||||
<UiSelect v-model="form.card_type_id" :disabled="!form.application_id || saving">
|
||||
<UiSelect v-model="formData.card_type_id" :disabled="saving">
|
||||
<UiSelectTrigger>
|
||||
<UiSelectValue :placeholder="t('admin.agentApps.createForm.selectCardTypePlaceholder')" />
|
||||
</UiSelectTrigger>
|
||||
@@ -268,7 +261,7 @@ onMounted(() => {
|
||||
<span class="absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground">¥</span>
|
||||
<UiInput
|
||||
id="price"
|
||||
v-model.number="form.price"
|
||||
v-model.number="formData.price"
|
||||
type="number"
|
||||
class="pl-7"
|
||||
:placeholder="t('admin.agentApps.createForm.pricePlaceholder')"
|
||||
@@ -277,17 +270,6 @@ onMounted(() => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<UiLabel>{{ t('admin.agentApps.createForm.remark') }}</UiLabel>
|
||||
<textarea
|
||||
v-model="form.remark"
|
||||
class="flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
|
||||
:placeholder="t('admin.agentApps.createForm.remarkPlaceholder')"
|
||||
:disabled="saving"
|
||||
rows="2"
|
||||
/>
|
||||
</div>
|
||||
</UiCardContent>
|
||||
</UiCard>
|
||||
</div>
|
||||
@@ -316,11 +298,7 @@ onMounted(() => {
|
||||
</div>
|
||||
<div class="flex justify-between text-sm">
|
||||
<span class="text-muted-foreground">{{ t('admin.agentApps.createForm.previewPrice') }}</span>
|
||||
<span>¥{{ form.price || 0 }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between text-sm">
|
||||
<span class="text-muted-foreground">{{ t('admin.agentApps.createForm.previewRemark') }}</span>
|
||||
<span class="truncate max-w-[120px]">{{ form.remark || '-' }}</span>
|
||||
<span>¥{{ formData.price || 0 }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</UiCardContent>
|
||||
@@ -332,8 +310,8 @@ onMounted(() => {
|
||||
<UiButton
|
||||
class="w-full"
|
||||
size="lg"
|
||||
:disabled="saving || !form.agent_id || !form.application_id || !form.card_type_id"
|
||||
@click="handleSave"
|
||||
:disabled="saving || !formData.card_type_id"
|
||||
@click="handleSubmit"
|
||||
>
|
||||
<Loader2 v-if="saving" class="mr-2 h-4 w-4 animate-spin" />
|
||||
<Check v-else class="mr-2 h-4 w-4" />
|
||||
@@ -353,4 +331,4 @@ onMounted(() => {
|
||||
</div>
|
||||
</div>
|
||||
</BasicPage>
|
||||
</template>
|
||||
</template>
|
||||
@@ -34,7 +34,7 @@ const agents = ref<Agent[]>([])
|
||||
const applications = ref<Application[]>([])
|
||||
const cardTypes = ref<CardType[]>([])
|
||||
|
||||
const form = ref({
|
||||
const formData = ref({
|
||||
agent_id: '',
|
||||
application_id: '',
|
||||
card_type_id: '',
|
||||
@@ -43,22 +43,22 @@ const form = ref({
|
||||
})
|
||||
|
||||
const selectedAgent = computed(() => {
|
||||
if (form.value.agent_id) {
|
||||
return agents.value.find(a => String(a.id) === form.value.agent_id)
|
||||
if (formData.value.agent_id) {
|
||||
return agents.value.find(a => String(a.id) === formData.value.agent_id)
|
||||
}
|
||||
return null
|
||||
})
|
||||
|
||||
const selectedApplication = computed(() => {
|
||||
if (form.value.application_id) {
|
||||
return applications.value.find(app => String(app.id) === form.value.application_id)
|
||||
if (formData.value.application_id) {
|
||||
return applications.value.find(app => String(app.id) === formData.value.application_id)
|
||||
}
|
||||
return null
|
||||
})
|
||||
|
||||
const selectedCardType = computed(() => {
|
||||
if (form.value.card_type_id) {
|
||||
return cardTypes.value.find(ct => String(ct.id) === form.value.card_type_id)
|
||||
if (formData.value.card_type_id) {
|
||||
return cardTypes.value.find(ct => String(ct.id) === formData.value.card_type_id)
|
||||
}
|
||||
return null
|
||||
})
|
||||
@@ -90,57 +90,56 @@ async function fetchApplications() {
|
||||
async function fetchCardTypes(appId: string) {
|
||||
if (!appId) {
|
||||
cardTypes.value = []
|
||||
form.value.card_type_id = ''
|
||||
form.value.price = 0
|
||||
formData.value.card_type_id = ''
|
||||
formData.value.price = 0
|
||||
return
|
||||
}
|
||||
try {
|
||||
const data = await api.get<{ card_types: CardType[] }>(`/dev/card-types?application_id=${appId}`)
|
||||
cardTypes.value = data?.card_types || []
|
||||
form.value.card_type_id = ''
|
||||
form.value.price = 0
|
||||
formData.value.card_type_id = ''
|
||||
formData.value.price = 0
|
||||
}
|
||||
catch {
|
||||
cardTypes.value = []
|
||||
form.value.card_type_id = ''
|
||||
form.value.price = 0
|
||||
formData.value.card_type_id = ''
|
||||
formData.value.price = 0
|
||||
}
|
||||
}
|
||||
|
||||
watch(selectedCardType, (ct) => {
|
||||
if (ct) {
|
||||
form.value.price = ct.price
|
||||
formData.value.price = ct.price
|
||||
}
|
||||
})
|
||||
|
||||
async function handleSave() {
|
||||
if (!form.value.agent_id) {
|
||||
async function handleSubmit() {
|
||||
if (!formData.value.agent_id) {
|
||||
toast.error(t('admin.agentApps.createForm.selectAgentRequired'))
|
||||
return
|
||||
}
|
||||
|
||||
if (!form.value.application_id) {
|
||||
if (!formData.value.application_id) {
|
||||
toast.error(t('admin.agentApps.createForm.selectAppRequired'))
|
||||
return
|
||||
}
|
||||
|
||||
if (!form.value.card_type_id) {
|
||||
if (!formData.value.card_type_id) {
|
||||
toast.error(t('admin.agentApps.createForm.selectCardRequired'))
|
||||
return
|
||||
}
|
||||
|
||||
saving.value = true
|
||||
try {
|
||||
await api.post('/dev/agent-apps', {
|
||||
agent_id: Number(form.value.agent_id),
|
||||
application_id: Number(form.value.application_id),
|
||||
await api.post('/dev/agent-apps/authorize', {
|
||||
agent_id: Number(formData.value.agent_id),
|
||||
application_id: Number(formData.value.application_id),
|
||||
discount: 1.0,
|
||||
card_types: [{
|
||||
card_type_id: Number(form.value.card_type_id),
|
||||
card_type_id: Number(formData.value.card_type_id),
|
||||
can_generate: true,
|
||||
price: Number(form.value.price),
|
||||
price: Number(formData.value.price),
|
||||
}],
|
||||
discount: 0,
|
||||
remark: form.value.remark,
|
||||
})
|
||||
toast.success(t('admin.agentApps.createForm.createSuccess'))
|
||||
router.push('/admin/agent-apps')
|
||||
@@ -181,48 +180,46 @@ onMounted(() => {
|
||||
<UiCardDescription>{{ t('admin.agentApps.createForm.authConfigDesc') }}</UiCardDescription>
|
||||
</UiCardHeader>
|
||||
<UiCardContent class="space-y-6">
|
||||
<div class="grid gap-4 sm:grid-cols-2">
|
||||
<div class="space-y-2">
|
||||
<UiLabel>{{ t('admin.agentApps.createForm.selectAgent') }} <span class="text-destructive">*</span></UiLabel>
|
||||
<UiSelect v-model="form.agent_id" :disabled="saving || loading">
|
||||
<UiSelectTrigger>
|
||||
<UiSelectValue :placeholder="t('admin.agentApps.createForm.selectAgentPlaceholder')" />
|
||||
</UiSelectTrigger>
|
||||
<UiSelectContent>
|
||||
<UiSelectItem
|
||||
v-for="agent in agents"
|
||||
:key="agent.id"
|
||||
:value="String(agent.id)"
|
||||
>
|
||||
{{ agent.username }}
|
||||
</UiSelectItem>
|
||||
</UiSelectContent>
|
||||
</UiSelect>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<UiLabel>{{ t('admin.agentApps.createForm.selectAgent') }} <span class="text-destructive">*</span></UiLabel>
|
||||
<UiSelect v-model="formData.agent_id" :disabled="saving || loading">
|
||||
<UiSelectTrigger>
|
||||
<UiSelectValue :placeholder="t('admin.agentApps.createForm.selectAgentPlaceholder')" />
|
||||
</UiSelectTrigger>
|
||||
<UiSelectContent>
|
||||
<UiSelectItem
|
||||
v-for="agent in agents"
|
||||
:key="agent.id"
|
||||
:value="String(agent.id)"
|
||||
>
|
||||
{{ agent.username }}
|
||||
</UiSelectItem>
|
||||
</UiSelectContent>
|
||||
</UiSelect>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<UiLabel>{{ t('admin.agentApps.createForm.selectApp') }} <span class="text-destructive">*</span></UiLabel>
|
||||
<UiSelect v-model="form.application_id" :disabled="saving || loading" @update:model-value="fetchCardTypes($event)">
|
||||
<UiSelectTrigger>
|
||||
<UiSelectValue :placeholder="t('admin.agentApps.createForm.selectAppPlaceholder')" />
|
||||
</UiSelectTrigger>
|
||||
<UiSelectContent>
|
||||
<UiSelectItem
|
||||
v-for="app in applications"
|
||||
:key="app.id"
|
||||
:value="String(app.id)"
|
||||
>
|
||||
{{ app.name }}
|
||||
</UiSelectItem>
|
||||
</UiSelectContent>
|
||||
</UiSelect>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<UiLabel>{{ t('admin.agentApps.createForm.selectApp') }} <span class="text-destructive">*</span></UiLabel>
|
||||
<UiSelect v-model="formData.application_id" :disabled="saving || loading" @update:model-value="fetchCardTypes($event)">
|
||||
<UiSelectTrigger>
|
||||
<UiSelectValue :placeholder="t('admin.agentApps.createForm.selectAppPlaceholder')" />
|
||||
</UiSelectTrigger>
|
||||
<UiSelectContent>
|
||||
<UiSelectItem
|
||||
v-for="app in applications"
|
||||
:key="app.id"
|
||||
:value="String(app.id)"
|
||||
>
|
||||
{{ app.name }}
|
||||
</UiSelectItem>
|
||||
</UiSelectContent>
|
||||
</UiSelect>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-4 sm:grid-cols-2">
|
||||
<div class="space-y-2">
|
||||
<UiLabel>{{ t('admin.agentApps.createForm.selectCardType') }} <span class="text-destructive">*</span></UiLabel>
|
||||
<UiSelect v-model="form.card_type_id" :disabled="!form.application_id || saving">
|
||||
<UiSelect v-model="formData.card_type_id" :disabled="!formData.application_id || saving">
|
||||
<UiSelectTrigger>
|
||||
<UiSelectValue :placeholder="t('admin.agentApps.createForm.selectCardTypePlaceholder')" />
|
||||
</UiSelectTrigger>
|
||||
@@ -240,7 +237,7 @@ onMounted(() => {
|
||||
<span class="absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground">¥</span>
|
||||
<UiInput
|
||||
id="price"
|
||||
v-model.number="form.price"
|
||||
v-model.number="formData.price"
|
||||
type="number"
|
||||
class="pl-7"
|
||||
:placeholder="t('admin.agentApps.createForm.pricePlaceholder')"
|
||||
@@ -251,9 +248,10 @@ onMounted(() => {
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<UiLabel>{{ t('admin.agentApps.createForm.remark') }}</UiLabel>
|
||||
<UiLabel for="remark">{{ t('admin.agentApps.createForm.remark') }}</UiLabel>
|
||||
<textarea
|
||||
v-model="form.remark"
|
||||
id="remark"
|
||||
v-model="formData.remark"
|
||||
class="flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
|
||||
:placeholder="t('admin.agentApps.createForm.remarkPlaceholder')"
|
||||
:disabled="saving"
|
||||
@@ -288,11 +286,11 @@ onMounted(() => {
|
||||
</div>
|
||||
<div class="flex justify-between text-sm">
|
||||
<span class="text-muted-foreground">{{ t('admin.agentApps.createForm.previewPrice') }}</span>
|
||||
<span>¥{{ form.price || 0 }}</span>
|
||||
<span>¥{{ formData.price || 0 }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between text-sm">
|
||||
<span class="text-muted-foreground">{{ t('admin.agentApps.createForm.previewRemark') }}</span>
|
||||
<span class="truncate max-w-[120px]">{{ form.remark || '-' }}</span>
|
||||
<span class="truncate max-w-[120px]">{{ formData.remark || '-' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</UiCardContent>
|
||||
@@ -304,8 +302,8 @@ onMounted(() => {
|
||||
<UiButton
|
||||
class="w-full"
|
||||
size="lg"
|
||||
:disabled="saving || !form.agent_id || !form.application_id || !form.card_type_id"
|
||||
@click="handleSave"
|
||||
:disabled="saving || !formData.agent_id || !formData.application_id || !formData.card_type_id"
|
||||
@click="handleSubmit"
|
||||
>
|
||||
<Loader2 v-if="saving" class="mr-2 h-4 w-4 animate-spin" />
|
||||
<Rocket v-else class="mr-2 h-4 w-4" />
|
||||
|
||||
Reference in New Issue
Block a user