Initial commit: DataTool backend, frontend and Docker
This commit is contained in:
124
frontend/src/views/HomeView.vue
Normal file
124
frontend/src/views/HomeView.vue
Normal file
@@ -0,0 +1,124 @@
|
||||
<template>
|
||||
<div class="flex items-center justify-center min-h-[calc(100vh-56px)] px-4">
|
||||
<div
|
||||
class="w-full max-w-4xl bg-white border border-slate-200 rounded-[var(--dt-radius-modal)] px-6 sm:px-8 py-10 grid gap-8 md:grid-cols-2"
|
||||
>
|
||||
<!-- 创建房间 -->
|
||||
<section class="space-y-4">
|
||||
<h2 class="text-xl font-semibold text-slate-900">创建房间</h2>
|
||||
<p class="text-sm text-slate-600">
|
||||
自动生成 6 位房间号,在本地浏览器会话之间快速传文本、文件和图片。
|
||||
</p>
|
||||
<div
|
||||
class="mt-4 flex items-center justify-between rounded-[var(--dt-radius-card)] border border-dashed border-slate-300 bg-slate-50 px-4 py-3"
|
||||
>
|
||||
<span class="text-2xl font-mono font-semibold text-slate-900">
|
||||
{{ createRoomCodeDisplay }}
|
||||
</span>
|
||||
<BaseButton
|
||||
size="lg"
|
||||
variant="primary"
|
||||
:loading="createLoading"
|
||||
:disabled="createLoading"
|
||||
@click="handleCreateAndEnter"
|
||||
>
|
||||
创建并进入
|
||||
</BaseButton>
|
||||
</div>
|
||||
<p v-if="createError" class="text-xs text-danger">
|
||||
{{ createError }}
|
||||
</p>
|
||||
<p class="text-xs text-slate-500">
|
||||
数据不落库,仅当前会话可见。关闭页面后历史记录仅保留在本地浏览器。
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- 加入房间 -->
|
||||
<section class="space-y-4">
|
||||
<h2 class="text-xl font-semibold text-slate-900">加入房间</h2>
|
||||
<p class="text-sm text-slate-600">
|
||||
输入房间号,与同一房间的其他终端进行数据同步传输。
|
||||
</p>
|
||||
<form class="space-y-3" @submit.prevent="handleJoin">
|
||||
<div class="space-y-1.5">
|
||||
<label class="block text-xs font-medium text-slate-700">
|
||||
房间号(6 位数字)
|
||||
</label>
|
||||
<input
|
||||
v-model="joinRoomCode"
|
||||
type="text"
|
||||
inputmode="numeric"
|
||||
maxlength="6"
|
||||
class="dt-input"
|
||||
:class="{ 'border-danger focus:border-danger': joinError }"
|
||||
placeholder="请输入 6 位数字房间号"
|
||||
@input="joinError = ''"
|
||||
/>
|
||||
<p v-if="joinError" class="text-xs text-danger">
|
||||
{{ joinError }}
|
||||
</p>
|
||||
</div>
|
||||
<BaseButton
|
||||
type="submit"
|
||||
size="lg"
|
||||
variant="primary"
|
||||
class="w-full"
|
||||
:disabled="!isJoinValid"
|
||||
>
|
||||
加入房间
|
||||
</BaseButton>
|
||||
</form>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import axios from 'axios';
|
||||
import BaseButton from '@/components/ui/BaseButton.vue';
|
||||
|
||||
// 开发时用空字符串走同源,由 Vite 代理到后端,便于其它设备通过本机 IP:5173 访问
|
||||
const API_BASE = import.meta.env.VITE_API_BASE ?? (import.meta.env.DEV ? '' : 'http://localhost:8080');
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const createRoomCodeDisplay = ref('------');
|
||||
const createLoading = ref(false);
|
||||
const createError = ref('');
|
||||
const joinRoomCode = ref('');
|
||||
const joinError = ref('');
|
||||
|
||||
const isJoinValid = computed(() => /^[0-9]{6}$/.test(joinRoomCode.value));
|
||||
|
||||
async function handleCreateAndEnter() {
|
||||
createError.value = '';
|
||||
createLoading.value = true;
|
||||
try {
|
||||
const { data } = await axios.post<{ roomCode: string }>(
|
||||
`${API_BASE}/api/room/create`,
|
||||
);
|
||||
const roomCode = data.roomCode;
|
||||
createRoomCodeDisplay.value = roomCode;
|
||||
createLoading.value = false;
|
||||
router.push({ name: 'room', params: { roomCode } });
|
||||
} catch {
|
||||
createError.value = '创建房间失败,请稍后重试。';
|
||||
createRoomCodeDisplay.value = String(
|
||||
Math.floor(100000 + Math.random() * 900000),
|
||||
);
|
||||
createLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function handleJoin() {
|
||||
joinError.value = '';
|
||||
if (!isJoinValid.value) {
|
||||
joinError.value = '房间号必须是 6 位数字。';
|
||||
return;
|
||||
}
|
||||
router.push({ name: 'room', params: { roomCode: joinRoomCode.value } });
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user