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 @@ + + + + + \ 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