Compare commits

..

4 Commits

Author SHA1 Message Date
虾壳 ea9d06a5ad 合并 2024-07-17 20:25:59 +08:00
虾壳 0c1bceb97b Merge remote-tracking branch 'origin/main'
# Conflicts:
#	src/views/home/index.vue
#	src/views/login/index.vue
2024-07-17 19:42:02 +08:00
虾壳 ed69b64f3c 111111 2024-07-17 19:37:16 +08:00
虾壳 ccfee1d011 111111 2024-07-17 19:36:45 +08:00
10 changed files with 326 additions and 42 deletions

View File

@ -12,14 +12,17 @@ export const getQuestion= (type)=>{
}, },
}) })
} }
//注册 //验证题目是否正确
export const validationAnswer= (user)=>{ export const checkQuestion= ({
questionId,
answer
})=>{
return http({ return http({
url:"/question/validationAnswer", url:"/question/validationAnswer",
method:"get", method:"get",
data:user, params:{
headers:{ questionId,
isToken:false answer
} }
}) })
} }

11
src/api/tag/tag.js Normal file
View File

@ -0,0 +1,11 @@
import http from "@/utils/http";
//获取标签名
export const getTags= (tagName)=>{
return http({
url:"/tag/getTags",
method:"get",
params:{
tagName
},
})
}

18
src/api/upload/upload.js Normal file
View File

@ -0,0 +1,18 @@
import httpInstance from '@/utils/http'
export const uploadImage = (file) => {
// 创建一个 FormData 对象
const formData = new FormData();
// 将文件添加到 FormData
formData.append('file', file);
// 发送 POST 请求
return httpInstance({
url: `/QiNiu/upload`,
method: "post",
data: formData, // 将 FormData 对象作为请求体
headers: {
'Content-Type': 'multipart/form-data'
}
});
}

View File

@ -33,6 +33,6 @@ export const updateUserInfo= (user)=>{
return http.request({ return http.request({
url:"/user/update", url:"/user/update",
method:"post", method:"post",
params:user data:user
}) })
} }

View File

@ -0,0 +1,124 @@
<template>
<div class="img-upload">
<input v-show="0 != 0" ref="input" type="file" name="image" accept="image/*" @change="upload" :v-model="file">
<!-- <el-button type="" @click="uploadClick">上传</el-button> -->
<!-- <div v-if="imageUrl == ''" class="img-upload-box" @click="uploadClick">
<p>+</p>
</div> -->
<!-- <img class="img-img" v-if="imageUrl!=''" :src="imageUrl" alt="" style="height: 100%;"> -->
<el-image class="img-img" v-if="imageUrl != ''" style="height:100%" :src="imageUrl" :zoom-rate="1.2" :max-scale="7" :min-scale="0.2"
:preview-src-list="[imageUrl]" fit="cover" />
<el-button v-if="imageUrl != ''" type="primary" class="img-button" @click="uploadClick">修改头像</el-button>
</div>
</template>
<style lang="scss" scoped>
.img-upload {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
position: relative;
border: 1px solid #ebeef5;
}
.img-img:hover + .img-button {
display: block;
}
.img-button{
position: absolute;
bottom: 0;
left: 0;
right: 0;
margin: 0 auto;
width: 100px;
height: 30px;
margin-bottom: 10px;
display: none;
}
.img-upload-box {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
background-color: #ffffff;
}
</style>
<script setup>
import { uploadImage } from '@/api/upload/upload';
import { ref, watch } from 'vue';
//
const emit = defineEmits(['upload']);
const props=defineProps({
img:{
type:String,
default:''
}
})
watch(props.img,(newV)=>{
if(newV!=null){
console.log("传入了图片")
imageUrl.value=newV;
}
},{
deep: true})
// const
// eslint-disable-next-line no-unused-vars
//
const file = ref(null);
//dom
const input = ref(null);
//url
const imageUrl = ref('');
//
const uploadClick = () => {
input.value.click();
}
//
const toUploadImage = async () => {
let res = await uploadImage(file.value);
if (res.code == 1) {
//
return res.data;
}
return null;
}
const upload = async (e) => {
let imgMaxSize = 1024 * 1024 * 4;
if (e.target.files[0].size > imgMaxSize) {
alert("图片大小不能超过4M");
return;
}
if (['jpeg', 'png', 'gif', 'jpg'].indexOf(e.target.files[0].type.split("/")[1]) < 0) {
//
alert("上传的文件必须是图片格式");
return;
}
file.value = e.target.files[0];
// alert("");
let url = await toUploadImage();
if (url != null) {
imageUrl.value = url;
emit('upload', url);
} else {
alert("上传失败");
}
}
const updateUrl=(img)=>{
file.value=null;
if(img==null){
imageUrl.value='';
return ;
}
imageUrl.value=img;
}
//
defineExpose(
{
updateUrl
}
)
</script>

