feat(vue-app,flask): Vue 试验田全量对接与 Session 用户上下文统一

新增 vue-app(生成/收藏/历史/登录/优化/Android/饭菜/诗词/简历等),Flask 增加 user_context 并调整历史、生成、简历等路由;模板 base/generate 可访问性改进;补充部署说明与文档。

Made-with: Cursor
This commit is contained in:
renjianbo
2026-04-05 21:10:41 +08:00
parent 9a3f15f3e2
commit daa34582e9
77 changed files with 8999 additions and 528 deletions

View File

@@ -0,0 +1,91 @@
<script setup lang="ts">
import { computed, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useAuthStore } from '@/stores/auth'
const route = useRoute()
const router = useRouter()
const auth = useAuthStore()
const loginName = ref('')
const loginPwd = ref('')
const loading = ref(false)
const redirectTo = computed(() => {
const r = route.query.redirect
if (typeof r === 'string' && r.startsWith('/') && !r.startsWith('/login')) return r
return '/'
})
async function onSubmit() {
const name = loginName.value.trim()
const pwd = loginPwd.value
if (!name || !pwd) {
ElMessage.warning('请输入用户名和密码')
return
}
loading.value = true
try {
await auth.login(name, pwd)
ElMessage.success('登录成功')
await router.replace(redirectTo.value)
} catch (e) {
ElMessage.error(e instanceof Error ? e.message : '登录失败')
} finally {
loading.value = false
}
}
</script>
<template>
<el-card class="auth-card" shadow="hover">
<template #header>
<div class="head">登录</div>
</template>
<el-form label-position="top" @submit.prevent="onSubmit">
<el-form-item label="用户名">
<el-input v-model="loginName" autocomplete="username" />
</el-form-item>
<el-form-item label="密码">
<el-input v-model="loginPwd" type="password" show-password autocomplete="current-password" />
</el-form-item>
<el-form-item>
<el-button type="primary" native-type="submit" :loading="loading" style="width: 100%">
登录
</el-button>
</el-form-item>
</el-form>
<div class="foot">
<router-link :to="{ name: 'register', query: route.query }">没有账号注册</router-link>
<router-link :to="{ name: 'home' }">返回首页</router-link>
</div>
</el-card>
</template>
<style scoped lang="scss">
.auth-card {
width: 100%;
max-width: 400px;
border-radius: 12px;
}
.head {
font-weight: 600;
font-size: 1.125rem;
}
.foot {
display: flex;
justify-content: space-between;
gap: 1rem;
font-size: 0.875rem;
a {
color: var(--el-color-primary);
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
}
</style>

View File

@@ -0,0 +1,102 @@
<script setup lang="ts">
import { ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useAuthStore } from '@/stores/auth'
const route = useRoute()
const router = useRouter()
const auth = useAuthStore()
const loginName = ref('')
const loginPwd = ref('')
const loginPwd2 = ref('')
const nickname = ref('')
const loading = ref(false)
async function onSubmit() {
const name = loginName.value.trim()
const pwd = loginPwd.value
const pwd2 = loginPwd2.value
const nick = nickname.value.trim()
if (!name || !pwd || !nick) {
ElMessage.warning('请填写用户名、密码与昵称')
return
}
if (pwd !== pwd2) {
ElMessage.warning('两次密码不一致')
return
}
loading.value = true
try {
await auth.register({ login_name: name, login_pwd: pwd, nickname: nick })
ElMessage.success('注册成功')
const r = route.query.redirect
const path =
typeof r === 'string' && r.startsWith('/') && !r.startsWith('/register') ? r : '/'
await router.replace(path)
} catch (e) {
ElMessage.error(e instanceof Error ? e.message : '注册失败')
} finally {
loading.value = false
}
}
</script>
<template>
<el-card class="auth-card" shadow="hover">
<template #header>
<div class="head">注册</div>
</template>
<el-form label-position="top" @submit.prevent="onSubmit">
<el-form-item label="昵称">
<el-input v-model="nickname" autocomplete="nickname" />
</el-form-item>
<el-form-item label="用户名">
<el-input v-model="loginName" autocomplete="username" />
</el-form-item>
<el-form-item label="密码">
<el-input v-model="loginPwd" type="password" show-password autocomplete="new-password" />
</el-form-item>
<el-form-item label="确认密码">
<el-input v-model="loginPwd2" type="password" show-password autocomplete="new-password" />
</el-form-item>
<el-form-item>
<el-button type="primary" native-type="submit" :loading="loading" style="width: 100%">
注册
</el-button>
</el-form-item>
</el-form>
<div class="foot">
<router-link :to="{ name: 'login', query: route.query }">已有账号登录</router-link>
<router-link :to="{ name: 'home' }">返回首页</router-link>
</div>
</el-card>
</template>
<style scoped lang="scss">
.auth-card {
width: 100%;
max-width: 400px;
border-radius: 12px;
}
.head {
font-weight: 600;
font-size: 1.125rem;
}
.foot {
display: flex;
justify-content: space-between;
gap: 1rem;
font-size: 0.875rem;
a {
color: var(--el-color-primary);
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
}
</style>