项目计划(3)
整合接口文档
开发搜索结果页
开发登录页
开发用户信息修改接口
开发主页
整合接口文档
Knife4j 对 Swagger UI 进行了增强,提供了更加美观的页面
官方文档:https://doc.xiaominfo.com/docs/quick-start
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>4.4.0</version>
</dependency>
knife4j文档访问地址:http://ip:port/doc.html
搜索结果页
选择好标签后,点击开始找伙伴,路由到搜索结果页面,而且把选择的标签传递过来
Axios请求后端接口(根据标签搜索用户)
-
Axios文档:https://www.axios-http.cn/docs/example
-
npm 安装
-
配置
import axios from "axios"; const myAxios = axios.create({ baseURL: 'http://localhost:8081/circle', }); // 添加请求拦截器 myAxios.interceptors.request.use(function (config) { // 在发送请求之前做些什么 return config; }, function (error) { // 对请求错误做些什么 return Promise.reject(error); }); // 添加响应拦截器 myAxios.interceptors.response.use(function (response) { // 2xx 范围内的状态码都会触发该函数。 // 对响应数据做点什么 return response.data.data; }, function (error) { // 超出 2xx 范围的状态码都会触发该函数。 // 对响应错误做点什么 return Promise.reject(error); }); export default myAxios;
展示数据,使用vant组件(商品卡片)
<template>
<van-card
v-for="user in userList"
:title="user.nickname"
:desc="user.profile"
:thumb="user.avatarUrl"
>
<template #tags>
<van-tag plain type="primary" v-for="tag in user.tags" style="margin-right: 8px; margin-top: 8px" >
{{ tag }}
</van-tag>
</template>
<template #footer>
<van-button size="small" color="#1989FA" plain>立即联系</van-button>
</template>
</van-card>
<van-empty v-if="!userList || userList.length <= 0" description="搜索结果为空" />
</template>
<script setup lang='ts'>
import { useRoute } from 'vue-router';
import { onMounted, ref } from 'vue';
import { UserType } from '../models/user';
import myAxios from '../plugins/myAxios';
import qs from 'qs';
const route = useRoute();
const tag = route.query.tag as string;
const userList = ref<UserType[]>([]);
onMounted( async () => {
try{
const userListData: UserType[] = await myAxios.get('/user/search/tags', {
params: {
tagNameList: tag
},
paramsSerializer: function(params) {
return qs.stringify(params, {arrayFormat: 'repeat'})
}
})
if(userListData){
userListData.forEach(user =>{
if (typeof user.tags === 'string') {
try {
user.tags = JSON.parse(user.tags);
} catch (error) {
console.error('Failed to parse user tags:', error);
}
}
})
userList.value = userListData;
}
console.log('/user/search/tags success');
console.log(userListData);
}catch(error){
console.log('/user/search/tags error');
console.log(error);
}
})
</script>
<style scoped>
</style>
开发登录页面
用户信息获取
<template>
<template v-if="user">
<div class="banner"></div>
<div class="part1">
<div class="face">
<van-image
round
width=87px
height=87px
fit="cover"
:src="user.avatarUrl"
/>
</div>
<div class="relation">
<div class="count">
<van-row justify="space-around">
<van-col span="6">关注</van-col>
<van-col span="6">粉丝</van-col>
<van-col span="6">获赞</van-col>
</van-row>
</div>
<van-button plain type="primary" class="follow-btn" @click="router.push('/userinfo')">编辑资料</van-button>
</div>
</div>
<div class="part2">
<div class="base">{{user.nickname}}</div>
<div class="profile">{{user.profile}}</div>
<div class="tags" v-for="tag in user.tags">
<van-tag plain type="primary">{{ tag }}</van-tag>
</div>
</div>
<van-tabs v-model:active="active" class="tabs">
<van-tab title="动态">动态</van-tab>
<van-tab title="我创建的队伍">我创建的队伍</van-tab>
<van-tab title="我加入的队伍">我加入的队伍</van-tab>
</van-tabs>
</template>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue';
import myAxios from '../plugins/myAxios';
import { useRouter } from 'vue-router';
import { showFailToast } from 'vant';
const active = ref(0);
const user = ref();
const router = useRouter();
onMounted( async () => {
const res = await myAxios.get('/user/current')
if(res.code === 0 && res.data){
user.value = res.data;
user.value.tags = JSON.parse(user.value.tags); // json格式字符串转换为数组
}else{
showFailToast('获取用户信息失败');
}
})
</script>
<style scoped>
.banner{
width: 100%;
height: 100px;
background-image: url(https://typora--images.oss-cn-beijing.aliyuncs.com/%E4%B8%8B%E8%BD%BD.png);
background-size: contain;
}
.part1{
width: 100%;
height: 80px;
display: flex;
/* justify-content: center;
align-items: center; */
background-color: #fff;
position: relative
}
.face{
flex: 1;
margin: -30px 0px 0px 20px;
}
.relation{
flex: 1.5;
padding: 5px 10px 5px 10px;
/* width: 100%;
height: 100px; */
}
/* .count{
} */
.follow-btn{
width: 100%;
height: 30px;
margin-top: 10px;
border-radius: 4px;
}
.tabs{
border: 3px grey;
}
.part2{
padding: 10px 10px 10px 10px;
background-color: #fff;
}
.base{
font-size: 18px;
}
.profile{
font-size: 12px;
color: #999;
margin-top: 10px;
}
</style>