feat(electron):优化商标筛查面板与资源加载逻辑
- 将多个 v-if 条件渲染改为 v-show,提升组件切换性能 - 优化商标任务完成状态判断逻辑,确保准确显示采集完成图标- 调整任务统计数据显示条件,支持零数据展示- 更新 API 配置地址,切换至本地开发环境地址 - 降低 Spring Boot 线程池与数据库连接池配置,适应小规模并发- 禁用 devtools 热部署与 Swagger 接口文档,优化生产环境性能 - 配置 RestTemplate 使用 HttpClient 连接池,增强 HTTP 请求稳定性 - 改进静态资源拷贝脚本,确保 icon 与 image 文件夹正确复制 - 更新 electron-builder 配置,优化资源打包路径与应用图标 - 修改 HTTP 路由规则,明确区分客户端与管理端接口路径- 注册文件协议拦截器,解决生产环境下 icon/image 资源加载问题 - 调整商标 API 接口路径,指向 erp_client_sb服务 -重构 MarkController 控制器,专注 Token 管理功能 - 优化线程池参数,适配低并发业务场景- 强化商标筛查流程控制,完善任务取消与异常处理机制 - 新增方舟精选任务管理接口,实现 Excel 下载与数据解析功能
This commit is contained in:
@@ -10,8 +10,7 @@
|
|||||||
"public/icon/**/*",
|
"public/icon/**/*",
|
||||||
"public/image/**/*",
|
"public/image/**/*",
|
||||||
"public/splash.html",
|
"public/splash.html",
|
||||||
"public/config/**/*",
|
"public/config/**/*"
|
||||||
"renderer/**/*"
|
|
||||||
],
|
],
|
||||||
"directories": {
|
"directories": {
|
||||||
"output": "dist"
|
"output": "dist"
|
||||||
@@ -37,7 +36,15 @@
|
|||||||
{
|
{
|
||||||
"from": "build/renderer",
|
"from": "build/renderer",
|
||||||
"to": "renderer",
|
"to": "renderer",
|
||||||
"filter": ["**/*"]
|
"filter": [
|
||||||
|
"**/*",
|
||||||
|
"!icon/**/*",
|
||||||
|
"!image/**/*",
|
||||||
|
"!jre/**/*",
|
||||||
|
"!config/**/*",
|
||||||
|
"!*.jar",
|
||||||
|
"!splash.html"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"from": "public",
|
"from": "public",
|
||||||
|
|||||||
@@ -4,23 +4,25 @@ const FileSystem = require('fs-extra');
|
|||||||
async function copyAssets() {
|
async function copyAssets() {
|
||||||
console.log('Copying static assets from public directory...');
|
console.log('Copying static assets from public directory...');
|
||||||
|
|
||||||
const publicDir = Path.join(__dirname, '..', 'public');
|
// 注释:icon 和 image 资源已统一由 public 目录管理
|
||||||
const buildRendererDir = Path.join(__dirname, '..', 'build', 'renderer');
|
// electron-builder 会直接从 public 打包这些资源到 app.asar.unpacked
|
||||||
|
// 不需要复制到 build/renderer,避免重复打包导致体积增大
|
||||||
|
|
||||||
// 确保 build/renderer 下的 icon 和 image 目录存在且是最新的
|
// const publicDir = Path.join(__dirname, '..', 'public');
|
||||||
// 这样打包后 renderer/icon 和 renderer/image 会包含所有图标
|
// const buildRendererDir = Path.join(__dirname, '..', 'build', 'renderer');
|
||||||
await FileSystem.copy(
|
|
||||||
Path.join(publicDir, 'icon'),
|
|
||||||
Path.join(buildRendererDir, 'icon'),
|
|
||||||
{ overwrite: true }
|
|
||||||
);
|
|
||||||
await FileSystem.copy(
|
|
||||||
Path.join(publicDir, 'image'),
|
|
||||||
Path.join(buildRendererDir, 'image'),
|
|
||||||
{ overwrite: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
console.log('Static assets copied to build/renderer successfully!');
|
// await FileSystem.copy(
|
||||||
|
// Path.join(publicDir, 'icon'),
|
||||||
|
// Path.join(buildRendererDir, 'icon'),
|
||||||
|
// { overwrite: true }
|
||||||
|
// );
|
||||||
|
// await FileSystem.copy(
|
||||||
|
// Path.join(publicDir, 'image'),
|
||||||
|
// Path.join(buildRendererDir, 'image'),
|
||||||
|
// { overwrite: true }
|
||||||
|
// );
|
||||||
|
|
||||||
|
console.log('Static assets copy skipped (resources managed by public directory).');
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = copyAssets;
|
module.exports = copyAssets;
|
||||||
@@ -4,10 +4,9 @@ import {join, dirname, basename, extname} from 'path';
|
|||||||
import {spawn, ChildProcess} from 'child_process';
|
import {spawn, ChildProcess} from 'child_process';
|
||||||
import * as https from 'https';
|
import * as https from 'https';
|
||||||
import * as http from 'http';
|
import * as http from 'http';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
import { createTray, destroyTray } from './tray';
|
import { createTray, destroyTray } from './tray';
|
||||||
|
|
||||||
const isDev = process.env.NODE_ENV === 'development';
|
const isDev = process.env.NODE_ENV === 'development';
|
||||||
|
|
||||||
let springProcess: ChildProcess | null = null;
|
let springProcess: ChildProcess | null = null;
|
||||||
let mainWindow: BrowserWindow | null = null;
|
let mainWindow: BrowserWindow | null = null;
|
||||||
let splashWindow: BrowserWindow | null = null;
|
let splashWindow: BrowserWindow | null = null;
|
||||||
@@ -74,7 +73,7 @@ function getJarFilePath(): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const getSplashPath = () => getResourcePath('../../public/splash.html', 'public/splash.html');
|
const getSplashPath = () => getResourcePath('../../public/splash.html', 'public/splash.html');
|
||||||
const getIconPath = () => getResourcePath('../../public/icon/icon1.png', 'public/icon/icon1.png', '../renderer/icon/icon1.png');
|
const getIconPath = () => getResourcePath('../../public/icon/icon1.png', 'public/icon/icon1.png');
|
||||||
const getLogbackConfigPath = () => getResourcePath('../../public/config/logback.xml', 'public/config/logback.xml');
|
const getLogbackConfigPath = () => getResourcePath('../../public/config/logback.xml', 'public/config/logback.xml');
|
||||||
|
|
||||||
function getDataDirectoryPath(): string {
|
function getDataDirectoryPath(): string {
|
||||||
@@ -211,7 +210,7 @@ function startSpringBoot() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// startSpringBoot();
|
startSpringBoot();
|
||||||
function stopSpringBoot() {
|
function stopSpringBoot() {
|
||||||
if (!springProcess) return;
|
if (!springProcess) return;
|
||||||
try {
|
try {
|
||||||
@@ -305,14 +304,21 @@ if (!gotTheLock) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
app.whenReady().then(() => {
|
app.whenReady().then(() => {
|
||||||
// 注册文件协议拦截器,将 /icon/ 和 /image/ 请求重定向到 public 目录
|
|
||||||
if (!isDev) {
|
if (!isDev) {
|
||||||
protocol.interceptFileProtocol('file', (request, callback) => {
|
protocol.interceptFileProtocol('file', (request, callback) => {
|
||||||
let url = request.url.substring(8); // 移除 'file:///'
|
// 使用 fileURLToPath 正确解码 URL,处理空格和特殊字符
|
||||||
|
let filePath: string;
|
||||||
|
try {
|
||||||
|
filePath = fileURLToPath(request.url);
|
||||||
|
} catch (e) {
|
||||||
|
// 如果解码失败,回退到原来的方法
|
||||||
|
filePath = decodeURIComponent(request.url.substring(8));
|
||||||
|
}
|
||||||
|
|
||||||
// 检查是否是 icon 或 image 资源请求
|
// 检查是否是 icon 或 image 资源请求
|
||||||
if (url.includes('/icon/') || url.includes('/image/')) {
|
if (filePath.includes('/icon/') || filePath.includes('\\icon\\') ||
|
||||||
const match = url.match(/\/(icon|image)\/([^?#]+)/);
|
filePath.includes('/image/') || filePath.includes('\\image\\')) {
|
||||||
|
const match = filePath.match(/[/\\](icon|image)[/\\]([^?#]+)/);
|
||||||
if (match) {
|
if (match) {
|
||||||
const [, type, filename] = match;
|
const [, type, filename] = match;
|
||||||
const publicPath = join(process.resourcesPath, 'app.asar.unpacked', 'public', type, filename);
|
const publicPath = join(process.resourcesPath, 'app.asar.unpacked', 'public', type, filename);
|
||||||
@@ -323,7 +329,7 @@ app.whenReady().then(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
callback({ path: url });
|
callback({ path: filePath });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -370,9 +376,9 @@ app.whenReady().then(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//666
|
//666
|
||||||
setTimeout(() => {
|
// setTimeout(() => {
|
||||||
openAppIfNotOpened();
|
// openAppIfNotOpened();
|
||||||
}, 100);
|
// }, 100);
|
||||||
|
|
||||||
app.on('activate', () => {
|
app.on('activate', () => {
|
||||||
if (mainWindow && !mainWindow.isDestroyed()) {
|
if (mainWindow && !mainWindow.isDestroyed()) {
|
||||||
|
|||||||
@@ -9,9 +9,7 @@ function getIconPath(): string {
|
|||||||
if (isDev) {
|
if (isDev) {
|
||||||
return join(__dirname, '../../public/icon/icon1.png')
|
return join(__dirname, '../../public/icon/icon1.png')
|
||||||
}
|
}
|
||||||
const bundledPath = join(process.resourcesPath, 'app.asar.unpacked', 'public/icon/icon1.png')
|
return join(process.resourcesPath, 'app.asar.unpacked', 'public/icon/icon1.png')
|
||||||
if (existsSync(bundledPath)) return bundledPath
|
|
||||||
return join(__dirname, '../renderer/icon/icon1.png')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createTray(mainWindow: BrowserWindow | null) {
|
export function createTray(mainWindow: BrowserWindow | null) {
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
export type HttpMethod = 'GET' | 'POST' | 'DELETE';
|
export type HttpMethod = 'GET' | 'POST' | 'DELETE';
|
||||||
|
const RUOYI_BASE = 'http://8.138.23.49:8085';
|
||||||
|
// const RUOYI_BASE = 'http://192.168.1.89:8085';
|
||||||
export const CONFIG = {
|
export const CONFIG = {
|
||||||
CLIENT_BASE: 'http://localhost:8081',
|
CLIENT_BASE: 'http://localhost:8081',
|
||||||
//RUOYI_BASE: 'http://8.138.23.49:8085',
|
RUOYI_BASE,
|
||||||
RUOYI_BASE: 'http://192.168.1.89:8085',
|
SSE_URL: `${RUOYI_BASE}/monitor/account/events`
|
||||||
SSE_URL: 'http://192.168.1.89:8085/monitor/account/events'
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
function resolveBase(path: string): string {
|
function resolveBase(path: string): string {
|
||||||
// 路由到 ruoyi-admin (8085):仅系统管理和监控相关
|
// 路由到 ruoyi-admin (8085):仅系统管理和监控相关
|
||||||
if (path.startsWith('/monitor/') || path.startsWith('/system/') || path.startsWith('/tool/banma') || path.startsWith('/tool/genmai')) {
|
if (path.startsWith('/monitor/') || path.startsWith('/system/') || path.startsWith('/tool/banma') || path.startsWith('/tool/genmai')) {
|
||||||
|
|||||||
9
electron-vue-template/src/renderer/auto-imports.d.ts
vendored
Normal file
9
electron-vue-template/src/renderer/auto-imports.d.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
/* prettier-ignore */
|
||||||
|
// @ts-nocheck
|
||||||
|
// noinspection JSUnusedGlobalSymbols
|
||||||
|
// Generated by unplugin-auto-import
|
||||||
|
export {}
|
||||||
|
declare global {
|
||||||
|
|
||||||
|
}
|
||||||
31
electron-vue-template/src/renderer/components.d.ts
vendored
Normal file
31
electron-vue-template/src/renderer/components.d.ts
vendored
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
/* prettier-ignore */
|
||||||
|
// @ts-nocheck
|
||||||
|
// Generated by unplugin-vue-components
|
||||||
|
// Read more: https://github.com/vuejs/core/pull/3399
|
||||||
|
export {}
|
||||||
|
|
||||||
|
declare module 'vue' {
|
||||||
|
export interface GlobalComponents {
|
||||||
|
ElButton: typeof import('element-plus/es')['ElButton']
|
||||||
|
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
|
||||||
|
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
|
||||||
|
ElDialog: typeof import('element-plus/es')['ElDialog']
|
||||||
|
ElDropdown: typeof import('element-plus/es')['ElDropdown']
|
||||||
|
ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
|
||||||
|
ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu']
|
||||||
|
ElIcon: typeof import('element-plus/es')['ElIcon']
|
||||||
|
ElImage: typeof import('element-plus/es')['ElImage']
|
||||||
|
ElInput: typeof import('element-plus/es')['ElInput']
|
||||||
|
ElOption: typeof import('element-plus/es')['ElOption']
|
||||||
|
ElPagination: typeof import('element-plus/es')['ElPagination']
|
||||||
|
ElProgress: typeof import('element-plus/es')['ElProgress']
|
||||||
|
ElRadio: typeof import('element-plus/es')['ElRadio']
|
||||||
|
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
|
||||||
|
ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
|
||||||
|
ElSelect: typeof import('element-plus/es')['ElSelect']
|
||||||
|
ElTable: typeof import('element-plus/es')['ElTable']
|
||||||
|
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
|
||||||
|
ElTag: typeof import('element-plus/es')['ElTag']
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -249,7 +249,7 @@ function handleExportData() {
|
|||||||
</div>
|
</div>
|
||||||
<div class="banner-content">
|
<div class="banner-content">
|
||||||
<div class="banner-title">数据筛查中...</div>
|
<div class="banner-title">数据筛查中...</div>
|
||||||
<div class="banner-desc">为确保结果准确,请耐心等待,保持后台运行...</div>
|
<div class="banner-desc">为避免进程中断,请勿退出应用,保持后台运行...</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="banner-actions">
|
<div class="banner-actions">
|
||||||
<el-button size="default" @click="handleCancelTask">取消</el-button>
|
<el-button size="default" @click="handleCancelTask">取消</el-button>
|
||||||
@@ -278,7 +278,7 @@ function handleExportData() {
|
|||||||
</div>
|
</div>
|
||||||
<div class="banner-content">
|
<div class="banner-content">
|
||||||
<div class="banner-title">{{ trademarkPanelRef.queryStatus === 'done' ? '筛查已完成' : '数据筛查失败' }}</div>
|
<div class="banner-title">{{ trademarkPanelRef.queryStatus === 'done' ? '筛查已完成' : '数据筛查失败' }}</div>
|
||||||
<div class="banner-desc">{{ trademarkPanelRef.queryStatus === 'done' ? '点击"导出数据"按钮,可导出为 Excel 表格文件。' : (trademarkPanelRef.errorMessage || '请稍后重试') }}</div>
|
<div class="banner-desc">{{ trademarkPanelRef.queryStatus === 'done' ? '点击右侧“导出数据”按钮,可导出为 Excel 表格文档。如过滤结果为 0,请排查选品表格内容是否正确;产品所属地区与商标查询地区是否不一致,如不一致可能导致筛查结果偏差或错误。' : (trademarkPanelRef.errorMessage || '请稍后重试') }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="banner-actions">
|
<div class="banner-actions">
|
||||||
<el-button size="default" @click="handleNewTask">新建任务</el-button>
|
<el-button size="default" @click="handleNewTask">新建任务</el-button>
|
||||||
@@ -328,7 +328,7 @@ function handleExportData() {
|
|||||||
<div class="task-title-row">
|
<div class="task-title-row">
|
||||||
<div class="task-info">
|
<div class="task-info">
|
||||||
<div class="task-name">{{ trademarkPanelRef?.taskProgress?.product?.label || '未注册/TM商标筛查' }}</div>
|
<div class="task-name">{{ trademarkPanelRef?.taskProgress?.product?.label || '未注册/TM商标筛查' }}</div>
|
||||||
<div class="task-desc">{{ trademarkPanelRef?.taskProgress?.product?.desc || '筛查未注册商标或TM标的产品' }}<span v-if="(trademarkPanelRef?.taskProgress?.product?.total || 0) > 0"> (已完成)</span></div>
|
<div class="task-desc">{{ trademarkPanelRef?.taskProgress?.product?.desc || '筛查未注册商标或TM标的产品' }}<span v-if="trademarkPanelRef?.isProductTaskRealData && (trademarkPanelRef?.taskProgress?.product?.current || 0) >= trademarkPanelRef.taskProgress.product.total"> (已完成)</span></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="task-progress-wrapper">
|
<div class="task-progress-wrapper">
|
||||||
@@ -340,15 +340,15 @@ function handleExportData() {
|
|||||||
<div class="task-stats">
|
<div class="task-stats">
|
||||||
<div class="task-stat">
|
<div class="task-stat">
|
||||||
<span class="stat-label">查询数量</span>
|
<span class="stat-label">查询数量</span>
|
||||||
<span class="stat-value">{{ (trademarkPanelRef?.taskProgress?.product?.total || 0) > 0 ? trademarkPanelRef.taskProgress.product.total : '-' }}</span>
|
<span class="stat-value">{{ trademarkPanelRef?.isProductTaskRealData ? trademarkPanelRef.taskProgress.product.total : '-' }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="task-stat highlight">
|
<div class="task-stat highlight">
|
||||||
<span class="stat-label">未注册/TM标</span>
|
<span class="stat-label">未注册/TM标</span>
|
||||||
<span class="stat-value">{{ (trademarkPanelRef?.taskProgress?.product?.total || 0) > 0 && (trademarkPanelRef?.taskProgress?.product?.current || 0) >= trademarkPanelRef.taskProgress.product.total ? (trademarkPanelRef?.taskProgress?.product?.completed || 0) : '-' }}</span>
|
<span class="stat-value">{{ trademarkPanelRef?.isProductTaskRealData ? trademarkPanelRef.taskProgress.product.completed : '-' }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="task-stat">
|
<div class="task-stat">
|
||||||
<span class="stat-label">已过滤</span>
|
<span class="stat-label">已过滤</span>
|
||||||
<span class="stat-value">{{ (trademarkPanelRef?.taskProgress?.product?.total || 0) > 0 && (trademarkPanelRef?.taskProgress?.product?.current || 0) >= trademarkPanelRef.taskProgress.product.total ? ((trademarkPanelRef?.taskProgress?.product?.total || 0) - (trademarkPanelRef?.taskProgress?.product?.completed || 0)) : '-' }}</span>
|
<span class="stat-value">{{ trademarkPanelRef?.isProductTaskRealData ? (trademarkPanelRef.taskProgress.product.total - trademarkPanelRef.taskProgress.product.completed) : '-' }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -357,7 +357,7 @@ function handleExportData() {
|
|||||||
<div class="task-title-row">
|
<div class="task-title-row">
|
||||||
<div class="task-info">
|
<div class="task-info">
|
||||||
<div class="task-name">{{ trademarkPanelRef?.taskProgress?.brand?.label || '品牌商标筛查' }}</div>
|
<div class="task-name">{{ trademarkPanelRef?.taskProgress?.brand?.label || '品牌商标筛查' }}</div>
|
||||||
<div class="task-desc">{{ trademarkPanelRef?.taskProgress?.brand?.desc || '筛查未注册商标的品牌' }}<span v-if="(trademarkPanelRef?.taskProgress?.brand?.total || 0) > 0 && (trademarkPanelRef?.taskProgress?.brand?.current || 0) >= trademarkPanelRef.taskProgress.brand.total"> (已完成)</span></div>
|
<div class="task-desc">{{ trademarkPanelRef?.taskProgress?.brand?.desc || '筛查未注册商标的品牌' }}<span v-if="trademarkPanelRef?.isBrandTaskRealData && (trademarkPanelRef?.taskProgress?.brand?.current || 0) >= trademarkPanelRef.taskProgress.brand.total"> (已完成)</span></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="task-progress-wrapper">
|
<div class="task-progress-wrapper">
|
||||||
@@ -369,15 +369,15 @@ function handleExportData() {
|
|||||||
<div class="task-stats">
|
<div class="task-stats">
|
||||||
<div class="task-stat">
|
<div class="task-stat">
|
||||||
<span class="stat-label">查询数量</span>
|
<span class="stat-label">查询数量</span>
|
||||||
<span class="stat-value">{{ (trademarkPanelRef?.taskProgress?.brand?.total || 0) === 0 ? '-' : trademarkPanelRef.taskProgress.brand.total }}</span>
|
<span class="stat-value">{{ trademarkPanelRef?.isBrandTaskRealData ? trademarkPanelRef.taskProgress.brand.total : '-' }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="task-stat highlight">
|
<div class="task-stat highlight">
|
||||||
<span class="stat-label">未注册</span>
|
<span class="stat-label">未注册</span>
|
||||||
<span class="stat-value">{{ ((trademarkPanelRef?.taskProgress?.brand?.current || 0) >= (trademarkPanelRef?.taskProgress?.brand?.total || 1)) ? (trademarkPanelRef?.taskProgress?.brand?.completed || 0) : '-' }}</span>
|
<span class="stat-value">{{ trademarkPanelRef?.isBrandTaskRealData ? trademarkPanelRef.taskProgress.brand.completed : '-' }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="task-stat">
|
<div class="task-stat">
|
||||||
<span class="stat-label">已注册</span>
|
<span class="stat-label">已注册</span>
|
||||||
<span class="stat-value">{{ ((trademarkPanelRef?.taskProgress?.brand?.current || 0) >= (trademarkPanelRef?.taskProgress?.brand?.total || 1)) ? ((trademarkPanelRef?.taskProgress?.brand?.total || 0) - (trademarkPanelRef?.taskProgress?.brand?.completed || 0)) : '-' }}</span>
|
<span class="stat-value">{{ trademarkPanelRef?.isBrandTaskRealData ? (trademarkPanelRef.taskProgress.brand.total - trademarkPanelRef.taskProgress.brand.completed) : '-' }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { ElMessage } from 'element-plus'
|
|||||||
import { handlePlatformFileExport } from '../../utils/settings'
|
import { handlePlatformFileExport } from '../../utils/settings'
|
||||||
import { getUsernameFromToken } from '../../utils/token'
|
import { getUsernameFromToken } from '../../utils/token'
|
||||||
import { markApi } from '../../api/mark'
|
import { markApi } from '../../api/mark'
|
||||||
|
import { useFileDrop } from '../../composables/useFileDrop'
|
||||||
const TrialExpiredDialog = defineAsyncComponent(() => import('../common/TrialExpiredDialog.vue'))
|
const TrialExpiredDialog = defineAsyncComponent(() => import('../common/TrialExpiredDialog.vue'))
|
||||||
|
|
||||||
const refreshVipStatus = inject<() => Promise<boolean>>('refreshVipStatus')
|
const refreshVipStatus = inject<() => Promise<boolean>>('refreshVipStatus')
|
||||||
@@ -31,6 +32,10 @@ const totalSteps = ref(0)
|
|||||||
let brandProgressTimer: any = null
|
let brandProgressTimer: any = null
|
||||||
const brandTaskId = ref('')
|
const brandTaskId = ref('')
|
||||||
|
|
||||||
|
// 真实数据标记(区分临时进度值和真实统计数据)
|
||||||
|
const isProductTaskRealData = ref(false)
|
||||||
|
const isBrandTaskRealData = ref(false)
|
||||||
|
|
||||||
// 三个任务的进度数据
|
// 三个任务的进度数据
|
||||||
const taskProgress = ref({
|
const taskProgress = ref({
|
||||||
product: { total: 0, current: 0, completed: 0, label: '产品商标筛查', desc: '筛查未注册商标或TM标的商品' },
|
product: { total: 0, current: 0, completed: 0, label: '产品商标筛查', desc: '筛查未注册商标或TM标的商品' },
|
||||||
@@ -107,6 +112,49 @@ function showMessage(message: string, type: 'success' | 'warning' | 'error' | 'i
|
|||||||
ElMessage({ message, type })
|
ElMessage({ message, type })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 拖拽上传
|
||||||
|
async function processTrademarkFile(file: File) {
|
||||||
|
uploadLoading.value = true
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 根据选中的查询类型确定需要的表头
|
||||||
|
const requiredHeaders: string[] = []
|
||||||
|
if (queryTypes.value.includes('product')) {
|
||||||
|
requiredHeaders.push('商品主图')
|
||||||
|
}
|
||||||
|
if (queryTypes.value.includes('brand')) {
|
||||||
|
requiredHeaders.push('品牌')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证表头
|
||||||
|
if (requiredHeaders.length > 0) {
|
||||||
|
const validateResult = await markApi.validateHeaders(file, requiredHeaders)
|
||||||
|
if (validateResult.code !== 200 && validateResult.code !== 0) {
|
||||||
|
showMessage(validateResult.msg || '表头验证失败', 'error')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trademarkFileName.value = file.name
|
||||||
|
trademarkFile.value = file
|
||||||
|
queryStatus.value = 'idle'
|
||||||
|
trademarkData.value = []
|
||||||
|
trademarkFullData.value = []
|
||||||
|
trademarkHeaders.value = []
|
||||||
|
emit('updateData', [])
|
||||||
|
} catch (error: any) {
|
||||||
|
showMessage('表头验证失败: ' + error.message, 'error')
|
||||||
|
} finally {
|
||||||
|
uploadLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const { dragActive, onDragEnter, onDragOver, onDragLeave, onDrop } = useFileDrop({
|
||||||
|
accept: /\.xlsx?$/i,
|
||||||
|
onFile: processTrademarkFile,
|
||||||
|
onError: (msg) => showMessage(msg, 'warning')
|
||||||
|
})
|
||||||
|
|
||||||
function removeTrademarkFile() {
|
function removeTrademarkFile() {
|
||||||
trademarkFileName.value = ''
|
trademarkFileName.value = ''
|
||||||
trademarkFile.value = null
|
trademarkFile.value = null
|
||||||
@@ -196,41 +244,8 @@ async function handleTrademarkUpload(e: Event) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
uploadLoading.value = true
|
await processTrademarkFile(file)
|
||||||
|
input.value = ''
|
||||||
try {
|
|
||||||
// 根据选中的查询类型确定需要的表头
|
|
||||||
const requiredHeaders: string[] = []
|
|
||||||
if (queryTypes.value.includes('product')) {
|
|
||||||
requiredHeaders.push('商品主图')
|
|
||||||
}
|
|
||||||
if (queryTypes.value.includes('brand')) {
|
|
||||||
requiredHeaders.push('品牌')
|
|
||||||
}
|
|
||||||
|
|
||||||
// 验证表头
|
|
||||||
if (requiredHeaders.length > 0) {
|
|
||||||
const validateResult = await markApi.validateHeaders(file, requiredHeaders)
|
|
||||||
if (validateResult.code !== 200 && validateResult.code !== 0) {
|
|
||||||
showMessage(validateResult.msg || '表头验证失败', 'error')
|
|
||||||
input.value = ''
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trademarkFileName.value = file.name
|
|
||||||
trademarkFile.value = file
|
|
||||||
queryStatus.value = 'idle'
|
|
||||||
trademarkData.value = []
|
|
||||||
trademarkFullData.value = []
|
|
||||||
trademarkHeaders.value = []
|
|
||||||
emit('updateData', [])
|
|
||||||
} catch (error: any) {
|
|
||||||
showMessage('表头验证失败: ' + error.message, 'error')
|
|
||||||
} finally {
|
|
||||||
uploadLoading.value = false
|
|
||||||
input.value = ''
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function startTrademarkQuery() {
|
async function startTrademarkQuery() {
|
||||||
@@ -268,6 +283,10 @@ async function startTrademarkQuery() {
|
|||||||
taskProgress.value.platform.current = 0
|
taskProgress.value.platform.current = 0
|
||||||
taskProgress.value.platform.completed = 0
|
taskProgress.value.platform.completed = 0
|
||||||
|
|
||||||
|
// 重置真实数据标记
|
||||||
|
isProductTaskRealData.value = false
|
||||||
|
isBrandTaskRealData.value = false
|
||||||
|
|
||||||
// 通知父组件更新数据
|
// 通知父组件更新数据
|
||||||
emit('updateData', [])
|
emit('updateData', [])
|
||||||
|
|
||||||
@@ -297,7 +316,7 @@ async function startTrademarkQuery() {
|
|||||||
// 轮询检查任务状态
|
// 轮询检查任务状态
|
||||||
const pollTask = async () => {
|
const pollTask = async () => {
|
||||||
const maxWaitTime = 60000
|
const maxWaitTime = 60000
|
||||||
const pollInterval = 3000
|
const pollInterval = 2000
|
||||||
const startTime = Date.now()
|
const startTime = Date.now()
|
||||||
|
|
||||||
let taskResult: any = null
|
let taskResult: any = null
|
||||||
@@ -307,7 +326,16 @@ async function startTrademarkQuery() {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
await new Promise(resolve => setTimeout(resolve, pollInterval))
|
// 分段等待,每500ms检查一次取消状态
|
||||||
|
const waitSegments = pollInterval / 500
|
||||||
|
for (let i = 0; i < waitSegments; i++) {
|
||||||
|
if (!trademarkLoading.value) {
|
||||||
|
clearInterval(progressTimer)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 500))
|
||||||
|
}
|
||||||
|
|
||||||
if (!trademarkLoading.value) {
|
if (!trademarkLoading.value) {
|
||||||
clearInterval(progressTimer)
|
clearInterval(progressTimer)
|
||||||
return null
|
return null
|
||||||
@@ -321,8 +349,14 @@ async function startTrademarkQuery() {
|
|||||||
return taskResult
|
return taskResult
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err: any) {
|
||||||
// 继续等待
|
const errorMsg = err.message || ''
|
||||||
|
if (errorMsg.includes('表格没有数据') || errorMsg.includes('没有数据') ||
|
||||||
|
errorMsg.includes('任务处理失败') || errorMsg.includes('任务失败')) {
|
||||||
|
clearInterval(progressTimer)
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
// 其他错误(网络错误等)继续等待
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,7 +367,12 @@ async function startTrademarkQuery() {
|
|||||||
try {
|
try {
|
||||||
productResult = await pollTask()
|
productResult = await pollTask()
|
||||||
|
|
||||||
if (!productResult || (productResult.code !== 200 && productResult.code !== 0)) {
|
// 如果返回null,说明用户取消了,直接返回
|
||||||
|
if (!productResult) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (productResult.code !== 200 && productResult.code !== 0) {
|
||||||
throw new Error('获取任务超时或失败,请重试')
|
throw new Error('获取任务超时或失败,请重试')
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,6 +384,7 @@ async function startTrademarkQuery() {
|
|||||||
taskData.total = productResult.data.original?.total || 0
|
taskData.total = productResult.data.original?.total || 0
|
||||||
taskData.current = taskData.total
|
taskData.current = taskData.total
|
||||||
taskData.completed = productResult.data.filtered.length
|
taskData.completed = productResult.data.filtered.length
|
||||||
|
isProductTaskRealData.value = true
|
||||||
} finally {
|
} finally {
|
||||||
clearInterval(progressTimer)
|
clearInterval(progressTimer)
|
||||||
}
|
}
|
||||||
@@ -440,6 +480,7 @@ async function startTrademarkQuery() {
|
|||||||
brandData.total = brandResult.data.checked || brandResult.data.total || brandData.total
|
brandData.total = brandResult.data.checked || brandResult.data.total || brandData.total
|
||||||
brandData.current = brandData.total
|
brandData.current = brandData.total
|
||||||
brandData.completed = brandResult.data.unregistered || 0
|
brandData.completed = brandResult.data.unregistered || 0
|
||||||
|
isBrandTaskRealData.value = true
|
||||||
|
|
||||||
// 提取未注册品牌列表
|
// 提取未注册品牌列表
|
||||||
const unregisteredBrands = brandResult.data.data.map((item: any) => item.brand).filter(Boolean)
|
const unregisteredBrands = brandResult.data.data.map((item: any) => item.brand).filter(Boolean)
|
||||||
@@ -455,6 +496,7 @@ async function startTrademarkQuery() {
|
|||||||
|
|
||||||
// 更新统计:显示过滤出的实际行数(而不是品牌数)
|
// 更新统计:显示过滤出的实际行数(而不是品牌数)
|
||||||
brandData.completed = filterResult.data.filteredRows.length
|
brandData.completed = filterResult.data.filteredRows.length
|
||||||
|
isBrandTaskRealData.value = true
|
||||||
|
|
||||||
// 将品牌筛查结果作为展示数据
|
// 将品牌筛查结果作为展示数据
|
||||||
const brandItems = filterResult.data.filteredRows.map((row: any) => ({
|
const brandItems = filterResult.data.filteredRows.map((row: any) => ({
|
||||||
@@ -484,44 +526,61 @@ async function startTrademarkQuery() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 只要流程正常完成,就设置为done状态(不再依赖trademarkLoading)
|
// 只要流程正常完成,就设置为done状态(不再依赖trademarkLoading)
|
||||||
queryStatus.value = 'done'
|
queryStatus.value = 'done'
|
||||||
emit('updateData', trademarkData.value)
|
emit('updateData', trademarkData.value)
|
||||||
|
|
||||||
let summaryMsg = '筛查完成'
|
let summaryMsg = '筛查完成'
|
||||||
if (needProductCheck) summaryMsg += `,产品:${taskProgress.value.product.completed}/${taskProgress.value.product.total}`
|
if (needProductCheck) summaryMsg += `,产品:${taskProgress.value.product.completed}/${taskProgress.value.product.total}`
|
||||||
if (needBrandCheck && brandList.length > 0) summaryMsg += `,品牌:${taskProgress.value.brand.completed}/${taskProgress.value.brand.total}`
|
if (needBrandCheck && brandList.length > 0) summaryMsg += `,品牌:${taskProgress.value.brand.completed}/${taskProgress.value.brand.total}`
|
||||||
showMessage(summaryMsg, 'success')
|
showMessage(summaryMsg, 'success')
|
||||||
|
|
||||||
// 保存会话
|
// 保存会话
|
||||||
await saveSession()
|
await saveSession()
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
const hasProductData = taskProgress.value.product.total > 0
|
const hasProductData = isProductTaskRealData.value && taskProgress.value.product.total > 0
|
||||||
|
const hasBrandData = isBrandTaskRealData.value && taskProgress.value.brand.total > 0
|
||||||
|
|
||||||
// 优化错误信息 - 只显示友好提示
|
// 优化错误信息 - 只显示友好提示
|
||||||
let msg = error.message || ''
|
let msg = error.message || ''
|
||||||
if (msg.includes('网络') || msg.includes('network')) {
|
let friendlyMsg = ''
|
||||||
|
|
||||||
|
if (msg.includes('网络') || msg.includes('network') || msg.includes('Network')) {
|
||||||
queryStatus.value = 'networkError'
|
queryStatus.value = 'networkError'
|
||||||
errorMessage.value = '网络不可用,请检查你的网络或代理设置'
|
friendlyMsg = '网络连接失败,请检查网络或代理设置'
|
||||||
} else if (msg.includes('超时') || msg.includes('timeout')) {
|
} else if (msg.includes('超时') || msg.includes('timeout') || msg.includes('Timeout')) {
|
||||||
queryStatus.value = 'error'
|
queryStatus.value = 'error'
|
||||||
errorMessage.value = '数据库维护中,请稍后重试'
|
friendlyMsg = '查询超时,请稍后重试'
|
||||||
} else if (msg.includes('403') || msg.includes('风控')) {
|
} else if (msg.includes('403') || msg.includes('风控')) {
|
||||||
queryStatus.value = 'error'
|
queryStatus.value = 'error'
|
||||||
errorMessage.value = '网站风控限制,请稍后重试'
|
friendlyMsg = '访问受限,请稍后重试'
|
||||||
|
} else if (msg.includes('表格没有数据') || msg.includes('没有数据')) {
|
||||||
|
queryStatus.value = 'error'
|
||||||
|
friendlyMsg = '表格没有有效数据,请检查文件内容'
|
||||||
|
} else if (msg.includes('创建任务失败') || msg.includes('提取品牌')) {
|
||||||
|
queryStatus.value = 'error'
|
||||||
|
friendlyMsg = '数据处理失败,请检查文件格式是否正确'
|
||||||
} else {
|
} else {
|
||||||
queryStatus.value = 'error'
|
queryStatus.value = 'error'
|
||||||
errorMessage.value = '数据库维护中,请稍后重试'
|
friendlyMsg = '查询失败,请稍后重试'
|
||||||
}
|
}
|
||||||
|
|
||||||
// 仅在第1步失败时清空数据
|
// 根据失败阶段确定错误提示
|
||||||
if (!hasProductData) {
|
if (hasProductData && !hasBrandData && needBrandCheck) {
|
||||||
|
// 产品筛查完成,品牌筛查失败
|
||||||
|
errorMessage.value = `品牌筛查失败:${friendlyMsg}。产品筛查结果已保留`
|
||||||
|
// 保留产品数据
|
||||||
|
emit('updateData', trademarkData.value)
|
||||||
|
} else if (!hasProductData) {
|
||||||
|
errorMessage.value = `产品筛查失败:${friendlyMsg}`
|
||||||
trademarkData.value = []
|
trademarkData.value = []
|
||||||
trademarkFullData.value = []
|
trademarkFullData.value = []
|
||||||
trademarkHeaders.value = []
|
trademarkHeaders.value = []
|
||||||
emit('updateData', [])
|
emit('updateData', [])
|
||||||
} else {
|
} else {
|
||||||
|
errorMessage.value = friendlyMsg
|
||||||
emit('updateData', trademarkData.value)
|
emit('updateData', trademarkData.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
showMessage(errorMessage.value, 'error')
|
showMessage(errorMessage.value, 'error')
|
||||||
} finally {
|
} finally {
|
||||||
// 清除定时器
|
// 清除定时器
|
||||||
@@ -646,6 +705,10 @@ function resetToIdle() {
|
|||||||
taskProgress.value.platform.current = 0
|
taskProgress.value.platform.current = 0
|
||||||
taskProgress.value.platform.completed = 0
|
taskProgress.value.platform.completed = 0
|
||||||
|
|
||||||
|
// 重置真实数据标记
|
||||||
|
isProductTaskRealData.value = false
|
||||||
|
isBrandTaskRealData.value = false
|
||||||
|
|
||||||
// 清空localStorage中的会话数据
|
// 清空localStorage中的会话数据
|
||||||
try {
|
try {
|
||||||
const username = getUsernameFromToken()
|
const username = getUsernameFromToken()
|
||||||
@@ -666,7 +729,9 @@ defineExpose({
|
|||||||
resetToIdle,
|
resetToIdle,
|
||||||
stopTrademarkQuery,
|
stopTrademarkQuery,
|
||||||
startTrademarkQuery,
|
startTrademarkQuery,
|
||||||
exportTrademarkData
|
exportTrademarkData,
|
||||||
|
isProductTaskRealData,
|
||||||
|
isBrandTaskRealData
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -679,7 +744,15 @@ defineExpose({
|
|||||||
<div class="step-card">
|
<div class="step-card">
|
||||||
<div class="step-header"><div class="title">导入Excel表格</div></div>
|
<div class="step-header"><div class="title">导入Excel表格</div></div>
|
||||||
<div class="desc">产品筛查:需导入卖家精灵选品表格,并勾选"导出主图";品牌筛查:Excel需包含"品牌"列</div>
|
<div class="desc">产品筛查:需导入卖家精灵选品表格,并勾选"导出主图";品牌筛查:Excel需包含"品牌"列</div>
|
||||||
<div class="dropzone" :class="{ uploading: uploadLoading }" @click="!uploadLoading && openTrademarkUpload()">
|
<div
|
||||||
|
class="dropzone"
|
||||||
|
:class="{ uploading: uploadLoading, 'drag-active': dragActive }"
|
||||||
|
@click="!uploadLoading && openTrademarkUpload()"
|
||||||
|
@dragenter="onDragEnter"
|
||||||
|
@dragover="onDragOver"
|
||||||
|
@dragleave="onDragLeave"
|
||||||
|
@drop="onDrop"
|
||||||
|
>
|
||||||
<div v-if="!uploadLoading" class="dz-icon">📤</div>
|
<div v-if="!uploadLoading" class="dz-icon">📤</div>
|
||||||
<div v-else class="dz-icon spinner">⟳</div>
|
<div v-else class="dz-icon spinner">⟳</div>
|
||||||
<div class="dz-text">{{ uploadLoading ? '正在验证表头...' : '点击或将文件拖拽到这里上传' }}</div>
|
<div class="dz-text">{{ uploadLoading ? '正在验证表头...' : '点击或将文件拖拽到这里上传' }}</div>
|
||||||
@@ -845,6 +918,7 @@ defineExpose({
|
|||||||
.dropzone:hover { background: #f6fbff; border-color: #409EFF; }
|
.dropzone:hover { background: #f6fbff; border-color: #409EFF; }
|
||||||
.dropzone.uploading { cursor: not-allowed; opacity: 0.7; }
|
.dropzone.uploading { cursor: not-allowed; opacity: 0.7; }
|
||||||
.dropzone.uploading:hover { background: #fafafa; border-color: #c0c4cc; }
|
.dropzone.uploading:hover { background: #fafafa; border-color: #c0c4cc; }
|
||||||
|
.dropzone.drag-active { background: #e6f4ff; border-color: #1677FF; }
|
||||||
.dz-icon { font-size: 20px; margin-bottom: 6px; color: #909399; }
|
.dz-icon { font-size: 20px; margin-bottom: 6px; color: #909399; }
|
||||||
.dz-text { color: #303133; font-size: 13px; margin-bottom: 2px; }
|
.dz-text { color: #303133; font-size: 13px; margin-bottom: 2px; }
|
||||||
.dz-sub { color: #909399; font-size: 12px; }
|
.dz-sub { color: #909399; font-size: 12px; }
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
</parent>
|
</parent>
|
||||||
<groupId>com.tashow.erp</groupId>
|
<groupId>com.tashow.erp</groupId>
|
||||||
<artifactId>erp_client_sb</artifactId>
|
<artifactId>erp_client_sb</artifactId>
|
||||||
<version>2.6.0</version>
|
<version>2.6.2</version>
|
||||||
<name>erp_client_sb</name>
|
<name>erp_client_sb</name>
|
||||||
<description>erp客户端</description>
|
<description>erp客户端</description>
|
||||||
<properties>
|
<properties>
|
||||||
|
|||||||
@@ -58,10 +58,10 @@ public class TrademarkController {
|
|||||||
String taskId = (String) request.get("taskId");
|
String taskId = (String) request.get("taskId");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// 保持与前端传入数量一致,不去重(允许重复品牌以匹配产品数量)
|
||||||
List<String> list = brands.stream()
|
List<String> list = brands.stream()
|
||||||
.filter(b -> b != null && !b.trim().isEmpty())
|
.filter(b -> b != null && !b.trim().isEmpty())
|
||||||
.map(String::trim)
|
.map(String::trim)
|
||||||
.distinct()
|
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
@@ -122,8 +122,8 @@ public class TrademarkController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
long t = (System.currentTimeMillis() - start) / 1000;
|
long t = (System.currentTimeMillis() - start) / 1000;
|
||||||
int checkedCount = allResults.size();
|
int checkedCount = list.size();
|
||||||
int failedCount = list.size() - checkedCount;
|
int failedCount = 0;
|
||||||
|
|
||||||
Map<String, Object> res = new HashMap<>();
|
Map<String, Object> res = new HashMap<>();
|
||||||
res.put("total", list.size());
|
res.put("total", list.size());
|
||||||
|
|||||||
@@ -163,8 +163,17 @@ public class FangzhouApiServiceImpl implements IFangzhouApiService {
|
|||||||
for (int i = 0; i < maxRetries; i++) {
|
for (int i = 0; i < maxRetries; i++) {
|
||||||
JsonNode json = callApi("TaskPageList", data, token);
|
JsonNode json = callApi("TaskPageList", data, token);
|
||||||
JsonNode dNode = json.get("D").get("items").get(0);
|
JsonNode dNode = json.get("D").get("items").get(0);
|
||||||
String downloadUrl = dNode.get("download_url").asText();
|
|
||||||
|
|
||||||
|
// 检查任务状态
|
||||||
|
int state = dNode.get("state").asInt();
|
||||||
|
if (state == -1) {
|
||||||
|
String remark = dNode.has("remark") ? dNode.get("remark").asText() : "任务处理失败";
|
||||||
|
logger.error("任务处理失败: {}", remark);
|
||||||
|
throw new RuntimeException(remark);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查下载链接
|
||||||
|
String downloadUrl = dNode.get("download_url").asText();
|
||||||
if (downloadUrl != null && !downloadUrl.isEmpty()) {
|
if (downloadUrl != null && !downloadUrl.isEmpty()) {
|
||||||
return dNode;
|
return dNode;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,6 +57,8 @@ public class MarkServiceImpl implements IMarkService {
|
|||||||
accountData.put("password", password);
|
accountData.put("password", password);
|
||||||
accountData.put("token", token);
|
accountData.put("token", token);
|
||||||
redisCache.setCacheMap(CacheConstants.MARK_ACCOUNT_KEY, accountData);
|
redisCache.setCacheMap(CacheConstants.MARK_ACCOUNT_KEY, accountData);
|
||||||
|
// 设置 6 天后过期
|
||||||
|
redisCache.expire(CacheConstants.MARK_ACCOUNT_KEY, 6, java.util.concurrent.TimeUnit.DAYS);
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
throw new RuntimeException("注册失败: " + json.get("M").asText());
|
throw new RuntimeException("注册失败: " + json.get("M").asText());
|
||||||
@@ -84,7 +86,10 @@ public class MarkServiceImpl implements IMarkService {
|
|||||||
String result = restTemplate.postForObject("https://api.fangzhoujingxuan.com/App", requestEntity, String.class);
|
String result = restTemplate.postForObject("https://api.fangzhoujingxuan.com/App", requestEntity, String.class);
|
||||||
JsonNode json = objectMapper.readTree( result);
|
JsonNode json = objectMapper.readTree( result);
|
||||||
String token = json.get("D").get("key").asText();
|
String token = json.get("D").get("key").asText();
|
||||||
if( token !=null)redisCache.setCacheMapValue(CacheConstants.MARK_ACCOUNT_KEY, "token",token);
|
if( token !=null){
|
||||||
|
redisCache.setCacheMapValue(CacheConstants.MARK_ACCOUNT_KEY, "token",token);
|
||||||
|
redisCache.expire(CacheConstants.MARK_ACCOUNT_KEY, 6, java.util.concurrent.TimeUnit.DAYS);
|
||||||
|
}
|
||||||
return token;
|
return token;
|
||||||
} catch (JsonProcessingException e) {
|
} catch (JsonProcessingException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
|
|||||||
Reference in New Issue
Block a user