PageSourceSearch

https://petpet.vn/_nuxt/CarIPEZf.js

js petpet.vn collected 2026-09-24 11:02:44 UTC 8,103 bytes, 1 lines download raw bytes

1import{b as l}from"./DDwdkoEU.js";import{c as o}from"./CSavATbq.js";const c="/spa_address/nearest-by-location",f=l("locatorStorage",{state:()=>({stores:[],provinces:[],loading:!1,error:null,districts:[],nearestStores:[],nearestClinics:[],userLocation:null,storeOffset:0,storeHasMore:!1,storeLoadingMore:!1}),actions:{async fetchStores(){this.loading=!0;try{const r=await o().get("/store_address/all");if(r.data?.success&&Array.isArray(r.data.data)){const t=r.data.data.map(e=>{const s=e.formatted_address||e.address||"",i=this.extractProvince(s),d=this.extractDistrict(s);return{name:e.name||"",fullAddress:s,province:i||"",district:d||"",rating:e.rating??null,latitude:e.latitude,longitude:e.longitude,status:e.status,phone:e.phone,hours:e.hours,address:e.address,formatted_address:e.formatted_address,map_direction_url:e.map_direction_url,opening_date:e.opening_date,raw:e,image:e.image,images:e.images,main_image:e.main_image,slug:e.slug||"",content:e.content||"",service:e.service||""}}),a={};t.forEach(e=>{const s=e.province||"Khác",i=e.district||"";a[s]||(a[s]=new Set),i&&a[s].add(i)});const n=Object.entries(a).map(([e,s])=>({name:e,districts:Array.from(s).sort()})).sort((e,s)=>e.name.localeCompare(s.name));this.stores=t,this.provinces=n}else console.warn("Fetch stores: unexpected response",r.data)}catch(r){console.error("Lỗi khi tải danh sách cửa hàng:",r),this.error=r}finally{this.loading=!1}},extractProvince(r){if(!r)return"";const t=r.split(",").map(a=>a.trim()).filter(Boolean);for(let a=t.length-1;a>=0;a--){const n=t[a],e=n.match(/^(Thành phố|Thị xã|TP\.?|Tp\.?)\s*(.+)$/iu);if(e&&e[2])return e[2].trim();const s=n.match(/^(Tỉnh)\s*(.+)$/iu);if(s&&s[2])return s[2].trim()}return t.length>=2?t[t.length-2]:t[t.length-1]||""},extractDistrict(r){if(!r)return"";const t=r.split(",").map(n=>n.trim()).filter(Boolean);let a=-1;for(let n=t.length-1;n>=0;n--)if(t[n].match(/^(Thành phố|Thị xã|TP\.?|Tp\.?|Tỉnh)\s*(.+)$/iu)){a=n;break}if(a>0)return t[a-1];if(t.length>=2)if(t[t.length-1].toLowerCase().includes("việt nam")){if(t.length>=3)return t[t.length-3]}else return t[t.length-2];return""},extractWard(r){if(!r)return"";const t=r.split(",").map(a=>a.trim()).filter(Boolean);for(const a of t){const n=a.match(/^(Phường|P\.?|Xã|Thị trấn)\s*(.+)$/iu);if(n&&n[2])return n[2].trim()}return""},async fetchNearestSpas(r,t){this.loading=!0,this.error=null,this.storeOffset=0,this.storeHasMore=!1;try{console.debug("[locator] fetchNearestSpas request",{lat:r,lng:t});const a=await o().post("/store_address/nearest-by-location",{lat:r,lng:t,limit:5,offset:0});if(console.debug("[locator] fetchNearestSpas response",{status:a.status,data:a.data}),a.data?.success&&a.data.data){const n=a.data.data,e=Array.isArray(n.nearest_stores)?n.nearest_stores:[];this.nearestStores=e.map(s=>({_id:s._id,name:s.name,address:s.address||s.formatted_address||"",formatted_address:s.formatted_address||s.address||"",latitude:s.latitude,longitude:s.longitude,place_id:s.place_id,types:s.types||[],rating:s.rating??null,user_ratings_total:s.user_ratings_total??0,business_status:s.business_status??"",status:s.status,distance:s.distance??null,raw:s})),this.storeOffset=e.length,this.storeHasMore=n.has_more??!1,n.user_location?this.userLocation={latitude:n.user_location.latitude,longitude:n.user_location.longitude}:this.userLocation={latitude:r,longitude:t}}else console.warn("fetchNearestStores: unexpected response",a.data),this.nearestStores=[],this.storeHasMore=!1,this.userLocation={latitude:r,longitude:t}}catch(a){console.error("Lỗi khi fetch nearest stores:",a),this.error=a,this.nearestStores=[],this.storeHasMore=!1,this.userLocation={latitude:r,longitude:t}}finally{this.loading=!1}},async fetchMoreStores(){if(!(!this.userLocation||!this.storeHasMore||this.storeLoadingMore)){this.storeLoadingMore=!0;try{const{latitude:r,longitude:t}=this.userLocation,a=await o().post("/store_address/nearest-by-location",{lat:r,lng:t,limit:5,offset:this.storeOffset});if(a.data?.success&&a.data.data){const n=a.data.data,s=(Array.isArray(n.nearest_stores)?n.nearest_stores:[]).map(i=>({_id:i._id,name:i.name,address:i.address||i.formatted_address||"",formatted_address:i.formatted_address||i.address||"",latitude:i.latitude,longitude:i.longitude,place_id:i.place_id,types:i.types||[],rating:i.rating??null,user_ratings_total:i.user_ratings_total??0,business_status:i.business_status??"",status:i.status,distance:i.distance??null,raw:i}));this.nearestStores=[...this.nearestStores,...s],this.storeOffset+=s.length,this.storeHasMore=n.has_more??!1}}catch(r){console.error("Lỗi khi fetch more stores:",r)}finally{this.storeLoadingMore=!1}}},async fetchNearestClinics(r,t){this.loading=!0,this.error=null;try{const a=await o().post(c,{lat:r,lng:t});if(a.data?.success&&a.data.data){const n=a.data.data,e=Array.isArray(n.nearest_spas)?n.nearest_spas:[];this.nearestClinics=e.map(s=>({_id:s._id,name:s.name,address:s.address||s.formatted_address||"",formatted_address:s.formatted_address||s.address||"",latitude:s.latitude,longitude:s.longitude,place_id:s.place_id,types:s.types||[],rating:s.rating??null,user_ratings_total:s.user_ratings_total??0,business_status:s.business_status??"",distance:s.distance??null,raw:s})),n.user_location?this.userLocation={latitude:n.user_location.latitude,longitude:n.user_location.longitude}:this.userLocation={latitude:r,longitude:t}}else console.warn("fetchNearestClinics: unexpected response",a.data),this.nearestClinics=[],this.userLocation={latitude:r,longitude:t}}catch(a){console.error("Lỗi khi fetch nearest clinics:",a),this.error=a,this.nearestClinics=[],this.userLocation={latitude:r,longitude:t}}finally{this.loading=!1}},async fetchProvincesWithLocations(r){this.loading=!0,this.error=null;try{const t=await o().get("/address/province",{params:{limit:50,page:1,sort:"related_score desc",has_addresses:!0,t
1ype:r}});t.data&&Array.isArray(t.data.data?.items)?this.provinces=t.data.data.items:t.data&&Array.isArray(t.data.data)?this.provinces=t.data.data:Array.isArray(t.data)?this.provinces=t.data:(console.warn("fetchProvincesWithLocations: unexpected response",t.data),this.provinces=[])}catch(t){console.error("Lỗi khi fetch provinces:",t),this.error=t,this.provinces=[]}finally{this.loading=!1}},async fetchDistrictsByProvince(r){this.loading=!0,this.error=null;try{const t=await o().get("/address/districts",{params:{limit:50,page:1,sort:"related_score desc",has_addresses:!0,level1_id:r}});return t.data&&Array.isArray(t.data.data?.items)?this.districts=t.data.data.items:t.data&&Array.isArray(t.data.data)?this.districts=t.data.data:Array.isArray(t.data)?this.districts=t.data:(console.warn("fetchDistrictsByProvince: unexpected response",t.data),this.districts=[]),this.districts}catch(t){return console.error("Lỗi khi fetch districts:",t),this.error=t,this.districts=[],[]}finally{this.loading=!1}},async fetchLocationsByDistrict(r,t){this.loading=!0,this.error=null;const n={clinic:"/veterinary_address/by-district",spa:"/spa_address/by-district"}[t];if(!n)return console.warn(`fetchLocationsByDistrict: loại '${t}' chưa được hỗ trợ`),[];try{const e=await o().get(n,{params:{level2_id:r}});if(e.data?.success&&Array.isArray(e.data.data?.items)){const s=e.data.data.items.map(i=>({_id:i._id,name:i.name,address:i.address||i.formatted_address||"",formatted_address:i.formatted_address||i.address||"",latitude:i.latitude,longitude:i.longitude,place_id:i.place_id,rating:i.rating??null,user_ratings_total:i.user_ratings_total??0,status:i.status,distance:i.distance??null,raw:i}));return t==="clinic"&&(this.nearestClinics=s),t==="spa"&&(this.nearestStores=s),s}else return console.warn(`fetchLocationsByDistrict (${t}): unexpected response`,e.data),t==="clinic"&&(this.nearestClinics=[]),t==="spa"&&(this.nearestStores=[]),[]}catch(e){return console.error(`Lỗi khi fetch ${t} by district:`,e),this.error=e,t==="clinic"&&(this.nearestClinics=[]),t==="spa"&&(this.nearestStores=[]),[]}finally{this.loading=!1}},clearNearest(){this.nearestStores=[],this.nearestClinics=[],this.userLocation=null}}});export{f as u};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.