<template>
	<div>
		<el-container style="height: 100vh;">
			<!-- #333744 -->
			<el-aside width="180px" style="user-select: none; border-right: 1px solid #fafafa; background-color: #333744; overflow-x: hidden;">
				<p class="soft-name" style="-webkit-app-region: drag; color: #fff;">
					<img src="../assets/image/icon.png" class="soft-icon" />
					<span style="letter-spacing: 1px;">{{productName}}</span>
				</p>
				
				<el-menu :default-openeds="['a', 'b']" :default-active="menuIndex" @select="setMenuIndex" active-text-color="#409EFF" background-color="#333744" text-color="#fff" style="margin-top: 10px;">
					<el-submenu index="a">
						<template slot="title"><img src="../assets/image/m-download.png" class="m-image"/>图片下载</template>
						<el-menu-item index="3">
							<img src="../assets/image/m-tmall.png" class="m-image"/><span slot="title">天猫</span>
						</el-menu-item>
						<el-menu-item index="2">
							<img src="../assets/image/m-jd.png" class="m-image"/><span slot="title">京东</span>
						</el-menu-item>
						<el-menu-item index="4">
							<img src="../assets/image/m-taobao.png" class="m-image"/><span slot="title">淘宝</span>
						</el-menu-item>
						<el-menu-item index="1">
							<img src="../assets/image/m-alibaba.png" class="m-image"/><span slot="title">阿里巴巴</span>
						</el-menu-item>
						<el-menu-item index="5">
							<img src="../assets/image/m-hong.png" class="m-image"/><span slot="title">小红书</span>
						</el-menu-item>
						<el-menu-item index="10">
							<img src="../assets/image/m-chrome.png" class="m-image"/><span slot="title">其他网址(Beta)</span>
						</el-menu-item>
					</el-submenu>
					
					<el-submenu index="b">
						<template slot="title"><img src="../assets/image/m-edit.png" class="m-image"/>图片处理</template>
						<el-menu-item index="2-1">
							<img src="../assets/image/m-geshi.png" class="m-image"/><span slot="title">格式转换</span>
						</el-menu-item>
						<el-menu-item index="2-2">
							<img src="../assets/image/m-yasuo.png" class="m-image"/><span slot="title">图片压缩</span>
						</el-menu-item>
						<el-menu-item index="2-3">
							<img src="../assets/image/m-chicun.png" class="m-image"/><span slot="title">修改尺寸</span>
						</el-menu-item>
						<el-menu-item index="2-5">
							<img src="../assets/image/m-shuiyin.png" class="m-image"/><span slot="title">添加水印</span>
						</el-menu-item>
					</el-submenu>
				</el-menu>
			</el-aside>
			
			<el-container>
				<el-header height="45px" style="background-color: #fafafa; padding: 0 10px;">
					<soft-header ref="headerRef" @update-soft="updateSoft()" @export-file="exportFile" @login-url="loginUrl" @clear-cache="clearCache"></soft-header>
				</el-header>
				
				<soft-img ref="imgRef" v-show="['2-1', '2-2', '2-3', '2-5'].indexOf(menuIndex) > -1" @open-vip="openVip" @check-authority="checkAuthority"></soft-img>
				
				<el-main v-show="['1', '2', '3', '4', '5', '10'].indexOf(menuIndex) > -1" ref="el-main" style="background-color: #fafafa;">
					<template>
						<div class="content-top">
							<div>
								<el-button-group>
									<el-button type="primary" size="mini" icon="el-icon-circle-plus-outline"
										@click="addVisible = true;">添加链接</el-button>
									<el-button type="primary" size="mini" icon="el-icon-upload"
										@click="pickLink()">导入链接</el-button>
									<el-button type="primary" size="mini" icon="el-icon-delete"
										@click="clearList()">清空链接</el-button>
								</el-button-group>
								
								<el-link type="info" style="margin-left: 20px; vertical-align:baseline;" @click="downloadExample()">模板下载<i class="el-icon-download"></i></el-link>
							</div>
							
							<el-row type="flex" style="align-items: center;">
								<div class="set-item">
									<span class="set-title">保存目录：</span>
									<el-input :title="downloadDir" ref="upload-input" size="mini" @focus="pickPath" placeholder="请选择输出目录" v-model="downloadDir" readonly style="width:200px;" prefix-icon="el-icon-folder"></el-input>
									<el-popover placement="bottom" popper-class="popper-open" trigger="hover" content="打开保存目录">
										<i class="el-icon-folder-opened" slot="reference" style="padding-left: 5px; cursor: pointer; font-size: 22px; vertical-align: middle;" @click="openFolder()"></i>
									</el-popover>
								</div>
								
								<el-button type="danger" @click="exportFile()" :loading="loading">开始下载</el-button>
							</el-row>
						</div>
						
						<div style="padding: 20px 20px 0 20px; height: calc(100% - 62px);">
							<el-row type="flex" justify="space-between">
								<div>
									<h3 style="display: inline-block;">
										<span v-if="menuIndex == '1'">阿里巴巴 - </span>
										<span v-if="menuIndex == '2'">京东 - </span>
										<span v-if="menuIndex == '3'">天猫 - </span>
										<span v-if="menuIndex == '4'">淘宝 - </span>
										<span v-if="menuIndex == '5'">小红书 - </span>
										<span v-if="menuIndex == '10'">网页 - </span>
										图片下载
									</h3>
									<el-link v-if="menuIndex == '5'" :underline="false" type="danger" style="text-align: center; font-size: 12px;">
										仅支持win10及以上系统，浏览器请选择最新版本
									</el-link>
									
									<!-- <el-link v-if="menuIndex == '3' || menuIndex == '4'" :underline="false" type="danger" style="text-align: center; font-size: 12px;">
										(需登录{{menuIndex == '3' ? '天猫' : '淘宝'}}账号后才能下载)
									</el-link>
									<el-link v-if="menuIndex == '2'" :underline="false" type="danger" style="text-align: center; font-size: 12px;">
										(需登录京东账号后才能下载)
									</el-link>
									<el-link v-if="menuIndex == '10'" :underline="false" type="info" style="text-align: center; font-size: 12px;">
										 (非会员功能，仅提供试用)
									</el-link> -->
								</div>
							</el-row>
							
							<div style="padding: 15px 0 20px;">
								<el-row type="flex" justify="space-between">
									<div v-if="menuIndex == '5'" style="padding-top: 10px;">
										<label>下载类型：</label>
										<el-checkbox :value="true" style="opacity: 0.6; cursor: not-allowed;">文章图/视频</el-checkbox>
										<el-popover placement="bottom" popper-class="popper-open" trigger="hover" content="实况(Live)图下载的格式是mp4,且同时下载任务量必须为1个">
											<i class="el-icon-info" slot="reference" style="margin-left: 10px; color: #F56C6C;"></i>
										</el-popover>
									</div>
									
									<div v-if="menuIndex == '10'" style="padding-top: 10px;">
										<label>下载类型：</label>
										<el-checkbox :value="true" style="opacity: 0.6; cursor: not-allowed;">图片</el-checkbox>
									</div>
									
									<div v-if="['1', '2', '3', '4'].indexOf(menuIndex) > -1" style="padding-top: 10px;">
										<label>下载类型：</label>
										<el-checkbox-group :min="1" v-model="settingArr" style="display: inline-block;" @input="settingGroup">
											<el-checkbox label="mainImg">主图</el-checkbox>
											<el-checkbox label="detailImg">详情图</el-checkbox>
											<el-checkbox label="skuImg">SKU图</el-checkbox>
											<el-checkbox label="commentImg" v-if="menuIndex == '3' || menuIndex == '4'">评论图</el-checkbox>
											<el-checkbox label="video">视频</el-checkbox>
										</el-checkbox-group>
										<el-popover placement="bottom" popper-class="popper-open" trigger="hover" content="下载类型至少选一个,评论图默认只下载商品首页展示的评论内容">
											<i class="el-icon-info" slot="reference" style="margin-left: 10px; color: #F56C6C;"></i>
										</el-popover>
									</div>
									
									<!-- 阿里巴巴账号 -->
									<template v-if="menuIndex == '1'">
										<div>
											<el-tag type="info" size="mini" v-if="alibabaStatus == 1">未检测</el-tag>
											<el-tag type="success" size="mini" v-if="alibabaStatus == 2">阿里巴巴账号已登录</el-tag>
											<el-link type="danger" style="text-decoration: underline;" v-if="alibabaStatus == 3" :underline="false" @click="loginUrl('https://www.1688.com')">未登录，点击登录阿里巴巴账号</el-link>
											<el-button size="mini" type="warning" :loading="checkLoading" style="margin-left: 10px;" :disabled='alibabaStatus == 2' @click="checkAlibabaLogin">检测登录状态</el-button>
										</div>
									</template>
									
									<!-- 天猫/淘宝 -->
									<template v-if="menuIndex == '3' || menuIndex == '4'">
										<div>
											<el-tag type="info" size="mini" v-if="tbStatus == 1">未检测</el-tag>
											<el-tag type="success" size="mini" v-if="tbStatus == 2">{{menuIndex == '3' ? '天猫' : '淘宝'}}账号已登录</el-tag>
											<el-link type="danger" style="text-decoration: underline;" v-if="tbStatus == 3" :underline="false" @click="loginUrl('https://login.taobao.com')">未登录，点击登录<span>{{menuIndex == '3' ? '天猫' : '淘宝'}}</span>账号</el-link>
											<el-button size="mini" type="warning" :loading="checkLoading" style="margin-left: 10px;" :disabled='tbStatus == 2' @click="checkLogin">检测登录状态</el-button>
										</div>
									</template>
									
									<!-- 京东账号 -->
									<template v-if="menuIndex == '2'">
										<div>
											<el-tag type="info" size="mini" v-if="jdStatus == 1">未检测</el-tag>
											<el-tag type="success" size="mini" v-if="jdStatus == 2">京东账号已登录</el-tag>
											<el-link type="danger" style="text-decoration: underline;" v-if="jdStatus == 3" :underline="false" @click="loginUrl('https://passport.jd.com/new/login.aspx')">未登录，点击登录京东账号</el-link>
											<el-button size="mini" type="warning" :loading="checkLoading" style="margin-left: 10px;" :disabled='jdStatus == 2' @click="checkJdLogin">检测登录状态</el-button>
										</div>
									</template>
									
									<!-- 小红书 -->
									<template v-if="menuIndex == '5'">
										<div>
											<el-tag type="info" size="mini" v-if="redStatus == 1">未检测</el-tag>
											<el-tag type="success" size="mini" v-if="redStatus == 2">小红书账号已登录</el-tag>
											<el-link type="danger" style="text-decoration: underline;" v-if="redStatus == 3" :underline="false" @click="loginUrl('https://www.xiaohongshu.com')">未登录，点击登录小红书账号</el-link>
											<el-button size="mini" type="warning" :loading="checkLoading" style="margin-left: 10px;" :disabled='redStatus == 2' @click="checkRedLogin">检测登录状态</el-button>
										</div>
									</template>
								</el-row>
							</div>
						
							<div class="table-scroll">
								<!-- 1、 -->
								<vxe-table ref="xTable" show-overflow class="img-table" max-height="100%" empty-text="没有更多数据了！" :loading="tabLoading" :row-config="{isHover: true}" 
									:loading-config="{icon: 'vxe-icon-indicator roll', text: '列表加载中...'}" :data="this[listStr+'List']" :scroll-y="{enabled: true}">
									<vxe-column type="seq" width="60"></vxe-column>
									<vxe-column field="title" title="目录名称" width="200">
										<template #default="{ row, rowIndex }">
											<span v-if="row.title">{{row.title}}</span>
											<el-tag size="mini" v-else>默认使用网页标题</el-tag>
										</template>
									</vxe-column>
									<vxe-column field="url" title="网页链接"></vxe-column>
									<vxe-column field="status" title="下载状态" width="200">
										<template #default="{ row }">
											<template v-if="row.status == '1'">
												<i class="el-icon-info" style="font-size: 16px; color: #999;"></i>
												<span>待操作</span>
											</template>
											<template v-if="row.status == '2'">
												<i class="el-icon-loading" style="font-size: 16px; color: #999;"></i>
												<span>任务处理中...</span>
											</template>
											<template v-if="row.status == '3'">
												<i class="el-icon-loading" style="font-size: 16px; color: #999;"></i>
												<span>图片下载中..<span v-if="row.num > 0">第{{row.num}}张</span></span>
											</template>
											<template v-if="row.status == '4'">
												<i class="el-icon-success" style="font-size: 16px; color: #19be6b;"></i>
												<span>下载完成</span>
											</template>
											<template v-if="row.status == '5'">
												<i class="el-icon-error" style="font-size: 16px; color: #ed4014;"></i>
												<span>网络异常,请重试!</span>
											</template>
											<template v-if="row.status == '6'">
												<i class="el-icon-error" style="font-size: 16px; color: #ed4014;"></i>
												<span>验证码拦截,请手动验证!</span>
											</template>
										</template>
									</vxe-column>
									<vxe-column title="操作" width="80">
										<template #default="{ row, rowIndex }">
											<i class="el-icon-delete cur-pointer" style="font-size: 20px;" @click="delFile(rowIndex)"></i>
										</template>
									</vxe-column>
								</vxe-table>
							</div>
						</div>
			
					</template>
					
					
					<el-dialog title="添加链接" :visible.sync="addVisible" width="500px" :close-on-click-modal="false" :close-on-press-escape="false" :show-close="false">
						<div>
							<el-form label-position="right" label-width="80px" :rules="rules" :model="formData" ref="formData">
								<el-form-item label="目录名称" prop="title">
									<el-input v-model="formData.title" placeholder="为空则默认使用网页标题前50个字符"></el-input>
								</el-form-item>
								<el-form-item label="网页链接" prop="url">
									<el-input type="textarea" :rows="10" v-if="menuIndex < 10" :placeholder="'请输入网址链接(例:' + exampleUrl[menuIndex-1] + ')'" v-model="formData.url"></el-input>
									<el-input type="textarea" :rows="10" v-else :placeholder="'请输入网址链接'" v-model="formData.url"></el-input>
								</el-form-item>
							</el-form>
						</div>
						<span slot="footer" class="dialog-footer">
							<el-button @click="addVisible = false; $refs['formData'].resetFields();">取 消</el-button>
							<el-button type="primary" @click="onSubmit">确 定</el-button>
						</span>
					</el-dialog>
					
					<el-dialog title="提示" :visible.sync="loginVisible" width="400px" :close-on-click-modal="false" :close-on-press-escape="false">
						<div style="text-align: center; color: #999; font-size: 14px;">
							<template v-if="menuIndex == '2'">
								<p>京东渠道需要登录后才能下载</p>
								<p class="visible-tips-style">目前检测还未登录京东账号，需立即登录</p>
							</template>
							<template v-else-if="menuIndex == '5'">
								<p>小红书渠道需要登录后才能下载</p>
								<p class="visible-tips-style">目前检测还未登录小红书账号，需立即登录</p>
							</template>
							<template v-else>
								<p>天猫/淘宝渠道需要登录后才能下载</p>
								<p class="visible-tips-style">目前检测还未登录天猫/淘宝账号，需立即登录</p>
							</template>
							
						</div>
						<div slot="footer" class="dialog-footer-center">
							<el-button v-if="menuIndex == '2'" @click="loginVisible = false; loginUrl('https://passport.jd.com/new/login.aspx')">点击登录京东账号</el-button>
							<el-button v-else-if="menuIndex == '5'" @click="loginVisible = false; loginUrl('https://www.xiaohongshu.com')">点击登录小红书账号</el-button>
							<el-button v-else @click="loginVisible = false; loginUrl('https://login.taobao.com')">点击登录天猫/淘宝账号</el-button>
						</div>
					</el-dialog>
					
					<!-- 非会员转换提示框 -->
					<el-dialog title="非会员提示" :visible.sync="tipsModal" width="400px">
						<div class="member-model">
							<div class="tips-flex">
								<i class="el-icon-s-opportunity"></i>
								<p class="m-title">{{tipsDesc}}</p>
							</div>
							<div class="member-btn">
								<el-button size="small" round type="primary" @click="openVip()">开通会员</el-button>
							</div>
						</div>
					</el-dialog>
			
				</el-main>
				
				<el-footer height="48px">
					<!-- 更新 -->
					<soft-update ref="updateRef" :showDowload="dowloadModel" :dowloadFinish="finishModel"></soft-update>
				</el-footer>
			</el-container>
		</el-container>
	</div>
