diff --git a/.env b/.env new file mode 100644 index 0000000..14faf22 --- /dev/null +++ b/.env @@ -0,0 +1 @@ +VITE_APP_BASE_API = 'https://aw.9miao.fun/prod-api' \ No newline at end of file diff --git a/index.html b/index.html index 99f583a..afbe082 100644 --- a/index.html +++ b/index.html @@ -4,6 +4,7 @@ + Vite App diff --git a/package-lock.json b/package-lock.json index 5866c4c..42f6580 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "zt-sys", "version": "0.0.0", "dependencies": { + "@element-plus/icons-vue": "^2.3.1", "axios": "^1.7.2", "element-plus": "^2.7.7", "pinia": "^2.1.7", diff --git a/package.json b/package.json index 456ba42..c696075 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore" }, "dependencies": { + "@element-plus/icons-vue": "^2.3.1", "axios": "^1.7.2", "element-plus": "^2.7.7", "pinia": "^2.1.7", diff --git a/src/api/question/question.js b/src/api/question/question.js new file mode 100644 index 0000000..69379b8 --- /dev/null +++ b/src/api/question/question.js @@ -0,0 +1,25 @@ +import http from "@/utils/http"; +//获取题目 +export const getQuestion= (type)=>{ + if(type==null||type==undefined){ + type="refresh"; + } + return http({ + url:"/question/getQuestion", + method:"get", + params:{ + type + }, + }) +} +//注册 +export const validationAnswer= (user)=>{ + return http({ + url:"/question/validationAnswer", + method:"get", + data:user, + headers:{ + isToken:false + } + }) +} \ No newline at end of file diff --git a/src/api/user/user.js b/src/api/user/user.js new file mode 100644 index 0000000..05ef924 --- /dev/null +++ b/src/api/user/user.js @@ -0,0 +1,38 @@ +import http from "@/utils/http"; +//登录 +export const login= (user)=>{ + return http({ + url:"/user/login", + method:"post", + data:user, + headers:{ + isToken:false + } + }) +} +//注册 +export const register= (user)=>{ + return http({ + url:"/user/register", + method:"post", + data:user, + headers:{ + isToken:false + } + }) +} +//获取用户信息 +export const getUserInfo= ()=>{ + return http({ + url:"/user", + method:"get" + }) +} +//修改用户信息 +export const updateUserInfo= (user)=>{ + return http.request({ + url:"/user/update", + method:"post", + params:user + }) +} diff --git a/src/assets/image/tibg.jpg b/src/assets/image/tibg.jpg new file mode 100644 index 0000000..2d3016c Binary files /dev/null and b/src/assets/image/tibg.jpg differ diff --git a/src/assets/image/userbg.jpg b/src/assets/image/userbg.jpg new file mode 100644 index 0000000..e0e9f3e Binary files /dev/null and b/src/assets/image/userbg.jpg differ diff --git a/src/components/HelloWorld.vue b/src/components/HelloWorld.vue deleted file mode 100644 index 5fb372c..0000000 --- a/src/components/HelloWorld.vue +++ /dev/null @@ -1,44 +0,0 @@ - - - - - diff --git a/src/components/TheWelcome.vue b/src/components/TheWelcome.vue deleted file mode 100644 index dab9536..0000000 --- a/src/components/TheWelcome.vue +++ /dev/null @@ -1,88 +0,0 @@ - - - diff --git a/src/components/TopicBox.vue b/src/components/TopicBox.vue new file mode 100644 index 0000000..9d02339 --- /dev/null +++ b/src/components/TopicBox.vue @@ -0,0 +1,63 @@ + + + + diff --git a/src/components/TypeSelect.vue b/src/components/TypeSelect.vue new file mode 100644 index 0000000..9230142 --- /dev/null +++ b/src/components/TypeSelect.vue @@ -0,0 +1,51 @@ + + + + \ No newline at end of file diff --git a/src/components/VideoBox.vue b/src/components/VideoBox.vue new file mode 100644 index 0000000..06fdd62 --- /dev/null +++ b/src/components/VideoBox.vue @@ -0,0 +1,62 @@ + + + + + \ No newline at end of file diff --git a/src/components/WelcomeItem.vue b/src/components/WelcomeItem.vue deleted file mode 100644 index ac366d0..0000000 --- a/src/components/WelcomeItem.vue +++ /dev/null @@ -1,86 +0,0 @@ - - - diff --git a/src/components/icons/IconCommunity.vue b/src/components/icons/IconCommunity.vue deleted file mode 100644 index 2dc8b05..0000000 --- a/src/components/icons/IconCommunity.vue +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/src/components/icons/IconDocumentation.vue b/src/components/icons/IconDocumentation.vue deleted file mode 100644 index 6d4791c..0000000 --- a/src/components/icons/IconDocumentation.vue +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/src/components/icons/IconEcosystem.vue b/src/components/icons/IconEcosystem.vue deleted file mode 100644 index c3a4f07..0000000 --- a/src/components/icons/IconEcosystem.vue +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/src/components/icons/IconSupport.vue b/src/components/icons/IconSupport.vue deleted file mode 100644 index 7452834..0000000 --- a/src/components/icons/IconSupport.vue +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/src/components/icons/IconTooling.vue b/src/components/icons/IconTooling.vue deleted file mode 100644 index 660598d..0000000 --- a/src/components/icons/IconTooling.vue +++ /dev/null @@ -1,19 +0,0 @@ - - diff --git a/src/main.js b/src/main.js index 698f0a1..582fad2 100644 --- a/src/main.js +++ b/src/main.js @@ -6,11 +6,16 @@ import ElementPlus from 'element-plus' import App from './App.vue' import router from './router' +// 如果您正在使用CDN引入,请删除下面一行。 +import * as ElementPlusIconsVue from '@element-plus/icons-vue' const app = createApp(App) app.use(createPinia()) app.use(router) app.use(ElementPlus, { size: 'small', zIndex: 3000 }) +for (const [key, component] of Object.entries(ElementPlusIconsVue)) { + app.component(key, component) + } app.mount('#app') diff --git a/src/utils/Sotrage.js b/src/utils/Sotrage.js new file mode 100644 index 0000000..321194b --- /dev/null +++ b/src/utils/Sotrage.js @@ -0,0 +1,12 @@ +const storage ={ + setStorage:function(key,value){ + window.localStorage.setItem(key,JSON.stringify(value)) + }, + getStorage:function(key){ + return JSON.parse(window.localStorage.getItem(key)) + }, + removeStorage:function(key){ + window.localStorage.removeItem(key) + } +} +export default storage \ No newline at end of file diff --git a/src/utils/http.js b/src/utils/http.js new file mode 100644 index 0000000..dcc2ab6 --- /dev/null +++ b/src/utils/http.js @@ -0,0 +1,35 @@ +import axios from 'axios' +import { ElMessage } from 'element-plus' +import 'element-plus/theme-chalk/el-message.css' +import TokenService from '@/utils/token' +import router from '@/router' +axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8' +const httpInstance=axios.create({ + baseURL: import.meta.env.VITE_APP_BASE_API, + timeout: 10000 +}) +// axios请求拦截器 +httpInstance.interceptors.request.use(config => { + // 是否需要设置 token + const isToken = (config.headers || {}).isToken === false + if (TokenService.hasToken() && !isToken) { + config.headers['Authorization'] = TokenService.getToken() // 让每个请求携带自定义token 请根据实际情况自行修改 + } + return config + }, e => Promise.reject(e)) + +// axios响应式拦截器 +httpInstance.interceptors.response.use(res => { +if (res.data.code === 401){ + router.push('/login') +} +if(res.data.code==0){ +ElMessage.error(res.data.msg) +} +return res.data +}, e => { +return Promise.reject(e) +}) +// let abb=1; +export default httpInstance; + diff --git a/src/utils/request.js b/src/utils/request.js deleted file mode 100644 index f0989e4..0000000 --- a/src/utils/request.js +++ /dev/null @@ -1,154 +0,0 @@ -import axios from 'axios' -import { ElNotification , ElMessageBox, ElMessage, ElLoading } from 'element-plus' -import 'element-plus/theme-chalk/el-message.css' -import 'element-plus/theme-chalk/el-message-box.css' -import { getToken } from '@/utils/auth' -import errorCode from '@/utils/errorCode' -import { tansParams, blobValidate } from '@/utils/ruoyi' -import cache from '@/plugins/cache' -import { saveAs } from 'file-saver' -import useUserStore from '@/store/modules/user' - -let downloadLoadingInstance; -// 是否显示重新登录 -export let isRelogin = { show: false }; - -axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8' -// 创建axios实例 -const service = axios.create({ - // axios中请求配置有baseURL选项,表示请求URL公共部分 - baseURL: import.meta.env.VITE_APP_BASE_API, - // 超时 - timeout: 10000 -}) - -// request拦截器 -service.interceptors.request.use(config => { - // 是否需要设置 token - const isToken = (config.headers || {}).isToken === false - // 是否需要防止数据重复提交 - const isRepeatSubmit = (config.headers || {}).repeatSubmit === false - if (getToken() && !isToken) { - config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改 - } - // get请求映射params参数 - if (config.method === 'get' && config.params) { - let url = config.url + '?' + tansParams(config.params); - url = url.slice(0, -1); - config.params = {}; - config.url = url; - } - if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) { - const requestObj = { - url: config.url, - data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data, - time: new Date().getTime() - } - const requestSize = Object.keys(JSON.stringify(requestObj)).length; // 请求数据大小 - const limitSize = 5 * 1024 * 1024; // 限制存放数据5M - if (requestSize >= limitSize) { - console.warn(`[${config.url}]: ` + '请求数据大小超出允许的5M限制,无法进行防重复提交验证。') - return config; - } - const sessionObj = cache.session.getJSON('sessionObj') - if (sessionObj === undefined || sessionObj === null || sessionObj === '') { - cache.session.setJSON('sessionObj', requestObj) - } else { - const s_url = sessionObj.url; // 请求地址 - const s_data = sessionObj.data; // 请求数据 - const s_time = sessionObj.time; // 请求时间 - const interval = 1000; // 间隔时间(ms),小于此时间视为重复提交 - if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) { - const message = '数据正在处理,请勿重复提交'; - console.warn(`[${s_url}]: ` + message) - return Promise.reject(new Error(message)) - } else { - cache.session.setJSON('sessionObj', requestObj) - } - } - } - return config -}, error => { - console.log(error) - Promise.reject(error) -}) - -// 响应拦截器 -service.interceptors.response.use(res => { - // 未设置状态码则默认成功状态 - const code = res.data.code || 200; - // 获取错误信息 - const msg = errorCode[code] || res.data.msg || errorCode['default'] - // 二进制数据则直接返回 - if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') { - return res.data - } - if (code === 401) { - if (!isRelogin.show) { - isRelogin.show = true; - ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => { - isRelogin.show = false; - useUserStore().logOut().then(() => { - location.href = '/index'; - }) - }).catch(() => { - isRelogin.show = false; - }); - } - return Promise.reject('无效的会话,或者会话已过期,请重新登录。') - } else if (code === 500) { - ElMessage({ message: msg, type: 'error' }) - return Promise.reject(new Error(msg)) - } else if (code === 601) { - ElMessage({ message: msg, type: 'warning' }) - return Promise.reject(new Error(msg)) - } else if (code !== 200) { - ElNotification.error({ title: msg }) - return Promise.reject('error') - } else { - return Promise.resolve(res.data) - } - }, - error => { - console.log('err' + error) - let { message } = error; - if (message == "Network Error") { - message = "后端接口连接异常"; - } else if (message.includes("timeout")) { - message = "系统接口请求超时"; - } else if (message.includes("Request failed with status code")) { - message = "系统接口" + message.substr(message.length - 3) + "异常"; - } - ElMessage({ message: message, type: 'error', duration: 5 * 1000 }) - return Promise.reject(error) - } -) - -// 通用下载方法 -export function download(url, params, filename, config) { - downloadLoadingInstance = ElLoading.service({ text: "正在下载数据,请稍候", background: "rgba(0, 0, 0, 0.7)", }) - return service.post(url, params, { - transformRequest: [(params) => { return tansParams(params) }], - headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, - responseType: 'blob', - ...config - }).then(async (data) => { - const isBlob = blobValidate(data); - if (isBlob) { - const blob = new Blob([data]) - saveAs(blob, filename) - } else { - const resText = await data.text(); - const rspObj = JSON.parse(resText); - const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default'] - ElMessage.error(errMsg); - } - downloadLoadingInstance.close(); - }).catch((r) => { - console.error(r) - ElMessage.error('下载文件出现错误,请联系管理员!') - downloadLoadingInstance.close(); - }) -} - -export default service diff --git a/src/views/home/index.vue b/src/views/home/index.vue index 490ef16..d07cfe9 100644 --- a/src/views/home/index.vue +++ b/src/views/home/index.vue @@ -1,8 +1,309 @@ - - - - \ No newline at end of file +
+ +
+
+
+
+
+ +
+
+
+
+
+
视频
+
解析
+
+ + + +
+
+
+ +
+
+
+
+
+ + + diff --git a/src/views/login/index.vue b/src/views/login/index.vue index 869a44a..06c5849 100644 --- a/src/views/login/index.vue +++ b/src/views/login/index.vue @@ -5,7 +5,7 @@
密码
记住密码
- 登录 + 登录 import {ElMessage} from "element-plus"; import 'element-plus/theme-chalk/el-message.css' -import 'element-plus/theme-chalk/el-message-box.css' -import { ref, reactive } from "vue"; +import { login , register } from "@/api/user/user"; +import storage from '@/utils/Sotrage' +import TokenService from '@/utils/token' +import router from '@/router' +import { ref, reactive,onMounted } from "vue"; const user=reactive({ username: "", password: "", }); //是否记住密码 const remember = ref(false); -const login = () => { - if(user.username===""||user.password===""){ - ElMessage({ message: "请输入完整信息", type: 'warning' }) - } +const toLogin = async () => { console.log(user); + if(user.username===""||user.username===null||user.password===""||user.password===null){ + ElMessage({ message: "请输入完整信息", type: 'warning' }) + } + + let res=await login(user); +if(res.code===200){ + ElMessage({ message: "登录成功", type: 'success' }) + if(remember.value){ + storage.setStorage("username",user.username); + storage.setStorage("password",user.password); + }else{ + storage.removeStorage("username"); + storage.removeStorage("password"); + } + TokenService.saveToken(res.token) + //跳转 + router.push('/'); +} }; //表单弹窗开关 const dialogFormVisible = ref(false); @@ -146,10 +164,10 @@ const ruleForm = reactive({ }); //表单验证 const usernamevalidate = (rule, value, callback) => { - if (value === "") { + if (value === ""||value==null) { callback(new Error("请输入账号")); - callback(); } + callback(); }; const validatePass = (rule, value, callback) => { if (value === "") { @@ -189,13 +207,25 @@ const rules = reactive({ //提交注册 const submitForm = (formEl) => { if (!formEl) return; - formEl.validate((valid) => { + formEl.validate(async(valid) => { if (valid) { - console.log("submit!"); + // console.log("submit!"); + let res =await register({username:ruleForm.username,password:ruleForm.password}); + if(res.code===200){ + ElMessage({ message: "注册成功", type: 'success' }) + dialogFormVisible.value=false; + }else{ + ElMessage({ message: res.msg, type: 'error' }) + } } else { console.log("error submit!"); } }); }; +onMounted(() => { + console.log("onMounted"); + user.username=storage.getStorage("username"); + user.password=storage.getStorage("password"); +}); diff --git a/src/views/user/index.vue b/src/views/user/index.vue index a528450..f890d35 100644 --- a/src/views/user/index.vue +++ b/src/views/user/index.vue @@ -1,8 +1,108 @@ - - - - \ No newline at end of file +
+
+
+ +
+
用户名
+
返回首页
+
+
+
收藏
+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + +