文章目錄
- 后端
- 新建圖片類型Picture
- 創建圖片接口類PictureController
- 新建PictureQueryRequest
- 創建Service類
- 創建實現類PictureServiceImpl
- 前端
- 添加接口獲取后端數據
- 修改picture頁面內容
- 添加文章,圖片的搜索功能
- 修改查詢參數的獲取,實現查詢用戶功能
- 存在的問題
- 幾種不同的業務場景
后端
新建圖片類型Picture
@Data
public class Picture implements Serializable {private String title;private String url;private static final long serialVersionUID = 1L;
}
創建圖片接口類PictureController
@RestController
@RequestMapping("/picture")
@Slf4j
@CrossOrigin(originPatterns = {"http://localhost:8081"}, allowCredentials = "true", allowedHeaders = {"*"})
public class PictureController {@Resourceprivate PictureService pictureService;/*** 分頁搜索(從 ES 查詢,封裝類)** @param pictureQueryRequest* @param request* @return*/@PostMapping("/search/page/vo")public BaseResponse<Page<Picture>> searchPictureByPage(@RequestBody PictureQueryRequest pictureQueryRequest,HttpServletRequest request) {long size = pictureQueryRequest.getPageSize();long current = pictureQueryRequest.getCurrent();// 限制爬蟲ThrowUtils.throwIf(size > 20, ErrorCode.PARAMS_ERROR);String searchText = pictureQueryRequest.getSearchText();Page<Picture> picturePage = pictureService.searchPicture(searchText,current,size);return ResultUtils.success(picturePage);}}
新建PictureQueryRequest
@Data
public class PictureQueryRequest extends PageRequest implements
Serializable {private String SearchText;private static final long serialVersionUID = 1L;
}
創建Service類
@Service
public interface PictureService {Page<Picture> searchPicture(String searchText, long pageNum, long pageSize);
}
創建實現類PictureServiceImpl
@Service
@Slf4j
public class PictureServiceImpl implements PictureService {@Overridepublic Page<Picture> searchPicture(String searchText, long pageNum, long pageSize) {long current = (pageNum - 1) * pageSize;String url = String.format("https://cn.bing.com/images/search?q=%s&first=%s",searchText,current);Document doc = null;try {doc = Jsoup.connect(url).get();} catch (IOException e) {throw new BusinessException(ErrorCode.PARAMS_ERROR, "數據抓取失敗");}Elements elements = doc.select(".iuscp.isv"); //數組,每個元素是每一張圖片List<Picture> pictures = new ArrayList<>();for (Element element : elements) {//取圖片地址murlString m = element.select(".iusc").attr("m");Map<String, Object> map = JSONUtil.toBean(m, Map.class);String murl = (String) map.get("murl");//取標題String title = element.select(".inflnk").attr("aria-label");Picture picture = new Picture();picture.setTitle(title);picture.setUrl(murl);pictures.add(picture);if (pictures.size() >= pageSize)break;}Page<Picture> picturePage = new Page<>(pageNum,pageSize);picturePage.setRecords(pictures);return picturePage;}}
前端
添加接口獲取后端數據
坐標:src/pages/InderxPage.vue
<template><div class="index-page"><a-tabs v-model:activeKey="activeKey" @change="onTabchange"><a-tab-pane key="picture" tab="圖片" force-render><PictureList :picture-list="pictureList" /></a-tab-pane></a-tabs></div>
</template>
<script setup lang="ts">const pictureList = ref([]);myAxios.post("/picture/list/page/vo", {}).then((res: any) => {pictureList.value = res.records;});
</script>
修改picture頁面內容
坐標:src/components/PictureList.vue
<template><!-- 獲取每一張圖片的pictureList --><a-list item-layout="horizontal" :data-source="props.pictureList":grid="{ gutter: 16, xs: 1, sm: 2, md: 4, lg: 4, xl: 6, xxl: 3 }"><template #renderItem="{ item }"><a-list-item><a-card hoverable><template #cover><img alt="example" :src="item.url" /></template><a-card-meta :title="item.title" /></a-card></a-list-item></template></a-list>
</template>
<script setup lang="ts">import { withDefaults, defineProps } from "vue";// 接口和默認值interface Props {pictureList: any[];}const props = withDefaults(defineProps<Props>(), {pictureList: () => [],});
</script>
<style scoped>.image-list {display: flex;flex-wrap: wrap;}
</style>
添加文章,圖片的搜索功能
坐標:src/pages/InderxPage.vue
<script setup lang="ts">
/*** 加載數據* @param params*/
const loadData = (params: any) => {const query = {...params,searchText: params.text,};myAxios.post("/post/list/page/vo", query).then((res: any) => {postList.value = res.records;});myAxios.post("/user/list/page/vo", query).then((res: any) => {userList.value = res.records;});myAxios.post("/picture/list/page/vo", query).then((res: any) => {pictureList.value = res.records;});
};
const searchParams = ref(initSearchParams);
// 首次請求
loadData(initSearchParams);
const onSearch = (value: string) => {console.log(value);router.push({query: searchParams.value,});// 根據條件查詢loadData(searchParams.value);
};
</script>
修改查詢參數的獲取,實現查詢用戶功能
因為用戶只能根據用戶名來查
坐標:src/pages/InderxPage.vue
<script setup lang="ts">
/*** 加載數據* @param params*/
const loadData = (params: any) => { const postQuery = {...params,searchText: params.text,};myAxios.post("/post/list/page/vo", postQuery).then((res: any) => {postList.value = res.records;});const pictureQuery = {...params,searchText: params.text,};myAxios.post("/picture/list/page/vo", pictureQuery).then((res: any) =>
{pictureList.value = res.records;});const userQuery = {...params,userName: params.text,};myAxios.post("/user/list/page/vo", userQuery).then((res: any) => {userList.value = res.records;});
};
</script>
存在的問題
- 請求數量過多,可能會受到瀏覽器的限制
- 請求不同的接口的參數可能不一致,增加前后端溝通成本
- 前端寫調用多個接口的代碼,重復代碼
幾種不同的業務場景
(目前在加載頁面時,分別調用接口獲取文章,圖片,用戶數據)
- 用戶點擊某個tab時,只調用這個tab的接口
- 針對聚合內容的網頁,一個請求搞定
- 有可能要查詢每個模塊數據的總數,反饋給用戶