This commit is contained in:
ZiJIe 2025-06-24 18:27:57 +08:00
parent a61e54cea2
commit 0a2e896962
8 changed files with 131 additions and 130 deletions

View File

@ -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" +
" ''-' `'-' `-..-' "); " ''-' `'-' `-..-' ");
} }
} }

View File

@ -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();

View File

@ -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

View File

@ -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'

View File

@ -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'

View File

@ -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": {

View File

@ -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
}; };
// 2ASIN // 2ASIN
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 '';

View File

@ -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'