222
This commit is contained in:
parent
a61e54cea2
commit
0a2e896962
@ -1,30 +1,30 @@
|
|||||||
package com.ruoyi;
|
package com.ruoyi;
|
||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 启动程序
|
* 启动程序
|
||||||
*
|
*
|
||||||
* @author ruoyi
|
* @author ruoyi
|
||||||
*/
|
*/
|
||||||
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
|
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
|
||||||
public class RuoYiApplication
|
public class RuoYiApplication
|
||||||
{
|
{
|
||||||
public static void main(String[] args)
|
public static void main(String[] args)
|
||||||
{
|
{
|
||||||
// System.setProperty("spring.devtools.restart.enabled", "false");
|
// System.setProperty("spring.devtools.restart.enabled", "false");
|
||||||
SpringApplication.run(RuoYiApplication.class, args);
|
SpringApplication.run(RuoYiApplication.class, args);
|
||||||
System.out.println("(♥◠‿◠)ノ゙ 若依启动成功 ლ(´ڡ`ლ)゙ \n" +
|
System.out.println("(♥◠‿◠)ノ゙ 若依启动成功 ლ(´ڡ`ლ)゙ \n" +
|
||||||
" .-------. ____ __ \n" +
|
" .-------. ____ __ \n" +
|
||||||
" | _ _ \\ \\ \\ / / \n" +
|
" | _ _ \\ \\ \\ / / \n" +
|
||||||
" | ( ' ) | \\ _. / ' \n" +
|
" | ( ' ) | \\ _. / ' \n" +
|
||||||
" |(_ o _) / _( )_ .' \n" +
|
" |(_ o _) / _( )_ .' \n" +
|
||||||
" | (_,_).' __ ___(_ o _)' \n" +
|
" | (_,_).' __ ___(_ o _)' \n" +
|
||||||
" | |\\ \\ | || |(_,_)' \n" +
|
" | |\\ \\ | || |(_,_)' \n" +
|
||||||
" | | \\ `' /| `-' / \n" +
|
" | | \\ `' /| `-' / \n" +
|
||||||
" | | \\ / \\ / \n" +
|
" | | \\ / \\ / \n" +
|
||||||
" ''-' `'-' `-..-' ");
|
" ''-' `'-' `-..-' ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ public class WebMagicController extends BaseController implements PageProcessor
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void loadProxyConfig() {
|
private void loadProxyConfig() {
|
||||||
try {
|
try {
|
||||||
// File configFile = ResourceUtils.getFile("classpath:test_proxy.yml");
|
//File configFile = ResourceUtils.getFile("classpath:test_proxy.yml");
|
||||||
File configFile = new File("/www/java_mall/erp/config/test_proxy.yml");
|
File configFile = new File("/www/java_mall/erp/config/test_proxy.yml");
|
||||||
if (configFile.exists()) {
|
if (configFile.exists()) {
|
||||||
Yaml yaml = new Yaml();
|
Yaml yaml = new Yaml();
|
||||||
@ -168,6 +168,7 @@ public class WebMagicController extends BaseController implements PageProcessor
|
|||||||
@Override
|
@Override
|
||||||
public void process(Page page) {
|
public void process(Page page) {
|
||||||
try {
|
try {
|
||||||
|
System.out.println("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
|
||||||
Html html = page.getHtml();
|
Html html = page.getHtml();
|
||||||
String priceSymbol = html.xpath("//span[@class='a-price-symbol']/text()").toString();
|
String priceSymbol = html.xpath("//span[@class='a-price-symbol']/text()").toString();
|
||||||
String priceWhole = html.xpath("//span[@class='a-price-whole']/text()").toString();
|
String priceWhole = html.xpath("//span[@class='a-price-whole']/text()").toString();
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
# 页面标题
|
# 页面标题
|
||||||
VUE_APP_TITLE = 若依管理系统
|
VUE_APP_TITLE =ERP管理系统
|
||||||
|
|
||||||
# 开发环境配置
|
# 开发环境配置
|
||||||
ENV = 'development'
|
ENV = 'development'
|
||||||
|
|
||||||
# 若依管理系统/开发环境
|
# ERP管理系统/开发环境
|
||||||
VUE_APP_BASE_API = '/dev-api'
|
VUE_APP_BASE_API = 'http://192.168.1.89:8080'
|
||||||
|
|
||||||
# 路由懒加载
|
# 路由懒加载
|
||||||
VUE_CLI_BABEL_TRANSPILE_MODULES = true
|
VUE_CLI_BABEL_TRANSPILE_MODULES = true
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
# 页面标题
|
# 页面标题
|
||||||
VUE_APP_TITLE = 若依管理系统
|
VUE_APP_TITLE = ERP管理系统
|
||||||
|
|
||||||
# 生产环境配置
|
# 生产环境配置
|
||||||
ENV = 'production'
|
ENV = 'production'
|
||||||
|
|
||||||
# 若依管理系统/生产环境
|
# ERP管理系统/生产环境
|
||||||
VUE_APP_BASE_API = 'https://erp.tashowz.com'
|
VUE_APP_BASE_API = 'https://erp.tashowz.com'
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# 页面标题
|
# 页面标题
|
||||||
VUE_APP_TITLE = 若依管理系统
|
VUE_APP_TITLE = ERP管理系统
|
||||||
|
|
||||||
BABEL_ENV = production
|
BABEL_ENV = production
|
||||||
|
|
||||||
@ -8,5 +8,5 @@ NODE_ENV = production
|
|||||||
# 测试环境配置
|
# 测试环境配置
|
||||||
ENV = 'staging'
|
ENV = 'staging'
|
||||||
|
|
||||||
# 若依管理系统/测试环境
|
# ERP管理系统/测试环境
|
||||||
VUE_APP_BASE_API = '/stage-api'
|
VUE_APP_BASE_API = '/stage-api'
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "ruoyi",
|
"name": "ruoyi",
|
||||||
"version": "3.9.0",
|
"version": "3.9.0",
|
||||||
"description": "若依管理系统",
|
"description": "ERP管理系统",
|
||||||
"author": "若依",
|
"author": "若依",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
class="action-button"
|
class="action-button"
|
||||||
>开始爬取</el-button>
|
>开始爬取</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="3">
|
<!-- <el-col :span="3">
|
||||||
<el-button
|
<el-button
|
||||||
type="info"
|
type="info"
|
||||||
plain
|
plain
|
||||||
@ -49,7 +49,7 @@
|
|||||||
@click="openProxyDialog"
|
@click="openProxyDialog"
|
||||||
class="action-button"
|
class="action-button"
|
||||||
>选择代理</el-button>
|
>选择代理</el-button>
|
||||||
</el-col>
|
</el-col>-->
|
||||||
<el-col :span="15">
|
<el-col :span="15">
|
||||||
<div class="notice-box" v-if="asinList.length > 0">
|
<div class="notice-box" v-if="asinList.length > 0">
|
||||||
已导入 <span class="count-number">{{asinList.length}}</span> 个ASIN
|
已导入 <span class="count-number">{{asinList.length}}</span> 个ASIN
|
||||||
@ -59,13 +59,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<!-- 爬取进度条 -->
|
<!-- 爬取进度条 -->
|
||||||
<el-row v-if="crawling">
|
<el-row v-if="crawling">
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<div class="progress-container">
|
<div class="progress-container">
|
||||||
<el-progress
|
<el-progress
|
||||||
:percentage="crawlProgress.percentage"
|
:percentage="crawlProgress.percentage"
|
||||||
:format="progressFormat"
|
:format="progressFormat"
|
||||||
:stroke-width="12"
|
:stroke-width="12"
|
||||||
class="crawl-progress"
|
class="crawl-progress"
|
||||||
@ -121,12 +121,12 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<!-- 代理选择对话框 -->
|
<!-- 代理选择对话框 -->
|
||||||
<el-dialog
|
<el-dialog
|
||||||
title="选择代理节点"
|
title="选择代理节点"
|
||||||
:visible="proxyDialog.open"
|
:visible="proxyDialog.open"
|
||||||
@close="proxyDialog.open = false"
|
@close="proxyDialog.open = false"
|
||||||
width="1300px"
|
width="1300px"
|
||||||
append-to-body
|
append-to-body
|
||||||
custom-class="proxy-dialog"
|
custom-class="proxy-dialog"
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
>
|
>
|
||||||
@ -142,11 +142,11 @@
|
|||||||
></el-input>
|
></el-input>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="7">
|
<el-col :span="7">
|
||||||
<el-button
|
<el-button
|
||||||
type="primary"
|
type="primary"
|
||||||
icon="el-icon-connection"
|
icon="el-icon-connection"
|
||||||
size="small"
|
size="small"
|
||||||
@click="testProxyDelay"
|
@click="testProxyDelay"
|
||||||
:loading="testingDelay"
|
:loading="testingDelay"
|
||||||
:disabled="filteredProxyNodes.length === 0"
|
:disabled="filteredProxyNodes.length === 0"
|
||||||
style="width: 100%;"
|
style="width: 100%;"
|
||||||
@ -157,16 +157,16 @@
|
|||||||
<div class="proxy-content" v-if="proxyNodes.length > 0">
|
<div class="proxy-content" v-if="proxyNodes.length > 0">
|
||||||
<el-row :gutter="10">
|
<el-row :gutter="10">
|
||||||
<el-col :xs="8" :sm="8" :md="6" :lg="6" :xl="6" v-for="(item, index) in filteredProxyNodes" :key="item.name">
|
<el-col :xs="8" :sm="8" :md="6" :lg="6" :xl="6" v-for="(item, index) in filteredProxyNodes" :key="item.name">
|
||||||
<div
|
<div
|
||||||
class="proxy-item"
|
class="proxy-item"
|
||||||
:class="{ 'is-selected': selectedProxy === item.name }"
|
:class="{ 'is-selected': selectedProxy === item.name }"
|
||||||
@click="selectProxy(item.name)"
|
@click="selectProxy(item.name)"
|
||||||
>
|
>
|
||||||
<div class="proxy-item-left">
|
<div class="proxy-item-left">
|
||||||
<span class="proxy-flag">{{ getCountryFlag(item.name) }}</span>
|
<span class="proxy-flag">{{ getCountryFlag(item.name) }}</span>
|
||||||
<el-radio
|
<el-radio
|
||||||
v-model="selectedProxy"
|
v-model="selectedProxy"
|
||||||
:label="item.name"
|
:label="item.name"
|
||||||
:disabled="loadingProxy"
|
:disabled="loadingProxy"
|
||||||
class="proxy-radio"
|
class="proxy-radio"
|
||||||
>
|
>
|
||||||
@ -269,8 +269,8 @@ export default {
|
|||||||
return this.proxyNodes;
|
return this.proxyNodes;
|
||||||
}
|
}
|
||||||
const keyword = this.proxySearchKeyword.toLowerCase();
|
const keyword = this.proxySearchKeyword.toLowerCase();
|
||||||
return this.proxyNodes.filter(proxy =>
|
return this.proxyNodes.filter(proxy =>
|
||||||
proxy.name.toLowerCase().includes(keyword) ||
|
proxy.name.toLowerCase().includes(keyword) ||
|
||||||
proxy.server.toLowerCase().includes(keyword)
|
proxy.server.toLowerCase().includes(keyword)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -291,7 +291,7 @@ export default {
|
|||||||
{ key: 'amazon_products_proxy', target: 'currentProxy' },
|
{ key: 'amazon_products_proxy', target: 'currentProxy' },
|
||||||
{ key: 'amazon_products_proxy_delays', target: 'cachedDelays' }
|
{ key: 'amazon_products_proxy_delays', target: 'cachedDelays' }
|
||||||
];
|
];
|
||||||
|
|
||||||
items.forEach(item => {
|
items.forEach(item => {
|
||||||
const data = localStorage.getItem(item.key);
|
const data = localStorage.getItem(item.key);
|
||||||
if (data) {
|
if (data) {
|
||||||
@ -307,7 +307,7 @@ export default {
|
|||||||
this.clearCache();
|
this.clearCache();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 保存数据到本地缓存 */
|
/** 保存数据到本地缓存 */
|
||||||
saveToCache() {
|
saveToCache() {
|
||||||
try {
|
try {
|
||||||
@ -324,7 +324,7 @@ export default {
|
|||||||
console.error('保存数据到缓存失败:', error);
|
console.error('保存数据到缓存失败:', error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 保存代理延迟数据到本地缓存 */
|
/** 保存代理延迟数据到本地缓存 */
|
||||||
saveProxyDelaysToCache() {
|
saveProxyDelaysToCache() {
|
||||||
try {
|
try {
|
||||||
@ -338,7 +338,7 @@ export default {
|
|||||||
status: node.status,
|
status: node.status,
|
||||||
timestamp: new Date().getTime()
|
timestamp: new Date().getTime()
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (delayData.length) {
|
if (delayData.length) {
|
||||||
|
|
||||||
const testJson = JSON.stringify(delayData);
|
const testJson = JSON.stringify(delayData);
|
||||||
@ -349,10 +349,10 @@ export default {
|
|||||||
console.error('保存代理延迟数据到缓存失败:', error);
|
console.error('保存代理延迟数据到缓存失败:', error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 清空缓存数据 */
|
/** 清空缓存数据 */
|
||||||
clearCache() {
|
clearCache() {
|
||||||
['amazon_products_data', 'amazon_products_asin_list',
|
['amazon_products_data', 'amazon_products_asin_list',
|
||||||
'amazon_products_proxy', 'amazon_products_proxy_delays'].forEach(key => {
|
'amazon_products_proxy', 'amazon_products_proxy_delays'].forEach(key => {
|
||||||
localStorage.removeItem(key);
|
localStorage.removeItem(key);
|
||||||
});
|
});
|
||||||
@ -370,19 +370,19 @@ export default {
|
|||||||
};
|
};
|
||||||
return styles[type.toLowerCase()] || '';
|
return styles[type.toLowerCase()] || '';
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 获取代理颜色 */
|
/** 获取代理颜色 */
|
||||||
getProxyColor(index) {
|
getProxyColor(index) {
|
||||||
return ['#409EFF', '#67C23A', '#E6A23C', '#F56C6C', '#909399'][index % 5];
|
return ['#409EFF', '#67C23A', '#E6A23C', '#F56C6C', '#909399'][index % 5];
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 选择代理 */
|
/** 选择代理 */
|
||||||
selectProxy(name) {
|
selectProxy(name) {
|
||||||
if (!this.loadingProxy && name) {
|
if (!this.loadingProxy && name) {
|
||||||
this.selectedProxy = name;
|
this.selectedProxy = name;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 加载代理节点列表 */
|
/** 加载代理节点列表 */
|
||||||
loadProxyNodes() {
|
loadProxyNodes() {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
@ -393,12 +393,12 @@ export default {
|
|||||||
this.loading = false;
|
this.loading = false;
|
||||||
if (response.code === 200) {
|
if (response.code === 200) {
|
||||||
this.proxyNodes = response.data || [];
|
this.proxyNodes = response.data || [];
|
||||||
|
|
||||||
if (this.proxyNodes.length) {
|
if (this.proxyNodes.length) {
|
||||||
if (this.currentProxy) {
|
if (this.currentProxy) {
|
||||||
this.selectedProxy = this.currentProxy;
|
this.selectedProxy = this.currentProxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.restoreCachedDelays();
|
this.restoreCachedDelays();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -408,13 +408,13 @@ export default {
|
|||||||
this.loading = false;
|
this.loading = false;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
restoreCachedDelays() {
|
restoreCachedDelays() {
|
||||||
if (!this.cachedDelays?.length || !this.proxyNodes?.length) return;
|
if (!this.cachedDelays?.length || !this.proxyNodes?.length) return;
|
||||||
|
|
||||||
const now = new Date().getTime();
|
const now = new Date().getTime();
|
||||||
const oneDay = 24 * 60 * 60 * 1000;
|
const oneDay = 24 * 60 * 60 * 1000;
|
||||||
|
|
||||||
this.cachedDelays.forEach(cachedItem => {
|
this.cachedDelays.forEach(cachedItem => {
|
||||||
if (cachedItem?.timestamp && (now - cachedItem.timestamp) < oneDay) {
|
if (cachedItem?.timestamp && (now - cachedItem.timestamp) < oneDay) {
|
||||||
const proxyNode = this.proxyNodes.find(p => p.name === cachedItem.name);
|
const proxyNode = this.proxyNodes.find(p => p.name === cachedItem.name);
|
||||||
@ -425,7 +425,7 @@ export default {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 打开代理选择对话框 */
|
/** 打开代理选择对话框 */
|
||||||
openProxyDialog() {
|
openProxyDialog() {
|
||||||
this.tempSelectedProxy = this.selectedProxy;
|
this.tempSelectedProxy = this.selectedProxy;
|
||||||
@ -440,11 +440,11 @@ export default {
|
|||||||
this.proxyDialog.open = false;
|
this.proxyDialog.open = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 切换代理节点 */
|
/** 切换代理节点 */
|
||||||
handleProxyChange(proxyName) {
|
handleProxyChange(proxyName) {
|
||||||
if (!proxyName) return;
|
if (!proxyName) return;
|
||||||
|
|
||||||
this.loadingProxy = true;
|
this.loadingProxy = true;
|
||||||
request({
|
request({
|
||||||
url: '/tool/webmagic/proxy/set',
|
url: '/tool/webmagic/proxy/set',
|
||||||
@ -453,7 +453,7 @@ export default {
|
|||||||
}).then(response => {
|
}).then(response => {
|
||||||
this.loadingProxy = false;
|
this.loadingProxy = false;
|
||||||
this.proxyDialog.open = false;
|
this.proxyDialog.open = false;
|
||||||
|
|
||||||
if (response.code === 200) {
|
if (response.code === 200) {
|
||||||
this.currentProxy = proxyName;
|
this.currentProxy = proxyName;
|
||||||
this.saveToCache();
|
this.saveToCache();
|
||||||
@ -467,11 +467,11 @@ export default {
|
|||||||
this.selectedProxy = this.currentProxy;
|
this.selectedProxy = this.currentProxy;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 获取国家/地区旗帜emoji */
|
/** 获取国家/地区旗帜emoji */
|
||||||
getCountryFlag(proxyName) {
|
getCountryFlag(proxyName) {
|
||||||
if (!proxyName) return '🌍';
|
if (!proxyName) return '🌍';
|
||||||
|
|
||||||
const lowerName = proxyName.toLowerCase();
|
const lowerName = proxyName.toLowerCase();
|
||||||
const flags = {
|
const flags = {
|
||||||
'hong kong': '🇭🇰', 'hk': '🇭🇰', '🇭🇰': '🇭🇰',
|
'hong kong': '🇭🇰', 'hk': '🇭🇰', '🇭🇰': '🇭🇰',
|
||||||
@ -492,7 +492,7 @@ export default {
|
|||||||
'canada': '🇨🇦', 'ca': '🇨🇦', '🇨🇦': '🇨🇦',
|
'canada': '🇨🇦', 'ca': '🇨🇦', '🇨🇦': '🇨🇦',
|
||||||
'malaysia': '🇲🇾', 'my': '🇲🇾', '🇲🇾': '🇲🇾'
|
'malaysia': '🇲🇾', 'my': '🇲🇾', '🇲🇾': '🇲🇾'
|
||||||
};
|
};
|
||||||
|
|
||||||
const matchedKey = Object.keys(flags).find(key => lowerName.includes(key));
|
const matchedKey = Object.keys(flags).find(key => lowerName.includes(key));
|
||||||
return matchedKey ? flags[matchedKey] : '🌍';
|
return matchedKey ? flags[matchedKey] : '🌍';
|
||||||
},
|
},
|
||||||
@ -503,25 +503,25 @@ export default {
|
|||||||
return proxyName.replace(/^[\uD800-\uDBFF][\uDC00-\uDFFF]\s*/, '')
|
return proxyName.replace(/^[\uD800-\uDBFF][\uDC00-\uDFFF]\s*/, '')
|
||||||
.replace(/^\s*(vn|jp|hk|tw|sg|us|kr|in|ph|id|th|de|fr|gb|ca|my)\s+/i, '');
|
.replace(/^\s*(vn|jp|hk|tw|sg|us|kr|in|ph|id|th|de|fr|gb|ca|my)\s+/i, '');
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 导入按钮操作 */
|
/** 导入按钮操作 */
|
||||||
handleImport() {
|
handleImport() {
|
||||||
this.upload.title = "导入ASIN";
|
this.upload.title = "导入ASIN";
|
||||||
this.upload.open = true;
|
this.upload.open = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 进度条格式化 */
|
/** 进度条格式化 */
|
||||||
progressFormat(percentage) {
|
progressFormat(percentage) {
|
||||||
return `${this.crawlProgress.current}/${this.crawlProgress.total}`;
|
return `${this.crawlProgress.current}/${this.crawlProgress.total}`;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 获取进度条状态 */
|
/** 获取进度条状态 */
|
||||||
getProgressStatus() {
|
getProgressStatus() {
|
||||||
if (this.crawlProgress.percentage >= 100) return 'success';
|
if (this.crawlProgress.percentage >= 100) return 'success';
|
||||||
if (this.crawlProgress.percentage < 0) return 'exception';
|
if (this.crawlProgress.percentage < 0) return 'exception';
|
||||||
return '';
|
return '';
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 下载模板操作 */
|
/** 下载模板操作 */
|
||||||
importTemplate() {
|
importTemplate() {
|
||||||
// 创建模板数据
|
// 创建模板数据
|
||||||
@ -533,7 +533,7 @@ export default {
|
|||||||
];
|
];
|
||||||
exportExcel(data, '亚马逊产品信息模板', '.et');
|
exportExcel(data, '亚马逊产品信息模板', '.et');
|
||||||
},
|
},
|
||||||
|
|
||||||
// 文件变更处理
|
// 文件变更处理
|
||||||
handleFileChange(file) {
|
handleFileChange(file) {
|
||||||
// 验证文件类型
|
// 验证文件类型
|
||||||
@ -544,11 +544,11 @@ export default {
|
|||||||
this.$refs.upload.clearFiles();
|
this.$refs.upload.clearFiles();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 保存当前选择的文件
|
// 保存当前选择的文件
|
||||||
this.selectedFile = file.raw;
|
this.selectedFile = file.raw;
|
||||||
},
|
},
|
||||||
|
|
||||||
// 提交文件表单
|
// 提交文件表单
|
||||||
submitFileForm() {
|
submitFileForm() {
|
||||||
if (!this.selectedFile) {
|
if (!this.selectedFile) {
|
||||||
@ -563,23 +563,23 @@ export default {
|
|||||||
this.$message.error('导入数据为空');
|
this.$message.error('导入数据为空');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 第一行是标题,从第二行开始
|
// 第一行是标题,从第二行开始
|
||||||
const asinList = data.slice(1)
|
const asinList = data.slice(1)
|
||||||
.map(row => row[0])
|
.map(row => row[0])
|
||||||
.filter(asin => asin && typeof asin === 'string' && asin.trim() !== '');
|
.filter(asin => asin && typeof asin === 'string' && asin.trim() !== '');
|
||||||
|
|
||||||
if (asinList.length === 0) {
|
if (asinList.length === 0) {
|
||||||
this.$message.error('未找到有效的ASIN数据');
|
this.$message.error('未找到有效的ASIN数据');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.asinList = asinList;
|
this.asinList = asinList;
|
||||||
this.$message.success(`成功解析到${this.asinList.length}个ASIN`);
|
this.$message.success(`成功解析到${this.asinList.length}个ASIN`);
|
||||||
|
|
||||||
// 保存ASIN列表到缓存
|
// 保存ASIN列表到缓存
|
||||||
this.saveToCache();
|
this.saveToCache();
|
||||||
|
|
||||||
// 关闭对话框并清除文件选择
|
// 关闭对话框并清除文件选择
|
||||||
this.upload.open = false;
|
this.upload.open = false;
|
||||||
this.$refs.upload && this.$refs.upload.clearFiles();
|
this.$refs.upload && this.$refs.upload.clearFiles();
|
||||||
@ -593,44 +593,44 @@ export default {
|
|||||||
this.$message.error('处理文件失败: ' + (error.message || error));
|
this.$message.error('处理文件失败: ' + (error.message || error));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 处理爬取
|
// 处理爬取
|
||||||
handleCrawl() {
|
handleCrawl() {
|
||||||
if (!this.asinList.length) {
|
if (!this.asinList.length) {
|
||||||
this.$message.warning("请先导入ASIN列表");
|
this.$message.warning("请先导入ASIN列表");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.currentProxy) {
|
if (!this.currentProxy) {
|
||||||
this.startCrawl(); // 直接开始爬取,不弹确认框
|
this.startCrawl(); // 直接开始爬取,不弹确认框
|
||||||
} else {
|
} else {
|
||||||
this.startCrawl();
|
this.startCrawl();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 开始爬取
|
// 开始爬取
|
||||||
startCrawl() {
|
startCrawl() {
|
||||||
this.crawling = true;
|
this.crawling = true;
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
|
|
||||||
// 初始化爬取进度
|
// 初始化爬取进度
|
||||||
this.crawlProgress = {
|
this.crawlProgress = {
|
||||||
total: this.asinList.length,
|
total: this.asinList.length,
|
||||||
current: 0,
|
current: 0,
|
||||||
percentage: 0
|
percentage: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
// 分批爬取,每批2个ASIN
|
// 分批爬取,每批2个ASIN
|
||||||
const batchSize = 2;
|
const batchSize = 2;
|
||||||
this.productData = []; // 清空之前的数据
|
this.productData = []; // 清空之前的数据
|
||||||
|
|
||||||
// 清空缓存中的产品数据
|
// 清空缓存中的产品数据
|
||||||
localStorage.removeItem('amazon_products_data');
|
localStorage.removeItem('amazon_products_data');
|
||||||
|
|
||||||
// 开始分批爬取
|
// 开始分批爬取
|
||||||
this.batchCrawl(this.asinList, 0, batchSize);
|
this.batchCrawl(this.asinList, 0, batchSize);
|
||||||
},
|
},
|
||||||
|
|
||||||
// 分批爬取方法
|
// 分批爬取方法
|
||||||
batchCrawl(asinList, startIndex, batchSize) {
|
batchCrawl(asinList, startIndex, batchSize) {
|
||||||
if (startIndex >= asinList.length) {
|
if (startIndex >= asinList.length) {
|
||||||
@ -641,26 +641,26 @@ export default {
|
|||||||
this.saveToCache();
|
this.saveToCache();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算当前批次的结束索引
|
// 计算当前批次的结束索引
|
||||||
const endIndex = Math.min(startIndex + batchSize, asinList.length);
|
const endIndex = Math.min(startIndex + batchSize, asinList.length);
|
||||||
// 获取当前批次的ASIN列表
|
// 获取当前批次的ASIN列表
|
||||||
const currentBatch = asinList.slice(startIndex, endIndex);
|
const currentBatch = asinList.slice(startIndex, endIndex);
|
||||||
|
|
||||||
// 更新进度信息
|
// 更新进度信息
|
||||||
this.crawlProgress.current = startIndex;
|
this.crawlProgress.current = startIndex;
|
||||||
this.crawlProgress.percentage = Math.floor((startIndex / this.crawlProgress.total) * 100);
|
this.crawlProgress.percentage = Math.floor((startIndex / this.crawlProgress.total) * 100);
|
||||||
|
|
||||||
// 调用后端爬取接口
|
// 调用后端爬取接口
|
||||||
request({
|
request({
|
||||||
url: '/tool/webmagic/batch',
|
url: '/tool/webmagic/batch',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: currentBatch,
|
data: currentBatch,
|
||||||
timeout: 9000000
|
timeout: 9000000
|
||||||
}).then(response => {
|
}).then(response => {
|
||||||
if (response.code === 200) {
|
if (response.code === 200) {
|
||||||
this.productData = [...this.productData, ...response.data];
|
this.productData = [...this.productData, ...response.data];
|
||||||
|
|
||||||
this.crawlProgress.current = endIndex;
|
this.crawlProgress.current = endIndex;
|
||||||
this.crawlProgress.percentage = Math.floor((endIndex / this.crawlProgress.total) * 100);
|
this.crawlProgress.percentage = Math.floor((endIndex / this.crawlProgress.total) * 100);
|
||||||
this.batchCrawl(asinList, endIndex, batchSize);
|
this.batchCrawl(asinList, endIndex, batchSize);
|
||||||
@ -672,7 +672,7 @@ export default {
|
|||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
console.error("爬取失败:", error);
|
console.error("爬取失败:", error);
|
||||||
this.$message.error("爬取失败: " + (error.message || error));
|
this.$message.error("爬取失败: " + (error.message || error));
|
||||||
|
|
||||||
if (error.message && error.message.includes('timeout')) {
|
if (error.message && error.message.includes('timeout')) {
|
||||||
this.$message.warning("当前批次请求超时,将尝试继续下一批");
|
this.$message.warning("当前批次请求超时,将尝试继续下一批");
|
||||||
|
|
||||||
@ -690,33 +690,33 @@ export default {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// 导出Excel
|
// 导出Excel
|
||||||
handleExport() {
|
handleExport() {
|
||||||
if (!this.productData.length) {
|
if (!this.productData.length) {
|
||||||
this.$message.warning("没有数据可导出");
|
this.$message.warning("没有数据可导出");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = [
|
const data = [
|
||||||
['ASIN', '卖家/配送方', '当前售价']
|
['ASIN', '卖家/配送方', '当前售价']
|
||||||
];
|
];
|
||||||
|
|
||||||
this.productData.forEach(item => {
|
this.productData.forEach(item => {
|
||||||
const seller = item.seller || '';
|
const seller = item.seller || '';
|
||||||
const shipper = item.shipper ? (item.shipper !== item.seller ? `配送方: ${item.shipper}` : '') : '';
|
const shipper = item.shipper ? (item.shipper !== item.seller ? `配送方: ${item.shipper}` : '') : '';
|
||||||
const sellerInfo = shipper ? `${seller} (${shipper})` : seller;
|
const sellerInfo = shipper ? `${seller} (${shipper})` : seller;
|
||||||
|
|
||||||
data.push([
|
data.push([
|
||||||
item.asin || '',
|
item.asin || '',
|
||||||
sellerInfo,
|
sellerInfo,
|
||||||
item.price || ''
|
item.price || ''
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
exportExcel(data, '亚马逊产品信息', '.et');
|
exportExcel(data, '亚马逊产品信息', '.et');
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 测试代理延迟 */
|
/** 测试代理延迟 */
|
||||||
testProxyDelay() {
|
testProxyDelay() {
|
||||||
if (!this.filteredProxyNodes?.length) {
|
if (!this.filteredProxyNodes?.length) {
|
||||||
@ -726,29 +726,29 @@ export default {
|
|||||||
|
|
||||||
this.startProxyTest(); // 直接开始测试,不弹确认框
|
this.startProxyTest(); // 直接开始测试,不弹确认框
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 开始测试代理节点 */
|
/** 开始测试代理节点 */
|
||||||
startProxyTest() {
|
startProxyTest() {
|
||||||
this.testingDelay = true;
|
this.testingDelay = true;
|
||||||
const proxyNames = this.filteredProxyNodes.map(item => item.name);
|
const proxyNames = this.filteredProxyNodes.map(item => item.name);
|
||||||
|
|
||||||
this.proxyNodes.forEach(proxy => {
|
this.proxyNodes.forEach(proxy => {
|
||||||
if (proxyNames.includes(proxy.name)) {
|
if (proxyNames.includes(proxy.name)) {
|
||||||
proxy.delay = undefined;
|
proxy.delay = undefined;
|
||||||
proxy.testing = true;
|
proxy.testing = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const batches = [];
|
const batches = [];
|
||||||
const batchSize = 10;
|
const batchSize = 10;
|
||||||
|
|
||||||
for (let i = 0; i < proxyNames.length; i += batchSize) {
|
for (let i = 0; i < proxyNames.length; i += batchSize) {
|
||||||
batches.push(proxyNames.slice(i, i + batchSize));
|
batches.push(proxyNames.slice(i, i + batchSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.testNextBatch(batches, 0);
|
this.testNextBatch(batches, 0);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 测试下一批代理节点 */
|
/** 测试下一批代理节点 */
|
||||||
testNextBatch(batches, batchIndex) {
|
testNextBatch(batches, batchIndex) {
|
||||||
if (batchIndex >= batches.length) {
|
if (batchIndex >= batches.length) {
|
||||||
@ -757,7 +757,7 @@ export default {
|
|||||||
this.saveProxyDelaysToCache();
|
this.saveProxyDelaysToCache();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
request({
|
request({
|
||||||
url: '/tool/webmagic/proxy/test',
|
url: '/tool/webmagic/proxy/test',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
@ -776,10 +776,10 @@ export default {
|
|||||||
this.handleTestError(error.message || '网络错误', batches, batchIndex);
|
this.handleTestError(error.message || '网络错误', batches, batchIndex);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
updateProxyDelays(results) {
|
updateProxyDelays(results) {
|
||||||
if (!results?.length) return;
|
if (!results?.length) return;
|
||||||
|
|
||||||
results.forEach(result => {
|
results.forEach(result => {
|
||||||
const proxyNode = this.proxyNodes.find(p => p.name === result.name);
|
const proxyNode = this.proxyNodes.find(p => p.name === result.name);
|
||||||
if (proxyNode) {
|
if (proxyNode) {
|
||||||
@ -789,11 +789,11 @@ export default {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 处理测试错误 */
|
/** 处理测试错误 */
|
||||||
handleTestError(errorMsg, batches, batchIndex) {
|
handleTestError(errorMsg, batches, batchIndex) {
|
||||||
console.error('测试代理延迟失败:', errorMsg);
|
console.error('测试代理延迟失败:', errorMsg);
|
||||||
|
|
||||||
batches[batchIndex].forEach(proxyName => {
|
batches[batchIndex].forEach(proxyName => {
|
||||||
const proxyNode = this.proxyNodes.find(p => p.name === proxyName);
|
const proxyNode = this.proxyNodes.find(p => p.name === proxyName);
|
||||||
if (proxyNode?.testing) {
|
if (proxyNode?.testing) {
|
||||||
@ -802,13 +802,13 @@ export default {
|
|||||||
proxyNode.testing = false;
|
proxyNode.testing = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.$message.warning('部分代理测试失败,继续测试下一批');
|
this.$message.warning('部分代理测试失败,继续测试下一批');
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.testNextBatch(batches, batchIndex + 1);
|
this.testNextBatch(batches, batchIndex + 1);
|
||||||
}, 500);
|
}, 500);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 获取延迟样式类 */
|
/** 获取延迟样式类 */
|
||||||
getDelayClass(delay) {
|
getDelayClass(delay) {
|
||||||
if (delay === undefined || delay < 0) return 'delay-error';
|
if (delay === undefined || delay < 0) return 'delay-error';
|
||||||
@ -818,7 +818,7 @@ export default {
|
|||||||
if (delay < 1000) return 'delay-slow';
|
if (delay < 1000) return 'delay-slow';
|
||||||
return 'delay-very-slow';
|
return 'delay-very-slow';
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 格式化延迟显示 */
|
/** 格式化延迟显示 */
|
||||||
formatDelay(delay) {
|
formatDelay(delay) {
|
||||||
if (delay === undefined) return '';
|
if (delay === undefined) return '';
|
||||||
|
@ -7,7 +7,7 @@ function resolve(dir) {
|
|||||||
|
|
||||||
const CompressionPlugin = require('compression-webpack-plugin')
|
const CompressionPlugin = require('compression-webpack-plugin')
|
||||||
|
|
||||||
const name = process.env.VUE_APP_TITLE || '若依管理系统' // 网页标题
|
const name = 'ERP管理系统' // 网页标题
|
||||||
|
|
||||||
const baseUrl = 'https://erp.tashowz.com' // 后端接口
|
const baseUrl = 'https://erp.tashowz.com' // 后端接口
|
||||||
//const baseUrl = 'http://43.136.31.205:8080'
|
//const baseUrl = 'http://43.136.31.205:8080'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user