diff --git a/frontend/App.vue b/frontend/App.vue
new file mode 100644
index 0000000000000000000000000000000000000000..8c2b732101d2c5679c3000a773ee4bb16995a630
--- /dev/null
+++ b/frontend/App.vue
@@ -0,0 +1,17 @@
+
+
+
diff --git a/frontend/api/auth.js b/frontend/api/auth.js
new file mode 100644
index 0000000000000000000000000000000000000000..7033998bb206b1afd6b9a2260e1815f12fade78e
--- /dev/null
+++ b/frontend/api/auth.js
@@ -0,0 +1,37 @@
+import {
+ useRequest
+} from "./config/index.js";
+
+export function useAuthApi() {
+ const {request} = useRequest()
+
+ const login = async (credentials) => {
+
+ const loginData = credentials
+
+ const response = await request({
+ url: '/auth/login',
+ method: 'POST',
+ data: loginData,
+ showLoading: true
+ })
+
+ return response;
+ }
+
+ const register = async (createUser) => {
+
+ const user = createUser
+
+ const respose = await request({
+ url: '/auth/register',
+ method: 'POST',
+ data: user,
+ showLoading: true
+ })
+
+ return respose;
+ }
+
+ return {login,register}
+}
\ No newline at end of file
diff --git a/frontend/api/chat.js b/frontend/api/chat.js
new file mode 100644
index 0000000000000000000000000000000000000000..d10d3962c50ded61dc9675dbd3088ecc464de34d
--- /dev/null
+++ b/frontend/api/chat.js
@@ -0,0 +1,72 @@
+
+import {
+ useRequest
+} from "./config";
+
+const {
+ request
+} = useRequest()
+
+export function useChatApi() {
+
+ const createChat = async (chatDto) => {
+
+
+ var res =await request({
+ url: '/AIQuestions/user',
+ method: 'POST',
+ data: chatDto,
+ showLoading: true
+ })
+
+ return res
+ }
+
+ const getChat = async (id) => {
+
+ var res =await request({
+ url: `/AIQuestions/user/${id}`,
+ method: 'GET',
+ data: null,
+ showLoading: true
+ })
+
+ return res
+ }
+
+ const getAllMessage = async (id)=> {
+ var res =await request({
+ url: `/AIQuestions/user/message/${id}`,
+ method: 'GET',
+ data: null,
+ showLoading: true
+ })
+
+ return res
+ }
+
+ const deleteChat = async (id) => {
+ var res = await request({
+ url:`/AIQuestions/user/${id}`,
+ method:'DELETE',
+ data:null,
+ showLoading:true
+ })
+
+ return res
+ }
+
+
+ const conversation = async (id,userMessage) => {
+ var res = await request({
+ url:`/AIQuestions/chat/${id}`,
+ method:'POST',
+ data:JSON.stringify(userMessage),
+ showLoading:true
+ })
+
+ return res
+ }
+
+ return {conversation,createChat,deleteChat,getAllMessage,getChat}
+}
\ No newline at end of file
diff --git a/frontend/api/config/Config.js b/frontend/api/config/Config.js
new file mode 100644
index 0000000000000000000000000000000000000000..6fcad25d8aee6d82fcc93c5cce1c4a5772e851ba
--- /dev/null
+++ b/frontend/api/config/Config.js
@@ -0,0 +1,17 @@
+const env = process.env.NODE_ENV || 'development'
+
+const configs = {
+ development: {
+ baseUrl: 'http://localhost:5101/api', // 简化结构
+ },
+ production: {
+ baseUrl: 'https://your-production-domain.com/api',
+ }
+}
+
+export default {
+ ...configs[env],
+ // 公共配置
+ appName: '多端应用',
+ version: '1.0.0',
+}
\ No newline at end of file
diff --git a/frontend/api/config/index.js b/frontend/api/config/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..729354dfa778a537b41754abebe6e86d1a97eaa1
--- /dev/null
+++ b/frontend/api/config/index.js
@@ -0,0 +1,128 @@
+import {
+ ref
+} from "vue";
+import {
+ useUserStore
+} from "../../stores/User";
+import config from './Config.js'
+
+const getBaseUrl = () => {
+ return config.baseUrl; // 直接使用配置中的 baseUrl
+}
+
+export function useRequest() {
+ const loading = ref(false)
+ const appStore = useUserStore()
+
+
+
+
+ const request = async (config) => {
+ // 合并配置
+
+ const baseUrl = getBaseUrl();
+ let finalUrl = config.url.startsWith('http') ?
+ config.url :
+ `${baseUrl}${config.url.startsWith('/') ? '' : '/'}${config.url}`;
+
+ console.log('完整请求 URL:', finalUrl);
+ const mergedConfig = {
+ url: finalUrl,
+ timeout: 15000,
+ header: {
+ 'Content-Type': 'application/json',
+ 'X-Requested-With': 'XMLHttpRequest',
+ 'X-Client-Platform': uni.getSystemInfoSync().platform
+ },
+ method : config.method,
+ data : config.data,
+ showLoading : config.showLoading
+ }
+
+
+ // 请求拦截
+ if (appStore.token) {
+ mergedConfig.header.Authorization = `Bearer ${appStore.token}`
+ }
+
+ // 显示加载状态
+ if (mergedConfig.showLoading) {
+ loading.value = true
+ uni.showLoading({
+ title: '加载中...',
+ mask: true
+ })
+ }
+
+ try {
+ const response = await uni.request(mergedConfig)
+
+ // 响应拦截
+ if (response.statusCode === 401) {
+ handleUnauthorized()
+ throw new Error('登录状态已过期')
+ }
+
+ if (response.statusCode >= 400) {
+ throw new Error(`请求失败: ${response.data.message}`)
+ }
+
+ return response.data
+ } catch (error) {
+ // 统一错误处理
+ // handleRequestError(error, mergedConfig)
+ throw error
+ } finally {
+ if (mergedConfig.showLoading) {
+ loading.value = false
+ uni.hideLoading()
+ }
+ }
+ }
+
+ return {
+ request,
+ loading
+ }
+}
+
+// 处理未授权情况
+function handleUnauthorized() {
+ const appStore = useAppStore()
+ appStore.clearToken()
+
+ // 跳转到登录页(不同平台处理)
+ // #ifdef H5 || APP
+ uni.navigateTo({
+ url: '/pages/login/login'
+ })
+ // #endif
+
+ // #ifdef MP-WEIXIN
+ uni.reLaunch({
+ url: '/pages/login/login'
+ })
+ // #endif
+}
+
+// // 错误处理
+// function handleRequestError(error, config) {
+// console.error('请求错误:', error)
+
+// // 不显示静默请求的错误
+// if (config.silent) return
+
+// let message = '网络请求失败'
+
+// if (error.errMsg.includes('timeout')) {
+// message = '请求超时,请检查网络'
+// } else if (error.errMsg.includes('network')) {
+// message = '网络不可用,请检查连接'
+// }
+
+// uni.showToast({
+// title: message,
+// icon: 'none',
+// duration: 3000
+// })
+// }
\ No newline at end of file
diff --git a/frontend/index.html b/frontend/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..b5d330d136f2ef4198b59bfd92ec3dc44df9292e
--- /dev/null
+++ b/frontend/index.html
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/main.js b/frontend/main.js
new file mode 100644
index 0000000000000000000000000000000000000000..0291d9e679675a991fe6bc2232cf2bcb5ecb775d
--- /dev/null
+++ b/frontend/main.js
@@ -0,0 +1,27 @@
+import App from './App'
+
+// #ifndef VUE3
+import Vue from 'vue'
+import './uni.promisify.adaptor'
+Vue.config.productionTip = false
+App.mpType = 'app'
+const app = new Vue({
+ ...App
+})
+app.$mount()
+// #endif
+
+// #ifdef VUE3
+import { createSSRApp } from 'vue'
+import { createPinia } from 'pinia'
+export function createApp() {
+ const app = createSSRApp(App)
+ const pinia = createPinia()
+
+ app.use(pinia)
+ return {
+ app
+ }
+}
+// #endif
+
diff --git a/frontend/manifest.json b/frontend/manifest.json
new file mode 100644
index 0000000000000000000000000000000000000000..b6ebc917d08e827c2779537dbc4ff95a1ec67b65
--- /dev/null
+++ b/frontend/manifest.json
@@ -0,0 +1,75 @@
+{
+ "name" : "uniapp-ai",
+ "appid" : "__UNI__3924A7E",
+ "description" : "",
+ "versionName" : "1.0.0",
+ "versionCode" : "100",
+ "transformPx" : false,
+ /* 5+App特有相关 */
+ "app-plus" : {
+ "usingComponents" : true,
+ "nvueStyleCompiler" : "uni-app",
+ "compilerVersion" : 3,
+ "splashscreen" : {
+ "alwaysShowBeforeRender" : true,
+ "waiting" : true,
+ "autoclose" : true,
+ "delay" : 0
+ },
+ /* 模块配置 */
+ "modules" : {},
+ /* 应用发布信息 */
+ "distribute" : {
+ /* android打包配置 */
+ "android" : {
+ "permissions" : [
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ ""
+ ],
+ "minSdkVersion" : 21
+ },
+ /* ios打包配置 */
+ "ios" : {
+ "dSYMs" : false
+ },
+ /* SDK配置 */
+ "sdkConfigs" : {}
+ }
+ },
+ /* 快应用特有相关 */
+ "quickapp" : {},
+ /* 小程序特有相关 */
+ "mp-weixin" : {
+ "appid" : "",
+ "setting" : {
+ "urlCheck" : false
+ },
+ "usingComponents" : true
+ },
+ "mp-alipay" : {
+ "usingComponents" : true
+ },
+ "mp-baidu" : {
+ "usingComponents" : true
+ },
+ "mp-toutiao" : {
+ "usingComponents" : true
+ },
+ "uniStatistics" : {
+ "enable" : false
+ },
+ "vueVersion" : "3"
+}
diff --git a/frontend/package.json b/frontend/package.json
new file mode 100644
index 0000000000000000000000000000000000000000..2d55fc493db675e3a6e46f2515d12d6bc93fa911
--- /dev/null
+++ b/frontend/package.json
@@ -0,0 +1,5 @@
+{
+ "dependencies": {
+ "pinia": "^3.0.3"
+ }
+}
diff --git a/frontend/pages.json b/frontend/pages.json
new file mode 100644
index 0000000000000000000000000000000000000000..b79a08f187813cf5c80effa07b81d29bfa26cc50
--- /dev/null
+++ b/frontend/pages.json
@@ -0,0 +1,39 @@
+{
+ "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
+ {
+ "path" : "pages/login/login",
+ "style" :
+ {
+ "navigationBarTitleText" : ""
+ }
+ },
+ {
+ "path" : "pages/chat/chat",
+ "style" :
+ {
+ "navigationBarTitleText" : ""
+ }
+ },
+ {
+ "path" : "pages/register/register",
+ "style" :
+ {
+ "navigationBarTitleText" : ""
+ }
+ },
+ {
+ "path" : "pages/document/document",
+ "style" :
+ {
+ "navigationBarTitleText" : ""
+ }
+ }
+ ],
+ "globalStyle": {
+ "navigationBarTextStyle": "black",
+ "navigationBarTitleText": "uni-app",
+ "navigationBarBackgroundColor": "#F8F8F8",
+ "backgroundColor": "#F8F8F8"
+ },
+ "uniIdRouter": {}
+}
diff --git a/frontend/pages/chat/chat.vue b/frontend/pages/chat/chat.vue
new file mode 100644
index 0000000000000000000000000000000000000000..c1cf49e2b0a72544f8b5304c7ba2eb38c22ac949
--- /dev/null
+++ b/frontend/pages/chat/chat.vue
@@ -0,0 +1,687 @@
+
+
+
+
+
+ 历史对话
+
+ AI聊天
+
+ 新对话
+ 头像
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ msg.content }}
+
+
+
+ {{ msg.content }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/pages/document/document.vue b/frontend/pages/document/document.vue
new file mode 100644
index 0000000000000000000000000000000000000000..6e5f27a28dd0c7f61fb1de60a5c4a4ca30c4a549
--- /dev/null
+++ b/frontend/pages/document/document.vue
@@ -0,0 +1,138 @@
+
+
+
+ 文档上传
+ 上传你的文档以便进行智能问答
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/pages/login/login.vue b/frontend/pages/login/login.vue
new file mode 100644
index 0000000000000000000000000000000000000000..0686c71c734c2e6ffd454f4c1626e59732c7e2aa
--- /dev/null
+++ b/frontend/pages/login/login.vue
@@ -0,0 +1,216 @@
+
+
+
+
+
+
+
+
+ 用户名
+
+
+
+
+ 密码
+
+
+
+
+
+
+
+
+ 立即注册
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/pages/register/register.vue b/frontend/pages/register/register.vue
new file mode 100644
index 0000000000000000000000000000000000000000..32ad67aa336166a6d92614af024ef3ccd0cffd43
--- /dev/null
+++ b/frontend/pages/register/register.vue
@@ -0,0 +1,183 @@
+
+
+
+
+
+
+
+
+ 用户名
+
+
+
+
+ 邮箱
+
+
+
+
+ 密码
+
+
+
+
+ 确认密码
+
+
+
+
+
+
+ 返回登录
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/static/logo.png b/frontend/static/logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..b5771e209bb677e2ebd5ff766ad5ee11790f305a
Binary files /dev/null and b/frontend/static/logo.png differ
diff --git a/frontend/stores/User.js b/frontend/stores/User.js
new file mode 100644
index 0000000000000000000000000000000000000000..db04646909c6d3e35296ece11787651642616a62
--- /dev/null
+++ b/frontend/stores/User.js
@@ -0,0 +1,27 @@
+import {defineStore} from "pinia"
+import { ref } from "vue"
+
+export const useUserStore = defineStore("User",()=>{
+ const token = ref(uni.getStorageSync("token") || "")
+ const userId = ref( uni.getStorageSync("userId") || '')
+
+ const setToken = (newToken) => {
+ token.value = newToken
+ uni.setStorageSync('token', newToken)
+ }
+
+
+ const setUserId = (newUserId) => {
+ userId.value = newUserId
+ uni.setStorageSync('userId',newUserId)
+ }
+
+ const loginOut = () => {
+ token.value = ''
+ userId.value = ''
+ uni.removeStorageSync('userId')
+ uni.removeStorageSync('token')
+ }
+
+ return {userId,token,setToken,setUserId,loginOut}
+})
\ No newline at end of file
diff --git a/frontend/txt.txt b/frontend/txt.txt
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/frontend/uni.promisify.adaptor.js b/frontend/uni.promisify.adaptor.js
new file mode 100644
index 0000000000000000000000000000000000000000..5fec4f3304b8017e7da59574f948ceea6aafe116
--- /dev/null
+++ b/frontend/uni.promisify.adaptor.js
@@ -0,0 +1,13 @@
+uni.addInterceptor({
+ returnValue (res) {
+ if (!(!!res && (typeof res === "object" || typeof res === "function") && typeof res.then === "function")) {
+ return res;
+ }
+ return new Promise((resolve, reject) => {
+ res.then((res) => {
+ if (!res) return resolve(res)
+ return res[0] ? reject(res[0]) : resolve(res[1])
+ });
+ });
+ },
+});
\ No newline at end of file
diff --git a/frontend/uni.scss b/frontend/uni.scss
new file mode 100644
index 0000000000000000000000000000000000000000..b9249e9d9fab23b573e4add469e22710dce91e2a
--- /dev/null
+++ b/frontend/uni.scss
@@ -0,0 +1,76 @@
+/**
+ * 这里是uni-app内置的常用样式变量
+ *
+ * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
+ * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
+ *
+ */
+
+/**
+ * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
+ *
+ * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
+ */
+
+/* 颜色变量 */
+
+/* 行为相关颜色 */
+$uni-color-primary: #007aff;
+$uni-color-success: #4cd964;
+$uni-color-warning: #f0ad4e;
+$uni-color-error: #dd524d;
+
+/* 文字基本颜色 */
+$uni-text-color:#333;//基本色
+$uni-text-color-inverse:#fff;//反色
+$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
+$uni-text-color-placeholder: #808080;
+$uni-text-color-disable:#c0c0c0;
+
+/* 背景颜色 */
+$uni-bg-color:#ffffff;
+$uni-bg-color-grey:#f8f8f8;
+$uni-bg-color-hover:#f1f1f1;//点击状态颜色
+$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
+
+/* 边框颜色 */
+$uni-border-color:#c8c7cc;
+
+/* 尺寸变量 */
+
+/* 文字尺寸 */
+$uni-font-size-sm:12px;
+$uni-font-size-base:14px;
+$uni-font-size-lg:16px;
+
+/* 图片尺寸 */
+$uni-img-size-sm:20px;
+$uni-img-size-base:26px;
+$uni-img-size-lg:40px;
+
+/* Border Radius */
+$uni-border-radius-sm: 2px;
+$uni-border-radius-base: 3px;
+$uni-border-radius-lg: 6px;
+$uni-border-radius-circle: 50%;
+
+/* 水平间距 */
+$uni-spacing-row-sm: 5px;
+$uni-spacing-row-base: 10px;
+$uni-spacing-row-lg: 15px;
+
+/* 垂直间距 */
+$uni-spacing-col-sm: 4px;
+$uni-spacing-col-base: 8px;
+$uni-spacing-col-lg: 12px;
+
+/* 透明度 */
+$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
+
+/* 文章场景相关 */
+$uni-color-title: #2C405A; // 文章标题颜色
+$uni-font-size-title:20px;
+$uni-color-subtitle: #555555; // 二级标题颜色
+$uni-font-size-subtitle:26px;
+$uni-color-paragraph: #3F536E; // 文章段落颜色
+$uni-font-size-paragraph:15px;
diff --git a/frontend/vue.config.js b/frontend/vue.config.js
new file mode 100644
index 0000000000000000000000000000000000000000..5e0050114d90d91a013d80b39345bd3847b1ddc2
--- /dev/null
+++ b/frontend/vue.config.js
@@ -0,0 +1,13 @@
+module.exports = {
+ devServer: {
+ proxy: {
+ '/api': { // 代理所有以/api开头的请求
+ target: 'http://localhost:5101', // 后端服务器地址
+ changeOrigin: true,
+ pathRewrite: {
+ '^/api': '/api' // 将路径中的/api保留
+ }
+ }
+ }
+ }
+}
\ No newline at end of file