Compare commits
4 Commits
bdae2cbd63
...
ea9d06a5ad
Author | SHA1 | Date |
---|---|---|
虾壳 | ea9d06a5ad | |
虾壳 | 0c1bceb97b | |
虾壳 | ed69b64f3c | |
虾壳 | ccfee1d011 |
|
@ -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
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
import http from "@/utils/http";
|
||||||
|
//获取标签名
|
||||||
|
export const getTags= (tagName)=>{
|
||||||
|
return http({
|
||||||
|
url:"/tag/getTags",
|
||||||
|
method:"get",
|
||||||
|
params:{
|
||||||
|
tagName
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
|
@ -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'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
|
@ -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
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 }
|
||||||
|
// })
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
};
|
|
@ -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>
|
||||||
|
@ -76,8 +119,8 @@
|
||||||
scrollbar-width: none; /* Firefox */
|
scrollbar-width: none; /* Firefox */
|
||||||
-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>
|
||||||
|
|
Loading…
Reference in New Issue