const { createApp, ref, reactive, computed, onMounted } = Vue; const { createRouter, createWebHashHistory } = VueRouter; function api(method, url, body) { const opts = { method, headers: { 'Content-Type': 'application/json' } }; const t = localStorage.getItem('gemold_token'); if (t) opts.headers.Authorization = 'Bearer ' + t; if (body) opts.body = JSON.stringify(body); return fetch(url, opts).then(r => { if (r.status === 401) { localStorage.removeItem('gemold_token'); localStorage.removeItem('gemold_user'); router.push('/login'); } if (!r.ok) return r.json().then(e => Promise.reject(e)); const ct = r.headers.get('content-type') || ''; return ct.includes('application/json') ? r.json() : r.text(); }); } function apiForm(url, form) { const opts = { method: 'POST', body: form }; const t = localStorage.getItem('gemold_token'); if (t) opts.headers = { Authorization: 'Bearer ' + t }; return fetch(url, opts).then(r => { if (r.status === 401) { localStorage.removeItem('gemold_token'); localStorage.removeItem('gemold_user'); router.push('/login'); } if (!r.ok) return r.json().then(e => Promise.reject(e)); return r.json(); }); } const store = reactive({ user: JSON.parse(localStorage.getItem('gemold_user') || 'null'), tasks: [], uploading: false, async login(username, password) { const form = new FormData(); form.append('username', username); form.append('password', password); const r = await apiForm('/api/auth/login', form); store.user = r.user; localStorage.setItem('gemold_token', r.access_token); localStorage.setItem('gemold_user', JSON.stringify(r.user)); return r; }, logout() { localStorage.removeItem('gemold_token'); localStorage.removeItem('gemold_user'); store.user = null; store.tasks = []; router.push('/login'); }, async fetchTasks() { const r = await api('GET', '/api/debug/tasks'); store.tasks = Object.values(r.tasks || {}).sort((a, b) => { const da = a.created_at || a.upload_time || ''; const db = b.created_at || b.upload_time || ''; return db.localeCompare(da); }); }, async uploadFile(file, material) { store.uploading = true; try { const form = new FormData(); form.append('file', file); if (material) form.append('material', material); const r = await apiForm('/api/upload', form); await store.fetchTasks(); return r; } finally { store.uploading = false; } }, }); const LoginPage = { setup() { const username = ref(''); const password = ref(''); const error = ref(''); const loading = ref(false); const doLogin = async () => { loading.value = true; error.value = ''; try { await store.login(username.value, password.value); router.push('/dashboard'); } catch (e) { error.value = e.detail || '登录失败'; } finally { loading.value = false; } }; return { username, password, error, loading, doLogin }; }, template: `
模具制造管理系统