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; +}>(); + + + + -

+

+ +

@@ -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); +};