diff --git a/src/views/admin/Dashboard.vue b/src/views/admin/Dashboard.vue index 6faf6f42..b68a39ec 100644 --- a/src/views/admin/Dashboard.vue +++ b/src/views/admin/Dashboard.vue @@ -373,7 +373,7 @@ onMounted(() => { loadTodayStats() loadLatestProducts() loadEmployeeStats() - // loadStoreInfo() + loadStoreInfo() }) diff --git a/src/views/config/config.vue b/src/views/config/config.vue index 216d1957..f4b951b9 100644 --- a/src/views/config/config.vue +++ b/src/views/config/config.vue @@ -25,12 +25,11 @@ - - +
- - 选择地址 + + 保存 打开程序 @@ -281,7 +280,6 @@ import { ref, onMounted } from 'vue' import axios from 'axios' import { ElMessage, ElMessageBox } from 'element-plus' import { Delete, Plus, Setting, User, Link, VideoPlay } from '@element-plus/icons-vue' -import { ServiceManager } from '@/utils/ServiceManager' import { testConnection, kongfzLogin, @@ -409,167 +407,16 @@ export default { const bindLoading = ref(false) const result = ref<{ success: boolean; message: string } | null>(null) - /** 通过本地服务管理器启动核价器 exe */ - const fileInputRef = ref(null) - const serviceManager = new ServiceManager('http://127.0.0.1:5000') - const SERVICE_ID = 'kfz-goods-pricing' - - const handleBrowseExe = () => { - fileInputRef.value?.click() - } - - const handleFileSelected = async () => { - const input = fileInputRef.value - if (!input?.files?.length) return - const file = input.files[0] - // 优先取完整路径(部分运行环境支持 file.path) - let fullPath = (file as any).path || '' - // 浏览器只给文件名时,从 ServiceManager 查完整路径 - if (!fullPath || !(fullPath.includes('\\') || fullPath.includes('/'))) { - try { - const services = await serviceManager.getServicesStatus() - const matched = services.find(s => s.exe_path && s.exe_path.includes(file.name)) - if (matched) { - fullPath = matched.exe_path - } - } catch { - // ServiceManager 不可用,降级用文件名 - } - } - dir.value = fullPath || file.name + /** 保存核价器所在目录到 localStorage */ + const handleSaveDir = () => { localStorage.setItem(STORAGE_KEY_FILE_DIR, dir.value) - - // 注册到启动器并启动 - if (fullPath && (fullPath.includes('\\') || fullPath.includes('/'))) { - const exeName = file.name.replace(/\.exe$/i, '') - try { - await serviceManager.registerService({ - id: SERVICE_ID, - name: '核价器', - exe_path: fullPath, - }) - ElMessage.success('已注册到启动器') - } catch { - // 注册失败不阻塞 - } - - // 通过 Vite 本地 API 直接启动(优先) - try { - const resp = await fetch('/api/local/launch-exe', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ exe_path: fullPath }) - }) - const result = await resp.json() - if (result.code === 0) { - ElMessage.success({ message: `核价器已启动 (PID ${result.pid})`, duration: 1000, customClass: 'scan-success-message' }) - } else { - // 降级:通过 ServiceManager 启动 - await serviceManager.startService(SERVICE_ID) - } - } catch { - // Vite API 不可用,降级 ServiceManager - try { - await serviceManager.startService(SERVICE_ID) - } catch { /* 无法启动 */ } - } - } - // 重置 input 以便重复选择同一文件时仍触发 change 事件 - input.value = '' + ElMessage.success({ message: '路径已保存', duration: 1000, customClass: 'scan-success-message' }) } - const handleOpenExe = async () => { - if (!dir.value) { - ElMessage.warning({ message: '请先设置程序所在位置', customClass: 'scan-warning-message' }) - return - } - - // 首选:通过 Vite 开发服务器本地 API 直接启动(无需任何外部脚本/服务) - try { - const resp = await fetch('/api/local/launch-exe', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ exe_path: dir.value }) - }) - const result = await resp.json() - if (result.code === 0) { - ElMessage.success({ message: `核价器已启动 (PID ${result.pid})`, duration: 1000, customClass: 'scan-success-message' }) - return - } - console.warn('[启动程序] Vite 本地 API 失败:', result.msg) - } catch { - // Vite API 不可用,继续降级 - } - - try { - // 尝试通过服务管理器启动 - const services = await serviceManager.getServicesStatus() - if (services.length > 0) { - let target = null - // 完整路径:按 exe_path 精确匹配;仅文件名:直接用 SERVICE_ID - const isFullPath = dir.value.includes('\\') || dir.value.includes('/') - if (isFullPath) { - target = services.find(s => s.exe_path && s.exe_path.includes(dir.value)) - } - if (!target) { - target = services.find(s => s.id === SERVICE_ID) - } - if (target) { - const ok = await serviceManager.startService(target.id) - if (ok) { - ElMessage.success({ message: `已启动: ${target.name || target.id}`, duration: 1000, customClass: 'scan-success-message' }) - return - } - } - } - // 服务管理器不可用或无匹配服务,回退到自定义协议 - console.warn('[启动程序] 服务管理器不可用,回退到自定义协议') - // 分离目录和 exe 文件名 - const lastSep = Math.max(dir.value.lastIndexOf('\\'), dir.value.lastIndexOf('/')) - const dirPath = lastSep > 0 ? dir.value.substring(0, lastSep) : dir.value - const exeName = lastSep > 0 ? dir.value.substring(lastSep + 1) : '' - - let launched = false - // 1. 尝试 kfzgs:// 协议 - try { - if (exeName) { - window.location.href = `kfzgs://launch?dir=${encodeURIComponent(dirPath)}&exe=${encodeURIComponent(exeName)}` - } else { - window.location.href = `kfzgs://launch?dir=${encodeURIComponent(dirPath)}` - } - launched = true - } catch { /* ignore */ } - - // 2. 降级:file:// 直链 + window.open - if (!launched) { - const fileUrl = `file:///${dir.value.replace(/\\/g, '/')}` - const win = window.open(fileUrl, '_blank') - if (!win) { - // 弹窗被拦截,用隐藏 a 标签触发 - const a = document.createElement('a') - a.href = fileUrl - a.target = '_blank' - a.click() - } - } - ElMessage.success({ message: '启动指令已发送', duration: 1000, customClass: 'scan-success-message' }) - } catch (err) { - // 服务管理器连接失败,回退到文件协议 - console.warn('[启动程序] 服务管理器连接失败:', err) - try { - const fileUrl = `file:///${dir.value.replace(/\\/g, '/')}` - const win = window.open(fileUrl, '_blank') - if (!win) { - const a = document.createElement('a') - a.href = fileUrl - a.target = '_blank' - a.click() - } - ElMessage.success({ message: '启动指令已发送', duration: 1000, customClass: 'scan-success-message' }) - } catch (err2) { - ElMessage.error({ message: `启动失败: ${err2.message || '未知错误'}`, customClass: 'scan-error-message' }) - } - } + /** 通过自定义协议启动核价器 exe */ + const handleOpenExe = () => { + window.location.href = 'kfzprice://launch' + ElMessage.success({ message: '启动指令已发送', duration: 1000, customClass: 'scan-success-message' }) } /** 将单个账号写入已保存列表 */ @@ -943,9 +790,7 @@ export default { return { dir, - fileInputRef, - handleBrowseExe, - handleFileSelected, + handleSaveDir, ip, port, verifyIndex, diff --git a/src/views/outbound/Outbound.vue b/src/views/outbound/Outbound.vue index 78d2d93a..330bdd8a 100644 --- a/src/views/outbound/Outbound.vue +++ b/src/views/outbound/Outbound.vue @@ -1,4 +1,14 @@