View File

@ -1,5 +1,6 @@
<template> <template>
<div class="word-list"> <div class="word-list">
<!-- {{ props.type }}{{ props }} -->
<div <div
v-for="word in words" v-for="word in words"
:key="word" :key="word"
@ -8,12 +9,36 @@
> >
{{ word }} {{ word }}
</div> </div>
</div> </div>
</template> </template>
<script setup> <script setup>
import { ref } from 'vue'; import { onMounted, ref ,watch} from 'vue';
import { getTags } from "@/api/tag/tag";
const emit=defineEmits(['select']) const emit=defineEmits(['select'])
const props=defineProps({
type:{
type:String,
default:''
}
})
const getWords=async(type)=>{
let res=await getTags(type);
if(res.code==200){
words.value=res.data.map(itme=>itme.name);
if(words.value.length==0){
words.value=['暂无数据']
}
}
}
watch(() => props.type,(newValue)=>{
getWords(newValue);
console.log("props",newValue);
},{
//
deep: true, //
})
// //
const words = ref([ const words = ref([
'高数上', '高数下', '线性代数', '数学分析', '解析几何', '高数上', '高数下', '线性代数', '数学分析', '解析几何',
@ -32,6 +57,9 @@
emit('select',word); emit('select',word);
// //
}; };
onMounted(()=>{
getWords();
})
</script> </script>
<style scoped> <style scoped>
.word-list { .word-list {

View File

@ -2,34 +2,21 @@
<div class="nav"> <div class="nav">
<div class="logo-box"><span class="loogText">Xuaua</span></div> <div class="logo-box"><span class="loogText">Xuaua</span></div>
<div> <div>
<div class="search-box">
<!-- <el-input type="text" prefix-icon="el-icon-search" style="height: 38px;" class="search-input" placeholder="搜索关键词" v-model="selectType">
</el-input> -->
<el-input
v-model="input3"
style="max-width: 600px"
placeholder="搜索关键词"
class="input-with-select"
>
<template #prepend>
<el-button :icon="Search" />
</template>
</el-input>
</div>
<el-popover :width="700" trigger="click"> <el-popover :width="700" trigger="click">
<template #reference> <template #reference>
<!-- <div class="selectInput"> <div class="search-box">
<div class="selectInput">
<div @click="selectClick"> <div @click="selectClick">
<el-icon :size="size" :color="color"> <el-icon :size="size" :color="color">
<Search /> <Search />
</el-icon> </el-icon>
</div> </div>
</div> --> <input type="text" placeholder="搜索关键词" v-model="type" />
</div>
</div>
</template> </template>
<TypeSelect @select="selectInput"></TypeSelect> <TypeSelect @select="selectInput" :type="type"></TypeSelect>
</el-popover> </el-popover>
</div> </div>
<div @click="router.push('/user')" class="user-avatar"> <div @click="router.push('/user')" class="user-avatar">
@ -39,12 +26,29 @@
</template> </template>
<script setup> <script setup>
// import {defineProps} from "vue" // import {defineProps} from "vue"
import { ElMessage } from "element-plus";
import TypeSelect from "@/components/TypeSelect.vue"; import TypeSelect from "@/components/TypeSelect.vue";
import { debounceRef } from "@/utils/debounceRef";
import { ref } from 'vue' import { ref } from 'vue'
import { Search } from '@element-plus/icons-vue' import { Search } from '@element-plus/icons-vue'
const type = debounceRef('', 500);
</script> </script>
<style lang="scss"> <style lang="scss" scoped>
.selectInput {
display: flex;
width: 100%;
height: 100%;
padding: 7px 10px;
border: 2px #000000 solid;
border-radius: 30px;
input {
background-color: #00000000; /* 透明背景 */
border: none; /* 无边框 */
outline: none; /* 去除聚焦时的轮廓 */
padding: 0; /* 无内边距 */
margin: 0; /* 无外边距 */
width: 100%;
}
}
.nav { .nav {
width: 100%; width: 100%;
height: 70px; height: 70px;

9
src/stores/TopicBox.js Normal file
View File

@ -0,0 +1,9 @@
// import { ref, computed } from 'vue'
// import { defineStore } from 'pinia'
// export const useCounterStore = defineStore('useTopicBox', () => {
// const index = ref(1);
// const Topics=ref([]);
// const count = computed(()=>Topics.value.length);
// return { count, doubleCount, increment }
// })

24
src/utils/debounceRef.js Normal file
View File

@ -0,0 +1,24 @@
import { customRef } from "vue";
/**
* 防抖Ref
* @param {} value
* @param {*} delay
* @returns
*/
export const debounceRef = (value, delay = 1000) => {
let timeout;
return customRef((track,trigger)=>({
get () {
track();
return value;
},
set (val) {
clearTimeout(timeout);
timeout = setTimeout(() => {
value = val;
trigger();
}, delay);
}
}))
};

View File

@ -1,27 +1,70 @@
<template> <template>
<div class="userBox"> <div class="userBox">
<div class="userInfo"> <div class="userInfo">
<div class="userT"> <div class="userT" @click="drawer = true">
<el-avatar :size="150" :src="circleUrl" /> <el-avatar :size="150" :src="circleUrl" />
</div> </div>
<div class="userName">用户名</div> <div class="userName">用户名</div>
<div class="userName" @click="router.push('/');">返回首页</div> <div class="userName" @click="router.push('/')">返回首页</div>
</div> </div>
<div class="collectionTopic"> <div class="collectionTopic">
<div class="title">收藏</div> <div class="title">收藏</div>
<div class="collectionList"> <div class="collectionList">
<div class="collectionTme"></div>
<div class="collectionTme"></div>
<div class="collectionTme"></div>
<div class="collectionTme"></div>
<div class="collectionTme"></div>
<div class="collectionTme"></div>
<div class="collectionTme"></div>
<div class="collectionTme"></div> <div class="collectionTme"></div>
<!-- <div class="collectionTme"></div> --> <!-- <div class="collectionTme"></div> -->
</div> </div>
</div> </div>
</div> </div>
<el-drawer
v-model="drawer"
title="个人信息"
direction="ltr"
:before-close="handleClose"
>
<div class="info">
<div class="infoItme">
<image-upload
ref="imgUpload"
img="123"
style="width: 200px; height: 200px; display: inline-block"
@upload="upload"
></image-upload>
</div>
<div class="infoItme">
<div class="text">账号</div>
<el-input
v-model="input"
style="width: 240px"
placeholder="Please input"
:disabled="true"
/>
</div>
<div class="infoItme">
<div class="text">签名</div>
<el-input
v-model="input"
style="width: 240px"
placeholder="Please input"
:rows="2"
type="textarea"
:disabled="true"
/>
</div>
<div class="infoItme">
<div class="text">手机号</div>
<el-input
v-model="input"
style="width: 240px"
placeholder="Please input"
:disabled="true"
/>
</div>
</div>
<template #footer>
<el-button type="success">更改信息</el-button>
<el-button type="danger">更改密码</el-button>
</template>
</el-drawer>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -77,7 +120,7 @@
-ms-overflow-style: none; /* IE 10+ */ -ms-overflow-style: none; /* IE 10+ */
::-webkit-scrollbar { ::-webkit-scrollbar {
display: none; /* Chrome Safari */ display: none; /* Chrome Safari */
} }
flex: 1; flex: 1;
width: 90%; width: 90%;
box-sizing: border-box; box-sizing: border-box;
@ -89,7 +132,7 @@
/* 宽度是固定好的 */ /* 宽度是固定好的 */
width: 30%; width: 30%;
height: 47%; height: 47%;
background-color: #D2FCE3; background-color: #d2fce3;
margin-bottom: 10px; margin-bottom: 10px;
// border: 1px solid red; // border: 1px solid red;
/*这个数值需要自己去调*/ /*这个数值需要自己去调*/
@ -102,7 +145,27 @@
} }
} }
} }
.infoItme {
display: flex;
justify-content: center;
width: 80%;
margin: 20px auto;
.text {
width: 30%;
text-align: right;
margin-right: 30px;
}
}
.info {
width: 100%;
display: flex;
justify-content: center;
flex-direction: column;
}
</style> </style>
<script setup> <script setup>
import router from '@/router' import router from "@/router";
import ImageUpload from "@/components/ImageUpload.vue";
import { ref } from "vue";
const drawer = ref(false);
</script> </script>