mirror of
https://github.com/yangjian102621/geekai.git
synced 2025-11-08 02:03:42 +08:00
feat: load preview page do not require user to login
This commit is contained in:
@@ -6,55 +6,20 @@
|
||||
:show-close="false"
|
||||
:before-close="close"
|
||||
>
|
||||
<template #header="{ close, titleId, titleClass }">
|
||||
<template #header="{titleId, titleClass }">
|
||||
<div class="header">
|
||||
<div class="title">用户登录</div>
|
||||
<div class="title" v-if="login">用户登录</div>
|
||||
<div class="title" v-else>用户注册</div>
|
||||
<div class="close-icon">
|
||||
<el-icon>
|
||||
<el-icon @click="close">
|
||||
<Close/>
|
||||
</el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div class="login-box">
|
||||
<el-form label-width="75px">
|
||||
<el-form-item>
|
||||
<template #label>
|
||||
<div class="label">
|
||||
<el-icon>
|
||||
<User/>
|
||||
</el-icon>
|
||||
<span>账号</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #default>
|
||||
<el-input v-model="data.username" size="large" placeholder="账号"/>
|
||||
</template>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<template #label>
|
||||
<div class="label">
|
||||
<el-icon>
|
||||
<Lock/>
|
||||
</el-icon>
|
||||
<span>密码</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #default>
|
||||
<el-input v-model="data.password" type="password" size="large" placeholder="密码"/>
|
||||
</template>
|
||||
</el-form-item>
|
||||
|
||||
<div class="login-btn">
|
||||
<el-button type="primary" @click="submit" size="large" round>登录</el-button>
|
||||
<el-button plain @click="submit" size="large" round>注册</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div class="register-box">
|
||||
<el-form :model="data" label-width="120px" ref="formRef">
|
||||
<div class="login-box" v-if="login">
|
||||
<el-form :model="data" label-width="120px" class="form">
|
||||
<div class="block">
|
||||
<el-input placeholder="账号"
|
||||
size="large"
|
||||
@@ -81,6 +46,119 @@
|
||||
</el-input>
|
||||
</div>
|
||||
|
||||
<el-row class="btn-row" :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-button class="login-btn" type="primary" size="large" @click="submitLogin">登录</el-button>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<div class="text">
|
||||
还没有账号?
|
||||
<el-tag @click="login = false">注册</el-tag>
|
||||
</div>
|
||||
</el-col>
|
||||
|
||||
</el-row>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div class="register-box" v-else>
|
||||
<el-form :model="data" class="form" v-if="enableRegister">
|
||||
<el-tabs v-model="activeName" class="demo-tabs">
|
||||
<el-tab-pane label="手机注册" name="mobile" v-if="enableMobile">
|
||||
<div class="block">
|
||||
<el-input placeholder="手机号码"
|
||||
size="large"
|
||||
v-model="data.username"
|
||||
autocomplete="off">
|
||||
<template #prefix>
|
||||
<el-icon>
|
||||
<Iphone/>
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
<div class="block">
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="12">
|
||||
<el-input placeholder="验证码"
|
||||
size="large" maxlength="30"
|
||||
v-model="data.code"
|
||||
autocomplete="off">
|
||||
<template #prefix>
|
||||
<el-icon>
|
||||
<Checked/>
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<send-msg size="large" :receiver="data.username"/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="邮箱注册" name="email" v-if="enableEmail">
|
||||
<div class="block">
|
||||
<el-input placeholder="邮箱地址"
|
||||
size="large"
|
||||
v-model="data.username"
|
||||
autocomplete="off">
|
||||
<template #prefix>
|
||||
<el-icon>
|
||||
<Iphone/>
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
<div class="block">
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="12">
|
||||
<el-input placeholder="验证码"
|
||||
size="large" maxlength="30"
|
||||
v-model="data.code"
|
||||
autocomplete="off">
|
||||
<template #prefix>
|
||||
<el-icon>
|
||||
<Checked/>
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<send-msg size="large" :receiver="data.username"/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="用户名注册" name="username" v-if="enableUser">
|
||||
<div class="block">
|
||||
<el-input placeholder="用户名"
|
||||
size="large"
|
||||
v-model="data.username"
|
||||
autocomplete="off">
|
||||
<template #prefix>
|
||||
<el-icon>
|
||||
<Iphone/>
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<div class="block">
|
||||
<el-input placeholder="请输入密码(8-16位)"
|
||||
maxlength="16" size="large"
|
||||
v-model="data.password" show-password
|
||||
autocomplete="off">
|
||||
<template #prefix>
|
||||
<el-icon>
|
||||
<Lock/>
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
|
||||
<div class="block">
|
||||
<el-input placeholder="重复密码(8-16位)"
|
||||
size="large" maxlength="16" v-model="data.repass" show-password
|
||||
@@ -93,26 +171,6 @@
|
||||
</el-input>
|
||||
</div>
|
||||
|
||||
<div class="block">
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="12">
|
||||
<el-input placeholder="验证码"
|
||||
size="large" maxlength="30"
|
||||
v-model="data.code"
|
||||
autocomplete="off">
|
||||
<template #prefix>
|
||||
<el-icon>
|
||||
<Checked/>
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<send-msg size="large" :receiver="data.username"/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
<div class="block">
|
||||
<el-input placeholder="邀请码(可选)"
|
||||
size="large"
|
||||
@@ -126,27 +184,51 @@
|
||||
</el-input>
|
||||
</div>
|
||||
|
||||
<el-row class="btn-row">
|
||||
<el-button class="login-btn" type="primary" @click="">注册</el-button>
|
||||
</el-row>
|
||||
<el-row class="btn-row" :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-button class="login-btn" type="primary" size="large" @click="submitRegister">注册</el-button>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<div class="text">
|
||||
已有账号?
|
||||
<el-tag @click="login = true">登录</el-tag>
|
||||
</div>
|
||||
</el-col>
|
||||
|
||||
<el-row class="text-line">
|
||||
已经有账号?
|
||||
<el-link type="primary" @click="">登录</el-link>
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
<div class="tip-result" v-else>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-result icon="error" title="注册功能已关闭">
|
||||
<template #sub-title>
|
||||
<p>抱歉,系统已关闭注册功能,请联系管理员添加账号!</p>
|
||||
</template>
|
||||
</el-result>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="12">
|
||||
<div class="wechat-card">
|
||||
<el-image :src="wxImg"/>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {computed, ref} from "vue"
|
||||
import {httpPost} from "@/utils/http";
|
||||
import {httpGet, httpPost} from "@/utils/http";
|
||||
import {ElMessage} from "element-plus";
|
||||
import {setUserToken} from "@/store/session";
|
||||
import {validateMobile} from "@/utils/validate";
|
||||
import {validateEmail, validateMobile} from "@/utils/validate";
|
||||
import {Checked, Close, Iphone, Lock, Message, Position, User} from "@element-plus/icons-vue";
|
||||
import SendMsg from "@/components/SendMsg.vue";
|
||||
import {arrayContains} from "@/utils/libs";
|
||||
import {useRouter} from "vue-router";
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
const props = defineProps({
|
||||
@@ -155,21 +237,106 @@ const props = defineProps({
|
||||
const showDialog = computed(() => {
|
||||
return props.show
|
||||
})
|
||||
|
||||
const login = ref(true)
|
||||
const data = ref({
|
||||
username: "",
|
||||
password: ""
|
||||
password: "",
|
||||
repass: "",
|
||||
code: "",
|
||||
invite_code: ""
|
||||
})
|
||||
const enableMobile = ref(false)
|
||||
const enableEmail = ref(false)
|
||||
const enableUser = ref(false)
|
||||
const enableRegister = ref(false)
|
||||
const activeName = ref("mobile")
|
||||
const wxImg = ref("/images/wx.png")
|
||||
// eslint-disable-next-line no-undef
|
||||
const emits = defineEmits(['hide']);
|
||||
const submit = function () {
|
||||
const emits = defineEmits(['hide', 'success']);
|
||||
|
||||
httpGet("/api/config/get?key=system").then(res => {
|
||||
if (res.data) {
|
||||
const registerWays = res.data['register_ways']
|
||||
if (arrayContains(registerWays, "mobile")) {
|
||||
enableMobile.value = true
|
||||
}
|
||||
if (arrayContains(registerWays, "email")) {
|
||||
enableEmail.value = true
|
||||
}
|
||||
if (arrayContains(registerWays, "username")) {
|
||||
enableUser.value = true
|
||||
}
|
||||
// 是否启用注册
|
||||
enableRegister.value = res.data['enabled_register']
|
||||
// 使用后台上传的客服微信二维码
|
||||
if (res.data['wechat_card_url'] !== '') {
|
||||
wxImg.value = res.data['wechat_card_url']
|
||||
}
|
||||
}
|
||||
}).catch(e => {
|
||||
ElMessage.error("获取系统配置失败:" + e.message)
|
||||
})
|
||||
|
||||
// 登录操作
|
||||
const submitLogin = () => {
|
||||
if (data.value.username === '') {
|
||||
return ElMessage.error('请输入用户名');
|
||||
}
|
||||
if (data.value.password === '') {
|
||||
return ElMessage.error('请输入密码');
|
||||
}
|
||||
|
||||
httpPost('/api/user/login', data.value).then((res) => {
|
||||
setUserToken(res.data)
|
||||
ElMessage.success("登录成功!")
|
||||
emits("hide")
|
||||
emits('success')
|
||||
}).catch((e) => {
|
||||
ElMessage.error('登录失败,' + e.message)
|
||||
})
|
||||
}
|
||||
|
||||
// 注册操作
|
||||
const submitRegister = () => {
|
||||
if (data.value.username === '') {
|
||||
return ElMessage.error('请输入用户名');
|
||||
}
|
||||
|
||||
if (activeName.value === 'mobile' && !validateMobile(data.value.username)) {
|
||||
return ElMessage.error('请输入合法的手机号');
|
||||
}
|
||||
|
||||
if (activeName.value === 'email' && !validateEmail(data.value.username)) {
|
||||
return ElMessage.error('请输入合法的邮箱地址');
|
||||
}
|
||||
|
||||
if (data.value.password.length < 8) {
|
||||
return ElMessage.error('密码的长度为8-16个字符');
|
||||
}
|
||||
if (data.value.repass !== data.value.password) {
|
||||
return ElMessage.error('两次输入密码不一致');
|
||||
}
|
||||
|
||||
if ((activeName.value === 'mobile' || activeName.value === 'email') && data.value.code === '') {
|
||||
return ElMessage.error('请输入验证码');
|
||||
}
|
||||
data.value.reg_way = activeName.value
|
||||
httpPost('/api/user/register', data.value).then((res) => {
|
||||
setUserToken(res.data)
|
||||
ElMessage.success({
|
||||
"message": "注册成功!",
|
||||
onClose: () => {
|
||||
emits("hide")
|
||||
emits('success')
|
||||
},
|
||||
duration: 1000
|
||||
})
|
||||
}).catch((e) => {
|
||||
ElMessage.error('注册失败,' + e.message)
|
||||
})
|
||||
}
|
||||
|
||||
const close = function () {
|
||||
emits('hide', false);
|
||||
}
|
||||
@@ -191,7 +358,7 @@ const close = function () {
|
||||
.close-icon {
|
||||
cursor pointer
|
||||
position absolute
|
||||
right 0
|
||||
right -10px
|
||||
top 0
|
||||
font-weight normal
|
||||
font-size 20px
|
||||
@@ -202,31 +369,37 @@ const close = function () {
|
||||
}
|
||||
}
|
||||
|
||||
.login-box {
|
||||
.label {
|
||||
padding-top 3px
|
||||
|
||||
.el-icon {
|
||||
position relative
|
||||
font-size 20px
|
||||
margin-right 6px
|
||||
top 4px
|
||||
}
|
||||
.el-dialog__body {
|
||||
padding 10px 20px 20px 20px
|
||||
}
|
||||
|
||||
span {
|
||||
font-size 16px
|
||||
}
|
||||
.form {
|
||||
.block {
|
||||
margin-bottom 10px
|
||||
}
|
||||
|
||||
.login-btn {
|
||||
.btn-row {
|
||||
display flex
|
||||
padding-top 10px
|
||||
justify-content center
|
||||
|
||||
.el-button {
|
||||
font-size 16px
|
||||
width 100px
|
||||
width 100%
|
||||
}
|
||||
|
||||
.text {
|
||||
line-height 40px
|
||||
|
||||
.el-tag {
|
||||
cursor pointer
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.register-box {
|
||||
.wechat-card {
|
||||
text-align center
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
<div class="chat-head">
|
||||
<div class="chat-config">
|
||||
<!-- <span class="role-select-label">聊天角色:</span>-->
|
||||
<el-select v-model="roleId" filterable placeholder="角色" class="role-select" @change="newChat">
|
||||
<el-select v-model="roleId" filterable placeholder="角色" class="role-select" @change="_newChat">
|
||||
<el-option
|
||||
v-for="item in roles"
|
||||
:key="item.id"
|
||||
@@ -97,7 +97,7 @@
|
||||
</el-option>
|
||||
</el-select>
|
||||
|
||||
<el-select v-model="modelID" placeholder="模型" @change="newChat">
|
||||
<el-select v-model="modelID" placeholder="模型" @change="_newChat">
|
||||
<el-option
|
||||
v-for="item in models"
|
||||
:key="item.id"
|
||||
@@ -238,7 +238,7 @@
|
||||
|
||||
<config-dialog v-if="isLogin" :show="showConfigDialog" :models="models" @hide="showConfigDialog = false"/>
|
||||
|
||||
<login-dialog :show="true"/>
|
||||
<login-dialog :show="showLoginDialog" @hide="showLoginDialog = false" @success="initData"/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -292,6 +292,7 @@ const roleId = ref(0)
|
||||
const newChatItem = ref(null);
|
||||
const router = useRouter();
|
||||
const showConfigDialog = ref(false);
|
||||
const showLoginDialog = ref(false)
|
||||
const isLogin = ref(false)
|
||||
const showHello = ref(true)
|
||||
const textInput = ref(null)
|
||||
@@ -303,26 +304,65 @@ if (isMobile()) {
|
||||
router.replace("/mobile")
|
||||
}
|
||||
|
||||
// 获取系统配置
|
||||
httpGet("/api/config/get?key=system").then(res => {
|
||||
title.value = res.data.title
|
||||
}).catch(e => {
|
||||
ElMessage.error("获取系统配置失败:" + e.message)
|
||||
})
|
||||
|
||||
// 获取系统公告
|
||||
httpGet("/api/config/get?key=notice").then(res => {
|
||||
notice.value = md.render(res.data['content'])
|
||||
const oldNotice = localStorage.getItem(noticeKey.value);
|
||||
// 如果公告有更新,则显示公告
|
||||
if (oldNotice !== notice.value && notice.value.length > 10) {
|
||||
showNotice.value = true
|
||||
}
|
||||
}).catch(e => {
|
||||
ElMessage.error("获取系统配置失败:" + e.message)
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
resizeElement();
|
||||
initData()
|
||||
|
||||
const clipboard = new Clipboard('.copy-reply, .copy-code-btn');
|
||||
clipboard.on('success', () => {
|
||||
ElMessage.success('复制成功!');
|
||||
})
|
||||
|
||||
clipboard.on('error', () => {
|
||||
ElMessage.error('复制失败!');
|
||||
})
|
||||
|
||||
window.onresize = () => resizeElement();
|
||||
});
|
||||
|
||||
// 初始化数据
|
||||
const initData = () => {
|
||||
// 检查会话
|
||||
checkSession().then((user) => {
|
||||
loginUser.value = user
|
||||
isLogin.value = true
|
||||
|
||||
// 获取会话列表
|
||||
httpGet("/api/chat/list?user_id=" + loginUser.value.id).then((res) => {
|
||||
httpGet("/api/chat/list").then((res) => {
|
||||
if (res.data) {
|
||||
chatList.value = res.data;
|
||||
allChats.value = res.data;
|
||||
}
|
||||
|
||||
// 加载模型
|
||||
httpGet('/api/model/list?enable=1').then(res => {
|
||||
httpGet('/api/model/list').then(res => {
|
||||
models.value = res.data
|
||||
modelID.value = models.value[0].id
|
||||
|
||||
// 加载角色列表
|
||||
httpGet(`/api/role/list?user_id=${user.id}`).then((res) => {
|
||||
httpGet(`/api/role/list`).then((res) => {
|
||||
roles.value = res.data;
|
||||
roleId.value = roles.value[0]['id'];
|
||||
|
||||
const chatId = localStorage.getItem("chat_id")
|
||||
const chat = getChatById(chatId)
|
||||
if (chat === null) {
|
||||
@@ -338,45 +378,38 @@ onMounted(() => {
|
||||
}).catch(e => {
|
||||
ElMessage.error("加载模型失败: " + e.message)
|
||||
})
|
||||
|
||||
}).catch(() => {
|
||||
// TODO: 增加重试按钮
|
||||
ElMessage.error("加载会话列表失败!")
|
||||
})
|
||||
}).catch(() => {
|
||||
loading.value = false
|
||||
// 加载会话
|
||||
httpGet("/api/chat/list").then((res) => {
|
||||
if (res.data) {
|
||||
chatList.value = res.data;
|
||||
allChats.value = res.data;
|
||||
}
|
||||
}).catch(() => {
|
||||
ElMessage.error("加载会话列表失败!")
|
||||
})
|
||||
|
||||
// 获取系统配置
|
||||
httpGet("/api/config/get?key=system").then(res => {
|
||||
title.value = res.data.title
|
||||
// 加载模型
|
||||
httpGet('/api/model/list').then(res => {
|
||||
models.value = res.data
|
||||
modelID.value = models.value[0].id
|
||||
}).catch(e => {
|
||||
ElMessage.error("获取系统配置失败:" + e.message)
|
||||
ElMessage.error("加载模型失败: " + e.message)
|
||||
})
|
||||
|
||||
// 获取系统公告
|
||||
httpGet("/api/config/get?key=notice").then(res => {
|
||||
notice.value = md.render(res.data['content'])
|
||||
const oldNotice = localStorage.getItem(noticeKey.value);
|
||||
// 如果公告有更新,则显示公告
|
||||
if (oldNotice !== notice.value && notice.value.length > 10) {
|
||||
showNotice.value = true
|
||||
}
|
||||
}).catch(e => {
|
||||
ElMessage.error("获取系统配置失败:" + e.message)
|
||||
// 加载角色列表
|
||||
httpGet(`/api/role/list`).then((res) => {
|
||||
roles.value = res.data;
|
||||
roleId.value = roles.value[0]['id'];
|
||||
}).catch((e) => {
|
||||
ElMessage.error('获取聊天角色失败: ' + e.messages)
|
||||
})
|
||||
}).catch(() => {
|
||||
router.push('/login')
|
||||
});
|
||||
|
||||
const clipboard = new Clipboard('.copy-reply, .copy-code-btn');
|
||||
clipboard.on('success', () => {
|
||||
ElMessage.success('复制成功!');
|
||||
})
|
||||
|
||||
clipboard.on('error', () => {
|
||||
ElMessage.error('复制失败!');
|
||||
})
|
||||
|
||||
window.onresize = () => resizeElement();
|
||||
});
|
||||
}
|
||||
|
||||
const getRoleById = function (rid) {
|
||||
for (let i = 0; i < roles.value.length; i++) {
|
||||
@@ -393,8 +426,17 @@ const resizeElement = function () {
|
||||
leftBoxHeight.value = window.innerHeight - 43 - 47 - 45;
|
||||
};
|
||||
|
||||
const _newChat = () => {
|
||||
if (isLogin.value) {
|
||||
newChat()
|
||||
}
|
||||
}
|
||||
// 新建会话
|
||||
const newChat = function () {
|
||||
const newChat = () => {
|
||||
if (!isLogin.value) {
|
||||
showLoginDialog.value = true
|
||||
return;
|
||||
}
|
||||
// 已有新开的会话
|
||||
if (newChatItem.value !== null && newChatItem.value['role_id'] === roles.value[0]['role_id']) {
|
||||
return;
|
||||
@@ -707,6 +749,11 @@ const autofillPrompt = (text) => {
|
||||
}
|
||||
// 发送消息
|
||||
const sendMessage = function () {
|
||||
if (!isLogin.value) {
|
||||
showLoginDialog.value = true
|
||||
return;
|
||||
}
|
||||
|
||||
if (canSend.value === false) {
|
||||
ElMessage.warning("AI 正在作答中,请稍后...");
|
||||
return
|
||||
@@ -769,8 +816,8 @@ const clearAllChats = function () {
|
||||
const logout = function () {
|
||||
activelyClose.value = true;
|
||||
httpGet('/api/user/logout').then(() => {
|
||||
removeUserToken();
|
||||
router.push('/login');
|
||||
removeUserToken()
|
||||
location.reload()
|
||||
}).catch(() => {
|
||||
ElMessage.error('注销失败!');
|
||||
})
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
<el-checkbox-group v-model="system['register_ways']">
|
||||
<el-checkbox label="mobile">手机注册</el-checkbox>
|
||||
<el-checkbox label="email">邮箱注册</el-checkbox>
|
||||
<el-checkbox label="username">用户名注册</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user