1624 字
8 分钟
伙伴匹配项目总结
第一部分
使用vite进行项目的初始化,node版本需要与其匹配,可以下载nvm来进行node版本的管理。
yarn create vite
使用vant进行前端页面的布局不限于导航栏,tab栏的搭建。
设计数据库表,分析需要哪些字段。
用户表的添加tag字段
- 关联表:
- 优点:查询灵活,可以正查,反查
- 缺点:需要多建一个表,多维护一个表
- 尽量减少关联查询。
- 往用户表中添加json字符串来补充tag字段。
- 优点:查询方便,不用新建表,标签是固有属性节省开发成本。
- 如果性能低可以用缓存。
- 具体情况根据需求具体分析,选择合适的。
- 关联表:
开发后端接口
搜索标签
- 允许用户传入多个标签,多个标签都存在才搜索出来,and。代码举例:like ‘%Java%’ and like ‘%C++%’。
- 允许用户传入多个标签,有任何一个标签存在就能搜索出来 or。代码举例:like ‘%Java%’ or like ‘%C++%’。
两种方式
- SQL查询(实现简单,可以通过拆分查询进一步优化)
- 内存查询(灵活,可以通过并发进一步优化)
选择场景
- 如果参数可以分析,根据用户的参数去选择查询方式,比如标签数。
- 如果参数不可分析,并且数据库连接足够、内存空间足够,可以并发同时查询,谁先返回用谁。
- 还可以SQL查询与内存计算相结合,比如先用SQL过滤掉部分Tag。
并行流和串行流
- 串行流 Stream ,并行流 parallelStream
- 并行流parallelStream缺点:parallelStream使用公共线程池,如果某一个方法耗时特别长,那么慢慢的整个线程池会都交给该方法,就没有多余的线程分配给其他任务了。
tag的判空
Optional可选类,可以减少判断的分支
tempTagNameSet = Optional.ofNullable(tempTagNameSet).orElse(new HashSet<>());
解析JSON字符串
名词解释
- 序列化:java对象转换成json
- 反序列化:把json转为java对象
java和json序列化库举例:
标签的string转json,利用gson库实现
Set<String> tempTagNameSet = gson.fromJson(tagsStr, new TypeToken<Set<User>>(){}.getType());
第二部分
前端整合路由
vue-router引入
main.ts
import {createApp} from 'vue' import {Button, Icon, NavBar, Tabbar, TabbarItem} from 'vant'; import App from './App.vue' import * as VueRouter from 'vue-router' import routes from "./config/route.ts"; const app = createApp(App); app.use(Button); app.use(NavBar); app.use(Tabbar); app.use(TabbarItem); app.use(Icon) const router = VueRouter.createRouter({ history: VueRouter.createWebHashHistory(), routes, }) app.use(router) app.mount('#app')
route.ts
import Index from "../pages/Index.vue"; import Team from "../pages/Team.vue"; const routes = [ { path: '/', component: Index }, { path: '/team', component: Team }, { path: '/user', component: Team }, ] export default routes;
BasicLayout.vue
<template> <van-nav-bar title="标题" left-text="返回" left-arrow> <template #right> <van-icon name="search" size="18"/> </template> </van-nav-bar> <div id="content"> <router-view/> </div> <van-tabbar route @change="onChange"> <van-tabbar-item to="/" icon="home-o" name="index">主页</van-tabbar-item> <van-tabbar-item to="/team" icon="search" name="team">队伍</van-tabbar-item> <van-tabbar-item to="/user" icon="friends-o" name="user">个人</van-tabbar-item> </van-tabbar> </template>
搜索页面开发
flat和flatmap
搜索的方法,展平tagList标签列表(逻辑有问题,仅用于相关方法学习)
const onSearch = () => { activeIds.value = tagList .flatMap((parentTag) => parentTag.children) .filter((item) => item.text.contain(searchText.value)); };
同上,正确方法
//标签列表 const originTagList = [ { text: "浙江", children: [ { text: "杭州", id: "杭州" }, { text: "温州", id: "温州" }, ], }, { text: "江苏", children: [ { text: "南京", id: "南京" }, { text: "无锡", id: "无锡" }, { text: "徐州", id: "徐州" }, ], }, ]; let tagList = ref(originTagList); const onSearch = () => { tagList.value = originTagList.map((parentTag) => { const tempChildren = [...parentTag.children]; const tempParentTag = { ...parentTag }; tempParentTag.children = tempChildren.filter((item) => item.text.includes(searchText.value), ); return tempParentTag; }); }; //清空搜索框 const onCancel = () => { searchText.value = ""; tagList.value = originTagList; };
个人信息页面
定义user的用户类型
/** * 用户类型 */ export type userType = { id: number; username: string; userAccount: string; avatarUrl?: string; gender: number; phone: string; email: string; userStatus: number; userRole: number; fantasyCode: string; tags: string[]; createTime: Date; };
编写前端页面
用户编辑页面
定义一个传三个参数的点击事件
@click="toEdit('avatarUrl', '头像', user.avatarUrl)"
具体方法
const toEdit = (editKey: string, editName: string, currentValue: string) => { router.push({ path: "/user/edit", query: { editKey, editName, currentValue, }, }); };
用户编辑页面定义传递过来的参数
const route = useRoute(); const editUser = ref({ editKey: route.query.editKey, editName: route.query.editName, currentValue: route.query.currentValue, });
采用模板动态展示
<van-form @submit="onSubmit"> <van-cell-group inset> <van-field v-model="editUser.currentValue" :name="editUser.editKey" :label="editUser.editName" :placeholder="`请输入${editUser.editName}`" /> </van-cell-group> <div style="margin: 16px"> <van-button round block type="primary" native-type="submit"> 提交 </van-button> </div> </van-form>
页面展示
个人信息
修改信息
搜索
第三部分
后端整合接口文档
什么是接口文档?
- 写接口信息的文档,每条信息包括
- 请求参数
- 相应参数
- 错误码
- 接口地址
- 接口名称
- 请求类型
- 请求格式
- 备注
- 谁用接口文档?一般是后端或者负责人提供,后端前端都要使用。
- 写接口信息的文档,每条信息包括
为什么需要接口文档
- 有个书面内容(背书或者归档),便于大家参考和查阅,便于沉淀和维护,拒绝口口相传
- 接口文档便于前端和后端开发对接,前后端联调介质。后端=>接口文档<=前端
- 好的接口文档支持在线调试、在线测试,可以作为工具提高我们的测试开发效率。
如何做接口文档
- 手写(比如腾讯文档,Markdown笔记)
- 自动化接口文档生成:自动根据项目代码生成完整的文档或在线调试的网页。Swagger、Postman(侧重接口管理);apifox、apipost、eolink(国产)
Swagger原理
自定义Swagger配置类
定义需要生成接口文档的代码位置(Controller)
注:线上环境不要把接口暴露出去。
可以通过在controller方法上添加@Api、@ApiImplicitParam(name=“name”,value=“姓名”,require=true)、@ApiOperation(value=“向客人问好”)等注解来自定义生成接口描述信息。
看上了网页信息怎么抓取到
分析网站是如何获取这些信息的,哪个接口?
curl "https://api.zsxq.com/v2/hashtags/28855251481421/topics?count=20" ^ -H "accept: application/json, text/plain, */*" ^ -H "accept-language: zh-CN,zh;q=0.9" ^ -H "origin: https://wx.zsxq.com" ^ -H "priority: u=1, i" ^ -H "referer: https://wx.zsxq.com/" ^ -H ^"sec-ch-ua: ^\^"Google Chrome^\^";v=^\^"125^\^", ^\^"Chromium^\^";v=^\^"125^\^", ^\^"Not.A/Brand^\^";v=^\^"24^\^"^" ^ -H "sec-ch-ua-mobile: ?0" ^ -H ^"sec-ch-ua-platform: ^\^"Windows^\^"^" ^ -H "sec-fetch-dest: empty" ^ -H "sec-fetch-mode: cors" ^ -H "sec-fetch-site: same-site" ^ -H "user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36" ^
用程序去调用接口(JAVA/Python)。
处理(清洗)一下数据,就可以写入数据库。
流程
- 从excal导入用户数据,判重。easy excal
- 抓取写了自我介绍的同学的信息,提取出用户昵称,用户唯一id自我介绍信息‘。
- 从自我介绍中提取信息,写入数据库中。
EasyExcal
两种读取方式
- 确定表头:建立对象和表格形成映射。
- 不确定表头:每一行的数据映射为Map<String,Object>