mirror of
https://gitee.com/blackfox/geekai.git
synced 2024-12-02 12:17:42 +08:00
feat: 完成移动端前段框架搭建
This commit is contained in:
parent
063b5655f7
commit
ad0f96fcb1
116
web/src/main.js
116
web/src/main.js
@ -1,115 +1,23 @@
|
||||
import {createRouter, createWebHistory} from 'vue-router'
|
||||
import {createApp} from 'vue'
|
||||
import ElementPlus from "element-plus"
|
||||
import "element-plus/dist/index.css"
|
||||
import 'vant/lib/index.css';
|
||||
import App from './App.vue'
|
||||
import ChatPlus from "@/views/ChatPlus.vue";
|
||||
import NotFound from './views/404.vue'
|
||||
import Home from "@/views/Home.vue";
|
||||
import Login from "@/views/Login.vue"
|
||||
import Register from "@/views/Register.vue";
|
||||
import {createPinia} from "pinia";
|
||||
|
||||
const routes = [
|
||||
{name: 'home', path: '/', component: Home, meta: {title: 'ChatGPT-Plus'}},
|
||||
{name: 'login', path: '/login', component: Login, meta: {title: '用户登录'}},
|
||||
{name: 'register', path: '/register', component: Register, meta: {title: '用户注册'}},
|
||||
{name: 'plus', path: '/chat', component: ChatPlus, meta: {title: 'ChatGPT-智能助手V3'}},
|
||||
{
|
||||
path: '/admin/login',
|
||||
name: 'admin-login',
|
||||
meta: {title: 'Chat-Plus 控制台登录'},
|
||||
component: () => import('@/views/admin/Login.vue'),
|
||||
},
|
||||
{
|
||||
name: 'admin',
|
||||
path: '/admin',
|
||||
redirect: '/admin/welcome',
|
||||
component: () => import("@/views/admin/Home.vue"),
|
||||
meta: {title: 'ChatGPT-Plus 管理后台'},
|
||||
children: [
|
||||
{
|
||||
path: '/admin/welcome',
|
||||
name: 'admin-home',
|
||||
meta: {title: '系统首页'},
|
||||
component: () => import('@/views/admin/Welcome.vue'),
|
||||
},
|
||||
{
|
||||
path: '/admin/system',
|
||||
name: 'admin-system',
|
||||
meta: {title: '系统设置'},
|
||||
component: () => import('@/views/admin/SysConfig.vue'),
|
||||
},
|
||||
{
|
||||
path: '/admin/user',
|
||||
name: 'admin-user',
|
||||
meta: {title: '用户管理'},
|
||||
component: () => import('@/views/admin/UserList.vue'),
|
||||
},
|
||||
{
|
||||
path: '/admin/role',
|
||||
name: 'admin-role',
|
||||
meta: {title: '角色管理'},
|
||||
component: () => import('@/views/admin/RoleList.vue'),
|
||||
},
|
||||
{
|
||||
path: '/admin/apikey',
|
||||
name: 'admin-apikey',
|
||||
meta: {title: 'API-KEY 管理'},
|
||||
component: () => import('@/views/admin/ApiKey.vue'),
|
||||
},
|
||||
{
|
||||
path: '/admin/loginLog',
|
||||
name: 'admin-loginLog',
|
||||
meta: {title: '登录日志'},
|
||||
component: () => import('@/views/admin/LoginLog.vue'),
|
||||
},
|
||||
{
|
||||
path: '/admin/demo/form',
|
||||
name: 'admin-form',
|
||||
meta: {title: '表单页面'},
|
||||
component: () => import('@/views/admin/demo/Form.vue'),
|
||||
},
|
||||
{
|
||||
path: '/admin/demo/table',
|
||||
name: 'admin-table',
|
||||
meta: {title: '数据列表'},
|
||||
component: () => import('@/views/admin/demo/Table.vue'),
|
||||
},
|
||||
{
|
||||
path: '/admin/demo/import',
|
||||
name: 'admin-import',
|
||||
meta: {title: '导入数据'},
|
||||
component: () => import('@/views/admin/demo/Import.vue'),
|
||||
},
|
||||
{
|
||||
path: '/admin/demo/editor',
|
||||
name: 'admin-editor',
|
||||
meta: {title: '富文本编辑器'},
|
||||
component: () => import('@/views/admin/demo/Editor.vue'),
|
||||
},
|
||||
]
|
||||
},
|
||||
{name: 'test', path: '/test', component: () => import('@/views/Test.vue'), meta: {title: '测试页面'}},
|
||||
{name: 'NotFound', path: '/:all(.*)', component: NotFound, meta: {title: '页面没有找到'}},
|
||||
]
|
||||
|
||||
// console.log(MY_VARIABLE)
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes: routes,
|
||||
})
|
||||
|
||||
// dynamic change the title when router change
|
||||
router.beforeEach((to, from, next) => {
|
||||
if (to.meta.title) {
|
||||
document.title = `${to.meta.title} | ChatGPT-PLUS`
|
||||
}
|
||||
next()
|
||||
})
|
||||
import {Cell, Image, List, NavBar, Notify, Search, Tabbar, TabbarItem, TextEllipsis} from "vant";
|
||||
import router from "@/router";
|
||||
|
||||
const app = createApp(App)
|
||||
app.use(createPinia())
|
||||
app.use(Tabbar);
|
||||
app.use(TabbarItem);
|
||||
app.use(NavBar);
|
||||
app.use(Search);
|
||||
app.use(Cell)
|
||||
app.use(Image)
|
||||
app.use(TextEllipsis)
|
||||
app.use(Notify)
|
||||
app.use(List);
|
||||
app.use(router).use(ElementPlus).mount('#app')
|
||||
|
||||
|
||||
|
157
web/src/router.js
Normal file
157
web/src/router.js
Normal file
@ -0,0 +1,157 @@
|
||||
import {createRouter, createWebHistory} from "vue-router";
|
||||
|
||||
const routes = [
|
||||
{
|
||||
name: 'home',
|
||||
path: '/',
|
||||
meta: {title: 'ChatGPT-Plus'},
|
||||
component: () => import('@/views/Home.vue'),
|
||||
},
|
||||
{
|
||||
name: 'login',
|
||||
path: '/login',
|
||||
meta: {title: '用户登录'},
|
||||
component: () => import('@/views/Login.vue'),
|
||||
},
|
||||
{
|
||||
name: 'register',
|
||||
path: '/register',
|
||||
|
||||
meta: {title: '用户注册'},
|
||||
component: () => import('@/views/Register.vue'),
|
||||
},
|
||||
{
|
||||
name: 'plus',
|
||||
path: '/chat',
|
||||
meta: {title: 'ChatGPT-智能助手V3'},
|
||||
component: () => import('@/views/ChatPlus.vue'),
|
||||
},
|
||||
{
|
||||
path: '/admin/login',
|
||||
name: 'admin-login',
|
||||
meta: {title: 'Chat-Plus 控制台登录'},
|
||||
component: () => import('@/views/admin/Login.vue'),
|
||||
},
|
||||
{
|
||||
name: 'admin',
|
||||
path: '/admin',
|
||||
redirect: '/admin/welcome',
|
||||
component: () => import("@/views/admin/Home.vue"),
|
||||
meta: {title: 'ChatGPT-Plus 管理后台'},
|
||||
children: [
|
||||
{
|
||||
path: '/admin/welcome',
|
||||
name: 'admin-home',
|
||||
meta: {title: '系统首页'},
|
||||
component: () => import('@/views/admin/Welcome.vue'),
|
||||
},
|
||||
{
|
||||
path: '/admin/system',
|
||||
name: 'admin-system',
|
||||
meta: {title: '系统设置'},
|
||||
component: () => import('@/views/admin/SysConfig.vue'),
|
||||
},
|
||||
{
|
||||
path: '/admin/user',
|
||||
name: 'admin-user',
|
||||
meta: {title: '用户管理'},
|
||||
component: () => import('@/views/admin/UserList.vue'),
|
||||
},
|
||||
{
|
||||
path: '/admin/role',
|
||||
name: 'admin-role',
|
||||
meta: {title: '角色管理'},
|
||||
component: () => import('@/views/admin/RoleList.vue'),
|
||||
},
|
||||
{
|
||||
path: '/admin/apikey',
|
||||
name: 'admin-apikey',
|
||||
meta: {title: 'API-KEY 管理'},
|
||||
component: () => import('@/views/admin/ApiKey.vue'),
|
||||
},
|
||||
{
|
||||
path: '/admin/loginLog',
|
||||
name: 'admin-loginLog',
|
||||
meta: {title: '登录日志'},
|
||||
component: () => import('@/views/admin/LoginLog.vue'),
|
||||
},
|
||||
{
|
||||
path: '/admin/demo/form',
|
||||
name: 'admin-form',
|
||||
meta: {title: '表单页面'},
|
||||
component: () => import('@/views/admin/demo/Form.vue'),
|
||||
},
|
||||
{
|
||||
path: '/admin/demo/table',
|
||||
name: 'admin-table',
|
||||
meta: {title: '数据列表'},
|
||||
component: () => import('@/views/admin/demo/Table.vue'),
|
||||
},
|
||||
{
|
||||
path: '/admin/demo/import',
|
||||
name: 'admin-import',
|
||||
meta: {title: '导入数据'},
|
||||
component: () => import('@/views/admin/demo/Import.vue'),
|
||||
},
|
||||
{
|
||||
path: '/admin/demo/editor',
|
||||
name: 'admin-editor',
|
||||
meta: {title: '富文本编辑器'},
|
||||
component: () => import('@/views/admin/demo/Editor.vue'),
|
||||
},
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
name: 'mobile',
|
||||
path: '/mobile',
|
||||
meta: {title: 'ChatGPT-智能助手V3'},
|
||||
component: () => import('@/views/mobile/Home.vue'),
|
||||
redirect: '/mobile/chat',
|
||||
children: [
|
||||
{
|
||||
path: '/mobile/chat',
|
||||
name: 'mobile-chat',
|
||||
component: () => import('@/views/mobile/Chat.vue'),
|
||||
},
|
||||
{
|
||||
path: '/mobile/setting',
|
||||
name: 'mobile-setting',
|
||||
component: () => import('@/views/mobile/Setting.vue'),
|
||||
},
|
||||
{
|
||||
path: '/mobile/profile',
|
||||
name: 'mobile-profile',
|
||||
component: () => import('@/views/mobile/Profile.vue'),
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'test',
|
||||
path: '/test',
|
||||
meta: {title: '测试页面'},
|
||||
component: () => import('@/views/Test.vue'),
|
||||
},
|
||||
{
|
||||
name: 'NotFound',
|
||||
path: '/:all(.*)',
|
||||
meta: {title: '页面没有找到'},
|
||||
component: () => import('@/views/404.vue'),
|
||||
},
|
||||
]
|
||||
|
||||
// console.log(MY_VARIABLE)
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes: routes,
|
||||
})
|
||||
|
||||
// dynamic change the title when router change
|
||||
router.beforeEach((to, from, next) => {
|
||||
if (to.meta.title) {
|
||||
document.title = `${to.meta.title} | ChatGPT-PLUS`
|
||||
}
|
||||
next()
|
||||
})
|
||||
|
||||
export default router;
|
@ -694,11 +694,12 @@ const chatName = ref('')
|
||||
// 搜索会话
|
||||
const searchChat = function () {
|
||||
if (chatName.value === '') {
|
||||
chatList.value = allChats.value
|
||||
return
|
||||
}
|
||||
const roles = [];
|
||||
for (let i = 0; i < allChats.value.length; i++) {
|
||||
if (allChats.value[i].title.indexOf(chatName.value) !== -1) {
|
||||
if (allChats.value[i].title.toLowerCase().indexOf(chatName.value.toLowerCase()) !== -1) {
|
||||
roles.push(allChats.value[i]);
|
||||
}
|
||||
}
|
||||
|
105
web/src/views/mobile/Chat.vue
Normal file
105
web/src/views/mobile/Chat.vue
Normal file
@ -0,0 +1,105 @@
|
||||
<template>
|
||||
<div class="chat-mobile">
|
||||
<van-nav-bar :title="title"/>
|
||||
|
||||
<div class="content">
|
||||
<van-search
|
||||
v-model="chatName"
|
||||
placeholder="请输入会话标题"
|
||||
input-align="center"
|
||||
@input="search"
|
||||
/>
|
||||
|
||||
<van-list
|
||||
v-model:loading="loading"
|
||||
v-model:error="error"
|
||||
error-text="请求失败,点击重新加载"
|
||||
:finished="finished"
|
||||
finished-text="没有更多了"
|
||||
@load="onLoad"
|
||||
>
|
||||
<van-cell v-for="item in chats" :key="item.id">
|
||||
<div class="chat-list-item">
|
||||
<van-image
|
||||
round
|
||||
:src="item.icon"
|
||||
/>
|
||||
<van-text-ellipsis class="text" :content="item.title"/>
|
||||
</div>
|
||||
</van-cell>
|
||||
</van-list>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {ref} from "vue";
|
||||
import {httpGet} from "@/utils/http";
|
||||
import {getLoginUser} from "@/utils/storage";
|
||||
import {showFailToast} from "vant";
|
||||
|
||||
const title = ref("会话列表")
|
||||
const chatName = ref("")
|
||||
const chats = ref([])
|
||||
const allChats = ref([])
|
||||
const loading = ref(false)
|
||||
const finished = ref(false)
|
||||
const error = ref(false)
|
||||
const user = getLoginUser()
|
||||
|
||||
const onLoad = () => {
|
||||
httpGet("/api/chat/list?user_id=" + user.id).then((res) => {
|
||||
if (res.data) {
|
||||
chats.value = res.data;
|
||||
allChats.value = res.data;
|
||||
finished.value = true
|
||||
}
|
||||
loading.value = false;
|
||||
}).catch(() => {
|
||||
error.value = true
|
||||
showFailToast("加载会话列表失败")
|
||||
})
|
||||
};
|
||||
|
||||
const search = () => {
|
||||
if (chatName.value === '') {
|
||||
chats.value = allChats.value
|
||||
return
|
||||
}
|
||||
const roles = [];
|
||||
for (let i = 0; i < allChats.value.length; i++) {
|
||||
if (allChats.value[i].title.toLowerCase().indexOf(chatName.value.toLowerCase()) !== -1) {
|
||||
roles.push(allChats.value[i]);
|
||||
}
|
||||
}
|
||||
chats.value = roles;
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="stylus">
|
||||
|
||||
.chat-mobile {
|
||||
.content {
|
||||
padding: 0 10px;
|
||||
|
||||
.van-cell__value {
|
||||
.chat-list-item {
|
||||
display flex
|
||||
|
||||
.van-image {
|
||||
width 30px
|
||||
height 30px
|
||||
}
|
||||
|
||||
.text {
|
||||
margin-top 4px;
|
||||
margin-left 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
29
web/src/views/mobile/Home.vue
Normal file
29
web/src/views/mobile/Home.vue
Normal file
@ -0,0 +1,29 @@
|
||||
<template>
|
||||
<div>
|
||||
<router-view/>
|
||||
|
||||
<van-tabbar route v-model="active" @change="onChange">
|
||||
<van-tabbar-item to="/mobile/chat" name="home" icon="chat-o"></van-tabbar-item>
|
||||
<van-tabbar-item to="/mobile/setting" name="setting" icon="setting-o"></van-tabbar-item>
|
||||
<van-tabbar-item to="/mobile/profile" name="profile" icon="user-o"></van-tabbar-item>
|
||||
</van-tabbar>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {ref} from "vue";
|
||||
|
||||
const active = ref('home');
|
||||
const onChange = (index) => {
|
||||
console.log(index)
|
||||
// showToast(`标签 ${index}`);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus">
|
||||
.van-toast--fail {
|
||||
background #fef0f0
|
||||
color #f56c6c
|
||||
}
|
||||
</style>
|
15
web/src/views/mobile/Profile.vue
Normal file
15
web/src/views/mobile/Profile.vue
Normal file
@ -0,0 +1,15 @@
|
||||
<template>
|
||||
<div>
|
||||
<van-nav-bar :title="title"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {ref} from "vue";
|
||||
|
||||
const title = ref('用户设置')
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
15
web/src/views/mobile/Setting.vue
Normal file
15
web/src/views/mobile/Setting.vue
Normal file
@ -0,0 +1,15 @@
|
||||
<template>
|
||||
<div>
|
||||
<van-nav-bar :title="title"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {ref} from "vue";
|
||||
|
||||
const title = ref('聊天设置')
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
Loading…
Reference in New Issue
Block a user