From 3a8110171f61f7f0506bd5a3d6cc5ded31e2a35a Mon Sep 17 00:00:00 2001
From: PetrichorFun <127877748+PetrichorFun@users.noreply.github.com>
Date: Wed, 21 Jan 2026 14:59:05 +0800
Subject: [PATCH] feat: add MulInputModal
---
package.json | 6 +-
plans/MulInputModal_modification.md | 77 +++++++++
pnpm-lock.yaml | 11 --
src/components/HeaderTitle.vue | 16 +-
src/env.ts | 4 +-
.../views/AmazonEntries/SearchPageEntry.vue | 40 +++--
.../views/components/MulInputModal.vue | 146 ++++++++++++++++++
7 files changed, 271 insertions(+), 29 deletions(-)
create mode 100644 plans/MulInputModal_modification.md
create mode 100644 src/sidepanel/views/components/MulInputModal.vue
diff --git a/package.json b/package.json
index e0b0167..ca7b377 100644
--- a/package.json
+++ b/package.json
@@ -1,9 +1,9 @@
{
"name": "azon-seeker",
- "displayName": "Azon Seeker",
- "version": "0.7.1",
+ "displayName": "Azon Seeker v0.7.1.1-beta",
+ "version": "0.7.2",
"private": true,
- "description": "Starter modify by honestfox101",
+ "description": "Starter modify by honestfox101 and PetrichorFun",
"scripts": {
"dev": "npm run clear && cross-env NODE_ENV=development run-p dev:prepare dev:web dev:background dev:js",
"dev-firefox": "npm run clear-firefox && cross-env NODE_ENV=development EXTENSION=firefox run-p dev:prepare dev:web dev:background dev:js",
diff --git a/plans/MulInputModal_modification.md b/plans/MulInputModal_modification.md
new file mode 100644
index 0000000..18f914e
--- /dev/null
+++ b/plans/MulInputModal_modification.md
@@ -0,0 +1,77 @@
+# MulInputModal.vue 修改计划
+
+## 目标
+
+修改 `src/sidepanel/views/components/MulInputModal.vue` 组件,使其支持从 Excel 复制一列值粘贴到输入框,并提供格式验证和确认后的消息通知。
+
+## 需求详情
+
+1. **输入格式**:每行一个值(换行分隔),不允许空行。
+2. **实时验证**:在用户输入时检查格式是否正确,并给出提示。
+3. **确认通知**:点击确认按钮后,显示 n-message 通知成功或失败。
+
+## 当前组件分析
+
+当前组件是一个简单的模态对话框,包含一个文本区域输入框。它通过 `v-model:show-modal` 控制显示,但没有处理输入值或验证逻辑。
+
+## 设计修改
+
+### 1. 模板修改
+
+- 保留现有的 `n-modal` 和 `n-dialog` 结构。
+- 修改 `n-dialog` 属性:
+ - 移除 `content` 属性(因为其内容与功能不符)。
+ - 动态设置确认按钮的文本和状态:格式正确时显示“确认”,格式错误时显示“格式错误”并禁用按钮。
+- 增强 `n-input`:
+ - 添加 `placeholder` 提示用户粘贴格式。
+ - 设置 `autosize` 适应多行内容。
+ - 绑定 `v-model:value` 到本地输入文本。
+- 添加验证提示区域:
+ - 显示验证状态消息(成功/错误)。
+ - 显示行数统计。
+
+### 2. 脚本修改
+
+- 导入必要的 Vue 和 Naive UI API。
+- 定义模型:
+ - `showModal`:控制模态框显示。
+ - `modelValue`:可选,用于双向绑定关键词数组(字符串数组)。
+- 定义本地响应式数据:
+ - `inputText`:文本区域的绑定值。
+- 计算属性 `validation`:
+ - 根据输入文本实时验证格式。
+ - 返回 `valid`、`lines`(非空行数组)、`message`。
+- 验证规则:
+ 1. 输入不能为空(去除首尾空格后)。
+ 2. 不允许空行(任何一行 trim 后为空即无效)。
+ 3. 检测制表符(警告用户可能粘贴了多列)。
+- 确认处理函数 `handleConfirm`:
+ - 检查验证结果,如果无效则显示错误消息并返回。
+ - 如果有效,更新 `modelValue`,发出 `confirm` 事件,显示成功消息,关闭模态框。
+- 初始化:当 `modelValue` 变化时,将数组转换为换行分隔的文本并填充到输入框。
+
+### 3. 样式修改
+
+- 添加验证提示区域的样式,根据状态改变颜色。
+- 调整布局间距。
+
+## 代码草案
+
+详见 [MulInputModal.vue 草案](草案内容略)
+
+## 向后兼容性
+
+- 添加的 `modelValue` 模型为可选,不影响现有使用(父组件可以不传递)。
+- 现有的 `showModal` 模型保持不变。
+- 新增的 `confirm` 事件可选,父组件可以监听以获取导入的行。
+
+## 测试计划
+
+1. 手动测试从 Excel 复制一列值并粘贴到输入框。
+2. 验证实时提示是否正确显示。
+3. 测试确认按钮在格式正确/错误时的行为。
+4. 测试 n-message 通知是否正常弹出。
+
+## 下一步
+
+完成详细设计后,切换到 Code 模式实施修改。
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index e5e98d9..afc79bb 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -988,7 +988,6 @@ packages:
}
cpu: [arm]
os: [linux]
- libc: [glibc]
'@rollup/rollup-linux-arm-musleabihf@4.45.1':
resolution:
@@ -997,7 +996,6 @@ packages:
}
cpu: [arm]
os: [linux]
- libc: [musl]
'@rollup/rollup-linux-arm64-gnu@4.45.1':
resolution:
@@ -1006,7 +1004,6 @@ packages:
}
cpu: [arm64]
os: [linux]
- libc: [glibc]
'@rollup/rollup-linux-arm64-musl@4.45.1':
resolution:
@@ -1015,7 +1012,6 @@ packages:
}
cpu: [arm64]
os: [linux]
- libc: [musl]
'@rollup/rollup-linux-loongarch64-gnu@4.45.1':
resolution:
@@ -1024,7 +1020,6 @@ packages:
}
cpu: [loong64]
os: [linux]
- libc: [glibc]
'@rollup/rollup-linux-powerpc64le-gnu@4.45.1':
resolution:
@@ -1033,7 +1028,6 @@ packages:
}
cpu: [ppc64]
os: [linux]
- libc: [glibc]
'@rollup/rollup-linux-riscv64-gnu@4.45.1':
resolution:
@@ -1042,7 +1036,6 @@ packages:
}
cpu: [riscv64]
os: [linux]
- libc: [glibc]
'@rollup/rollup-linux-riscv64-musl@4.45.1':
resolution:
@@ -1051,7 +1044,6 @@ packages:
}
cpu: [riscv64]
os: [linux]
- libc: [musl]
'@rollup/rollup-linux-s390x-gnu@4.45.1':
resolution:
@@ -1060,7 +1052,6 @@ packages:
}
cpu: [s390x]
os: [linux]
- libc: [glibc]
'@rollup/rollup-linux-x64-gnu@4.45.1':
resolution:
@@ -1069,7 +1060,6 @@ packages:
}
cpu: [x64]
os: [linux]
- libc: [glibc]
'@rollup/rollup-linux-x64-musl@4.45.1':
resolution:
@@ -1078,7 +1068,6 @@ packages:
}
cpu: [x64]
os: [linux]
- libc: [musl]
'@rollup/rollup-win32-arm64-msvc@4.45.1':
resolution:
diff --git a/src/components/HeaderTitle.vue b/src/components/HeaderTitle.vue
index e0d29e7..b21254a 100644
--- a/src/components/HeaderTitle.vue
+++ b/src/components/HeaderTitle.vue
@@ -2,6 +2,9 @@
const openOptionsPage = async () => {
await browser.runtime.openOptionsPage();
};
+const emit = defineEmits<{
+ (e: 'clickMulInput', event: MouseEvent): void;
+}>();
@@ -15,10 +18,20 @@ const openOptionsPage = async () => {
数据
+
+
+
+
+
+
+ 输入
+
-
+
+
+
@@ -40,6 +53,7 @@ const openOptionsPage = async () => {
.setting-button {
margin: 12px 20px 0 0;
opacity: 0.7;
+
&:hover {
opacity: 1;
}
diff --git a/src/env.ts b/src/env.ts
index 10e5558..22acb84 100644
--- a/src/env.ts
+++ b/src/env.ts
@@ -14,5 +14,7 @@ export function isForbiddenUrl(url: string): boolean {
export const isFirefox = navigator.userAgent.includes('Firefox');
-export const remoteHost = __DEV__ ? '127.0.0.1:8000' : '47.251.4.191:8000';
+// export const remoteHost = __DEV__ ? '127.0.0.1:8000' : '47.251.4.191:8000';
+export const remoteHost = __DEV__ ? '127.0.0.1:18000' : 'vm8nc3zr-18000.usw2.devtunnels.ms';
+
// export const remoteHost = '47.251.4.191:8000';
diff --git a/src/sidepanel/views/AmazonEntries/SearchPageEntry.vue b/src/sidepanel/views/AmazonEntries/SearchPageEntry.vue
index f452abd..b1efcf9 100644
--- a/src/sidepanel/views/AmazonEntries/SearchPageEntry.vue
+++ b/src/sidepanel/views/AmazonEntries/SearchPageEntry.vue
@@ -2,8 +2,9 @@
import { keywordsList } from '~/storages/amazon';
import type { Timeline } from '~/components/ProgressReport.vue';
import { usePageWorker } from '~/page-worker';
-
+import MulInputModal from '~/sidepanel/views/components/MulInputModal.vue';
const message = useMessage();
+const showModal = ref(false);
//#region Initial Page Worker
const worker = usePageWorker('amazon', { objects: ['search'] });
@@ -72,23 +73,35 @@ const handleInterrupt = () => {
worker.stop();
message.info('已触发中断,正在等待当前任务完成。', { duration: 2000 });
};
+const clickInputButton = (e: MouseEvent) => {
+ showModal.value = true;
+};
+
+const handleModalConfirm = (keys: string[]) => {
+ keywordsList.value = keys;
+ // console.log(keys);
+};
-
Amazon Search
+
Amazon Search
-
+
+
+
+
{
+