</template>

<script>
	import os from 'os'
	import fs from 'fs'
	import request from 'request'
	import path from 'path';
	import xlsx from 'node-xlsx';
	import softUpdate from './update.vue';
	import softHeader from './header.vue';
	import softImg from './img.vue';
	import electronApi from '@/utils/electronApi';
	import pjson from '/package.json'
	// import puppeteer from 'puppeteer'
	import puppeteer from 'puppeteer-extra'
	const StealthPlugin = require('puppeteer-extra-plugin-stealth');

	let separator = '';
	if (os.platform == 'linux') {
		separator = '/'
	} else {
		separator = '\\'
	}
	
	// let chromePath = process.cwd() + '\\resources\\app\\node_modules\\puppeteer\\.local-chromium\\win64-1045629\\chrome-win\\chrome.exe';
	// if (process.env.NODE_ENV == 'development') {
	//     chromePath = process.cwd() + '\\node_modules\\puppeteer\\.local-chromium\\win64-1045629\\chrome-win\\chrome.exe';
	// }
	export default {
		name: 'landing-page',
		components: {
			softUpdate,
			softHeader,
			softImg
		},
		data() {
			return {
				tipsModal: false,
				tipsDesc: "非VIP用户不能下载视频，如需完整功能请开通VIP会员。",
				settingArr: ['mainImg'],
				loginVisible: false,
				addVisible: false,
				formData: {
					title: '',
					url: ''
				},
				rules:{ //   
					title: [
						{ min: 0, max: 50, message: '不能超过 50 个字符', trigger: 'blur' },  
						{ pattern: /^[^\\/:*?"<>|]*$/, message: '标题中不能包含 \\ / : * ? " < > |', trigger: 'blur' } 
					],
					url: [
						{ required: true, message: '请输入网页链接', trigger: 'blur' },
						{ pattern: /^(http|https):\/\/.+$/, message: '请输入正确的网址链接(http://或https://开头)', trigger: 'blur' } 
					],
				},
				tabLoading: false,
				alibabaList: [],
				jdList: [],
				tbList: [],
				tmallList: [],
				redList: [],
				commonList: [],
				productName: pjson.softInfo.softName,
				imgUrl: this.$api.imgUrl,
				imgSrc: '',
				menuIndex: '3',
				settingData: {
					detailImg: true,
					skuImg: true,
					commentImg: false,
					video: false,
				},
				exampleUrl: ['https://www.1688.com', 'https://www.jd.com', 'https://www.tmall.com', 'https://www.taobao.com', 'https://www.xiaohongshu.com'],

				fileList: [],
				
				downloadDir: os.userInfo().homedir + separator + "Downloads",
				dowloadModel: false,
				finishModel: false,

				loading: false,
				checkLoading: false, //点击检测登录状态
				tbStatus: 1, // 1、未检测 2、已经登录 3、未登录 
				jdStatus: 1, // 1、未检测 2、已经登录 3、未登录 
				redStatus: 1, //同上
				alibabaStatus: 1, //同上上
				execLimit: 2,
				execNum: 3, // 限制5张
				
				/** 浏览器名称 **/
				alibabaBrowser: null,
				tbBrowser: null,
				jdBrowser: null,
				otherBrowser: null,
				redBrowser: null,
				loginBrowser: null, // 登录用的浏览器实例
			};
		},
		computed: {
			listStr: function(){
				let str = 'alibaba';
				switch(this.menuIndex){
					case '1':
						str = 'alibaba';
						break;
					case '2':
						str = 'jd';
						break;
					case '3':
						str = 'tmall';
						break;
					case '4':
						str = 'tb';
						break;
					case '5':
						str = 'red';
						break;
					case '10':
						str = 'common';
						break;
				}
				return str;
			}
		},
		async mounted() {
			this.$refs.updateRef.updateSoft(true);

			let homedir = os.userInfo().homedir;
			if (fs.existsSync(homedir + separator + "Desktop")) {
				this.downloadDir = homedir + separator + "Desktop"
			} else {
				this.downloadDir = homedir + separator + "Downloads"
			}
			
			if (!fs.existsSync(os.tmpdir() + separator + 'chrome-data-capture')) {
				fs.mkdirSync(os.tmpdir() + separator + 'chrome-data-capture');
			}
			
			if (!fs.existsSync(os.tmpdir() + separator + 'chrome-data-capture-jd')) {
				fs.mkdirSync(os.tmpdir() + separator + 'chrome-data-capture-jd');
			}
			
			let path = os.tmpdir() + separator + 'chrome-data-capture';
			let path2 = os.tmpdir() + separator + 'chrome-data-capture-jd';
			//this.deleteAll(path, false);
			//this.deleteAll(path2, false);

			// 打开浏览器
			const {
				shell
			} = require('electron');
			const links = document.querySelectorAll('a[href]');
			links.forEach(link => {
				link.addEventListener('click', e => {
					const url = link.getAttribute('href');
					e.preventDefault();
					shell.openExternal(url);
				});
			});
			
			// 判断系统版本 低于10使用兼容模式
			if(os.release() && os.release().indexOf('.') > -1){
				let systemVersion = Number(os.release().split('.')[0]);
				if(systemVersion < 10){ // 低于win10，软件打开时候浏览器设置为兼容版
					this.$utils.setStorage('versionType', 1);
				}else{
					this.$utils.setStorage('versionType', 2);
				}
			}
		},
		methods: {
			// 实时获取浏览器路径
			initPath(){
				let chromePath = puppeteer.executablePath().replace('win32-1', 'win64-1');
				let versionType = this.$utils.getStorage('versionType');
				if(versionType && versionType == 1){
					chromePath = chromePath.replace('chrome-win', 'chrome7');
				}
				return chromePath;
			},
			// 删除文件夹内容
			deleteAll(folderPath, flag) {
				if (fs.existsSync(folderPath)) {
					fs.readdirSync(folderPath).forEach((file, index) => {
						var curPath = path.join(folderPath, file);
						if (fs.lstatSync(curPath).isDirectory()) {
							this.deleteAll(curPath, true);
						} else {
							fs.unlinkSync(curPath);
						}
					});
					if(flag){
						fs.rmdirSync(folderPath);
					}
				}
			},
			checkAuthority(){
				let authority = this.$refs.headerRef.authority;
				this.$refs.imgRef.authority = authority;
			},
			setMenuIndex(index){
				this.menuIndex = index;
				if(index.indexOf('2-') > -1){
					let num = Number(index.split('-')[1]);
					this.$refs.imgRef.setMenuIndex(num);
				}
			},
			// 选择目录
			pickPath() {
				this.$refs['upload-input'].blur();
				electronApi.call('pickDir', []).then((path) => {
					if (path) {
						this.downloadDir = path;
					}
				});
			},
			// 打开自定义下载目录
			openFolder() {
				let path = this.downloadDir;
				if (fs.existsSync(this.downloadDir + separator + pjson.softInfo.softName)) {
					path = this.downloadDir + separator + pjson.softInfo.softName;
				} else {
					fs.mkdirSync(this.downloadDir + separator + pjson.softInfo.softName);
					path = this.downloadDir + separator + pjson.softInfo.softName;
				}
				electronApi.call('showItemInfolder', [path + '\\tty.tty'])
			},
			openVip() {
				this.$refs.headerRef.openVip();
			},
			updateSoft() {
				this.$refs.updateRef.updateSoft();
			},
			// 删除文件
			delFile(rowIndex){
				let type = 'alibaba';
				switch(this.menuIndex){
					case '1':
						type = 'alibaba';
						break;
					case '2':
						type = 'jd';
						break;
					case '3':
						type = 'tmall';
						break;
					case '4':
						type = 'tb';
						break;
					case '5':
						type = 'red';
						break;
					case '10':
						type = 'common';
						break;
				}
				this.$confirm('确认删除此行数据吗?', '提示', {
					confirmButtonText: '确定',
					cancelButtonText: '取消',
					type: 'warning'
				}).then(() => {
					this[type+'List'].splice(rowIndex, 1);
					if(this[type+'List'].length == 0) {
						this.clearList();
					}
				}).catch(() => {
						  
				});
			},
			// 清除列表
			clearList() {
				switch(this.menuIndex){
					case '1':
						this.alibabaList = [];
						break;
					case '2':
						this.jdList = [];
						break;
					case '3':
						this.tmallList = [];
						break;
					case '4':
						this.tbList = [];
						break;
					case '5':
						this.redList = [];
						break;
					case '10':
						this.commonList = [];
						break;
				}
			},
			// 提交表单
			onSubmit(){
				this.$refs['formData'].validate((valid) => {
					if (valid) {
						let info = {
							url: this.formData.url,
							title: this.formData.title,
							status: '1',
							num: 0,
							newPath: ''
						}
						switch(this.menuIndex){
							case '1':
								this.alibabaList.push(info);
								break;
							case '2':
								this.jdList.push(info);
								break;
							case '3':
								this.tmallList.push(info);
								break;
							case '4':
								this.tbList.push(info);
								break;
							case '5':
								this.redList.push(info);
								break;
							case '10':
								this.commonList.push(info);
								break;
						}
						this.$refs['formData'].resetFields();
						this.addVisible = false;
					} else {
						return false;
					}
				});
			},
			async pickLink() { // 导入链接
				const spinLoad = this.$loading();
				await electronApi.call('pickFile', ['xlsx,xls', true]).then(async (path) => {
					spinLoad.close();
					if(path.length > 0){
						this.$notify({
							title: '提示',
							message: '导入成功',
							type: 'success'
						});
						let workSheetsFromBuffer = xlsx.parse(fs.readFileSync(path[0]));
						if(workSheetsFromBuffer && workSheetsFromBuffer.length > 0){
							let errMsg = "";
							workSheetsFromBuffer[0].data.map((item, index) => {
								if(item.length > 0){
									let ititle = '';
									if(item[0]){
										ititle = item[0].toString().trim();
									}
									
									if(item[0] == '目录名称' && item[1] == '网页链接'){
										return false;
									}

									if(this.containsAnyChar(ititle.toString(), ['\\', '/', ':', '*', '?', '"', '<', '>', '|'])){  //判断是否含有特殊字符
										errMsg += "第" + (index+1) + '行-名称不能包以下字符 \\ / : * ? " < > |';
										ititle = ititle.replace(/[\\|/|:|*|?|"|<|>||]/g, "");
									}
									if(item[1] == undefined){
										errMsg += "第" + (index+1) + "行格式有误</br>";
										item[1] = '';
									}else if(!/^(http|https):\/\/.+$/.exec(item[1])){
										errMsg += "第" + (index+1) + "行网址格式有误</br>";
									}else{
										let info = {
											url: item[1],
											title: ititle,
											status: '1',
											num: 0,
											newPath: ''
										}
										switch(this.menuIndex){
											case '1':
												this.alibabaList.push(info);
												break;
											case '2':
												this.jdList.push(info);
												break;
											case '3':
												this.tmallList.push(info);
												break;
											case '4':
												this.tbList.push(info);
												break;
											case '5':
												this.redList.push(info);
												break;
											case '10':
												this.commonList.push(info);
												break;
										}
									}
								}
							});
							if(errMsg){
								this.$notify({
									title: '请检查文件以下问题',
									dangerouslyUseHTMLString: true,
									message: errMsg,
									type: 'warning'
								});
							}
						}else{
							this.$notify({
								title: '提示',
								message: '格式有误，请重新导入',
								type: 'warning'
							});
						}
					}
				});
			},
			settingGroup(name){
				let authority = this.$refs.headerRef.authority.isAuthority;
				let index = name.indexOf('video');
				if(index > -1 && !authority){ // 非会员选中下载视频选项-提示
					this.tipsModal = true;
					name.splice(index, 1);
				}
			},
			// 清除缓存
			async clearCache(){
				this.jdStatus = 3;
				this.tbStatus = 3;
				this.redStatus = 3;
				
				if(this.loginBrowser){
					await this.loginBrowser.close();
					this.loginBrowser = null;
				}
				if(this.alibabaBrowser){
					await this.alibabaBrowser.close();
					this.alibabaBrowser = null;
				}
				if(this.tbBrowser){
					await this.tbBrowser.close();
					this.tbBrowser = null;
				}
				if(this.jdBrowser){
					await this.jdBrowser.close();
					this.jdBrowser = null;
				}
				if(this.redBrowser){
					await this.redBrowser.close();
					this.redBrowser = null;
				}
				if(this.otherBrowser){
					await this.otherBrowser.close();
					this.otherBrowser = null;
				}
			},
			
			// 去登录
			loginUrl(url){
				(async () => {
					try{
						if (!fs.existsSync(os.tmpdir() + separator + 'chrome-data-capture')) {
							fs.mkdirSync(os.tmpdir() + separator + 'chrome-data-capture');
						}
						if (!fs.existsSync(os.tmpdir() + separator + 'chrome-data-capture-jd')) {
							fs.mkdirSync(os.tmpdir() + separator + 'chrome-data-capture-jd');
						}
						
						let userDataDir = os.tmpdir() + separator + 'chrome-data-capture';
						if(url.indexOf('.jd.com/') > -1){
							userDataDir = os.tmpdir() + separator + 'chrome-data-capture-jd';
						}
						
						this.loginBrowser = await puppeteer.launch({
							headless: false,
							executablePath: this.initPath(),
							args: ['--window-size=1280,800'],
							userDataDir: userDataDir, 
						});
						const page = await this.loginBrowser.newPage();
						await page.setViewport({ width: 1280, height: 800 });
						
						await page.evaluateOnNewDocument(() => {
						    const newProto = navigator.__proto__;
							delete newProto.webdriver;
							navigator.__proto__ = newProto;
						});
						await page.goto(url, {waitUntil : 'networkidle2'});
					}catch(e){
						this.showError(e);
					}
				})();
			},
			
			// 开始下载
			async exportFile(flag) {
				if(this.loginBrowser){
					await this.loginBrowser.close();
					this.loginBrowser = null;
				}
				let authority = this.$refs.headerRef.authority.isAuthority;
				if (!fs.existsSync(this.downloadDir + separator + pjson.softInfo.softName)) {
					fs.mkdirSync(this.downloadDir + separator + pjson.softInfo.softName);
				}
				
				let fileList = [];
				switch(this.menuIndex){
					case '1': // 阿里巴巴
						fileList = this.alibabaList;
						break;
					case '2': // 京东
						fileList = this.jdList;
						break;
					case '3': // 天猫
						fileList = this.tmallList;
						break;
					case '4': // 淘宝
						fileList = this.tbList;
						break;
					case '5': // 小红书
						fileList = this.redList;
						break;
					case '10': // 普通网址
						fileList = this.commonList;
						break;
				}
				
				if(fileList.length > 0){
					if (!authority && !flag) { // 非会员点击转换弹出提示框
						this.$refs.headerRef.memberModel = true;
						this.$refs.headerRef.isClick = true;
						return false;
					} else {
						this.$refs.headerRef.memberModel = false;
						this.loading = true;
						setTimeout(() => {
							this.loading = false;
						}, 60000);
					}
					
					if (!fs.existsSync(os.tmpdir() + separator + 'chrome-data-capture')) {
						fs.mkdirSync(os.tmpdir() + separator + 'chrome-data-capture');
					}
					
					if(this.menuIndex == '2'){ // 京东
						if(this.jdStatus == 1 || this.jdStatus == 3){  // 未检测登录状态/或提示未登录状态，开始检测
							await this.checkJdLogin().then((data) => {
								if(data != 2){  // 未登录
									this.jdStatus = 3;
									this.loginVisible = true;
								}
							}).catch(err => {
								this.jdStatus = 3;
							});
							if(this.jdStatus == 3){
								this.loading = false;
								return false;
							}
						}
					}
					
					if(this.menuIndex == '3' || this.menuIndex == '4'){ // 天猫/淘宝
						if(this.tbStatus == 1 || this.tbStatus == 3){  // 未检测登录状态/或提示未登录状态，开始检测
							await this.checkLogin().then((data) => {
								if(data != 2){ // 未登录
									this.tbStatus = 3;
									this.loginVisible = true;
								}
							}).catch(err => {
								this.tbStatus = 3;
							});
						}
						if(this.tbStatus == 3){
							this.loading = false;
							return false;
						}
					}
					
					if(this.menuIndex == '5'){ // 小红书
						if(this.redStatus == 1 || this.redStatus == 3){  // 未检测登录状态/或提示未登录状态，开始检测
							await this.checkRedLogin().then((data) => {
								if(data != 2){  // 未登录
									this.redStatus = 3;
									this.loginVisible = true;
								}
							}).catch(err => {
								this.redStatus = 3;
							});
							if(this.redStatus == 3){
								this.loading = false;
								return false;
							}
						}
					}
					
					let taskArr = [];
					let task = "";
					let browserName = '';
					let userDataDir = os.tmpdir() + separator + 'chrome-data-capture';
					switch(this.menuIndex){
						case '1': // 阿里巴巴
							browserName = 'alibaba';
							break;
						case '2': // 京东
							browserName = 'jd';
							userDataDir = os.tmpdir() + separator + 'chrome-data-capture-jd';
							break;
						case '3': // 天猫
						case '4': // 淘宝
							browserName = 'tb';
							break;
						case '5': // 小红书
							browserName = 'red';
							break;
						case '10': // 普通网址
							browserName = 'other';
							break;
					}
					// 运行不同平台的浏览器
					puppeteer.use(StealthPlugin());
					this[browserName + 'Browser'] = await puppeteer.launch({
						executablePath: this.initPath(),
						userDataDir: userDataDir, 
						args: [
							'--start-maximized',
							'--no-sandbox',
							'--disable-setuid-sandbox',
							'--disable-blink-features=AutomationControlled',
						]
					});
					
					for(let i = 0; i < fileList.length; i++){
						let item = fileList[i];
						
						switch(this.menuIndex){
							case '1': // 阿里巴巴
								task = this.alibabaDownload(item, this.alibabaBrowser);
								break;
							case '2': // 京东
								task = this.jdScanImg(item, this.jdBrowser);
								break;
							case '3': // 天猫
							case '4': // 淘宝
								task = this.tbScanImg(item, this.tbBrowser);
								break;
							case '5': // 小红书
								task = this.redDownload(item, this.redBrowser);
								break;
							case '10': // 普通网址
								task = this.normalDownload(item, this.otherBrowser);
								break;
						}
					
						if(task){
							taskArr.push(task);
						}
						
						let numType = this.$utils.getStorage('numType');
						if(numType){
							this.execLimit = numType;
						}
						
						if((i+1) % this.execLimit == 0){
							await Promise.all(taskArr).then(result => {
								taskArr = [];
							}).catch(err => {
								console.log('err'+i, err)
							})
						}
					}
					
					if(taskArr.length > 0){
						await Promise.all(taskArr).then(result => {
							taskArr = [];
						}).catch(err => {
							// 错误文件添加到服务中
							console.log('err',err)
						})
					}
					
					if(this[browserName + 'Browser']){
						this[browserName + 'Browser'].close();
						this[browserName + 'Browser'] = null;
					}
					
					this.loading = false;
					// 打开文件夹
					if(fileList.length > 0){
						this.$message({message: '恭喜你，任务已完成！', type: 'success'});
						electronApi.call('showItemInfolder',[this.downloadDir + separator + pjson.softInfo.softName +'\\tty.tty'])
					}
				}
			},
			
			// 10-普通网址下载
			async normalDownload(urlInfo, otherBrowser){
				let task = await new Promise((resolve,reject) =>{
					(async () => {
						try{
							let authority = this.$refs.headerRef.authority.isAuthority;
							let number = 0;
							urlInfo.status = '2';
							urlInfo.num = 0;
							// puppeteer.use(StealthPlugin());
							// const otherBrowser = await puppeteer.launch({
							// 	executablePath: this.initPath(),
							// 	userDataDir: os.tmpdir() + separator + 'chrome-data-capture',
							// 	args: [
							// 		'--start-maximized',
							// 		'--no-sandbox',
							// 		'--disable-setuid-sandbox',
							// 		'--disable-blink-features=AutomationControlled',
							// 	]
							// });
							const page = await otherBrowser.newPage();
							
							page.on('response', async(response) => {
								// 检查响应的 MIME 类型是否以 'image/' 开头
								if (response.headers()['content-type'] && response.headers()['content-type'].startsWith('image/') && response.headers()['content-length']) {
									let imgArr = ['gif', 'jpeg', 'png', 'webp', 'svg', 'tiff', 'bmp', 'ico', 'avif'];
									let imgType = 'jpg';
									let isBase = false;
									imgArr.map((item, index) => {
										if(response.headers()['content-type'].indexOf(item) > -1){
											imgType = item;
											if(item == 'jpeg'){
												imgType = 'jpg';
											}else if(item == 'avif'){
												imgType = 'png';
											}
										}
									});
									
									let url = response.url();
									let regex = /^data:image\/[\w|+|-]+;base64,/;
									if(regex.exec(url)){
										url = response.url().replace(/^data:image\/[\w|+|-]+;base64,/, ''); 
										isBase = true;
									}
									
									let imgInfo = {
										url: url,
										contentType: response.headers()['content-type'],
										status: response.status(),
										imgType: imgType,
										isBase: isBase
									}
									
									if(urlInfo.title){
										if (fs.existsSync(this.downloadDir + separator + pjson.softInfo.softName + separator + urlInfo.title)) {
											urlInfo.newPath = this.downloadDir + separator + pjson.softInfo.softName + separator + urlInfo.title;
										} else {
											fs.mkdirSync(this.downloadDir + separator + pjson.softInfo.softName + separator + urlInfo.title);
											urlInfo.newPath = this.downloadDir + separator + pjson.softInfo.softName + separator + urlInfo.title;
										}
									}else{
										await this.getTitle(page, urlInfo); // 生成页面标题对应的文件夹
									}
									
									let outputPath = urlInfo.newPath + '\\' + this.randomString(35) + '.' + imgInfo.imgType;
									
									urlInfo.status = '3';
									number++;
									if(!authority && number <= this.execNum){
										if(imgInfo.isBase){ //base64位图片下载
											this.downloadBaseImage(imgInfo.url, outputPath, urlInfo)
										}else{
											this.downloadImage(imgInfo.url, outputPath, urlInfo);
										}
									}
									
									if(authority){
										if(imgInfo.isBase){ //base64位图片下载
											this.downloadBaseImage(imgInfo.url, outputPath, urlInfo)
										}else{
											this.downloadImage(imgInfo.url, outputPath, urlInfo);
										}
									}
									
								}
							});

							await page.goto(urlInfo.url, {waitUntil : 'networkidle2'});
							
							let pageInfo = await page.evaluate(() => {
								let cHeight = document.documentElement.clientHeight;
								let scrollHeight = document.body.scrollHeight;
								return {'scrollHeight': scrollHeight, 'cHeight': cHeight}
							});
							
							let scrollHeight = pageInfo.scrollHeight;
							let cHeight = pageInfo.cHeight;
							
							let num = Math.ceil(scrollHeight / cHeight);
							let start = -1;
							let scrollInt = setInterval(async() => {
								start ++;
								await page.evaluate((start) => {
									let cHeight = document.documentElement.clientHeight;
									window.scrollTo({
										top: cHeight * start, 
										behavior: "smooth" 
									});
								}, start);
								if(start > num || start > 200){ // 防止页面过长，滚动200次自动停止
									clearInterval(scrollInt);
									await page.close();
									urlInfo.status = '4';
									resolve(true);
									this.loading = false;
								}
							}, 300);
							
						}catch(e){
							urlInfo.status = '5';
							reject(e);
							this.showError(e);
						}
					})();
				});
				
			},
			
			// 检查天猫淘宝登录状态
			checkAlibabaLogin(){
				this.checkLoading = true;
				this.alibabaStatus = 1;
				return new Promise((resolve, reject) => {
					(async () => {
						try{
							if(this.loginBrowser){
								await this.loginBrowser.close();
								this.loginBrowser = null;
							}
							this.loginBrowser = await puppeteer.launch({
								executablePath: this.initPath(),
								args: ['--window-size=1280,800'],
								userDataDir: os.tmpdir() + separator + 'chrome-data-capture', 
							});
							const page = await this.loginBrowser.newPage();
							await page.setViewport({ width: 1280, height: 800 });
							let testUrl = 'https://www.1688.com';
							await page.goto(testUrl, {waitUntil : 'networkidle2'});
							
							let loginInfo = await page.evaluate(() => {
								let navTags = document.querySelector('.site-nav-sign a');
								let userTags = document.querySelector('.site-nav-user a');
								
								if(navTags && navTags.innerHTML.indexOf('登录') > -1){
									return false;
								}else if(userTags){
									return true;
								}else{
									return false;
								}
							});
							
							if(loginInfo){
								this.tbStatus = 2;
							}else{
								this.tbStatus = 3;
							}
							
							resolve(this.tbStatus);
							this.checkLoading = false;
							await this.loginBrowser.close();
							this.loginBrowser = null;
						}catch(e){
							this.checkLoading = false;
							reject(3);
							this.showError(e);
						}
					})();
				});
				
			},
			
			// 1 - 阿里巴巴下载
			async alibabaDownload(urlInfo, browser){
				let task = await new Promise((resolve,reject) =>{
					(async () => {
						try{
							let authority = this.$refs.headerRef.authority.isAuthority;
							urlInfo.status = '2';
							urlInfo.num = 0;
							// puppeteer.use(StealthPlugin());
							// const browser = await puppeteer.launch({
							// 	executablePath: this.initPath(),
							// 	userDataDir: os.tmpdir() + separator + 'chrome-data-capture', 
							// });
							const page = await browser.newPage();
							await page.goto(urlInfo.url, {waitUntil : 'networkidle2'});
							
							if(urlInfo.title){
								if (fs.existsSync(this.downloadDir + separator + pjson.softInfo.softName + separator + urlInfo.title)) {
									urlInfo.newPath = this.downloadDir + separator + pjson.softInfo.softName + separator + urlInfo.title;
								} else {
									fs.mkdirSync(this.downloadDir + separator + pjson.softInfo.softName + separator + urlInfo.title);
									urlInfo.newPath = this.downloadDir + separator + pjson.softInfo.softName + separator + urlInfo.title;
								}
							}else{
								await this.getTitle(page, urlInfo); // 生成页面标题对应的文件夹
							}
							
							let pageInfo = await page.evaluate(() => {
								let cHeight = document.documentElement.clientHeight;
								let scrollHeight = document.body.scrollHeight;
								return {'scrollHeight': scrollHeight, 'cHeight': cHeight}
							});
							
							let scrollHeight = pageInfo.scrollHeight;
							let cHeight = pageInfo.cHeight;
							
							let num = Math.ceil(scrollHeight / cHeight);
							let start = -1;
							let scrollInt = setInterval(async() => {
								start ++;
								if(this.settingArr.indexOf('detailImg') > -1){
									let scrollHeight2 = await page.evaluate((start) => {
										let scrollHeight = document.body.scrollHeight;
										let cHeight = document.documentElement.clientHeight;
										// let num = Math.ceil(scrollHeight / cHeight);
										window.scrollTo({
											top: cHeight * start, 
											behavior: "smooth" 
										});
										return scrollHeight;
									}, start);
									num = Math.ceil(scrollHeight2 / cHeight);
								}
								
								if(start > num || start > 200){ // 防止页面过长，滚动200次自动停止
									urlInfo.status = '3';
									clearInterval(scrollInt);
									await this.alibabaScanImg(browser, page, urlInfo, authority);
									this.loading = false;
									urlInfo.status = '4';
									resolve(true);
								}
							}, 300);
							
						}catch(e){
							urlInfo.status = '5';
							reject(e);
							this.showError(e);
						}
					})();
				});
			},
			
			// 检查京东登录状态
			checkJdLogin(){
				this.checkLoading = true;
				this.jdStatus = 1;
				return new Promise((resolve, reject) => {
					(async () => {
						try{
							if(this.loginBrowser){
								await this.loginBrowser.close();
								this.loginBrowser = null;
							}
							this.loginBrowser = await puppeteer.launch({
								executablePath: this.initPath(),
								args: ['--window-size=1280,800'],
								userDataDir: os.tmpdir() + separator + 'chrome-data-capture-jd', 
							});
							const page = await this.loginBrowser.newPage();
							await page.setViewport({ width: 1280, height: 800 });
							let testUrl = 'https://www.jd.com';
							await page.goto(testUrl, {waitUntil : 'networkidle2'});
							
							let loginInfo = await page.evaluate(() => {
								let navTags = document.querySelector('.link-login');
								let userTags = document.querySelector('.nickname');
								let userTags2 = document.querySelector('.nick'); //企业账号
								
								if(navTags && navTags.innerHTML.indexOf('请登录') > -1){
									return false;
								}else if(userTags || userTags2){
									return true;
								}else{
									return false;
								}
							});
							
							if(loginInfo){
								this.jdStatus = 2;
							}else{
								this.jdStatus = 3;
							}
							
							resolve(this.jdStatus);
							this.checkLoading = false;
							await this.loginBrowser.close();
							this.loginBrowser = null;
						}catch(e){
							this.checkLoading = false;
							reject(3);
							this.showError(e);
						}
					})();
				});
			},
			
			// 京东下载
			async jdScanImg(urlInfo, jdBrowser){
				let task = await new Promise((resolve,reject) =>{
					(async () => {
						try{
							let authority = this.$refs.headerRef.authority.isAuthority;
							urlInfo.status = '2';
							urlInfo.num = 0;
							// puppeteer.use(StealthPlugin());
							// const jdBrowser = await puppeteer.launch({
							// 	executablePath: this.initPath(),
							// 	userDataDir: os.tmpdir() + separator + 'chrome-data-capture-jd',
							// 	args: [
							// 		'--no-sandbox',
							// 		'--disable-setuid-sandbox',
							// 		'--disable-blink-features=AutomationControlled',
							// 	]
							// });
							const page = await jdBrowser.newPage();
							await page.evaluateOnNewDocument(() => {
							    const newProto = navigator.__proto__;
								delete newProto.webdriver;
								navigator.__proto__ = newProto;
							});
							
							let jdImgInfo = {
								mainImg: [],
								skuImg: [],
								commentImg: [],
								detailImg: [],
								video: []
							};
							
							let titleFlag = true;
							let skuNum = 0, mainNum = 0, videoNum = 0;
							
							page.on('response', async(response) => {
								if(titleFlag){ // 第一次生成页面标题
									if(urlInfo.title){
										if (fs.existsSync(this.downloadDir + separator + pjson.softInfo.softName + separator + urlInfo.title)) {
											urlInfo.newPath = this.downloadDir + separator + pjson.softInfo.softName + separator + urlInfo.title;
										} else {
											fs.mkdirSync(this.downloadDir + separator + pjson.softInfo.softName + separator + urlInfo.title);
											urlInfo.newPath = this.downloadDir + separator + pjson.softInfo.softName + separator + urlInfo.title;
										}
									}else{
										await this.getTitle(page, urlInfo); // 生成页面标题对应的文件夹
									}
									titleFlag = false;
								}
							
								// 检查响应的 MIME 类型是否以 'image/' 开头
								if (response.headers()['content-type'] && response.headers()['content-type'].startsWith('application/json')) {
								
									let detailUrl = '';
									let videoUrl = '';
									if(response.url().indexOf('/description/') > -1){ // 商品详情接口  
										detailUrl = response.url();
									}
									
									if(response.url().indexOf('/tencent/video_v3') > -1){ // 商品视频接口
										videoUrl = response.url();
									}
									
									urlInfo.status = '3';
									
									if(detailUrl && this.settingArr.indexOf('detailImg') > -1){ // jd商品详情
										try {
											let data = await response.text();
											if(data.indexOf('showdesc(') > -1){
												data = data.slice(0, -1).replace('showdesc(', '');
											}
											let detailInfo = JSON.parse(data);
											let regex = /\/\/img[0-9]+.360buyimg.com\S+.(jpg|jpeg|png|gif|avif|tif|tiff)/g;
											let detailImgArr = [];
											if(detailInfo && detailInfo.content){
												detailImgArr = detailInfo.content.match(regex);
											}
											
											jdImgInfo.detailImg = detailImgArr;
											
											for(let i = 0; i < detailImgArr.length; i++){
												let imgUrl = 'https:' + detailImgArr[i];
												imgUrl = imgUrl.replace('.avif', '');
												let fileName = imgUrl.split('/').pop();
												if(fileName){
													let queryIndex = fileName.indexOf('?');
													if (queryIndex !== -1) {
														fileName = fileName.substr(0, queryIndex);  
													}
													
													let num = Number(i) + 1;
													let suffix = '';
													if(fileName.lastIndexOf('.') > -1){
														suffix = fileName.substr(fileName.lastIndexOf('.'));
													}
													
													if (!fs.existsSync(urlInfo.newPath + '\\详情图')) {
														fs.mkdirSync(urlInfo.newPath + '\\详情图');
													}
													
													let outputPath = urlInfo.newPath + '\\详情图\\详情图' + num + suffix;
													if(!authority && i < this.execNum){
														await this.downloadImage(imgUrl, outputPath, urlInfo);
													}
													if(authority){
														await this.downloadImage(imgUrl, outputPath, urlInfo);
													}
												}
											}
											
										} catch (error) {  
											console.error('详情图片解析失败:', error);
										}
									}
									
									if(videoUrl && this.settingArr.indexOf('video') > -1){ // jd商品视频
										try {
											let data = await response.text();
											data = data.slice(0, -1).replace(/^jQuery[0-9]+\(/, '');
											let videoInfo = JSON.parse(data);
											let videoUrl = videoInfo.playUrl;
											jdImgInfo.video.push(videoUrl);
											
											let fileName = videoUrl.split('/').pop();
											if(fileName){
												let queryIndex = fileName.indexOf('?');
												if (queryIndex !== -1) {
													fileName = fileName.substr(0, queryIndex);  
												}
												
												if (!fs.existsSync(urlInfo.newPath + '\\视频')) {
													fs.mkdirSync(urlInfo.newPath + '\\视频');
												}
												
												let outputPath = urlInfo.newPath + '\\视频\\' + fileName;
												await this.downloadImage(videoUrl, outputPath, urlInfo);
											}
											
										} catch (error) {  
											console.error('视频解析失败:', error);  
										}
									}
								}
								
							});
							await page.goto(urlInfo.url, {waitUntil : 'networkidle2'});
							
							/**new**/
							//detailImg：详情图；skuImg：sku图片；commentImg: 评论图；video: 视频
							const imgInfo = await page.evaluate((authority, execNum) => {
								let outObj = {
									mainImg: [],
									skuImg: [],
								};
								//主图 
								let arr1 = document.querySelectorAll('#spec-list img');
								for(let i=0; i< arr1.length; i++){
									let mainImgUrl = arr1[i].src;
									let reg = /\/n[0-9]+\/jfs\//;
									let reg2 = /\/n[0-9]+\/s(54|50)x(54|66)_jfs\//;
									let reg3 = /![a-z]+_[0-9]+x[0-9]+(.avif)?/;
									let replaceStr = '/n1/s800x800_jfs/';
									if(mainImgUrl.match(/\/n[0-9]+\/s50x66_jfs\//)){
										replaceStr = '/n1/s750x1000_jfs/';
									}
									mainImgUrl = mainImgUrl.replace(reg, replaceStr).replace(reg2, replaceStr).replace(reg3, '').replace('.avif', '');
								
									if(!authority && i < execNum){
										outObj.mainImg.push(mainImgUrl);
									}
									if(authority){
										outObj.mainImg.push(mainImgUrl);
									}
								}
								//sku图片 
								let arr2 = document.querySelectorAll('#choose-attr-1 img');
								for(let i=0; i< arr2.length; i++){
									let skuImgUrl = arr2[i].src;
									let skuReg = /\/n[0-9]+\/s(60|40)x(80|40)_jfs\//;
									let replaceStr = '/n1/s800x800_jfs/';
									if(skuImgUrl.match(/\/n[0-9]+\/s60x80_jfs\//)){
										replaceStr = '/n1/s750x1000_jfs/';
									}
									skuImgUrl = skuImgUrl.replace(skuReg, replaceStr).replace('.avif', '');
									if(!authority && i < execNum){
										outObj.skuImg.push(skuImgUrl);
									}
									if(authority){
										outObj.skuImg.push(skuImgUrl);
									}
									
								}
								
								return outObj;
							}, authority, this.execNum);
							
							if(this.settingArr.indexOf('mainImg') > -1){
								// 主图下载
								for(let j = 0; j < imgInfo.mainImg.length; j++){
									let fileName = imgInfo.mainImg[j].split('/').pop();
									if(fileName){
										let queryIndex = fileName.indexOf('?');
										if (queryIndex !== -1) {
											fileName = fileName.substr(0, queryIndex);  
										}
										
										let num = Number(j) + 1;
										let suffix = '';
										if(fileName.lastIndexOf('.') > -1){
											suffix = fileName.substr(fileName.lastIndexOf('.'));
										}
										
										if (!fs.existsSync(urlInfo.newPath + '\\主图')) {
											fs.mkdirSync(urlInfo.newPath + '\\主图');
										}
										
										let outputPath = urlInfo.newPath + '\\主图\\主图' + num + suffix;
										await this.downloadImage(imgInfo.mainImg[j], outputPath, urlInfo);
									}
								}
							}
							
							
							// sku图片下载
							if(this.settingArr.indexOf('skuImg') > -1){
								for(let j = 0; j < imgInfo.skuImg.length; j++){
									let fileName = imgInfo.skuImg[j].split('/').pop();
									if(fileName){
										let queryIndex = fileName.indexOf('?');
										if (queryIndex !== -1) {
											fileName = fileName.substr(0, queryIndex);  
										}
										
										let num = Number(j) + 1;
										let suffix = '';
										if(fileName.lastIndexOf('.') > -1){
											suffix = fileName.substr(fileName.lastIndexOf('.'));
										}
										
										if (!fs.existsSync(urlInfo.newPath + '\\sku图')) {
											fs.mkdirSync(urlInfo.newPath + '\\sku图');
										}
										
										let outputPath = urlInfo.newPath + '\\sku图\\sku图' + num + suffix;
										await this.downloadImage(imgInfo.skuImg[j], outputPath, urlInfo);
									}
								}
							}
							/**end**/
							await page.close();
							urlInfo.status = '4';
							resolve(true);
						}catch(e){
							reject(e);
							this.showError(e);
						}
					})();
				});
			},
			
			// 检查天猫淘宝登录状态
			checkLogin(){
				this.checkLoading = true;
				this.tbStatus = 1;
				return new Promise((resolve, reject) => {
					(async () => {
						try{
							if(this.loginBrowser){
								await this.loginBrowser.close();
								this.loginBrowser = null;
							}
							this.loginBrowser = await puppeteer.launch({
								executablePath: this.initPath(),
								args: ['--window-size=1280,800'],
								userDataDir: os.tmpdir() + separator + 'chrome-data-capture', 
							});
							const page = await this.loginBrowser.newPage();
							await page.setViewport({ width: 1280, height: 800 });
							let testUrl = 'https://www.taobao.com';
							await page.goto(testUrl, {waitUntil : 'networkidle2'});
							
							let loginInfo = await page.evaluate(() => {
								let navTags = document.querySelector('.site-nav-sign a');
								let userTags = document.querySelector('.site-nav-user a');
								
								if(navTags && navTags.innerHTML.indexOf('登录') > -1){
									return false;
								}else if(userTags){
									return true;
								}else{
									return false;
								}
							});
							
							if(loginInfo){
								this.tbStatus = 2;
							}else{
								this.tbStatus = 3;
							}
							
							resolve(this.tbStatus);
							this.checkLoading = false;
							await this.loginBrowser.close();
							this.loginBrowser = null;
						}catch(e){
							this.checkLoading = false;
							reject(3);
							this.showError(e);
						}
					})();
				});
				
			},
			
			// 淘宝天猫扫描下载图片
			async tbScanImg(urlInfo, tbBrowser){
				let task = await new Promise((resolve,reject) =>{
					(async () => {
						try{
							let authority = this.$refs.headerRef.authority.isAuthority;
							urlInfo.status = '2';
							urlInfo.num = 0;
							// puppeteer.use(StealthPlugin());
							// const tbBrowser = await puppeteer.launch({
							// 	executablePath: this.initPath(),
							// 	userDataDir: os.tmpdir() + separator + 'chrome-data-capture', 
							// });
							const page = await tbBrowser.newPage();
							await page.goto(urlInfo.url, {waitUntil : 'networkidle0'});
							
							if(urlInfo.title){
								if (fs.existsSync(this.downloadDir + separator + pjson.softInfo.softName + separator + urlInfo.title)) {
									urlInfo.newPath = this.downloadDir + separator + pjson.softInfo.softName + separator + urlInfo.title;
								} else {
									fs.mkdirSync(this.downloadDir + separator + pjson.softInfo.softName + separator + urlInfo.title);
									urlInfo.newPath = this.downloadDir + separator + pjson.softInfo.softName + separator + urlInfo.title;
								}
							}else{
								await this.getTitle(page, urlInfo); // 生成页面标题对应的文件夹
							}
							
							let responseVideo = [];
							page.on('response', async(response) => {
								// 检查响应的 MIME 类型是否以 'video/' 开头
								if (response.headers()['content-type'] && response.headers()['content-type'].startsWith('video/')) {
									responseVideo.push(response.url());
								}
							});
							
							if(this.settingArr.indexOf('video') > -1){ // 用户选择下载视频的时候才会触发
								//鼠标放在主图第一张，生成视频
								const elementHandle = await page.$('li[class*=thumbnail--]');
								if(elementHandle){
									const classListProperty = await elementHandle.getProperty('classList');
									const classList = await classListProperty.jsonValue();
									const classesArray = Object.values(classList);
									const allClasses = classesArray.join('.');
									if(allClasses && allClasses.indexOf('active-') < 0){
										await page.hover('li.'+allClasses);
									}
								}
							}
							
							let iframeElementHandle = await page.$('iframe');
							if(iframeElementHandle){
								let m1 = await page.$('img[class^=PicGallery--thumbnailPic--]');
								let m2 = await page.$('img[class*=thumbnailPic--]');
								if(!m1 && !m2){ // 出现弹窗而且没有主图，判断为拦截模式
									await page.close();
									urlInfo.status = '6';
									resolve(true);
									this.loading = false;
									return false;
								}
							}
							
							let pageInfo = await page.evaluate(() => {
								let cHeight = document.documentElement.clientHeight;
								let scrollHeight = document.body.scrollHeight;
								return {'scrollHeight': scrollHeight, 'cHeight': cHeight}
							});
							let scrollHeight = pageInfo.scrollHeight;
							let cHeight = pageInfo.cHeight;
							let num = Math.ceil(scrollHeight / cHeight);
							let start = -1;
							let scrollInt = setInterval(async() => {
								start ++;
								if(this.settingArr.indexOf('commentImg') > -1 && this.settingArr.indexOf('detailImg') < 0){ // 选择了评论图没选择详情图
									let scrollHeight2 = await page.evaluate((start) => {
										let scrollHeight = document.body.scrollHeight;
										let cHeight = document.documentElement.clientHeight;
										let obj = document.getElementById('container') || document.getElementById('content');
										if(obj && obj.getBoundingClientRect().top < -500){
											return -1;
										}
										window.scrollTo({
											top: cHeight * start, 
											behavior: "smooth" 
										});
										return scrollHeight;
									}, start);
									
									if(scrollHeight2 > 0){
										num = Math.ceil(scrollHeight2 / cHeight);
									}else{
										num = 0;
									}
								}
								if(this.settingArr.indexOf('detailImg') > -1){ // 选择详情图
									let scrollHeight2 = await page.evaluate((start) => {
										let scrollHeight = document.body.scrollHeight;
										let cHeight = document.documentElement.clientHeight;
										let obj = document.getElementById('container') || document.getElementById('content');
										if(obj && obj.getBoundingClientRect().bottom < 100){
											return -1;
										}
										window.scrollTo({
											top: cHeight * start, 
											behavior: "smooth" 
										});
										return scrollHeight;
									}, start);
									
									if(scrollHeight2 > 0){
										num = Math.ceil(scrollHeight2 / cHeight);
									}else{
										num = 0;
									}
								}
								if(this.settingArr.indexOf('skuImg') > -1 && this.settingArr.indexOf('commentImg') < 0 && this.settingArr.indexOf('detailImg') < 0){ // 选择了sku图片没选择评论和详情
									let scrollHeight2 = await page.evaluate((start) => {
										let scrollHeight = document.body.scrollHeight;
										let cHeight = document.documentElement.clientHeight;
										let obj = document.querySelector('div[class^=SkuContent--]');
										if(obj && obj.getBoundingClientRect().bottom < 500){
											return -1;
										}
										window.scrollTo({
											top: cHeight * start, 
											behavior: "smooth" 
										});
										return scrollHeight;
									}, start);
									
									if(scrollHeight2 > 0){
										num = Math.ceil(scrollHeight2 / cHeight);
									}else{
										num = 0;
									}
								}
								if(this.settingArr.indexOf('skuImg') < 0 && this.settingArr.indexOf('detailImg') < 0 && this.settingArr.indexOf('commentImg') < 0){ // 没有选择评论图和详情图
									num = 0;
								}
								if(start > num || start > 200){ // 防止页面过长，滚动200次自动停止
									urlInfo.status = '3';
									clearInterval(scrollInt);
									
									//detailImg：详情图；skuImg：sku图片；commentImg: 评论图；video: 视频
									const imgInfo = await page.evaluate((authority, execNum) => {
										let outObj = {
											mainImg: [],
											detailImg: [],
											skuImg: [],
											commentImg: [],
											video: []
										};
										
										// 正则表达式匹配字符 重写图片路径
										let regex = /\.(.{3,4})_[0-9a-zA-z]+\.(.{3,4})_\.(.{3,4})/;
										
										//主图 
										let arr1 = document.querySelectorAll('img[class^=PicGallery--thumbnailPic--]');
										if(arr1.length === 0){
											arr1 = document.querySelectorAll('img[class*=thumbnailPic--]');
										}
										for(let i=0; i< arr1.length; i++){
											let mainImgUrl = arr1[i].src;
											let result = regex.exec(mainImgUrl);
											if(result){
												mainImgUrl = mainImgUrl.replace(result[0], '.'+result[1]); 
											}
											if(!authority && i < execNum){
												outObj.mainImg.push(mainImgUrl);
											}
											if(authority){
												outObj.mainImg.push(mainImgUrl);
											}
										}
										//sku图片 
										let arr2 = document.querySelectorAll('img[class^=SkuContent--valueItemImg--]');
										if(arr2.length === 0){
											arr2 = document.querySelectorAll('img[class*=valueItemImg--]');
										}
										for(let i=0; i< arr2.length; i++){
											let skuImgUrl = arr2[i].src;
											let result = regex.exec(skuImgUrl);
											if(result){
												skuImgUrl = skuImgUrl.replace(result[0], '.'+result[1]); 
											}
											if(!authority && i < execNum){
												outObj.skuImg.push(skuImgUrl);
											}
											if(authority){
												outObj.skuImg.push(skuImgUrl);
											}
										}
										//详情图片 
										let arr3 = document.querySelectorAll('#content img');
										for(let i=0; i< arr3.length; i++){
											let detailImgUrl = arr3[i].src;
											let lazyUrl = arr3[i].getAttribute('data-src');
											if(arr3[i].src.indexOf('/s.gif') > -1 && lazyUrl){
												detailImgUrl = lazyUrl;
												if(!/^http/.exec(lazyUrl)){
													detailImgUrl = 'https:' + lazyUrl;
												}
											}
											let result = regex.exec(detailImgUrl);
											if(result){
												detailImgUrl = detailImgUrl.replace(result[0], '.'+result[1]); 
											}
											if(!authority && i < execNum){
												outObj.detailImg.push(detailImgUrl);
											}
											if(authority){
												outObj.detailImg.push(detailImgUrl);
											}
										}
										//评论图片  
										let arr4 = document.querySelectorAll('div[class^=Comments--comments--] img');
										if(arr4.length === 0){
											arr4 = document.querySelectorAll('div[class^=comments--] img');
										}
										for(let i=0; i< arr4.length; i++){ 
											if(arr4[i].src.indexOf('/avatar/sns/user/flag/sns_logo') == -1){ //过滤淘宝用户头像
												if(!authority && i < execNum){
													outObj.commentImg.push(arr4[i].src);
												}
												if(authority){
													outObj.commentImg.push(arr4[i].src);
												}
											}
										}
										// 视频
										let arr5 = document.querySelectorAll('video.lib-video');
										for(let i=0; i< arr5.length; i++){
											if(outObj.video.indexOf(arr5[i].src) == -1){
												if(!authority && i < execNum){
													outObj.video.push(arr5[i].src);
												}
												if(authority){
													outObj.video.push(arr5[i].src);
												}
											}
										}
										return outObj;
									}, authority, this.execNum);
				
									if(imgInfo.video.length == 0 && responseVideo.length > 0){
										imgInfo.video = responseVideo;
									}
									
									if(this.settingArr.indexOf('mainImg') > -1){
										// 主图下载
										for(let j = 0; j < imgInfo.mainImg.length; j++){
											let fileName = imgInfo.mainImg[j].split('/').pop();
											if(fileName){
												let queryIndex = fileName.indexOf('?');
												if (queryIndex !== -1) {
													fileName = fileName.substr(0, queryIndex);  
												}
												
												let num = Number(j) + 1;
												let suffix = '';
												if(fileName.lastIndexOf('.') > -1){
													suffix = fileName.substr(fileName.lastIndexOf('.'));
												}
												
												if (!fs.existsSync(urlInfo.newPath + '\\主图')) {
													fs.mkdirSync(urlInfo.newPath + '\\主图');
												}
												
												let outputPath = urlInfo.newPath + '\\主图\\主图' + num + suffix;
												await this.downloadImage(imgInfo.mainImg[j], outputPath, urlInfo);
											}
										}
									}
									
									// sku图片下载
									if(this.settingArr.indexOf('skuImg') > -1){
										for(let j = 0; j < imgInfo.skuImg.length; j++){
											let fileName = imgInfo.skuImg[j].split('/').pop();
											if(fileName){
												let queryIndex = fileName.indexOf('?');
												if (queryIndex !== -1) {
													fileName = fileName.substr(0, queryIndex);  
												}
												
												let num = Number(j) + 1;
												let suffix = '';
												if(fileName.lastIndexOf('.') > -1){
													suffix = fileName.substr(fileName.lastIndexOf('.'));
												}
												
												if (!fs.existsSync(urlInfo.newPath + '\\sku图')) {
													fs.mkdirSync(urlInfo.newPath + '\\sku图');
												}
												
												let outputPath = urlInfo.newPath + '\\sku图\\sku图' + num + suffix;
												await this.downloadImage(imgInfo.skuImg[j], outputPath, urlInfo);
											}
										}
									}
									
									//详情图下载
									if(this.settingArr.indexOf('detailImg') > -1){
										for(let j = 0; j < imgInfo.detailImg.length; j++){
											let fileName = imgInfo.detailImg[j].split('/').pop();
											if(fileName){
												let queryIndex = fileName.indexOf('?');
												if (queryIndex !== -1) {
													fileName = fileName.substr(0, queryIndex);  
												}
												
												let num = Number(j) + 1;
												let suffix = '';
												if(fileName.lastIndexOf('.') > -1){
													suffix = fileName.substr(fileName.lastIndexOf('.'));
												}
												
												if (!fs.existsSync(urlInfo.newPath + '\\详情图')) {
													fs.mkdirSync(urlInfo.newPath + '\\详情图');
												}
												
												let outputPath = urlInfo.newPath + '\\详情图\\详情图' + num + suffix;
												await this.downloadImage(imgInfo.detailImg[j], outputPath, urlInfo);
											}
										}
									}
									
									//评论图下载
									if(this.settingArr.indexOf('commentImg') > -1){
										for(let j = 0; j < imgInfo.commentImg.length; j++){
											let fileName = imgInfo.commentImg[j].split('/').pop();
											if(fileName){
												let queryIndex = fileName.indexOf('?');
												if (queryIndex !== -1) {
													fileName = fileName.substr(0, queryIndex);  
												}
												
												let num = Number(j) + 1;
												let suffix = '';
												if(fileName.lastIndexOf('.') > -1){
													suffix = fileName.substr(fileName.lastIndexOf('.'));
												}
												
												if (!fs.existsSync(urlInfo.newPath + '\\评论图')) {
													fs.mkdirSync(urlInfo.newPath + '\\评论图');
												}
												
												let outputPath = urlInfo.newPath + '\\评论图\\评论图' + num + suffix;
												await this.downloadImage(imgInfo.commentImg[j], outputPath, urlInfo);
											}
										}
									}
									
									//视频下载
									if(this.settingArr.indexOf('video') > -1){
										for(let j = 0; j < imgInfo.video.length; j++){
											let fileName = imgInfo.video[j].split('/').pop();
											if(fileName){
												let queryIndex = fileName.indexOf('?');
												if (queryIndex !== -1) {
													fileName = fileName.substr(0, queryIndex);  
												}
												
												if (!fs.existsSync(urlInfo.newPath + '\\视频')) {
													fs.mkdirSync(urlInfo.newPath + '\\视频');
												}
												
												let outputPath = urlInfo.newPath + '\\视频\\' + fileName;
												await this.downloadImage(imgInfo.video[j], outputPath, urlInfo);
											}
										}
									}
									
									await page.close();
									urlInfo.status = '4';
									resolve(true);
									this.loading = false;
								}
							}, 300);
						}catch(e){
							reject(e);
							this.showError(e);
						}
					})();
				});
			},
			
			// 阿里巴巴 - 扫描并下载图片
			async alibabaScanImg(browser, page, urlInfo, authority){
				//detailImg：详情图；skuImg：sku图片；commentImg: 评论图；video: 视频
				const imgInfo = await page.evaluate((authority, execNum) => {
					let outObj = {
						mainImg: [],
						detailImg: [],
						skuImg: [],
						commentImg: [],
						video: []
					};
					
					//主图
					let arr1 = document.querySelectorAll('img[class*="-gallery-img"]');
					for(let i=0; i< arr1.length; i++){
						if(!authority && i < execNum){
							outObj.mainImg.push(arr1[i].src);
						}
						if(authority){
							outObj.mainImg.push(arr1[i].src);
						}
					}
					//sku图片
					let type = 'bg';
					let arr2 = document.querySelectorAll('.prop-img');
					if(arr2.length == 0){
						arr2 = document.querySelectorAll('.sku-item-image');
					}
					if(arr2.length == 0){
						arr2 = document.querySelectorAll('.ant-image-img');
						type = 'img';
					}
					for(let i=0; i< arr2.length; i++){
						let src;
						if(type == 'bg'){
							src = window.getComputedStyle(arr2[i]).backgroundImage.replace(/url\(["']?(.+?)["']?\)/i, '$1');
						}
						if(type == 'img'){
							src = arr2[i].src;
						}
						if(!authority && i < execNum){
							outObj.skuImg.push(src);
						}
						if(authority){
							outObj.skuImg.push(src);
						}
					}
					//详情图片 
					let arr3 = document.querySelectorAll('img.desc-img-loaded');
					if(arr3.length == 0){
						if(document.getElementById('description') && document.getElementById('description').querySelector('.html-description')){
							arr3 = document.getElementById('description').querySelector('.html-description').shadowRoot.querySelectorAll('img');
						}
					}
					for(let i=0; i< arr3.length; i++){
						if(!authority && i < execNum){
							outObj.detailImg.push(arr3[i].src);
						}
						if(authority){
							outObj.detailImg.push(arr3[i].src);
						}
					}
					// 视频
					let arr5 = document.querySelectorAll('video.lib-video');
					for(let i=0; i< arr5.length; i++){
						if(outObj.video.indexOf(arr5[i].src) == -1){
							if(!authority && i < execNum){
								outObj.video.push(arr5[i].src);
							}
							if(authority){
								outObj.video.push(arr5[i].src);
							}
						}
					}
					return outObj;
				}, authority, this.execNum);
				
				// 主图下载
				if(this.settingArr.indexOf('mainImg') > -1){
					for(let j = 0; j < imgInfo.mainImg.length; j++){
						let fileName = imgInfo.mainImg[j].split('/').pop();
						if(fileName){
							let queryIndex = fileName.indexOf('?');
							if (queryIndex !== -1) {
								fileName = fileName.substr(0, queryIndex);  
							}
							
							let num = Number(j) + 1;
							let suffix = '';
							if(fileName.lastIndexOf('.') > -1){
								suffix = fileName.substr(fileName.lastIndexOf('.'));
							}
							
							if (!fs.existsSync(urlInfo.newPath + '\\主图')) {
								fs.mkdirSync(urlInfo.newPath + '\\主图');
							}
							
							let outputPath = urlInfo.newPath + '\\主图\\主图' + num + suffix;
							await this.downloadImage(imgInfo.mainImg[j], outputPath, urlInfo);
						}
					}
				}
				
				// sku图片下载
				if(this.settingArr.indexOf('skuImg') > -1){
					for(let j = 0; j < imgInfo.skuImg.length; j++){
						let fileName = imgInfo.skuImg[j].split('/').pop();
						if(fileName){
							let queryIndex = fileName.indexOf('?');
							if (queryIndex !== -1) {
								fileName = fileName.substr(0, queryIndex);  
							}
							
							let num = Number(j) + 1;
							let suffix = '';
							if(fileName.lastIndexOf('.') > -1){
								suffix = fileName.substr(fileName.lastIndexOf('.'));
							}
							
							if (!fs.existsSync(urlInfo.newPath + '\\sku图')) {
								fs.mkdirSync(urlInfo.newPath + '\\sku图');
							}
							
							let outputPath = urlInfo.newPath + '\\sku图\\sku图' + num + suffix;
							await this.downloadImage(imgInfo.skuImg[j], outputPath, urlInfo);
						}
					}
				}
				
				//详情图下载
				if(this.settingArr.indexOf('detailImg') > -1){
					for(let j = 0; j < imgInfo.detailImg.length; j++){
						let fileName = imgInfo.detailImg[j].split('/').pop();
						if(fileName){
							let queryIndex = fileName.indexOf('?');
							if (queryIndex !== -1) {
								fileName = fileName.substr(0, queryIndex);  
							}
							
							let num = Number(j) + 1;
							let suffix = '';
							if(fileName.lastIndexOf('.') > -1){
								suffix = fileName.substr(fileName.lastIndexOf('.'));
							}
							
							if (!fs.existsSync(urlInfo.newPath + '\\详情图')) {
								fs.mkdirSync(urlInfo.newPath + '\\详情图');
							}
							
							let outputPath = urlInfo.newPath + '\\详情图\\' + '详情图' + num + suffix;
							await this.downloadImage(imgInfo.detailImg[j], outputPath, urlInfo);
						}
					}
				}
				//视频下载
				if(this.settingArr.indexOf('video') > -1){
					for(let j = 0; j < imgInfo.video.length; j++){
						let fileName = imgInfo.video[j].split('/').pop();
						if(fileName){
							let queryIndex = fileName.indexOf('?');
							if (queryIndex !== -1) {
								fileName = fileName.substr(0, queryIndex);  
							}
							
							if (!fs.existsSync(urlInfo.newPath + '\\视频')) {
								fs.mkdirSync(urlInfo.newPath + '\\视频');
							}
							
							let outputPath = urlInfo.newPath + '\\视频\\' + fileName;
							await this.downloadImage(imgInfo.video[j], outputPath, urlInfo);
						}
					}
				}
				
				await page.close(); // 关闭页面但不关闭浏览器
			},
			
			// 检查小红书登录状态
			checkRedLogin(){
				this.checkLoading = true;
				this.redStatus = 1;
				return new Promise((resolve, reject) => {
					(async () => {
						try{
							if(this.loginBrowser){
								await this.loginBrowser.close();
								this.loginBrowser = null;
							}
							puppeteer.use(StealthPlugin());
							this.loginBrowser = await puppeteer.launch({
								executablePath: this.initPath(),
								userDataDir: os.tmpdir() + separator + 'chrome-data-capture', 
								args: [
									'--start-maximized',
									'--no-sandbox',
									'--disable-setuid-sandbox',
									'--disable-blink-features=AutomationControlled',
									'--window-size=1280,800'
								],
							});
							const page = await this.loginBrowser.newPage();
							await page.setViewport({ width: 1280, height: 800 });
							let testUrl = "https://www.xiaohongshu.com";
							await page.goto(testUrl, {waitUntil : 'networkidle2'});
							
							let loginBtn = await page.$$('#login-btn');
							let loginContainer = await page.$$('.login-container');
							if(loginContainer.length > 0 || loginBtn.length > 0){
								this.redStatus = 3; //未登录
							}else{
								this.redStatus = 2;
							}
							
							resolve(this.redStatus);
							this.checkLoading = false;
							await this.loginBrowser.close();
							this.loginBrowser = null;
						}catch(e){
							this.checkLoading = false;
							reject(3);
							this.showError(e);
						}
					})();
				});
			},
			// 5-小红书下载
			async redDownload(urlInfo, redBrowser){
				let task = await new Promise((resolve,reject) =>{
					(async () => {
						try{
							let authority = this.$refs.headerRef.authority.isAuthority;
							let number = 0;
							urlInfo.status = '2';
							urlInfo.num = 0;
							// puppeteer.use(StealthPlugin());
							// const redBrowser = await puppeteer.launch({
							// 	headless: false,
							// 	executablePath: this.initPath(),
							// 	userDataDir: os.tmpdir() + separator + 'chrome-data-capture',
							// 	args: [
							// 		'--start-maximized',
							// 		'--no-sandbox',
							// 		'--disable-setuid-sandbox',
							// 		'--disable-blink-features=AutomationControlled',
							// 	]
							// });
							const page = await redBrowser.newPage();
							let responseVideo = [];
							page.on('response', async(response) => {
								// 检查响应的 MIME 类型是否以 'video/' 开头
								if (response.headers()['content-type'] && response.headers()['content-type'].startsWith('video/')) {
									if(responseVideo.indexOf(response.url()) < 0 && !response.url().startsWith('blob:https://')){
										responseVideo.push(response.url());
									}
								}
							});
							await page.goto(urlInfo.url, {waitUntil : 'networkidle2'});
							
							if(urlInfo.title){
								if (fs.existsSync(this.downloadDir + separator + pjson.softInfo.softName + separator + urlInfo.title)) {
									urlInfo.newPath = this.downloadDir + separator + pjson.softInfo.softName + separator + urlInfo.title;
								} else {
									fs.mkdirSync(this.downloadDir + separator + pjson.softInfo.softName + separator + urlInfo.title);
									urlInfo.newPath = this.downloadDir + separator + pjson.softInfo.softName + separator + urlInfo.title;
								}
							}else{
								await this.getTitle(page, urlInfo); // 生成页面标题对应的文件夹
							}
							urlInfo.status = '3';
							
							// 定位元素
							const handle = await page.$$('.pagination-media-container .pagination-item'); 
							if(handle.length > 0){ // 模拟鼠标拖动 将鼠标移动到元素的中心，然后开始拖动
								let handleLength = handle.length;
								const box = await handle[0].boundingBox();
								const boxEnd = await handle[handleLength - 1].boundingBox();
								const center = {
									x: box.x + box.width / 2,
									y: box.y + box.height / 2
								};
								const centerEnd = {
									x: boxEnd.x + boxEnd.width / 2,
									y: boxEnd.y + boxEnd.height / 2
								};
								await page.mouse.move(center.x, center.y);
								await page.mouse.down();
								await page.mouse.move(centerEnd.x, centerEnd.y, { steps: 50 }); // 新的位置，可以根据需要调整步骤数
							}
							
							//detailImg：详情图；skuImg：sku图片；commentImg: 评论图；video: 视频
							const imgInfo = await page.evaluate((authority, execNum) => {
								let outObj = {
									mainImg: [],
									detailImg: [],
									skuImg: [],
									commentImg: [],
									video: []
								};
								
								// 正则表达式匹配字符 重写图片路径
								let regex = /\.(.{3,4})_[0-9a-zA-z]+\.(.{3,4})_\.(.{3,4})/;
								
								//主图 
								let arr1 = document.querySelectorAll('img[class^=note-slider-img]');
								for(let i=0; i< arr1.length; i++){
									let mainImgUrl = arr1[i].src;
									let result = regex.exec(mainImgUrl);
									if(result){
										mainImgUrl = mainImgUrl.replace(result[0], '.'+result[1]); 
									}
									if(!authority && i < execNum){
										outObj.mainImg.push(mainImgUrl);
									}
									if(authority){
										outObj.mainImg.push(mainImgUrl);
									}
								}
								// 视频
								let arr5 = document.querySelectorAll('video.lib-video');
								for(let i=0; i< arr5.length; i++){
									if(outObj.video.indexOf(arr5[i].src) == -1){
										if(!authority && i < execNum){
											outObj.video.push(arr5[i].src);
										}
										if(authority){
											outObj.video.push(arr5[i].src);
										}
									}
								}
								return outObj;
							}, authority, this.execNum);
							
							if(imgInfo.mainImg.length >= 3){
								imgInfo.mainImg = imgInfo.mainImg.slice(1, imgInfo.mainImg.length-1); //小红书轮播图第一个/最后一个和内容重复去掉
							}
							imgInfo.video = responseVideo;
							
							// 主图下载
							for(let j = 0; j < imgInfo.mainImg.length; j++){
								let fileName = imgInfo.mainImg[j].split('/').pop();
								if(fileName){
									let queryIndex = fileName.indexOf('?');
									if (queryIndex !== -1) {
										fileName = fileName.substr(0, queryIndex);  
									}
									
									let num = Number(j) + 1;
									let suffix = '.jpg';
									if(fileName.lastIndexOf('.') > -1){
										suffix = fileName.substr(fileName.lastIndexOf('.'));
									}
									
									let outputPath = urlInfo.newPath + '\\文章图' + num + suffix;
									await this.downloadImage(imgInfo.mainImg[j], outputPath, urlInfo);
								}
							}
							
							//视频下载
							for(let j = 0; j < imgInfo.video.length; j++){
								let fileName = imgInfo.video[j].split('/').pop();
								if(fileName){
									let queryIndex = fileName.indexOf('?');
									if (queryIndex !== -1) {
										fileName = fileName.substr(0, queryIndex);  
									}
									
									let num = Number(j) + 1;
									let suffix = '.mp4';
									if(fileName.lastIndexOf('.') > -1){
										suffix = fileName.substr(fileName.lastIndexOf('.'));
									}
									let outputPath = urlInfo.newPath + '\\视频' + num + suffix;
									await this.downloadImage(imgInfo.video[j], outputPath, urlInfo);
								}
							}
							
							await page.close();
							urlInfo.status = '4';
							resolve(true);
							this.loading = false;
						}catch(e){
							urlInfo.status = '5';
							reject(e);
							this.showError(e);
						}
					})();
				});
			},
			
			//
			downloadExample(){
				let url = 'https://www.xingyousoft.com/soft/XYCapture/example.xlsx';
				if (!fs.existsSync(this.downloadDir + separator + pjson.softInfo.softName)) {
					fs.mkdirSync(this.downloadDir + separator + pjson.softInfo.softName);
				}
				let path = this.downloadDir + separator + pjson.softInfo.softName + '\\链接模板下载.xlsx';
				this.downloadImage(url, path, 'example');
			},
			
			// 下载网址链接的图片
			async downloadImage(imageUrl, outputPath, urlInfo) {
				let _this = this;
				let received_bytes = 0;
				let total_bytes = 0;
				try {
					let req = request({
					    method: 'GET', uri: imageUrl, strictSSL: false
					});
					let out = fs.createWriteStream(outputPath);
					req.pipe(out);
					
					return new Promise((resolve, reject) => { 
						req.on('response', (data) => {
							total_bytes = parseInt(data.headers['content-length']);
							const status = data.statusCode;
							if (status < 200 || status >= 300) {
								//reject(false);
								this.$notify.error({
									title: '网络图片访问异常！- 1',
									message: imageUrl.slice(0,50)
								});
							}else if(isNaN(total_bytes)){
								//reject(false);
								this.$notify.error({
									title: '网络图片访问异常！- 2',
									message: imageUrl.slice(0,50)
								});
							}else{
								// console.log('下载中...')
							}
						});
									
						req.on('data', (chunk) => {
						    received_bytes += chunk.length;
						});
						
						req.on('end', ()=> {
							if(urlInfo != 'example'){
								urlInfo.num += 1;
							}else{
								this.$msgbox({
									title: '消息',
									message: '模板下载成功，保存位置：' + this.downloadDir + separator + pjson.softInfo.softName,
									showCancelButton: true,
									confirmButtonText: '去查看',
									cancelButtonText: '取消',
								}).then(action => {
									this.openFolder();
								}).catch(action => {
									
								});
							}
							//console.log('下载完成', outputPath)
							resolve(true);
						});
					});
			    } catch (error) {  
			        console.error(imageUrl, `Failed to download image: ${error.message}`);  
			        throw error;  
			    }  
			},
			
			// 获取页面标题 - 生成对应的文件夹
			async getTitle(page, urlInfo){
				// 已页面标题作为新建文件夹,保留前50个字
				let title = await page.title();
				if(title){
					title = title.substring(0, 50);
					if(this.containsAnyChar(title, ['\\', '/', ':', '*', '?', '"', '<', '>', '|'])){  //判断是否含有特殊字符
						title = title.replace(/[\\|/|:|*|?|"|<|>||]/g, "");
					}
					if (fs.existsSync(this.downloadDir + separator + pjson.softInfo.softName + separator + title)) {
						urlInfo.newPath = this.downloadDir + separator + pjson.softInfo.softName + separator + title;
					} else {
						fs.mkdirSync(this.downloadDir + separator + pjson.softInfo.softName + separator + title);
						urlInfo.newPath = this.downloadDir + separator + pjson.softInfo.softName + separator + title;
					}
				}
			},
			
			// 下载base64位的图片
			async downloadBaseImage(base64String, outputPath, urlInfo) {
				const buffer = Buffer.from(base64String, 'base64');
				const writeStream = fs.createWriteStream(outputPath);
				writeStream.write(buffer);  
				writeStream.end();
				writeStream.on('finish', () => {
					urlInfo.num += 1;
				});
				// 监听错误事件  
				writeStream.on('error', (err) => {  
					console.error('base64位写入文件时出错:', err);  
				});
			},
			
			// 错误提示
			showError(e){
				let str = '';
				if(e.toString().indexOf('ERR_NAME_NOT_RESOLVE') > -1){
					str = '无法解析该网址，请查看网址是否正确！-1';
				}else if(e.toString().indexOf('Cannot navigate to invalid URL') > -1){
					str = '无效的网址，请查看网址格式是否正确！-2';
				}else if(e.toString().indexOf('ERR_CONNECTION_TIMED_OUT') > -1){
					str = '链接请求超时，请查看网络状态！-3';
				}else if(e.toString().indexOf('TimeoutError') > -1){
					str = '链接请求超时，请查看网络状态！-4';
				}else if(e.toString().indexOf('operation not permitted') > -1){
					str = '权限受限，请以管理员权限运行软件！-5';
				}else if(e.toString().indexOf('browser has disconnected') > -1){
					str = '内置浏览器已关闭！-6';
				}else if(e.toString().indexOf('Failed to launch the browser') > -1){
					str = '请先关闭内置浏览器！-7';
				}else{
					str = e.toString();
					//console.log(e);
				}
				this.loading = false;
				this.$notify.error({
					title: '提示',
					message: str
				});
			},
			
			// 是否包含特殊字符
			containsAnyChar(str, charsArray) {
			    for (let i = 0; i < charsArray.length; i++) {
			        if (str.includes(charsArray[i])) {  
			            return true;
			        }  
			    }  
			    return false; 
			},
			
			// 随机生成字符
			randomString(length) {  
			    let result  = '';  
			    const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';  
			    const charactersLength = characters.length;  
			    for (let i = 0; i < length; i++ ) {
			       result += characters.charAt(Math.floor(Math.random() * charactersLength));  
			    }  
			    return result;  
			} 
			
		}
	};
</script>

<style lang="scss">
	@import "../assets/css/fontx/iconfont.css";
	@import "../assets/css/home.scss";

	.ivu-input-number-controls-outside-btn i {
		font-weight: 800;
	}

	.update-point {
		display: inline-block;
		width: 8px;
		height: 8px;
		border-radius: 8px;
		background: #ff0000;
		top: 14px;
		position: absolute;
		left: -13px;
	}

	.menu-item {
		padding: 8px 0;
		font-size: 14px;

		.iconfont {
			font-size: 32px;
		}

		&:hover,
		&.active {
			color: #ed4014;
		}
	}

	.ivu-progress-show-info .ivu-progress-outer {
		padding-right: 40px !important;
		margin-right: -40px !important;
	}

	.tips {
		text-align: center;
		padding: 10px 0;
		color: #ed4014;
		font-size: 12px;
	}

	.handle-desc {
		display: inline-block;
		width: calc(100% - 100px);
		overflow: hidden;
	}

	.ivu-menu-submenu-title {
		font-weight: 600;
	}

	.ivu-menu .ivu-menu-item {
		line-height: 1;
	}

	// new-el
	.el-menu {
		border-right: none !important;
	}

	.cmenu-item {
		padding: 0 20px 20px;
		margin-bottom: 15px;

		.cmenu-title {
			font-size: 18px;
			font-weight: 600;
			padding-bottom: 20px;
		}

		.citem-nav {
			text-align: center;
			border-radius: 10px;
			min-height: 110px;
			padding: 15px 0;
			background-color: #fff;
			font-size: 15px;
			cursor: pointer;

			&.bg-linear1 {
				color: #fff;
				font-size: 20px;
				background: linear-gradient(to right bottom, #2A56CA, #5795F4);
			}

			&.bg-linear2 {
				color: #fff;
				font-size: 20px;
				background: linear-gradient(to right top, #147FBB, #5EB3E3);
			}

			&.bg-linear3 {
				color: #fff;
				font-size: 20px;
				background: linear-gradient(to right bottom, #2F9E8A, #56CDB1);
			}

			&:hover {
				margin-top: -5px;
				box-shadow: 3px 3px 6px #ccc, -3px -3px 6px #ccc;
			}

			.citem-img {
				width: 50px;
				margin-bottom: 10px;
			}
		}
	}
	
	.popper-open{
		text-align: center !important;
		padding: 10px !important;
		background: #303133 !important;
		color: #fff !important;
		min-width: 120px !important;
		opacity: 0.8;
	}
	
	.popper-open[x-placement^=bottom] .popper__arrow::after{
		border-bottom-color: #303133 !important;
	}
	
	textarea.el-textarea__inner{
		height: 100% !important;
		font-family: "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif;
	}
	
	.set-item{
		margin-right: 15px;
		
		.set-title{
			font-size: 13px;
		}
	}
	
	.outarea{
		height: 100%;
		border: 1px solid #DCDFE6;
		background-color: #4851a415; 
		padding: 15px;
		font-size: 20px;
		overflow: hidden auto;
	}
	
	.outtext{
		height: 100%;
		font-size: 20px;
		overflow: hidden auto;
		
		textarea{
			background-color: #4851a415; 
		}
	}
	
	.pin-tips{
		font-size: 14px;
		position: absolute;
		bottom: 10px;
		color: #ff0000;
		left: 0;
		right: 0;
		margin: auto;
		text-align: center;
	}
	
	.outarea.red-border{
		border: 1px solid #F56C6C;
	}
	
	.outtext.red-border textarea{
		border: 1px solid #F56C6C;
	}
	
	h3{
		margin: 0;
	}
	
	.m-image{
		width: 20px;
		margin-right: 5px;
	}
	
	.dialog-footer-center{
		text-align: center;
	}
	
	.visible-tips-style{
		font-size: 18px; 
		color: #f73131; 
		font-weight: 600; 
		padding: 30px 40px 0;
	}
	
	.no-select{
		user-select: none; 
	}
	
	.tips-flex{
		display: flex;
		flex-wrap: nowrap;
		justify-content: space-around;
		align-items: center;
		
		.el-icon-s-opportunity{
			font-size: 50px;
			color: #f73131;
			margin-right: 10px;
		}
		
		.m-title{
			flex: 1;
			color: #f73131;
		}
	}
	
</style>