Files
HookPilot/web/src/views/hook/BasicTab.vue
T
2026-09-27 20:09:10 +08:00

88 lines
3.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import { computed } from 'vue';
import type { HookDetail, HookForm } from '../../api/types';
import { toast } from '../../composables/toast';
import { copyText, formatTime, webhookUrl } from '../../utils/format';
const props = defineProps<{ form: HookForm; hook: HookDetail | null; groups: string[] }>();
const emit = defineEmits<{ regenerateToken: [] }>();
const url = computed(() => webhookUrl(props.form.slug));
const slugChanged = computed(() => props.hook !== null && props.hook.slug !== props.form.slug);
const hasBodyParams = computed(() => props.form.params.some((p) => p.source === 'json' || p.source === 'form'));
async function copyUrl() {
if (await copyText(url.value)) toast.success('调用地址已复制');
}
</script>
<template>
<div class="form-grid">
<div class="field">
<label class="required">接口名称</label>
<input v-model="form.name" maxlength="100" placeholder="如:更新家庭 IP" />
</div>
<div class="field">
<label>分组</label>
<input v-model="form.group" list="hook-groups" maxlength="50" placeholder="可选,用于在列表中归类" />
<datalist id="hook-groups">
<option v-for="g in groups" :key="g" :value="g" />
</datalist>
</div>
<div class="field">
<label class="required">接口标识</label>
<input v-model="form.slug" maxlength="64" placeholder="如:home-ip" class="mono" />
<div class="hint">小写字母、数字、下划线和连字符,以字母或数字开头。</div>
</div>
<div class="field">
<label class="required">请求方式</label>
<select v-model="form.method">
<option value="POST">POST</option>
<option value="GET">GET</option>
</select>
<div v-if="form.method === 'GET' && hasBodyParams" class="hint" style="color: var(--danger)">
GET 接口只能从 Query 或 Header 提取参数,请调整参数配置。
</div>
</div>
<div class="field full">
<label>调用地址</label>
<div class="row">
<div class="input-group" style="flex: 1">
<span class="addon">{{ form.method }}</span>
<input :value="url" readonly class="mono" />
</div>
<button class="btn" :disabled="!form.slug" @click="copyUrl">复制</button>
</div>
<div v-if="slugChanged" class="hint" style="color: var(--warning)">
修改标识后原地址 /hooks/{{ hook!.slug }} 将失效,调用方需同步更新。
</div>
</div>
<div class="field full">
<label>描述</label>
<textarea v-model="form.description" rows="3" maxlength="1000" placeholder="接口用途、调用方等说明" />
</div>
<div class="field full">
<label>接口 Token</label>
<template v-if="hook">
<div class="row">
<input :value="`hp_••••••••••••••••••••••••${hook.tokenHint}`" readonly class="mono" style="max-width: 360px" />
<button class="btn btn-danger-outline" @click="emit('regenerateToken')">重新生成</button>
</div>
<div class="hint">
Token 仅在创建或重新生成时完整显示一次。调用时通过 <code>Authorization: Bearer &lt;token&gt;</code> 或
<code>X-Hook-Token</code> 请求头传递。
</div>
</template>
<div v-else class="hint">创建接口后自动生成,届时只显示一次,请妥善保存。</div>
</div>
<div v-if="hook" class="field full">
<div class="small faint">创建于 {{ formatTime(hook.createdAt) }} · 最后修改 {{ formatTime(hook.updatedAt) }}</div>
</div>
</div>
</template>