場景:如何根據被篩選出的商品查出他們的平臺屬性列表? 平臺屬性和麪包屑請求的分析?排除被選中的平臺屬性組?
如何根據被篩選出的商品查出他們的平臺屬性列表?
明確一個概念 根據三級分類id查詢出的平臺屬性的集合和被篩選的商品平臺屬性集合是不同的
我們先明確這個概念 我們通過電商網站實例來分析一下
這張圖片是我們進入手機這個三級分類id後所展示的平臺屬性及其值的集合
這張圖片展示了我們在搜索框輸入ipone後 所有篩選出來的iPhone手機的平臺屬性及平臺屬性值的集合
我們看到 當在搜索框輸入一個具體的keyword之後 頁面展示的平臺屬性列表將會根據keyword的不同發生不同的改變
如何根據keyword拿到我們想要的平臺屬性集合
通過我們上面的分析 這個具體的平臺屬性列表是我們從搜索結果中抽取出來的 而不是根據三級分類id查出的所有手機的平臺屬性的列表集合
我們的思路大致就是這樣 我們取出每一個pmsSearchSkuInfo對象中的平臺屬性的集合
這裏我們根據平臺屬性值(value_id)去取 並且根據平臺屬性值(value_id)進行去重處理
我們看具體的代碼實現
//抽取檢索結果包含的平臺屬性的集合
HashSet<String> valueIdSet=new HashSet<>();
for (PmsSearchSkuInfo pmsSearchSkuInfo : pmsSearchSkuInfoList) {
List<PmsSkuAttrValue> skuAttrValueList = pmsSearchSkuInfo.getSkuAttrValueList();
for (PmsSkuAttrValue pmsSkuAttrValue : skuAttrValueList) {
String valueId = pmsSkuAttrValue.getValueId();
valueIdSet.add(valueId);
}
}
這一步完成的功能實際就是將上面這個圖中的紅框選中部分展示了出來
只不過我們這裏僅僅是拿到了value_id 我們還得根據value_id把對應的這個平臺屬性和平臺屬性值的集合全部展示出來
這裏要注意的是 我們進行了去重 爲什麼要去重呢?
比如說 我們116號的sku和117號的sku和118的sku都是64G的
呢我們只保留一個64G的平臺屬性值就好了
否則不去重的話 就會看到存儲這個平臺屬性下面對應的平臺屬性值有64G 64G 64G 這種情況
調用attrService根據平臺屬性值的集合將在頁面展示的平臺屬性及值的集合查詢出來
//根據value_id將屬性列表查詢出來
List<PmsBaseAttrInfo> pmsBaseAttrInfos=attrService.getAttrValueListByValueId(valueIdSet);
modelMap.put("attrList",pmsBaseAttrInfos);
這裏service層的具體代碼我們不做展示了 我們把這個核心的sql展示下
最後這個表就是我們在頁面上展示的平臺屬性及其值的平臺屬性列表
SELECT *
FROM
`pms_base_attr_info` pa,
`pms_base_attr_value` pv
WHERE
pa.id=pv.attr_id
AND
pv.id IN(72,73,74,75,76,77,78,79,51,39)
這裏的72 73 74 75 這些就是我們假設的一個valueId的set集合
這個集合就是我們根據根據搜索結果抽取出來的平臺屬性值的集合(valueIdSet)
平臺屬性值和麪包屑請求的分析?
功能的分析
我們發現當我們選中某一個具體的平臺屬性值的時候 這裏都會發送一個GET請求
也就是說 當我們點擊某一個具體的平臺屬性值或者上方的麪包屑的時候 這裏都會發送一個獨立的GET請求
這裏我們可以得到兩個類似公式的結論
當我們點擊一個平臺屬性值以後
新的請求的URL=當前URL+這個平臺屬性值的value_id
當我們點擊要刪除一個麪包屑的時候
新的請求的URL=當前URL-點擊的這個麪包屑對應的value_id
每次我們進行一個點擊 都會發送一個獨立的新的請求
功能的實現—URL的拼接
這裏以點擊平臺屬性值爲例實現
目標功能:要實現每次點擊平臺屬性值和麪包屑的時候發送一個新的請求
我們發現目標功能的核心就是發送一個新的請求
呢我們的開發思路就轉化成了 我要發送一個新的請求 我得有個新的url啊
所以我們的任務重點就是把這個url算出來
我們計算出來url以後 要把他在放到頁面上
String urlParam=getUrlParam(pmsSearchParam);
modelMap.put("urlParam",urlParam);
我們看一下getUrlParam這個方法的實現
首先進入方法之前 我們再次明確 要進行一個URL的拼接
就要拿到對應平臺屬性值的value_id 而value_id被封裝在了pmsSearchParam這個對象中
所以getUrlParam這個方法要傳入一個pmsSearchParam的參數
private String getUrlParam(PmsSearchParam pmsSearchParam) {
String catalog3Id = pmsSearchParam.getCatalog3Id();
String keyword = pmsSearchParam.getKeyword();
String[] skuAttrValueList = pmsSearchParam.getValueId();
String urlParam="";
if(StringUtils.isNotBlank(catalog3Id)){
if (StringUtils.isNotBlank(urlParam)){
urlParam=urlParam+"&";
}
urlParam=urlParam+"catalog3Id="+catalog3Id;
}
if(StringUtils.isNotBlank(keyword)){
if(StringUtils.isNotBlank(urlParam)){
urlParam=urlParam+"&";
}
urlParam=urlParam+"keyword="+keyword;
}
if (skuAttrValueList!=null){
for (String pmsSkuAttrValue : skuAttrValueList) {
urlParam=urlParam+"&valueId="+pmsSkuAttrValue;
}
}
return urlParam;
}
這樣我們就會獲得一個拼接好的URL
關於獨立的GET請求的再思考
現在的場景是這樣的 當我們確認點擊了金這個平臺屬性值以後 瀏覽器會向服務器發送一次新的GET請求
新的GET請求的URL是圖片左下方的新的拼接好的URL
要注意的是 這個時候頁面在elasticsearch中做一次新的檢索 檢索出的sku列表會發生變化
相應的根據pmsSearchSkuInfoList獲得的valueIdSet也會發生變化
爲了驗證 我們打個一個dubug斷點
現在我們點擊金這個平臺屬性值讓它向後臺發送一次新的請求*
上圖說明我們在後臺確實做了一次新的搜索 並且這裏返回的pmsSearchSkuInfoList的大小爲1
這裏有個筆誤 應該是64是我們新添加的value_id
同時elasticsearch這裏也增加了一個新的term
再看下頁面
排除被選中的平臺屬性組
在我們選擇完一個平臺屬性值以後 就會去除當前value_id所在的平臺屬性組
//去掉當前valueid的屬性組
String[] delValueIds=pmsSearchParam.getValueId();
if (delValueIds!=null){
Iterator<PmsBaseAttrInfo> iterator = pmsBaseAttrInfos.iterator();
while (iterator.hasNext()){
PmsBaseAttrInfo pmsBaseAttrInfo=iterator.next();
List<PmsBaseAttrValue> attrValueList = pmsBaseAttrInfo.getAttrValueList();
for (PmsBaseAttrValue pmsBaseAttrValue : attrValueList) {
String valueId = pmsBaseAttrValue.getId();
for (String delValueId : delValueIds) {
if (delValueId.equals(valueId)){
iterator.remove();
}
}
}
}
}
這裏要注意的細節是 我們在遍歷這個pmsBaseAttrInfos集合的時候沒有用for循環
當我們的value_id和和需要被刪除的delValueId的匹配時
我們把此時迭代器指向的pmsBaseAttrInfo的對象幹掉
也就是把這個平臺屬性和這個屬性下的所有平臺屬性值全部刪除
每一次新的請求過來的時候 pmsSearchParam 這個對象就封裝好了此時URL中包括的value_id數組
這個數組中的value_id就是我們要刪除的平臺屬性組
我們每次進入一個新的請求頁面 先根據pmsSearchParam進行刪除 就得到了我們想要的平臺屬性列表