mirror of
https://github.com/primedigitaltech/azon_seeker.git
synced 2026-01-19 13:13:22 +08:00
Update UI & Worker
This commit is contained in:
parent
6662bba2b1
commit
3734c83d21
@ -6,7 +6,7 @@ const props = defineProps<{ model: AmazonDetailItem }>();
|
||||
|
||||
<template>
|
||||
<div class="detail-description">
|
||||
<n-descriptions label-placement="left" bordered :column="4">
|
||||
<n-descriptions label-placement="left" bordered :column="4" label-style="min-width: 100px">
|
||||
<n-descriptions-item label="ASIN" :span="2">
|
||||
{{ props.model.asin }}
|
||||
</n-descriptions-item>
|
||||
@ -28,11 +28,19 @@ const props = defineProps<{ model: AmazonDetailItem }>();
|
||||
<n-descriptions-item label="排名">
|
||||
{{ props.model.category2?.rank || '-' }}
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item label="图片链接">
|
||||
<n-descriptions-item label="图片链接" :span="4">
|
||||
<div v-for="link in props.model.imageUrls">
|
||||
{{ link }}
|
||||
</div>
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item label="评论" :span="2">
|
||||
<div v-for="review in props.model.topReviews" style="margin-bottom: 5px">
|
||||
<h5 style="margin: 0">{{ review.username }}:</h5>
|
||||
<div v-for="paragraph in review.content.split('\n')">
|
||||
{{ paragraph }}
|
||||
</div>
|
||||
</div>
|
||||
</n-descriptions-item>
|
||||
</n-descriptions>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -1,35 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
const openOptionsPage = async () => {
|
||||
await browser.runtime.openOptionsPage();
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="header-menu">
|
||||
<n-button class="setting-button" round @click="openOptionsPage" size="small">
|
||||
<template #icon>
|
||||
<n-icon size="18" color="#0f0f0f">
|
||||
<stash:search-results />
|
||||
</n-icon>
|
||||
</template>
|
||||
<template #default> 数据 </template>
|
||||
</n-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.header-menu {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
justify-content: flex-start;
|
||||
|
||||
.setting-button {
|
||||
margin-right: 20px;
|
||||
opacity: 0.7;
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
52
src/components/HeaderTitle.vue
Normal file
52
src/components/HeaderTitle.vue
Normal file
@ -0,0 +1,52 @@
|
||||
<script setup lang="ts">
|
||||
const openOptionsPage = async () => {
|
||||
await browser.runtime.openOptionsPage();
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="header-title">
|
||||
<div class="header-menu">
|
||||
<n-button class="setting-button" round @click="openOptionsPage" size="small">
|
||||
<template #icon>
|
||||
<n-icon size="18" color="#0f0f0f">
|
||||
<stash:search-results />
|
||||
</n-icon>
|
||||
</template>
|
||||
<template #default> 数据 </template>
|
||||
</n-button>
|
||||
</div>
|
||||
<n-space class="app-title">
|
||||
<mdi-cat style="font-size: 60px; color: black" />
|
||||
<h1><slot></slot></h1>
|
||||
</n-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.header-title {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.header-menu {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
justify-content: flex-start;
|
||||
|
||||
.setting-button {
|
||||
margin-right: 20px;
|
||||
opacity: 0.7;
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.app-title {
|
||||
margin-top: 20px;
|
||||
}
|
||||
</style>
|
||||
@ -177,11 +177,12 @@ class AmazonPageWorkerImpl implements AmazonPageWorker {
|
||||
await new Promise((resolve) => setTimeout(resolve, 2000)); // Wait 2 seconds.
|
||||
//#endregion
|
||||
//#region Fetch Top Reviews
|
||||
// const reviews = await injector.getReviews();
|
||||
// reviews.length > 0 &&
|
||||
// this.channel.emit('item-top-reviews-collected', {
|
||||
// reviews: reviews.map((r) => ({ asin: params.asin, ...r })),
|
||||
// });
|
||||
const reviews = await injector.getTopReviews();
|
||||
reviews.length > 0 &&
|
||||
this.channel.emit('item-top-reviews-collected', {
|
||||
asin: params.asin,
|
||||
topReviews: reviews.map((r) => ({ asin: params.asin, ...r })),
|
||||
});
|
||||
//#endregion
|
||||
}
|
||||
|
||||
|
||||
2
src/logic/page-worker/types.d.ts
vendored
2
src/logic/page-worker/types.d.ts
vendored
@ -57,7 +57,7 @@ interface AmazonPageWorkerEvents {
|
||||
/**
|
||||
* The event is fired when top reviews collected
|
||||
*/
|
||||
['item-top-reviews-collected']: { reviews: AmazonReview[] };
|
||||
['item-top-reviews-collected']: Pick<AmazonDetailItem, 'asin' | 'topReviews'>;
|
||||
|
||||
/**
|
||||
* Error event that occurs when there is an issue with the Amazon page worker.
|
||||
|
||||
@ -45,7 +45,7 @@ worker.channel.on('item-rating-collected', (ev) => {
|
||||
time: new Date().toLocaleString(),
|
||||
content: `评分: ${ev.rating};评价数:${ev.ratingCount}`,
|
||||
});
|
||||
createOrUpdateDetailItem(ev);
|
||||
updateDetailItems(ev);
|
||||
});
|
||||
worker.channel.on('item-category-rank-collected', (ev) => {
|
||||
timelines.value.push({
|
||||
@ -57,7 +57,7 @@ worker.channel.on('item-category-rank-collected', (ev) => {
|
||||
ev.category2 ? `#${ev.category2.rank} in ${ev.category2.name}` : '',
|
||||
].join('\n'),
|
||||
});
|
||||
createOrUpdateDetailItem(ev);
|
||||
updateDetailItems(ev);
|
||||
});
|
||||
worker.channel.on('item-images-collected', (ev) => {
|
||||
timelines.value.push({
|
||||
@ -66,7 +66,16 @@ worker.channel.on('item-images-collected', (ev) => {
|
||||
time: new Date().toLocaleString(),
|
||||
content: `图片数: ${ev.imageUrls!.length}`,
|
||||
});
|
||||
createOrUpdateDetailItem(ev);
|
||||
updateDetailItems(ev);
|
||||
});
|
||||
worker.channel.on('item-top-reviews-collected', (ev) => {
|
||||
timelines.value.push({
|
||||
type: 'success',
|
||||
title: `商品${ev.asin}精选评论`,
|
||||
time: new Date().toLocaleString(),
|
||||
content: `精选评论数: ${ev.topReviews!.length}`,
|
||||
});
|
||||
updateDetailItems(ev);
|
||||
});
|
||||
|
||||
const handleImportAsin: UploadOnChange = ({ fileList }) => {
|
||||
@ -139,7 +148,7 @@ const handleInterrupt = () => {
|
||||
message.info('已触发中断,正在等待当前任务完成。', { duration: 2000 });
|
||||
};
|
||||
|
||||
const createOrUpdateDetailItem = (info: AmazonDetailItem) => {
|
||||
const updateDetailItems = (info: AmazonDetailItem) => {
|
||||
const targetIndex = detailItems.value.findLastIndex((item) => info.asin === item.asin);
|
||||
if (targetIndex > -1) {
|
||||
const origin = detailItems.value[targetIndex];
|
||||
@ -152,12 +161,8 @@ const createOrUpdateDetailItem = (info: AmazonDetailItem) => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="detail-page-worker">
|
||||
<header-menu />
|
||||
<div class="title">
|
||||
<mdi-cat style="color: black; font-size: 60px" />
|
||||
<h1 style="font-size: 30px; color: black">Detail Page</h1>
|
||||
</div>
|
||||
<div class="detail-page-entry">
|
||||
<header-title>Detail Page</header-title>
|
||||
<div class="interative-section">
|
||||
<n-space>
|
||||
<n-upload @change="handleImportAsin" accept=".txt" :max="1">
|
||||
@ -210,24 +215,13 @@ const createOrUpdateDetailItem = (info: AmazonDetailItem) => {
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.detail-page-worker {
|
||||
.detail-page-entry {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
.title {
|
||||
margin: 20px 0 30px 0;
|
||||
font-size: 60px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.interative-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
18
src/sidepanel/ReviewPageEntry.vue
Normal file
18
src/sidepanel/ReviewPageEntry.vue
Normal file
@ -0,0 +1,18 @@
|
||||
<script lang="ts" setup></script>
|
||||
|
||||
<template>
|
||||
<div class="review-page-entry">
|
||||
<header-title>Review Page</header-title>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.review-page-entry {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
}
|
||||
</style>
|
||||
@ -82,12 +82,8 @@ const handleInterrupt = () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main class="search-page-worker">
|
||||
<header-menu />
|
||||
<n-space class="app-title">
|
||||
<mdi-cat style="font-size: 60px; color: black" />
|
||||
<h1>Search Page</h1>
|
||||
</n-space>
|
||||
<div class="search-page-entry">
|
||||
<header-title>Search Page</header-title>
|
||||
<div class="interactive-section">
|
||||
<n-dynamic-input
|
||||
:disabled="running"
|
||||
@ -121,11 +117,11 @@ const handleInterrupt = () => {
|
||||
<n-alert title="Warning" type="warning"> 警告,在插件运行期间请勿与浏览器交互。 </n-alert>
|
||||
</div>
|
||||
<progress-report class="progress-report" :timelines="timelines" />
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.search-page-worker {
|
||||
.search-page-entry {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -133,10 +129,6 @@ const handleInterrupt = () => {
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
|
||||
.app-title {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.interactive-section {
|
||||
border-radius: 10px;
|
||||
width: 80%;
|
||||
@ -1,15 +1,20 @@
|
||||
<script setup lang="ts">
|
||||
import DetailPageWorker from './DetailPageWorker.vue';
|
||||
import SearchPageWorker from './SearchPageWorker.vue';
|
||||
import DetailPageEntry from './DetailPageEntry.vue';
|
||||
import SearchPageEntry from './SearchPageEntry.vue';
|
||||
import ReviewPageEntry from './ReviewPageEntry.vue';
|
||||
|
||||
const tabs = [
|
||||
{
|
||||
name: '搜索页',
|
||||
component: SearchPageWorker,
|
||||
component: SearchPageEntry,
|
||||
},
|
||||
{
|
||||
name: '详情页',
|
||||
component: DetailPageWorker,
|
||||
component: DetailPageEntry,
|
||||
},
|
||||
{
|
||||
name: '评论页',
|
||||
component: ReviewPageEntry,
|
||||
},
|
||||
];
|
||||
const selectedTab = ref(tabs[0].name);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user